30#define DEBUG_TYPE "hexagon-brelax"
51 return "Hexagon Branch Relaxation";
72 char HexagonBranchRelaxation::ID = 0;
77 "Hexagon Branch Relaxation",
false,
false)
80 return new HexagonBranchRelaxation();
83bool HexagonBranchRelaxation::runOnMachineFunction(
MachineFunction &MF) {
88 HRI = HST.getRegisterInfo();
91 Changed = relaxBranches(MF);
98 unsigned InstOffset = 0;
100 if (
B.getAlignment() !=
Align(1)) {
104 InstOffset =
alignTo(InstOffset,
B.getAlignment());
106 OffsetMap[&
B] = InstOffset;
107 for (
auto &
MI :
B.instrs()) {
108 InstOffset += HII->getSize(
MI);
110 if (
MI.isBranch() && HII->isExtendable(
MI))
126 computeOffset(MF, BlockToInstOffset);
128 return reGenerateBranch(MF, BlockToInstOffset);
138 auto FirstTerm =
B.getFirstInstrTerminator();
139 if (FirstTerm ==
B.instr_end())
142 if (HII->isExtended(
MI))
145 unsigned InstOffset = BlockToInstOffset[&
B];
146 unsigned Distance = 0;
157 if (HII->analyzeBranch(
B,
TBB, FBB,
Cond,
false)) {
161 if (HII->isNewValueJump(*FirstTerm))
162 TBB = FirstTerm->getOperand(HII->getCExtOpNum(*FirstTerm)).getMBB();
164 if (
TBB && &
MI == &*FirstTerm) {
165 Distance = std::abs((
long long)InstOffset - BlockToInstOffset[
TBB])
167 return !HII->isJumpWithinBranchRange(*FirstTerm, Distance);
171 auto SecondTerm = std::next(FirstTerm);
172 assert(SecondTerm !=
B.instr_end() &&
173 (SecondTerm->isBranch() || SecondTerm->isCall()) &&
174 "Bad second terminator");
175 if (&
MI != &*SecondTerm)
178 Distance = std::abs((
long long)InstOffset - BlockToInstOffset[FBB])
180 return !HII->isJumpWithinBranchRange(*SecondTerm, Distance);
187 bool Changed =
false;
191 if (!
MI.isBranch() || !isJumpOutOfRange(
MI, BlockToInstOffset))
194 << HII->isExtendable(
MI) <<
") isConstExtended("
195 << HII->isConstExtended(
MI) <<
") " <<
MI);
199 if (!HII->isExtendable(
MI) && !HII->isExtended(
MI)) {
200 LLVM_DEBUG(
dbgs() <<
"\tUnderimplemented relax branch instruction.\n");
203 int ExtOpNum = HII->getCExtOpNum(
MI);
208 assert(MO.
isMBB() &&
"Branch with unknown expandable field type");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
static cl::opt< uint32_t > BranchRelaxSafetyBuffer("branch-relax-safety-buffer", cl::init(200), cl::Hidden, cl::desc("safety buffer size"))
#define HEXAGON_INSTR_SIZE
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
const HexagonInstrInfo * getInstrInfo() const override
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void addTargetFlag(unsigned F)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createHexagonBranchRelaxation()
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.