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) {}
69 StringRef getPassName()
const override {
return "Mips Long Branch"; }
84 void expandToLongBranch(MBBInfo &Info);
91 unsigned LongBranchSeqSize;
100 return new MipsLongBranch(tm);
120 if (!B->isDebugValue())
132 if ((LastBr == End) ||
133 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
140 if ((FirstBr == End) ||
141 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
144 assert(!FirstBr->isIndirectBranch() &&
"Unexpected indirect branch found.");
152 NewMBB->transferSuccessors(MBB);
153 NewMBB->removeSuccessor(Tgt,
true);
158 NewMBB->splice(NewMBB->end(),
MBB, LastBr.getReverse(), MBB->
end());
162 void MipsLongBranch::initMBBInfo() {
165 for (
auto &MBB : *MF)
168 MF->RenumberBlocks();
170 MBBInfos.resize(MF->size());
173 static_cast<const MipsInstrInfo *
>(MF->getSubtarget().getInstrInfo());
174 for (
unsigned I = 0,
E = MBBInfos.size();
I <
E; ++
I) {
183 ReverseIter End = MBB->
rend();
186 if ((Br != End) && !Br->isIndirectBranch() &&
187 (Br->isConditionalBranch() || (Br->isUnconditionalBranch() && IsPIC)))
188 MBBInfos[
I].Br = &*Br;
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;
225 for (
unsigned I = 0, E = Br->getDesc().getNumOperands();
I <
E; ++
I) {
238 if (Br->hasDelaySlot()) {
241 assert(Br->isBundledWithSucc());
245 Br->eraseFromParent();
253 void MipsLongBranch::expandToLongBranch(MBBInfo &
I) {
265 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 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
336 .addReg(Mips::SP).
addImm(8);
339 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR))
340 .addReg(Mips::ZERO).
addReg(Mips::AT);
342 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT);
345 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
349 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
350 .addReg(Mips::SP).
addImm(8);
352 BalTgtMBB->
rbegin()->bundleWithPred();
384 Pos = LongBrMBB->
begin();
386 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
387 .addReg(Mips::SP_64).
addImm(-16);
388 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
390 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
391 Mips::AT_64).addReg(Mips::ZERO_64)
393 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
394 .addReg(Mips::AT_64).
addImm(16);
399 BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
404 Pos = BalTgtMBB->
begin();
406 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
407 .addReg(Mips::RA_64).
addReg(Mips::AT_64);
409 .addReg(Mips::SP_64).
addImm(0);
412 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64))
413 .addReg(Mips::ZERO_64).
addReg(Mips::AT_64);
415 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64);
417 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
418 .addReg(Mips::SP_64).
addImm(16);
419 BalTgtMBB->
rbegin()->bundleWithPred();
422 assert(LongBrMBB->
size() + BalTgtMBB->
size() == LongBranchSeqSize);
429 Pos = LongBrMBB->
begin();
435 assert(LongBrMBB->
size() == LongBranchSeqSize);
438 if (I.Br->isUnconditionalBranch()) {
440 assert(I.Br->getDesc().getNumOperands() == 1);
441 I.Br->RemoveOperand(0);
445 replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB);
452 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
454 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
465 !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.
isTargetNaCl() ? 9 : 10));
469 if (IsPIC && static_cast<const MipsTargetMachine &>(
TM).getABI().IsO32() &&
480 bool EverMadeChange =
false, MadeChange =
true;
485 for (I = MBBInfos.begin(); I !=
E; ++
I) {
488 if (!I->Br || I->HasLongBranch)
492 int64_t Offset = computeOffset(I->Br) / ShVal;
506 I->HasLongBranch =
true;
507 I->Size += LongBranchSeqSize * 4;
509 EverMadeChange = MadeChange =
true;
520 for (I = MBBInfos.begin(); I !=
E; Address += I->Size, ++
I)
521 I->Address = Address;
525 for (I = MBBInfos.begin(); I !=
E; ++
I)
526 if (I->HasLongBranch)
527 expandToLongBranch(*I);
529 MF->RenumberBlocks();
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
Return the number of bytes of code the specified instruction may be.
const MachineFunction * getParent() const
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
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Describe properties that are true of each instruction in the target description file.
const MipsInstrInfo * getInstrInfo() const override
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
constexpr bool isInt< 16 >(int64_t x)
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
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
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
const MachineBasicBlock & front() const
Function Alias Analysis false
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
reverse_iterator rbegin()
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
LLVM Basic Block Representation.
FunctionPass * createMipsLongBranchPass(MipsTargetMachine &TM)
createMipsLongBranchPass - Returns a pass that converts branches to long branches.
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)
static const unsigned End
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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions.
Iterator for intrusive lists based on ilist_node.
bool isTargetNaCl() const
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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 replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
MachineFunctionProperties & set(Property P)
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...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
static ReverseIter getNonDebugInstr(ReverseIter B, const ReverseIter &E)
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.
StringRef - Represent a constant reference to a string, i.e.
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
Add a new virtual register operand.
Properties which a MachineFunction may have at a given point in time.
Helper class for constructing bundles of MachineInstrs.