30#define DEBUG_TYPE "hexagon-brelax"
60 return "Hexagon Branch Relaxation";
81 char HexagonBranchRelaxation::ID = 0;
86 "Hexagon Branch Relaxation",
false,
false)
89 return new HexagonBranchRelaxation();
92bool HexagonBranchRelaxation::runOnMachineFunction(
MachineFunction &MF) {
97 HRI = HST.getRegisterInfo();
100 Changed = relaxBranches(MF);
107 unsigned InstOffset = 0;
109 if (
B.getAlignment() !=
Align(1)) {
113 InstOffset =
alignTo(InstOffset,
B.getAlignment());
115 OffsetMap[&
B] = InstOffset;
116 for (
auto &
MI :
B.instrs()) {
117 InstOffset += HII->getSize(
MI);
119 if (
MI.isBranch() && HII->isExtendable(
MI))
135 computeOffset(MF, BlockToInstOffset);
137 return reGenerateBranch(MF, BlockToInstOffset);
147 auto FirstTerm =
B.getFirstInstrTerminator();
148 if (FirstTerm ==
B.instr_end())
151 if (HII->isExtended(
MI))
154 unsigned InstOffset = BlockToInstOffset[&
B];
155 unsigned Distance = 0;
166 if (HII->analyzeBranch(
B,
TBB, FBB,
Cond,
false)) {
170 if (HII->isNewValueJump(*FirstTerm))
171 TBB = FirstTerm->getOperand(HII->getCExtOpNum(*FirstTerm)).getMBB();
173 if (
TBB && &
MI == &*FirstTerm) {
174 Distance = std::abs((
long long)InstOffset - BlockToInstOffset[
TBB])
176 return !HII->isJumpWithinBranchRange(*FirstTerm, Distance);
180 auto SecondTerm = std::next(FirstTerm);
181 assert(SecondTerm !=
B.instr_end() &&
182 (SecondTerm->isBranch() || SecondTerm->isCall()) &&
183 "Bad second terminator");
184 if (&
MI != &*SecondTerm)
187 Distance = std::abs((
long long)InstOffset - BlockToInstOffset[FBB])
189 return !HII->isJumpWithinBranchRange(*SecondTerm, Distance);
196 bool Changed =
false;
200 if (!
MI.isBranch() || !isJumpOutOfRange(
MI, BlockToInstOffset))
203 << HII->isExtendable(
MI) <<
") isConstExtended("
204 << HII->isConstExtended(
MI) <<
") " <<
MI);
208 if (!HII->isExtendable(
MI) && !HII->isExtended(
MI)) {
209 LLVM_DEBUG(
dbgs() <<
"\tUnderimplemented relax branch instruction.\n");
212 int ExtOpNum = HII->getCExtOpNum(
MI);
217 assert(MO.
isMBB() &&
"Branch with unknown expandable field type");
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
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.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializeHexagonBranchRelaxationPass(PassRegistry &)
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.