19 #define DEBUG_TYPE "mips-long-branch"
36 STATISTIC(LongBranches,
"Number of long branches.");
39 "skip-mips-long-branch",
41 cl::desc(
"MIPS: Skip long branch pass."),
45 "force-mips-long-branch",
47 cl::desc(
"MIPS: Expand all branches to long format."),
55 uint64_t Size, Address;
59 MBBInfo() : Size(0), HasLongBranch(
false), Br(0) {}
68 IsPIC(
TM.getRelocationModel() == Reloc::
PIC_),
70 LongBranchSeqSize(!IsPIC ? 2 : (ABI ==
MipsSubtarget::N64 ? 13 : 9)) {}
72 virtual const char *getPassName()
const {
73 return "Mips Long Branch";
84 void expandToLongBranch(MBBInfo &Info);
91 unsigned LongBranchSeqSize;
100 return new MipsLongBranch(tm);
113 assert(
false &&
"This instruction does not have an MBB operand.");
121 if (!B->isDebugValue())
129 ReverseIter End = MBB->
rend();
133 if ((LastBr == End) ||
134 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
141 if ((FirstBr == End) ||
142 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
145 assert(!FirstBr->isIndirectBranch() &&
"Unexpected indirect branch found.");
153 NewMBB->transferSuccessors(MBB);
154 NewMBB->removeSuccessor(Tgt);
159 NewMBB->splice(NewMBB->end(), MBB, (++LastBr).base(), MBB->
end());
163 void MipsLongBranch::initMBBInfo() {
169 MF->RenumberBlocks();
171 MBBInfos.resize(MF->size());
175 for (
unsigned I = 0, E = MBBInfos.size();
I < E; ++
I) {
184 ReverseIter End = MBB->
rend();
187 if ((Br != End) && !Br->isIndirectBranch() &&
188 (Br->isConditionalBranch() ||
189 (Br->isUnconditionalBranch() &&
191 MBBInfos[
I].Br = (++Br).base();
196 int64_t MipsLongBranch::computeOffset(
const MachineInstr *Br) {
202 if (ThisMBB < TargetMBB) {
203 for (
int N = ThisMBB + 1;
N < TargetMBB; ++
N)
204 Offset += MBBInfos[
N].Size;
210 for (
int N = ThisMBB;
N >= TargetMBB; --
N)
211 Offset += MBBInfos[
N].Size;
227 for (
unsigned I = 0, E = Br->getDesc().getNumOperands();
I < E; ++
I) {
231 assert(MO.
isMBB() &&
"MBB operand expected.");
242 assert(Br->isBundledWithSucc());
245 Br->eraseFromParent();
249 void MipsLongBranch::expandToLongBranch(MBBInfo &
I) {
260 MF->insert(FallThroughMBB, LongBrMBB);
266 MF->
insert(FallThroughMBB, BalTgtMBB);
270 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address;
271 unsigned BalTgtMBBSize = 5;
272 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4);
273 int64_t
Lo = SignExtend64<16>(Offset & 0xffff);
274 int64_t
Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff);
291 Pos = LongBrMBB->
begin();
293 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
294 .addReg(Mips::SP).
addImm(-8);
295 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA)
299 .
append(
BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
302 Pos = BalTgtMBB->
begin();
304 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT)
306 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
307 .addReg(Mips::RA).
addReg(Mips::AT);
308 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
309 .addReg(Mips::SP).
addImm(0);
312 .
append(
BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
314 .addReg(Mips::SP).
addImm(8));
334 int64_t Higher = SignExtend64<16>(((Offset + 0x80008000) >> 32) & 0xffff);
336 SignExtend64<16>(((Offset + 0x800080008000LL) >> 48) & 0xffff);
338 Pos = LongBrMBB->
begin();
340 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
341 .addReg(Mips::SP_64).
addImm(-16);
342 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
344 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LUi64), Mips::AT_64)
346 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
347 .addReg(Mips::AT_64).
addImm(Higher);
348 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
349 .addReg(Mips::AT_64).
addImm(16);
350 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
354 .
append(
BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
356 .addReg(Mips::AT_64).
addImm(16));
358 Pos = BalTgtMBB->
begin();
360 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
362 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
363 .addReg(Mips::RA_64).
addReg(Mips::AT_64);
365 .addReg(Mips::SP_64).
addImm(0);
368 .
append(
BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64))
369 .
append(
BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64)
370 .addReg(Mips::SP_64).
addImm(16));
373 assert(BalTgtMBBSize == BalTgtMBB->
size());
374 assert(LongBrMBB->
size() + BalTgtMBBSize == LongBranchSeqSize);
381 Pos = LongBrMBB->
begin();
387 assert(LongBrMBB->
size() == LongBranchSeqSize);
390 if (I.Br->isUnconditionalBranch()) {
392 assert(I.Br->getDesc().getNumOperands() == 1);
393 I.Br->RemoveOperand(0);
397 replaceBranch(*MBB, I.Br, DL, FallThroughMBB);
404 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
406 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
429 bool EverMadeChange =
false, MadeChange =
true;
434 for (I = MBBInfos.begin(); I != E; ++
I) {
437 if (!I->Br || I->HasLongBranch)
444 I->HasLongBranch =
true;
445 I->Size += LongBranchSeqSize * 4;
447 EverMadeChange = MadeChange =
true;
456 uint64_t Address = 0;
458 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++
I)
459 I->Address = Address;
463 for (I = MBBInfos.begin(); I != E; ++
I)
464 if (I->HasLongBranch)
465 expandToLongBranch(*I);
467 MF->RenumberBlocks();
instr_iterator instr_begin()
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
void removeLiveIn(unsigned Reg)
const MCInstrDesc & getDesc() const
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 HexagonInstrInfo * TII
bool isReg() const
isReg - Tests if this is a MO_Register operand.
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
const MachineBasicBlock & front() const
reverse_iterator rbegin()
const BasicBlock * getBasicBlock() const
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
LLVM Basic Block Representation.
FunctionPass * createMipsLongBranchPass(MipsTargetMachine &TM)
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)
ItTy next(ItTy it, Dist n)
STATISTIC(LongBranches,"Number of long branches.")
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
void removeSuccessor(MachineBasicBlock *succ)
static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E)
DebugLoc findDebugLoc(instr_iterator MBBI)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
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)
instr_iterator insert(instr_iterator I, MachineInstr *M)
bool isInt< 16 >(int64_t x)
unsigned getReg() const
getReg - Returns the register number.
MIBundleBuilder & append(MachineInstr *MI)
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. Note that variadic (isVari...
BasicBlockListType::iterator iterator
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
Return the number of bytes of code the specified instruction may be.
static MachineBasicBlock * getTargetMBB(const MachineInstr &Br)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)