38#include "llvm/Config/llvm-config.h"
57#define DEBUG_TYPE "mips-constant-islands"
60STATISTIC(NumSplit,
"Number of uncond branches inserted");
61STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
62STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
67 cl::desc(
"Align constant islands in code"));
72 "mips-constant-islands-small-offset",
74 cl::desc(
"Make small offsets be this amount for testing purposes"),
80 "mips-constant-islands-no-load-relaxation",
82 cl::desc(
"Don't relax loads to long loads - for testing purposes"),
86 switch (
MI->getOpcode()) {
95 case Mips::BeqzRxImm16:
96 case Mips::BeqzRxImmX16:
97 case Mips::BnezRxImm16:
98 case Mips::BnezRxImmX16:
108 return Mips::BimmX16;
111 return Mips::BteqzX16;
114 return Mips::BtnezX16;
117 case Mips::BeqzRxImm16:
118 case Mips::BeqzRxImmX16:
119 return Mips::BeqzRxImmX16;
120 case Mips::BnezRxImm16:
121 case Mips::BnezRxImmX16:
122 return Mips::BnezRxImmX16;
132 unsigned Bits, Scale;
142 case Mips::BeqzRxImm16:
146 case Mips::BeqzRxImmX16:
150 case Mips::BnezRxImm16:
154 case Mips::BnezRxImmX16:
177 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
222 unsigned postOffset()
const {
return Offset +
Size; }
225 std::vector<BasicBlockInfo> BBInfo;
230 std::vector<MachineBasicBlock*> WaterList;
236 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
257 unsigned LongFormMaxDisp;
259 unsigned LongFormOpcode;
266 unsigned longformmaxdisp,
unsigned longformopcode)
267 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
268 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
274 unsigned getMaxDisp()
const {
280 void setMaxDisp(
unsigned val) {
284 unsigned getLongFormMaxDisp()
const {
285 return LongFormMaxDisp;
288 unsigned getLongFormOpcode()
const {
289 return LongFormOpcode;
295 std::vector<CPUser> CPUsers;
306 : CPEMI(cpemi), CPI(cpi), RefCount(
rc) {}
314 std::vector<std::vector<CPEntry>> CPEntries;
322 unsigned MaxDisp : 31;
327 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
328 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
333 std::vector<ImmBranch> ImmBranches;
345 unsigned PICLabelUId;
346 bool PrescannedForConstants =
false;
348 void initPICLabelUId(
unsigned UId) {
352 unsigned createPICLabelUId() {
353 return PICLabelUId++;
369 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
370 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
372 void initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs);
374 unsigned getUserOffset(CPUser&)
const;
377 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
378 unsigned Disp,
bool NegativeOK);
379 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
386 bool decrementCPEReferenceCount(
unsigned CPI,
MachineInstr* CPEMI);
387 int findInRangeCPEntry(CPUser& U,
unsigned UserOffset);
388 int findLongFormInRangeCPEntry(CPUser& U,
unsigned UserOffset);
389 bool findAvailableWater(CPUser&U,
unsigned UserOffset,
390 water_iterator &WaterIter);
391 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
393 bool handleConstantPoolUser(
unsigned CPUserIndex);
395 bool removeUnusedCPEntries();
398 bool DoDump =
false);
400 CPUser &U,
unsigned &Growth);
402 bool fixupImmediateBr(ImmBranch &Br);
403 bool fixupConditionalBr(ImmBranch &Br);
404 bool fixupUnconditionalBr(ImmBranch &Br);
406 void prescanForConstants();
411char MipsConstantIslands::ID = 0;
413bool MipsConstantIslands::isOffsetInRange
414 (
unsigned UserOffset,
unsigned TrialOffset,
416 return isOffsetInRange(UserOffset, TrialOffset,
417 U.getMaxDisp(),
U.NegOk);
420#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
423 for (
unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
450 if (!PrescannedForConstants) prescanForConstants();
454 MF->getRegInfo().invalidateLiveness();
458 MF->RenumberBlocks();
460 bool MadeChange =
false;
464 std::vector<MachineInstr*> CPEMIs;
466 doInitialPlacement(CPEMIs);
469 initPICLabelUId(CPEMIs.size());
474 initializeFunctionInfo(CPEMIs);
479 MadeChange |= removeUnusedCPEntries();
483 unsigned NoCPIters = 0, NoBRIters = 0;
486 LLVM_DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
487 bool CPChange =
false;
488 for (
unsigned i = 0, e = CPUsers.size(); i != e; ++i)
489 CPChange |= handleConstantPoolUser(i);
490 if (CPChange && ++NoCPIters > 30)
496 NewWaterList.
clear();
498 LLVM_DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
499 bool BRChange =
false;
500 for (
unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
501 BRChange |= fixupImmediateBr(ImmBranches[i]);
502 if (BRChange && ++NoBRIters > 30)
505 if (!CPChange && !BRChange)
523MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
529 const Align MaxAlign = MCP->getConstantPoolAlign();
548 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
551 for (
unsigned i = 0, e = CPs.size(); i != e; ++i) {
552 unsigned Size = CPs[i].getSizeInBytes(TD);
553 assert(
Size >= 4 &&
"Too small constant pool entry");
554 Align Alignment = CPs[i].getAlign();
560 unsigned LogAlign =
Log2(Alignment);
567 CPEMIs.push_back(CPEMI);
571 for (
unsigned a = LogAlign + 1; a <=
Log2(MaxAlign); ++a)
572 if (InsPoint[a] == InsAt)
575 CPEntries.emplace_back(1, CPEntry(CPEMI, i));
577 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = "
578 <<
Size <<
", align = " << Alignment.
value() <<
'\n');
598MipsConstantIslands::CPEntry
599*MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
601 std::vector<CPEntry> &CPEs = CPEntries[CPI];
604 for (CPEntry &CPE : CPEs) {
605 if (CPE.CPEMI == CPEMI)
621 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
622 return MCP->getConstants()[CPI].getAlign();
628void MipsConstantIslands::
629initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
631 BBInfo.resize(MF->getNumBlockIDs());
638 computeBlockSize(&
MBB);
641 adjustBBOffsetsAfter(&MF->front());
648 WaterList.push_back(&
MBB);
650 if (
MI.isDebugInstr())
653 int Opc =
MI.getOpcode();
672 case Mips::BeqzRxImm16:
678 case Mips::BeqzRxImmX16:
684 case Mips::BnezRxImm16:
690 case Mips::BnezRxImmX16:
722 unsigned MaxOffs = ((1 << (
Bits-1))-1) * Scale;
723 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, isCond, UOpc));
726 if (
Opc == Mips::CONSTPOOL_ENTRY)
739 unsigned LongFormBits = 0;
740 unsigned LongFormScale = 0;
741 unsigned LongFormOpcode = 0;
745 case Mips::LwRxPcTcp16:
748 LongFormOpcode = Mips::LwRxPcTcpX16;
752 case Mips::LwRxPcTcpX16:
759 unsigned CPI = MO.getIndex();
761 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
762 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
763 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs,
767 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
768 assert(CPE &&
"Cannot find a corresponding CPEntry!");
792unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
802 assert(
I !=
MBB->
end() &&
"Didn't find MI in its own basic block?");
812 return LHS->getNumber() <
RHS->getNumber();
818void MipsConstantIslands::updateForInsertedWaterBlock
830 WaterList.insert(IP, NewBB);
833unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
834 return getOffsetOf(
U.MI);
848 MF->insert(
MBBI, NewBB);
869 MF->RenumberBlocks(NewBB);
881 if (WaterBB == OrigBB)
882 WaterList.
insert(std::next(IP), NewBB);
884 WaterList.insert(IP, OrigBB);
885 NewWaterList.
insert(OrigBB);
892 computeBlockSize(OrigBB);
896 computeBlockSize(NewBB);
899 adjustBBOffsetsAfter(OrigBB);
907bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
908 unsigned TrialOffset,
unsigned MaxDisp,
910 if (UserOffset <= TrialOffset) {
912 if (TrialOffset - UserOffset <= MaxDisp)
914 }
else if (NegativeOK) {
915 if (UserOffset - TrialOffset <= MaxDisp)
925bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
928 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset();
929 unsigned NextBlockOffset;
930 Align NextBlockAlignment;
932 if (NextBlock == MF->end()) {
933 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
934 NextBlockAlignment =
Align(1);
936 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
937 NextBlockAlignment = NextBlock->getAlignment();
939 unsigned Size =
U.CPEMI->getOperand(2).getImm();
940 unsigned CPEEnd = CPEOffset +
Size;
945 if (CPEEnd > NextBlockOffset) {
946 Growth = CPEEnd - NextBlockOffset;
954 if (CPEOffset < UserOffset)
955 UserOffset += Growth;
960 return isOffsetInRange(UserOffset, CPEOffset, U);
965bool MipsConstantIslands::isCPEntryInRange
968 bool NegOk,
bool DoDump) {
969 unsigned CPEOffset = getOffsetOf(CPEMI);
973 unsigned Block =
MI->getParent()->getNumber();
976 <<
" max delta=" << MaxDisp
977 <<
format(
" insn address=%#x", UserOffset) <<
" in "
980 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
981 int(CPEOffset - UserOffset));
985 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
1005 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
1008 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
1009 BBInfo[i].Offset =
Offset;
1017bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
1020 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
1021 assert(CPE &&
"Unexpected!");
1022 if (--CPE->RefCount == 0) {
1023 removeDeadCPEMI(CPEMI);
1024 CPE->CPEMI =
nullptr;
1037int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
1043 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
U.getMaxDisp(),
U.NegOk,
1051 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1052 for (CPEntry &CPE : CPEs) {
1054 if (CPE.CPEMI == CPEMI)
1057 if (CPE.CPEMI ==
nullptr)
1059 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI,
U.getMaxDisp(),
1061 LLVM_DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#" << CPE.CPI
1064 U.CPEMI = CPE.CPEMI;
1068 MO.setIndex(CPE.CPI);
1075 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1089int MipsConstantIslands::findLongFormInRangeCPEntry
1090 (CPUser& U,
unsigned UserOffset)
1096 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
1097 U.getLongFormMaxDisp(),
U.NegOk,
1101 U.setMaxDisp(
U.getLongFormMaxDisp());
1107 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1108 for (CPEntry &CPE : CPEs) {
1110 if (CPE.CPEMI == CPEMI)
1113 if (CPE.CPEMI ==
nullptr)
1115 if (isCPEntryInRange(UserMI, UserOffset, CPE.CPEMI,
U.getLongFormMaxDisp(),
1117 LLVM_DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#" << CPE.CPI
1120 U.CPEMI = CPE.CPEMI;
1124 MO.setIndex(CPE.CPI);
1131 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1142 return ((1<<10)-1)*2;
1144 return ((1<<16)-1)*2;
1148 return ((1<<16)-1)*2;
1159bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1160 water_iterator &WaterIter) {
1161 if (WaterList.empty())
1164 unsigned BestGrowth = ~0
u;
1165 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
1177 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1178 (WaterBB->
getNumber() <
U.HighWaterMark->getNumber() ||
1179 NewWaterList.
count(WaterBB)) && Growth < BestGrowth) {
1181 BestGrowth = Growth;
1184 <<
" Growth=" << Growth <<
'\n');
1187 if (BestGrowth == 0)
1193 return BestGrowth != ~0
u;
1203void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1204 unsigned UserOffset,
1206 CPUser &
U = CPUsers[CPUserIndex];
1218 unsigned CPEOffset = UserBBI.
postOffset() + Delta;
1220 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1222 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1229 int UncondBr = Mips::Bimm16;
1232 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1233 MaxDisp,
false, UncondBr));
1234 BBInfo[UserMBB->
getNumber()].Size += Delta;
1235 adjustBBOffsetsAfter(UserMBB);
1246 unsigned BaseInsertOffset = UserOffset +
U.getMaxDisp();
1253 BaseInsertOffset -= 4;
1262 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1266 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1270 unsigned CPUIndex = CPUserIndex+1;
1271 unsigned NumCPUsers = CPUsers.size();
1273 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1274 Offset < BaseInsertOffset;
1276 assert(
MI != UserMBB->
end() &&
"Fell off end of block");
1277 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].
MI ==
MI) {
1278 CPUser &
U = CPUsers[CPUIndex];
1279 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1288 EndInsertOffset +=
U.CPEMI->getOperand(2).getImm();
1293 NewMBB = splitBlockBeforeInstr(*--
MI);
1300bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1301 CPUser &
U = CPUsers[CPUserIndex];
1307 unsigned UserOffset = getUserOffset(U);
1311 int result = findInRangeCPEntry(U, UserOffset);
1312 if (result==1)
return false;
1313 else if (result==2)
return true;
1319 if (findAvailableWater(U, UserOffset, IP)) {
1326 if (NewWaterList.
erase(WaterBB))
1327 NewWaterList.
insert(NewIsland);
1336 result = findLongFormInRangeCPEntry(U, UserOffset);
1337 if (result != 0)
return true;
1340 createNewWater(CPUserIndex, UserOffset, NewMBB);
1349 if (IP != WaterList.end())
1350 NewWaterList.
erase(WaterBB);
1353 NewWaterList.
insert(NewIsland);
1360 if (IP != WaterList.end())
1361 WaterList.erase(IP);
1367 updateForInsertedWaterBlock(NewIsland);
1370 decrementCPEReferenceCount(CPI, CPEMI);
1374 unsigned ID = createPICLabelUId();
1378 U.HighWaterMark = NewIsland;
1381 CPEntries[CPI].push_back(CPEntry(
U.CPEMI,
ID, 1));
1389 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1399 dbgs() <<
" Moved CPE to #" <<
ID <<
" CPI=" << CPI
1407void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1413 if (CPEBB->
empty()) {
1423 adjustBBOffsetsAfter(CPEBB);
1433bool MipsConstantIslands::removeUnusedCPEntries() {
1434 unsigned MadeChange =
false;
1435 for (std::vector<CPEntry> &CPEs : CPEntries) {
1436 for (CPEntry &CPE : CPEs) {
1437 if (CPE.RefCount == 0 && CPE.CPEMI) {
1438 removeDeadCPEMI(CPE.CPEMI);
1439 CPE.CPEMI =
nullptr;
1449bool MipsConstantIslands::isBBInRange
1452 unsigned BrOffset = getOffsetOf(
MI) + PCAdj;
1453 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1457 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(
MI)
1458 <<
" to " << DestOffset <<
" offset "
1459 <<
int(DestOffset - BrOffset) <<
"\t" << *
MI);
1461 if (BrOffset <= DestOffset) {
1463 if (DestOffset-BrOffset <= MaxDisp)
1466 if (BrOffset-DestOffset <= MaxDisp)
1474bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1480 if (isBBInRange(
MI, DestBB, Br.MaxDisp))
1484 return fixupUnconditionalBr(Br);
1485 return fixupConditionalBr(Br);
1493MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1498 unsigned BimmX16MaxDisp = ((1 << 16)-1) * 2;
1499 if (isBBInRange(
MI, DestBB, BimmX16MaxDisp)) {
1500 Br.MaxDisp = BimmX16MaxDisp;
1501 MI->setDesc(
TII->get(Mips::BimmX16));
1516 Br.MaxDisp = ((1<<24)-1) * 2;
1517 MI->setDesc(
TII->get(Mips::JalB16));
1520 adjustBBOffsetsAfter(
MBB);
1533MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1537 unsigned Opcode =
MI->getOpcode();
1542 if (isBBInRange(
MI, DestBB, LongFormMaxOff)) {
1543 Br.MaxDisp = LongFormMaxOff;
1544 MI->setDesc(
TII->get(LongFormOpcode));
1562 unsigned OppositeBranchOpcode =
TII->getOppositeBranchOpc(Opcode);
1578 if (isBBInRange(
MI, NewDest, Br.MaxDisp)) {
1580 dbgs() <<
" Invert Bcc condition and swap its destination with "
1582 MI->setDesc(
TII->get(OppositeBranchOpcode));
1584 MI->getOperand(TargetOperand).setMBB(NewDest);
1591 splitBlockBeforeInstr(*
MI);
1594 int delta =
TII->getInstSizeInBytes(
MBB->
back());
1602 <<
" also invert condition and change dest. to "
1607 if (
MI->getNumExplicitOperands() == 2) {
1609 .
addReg(
MI->getOperand(0).getReg())
1620 ImmBranches.push_back(ImmBranch(&
MBB->
back(), MaxDisp,
false, Br.UncondBr));
1623 BBInfo[
MI->getParent()->getNumber()].Size -=
TII->getInstSizeInBytes(*
MI);
1624 MI->eraseFromParent();
1625 adjustBBOffsetsAfter(
MBB);
1629void MipsConstantIslands::prescanForConstants() {
1632 switch (
MI.getDesc().getOpcode()) {
1633 case Mips::LwConstant32: {
1634 PrescannedForConstants =
true;
1642 const Constant *
C = ConstantInt::get(Int32Ty, V);
1643 unsigned index = MCP->getConstantPoolIndex(
C,
Align(4));
1644 MI.getOperand(2).ChangeToImmediate(index);
1646 MI.setDesc(
TII->get(Mips::LwRxPcTcp16));
1647 MI.removeOperand(1);
1648 MI.removeOperand(1);
1663 return new MipsConstantIslands();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_PREFERRED_TYPE(T)
\macro LLVM_PREFERRED_TYPE Adjust type of bit-field in debug info.
#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...
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
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
LLVM_ABI 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.
LLVM_ABI void dump() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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.
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
LLVM_ABI 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.
LLVM_ABI 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.
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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 LLVM_ABI 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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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.
LLVM_ABI 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.