40 #include "llvm/Config/llvm-config.h" 61 #define DEBUG_TYPE "mips-constant-islands" 63 STATISTIC(NumCPEs,
"Number of constpool entries");
64 STATISTIC(NumSplit,
"Number of uncond branches inserted");
65 STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
66 STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
71 cl::desc(
"Align constant islands in code"));
76 "mips-constant-islands-small-offset",
78 cl::desc(
"Make small offsets be this amount for testing purposes"),
84 "mips-constant-islands-no-load-relaxation",
86 cl::desc(
"Don't relax loads to long loads - for testing purposes"),
99 case Mips::BeqzRxImm16:
100 case Mips::BeqzRxImmX16:
101 case Mips::BnezRxImm16:
102 case Mips::BnezRxImmX16:
112 return Mips::BimmX16;
115 return Mips::BteqzX16;
118 return Mips::BtnezX16;
121 case Mips::BeqzRxImm16:
122 case Mips::BeqzRxImmX16:
123 return Mips::BeqzRxImmX16;
124 case Mips::BnezRxImm16:
125 case Mips::BnezRxImmX16:
126 return Mips::BnezRxImmX16;
136 unsigned Bits, Scale;
146 case Mips::BeqzRxImm16:
150 case Mips::BeqzRxImmX16:
154 case Mips::BnezRxImm16:
158 case Mips::BnezRxImmX16:
181 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
228 unsigned postOffset(
unsigned LogAlign = 0)
const {
229 unsigned PO = Offset +
Size;
234 std::vector<BasicBlockInfo> BBInfo;
239 std::vector<MachineBasicBlock*> WaterList;
245 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
266 unsigned LongFormMaxDisp;
268 unsigned LongFormOpcode;
275 unsigned longformmaxdisp,
unsigned longformopcode)
276 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
277 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
283 unsigned getMaxDisp()
const {
289 void setMaxDisp(
unsigned val) {
293 unsigned getLongFormMaxDisp()
const {
294 return LongFormMaxDisp;
297 unsigned getLongFormOpcode()
const {
298 return LongFormOpcode;
304 std::vector<CPUser> CPUsers;
315 : CPEMI(cpemi), CPI(cpi), RefCount(
rc) {}
323 std::vector<std::vector<CPEntry>> CPEntries;
331 unsigned MaxDisp : 31;
335 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
336 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
341 std::vector<ImmBranch> ImmBranches;
353 unsigned PICLabelUId;
354 bool PrescannedForConstants =
false;
356 void initPICLabelUId(
unsigned UId) {
360 unsigned createPICLabelUId() {
361 return PICLabelUId++;
369 StringRef getPassName()
const override {
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();
405 bool isCPEntryInRange(
MachineInstr *MI,
unsigned UserOffset,
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();
422 bool MipsConstantIslands::isOffsetInRange
423 (
unsigned UserOffset,
unsigned TrialOffset,
425 return isOffsetInRange(UserOffset, TrialOffset,
426 U.getMaxDisp(), U.NegOk);
429 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 432 for (
unsigned J = 0,
E = BBInfo.size(); J !=
E; ++J) {
459 if (!PrescannedForConstants) prescanForConstants();
463 MF->getRegInfo().invalidateLiveness();
467 MF->RenumberBlocks();
469 bool MadeChange =
false;
473 std::vector<MachineInstr*> CPEMIs;
475 doInitialPlacement(CPEMIs);
478 initPICLabelUId(CPEMIs.size());
483 initializeFunctionInfo(CPEMIs);
488 MadeChange |= removeUnusedCPEntries();
492 unsigned NoCPIters = 0, NoBRIters = 0;
495 LLVM_DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
496 bool CPChange =
false;
497 for (
unsigned i = 0, e = CPUsers.size(); i != e; ++i)
498 CPChange |= handleConstantPoolUser(i);
499 if (CPChange && ++NoCPIters > 30)
505 NewWaterList.clear();
507 LLVM_DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
508 bool BRChange =
false;
509 for (
unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
510 BRChange |= fixupImmediateBr(ImmBranches[i]);
511 if (BRChange && ++NoBRIters > 30)
514 if (!CPChange && !BRChange)
532 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
538 unsigned MaxAlign =
Log2_32(MCP->getConstantPoolAlignment());
556 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
559 for (
unsigned i = 0, e = CPs.
size(); i != e; ++i) {
561 assert(Size >= 4 &&
"Too small constant pool entry");
562 unsigned Align = CPs[i].getAlignment();
566 assert((Size % Align) == 0 &&
"CP Entry not multiple of 4 bytes!");
569 unsigned LogAlign =
Log2_32(Align);
576 CPEMIs.push_back(CPEMI);
580 for (
unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
581 if (InsPoint[a] == InsAt)
584 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
586 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = " 587 << Size <<
", align = " << Align <<
'\n');
612 MipsConstantIslands::CPEntry
613 *MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
615 std::vector<CPEntry> &CPEs = CPEntries[CPI];
618 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
619 if (CPEs[i].CPEMI == CPEMI)
627 unsigned MipsConstantIslands::getCPELogAlign(
const MachineInstr &CPEMI) {
635 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
636 unsigned Align = MCP->getConstants()[CPI].getAlignment();
644 void MipsConstantIslands::
645 initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
647 BBInfo.resize(MF->getNumBlockIDs());
657 adjustBBOffsetsAfter(&MF->front());
664 WaterList.push_back(&MBB);
666 if (
MI.isDebugInstr())
669 int Opc =
MI.getOpcode();
688 case Mips::BeqzRxImm16:
694 case Mips::BeqzRxImmX16:
700 case Mips::BnezRxImm16:
706 case Mips::BnezRxImmX16:
738 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
739 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, isCond, UOpc));
742 if (Opc == Mips::CONSTPOOL_ENTRY)
746 for (
unsigned op = 0, e =
MI.getNumOperands();
op != e; ++
op)
747 if (
MI.getOperand(
op).isCPI()) {
755 unsigned LongFormBits = 0;
756 unsigned LongFormScale = 0;
757 unsigned LongFormOpcode = 0;
761 case Mips::LwRxPcTcp16:
764 LongFormOpcode = Mips::LwRxPcTcpX16;
768 case Mips::LwRxPcTcpX16:
775 unsigned CPI =
MI.getOperand(
op).getIndex();
777 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
778 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
779 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
783 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
784 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
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);
901 if (WaterBB == OrigBB)
902 WaterList.
insert(std::next(IP), NewBB);
904 WaterList.insert(IP, OrigBB);
905 NewWaterList.insert(OrigBB);
919 adjustBBOffsetsAfter(OrigBB);
927 bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
928 unsigned TrialOffset,
unsigned MaxDisp,
930 if (UserOffset <= TrialOffset) {
932 if (TrialOffset - UserOffset <= MaxDisp)
934 }
else if (NegativeOK) {
935 if (UserOffset - TrialOffset <= MaxDisp)
945 bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
948 unsigned CPELogAlign = getCPELogAlign(*U.CPEMI);
949 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset(CPELogAlign);
950 unsigned NextBlockOffset, NextBlockAlignment;
952 if (NextBlock == MF->end()) {
953 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
954 NextBlockAlignment = 0;
956 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
957 NextBlockAlignment = NextBlock->getAlignment();
959 unsigned Size = U.CPEMI->getOperand(2).getImm();
960 unsigned CPEEnd = CPEOffset +
Size;
965 if (CPEEnd > NextBlockOffset) {
966 Growth = CPEEnd - NextBlockOffset;
974 if (CPEOffset < UserOffset)
975 UserOffset += Growth;
980 return isOffsetInRange(UserOffset, CPEOffset, U);
985 bool MipsConstantIslands::isCPEntryInRange
988 bool NegOk,
bool DoDump) {
989 unsigned CPEOffset = getOffsetOf(CPEMI);
996 <<
" max delta=" << MaxDisp
997 <<
format(
" insn address=%#x", UserOffset) <<
" in " 1000 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
1001 int(CPEOffset - UserOffset));
1005 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1017 if (PredMI->
getOpcode() == Mips::Bimm16)
1025 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
1028 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1029 BBInfo[i].Offset =
Offset;
1037 bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1040 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1041 assert(CPE &&
"Unexpected!");
1042 if (--CPE->RefCount == 0) {
1043 removeDeadCPEMI(CPEMI);
1044 CPE->CPEMI =
nullptr;
1057 int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1063 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
1071 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1072 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1074 if (CPEs[i].CPEMI == CPEMI)
1077 if (CPEs[i].CPEMI ==
nullptr)
1079 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
1082 << CPEs[i].CPI <<
"\n");
1084 U.CPEMI = CPEs[i].CPEMI;
1095 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1109 int MipsConstantIslands::findLongFormInRangeCPEntry
1110 (CPUser& U,
unsigned UserOffset)
1116 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1117 U.getLongFormMaxDisp(), U.NegOk,
1120 UserMI->
setDesc(
TII->get(U.getLongFormOpcode()));
1121 U.setMaxDisp(U.getLongFormMaxDisp());
1127 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1128 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1130 if (CPEs[i].CPEMI == CPEMI)
1133 if (CPEs[i].CPEMI ==
nullptr)
1135 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1136 U.getLongFormMaxDisp(), U.NegOk)) {
1138 << CPEs[i].CPI <<
"\n");
1140 U.CPEMI = CPEs[i].CPEMI;
1151 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1162 return ((1<<10)-1)*2;
1164 return ((1<<16)-1)*2;
1168 return ((1<<16)-1)*2;
1179 bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1180 water_iterator &WaterIter) {
1181 if (WaterList.empty())
1184 unsigned BestGrowth = ~0u;
1185 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
1197 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1198 (WaterBB->
getNumber() < U.HighWaterMark->getNumber() ||
1199 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1201 BestGrowth = Growth;
1204 <<
" Growth=" << Growth <<
'\n');
1207 if (BestGrowth == 0)
1213 return BestGrowth != ~0u;
1223 void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1224 unsigned UserOffset,
1226 CPUser &U = CPUsers[CPUserIndex];
1229 unsigned CPELogAlign = getCPELogAlign(*CPEMI);
1239 unsigned CPEOffset = UserBBI.
postOffset(CPELogAlign) + Delta;
1241 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1243 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1250 int UncondBr = Mips::Bimm16;
1253 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1254 MaxDisp,
false, UncondBr));
1255 BBInfo[UserMBB->
getNumber()].Size += Delta;
1256 adjustBBOffsetsAfter(UserMBB);
1266 unsigned LogAlign = MF->getAlignment();
1267 assert(LogAlign >= CPELogAlign &&
"Over-aligned constant pool entry");
1268 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1275 BaseInsertOffset -= 4;
1278 <<
" la=" << LogAlign <<
'\n');
1284 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1288 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1292 unsigned CPUIndex = CPUserIndex+1;
1293 unsigned NumCPUsers = CPUsers.size();
1295 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1296 Offset < BaseInsertOffset;
1297 Offset +=
TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
1298 assert(MI != UserMBB->
end() &&
"Fell off end of block");
1299 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1300 CPUser &U = CPUsers[CPUIndex];
1301 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1303 BaseInsertOffset -= 1u << LogAlign;
1304 EndInsertOffset -= 1u << LogAlign;
1310 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1315 NewMBB = splitBlockBeforeInstr(*--MI);
1322 bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1323 CPUser &U = CPUsers[CPUserIndex];
1329 unsigned UserOffset = getUserOffset(U);
1333 int result = findInRangeCPEntry(U, UserOffset);
1334 if (result==1)
return false;
1335 else if (result==2)
return true;
1341 if (findAvailableWater(U, UserOffset, IP)) {
1348 if (NewWaterList.erase(WaterBB))
1349 NewWaterList.
insert(NewIsland);
1358 result = findLongFormInRangeCPEntry(U, UserOffset);
1359 if (result != 0)
return true;
1362 createNewWater(CPUserIndex, UserOffset, NewMBB);
1371 if (IP != WaterList.end())
1372 NewWaterList.erase(WaterBB);
1375 NewWaterList.insert(NewIsland);
1382 if (IP != WaterList.end())
1383 WaterList.erase(IP);
1389 updateForInsertedWaterBlock(NewIsland);
1392 decrementCPEReferenceCount(CPI, CPEMI);
1396 unsigned ID = createPICLabelUId();
1400 U.HighWaterMark = NewIsland;
1403 CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
1411 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1421 dbgs() <<
" Moved CPE to #" << ID <<
" CPI=" << CPI
1429 void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1435 if (CPEBB->
empty()) {
1444 adjustBBOffsetsAfter(CPEBB);
1454 bool MipsConstantIslands::removeUnusedCPEntries() {
1455 unsigned MadeChange =
false;
1456 for (
unsigned i = 0, e = CPEntries.size(); i != e; ++i) {
1457 std::vector<CPEntry> &CPEs = CPEntries[i];
1458 for (
unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1459 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1460 removeDeadCPEMI(CPEs[j].CPEMI);
1461 CPEs[j].CPEMI =
nullptr;
1471 bool MipsConstantIslands::isBBInRange
1474 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
1475 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1479 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(MI)
1480 <<
" to " << DestOffset <<
" offset " 1481 << int(DestOffset - BrOffset) <<
"\t" << *
MI);
1483 if (BrOffset <= DestOffset) {
1485 if (DestOffset-BrOffset <= MaxDisp)
1488 if (BrOffset-DestOffset <= MaxDisp)
1496 bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1502 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1506 return fixupUnconditionalBr(Br);
1507 return fixupConditionalBr(Br);
1515 MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1520 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1521 if (isBBInRange(MI, DestBB, BimmX16MaxDisp)) {
1522 Br.MaxDisp = BimmX16MaxDisp;
1538 Br.MaxDisp = ((1<<24)-1) * 2;
1542 adjustBBOffsetsAfter(MBB);
1555 MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1564 if (isBBInRange(MI, DestBB, LongFormMaxOff)) {
1565 Br.MaxDisp = LongFormMaxOff;
1584 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1600 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1602 dbgs() <<
" Invert Bcc condition and swap its destination with " 1613 splitBlockBeforeInstr(*MI);
1616 int delta =
TII->getInstSizeInBytes(MBB->
back());
1624 <<
" also invert condition and change dest. to " 1637 Br.MI = &MBB->
back();
1642 ImmBranches.push_back(ImmBranch(&MBB->
back(), MaxDisp,
false, Br.UncondBr));
1647 adjustBBOffsetsAfter(MBB);
1651 void MipsConstantIslands::prescanForConstants() {
1655 MF->begin(),
E = MF->end();
B !=
E; ++
B) {
1657 B->instr_begin(), EB =
B->instr_end();
I != EB; ++
I) {
1658 switch(
I->getDesc().getOpcode()) {
1659 case Mips::LwConstant32: {
1660 PrescannedForConstants =
true;
1662 J =
I->getNumOperands();
1665 if (Literal.
isImm()) {
1666 int64_t V = Literal.
getImm();
1671 unsigned index = MCP->getConstantPoolIndex(C, 4);
1672 I->getOperand(2).ChangeToImmediate(index);
1674 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1675 I->RemoveOperand(1);
1676 I->RemoveOperand(1);
1691 return new MipsConstantIslands();
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.
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.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them...
unsigned getReg() const
getReg - Returns the register number.
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.
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.
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.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
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.
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...
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.
unsigned postOffset(unsigned LogAlign=0) const
Compute the offset immediately following this block.
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...
unsigned getAlignment() const
Return alignment of the basic block.
void setMBB(MachineBasicBlock *MBB)
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 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.
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 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...
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
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)
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
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())
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.
const MachineOperand & getOperand(unsigned i) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
Properties which a MachineFunction may have at a given point in time.