39#include "llvm/Config/llvm-config.h"
60#define DEBUG_TYPE "mips-constant-islands"
63STATISTIC(NumSplit,
"Number of uncond branches inserted");
64STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
65STATISTIC(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"),
89 switch (
MI->getOpcode()) {
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++;
369 MachineFunctionProperties::Property::NoVRegs);
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();
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();
414char MipsConstantIslands::ID = 0;
416bool 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)
526MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
532 const Align MaxAlign = MCP->getConstantPoolAlign();
551 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
554 for (
unsigned i = 0, e = CPs.size(); i != e; ++i) {
555 unsigned Size = CPs[i].getSizeInBytes(TD);
556 assert(
Size >= 4 &&
"Too small constant pool entry");
557 Align Alignment = CPs[i].getAlign();
563 unsigned LogAlign =
Log2(Alignment);
570 CPEMIs.push_back(CPEMI);
574 for (
unsigned a = LogAlign + 1; a <=
Log2(MaxAlign); ++a)
575 if (InsPoint[a] == InsAt)
578 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
580 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = "
581 <<
Size <<
", align = " << Alignment.
value() <<
'\n');
601MipsConstantIslands::CPEntry
602*MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
604 std::vector<CPEntry> &CPEs = CPEntries[CPI];
607 for (CPEntry &CPE : CPEs) {
608 if (CPE.CPEMI == CPEMI)
624 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
625 return MCP->getConstants()[CPI].getAlign();
631void MipsConstantIslands::
632initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
634 BBInfo.resize(MF->getNumBlockIDs());
641 computeBlockSize(&
MBB);
644 adjustBBOffsetsAfter(&MF->front());
651 WaterList.push_back(&
MBB);
653 if (
MI.isDebugInstr())
656 int Opc =
MI.getOpcode();
675 case Mips::BeqzRxImm16:
681 case Mips::BeqzRxImmX16:
687 case Mips::BnezRxImm16:
693 case Mips::BnezRxImmX16:
725 unsigned MaxOffs = ((1 << (
Bits-1))-1) * Scale;
726 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, isCond, UOpc));
729 if (Opc == Mips::CONSTPOOL_ENTRY)
742 unsigned LongFormBits = 0;
743 unsigned LongFormScale = 0;
744 unsigned LongFormOpcode = 0;
748 case Mips::LwRxPcTcp16:
751 LongFormOpcode = Mips::LwRxPcTcpX16;
755 case Mips::LwRxPcTcpX16:
762 unsigned CPI = MO.getIndex();
764 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
765 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
766 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
770 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
771 assert(CPE &&
"Cannot find a corresponding CPEntry!");
795unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
805 assert(
I !=
MBB->
end() &&
"Didn't find MI in its own basic block?");
815 return LHS->getNumber() <
RHS->getNumber();
821void MipsConstantIslands::updateForInsertedWaterBlock
833 WaterList.insert(IP, NewBB);
836unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
837 return getOffsetOf(
U.MI);
851 MF->insert(
MBBI, NewBB);
872 MF->RenumberBlocks(NewBB);
884 if (WaterBB == OrigBB)
885 WaterList.
insert(std::next(IP), NewBB);
887 WaterList.insert(IP, OrigBB);
888 NewWaterList.
insert(OrigBB);
895 computeBlockSize(OrigBB);
899 computeBlockSize(NewBB);
902 adjustBBOffsetsAfter(OrigBB);
910bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
911 unsigned TrialOffset,
unsigned MaxDisp,
913 if (UserOffset <= TrialOffset) {
915 if (TrialOffset - UserOffset <= MaxDisp)
917 }
else if (NegativeOK) {
918 if (UserOffset - TrialOffset <= MaxDisp)
928bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
931 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset();
932 unsigned NextBlockOffset;
933 Align NextBlockAlignment;
935 if (NextBlock == MF->end()) {
936 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
937 NextBlockAlignment =
Align(1);
939 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
940 NextBlockAlignment = NextBlock->getAlignment();
942 unsigned Size =
U.CPEMI->getOperand(2).getImm();
943 unsigned CPEEnd = CPEOffset +
Size;
948 if (CPEEnd > NextBlockOffset) {
949 Growth = CPEEnd - NextBlockOffset;
957 if (CPEOffset < UserOffset)
958 UserOffset += Growth;
963 return isOffsetInRange(UserOffset, CPEOffset, U);
968bool MipsConstantIslands::isCPEntryInRange
971 bool NegOk,
bool DoDump) {
972 unsigned CPEOffset = getOffsetOf(CPEMI);
976 unsigned Block =
MI->getParent()->getNumber();
979 <<
" max delta=" << MaxDisp
980 <<
format(
" insn address=%#x", UserOffset) <<
" in "
983 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
984 int(CPEOffset - UserOffset));
988 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1000 if (PredMI->
getOpcode() == Mips::Bimm16)
1008 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
1011 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1012 BBInfo[i].Offset =
Offset;
1020bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1023 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1024 assert(CPE &&
"Unexpected!");
1025 if (--CPE->RefCount == 0) {
1026 removeDeadCPEMI(CPEMI);
1027 CPE->CPEMI =
nullptr;
1040int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1046 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
U.getMaxDisp(),
U.NegOk,
1054 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1055 for (CPEntry &CPE : CPEs) {
1057 if (CPE.CPEMI == CPEMI)
1060 if (CPE.CPEMI ==
nullptr)
1062 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI,
U.getMaxDisp(),
1064 LLVM_DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#" << CPE.CPI
1067 U.CPEMI = CPE.CPEMI;
1071 MO.setIndex(CPE.CPI);
1078 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1092int MipsConstantIslands::findLongFormInRangeCPEntry
1093 (CPUser& U,
unsigned UserOffset)
1099 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1100 U.getLongFormMaxDisp(),
U.NegOk,
1104 U.setMaxDisp(
U.getLongFormMaxDisp());
1110 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1111 for (CPEntry &CPE : CPEs) {
1113 if (CPE.CPEMI == CPEMI)
1116 if (CPE.CPEMI ==
nullptr)
1118 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI,
U.getLongFormMaxDisp(),
1120 LLVM_DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#" << CPE.CPI
1123 U.CPEMI = CPE.CPEMI;
1127 MO.setIndex(CPE.CPI);
1134 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1145 return ((1<<10)-1)*2;
1147 return ((1<<16)-1)*2;
1151 return ((1<<16)-1)*2;
1162bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1163 water_iterator &WaterIter) {
1164 if (WaterList.empty())
1167 unsigned BestGrowth = ~0
u;
1168 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
1180 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1181 (WaterBB->
getNumber() <
U.HighWaterMark->getNumber() ||
1182 NewWaterList.
count(WaterBB)) && Growth < BestGrowth) {
1184 BestGrowth = Growth;
1187 <<
" Growth=" << Growth <<
'\n');
1190 if (BestGrowth == 0)
1196 return BestGrowth != ~0
u;
1206void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1207 unsigned UserOffset,
1209 CPUser &
U = CPUsers[CPUserIndex];
1221 unsigned CPEOffset = UserBBI.
postOffset() + Delta;
1223 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1225 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1232 int UncondBr = Mips::Bimm16;
1235 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1236 MaxDisp,
false, UncondBr));
1237 BBInfo[UserMBB->
getNumber()].Size += Delta;
1238 adjustBBOffsetsAfter(UserMBB);
1249 unsigned BaseInsertOffset = UserOffset +
U.getMaxDisp();
1256 BaseInsertOffset -= 4;
1265 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1269 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1273 unsigned CPUIndex = CPUserIndex+1;
1274 unsigned NumCPUsers = CPUsers.size();
1276 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1277 Offset < BaseInsertOffset;
1279 assert(
MI != UserMBB->
end() &&
"Fell off end of block");
1280 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].
MI ==
MI) {
1281 CPUser &
U = CPUsers[CPUIndex];
1282 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1291 EndInsertOffset +=
U.CPEMI->getOperand(2).getImm();
1296 NewMBB = splitBlockBeforeInstr(*--
MI);
1303bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1304 CPUser &
U = CPUsers[CPUserIndex];
1310 unsigned UserOffset = getUserOffset(U);
1314 int result = findInRangeCPEntry(U, UserOffset);
1315 if (result==1)
return false;
1316 else if (result==2)
return true;
1322 if (findAvailableWater(U, UserOffset, IP)) {
1329 if (NewWaterList.
erase(WaterBB))
1330 NewWaterList.
insert(NewIsland);
1339 result = findLongFormInRangeCPEntry(U, UserOffset);
1340 if (result != 0)
return true;
1343 createNewWater(CPUserIndex, UserOffset, NewMBB);
1352 if (IP != WaterList.end())
1353 NewWaterList.
erase(WaterBB);
1356 NewWaterList.
insert(NewIsland);
1363 if (IP != WaterList.end())
1364 WaterList.erase(IP);
1370 updateForInsertedWaterBlock(NewIsland);
1373 decrementCPEReferenceCount(CPI, CPEMI);
1377 unsigned ID = createPICLabelUId();
1381 U.HighWaterMark = NewIsland;
1384 CPEntries[CPI].push_back(CPEntry(
U.CPEMI,
ID, 1));
1392 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1402 dbgs() <<
" Moved CPE to #" <<
ID <<
" CPI=" << CPI
1410void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1416 if (CPEBB->
empty()) {
1426 adjustBBOffsetsAfter(CPEBB);
1436bool MipsConstantIslands::removeUnusedCPEntries() {
1437 unsigned MadeChange =
false;
1438 for (std::vector<CPEntry> &CPEs : CPEntries) {
1439 for (CPEntry &CPE : CPEs) {
1440 if (CPE.RefCount == 0 && CPE.CPEMI) {
1441 removeDeadCPEMI(CPE.CPEMI);
1442 CPE.CPEMI =
nullptr;
1452bool MipsConstantIslands::isBBInRange
1455 unsigned BrOffset = getOffsetOf(
MI) + PCAdj;
1456 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1460 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(
MI)
1461 <<
" to " << DestOffset <<
" offset "
1462 <<
int(DestOffset - BrOffset) <<
"\t" << *
MI);
1464 if (BrOffset <= DestOffset) {
1466 if (DestOffset-BrOffset <= MaxDisp)
1469 if (BrOffset-DestOffset <= MaxDisp)
1477bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1483 if (isBBInRange(
MI, DestBB, Br.MaxDisp))
1487 return fixupUnconditionalBr(Br);
1488 return fixupConditionalBr(Br);
1496MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1501 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1502 if (isBBInRange(
MI, DestBB, BimmX16MaxDisp)) {
1503 Br.MaxDisp = BimmX16MaxDisp;
1504 MI->setDesc(
TII->get(Mips::BimmX16));
1519 Br.MaxDisp = ((1<<24)-1) * 2;
1520 MI->setDesc(
TII->get(Mips::JalB16));
1523 adjustBBOffsetsAfter(
MBB);
1536MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1540 unsigned Opcode =
MI->getOpcode();
1545 if (isBBInRange(
MI, DestBB, LongFormMaxOff)) {
1546 Br.MaxDisp = LongFormMaxOff;
1547 MI->setDesc(
TII->get(LongFormOpcode));
1565 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1581 if (isBBInRange(
MI, NewDest, Br.MaxDisp)) {
1583 dbgs() <<
" Invert Bcc condition and swap its destination with "
1585 MI->setDesc(
TII->get(OppositeBranchOpcode));
1587 MI->getOperand(TargetOperand).setMBB(NewDest);
1594 splitBlockBeforeInstr(*
MI);
1597 int delta =
TII->getInstSizeInBytes(
MBB->
back());
1605 <<
" also invert condition and change dest. to "
1610 if (
MI->getNumExplicitOperands() == 2) {
1612 .
addReg(
MI->getOperand(0).getReg())
1623 ImmBranches.push_back(ImmBranch(&
MBB->
back(), MaxDisp,
false, Br.UncondBr));
1626 BBInfo[
MI->getParent()->getNumber()].Size -=
TII->getInstSizeInBytes(*
MI);
1627 MI->eraseFromParent();
1628 adjustBBOffsetsAfter(
MBB);
1632void MipsConstantIslands::prescanForConstants() {
1639 switch(
I->getDesc().getOpcode()) {
1640 case Mips::LwConstant32: {
1641 PrescannedForConstants =
true;
1643 J =
I->getNumOperands();
1651 const Constant *
C = ConstantInt::get(Int32Ty, V);
1652 unsigned index = MCP->getConstantPoolIndex(
C,
Align(4));
1653 I->getOperand(2).ChangeToImmediate(index);
1655 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1656 I->removeOperand(1);
1657 I->removeOperand(1);
1672 return new MipsConstantIslands();
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static bool CompareMBBNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)
CompareMBBNumbers - Little predicate function to sort the WaterList by MBB ID.
static unsigned getUnconditionalBrDisp(int Opc)
getUnconditionalBrDisp - Returns the maximum displacement that can fit in the specific unconditional ...
static unsigned int longformBranchOpcode(unsigned int Opcode)
static unsigned int branchMaxOffsets(unsigned int Opcode)
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)
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 bool BBHasFallthrough(MachineBasicBlock *MBB)
BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...
static cl::opt< bool > AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code"))
static unsigned int branchTargetOperand(MachineInstr *MI)
static bool BBIsJumpedOver(MachineBasicBlock *MBB)
BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
unsigned pred_size() const
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
succ_iterator succ_begin()
unsigned succ_size() const
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.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
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 '...
Align getAlignment() const
Return alignment of the basic block.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
BasicBlockListType::const_iterator const_iterator
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
iterator_range< mop_iterator > operands()
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
static bool useConstantIslands()
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt32Ty(LLVMContext &C)
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
FunctionPass * createMipsConstantIslandPass()
Returns a pass that converts branches to long branches.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
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...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
APFloat neg(APFloat X)
Returns the negated value of the argument.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
BasicBlockInfo - Information about the offset and size of a single basic block.
unsigned Size
Size - Size of the basic block in bytes.
unsigned postOffset(Align Alignment=Align(1)) const
Compute the offset immediately following this block.
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block.