49 #define DEBUG_TYPE "mips-constant-islands"
51 STATISTIC(NumCPEs,
"Number of constpool entries");
52 STATISTIC(NumSplit,
"Number of uncond branches inserted");
53 STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
54 STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
59 cl::desc(
"Align constant islands in code"));
66 "mips-constant-islands-small-offset",
68 cl::desc(
"Make small offsets be this amount for testing purposes"),
76 "mips-constant-islands-no-load-relaxation",
78 cl::desc(
"Don't relax loads to long loads - for testing purposes"),
91 case Mips::BeqzRxImm16:
92 case Mips::BeqzRxImmX16:
93 case Mips::BnezRxImm16:
94 case Mips::BnezRxImmX16:
104 return Mips::BimmX16;
107 return Mips::BteqzX16;
110 return Mips::BtnezX16;
113 case Mips::BeqzRxImm16:
114 case Mips::BeqzRxImmX16:
115 return Mips::BeqzRxImmX16;
116 case Mips::BnezRxImm16:
117 case Mips::BnezRxImmX16:
118 return Mips::BnezRxImmX16;
130 unsigned Bits, Scale;
140 case Mips::BeqzRxImm16:
144 case Mips::BeqzRxImmX16:
148 case Mips::BnezRxImm16:
152 case Mips::BnezRxImmX16:
175 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
222 unsigned postOffset(
unsigned LogAlign = 0)
const {
223 unsigned PO =
Offset + Size;
231 std::vector<BasicBlockInfo> BBInfo;
236 std::vector<MachineBasicBlock*> WaterList;
242 typedef std::vector<MachineBasicBlock*>::iterator water_iterator;
262 unsigned LongFormMaxDisp;
264 unsigned LongFormOpcode;
269 unsigned longformmaxdisp,
unsigned longformopcode)
270 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
271 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
273 HighWaterMark = CPEMI->getParent();
276 unsigned getMaxDisp()
const {
281 void setMaxDisp(
unsigned val) {
284 unsigned getLongFormMaxDisp()
const {
285 return LongFormMaxDisp;
287 unsigned getLongFormOpcode()
const {
288 return LongFormOpcode;
294 std::vector<CPUser> CPUsers;
304 : CPEMI(cpemi), CPI(cpi), RefCount(
rc) {}
312 std::vector<std::vector<CPEntry> > CPEntries;
320 unsigned MaxDisp : 31;
323 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
324 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
329 std::vector<ImmBranch> ImmBranches;
341 unsigned PICLabelUId;
342 bool PrescannedForConstants;
344 void initPICLabelUId(
unsigned UId) {
349 unsigned createPICLabelUId() {
350 return PICLabelUId++;
355 MipsConstantIslands()
357 PrescannedForConstants(
false) {}
359 StringRef getPassName()
const override {
return "Mips Constant Islands"; }
368 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
369 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
371 void initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs);
373 unsigned getUserOffset(CPUser&)
const;
376 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
377 unsigned Disp,
bool NegativeOK);
378 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
385 bool decrementCPEReferenceCount(
unsigned CPI,
MachineInstr* CPEMI);
386 int findInRangeCPEntry(CPUser& U,
unsigned UserOffset);
387 int findLongFormInRangeCPEntry(CPUser& U,
unsigned UserOffset);
388 bool findAvailableWater(CPUser&U,
unsigned UserOffset,
389 water_iterator &WaterIter);
390 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
392 bool handleConstantPoolUser(
unsigned CPUserIndex);
394 bool removeUnusedCPEntries();
397 bool DoDump =
false);
399 CPUser &U,
unsigned &Growth);
401 bool fixupImmediateBr(ImmBranch &Br);
402 bool fixupConditionalBr(ImmBranch &Br);
403 bool fixupUnconditionalBr(ImmBranch &Br);
405 void prescanForConstants();
414 bool MipsConstantIslands::isOffsetInRange
415 (
unsigned UserOffset,
unsigned TrialOffset,
417 return isOffsetInRange(UserOffset, TrialOffset,
418 U.getMaxDisp(), U.NegOk);
421 void MipsConstantIslands::dumpBBs() {
423 for (
unsigned J = 0,
E = BBInfo.size(); J !=
E; ++J) {
426 <<
format(
" size=%#x\n", BBInfo[J].Size);
432 return new MipsConstantIslands();
441 DEBUG(
dbgs() <<
"constant island machine function " <<
"\n");
447 DEBUG(
dbgs() <<
"constant island processing " <<
"\n");
452 if (!PrescannedForConstants) prescanForConstants();
456 MF->getRegInfo().invalidateLiveness();
460 MF->RenumberBlocks();
462 bool MadeChange =
false;
466 std::vector<MachineInstr*> CPEMIs;
468 doInitialPlacement(CPEMIs);
471 initPICLabelUId(CPEMIs.size());
476 initializeFunctionInfo(CPEMIs);
481 MadeChange |= removeUnusedCPEntries();
485 unsigned NoCPIters = 0, NoBRIters = 0;
488 DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
489 bool CPChange =
false;
490 for (
unsigned i = 0, e = CPUsers.size();
i != e; ++
i)
491 CPChange |= handleConstantPoolUser(
i);
492 if (CPChange && ++NoCPIters > 30)
498 NewWaterList.clear();
500 DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
501 bool BRChange =
false;
502 for (
unsigned i = 0, e = ImmBranches.size();
i != e; ++
i)
503 BRChange |= fixupImmediateBr(ImmBranches[
i]);
504 if (BRChange && ++NoBRIters > 30)
507 if (!CPChange && !BRChange)
525 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
532 unsigned MaxAlign =
Log2_32(MCP->getConstantPoolAlignment());
550 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
553 for (
unsigned i = 0, e = CPs.
size(); i != e; ++
i) {
555 assert(Size >= 4 &&
"Too small constant pool entry");
556 unsigned Align = CPs[
i].getAlignment();
560 assert((Size % Align) == 0 &&
"CP Entry not multiple of 4 bytes!");
563 unsigned LogAlign =
Log2_32(Align);
570 CPEMIs.push_back(CPEMI);
574 for (
unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
575 if (InsPoint[a] == InsAt)
578 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
580 DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = "
581 << Size <<
", align = " << Align <<
'\n');
606 MipsConstantIslands::CPEntry
607 *MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
609 std::vector<CPEntry> &CPEs = CPEntries[CPI];
612 for (
unsigned i = 0, e = CPEs.size(); i != e; ++
i) {
613 if (CPEs[i].CPEMI == CPEMI)
621 unsigned MipsConstantIslands::getCPELogAlign(
const MachineInstr &CPEMI) {
629 assert(CPI < MCP->getConstants().size() &&
"Invalid constant pool index.");
630 unsigned Align = MCP->getConstants()[CPI].getAlignment();
638 void MipsConstantIslands::
639 initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
641 BBInfo.resize(MF->getNumBlockIDs());
652 adjustBBOffsetsAfter(&MF->front());
659 WaterList.push_back(&
MBB);
661 if (
MI.isDebugValue())
664 int Opc =
MI.getOpcode();
683 case Mips::BeqzRxImm16:
689 case Mips::BeqzRxImmX16:
695 case Mips::BnezRxImm16:
701 case Mips::BnezRxImmX16:
733 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
734 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, isCond, UOpc));
737 if (Opc == Mips::CONSTPOOL_ENTRY)
742 for (
unsigned op = 0, e =
MI.getNumOperands();
op != e; ++
op)
743 if (
MI.getOperand(
op).isCPI()) {
752 unsigned LongFormBits = 0;
753 unsigned LongFormScale = 0;
754 unsigned LongFormOpcode = 0;
758 case Mips::LwRxPcTcp16:
761 LongFormOpcode = Mips::LwRxPcTcpX16;
765 case Mips::LwRxPcTcpX16:
772 unsigned CPI =
MI.getOperand(
op).getIndex();
774 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
775 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
776 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
780 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
781 assert(CPE &&
"Cannot find a corresponding CPEntry!");
808 unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
818 assert(
I != MBB->
end() &&
"Didn't find MI in its own basic block?");
819 Offset +=
TII->getInstSizeInBytes(*
I);
834 void MipsConstantIslands::updateForInsertedWaterBlock
846 std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,
848 WaterList.insert(IP, NewBB);
851 unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
852 return getOffsetOf(U.MI);
859 MipsConstantIslands::splitBlockBeforeInstr(
MachineInstr &MI) {
866 MF->insert(MBBI, NewBB);
887 MF->RenumberBlocks(NewBB);
898 std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB,
901 if (WaterBB == OrigBB)
902 WaterList.
insert(std::next(IP), NewBB);
904 WaterList.insert(IP, OrigBB);
905 NewWaterList.insert(OrigBB);
919 adjustBBOffsetsAfter(OrigBB);
929 bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
930 unsigned TrialOffset,
unsigned MaxDisp,
932 if (UserOffset <= TrialOffset) {
934 if (TrialOffset - UserOffset <= MaxDisp)
936 }
else if (NegativeOK) {
937 if (UserOffset - TrialOffset <= MaxDisp)
947 bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
950 unsigned CPELogAlign = getCPELogAlign(*U.CPEMI);
951 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset(CPELogAlign);
952 unsigned NextBlockOffset, NextBlockAlignment;
954 if (NextBlock == MF->end()) {
955 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
956 NextBlockAlignment = 0;
958 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
959 NextBlockAlignment = NextBlock->getAlignment();
961 unsigned Size = U.CPEMI->getOperand(2).getImm();
962 unsigned CPEEnd = CPEOffset + Size;
967 if (CPEEnd > NextBlockOffset) {
968 Growth = CPEEnd - NextBlockOffset;
976 if (CPEOffset < UserOffset)
977 UserOffset += Growth;
982 return isOffsetInRange(UserOffset, CPEOffset, U);
987 bool MipsConstantIslands::isCPEntryInRange
990 bool NegOk,
bool DoDump) {
991 unsigned CPEOffset = getOffsetOf(CPEMI);
998 <<
" max delta=" << MaxDisp
999 <<
format(
" insn address=%#x", UserOffset)
1000 <<
" in BB#" << Block <<
": "
1002 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
1003 int(CPEOffset-UserOffset));
1007 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1019 if (PredMI->
getOpcode() == Mips::Bimm16)
1027 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++
i) {
1030 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1040 bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1043 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1044 assert(CPE &&
"Unexpected!");
1045 if (--CPE->RefCount == 0) {
1046 removeDeadCPEMI(CPEMI);
1047 CPE->CPEMI =
nullptr;
1060 int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1066 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
1074 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1075 for (
unsigned i = 0, e = CPEs.size(); i != e; ++
i) {
1077 if (CPEs[i].CPEMI == CPEMI)
1080 if (CPEs[i].CPEMI ==
nullptr)
1082 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
1084 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
1085 << CPEs[i].CPI <<
"\n");
1087 U.CPEMI = CPEs[
i].CPEMI;
1098 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1112 int MipsConstantIslands::findLongFormInRangeCPEntry
1113 (CPUser& U,
unsigned UserOffset)
1119 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1120 U.getLongFormMaxDisp(), U.NegOk,
1123 UserMI->
setDesc(
TII->get(U.getLongFormOpcode()));
1124 U.setMaxDisp(U.getLongFormMaxDisp());
1130 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1131 for (
unsigned i = 0, e = CPEs.size(); i != e; ++
i) {
1133 if (CPEs[i].CPEMI == CPEMI)
1136 if (CPEs[i].CPEMI ==
nullptr)
1138 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1139 U.getLongFormMaxDisp(), U.NegOk)) {
1140 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
1141 << CPEs[i].CPI <<
"\n");
1143 U.CPEMI = CPEs[
i].CPEMI;
1154 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1165 return ((1<<10)-1)*2;
1167 return ((1<<16)-1)*2;
1171 return ((1<<16)-1)*2;
1182 bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1183 water_iterator &WaterIter) {
1184 if (WaterList.empty())
1187 unsigned BestGrowth = ~0u;
1188 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
1200 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1201 (WaterBB->
getNumber() < U.HighWaterMark->getNumber() ||
1202 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1204 BestGrowth = Growth;
1207 <<
" Growth=" << Growth <<
'\n');
1210 if (BestGrowth == 0)
1216 return BestGrowth != ~0u;
1226 void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1227 unsigned UserOffset,
1229 CPUser &U = CPUsers[CPUserIndex];
1232 unsigned CPELogAlign = getCPELogAlign(*CPEMI);
1242 unsigned CPEOffset = UserBBI.
postOffset(CPELogAlign) + Delta;
1244 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1246 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1253 int UncondBr = Mips::Bimm16;
1256 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1257 MaxDisp,
false, UncondBr));
1258 BBInfo[UserMBB->
getNumber()].Size += Delta;
1259 adjustBBOffsetsAfter(UserMBB);
1269 unsigned LogAlign = MF->getAlignment();
1270 assert(LogAlign >= CPELogAlign &&
"Over-aligned constant pool entry");
1271 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1278 BaseInsertOffset -= 4;
1281 <<
" la=" << LogAlign <<
'\n');
1287 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1289 DEBUG(
dbgs() <<
format(
"Move inside block: %#x\n", BaseInsertOffset));
1291 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1295 unsigned CPUIndex = CPUserIndex+1;
1296 unsigned NumCPUsers = CPUsers.size();
1298 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1299 Offset < BaseInsertOffset;
1300 Offset +=
TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
1301 assert(MI != UserMBB->
end() &&
"Fell off end of block");
1302 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1303 CPUser &U = CPUsers[CPUIndex];
1304 if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
1306 BaseInsertOffset -= 1u << LogAlign;
1307 EndInsertOffset -= 1u << LogAlign;
1313 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1318 NewMBB = splitBlockBeforeInstr(*--MI);
1325 bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1326 CPUser &U = CPUsers[CPUserIndex];
1332 unsigned UserOffset = getUserOffset(U);
1336 int result = findInRangeCPEntry(U, UserOffset);
1337 if (result==1)
return false;
1338 else if (result==2)
return true;
1345 if (findAvailableWater(U, UserOffset, IP)) {
1346 DEBUG(
dbgs() <<
"Found water in range\n");
1352 if (NewWaterList.erase(WaterBB))
1353 NewWaterList.
insert(NewIsland);
1362 result = findLongFormInRangeCPEntry(U, UserOffset);
1363 if (result != 0)
return true;
1366 createNewWater(CPUserIndex, UserOffset, NewMBB);
1374 IP =
find(WaterList, WaterBB);
1375 if (IP != WaterList.end())
1376 NewWaterList.erase(WaterBB);
1379 NewWaterList.insert(NewIsland);
1386 if (IP != WaterList.end())
1387 WaterList.erase(IP);
1393 updateForInsertedWaterBlock(NewIsland);
1396 decrementCPEReferenceCount(CPI, CPEMI);
1400 unsigned ID = createPICLabelUId();
1404 U.HighWaterMark = NewIsland;
1407 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1414 BBInfo[NewIsland->
getNumber()].Size += Size;
1415 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1424 DEBUG(
dbgs() <<
" Moved CPE to #" << ID <<
" CPI=" << CPI
1432 void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1436 BBInfo[CPEBB->
getNumber()].Size -= Size;
1438 if (CPEBB->
empty()) {
1447 adjustBBOffsetsAfter(CPEBB);
1457 bool MipsConstantIslands::removeUnusedCPEntries() {
1458 unsigned MadeChange =
false;
1459 for (
unsigned i = 0, e = CPEntries.size(); i != e; ++
i) {
1460 std::vector<CPEntry> &CPEs = CPEntries[
i];
1461 for (
unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1462 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1463 removeDeadCPEMI(CPEs[j].CPEMI);
1464 CPEs[j].CPEMI =
nullptr;
1474 bool MipsConstantIslands::isBBInRange
1479 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
1480 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1484 <<
" max delta=" << MaxDisp
1485 <<
" from " << getOffsetOf(MI) <<
" to " << DestOffset
1486 <<
" offset " << int(DestOffset-BrOffset) <<
"\t" << *
MI);
1488 if (BrOffset <= DestOffset) {
1490 if (DestOffset-BrOffset <= MaxDisp)
1493 if (BrOffset-DestOffset <= MaxDisp)
1501 bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1507 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1511 return fixupUnconditionalBr(Br);
1512 return fixupConditionalBr(Br);
1520 MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1525 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1526 if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
1527 Br.MaxDisp = BimmX16MaxDisp;
1543 Br.MaxDisp = ((1<<24)-1) * 2;
1547 adjustBBOffsetsAfter(MBB);
1551 DEBUG(
dbgs() <<
" Changed B to long jump " << *MI);
1561 MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1570 if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
1571 Br.MaxDisp = LongFormMaxOff;
1590 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1606 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1607 DEBUG(
dbgs() <<
" Invert Bcc condition and swap its destination with "
1619 splitBlockBeforeInstr(*MI);
1622 int delta =
TII->getInstSizeInBytes(MBB->
back());
1630 <<
" also invert condition and change dest. to BB#"
1643 Br.MI = &MBB->
back();
1648 ImmBranches.push_back(ImmBranch(&MBB->
back(), MaxDisp,
false, Br.UncondBr));
1653 adjustBBOffsetsAfter(MBB);
1658 void MipsConstantIslands::prescanForConstants() {
1662 MF->begin(),
E = MF->end();
B !=
E; ++
B) {
1664 B->instr_begin(), EB =
B->instr_end();
I != EB; ++
I) {
1665 switch(
I->getDesc().getOpcode()) {
1666 case Mips::LwConstant32: {
1667 PrescannedForConstants =
true;
1668 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1669 J =
I->getNumOperands();
1670 DEBUG(
dbgs() <<
"num operands " << J <<
"\n");
1672 if (Literal.
isImm()) {
1673 int64_t V = Literal.
getImm();
1674 DEBUG(
dbgs() <<
"literal " << V <<
"\n");
1678 unsigned index = MCP->getConstantPoolIndex(C, 4);
1679 I->getOperand(2).ChangeToImmediate(index);
1680 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1681 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1682 I->RemoveOperand(1);
1683 I->RemoveOperand(1);
unsigned succ_size() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
A parsed version of the target data layout string in and methods for querying it. ...
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
static unsigned int branchTargetOperand(MachineInstr *MI)
static bool CompareMBBNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)
CompareMBBNumbers - Little predicate function to sort the WaterList by MBB ID.
STATISTIC(NumFunctions,"Total number of functions")
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them...
MachineBasicBlock * getMBB() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block...
static unsigned int branchMaxOffsets(unsigned int Opcode)
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB, BasicBlockInfo &BBI)
void setAlignment(unsigned Align)
Set alignment of the basic block.
BasicBlockInfo - Information about the offset and size of a single basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
std::vector< MachineBasicBlock * >::iterator succ_iterator
static cl::opt< bool > AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code"))
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
Function Alias Analysis false
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
static cl::opt< int > ConstantIslandsSmallOffset("mips-constant-islands-small-offset", cl::init(0), cl::desc("Make small offsets be this amount for testing purposes"), cl::Hidden)
static cl::opt< bool > NoLoadRelaxation("mips-constant-islands-no-load-relaxation", cl::init(false), cl::desc("Don't relax loads to long loads - for testing purposes"), cl::Hidden)
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)
static unsigned int longformBranchOpcode(unsigned int Opcode)
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned char TargetFlags=0)
The instances of the Type class are immutable: once they are created, they are never changed...
static bool BBIsJumpedOver(MachineBasicBlock *MBB)
BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...
This is an important base class in LLVM.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
void setMBB(MachineBasicBlock *MBB)
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
void neg(uint64_t &Value)
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createMipsConstantIslandPass()
Returns a pass that converts branches to long branches.
self_iterator getIterator()
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
succ_iterator succ_begin()
pred_iterator pred_begin()
static unsigned getUnconditionalBrDisp(int Opc)
getUnconditionalBrDisp - Returns the maximum displacement that can fit in the specific unconditional ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool useConstantIslands()
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
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...
unsigned Size
Size - Size of the basic block in bytes.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
static IntegerType * getInt32Ty(LLVMContext &C)
static bool BBHasFallthrough(MachineBasicBlock *MBB)
BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
static MachineOperand CreateImm(int64_t Val)
void push_back(MachineInstr *MI)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
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.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
StringRef - Represent a constant reference to a string, i.e.
unsigned pred_size() const
Properties which a MachineFunction may have at a given point in time.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...
unsigned postOffset(unsigned LogAlign=0) const
Compute the offset immediately following this block.
unsigned getAlignment() const
Return alignment of the basic block.