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:
102 default:
return false;
114 return Mips::BimmX16;
117 return Mips::BteqzX16;
120 return Mips::BtnezX16;
123 case Mips::BeqzRxImm16:
124 case Mips::BeqzRxImmX16:
125 return Mips::BeqzRxImmX16;
126 case Mips::BnezRxImm16:
127 case Mips::BnezRxImmX16:
128 return Mips::BnezRxImmX16;
140 unsigned Bits, Scale;
150 case Mips::BeqzRxImm16:
154 case Mips::BeqzRxImmX16:
158 case Mips::BnezRxImm16:
162 case Mips::BnezRxImmX16:
185 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
211 struct BasicBlockInfo {
232 unsigned postOffset(
unsigned LogAlign = 0)
const {
233 unsigned PO = Offset + Size;
237 BasicBlockInfo() : Offset(0), Size(0) {}
241 std::vector<BasicBlockInfo> BBInfo;
246 std::vector<MachineBasicBlock*> WaterList;
252 typedef std::vector<MachineBasicBlock*>::iterator water_iterator;
272 unsigned LongFormMaxDisp;
274 unsigned LongFormOpcode;
279 unsigned longformmaxdisp,
unsigned longformopcode)
280 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
281 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
283 HighWaterMark = CPEMI->getParent();
286 unsigned getMaxDisp()
const {
291 void setMaxDisp(
unsigned val) {
294 unsigned getLongFormMaxDisp()
const {
295 return LongFormMaxDisp;
297 unsigned getLongFormOpcode()
const {
298 return LongFormOpcode;
304 std::vector<CPUser> CPUsers;
314 : CPEMI(cpemi), CPI(cpi), RefCount(
rc) {}
322 std::vector<std::vector<CPEntry> > CPEntries;
330 unsigned MaxDisp : 31;
333 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
334 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
339 std::vector<ImmBranch> ImmBranches;
353 unsigned PICLabelUId;
354 bool PrescannedForConstants;
356 void initPICLabelUId(
unsigned UId) {
361 unsigned createPICLabelUId() {
362 return PICLabelUId++;
369 IsPIC(
TM.getRelocationModel() == Reloc::
PIC_), STI(nullptr),
370 MF(nullptr), MCP(nullptr), PrescannedForConstants(
false) {}
372 const char *getPassName()
const override {
373 return "Mips Constant Islands";
378 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
379 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
381 void initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs);
383 unsigned getUserOffset(CPUser&)
const;
386 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
387 unsigned Disp,
bool NegativeOK);
388 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
395 bool decrementCPEReferenceCount(
unsigned CPI,
MachineInstr* CPEMI);
396 int findInRangeCPEntry(CPUser& U,
unsigned UserOffset);
397 int findLongFormInRangeCPEntry(CPUser& U,
unsigned UserOffset);
398 bool findAvailableWater(CPUser&U,
unsigned UserOffset,
399 water_iterator &WaterIter);
400 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
402 bool handleConstantPoolUser(
unsigned CPUserIndex);
404 bool removeUnusedCPEntries();
407 bool DoDump =
false);
409 CPUser &U,
unsigned &Growth);
411 bool fixupImmediateBr(ImmBranch &Br);
412 bool fixupConditionalBr(ImmBranch &Br);
413 bool fixupUnconditionalBr(ImmBranch &Br);
415 void prescanForConstants();
424 bool MipsConstantIslands::isOffsetInRange
425 (
unsigned UserOffset,
unsigned TrialOffset,
427 return isOffsetInRange(UserOffset, TrialOffset,
428 U.getMaxDisp(), U.NegOk);
431 void MipsConstantIslands::dumpBBs() {
433 for (
unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
434 const BasicBlockInfo &BBI = BBInfo[J];
435 dbgs() <<
format(
"%08x BB#%u\t", BBI.Offset, J)
436 <<
format(
" size=%#x\n", BBInfo[J].Size);
443 return new MipsConstantIslands(tm);
452 DEBUG(
dbgs() <<
"constant island machine function " <<
"\n");
458 DEBUG(
dbgs() <<
"constant island processing " <<
"\n");
463 if (!PrescannedForConstants) prescanForConstants();
467 MF->getRegInfo().invalidateLiveness();
471 MF->RenumberBlocks();
473 bool MadeChange =
false;
477 std::vector<MachineInstr*> CPEMIs;
479 doInitialPlacement(CPEMIs);
482 initPICLabelUId(CPEMIs.size());
487 initializeFunctionInfo(CPEMIs);
492 MadeChange |= removeUnusedCPEntries();
496 unsigned NoCPIters = 0, NoBRIters = 0;
499 DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
500 bool CPChange =
false;
501 for (
unsigned i = 0, e = CPUsers.size(); i != e; ++i)
502 CPChange |= handleConstantPoolUser(i);
503 if (CPChange && ++NoCPIters > 30)
509 NewWaterList.clear();
511 DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
512 bool BRChange =
false;
513 for (
unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
514 BRChange |= fixupImmediateBr(ImmBranches[i]);
515 if (BRChange && ++NoBRIters > 30)
518 if (!CPChange && !BRChange)
536 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
543 unsigned MaxAlign =
Log2_32(MCP->getConstantPoolAlignment());
561 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
563 const DataLayout &TD = *MF->getTarget().getDataLayout();
564 for (
unsigned i = 0, e = CPs.
size(); i != e; ++i) {
566 assert(Size >= 4 &&
"Too small constant pool entry");
567 unsigned Align = CPs[i].getAlignment();
571 assert((Size % Align) == 0 &&
"CP Entry not multiple of 4 bytes!");
574 unsigned LogAlign =
Log2_32(Align);
581 CPEMIs.push_back(CPEMI);
585 for (
unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
586 if (InsPoint[a] == InsAt)
589 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
591 DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = "
592 << Size <<
", align = " << Align <<
'\n');
617 MipsConstantIslands::CPEntry
618 *MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
620 std::vector<CPEntry> &CPEs = CPEntries[CPI];
623 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
624 if (CPEs[i].CPEMI == CPEMI)
632 unsigned MipsConstantIslands::getCPELogAlign(
const MachineInstr *CPEMI) {
633 assert(CPEMI && CPEMI->
getOpcode() == Mips::CONSTPOOL_ENTRY);
640 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
641 unsigned Align = MCP->getConstants()[CPI].getAlignment();
649 void MipsConstantIslands::
650 initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
652 BBInfo.resize(MF->getNumBlockIDs());
663 adjustBBOffsetsAfter(MF->begin());
676 if (
I->isDebugValue())
679 int Opc =
I->getOpcode();
698 case Mips::BeqzRxImm16:
704 case Mips::BeqzRxImmX16:
710 case Mips::BnezRxImm16:
716 case Mips::BnezRxImmX16:
748 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
749 ImmBranches.push_back(ImmBranch(
I, MaxOffs, isCond, UOpc));
752 if (Opc == Mips::CONSTPOOL_ENTRY)
757 for (
unsigned op = 0, e =
I->getNumOperands();
op != e; ++
op)
758 if (
I->getOperand(
op).isCPI()) {
767 unsigned LongFormBits = 0;
768 unsigned LongFormScale = 0;
769 unsigned LongFormOpcode = 0;
773 case Mips::LwRxPcTcp16:
776 LongFormOpcode = Mips::LwRxPcTcpX16;
780 case Mips::LwRxPcTcpX16:
787 unsigned CPI =
I->getOperand(
op).getIndex();
789 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
790 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
791 CPUsers.push_back(CPUser(
I, CPEMI, MaxOffs, NegOk,
792 LongFormMaxOffs, LongFormOpcode));
795 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
796 assert(CPE &&
"Cannot find a corresponding CPEntry!");
813 BasicBlockInfo &BBI = BBInfo[MBB->
getNumber()];
818 BBI.Size +=
TII->GetInstSizeInBytes(
I);
825 unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
831 unsigned Offset = BBInfo[MBB->
getNumber()].Offset;
835 assert(
I != MBB->
end() &&
"Didn't find MI in its own basic block?");
836 Offset +=
TII->GetInstSizeInBytes(
I);
851 void MipsConstantIslands::updateForInsertedWaterBlock
858 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
863 std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,
865 WaterList.insert(IP, NewBB);
868 unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
869 return getOffsetOf(U.MI);
904 MF->RenumberBlocks(NewBB);
908 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
915 std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB,
918 if (WaterBB == OrigBB)
919 WaterList.
insert(std::next(IP), NewBB);
921 WaterList.insert(IP, OrigBB);
922 NewWaterList.insert(OrigBB);
929 computeBlockSize(OrigBB);
933 computeBlockSize(NewBB);
936 adjustBBOffsetsAfter(OrigBB);
946 bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
947 unsigned TrialOffset,
unsigned MaxDisp,
949 if (UserOffset <= TrialOffset) {
951 if (TrialOffset - UserOffset <= MaxDisp)
953 }
else if (NegativeOK) {
954 if (UserOffset - TrialOffset <= MaxDisp)
964 bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
967 unsigned CPELogAlign = getCPELogAlign(U.CPEMI);
968 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset(CPELogAlign);
969 unsigned NextBlockOffset, NextBlockAlignment;
971 if (++NextBlock == MF->end()) {
972 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
973 NextBlockAlignment = 0;
975 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
976 NextBlockAlignment = NextBlock->getAlignment();
978 unsigned Size = U.CPEMI->getOperand(2).getImm();
979 unsigned CPEEnd = CPEOffset + Size;
984 if (CPEEnd > NextBlockOffset) {
985 Growth = CPEEnd - NextBlockOffset;
993 if (CPEOffset < UserOffset)
994 UserOffset += Growth;
999 return isOffsetInRange(UserOffset, CPEOffset, U);
1004 bool MipsConstantIslands::isCPEntryInRange
1007 bool NegOk,
bool DoDump) {
1008 unsigned CPEOffset = getOffsetOf(CPEMI);
1013 const BasicBlockInfo &BBI = BBInfo[Block];
1015 <<
" max delta=" << MaxDisp
1016 <<
format(
" insn address=%#x", UserOffset)
1017 <<
" in BB#" << Block <<
": "
1018 <<
format(
"%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
1019 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
1020 int(CPEOffset-UserOffset));
1024 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1036 if (PredMI->
getOpcode() == Mips::Bimm16)
1044 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
1047 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1048 BBInfo[i].Offset = Offset;
1057 bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1060 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1061 assert(CPE &&
"Unexpected!");
1062 if (--CPE->RefCount == 0) {
1063 removeDeadCPEMI(CPEMI);
1064 CPE->CPEMI =
nullptr;
1077 int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1083 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
1091 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1092 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1094 if (CPEs[i].CPEMI == CPEMI)
1097 if (CPEs[i].CPEMI ==
nullptr)
1099 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
1101 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
1102 << CPEs[i].CPI <<
"\n");
1104 U.CPEMI = CPEs[i].CPEMI;
1115 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1129 int MipsConstantIslands::findLongFormInRangeCPEntry
1130 (CPUser& U,
unsigned UserOffset)
1136 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1137 U.getLongFormMaxDisp(), U.NegOk,
1140 UserMI->
setDesc(
TII->get(U.getLongFormOpcode()));
1141 U.setMaxDisp(U.getLongFormMaxDisp());
1147 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1148 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1150 if (CPEs[i].CPEMI == CPEMI)
1153 if (CPEs[i].CPEMI ==
nullptr)
1155 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1156 U.getLongFormMaxDisp(), U.NegOk)) {
1157 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
1158 << CPEs[i].CPI <<
"\n");
1160 U.CPEMI = CPEs[i].CPEMI;
1171 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1182 return ((1<<10)-1)*2;
1184 return ((1<<16)-1)*2;
1188 return ((1<<16)-1)*2;
1199 bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1200 water_iterator &WaterIter) {
1201 if (WaterList.empty())
1204 unsigned BestGrowth = ~0u;
1205 for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();;
1217 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1218 (WaterBB->
getNumber() < U.HighWaterMark->getNumber() ||
1219 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1221 BestGrowth = Growth;
1224 <<
" Growth=" << Growth <<
'\n');
1227 if (BestGrowth == 0)
1233 return BestGrowth != ~0u;
1243 void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1244 unsigned UserOffset,
1246 CPUser &U = CPUsers[CPUserIndex];
1249 unsigned CPELogAlign = getCPELogAlign(CPEMI);
1251 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->
getNumber()];
1259 unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;
1261 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1263 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1270 int UncondBr = Mips::Bimm16;
1273 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1274 MaxDisp,
false, UncondBr));
1275 BBInfo[UserMBB->
getNumber()].Size += Delta;
1276 adjustBBOffsetsAfter(UserMBB);
1286 unsigned LogAlign = MF->getAlignment();
1287 assert(LogAlign >= CPELogAlign &&
"Over-aligned constant pool entry");
1288 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1295 BaseInsertOffset -= 4;
1298 <<
" la=" << LogAlign <<
'\n');
1304 if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
1305 BaseInsertOffset = UserBBI.postOffset() - 8;
1306 DEBUG(
dbgs() <<
format(
"Move inside block: %#x\n", BaseInsertOffset));
1308 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1312 unsigned CPUIndex = CPUserIndex+1;
1313 unsigned NumCPUsers = CPUsers.size();
1315 for (
unsigned Offset = UserOffset+
TII->GetInstSizeInBytes(UserMI);
1316 Offset < BaseInsertOffset;
1317 Offset +=
TII->GetInstSizeInBytes(MI), MI = std::next(MI)) {
1318 assert(MI != UserMBB->
end() &&
"Fell off end of block");
1319 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1320 CPUser &U = CPUsers[CPUIndex];
1321 if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
1323 BaseInsertOffset -= 1u << LogAlign;
1324 EndInsertOffset -= 1u << LogAlign;
1330 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1336 NewMBB = splitBlockBeforeInstr(MI);
1343 bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1344 CPUser &U = CPUsers[CPUserIndex];
1350 unsigned UserOffset = getUserOffset(U);
1354 int result = findInRangeCPEntry(U, UserOffset);
1355 if (result==1)
return false;
1356 else if (result==2)
return true;
1363 if (findAvailableWater(U, UserOffset, IP)) {
1364 DEBUG(
dbgs() <<
"Found water in range\n");
1370 if (NewWaterList.erase(WaterBB))
1371 NewWaterList.
insert(NewIsland);
1381 result = findLongFormInRangeCPEntry(U, UserOffset);
1382 if (result != 0)
return true;
1385 createNewWater(CPUserIndex, UserOffset, NewMBB);
1393 IP = std::find(WaterList.begin(), WaterList.end(), WaterBB);
1394 if (IP != WaterList.end())
1395 NewWaterList.erase(WaterBB);
1398 NewWaterList.insert(NewIsland);
1405 if (IP != WaterList.end())
1406 WaterList.erase(IP);
1409 MF->insert(NewMBB, NewIsland);
1412 updateForInsertedWaterBlock(NewIsland);
1415 decrementCPEReferenceCount(CPI, CPEMI);
1419 unsigned ID = createPICLabelUId();
1423 U.HighWaterMark = NewIsland;
1426 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1433 BBInfo[NewIsland->
getNumber()].Size += Size;
1445 DEBUG(
dbgs() <<
" Moved CPE to #" << ID <<
" CPI=" << CPI
1453 void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1457 BBInfo[CPEBB->
getNumber()].Size -= Size;
1459 if (CPEBB->
empty()) {
1468 adjustBBOffsetsAfter(CPEBB);
1478 bool MipsConstantIslands::removeUnusedCPEntries() {
1479 unsigned MadeChange =
false;
1480 for (
unsigned i = 0, e = CPEntries.size(); i != e; ++i) {
1481 std::vector<CPEntry> &CPEs = CPEntries[i];
1482 for (
unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1483 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1484 removeDeadCPEMI(CPEs[j].CPEMI);
1485 CPEs[j].CPEMI =
nullptr;
1495 bool MipsConstantIslands::isBBInRange
1500 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
1501 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1505 <<
" max delta=" << MaxDisp
1506 <<
" from " << getOffsetOf(MI) <<
" to " << DestOffset
1507 <<
" offset " <<
int(DestOffset-BrOffset) <<
"\t" << *
MI);
1509 if (BrOffset <= DestOffset) {
1511 if (DestOffset-BrOffset <= MaxDisp)
1514 if (BrOffset-DestOffset <= MaxDisp)
1522 bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1528 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1532 return fixupUnconditionalBr(Br);
1533 return fixupConditionalBr(Br);
1541 MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1546 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1547 if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
1548 Br.MaxDisp = BimmX16MaxDisp;
1564 Br.MaxDisp = ((1<<24)-1) * 2;
1568 adjustBBOffsetsAfter(MBB);
1572 DEBUG(
dbgs() <<
" Changed B to long jump " << *MI);
1582 MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1591 if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
1592 Br.MaxDisp = LongFormMaxOff;
1611 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1627 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1628 DEBUG(
dbgs() <<
" Invert Bcc condition and swap its destination with "
1640 splitBlockBeforeInstr(MI);
1643 int delta =
TII->GetInstSizeInBytes(&MBB->
back());
1651 <<
" also invert condition and change dest. to BB#"
1664 Br.MI = &MBB->
back();
1669 ImmBranches.push_back(ImmBranch(&MBB->
back(), MaxDisp,
false, Br.UncondBr));
1674 adjustBBOffsetsAfter(MBB);
1679 void MipsConstantIslands::prescanForConstants() {
1683 MF->begin(), E = MF->end(); B != E; ++B) {
1685 B->instr_begin(), EB = B->instr_end();
I != EB; ++
I) {
1686 switch(
I->getDesc().getOpcode()) {
1687 case Mips::LwConstant32: {
1688 PrescannedForConstants =
true;
1689 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1690 J =
I->getNumOperands();
1691 DEBUG(
dbgs() <<
"num operands " << J <<
"\n");
1693 if (Literal.
isImm()) {
1694 int64_t V = Literal.
getImm();
1695 DEBUG(
dbgs() <<
"literal " << V <<
"\n");
1699 unsigned index = MCP->getConstantPoolIndex(C, 4);
1700 I->getOperand(2).ChangeToImmediate(index);
1701 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1702 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1703 I->RemoveOperand(1);
1704 I->RemoveOperand(1);
unsigned succ_size() const
const MachineFunction * getParent() const
getParent - 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 isUnconditionalBranch(unsigned int Opcode)
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")
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them...
MachineBasicBlock * getMBB() const
int getNumber() const
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
static unsigned int branchMaxOffsets(unsigned int Opcode)
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Instructions::iterator instr_iterator
void setAlignment(unsigned Align)
setAlignment - Set alignment of the basic block.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static bool BBHasFallthrough(MachineBasicBlock *MBB)
BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...
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
addImm - 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.
void transferSuccessors(MachineBasicBlock *fromMBB)
transferSuccessors - Transfers all the successors from MBB to this machine basic block (i...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
getBasicBlock - Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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)
bundle_iterator< MachineInstr, instr_iterator > iterator
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)
initializer< Ty > init(const Ty &Val)
static unsigned int longformBranchOpcode(unsigned int Opcode)
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.
FunctionPass class - This class is used to implement most global optimizations.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
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 ...
static bool useConstantIslands()
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
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...
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 cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
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...
Representation of each machine instruction.
FunctionPass * createMipsConstantIslandPass(MipsTargetMachine &tm)
createMipsLongBranchPass - Returns a pass that converts branches to long branches.
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)
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
static MachineOperand CreateImm(int64_t Val)
void push_back(MachineInstr *MI)
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
unsigned getReg() const
getReg - Returns the register number.
std::reverse_iterator< iterator > reverse_iterator
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...
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.
C - The default llvm calling convention, compatible with C.
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.
unsigned pred_size() const
unsigned getAlignment() const
getAlignment - Return alignment of the basic block.