33 #define DEBUG_TYPE "mips-long-branch"
35 STATISTIC(LongBranches,
"Number of long branches.");
38 "skip-mips-long-branch",
40 cl::desc(
"MIPS: Skip long branch pass."),
44 "force-mips-long-branch",
46 cl::desc(
"MIPS: Expand all branches to long format."),
58 MBBInfo() : Size(0), HasLongBranch(
false), Br(nullptr) {}
67 IsPIC(
TM.getRelocationModel() == Reloc::
PIC_),
70 const char *getPassName()
const override {
71 return "Mips Long Branch";
82 void expandToLongBranch(MBBInfo &Info);
89 unsigned LongBranchSeqSize;
98 return new MipsLongBranch(tm);
118 if (!B->isDebugValue())
126 ReverseIter End = MBB->
rend();
130 if ((LastBr == End) ||
131 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
138 if ((FirstBr == End) ||
139 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
142 assert(!FirstBr->isIndirectBranch() &&
"Unexpected indirect branch found.");
150 NewMBB->transferSuccessors(MBB);
151 NewMBB->removeSuccessor(Tgt);
156 NewMBB->splice(NewMBB->end(), MBB, (++LastBr).base(), MBB->
end());
160 void MipsLongBranch::initMBBInfo() {
166 MF->RenumberBlocks();
168 MBBInfos.resize(MF->size());
171 static_cast<const MipsInstrInfo *
>(MF->getSubtarget().getInstrInfo());
172 for (
unsigned I = 0, E = MBBInfos.size();
I < E; ++
I) {
181 ReverseIter End = MBB->
rend();
184 if ((Br != End) && !Br->isIndirectBranch() &&
185 (Br->isConditionalBranch() ||
186 (Br->isUnconditionalBranch() &&
188 MBBInfos[
I].Br = (++Br).base();
193 int64_t MipsLongBranch::computeOffset(
const MachineInstr *Br) {
199 if (ThisMBB < TargetMBB) {
200 for (
int N = ThisMBB + 1;
N < TargetMBB; ++
N)
201 Offset += MBBInfos[
N].Size;
207 for (
int N = ThisMBB;
N >= TargetMBB; --
N)
208 Offset += MBBInfos[
N].Size;
224 for (
unsigned I = 0, E = Br->getDesc().getNumOperands();
I < E; ++
I) {
228 assert(MO.
isMBB() &&
"MBB operand expected.");
237 if (Br->hasDelaySlot()) {
240 assert(Br->isBundledWithSucc());
244 Br->eraseFromParent();
252 void MipsLongBranch::expandToLongBranch(MBBInfo &
I) {
264 MF->insert(FallThroughMBB, LongBrMBB);
270 MF->
insert(FallThroughMBB, BalTgtMBB);
277 unsigned BalOp = Subtarget.
hasMips32r6() ? Mips::BAL : Mips::BAL_BR;
294 Pos = LongBrMBB->
begin();
296 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
297 .addReg(Mips::SP).
addImm(-8);
298 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA)
317 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
318 .addMBB(TgtMBB).
addMBB(BalTgtMBB);
321 .
append(
BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
326 Pos = BalTgtMBB->
begin();
328 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
329 .addReg(Mips::RA).
addReg(Mips::AT);
330 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
331 .addReg(Mips::SP).
addImm(0);
335 .
append(
BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
337 .addReg(Mips::SP).
addImm(8));
340 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
341 .addReg(Mips::SP).
addImm(8);
344 .
append(
BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
381 Pos = LongBrMBB->
begin();
383 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
384 .addReg(Mips::SP_64).
addImm(-16);
385 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
387 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
388 Mips::AT_64).addReg(Mips::ZERO_64)
390 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
391 .addReg(Mips::AT_64).
addImm(16);
396 BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
401 Pos = BalTgtMBB->
begin();
403 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
404 .addReg(Mips::RA_64).
addReg(Mips::AT_64);
406 .addReg(Mips::SP_64).
addImm(0);
409 .
append(
BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64))
410 .
append(
BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64)
411 .addReg(Mips::SP_64).
addImm(16));
414 assert(LongBrMBB->
size() + BalTgtMBB->
size() == LongBranchSeqSize);
421 Pos = LongBrMBB->
begin();
427 assert(LongBrMBB->
size() == LongBranchSeqSize);
430 if (I.Br->isUnconditionalBranch()) {
432 assert(I.Br->getDesc().getNumOperands() == 1);
433 I.Br->RemoveOperand(0);
437 replaceBranch(*MBB, I.Br, DL, FallThroughMBB);
444 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
446 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
457 !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.
isTargetNaCl() ? 9 : 10));
462 static_cast<const MipsTargetMachine &>(
TM).getABI().IsO32() &&
473 bool EverMadeChange =
false, MadeChange =
true;
478 for (I = MBBInfos.begin(); I != E; ++
I) {
481 if (!I->Br || I->HasLongBranch)
485 int64_t Offset = computeOffset(I->Br) / ShVal;
499 I->HasLongBranch =
true;
500 I->Size += LongBranchSeqSize * 4;
502 EverMadeChange = MadeChange =
true;
513 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++
I)
514 I->Address = Address;
518 for (I = MBBInfos.begin(); I != E; ++
I)
519 if (I->HasLongBranch)
520 expandToLongBranch(*I);
522 MF->RenumberBlocks();
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
instr_iterator instr_begin()
instr_iterator instr_end()
STATISTIC(NumFunctions,"Total number of functions")
MachineBasicBlock * getMBB() const
int getNumber() const
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
Describe properties that are true of each instruction in the target description file.
void removeLiveIn(unsigned Reg)
removeLiveIn - Remove the specified register from the live in set.
const MipsInstrInfo * getInstrInfo() const override
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
Instructions::iterator instr_iterator
static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII)
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
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...
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
const MachineBasicBlock & front() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
reverse_iterator rbegin()
const BasicBlock * getBasicBlock() const
getBasicBlock - Return the LLVM basic block that this instance corresponded to originally.
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
LLVM Basic Block Representation.
FunctionPass * createMipsLongBranchPass(MipsTargetMachine &TM)
createMipsLongBranchPass - Returns a pass that converts branches to long branches.
DebugLoc findDebugLoc(instr_iterator MBBI)
findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions...
const MachineOperand & getOperand(unsigned i) const
static cl::opt< bool > SkipLongBranch("skip-mips-long-branch", cl::init(false), cl::desc("MIPS: Skip long branch pass."), cl::Hidden)
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
bool inMicroMipsMode() const
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
void removeSuccessor(MachineBasicBlock *succ)
removeSuccessor - Remove successor from the successors list of this MachineBasicBlock.
static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E)
bool isTargetNaCl() const
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.
static const unsigned MIPS_NACL_BUNDLE_ALIGN
Representation of each machine instruction.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0)
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
static cl::opt< bool > ForceLongBranch("force-mips-long-branch", cl::init(false), cl::desc("MIPS: Expand all branches to long format."), cl::Hidden)
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
bool isInt< 16 >(int64_t x)
bool enableLongBranchPass() const
unsigned getReg() const
getReg - Returns the register number.
MIBundleBuilder & append(MachineInstr *MI)
Insert MI into MBB by appending it to the instructions in the bundle.
virtual const TargetInstrInfo * getInstrInfo() const
std::reverse_iterator< iterator > reverse_iterator
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
Return the number of bytes of code the specified instruction may be.
static MachineBasicBlock * getTargetMBB(const MachineInstr &Br)
Iterate over list of Br's operands and search for a MachineBasicBlock operand.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.
Helper class for constructing bundles of MachineInstrs.