10 #define DEBUG_TYPE "hexagon-brelax"
60 return "Hexagon Branch Relaxation";
86 "Hexagon Branch Relaxation",
false,
false)
89 return new HexagonBranchRelaxation();
92 bool HexagonBranchRelaxation::runOnMachineFunction(
MachineFunction &MF) {
93 DEBUG(
dbgs() <<
"****** Hexagon Branch Relaxation ******\n");
100 Changed = relaxBranches(MF);
107 unsigned InstOffset = 0;
109 if (
B.getAlignment()) {
113 int ByteAlign = (1u <<
B.getAlignment()) - 1;
114 InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
116 OffsetMap[&
B] = InstOffset;
117 for (
auto &
MI :
B.instrs())
118 InstOffset += HII->getSize(
MI);
132 computeOffset(MF, BlockToInstOffset);
134 return reGenerateBranch(MF, BlockToInstOffset);
148 unsigned InstOffset = BlockToInstOffset[&
B];
149 unsigned Distance = 0;
160 if (HII->analyzeBranch(B, TBB, FBB, Cond,
false)) {
164 if (HII->isNewValueJump(*FirstTerm))
165 TBB = FirstTerm->getOperand(HII->getCExtOpNum(*FirstTerm)).getMBB();
167 if (TBB && &MI == &*FirstTerm) {
168 Distance =
std::abs((
long long)InstOffset - BlockToInstOffset[TBB])
170 return !HII->isJumpWithinBranchRange(*FirstTerm, Distance);
174 auto SecondTerm = std::next(FirstTerm);
176 (SecondTerm->isBranch() || SecondTerm->isCall()) &&
177 "Bad second terminator");
178 if (&MI != &*SecondTerm)
181 Distance =
std::abs((
long long)InstOffset - BlockToInstOffset[FBB])
183 return !HII->isJumpWithinBranchRange(*SecondTerm, Distance);
190 bool Changed =
false;
194 if (!MI.
isBranch() || !isJumpOutOfRange(MI, BlockToInstOffset))
196 DEBUG(
dbgs() <<
"Long distance jump. isExtendable("
197 << HII->isExtendable(MI) <<
") isConstExtended("
198 << HII->isConstExtended(MI) <<
") " <<
MI);
202 if (!HII->isExtendable(MI) && !HII->isExtended(MI)) {
203 DEBUG(
dbgs() <<
"\tUnderimplemented relax branch instruction.\n");
206 int ExtOpNum = HII->getCExtOpNum(MI);
211 assert(MO.
isMBB() &&
"Branch with unknown expandable field type");
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
instr_iterator instr_end()
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
INITIALIZE_PASS(HexagonBranchRelaxation,"hexagon-brelax","Hexagon Branch Relaxation", false, false) FunctionPass *llvm
const HexagonRegisterInfo & getRegisterInfo() const
HexagonInstrInfo specifics.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
const MachineBasicBlock * getParent() const
initializer< Ty > init(const Ty &Val)
void initializeHexagonBranchRelaxationPass(PassRegistry &)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
static cl::opt< uint32_t > BranchRelaxSafetyBuffer("branch-relax-safety-buffer", cl::init(200), cl::Hidden, cl::ZeroOrMore, cl::desc("safety buffer size"))
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createHexagonBranchRelaxation()
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Representation of each machine instruction.
void addTargetFlag(unsigned F)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define HEXAGON_INSTR_SIZE
const HexagonInstrInfo * getInstrInfo() const override
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...