39 #include "llvm/Config/llvm-config.h" 60 #define DEBUG_TYPE "mips-constant-islands" 62 STATISTIC(NumCPEs,
"Number of constpool entries");
63 STATISTIC(NumSplit,
"Number of uncond branches inserted");
64 STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
65 STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
70 cl::desc(
"Align constant islands in code"));
75 "mips-constant-islands-small-offset",
77 cl::desc(
"Make small offsets be this amount for testing purposes"),
83 "mips-constant-islands-no-load-relaxation",
85 cl::desc(
"Don't relax loads to long loads - for testing purposes"),
98 case Mips::BeqzRxImm16:
99 case Mips::BeqzRxImmX16:
100 case Mips::BnezRxImm16:
101 case Mips::BnezRxImmX16:
111 return Mips::BimmX16;
114 return Mips::BteqzX16;
117 return Mips::BtnezX16;
120 case Mips::BeqzRxImm16:
121 case Mips::BeqzRxImmX16:
122 return Mips::BeqzRxImmX16;
123 case Mips::BnezRxImm16:
124 case Mips::BnezRxImmX16:
125 return Mips::BnezRxImmX16;
135 unsigned Bits, Scale;
145 case Mips::BeqzRxImm16:
149 case Mips::BeqzRxImmX16:
153 case Mips::BnezRxImm16:
157 case Mips::BnezRxImmX16:
180 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
225 unsigned postOffset()
const {
return Offset +
Size; }
228 std::vector<BasicBlockInfo> BBInfo;
233 std::vector<MachineBasicBlock*> WaterList;
239 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
260 unsigned LongFormMaxDisp;
262 unsigned LongFormOpcode;
269 unsigned longformmaxdisp,
unsigned longformopcode)
270 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
271 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
277 unsigned getMaxDisp()
const {
283 void setMaxDisp(
unsigned val) {
287 unsigned getLongFormMaxDisp()
const {
288 return LongFormMaxDisp;
291 unsigned getLongFormOpcode()
const {
292 return LongFormOpcode;
298 std::vector<CPUser> CPUsers;
309 : CPEMI(cpemi), CPI(cpi), RefCount(
rc) {}
317 std::vector<std::vector<CPEntry>> CPEntries;
325 unsigned MaxDisp : 31;
329 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
330 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
335 std::vector<ImmBranch> ImmBranches;
347 unsigned PICLabelUId;
348 bool PrescannedForConstants =
false;
350 void initPICLabelUId(
unsigned UId) {
354 unsigned createPICLabelUId() {
355 return PICLabelUId++;
363 StringRef getPassName()
const override {
return "Mips Constant Islands"; }
372 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
373 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
375 void initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs);
377 unsigned getUserOffset(CPUser&)
const;
380 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
381 unsigned Disp,
bool NegativeOK);
382 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
389 bool decrementCPEReferenceCount(
unsigned CPI,
MachineInstr* CPEMI);
390 int findInRangeCPEntry(CPUser& U,
unsigned UserOffset);
391 int findLongFormInRangeCPEntry(CPUser& U,
unsigned UserOffset);
392 bool findAvailableWater(CPUser&U,
unsigned UserOffset,
393 water_iterator &WaterIter);
394 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
396 bool handleConstantPoolUser(
unsigned CPUserIndex);
398 bool removeUnusedCPEntries();
399 bool isCPEntryInRange(
MachineInstr *MI,
unsigned UserOffset,
401 bool DoDump =
false);
403 CPUser &U,
unsigned &Growth);
405 bool fixupImmediateBr(ImmBranch &Br);
406 bool fixupConditionalBr(ImmBranch &Br);
407 bool fixupUnconditionalBr(ImmBranch &Br);
409 void prescanForConstants();
416 bool MipsConstantIslands::isOffsetInRange
417 (
unsigned UserOffset,
unsigned TrialOffset,
419 return isOffsetInRange(UserOffset, TrialOffset,
420 U.getMaxDisp(), U.NegOk);
423 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 426 for (
unsigned J = 0,
E = BBInfo.size(); J !=
E; ++J) {
453 if (!PrescannedForConstants) prescanForConstants();
457 MF->getRegInfo().invalidateLiveness();
461 MF->RenumberBlocks();
463 bool MadeChange =
false;
467 std::vector<MachineInstr*> CPEMIs;
469 doInitialPlacement(CPEMIs);
472 initPICLabelUId(CPEMIs.size());
477 initializeFunctionInfo(CPEMIs);
482 MadeChange |= removeUnusedCPEntries();
486 unsigned NoCPIters = 0, NoBRIters = 0;
489 LLVM_DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
490 bool CPChange =
false;
491 for (
unsigned i = 0,
e = CPUsers.size(); i !=
e; ++i)
492 CPChange |= handleConstantPoolUser(i);
493 if (CPChange && ++NoCPIters > 30)
499 NewWaterList.clear();
501 LLVM_DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
502 bool BRChange =
false;
503 for (
unsigned i = 0,
e = ImmBranches.size(); i !=
e; ++i)
504 BRChange |= fixupImmediateBr(ImmBranches[i]);
505 if (BRChange && ++NoBRIters > 30)
508 if (!CPChange && !BRChange)
526 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
532 const Align MaxAlign(MCP->getConstantPoolAlignment());
551 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
554 for (
unsigned i = 0,
e = CPs.
size(); i !=
e; ++i) {
556 assert(Size >= 4 &&
"Too small constant pool entry");
557 unsigned Align = CPs[i].getAlignment();
561 assert((Size % Align) == 0 &&
"CP Entry not multiple of 4 bytes!");
564 unsigned LogAlign =
Log2_32(Align);
571 CPEMIs.push_back(CPEMI);
575 for (
unsigned a = LogAlign + 1; a <=
Log2(MaxAlign); ++a)
576 if (InsPoint[a] == InsAt)
579 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
581 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = " 582 << Size <<
", align = " << Align <<
'\n');
607 MipsConstantIslands::CPEntry
608 *MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
610 std::vector<CPEntry> &CPEs = CPEntries[CPI];
613 for (
unsigned i = 0,
e = CPEs.size(); i !=
e; ++i) {
614 if (CPEs[i].CPEMI == CPEMI)
630 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
631 return Align(MCP->getConstants()[CPI].getAlignment());
637 void MipsConstantIslands::
638 initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
640 BBInfo.resize(MF->getNumBlockIDs());
647 computeBlockSize(&*
I);
650 adjustBBOffsetsAfter(&MF->front());
657 WaterList.push_back(&MBB);
659 if (
MI.isDebugInstr())
662 int Opc =
MI.getOpcode();
681 case Mips::BeqzRxImm16:
687 case Mips::BeqzRxImmX16:
693 case Mips::BnezRxImm16:
699 case Mips::BnezRxImmX16:
731 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
732 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, isCond, UOpc));
735 if (Opc == Mips::CONSTPOOL_ENTRY)
739 for (
unsigned op = 0,
e =
MI.getNumOperands();
op !=
e; ++
op)
740 if (
MI.getOperand(
op).isCPI()) {
748 unsigned LongFormBits = 0;
749 unsigned LongFormScale = 0;
750 unsigned LongFormOpcode = 0;
754 case Mips::LwRxPcTcp16:
757 LongFormOpcode = Mips::LwRxPcTcpX16;
761 case Mips::LwRxPcTcpX16:
768 unsigned CPI =
MI.getOperand(
op).getIndex();
770 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
771 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
772 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
776 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
777 assert(CPE &&
"Cannot find a corresponding CPEntry!");
801 unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
811 assert(
I != MBB->
end() &&
"Didn't find MI in its own basic block?");
812 Offset +=
TII->getInstSizeInBytes(*
I);
827 void MipsConstantIslands::updateForInsertedWaterBlock
839 WaterList.insert(IP, NewBB);
842 unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
843 return getOffsetOf(U.MI);
850 MipsConstantIslands::splitBlockBeforeInstr(
MachineInstr &MI) {
857 MF->insert(MBBI, NewBB);
878 MF->RenumberBlocks(NewBB);
890 if (WaterBB == OrigBB)
891 WaterList.
insert(std::next(IP), NewBB);
893 WaterList.insert(IP, OrigBB);
894 NewWaterList.insert(OrigBB);
901 computeBlockSize(OrigBB);
905 computeBlockSize(NewBB);
908 adjustBBOffsetsAfter(OrigBB);
916 bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
917 unsigned TrialOffset,
unsigned MaxDisp,
919 if (UserOffset <= TrialOffset) {
921 if (TrialOffset - UserOffset <= MaxDisp)
923 }
else if (NegativeOK) {
924 if (UserOffset - TrialOffset <= MaxDisp)
934 bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
937 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset();
938 unsigned NextBlockOffset;
939 Align NextBlockAlignment;
941 if (NextBlock == MF->end()) {
942 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
945 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
946 NextBlockAlignment = NextBlock->getAlignment();
948 unsigned Size = U.CPEMI->getOperand(2).getImm();
949 unsigned CPEEnd = CPEOffset +
Size;
954 if (CPEEnd > NextBlockOffset) {
955 Growth = CPEEnd - NextBlockOffset;
963 if (CPEOffset < UserOffset)
964 UserOffset += Growth;
969 return isOffsetInRange(UserOffset, CPEOffset, U);
974 bool MipsConstantIslands::isCPEntryInRange
977 bool NegOk,
bool DoDump) {
978 unsigned CPEOffset = getOffsetOf(CPEMI);
985 <<
" max delta=" << MaxDisp
986 <<
format(
" insn address=%#x", UserOffset) <<
" in " 989 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
990 int(CPEOffset - UserOffset));
994 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1006 if (PredMI->
getOpcode() == Mips::Bimm16)
1014 for(
unsigned i = BBNum + 1,
e = MF->getNumBlockIDs(); i <
e; ++i) {
1017 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1018 BBInfo[i].Offset =
Offset;
1026 bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1029 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1030 assert(CPE &&
"Unexpected!");
1031 if (--CPE->RefCount == 0) {
1032 removeDeadCPEMI(CPEMI);
1033 CPE->CPEMI =
nullptr;
1046 int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1052 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
1060 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1061 for (
unsigned i = 0,
e = CPEs.size(); i !=
e; ++i) {
1063 if (CPEs[i].CPEMI == CPEMI)
1066 if (CPEs[i].CPEMI ==
nullptr)
1068 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
1071 << CPEs[i].CPI <<
"\n");
1073 U.CPEMI = CPEs[i].CPEMI;
1084 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1098 int MipsConstantIslands::findLongFormInRangeCPEntry
1099 (CPUser& U,
unsigned UserOffset)
1105 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1106 U.getLongFormMaxDisp(), U.NegOk,
1109 UserMI->
setDesc(
TII->get(U.getLongFormOpcode()));
1110 U.setMaxDisp(U.getLongFormMaxDisp());
1116 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1117 for (
unsigned i = 0,
e = CPEs.size(); i !=
e; ++i) {
1119 if (CPEs[i].CPEMI == CPEMI)
1122 if (CPEs[i].CPEMI ==
nullptr)
1124 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1125 U.getLongFormMaxDisp(), U.NegOk)) {
1127 << CPEs[i].CPI <<
"\n");
1129 U.CPEMI = CPEs[i].CPEMI;
1140 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1151 return ((1<<10)-1)*2;
1153 return ((1<<16)-1)*2;
1157 return ((1<<16)-1)*2;
1168 bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1169 water_iterator &WaterIter) {
1170 if (WaterList.empty())
1173 unsigned BestGrowth = ~0u;
1174 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
1186 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1187 (WaterBB->
getNumber() < U.HighWaterMark->getNumber() ||
1188 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1190 BestGrowth = Growth;
1193 <<
" Growth=" << Growth <<
'\n');
1196 if (BestGrowth == 0)
1202 return BestGrowth != ~0u;
1212 void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1213 unsigned UserOffset,
1215 CPUser &U = CPUsers[CPUserIndex];
1227 unsigned CPEOffset = UserBBI.
postOffset() + Delta;
1229 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1231 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1238 int UncondBr = Mips::Bimm16;
1241 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1242 MaxDisp,
false, UncondBr));
1243 BBInfo[UserMBB->
getNumber()].Size += Delta;
1244 adjustBBOffsetsAfter(UserMBB);
1255 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1262 BaseInsertOffset -= 4;
1265 <<
" la=" <<
Log2(Align) <<
'\n');
1271 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1275 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1279 unsigned CPUIndex = CPUserIndex+1;
1280 unsigned NumCPUsers = CPUsers.size();
1282 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1283 Offset < BaseInsertOffset;
1284 Offset +=
TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
1285 assert(MI != UserMBB->
end() &&
"Fell off end of block");
1286 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1287 CPUser &U = CPUsers[CPUIndex];
1288 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1290 BaseInsertOffset -= Align.
value();
1291 EndInsertOffset -= Align.
value();
1297 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1302 NewMBB = splitBlockBeforeInstr(*--MI);
1309 bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1310 CPUser &U = CPUsers[CPUserIndex];
1316 unsigned UserOffset = getUserOffset(U);
1320 int result = findInRangeCPEntry(U, UserOffset);
1321 if (result==1)
return false;
1322 else if (result==2)
return true;
1328 if (findAvailableWater(U, UserOffset, IP)) {
1335 if (NewWaterList.erase(WaterBB))
1336 NewWaterList.
insert(NewIsland);
1345 result = findLongFormInRangeCPEntry(U, UserOffset);
1346 if (result != 0)
return true;
1349 createNewWater(CPUserIndex, UserOffset, NewMBB);
1358 if (IP != WaterList.end())
1359 NewWaterList.erase(WaterBB);
1362 NewWaterList.insert(NewIsland);
1369 if (IP != WaterList.end())
1370 WaterList.erase(IP);
1376 updateForInsertedWaterBlock(NewIsland);
1379 decrementCPEReferenceCount(CPI, CPEMI);
1383 unsigned ID = createPICLabelUId();
1387 U.HighWaterMark = NewIsland;
1390 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1398 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1408 dbgs() <<
" Moved CPE to #" << ID <<
" CPI=" << CPI
1416 void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1422 if (CPEBB->
empty()) {
1432 adjustBBOffsetsAfter(CPEBB);
1442 bool MipsConstantIslands::removeUnusedCPEntries() {
1443 unsigned MadeChange =
false;
1444 for (
unsigned i = 0,
e = CPEntries.size(); i !=
e; ++i) {
1445 std::vector<CPEntry> &CPEs = CPEntries[i];
1446 for (
unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1447 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1448 removeDeadCPEMI(CPEs[j].CPEMI);
1449 CPEs[j].CPEMI =
nullptr;
1459 bool MipsConstantIslands::isBBInRange
1462 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
1463 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1467 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(MI)
1468 <<
" to " << DestOffset <<
" offset " 1469 << int(DestOffset - BrOffset) <<
"\t" << *
MI);
1471 if (BrOffset <= DestOffset) {
1473 if (DestOffset-BrOffset <= MaxDisp)
1476 if (BrOffset-DestOffset <= MaxDisp)
1484 bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1490 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1494 return fixupUnconditionalBr(Br);
1495 return fixupConditionalBr(Br);
1503 MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1508 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1509 if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
1510 Br.MaxDisp = BimmX16MaxDisp;
1526 Br.MaxDisp = ((1<<24)-1) * 2;
1530 adjustBBOffsetsAfter(MBB);
1543 MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1552 if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
1553 Br.MaxDisp = LongFormMaxOff;
1572 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1588 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1590 dbgs() <<
" Invert Bcc condition and swap its destination with " 1601 splitBlockBeforeInstr(*MI);
1604 int delta =
TII->getInstSizeInBytes(MBB->
back());
1612 <<
" also invert condition and change dest. to " 1625 Br.MI = &MBB->
back();
1630 ImmBranches.push_back(ImmBranch(&MBB->
back(), MaxDisp,
false, Br.UncondBr));
1635 adjustBBOffsetsAfter(MBB);
1639 void MipsConstantIslands::prescanForConstants() {
1643 MF->begin(),
E = MF->end();
B !=
E; ++
B) {
1645 B->instr_begin(), EB =
B->instr_end();
I != EB; ++
I) {
1646 switch(
I->getDesc().getOpcode()) {
1647 case Mips::LwConstant32: {
1648 PrescannedForConstants =
true;
1650 J =
I->getNumOperands();
1653 if (Literal.
isImm()) {
1654 int64_t V = Literal.
getImm();
1659 unsigned index = MCP->getConstantPoolIndex(C, 4);
1660 I->getOperand(2).ChangeToImmediate(index);
1662 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1663 I->RemoveOperand(1);
1664 I->RemoveOperand(1);
1679 return new MipsConstantIslands();
auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
unsigned Log2(Align A)
Returns the log2 of the alignment.
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
unsigned postOffset(Align Alignment=Align::None()) const
Compute the offset immediately following this block.
MachineBasicBlock * getMBB() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them...
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block...
static unsigned int branchMaxOffsets(unsigned int Opcode)
STATISTIC(NumFunctions, "Total number of functions")
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
BasicBlockInfo - Information about the offset and size of a single basic block.
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
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static cl::opt< bool > AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code"))
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Align getAlignment() const
Return alignment of the basic block.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
uint64_t value() const
This is a hole in the type system and should not be abused.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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)
MachineInstrBundleIterator< MachineInstr > iterator
static unsigned int longformBranchOpcode(unsigned int Opcode)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
The instances of the Type class are immutable: once they are created, they are never changed...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool BBIsJumpedOver(MachineBasicBlock *MBB)
BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)
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()
static constexpr const Align None()
Returns a default constructed Align which corresponds to no alignment.
pred_iterator pred_begin()
static wasm::ValType getType(const TargetRegisterClass *RC)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
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.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static bool useConstantIslands()
Iterator for intrusive lists based on ilist_node.
void setAlignment(Align A)
Set alignment of the basic block.
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 size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
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.
APFloat neg(APFloat X)
Returns the negated value of the argument.
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.
unsigned pred_size() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...
unsigned succ_size() const
const MachineBasicBlock * getParent() const
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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...
static MachineOperand CreateImm(int64_t Val)
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
Properties which a MachineFunction may have at a given point in time.