38#include "llvm/Config/llvm-config.h"
58#define DEBUG_TYPE "CSKY-constant-islands"
61STATISTIC(NumSplit,
"Number of uncond branches inserted");
62STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
63STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
106 unsigned postOffset()
const {
return Offset +
Size; }
109 std::vector<BasicBlockInfo> BBInfo;
114 std::vector<MachineBasicBlock *> WaterList;
118 SmallPtrSet<MachineBasicBlock *, 4> NewWaterList;
120 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
137 MachineBasicBlock *HighWaterMark;
145 CPUser(MachineInstr *Mi, MachineInstr *Cpemi,
unsigned Maxdisp,
bool Neg)
146 : MI(Mi), CPEMI(Cpemi), MaxDisp(Maxdisp), NegOk(Neg) {
147 HighWaterMark = CPEMI->getParent();
151 unsigned getMaxDisp()
const {
return MaxDisp - 16; }
153 void setMaxDisp(
unsigned Val) { MaxDisp = Val; }
158 std::vector<CPUser> CPUsers;
168 CPEntry(MachineInstr *Cpemi,
unsigned Cpi,
unsigned Rc = 0)
169 : CPEMI(Cpemi), CPI(Cpi), RefCount(Rc) {}
177 std::vector<std::vector<CPEntry>> CPEntries;
185 unsigned MaxDisp : 31;
190 ImmBranch(MachineInstr *Mi,
unsigned Maxdisp,
bool Cond,
int Ubr)
191 : MI(Mi), MaxDisp(Maxdisp), IsCond(
Cond), UncondBr(Ubr) {}
196 std::vector<ImmBranch> ImmBranches;
198 const CSKYSubtarget *STI =
nullptr;
199 const CSKYInstrInfo *TII;
200 CSKYMachineFunctionInfo *MFI;
201 MachineFunction *MF =
nullptr;
202 MachineConstantPool *MCP =
nullptr;
204 unsigned PICLabelUId;
206 void initPICLabelUId(
unsigned UId) { PICLabelUId = UId; }
208 unsigned createPICLabelUId() {
return PICLabelUId++; }
213 CSKYConstantIslands() : MachineFunctionPass(ID) {}
215 StringRef getPassName()
const override {
return "CSKY Constant Islands"; }
217 bool runOnMachineFunction(MachineFunction &
F)
override;
219 MachineFunctionProperties getRequiredProperties()
const override {
220 return MachineFunctionProperties().setNoVRegs();
223 void doInitialPlacement(std::vector<MachineInstr *> &CPEMIs);
224 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
225 Align getCPEAlign(
const MachineInstr &CPEMI);
226 void initializeFunctionInfo(
const std::vector<MachineInstr *> &CPEMIs);
227 unsigned getOffsetOf(MachineInstr *
MI)
const;
228 unsigned getUserOffset(CPUser &)
const;
231 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
unsigned Disp,
233 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
236 void computeBlockSize(MachineBasicBlock *
MBB);
237 MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &
MI);
238 void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
239 void adjustBBOffsetsAfter(MachineBasicBlock *BB);
240 bool decrementCPEReferenceCount(
unsigned CPI, MachineInstr *CPEMI);
241 int findInRangeCPEntry(CPUser &U,
unsigned UserOffset);
242 bool findAvailableWater(CPUser &U,
unsigned UserOffset,
243 water_iterator &WaterIter);
244 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
245 MachineBasicBlock *&NewMBB);
246 bool handleConstantPoolUser(
unsigned CPUserIndex);
247 void removeDeadCPEMI(MachineInstr *CPEMI);
248 bool removeUnusedCPEntries();
249 bool isCPEntryInRange(MachineInstr *
MI,
unsigned UserOffset,
250 MachineInstr *CPEMI,
unsigned Disp,
bool NegOk,
251 bool DoDump =
false);
252 bool isWaterInRange(
unsigned UserOffset, MachineBasicBlock *Water, CPUser &U,
254 bool isBBInRange(MachineInstr *
MI, MachineBasicBlock *BB,
unsigned Disp);
255 bool fixupImmediateBr(ImmBranch &Br);
256 bool fixupConditionalBr(ImmBranch &Br);
257 bool fixupUnconditionalBr(ImmBranch &Br);
261char CSKYConstantIslands::ID = 0;
263bool CSKYConstantIslands::isOffsetInRange(
unsigned UserOffset,
264 unsigned TrialOffset,
266 return isOffsetInRange(UserOffset, TrialOffset,
U.getMaxDisp(),
U.NegOk);
269#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
272 for (
unsigned J = 0,
E = BBInfo.size(); J !=
E; ++J) {
273 const BasicBlockInfo &BBI = BBInfo[J];
280bool CSKYConstantIslands::runOnMachineFunction(MachineFunction &Mf) {
286 << MCP->
getConstants().size() <<
" CP entries, aligned to "
290 MFI = MF->
getInfo<CSKYMachineFunctionInfo>();
299 bool MadeChange =
false;
303 std::vector<MachineInstr *> CPEMIs;
305 doInitialPlacement(CPEMIs);
308 initPICLabelUId(CPEMIs.size());
313 initializeFunctionInfo(CPEMIs);
318 MadeChange |= removeUnusedCPEntries();
322 unsigned NoCPIters = 0, NoBRIters = 0;
325 LLVM_DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
326 bool CPChange =
false;
327 for (
unsigned I = 0,
E = CPUsers.size();
I !=
E; ++
I)
328 CPChange |= handleConstantPoolUser(
I);
329 if (CPChange && ++NoCPIters > 30)
335 NewWaterList.
clear();
337 LLVM_DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
338 bool BRChange =
false;
339 for (
unsigned I = 0,
E = ImmBranches.size();
I !=
E; ++
I)
340 BRChange |= fixupImmediateBr(ImmBranches[
I]);
341 if (BRChange && ++NoBRIters > 30)
344 if (!CPChange && !BRChange)
361void CSKYConstantIslands::doInitialPlacement(
362 std::vector<MachineInstr *> &CPEMIs) {
386 const std::vector<MachineConstantPoolEntry> &CPs = MCP->
getConstants();
389 for (
unsigned I = 0,
E = CPs.size();
I !=
E; ++
I) {
390 unsigned Size = CPs[
I].getSizeInBytes(TD);
391 assert(
Size >= 4 &&
"Too small constant pool entry");
392 Align Alignment = CPs[
I].getAlign();
398 unsigned LogAlign =
Log2(Alignment);
401 MachineInstr *CPEMI =
407 CPEMIs.push_back(CPEMI);
411 for (
unsigned A = LogAlign + 1;
A <=
Log2(MaxAlign); ++
A)
412 if (InsPoint[
A] == InsAt)
415 CPEntries.emplace_back(1, CPEntry(CPEMI,
I));
417 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" <<
I <<
" to end of function, size = "
418 <<
Size <<
", align = " << Alignment.
value() <<
'\n');
429 if (std::next(
MBBI) ==
MBB->getParent()->end())
444CSKYConstantIslands::CPEntry *
445CSKYConstantIslands::findConstPoolEntry(
unsigned CPI,
446 const MachineInstr *CPEMI) {
447 std::vector<CPEntry> &CPEs = CPEntries[CPI];
450 for (
unsigned I = 0,
E = CPEs.size();
I !=
E; ++
I) {
451 if (CPEs[
I].CPEMI == CPEMI)
459Align CSKYConstantIslands::getCPEAlign(
const MachineInstr &CPEMI) {
463 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
470void CSKYConstantIslands::initializeFunctionInfo(
471 const std::vector<MachineInstr *> &CPEMIs) {
480 computeBlockSize(&*
I);
483 adjustBBOffsetsAfter(&MF->
front());
486 for (MachineBasicBlock &
MBB : *MF) {
490 WaterList.push_back(&
MBB);
491 for (MachineInstr &
MI :
MBB) {
492 if (
MI.isDebugInstr())
495 int Opc =
MI.getOpcode();
496 if (
MI.isBranch() && !
MI.isIndirectBranch()) {
497 bool IsCond =
MI.isConditionalBranch();
500 int UOpc = CSKY::BR32;
502 switch (
MI.getOpcode()) {
516 unsigned MaxOffs = ((1 << (
Bits - 1)) - 1) * Scale;
517 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, IsCond, UOpc));
520 if (
Opc == CSKY::CONSTPOOL_ENTRY)
524 for (
unsigned Op = 0,
E =
MI.getNumOperands();
Op !=
E; ++
Op)
525 if (
MI.getOperand(
Op).isCPI()) {
540 case CSKY::PseudoTLSLA32:
544 case CSKY::LRW32_Gen:
560 unsigned CPI =
MI.getOperand(
Op).getIndex();
561 MachineInstr *CPEMI = CPEMIs[CPI];
562 unsigned MaxOffs = ((1 <<
Bits) - 1) * Scale;
563 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk));
566 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
567 assert(CPE &&
"Cannot find a corresponding CPEntry!");
576void CSKYConstantIslands::computeBlockSize(MachineBasicBlock *
MBB) {
580 for (
const MachineInstr &
MI : *
MBB)
587unsigned CSKYConstantIslands::getOffsetOf(MachineInstr *
MI)
const {
588 MachineBasicBlock *
MBB =
MI->getParent();
597 assert(
I !=
MBB->
end() &&
"Didn't find MI in its own basic block?");
607 return LHS->getNumber() <
RHS->getNumber();
613void CSKYConstantIslands::updateForInsertedWaterBlock(
614 MachineBasicBlock *NewBB) {
620 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
625 WaterList.insert(IP, NewBB);
628unsigned CSKYConstantIslands::getUserOffset(CPUser &U)
const {
629 unsigned UserOffset = getOffsetOf(
U.MI);
640CSKYConstantIslands::splitBlockBeforeInstr(MachineInstr &
MI) {
641 MachineBasicBlock *OrigBB =
MI.getParent();
644 MachineBasicBlock *NewBB =
647 MF->insert(
MBBI, NewBB);
670 MF->RenumberBlocks(NewBB);
674 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
681 MachineBasicBlock *WaterBB = *IP;
682 if (WaterBB == OrigBB)
683 WaterList.insert(std::next(IP), NewBB);
685 WaterList.insert(IP, OrigBB);
686 NewWaterList.
insert(OrigBB);
693 computeBlockSize(OrigBB);
697 computeBlockSize(NewBB);
700 adjustBBOffsetsAfter(OrigBB);
708bool CSKYConstantIslands::isOffsetInRange(
unsigned UserOffset,
709 unsigned TrialOffset,
710 unsigned MaxDisp,
bool NegativeOK) {
711 if (UserOffset <= TrialOffset) {
713 if (TrialOffset - UserOffset <= MaxDisp)
715 }
else if (NegativeOK) {
716 if (UserOffset - TrialOffset <= MaxDisp)
726bool CSKYConstantIslands::isWaterInRange(
unsigned UserOffset,
727 MachineBasicBlock *Water, CPUser &U,
729 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset();
730 unsigned NextBlockOffset;
731 Align NextBlockAlignment;
733 if (NextBlock == MF->end()) {
734 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
735 NextBlockAlignment =
Align(4);
737 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
738 NextBlockAlignment = NextBlock->getAlignment();
740 unsigned Size =
U.CPEMI->getOperand(2).getImm();
741 unsigned CPEEnd = CPEOffset +
Size;
746 if (CPEEnd > NextBlockOffset) {
747 Growth = CPEEnd - NextBlockOffset;
755 if (CPEOffset < UserOffset)
756 UserOffset += Growth;
761 return isOffsetInRange(UserOffset, CPEOffset, U);
766bool CSKYConstantIslands::isCPEntryInRange(MachineInstr *
MI,
769 unsigned MaxDisp,
bool NegOk,
771 unsigned CPEOffset = getOffsetOf(CPEMI);
775 unsigned Block =
MI->getParent()->getNumber();
776 const BasicBlockInfo &BBI = BBInfo[
Block];
778 <<
" max delta=" << MaxDisp
779 <<
format(
" insn address=%#x", UserOffset) <<
" in "
782 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
783 int(CPEOffset - UserOffset));
787 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
794 if (
MBB->pred_size() != 1 ||
MBB->succ_size() != 1)
805void CSKYConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
807 for (
unsigned I = BBNum + 1,
E = MF->getNumBlockIDs();
I <
E; ++
I) {
810 unsigned Offset = BBInfo[
I - 1].Offset + BBInfo[
I - 1].Size;
819bool CSKYConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
820 MachineInstr *CPEMI) {
822 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
823 assert(CPE &&
"Unexpected!");
824 if (--CPE->RefCount == 0) {
825 removeDeadCPEMI(CPEMI);
826 CPE->CPEMI =
nullptr;
839int CSKYConstantIslands::findInRangeCPEntry(CPUser &U,
unsigned UserOffset) {
840 MachineInstr *UserMI =
U.MI;
841 MachineInstr *CPEMI =
U.CPEMI;
844 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
U.getMaxDisp(),
U.NegOk,
852 std::vector<CPEntry> &CPEs = CPEntries[CPI];
853 for (
unsigned I = 0,
E = CPEs.size();
I !=
E; ++
I) {
855 if (CPEs[
I].CPEMI == CPEMI)
858 if (CPEs[
I].CPEMI ==
nullptr)
860 if (isCPEntryInRange(UserMI, UserOffset, CPEs[
I].CPEMI,
U.getMaxDisp(),
863 << CPEs[
I].CPI <<
"\n");
865 U.CPEMI = CPEs[
I].CPEMI;
876 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
885 unsigned Bits, Scale;
900 unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale;
912bool CSKYConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
913 water_iterator &WaterIter) {
914 if (WaterList.empty())
917 unsigned BestGrowth = ~0
u;
918 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
920 MachineBasicBlock *WaterBB = *IP;
930 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
931 (WaterBB->
getNumber() <
U.HighWaterMark->getNumber() ||
932 NewWaterList.
count(WaterBB)) &&
933 Growth < BestGrowth) {
938 <<
" Growth=" << Growth <<
'\n');
947 return BestGrowth != ~0
u;
957void CSKYConstantIslands::createNewWater(
unsigned CPUserIndex,
959 MachineBasicBlock *&NewMBB) {
960 CPUser &
U = CPUsers[CPUserIndex];
961 MachineInstr *UserMI =
U.MI;
962 MachineInstr *CPEMI =
U.CPEMI;
963 MachineBasicBlock *UserMBB = UserMI->
getParent();
964 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->
getNumber()];
972 unsigned CPEOffset = UserBBI.
postOffset() + Delta;
974 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
976 <<
format(
", expected CPE offset %#x\n", CPEOffset));
985 int UncondBr = CSKY::BR32;
990 ImmBranches.push_back(
991 ImmBranch(&UserMBB->
back(), MaxDisp,
false, UncondBr));
992 BBInfo[UserMBB->
getNumber()].Size +=
TII->getInstSizeInBytes(*NewMI);
993 adjustBBOffsetsAfter(UserMBB);
1004 unsigned BaseInsertOffset = UserOffset +
U.getMaxDisp();
1011 BaseInsertOffset -= 4;
1014 <<
" la=" <<
Log2(Align) <<
'\n');
1020 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1024 unsigned EndInsertOffset =
1028 unsigned CPUIndex = CPUserIndex + 1;
1029 unsigned NumCPUsers = CPUsers.size();
1030 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1031 Offset < BaseInsertOffset;
1033 assert(
MI != UserMBB->
end() &&
"Fell off end of block");
1034 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].
MI ==
MI) {
1035 CPUser &
U = CPUsers[CPUIndex];
1036 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1038 BaseInsertOffset -=
Align.value();
1039 EndInsertOffset -=
Align.value();
1045 EndInsertOffset +=
U.CPEMI->getOperand(2).getImm();
1050 NewMBB = splitBlockBeforeInstr(*--
MI);
1057bool CSKYConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1058 CPUser &
U = CPUsers[CPUserIndex];
1059 MachineInstr *UserMI =
U.MI;
1060 MachineInstr *CPEMI =
U.CPEMI;
1064 unsigned UserOffset = getUserOffset(U);
1068 int result = findInRangeCPEntry(U, UserOffset);
1075 MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
1076 MachineBasicBlock *NewMBB;
1078 if (findAvailableWater(U, UserOffset, IP)) {
1080 MachineBasicBlock *WaterBB = *IP;
1085 if (NewWaterList.
erase(WaterBB))
1086 NewWaterList.
insert(NewIsland);
1092 createNewWater(CPUserIndex, UserOffset, NewMBB);
1099 MachineBasicBlock *WaterBB = &*--NewMBB->
getIterator();
1101 if (IP != WaterList.end())
1102 NewWaterList.
erase(WaterBB);
1105 NewWaterList.
insert(NewIsland);
1112 if (IP != WaterList.end())
1113 WaterList.erase(IP);
1119 updateForInsertedWaterBlock(NewIsland);
1122 decrementCPEReferenceCount(CPI, CPEMI);
1126 unsigned ID = createPICLabelUId();
1130 U.HighWaterMark = NewIsland;
1135 CPEntries[CPI].push_back(CPEntry(
U.CPEMI,
ID, 1));
1143 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1153 dbgs() <<
" Moved CPE to #" <<
ID <<
" CPI=" << CPI
1161void CSKYConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
1162 MachineBasicBlock *CPEBB = CPEMI->
getParent();
1167 if (CPEBB->
empty()) {
1177 adjustBBOffsetsAfter(CPEBB);
1187bool CSKYConstantIslands::removeUnusedCPEntries() {
1188 unsigned MadeChange =
false;
1189 for (
unsigned I = 0,
E = CPEntries.size();
I !=
E; ++
I) {
1190 std::vector<CPEntry> &CPEs = CPEntries[
I];
1191 for (
unsigned J = 0, Ee = CPEs.size(); J != Ee; ++J) {
1192 if (CPEs[J].RefCount == 0 && CPEs[J].CPEMI) {
1193 removeDeadCPEMI(CPEs[J].CPEMI);
1194 CPEs[J].CPEMI =
nullptr;
1204bool CSKYConstantIslands::isBBInRange(MachineInstr *
MI,
1205 MachineBasicBlock *DestBB,
1207 unsigned BrOffset = getOffsetOf(
MI);
1208 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1212 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(
MI)
1213 <<
" to " << DestOffset <<
" offset "
1214 <<
int(DestOffset - BrOffset) <<
"\t" << *
MI);
1216 if (BrOffset <= DestOffset) {
1218 if (DestOffset - BrOffset <= MaxDisp)
1221 if (BrOffset - DestOffset <= MaxDisp)
1229bool CSKYConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1230 MachineInstr *
MI = Br.MI;
1231 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(*
MI);
1234 if (isBBInRange(
MI, DestBB, Br.MaxDisp))
1238 return fixupUnconditionalBr(Br);
1239 return fixupConditionalBr(Br);
1246bool CSKYConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1247 MachineInstr *
MI = Br.MI;
1248 MachineBasicBlock *
MBB =
MI->getParent();
1254 Br.MaxDisp = ((1 << (26 - 1)) - 1) * 2;
1255 MI->setDesc(
TII->get(CSKY::BSR32_BR));
1257 adjustBBOffsetsAfter(
MBB);
1268bool CSKYConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1269 MachineInstr *
MI = Br.MI;
1270 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(*
MI);
1274 Cond.push_back(
MI->getOperand(0));
1288 MachineBasicBlock *
MBB =
MI->getParent();
1289 MachineInstr *BMI = &
MBB->
back();
1303 MachineBasicBlock *NewDest =
TII->getBranchDestBlock(*BMI);
1304 if (isBBInRange(
MI, NewDest, Br.MaxDisp)) {
1306 dbgs() <<
" Invert Bcc condition and swap its destination with "
1309 MI->getOperand(
MI->getNumExplicitOperands() - 1).setMBB(NewDest);
1311 MI->setDesc(
TII->get(
Cond[0].getImm()));
1318 splitBlockBeforeInstr(*
MI);
1321 int Delta =
TII->getInstSizeInBytes(
MBB->
back());
1334 <<
" also invert condition and change dest. to "
1341 .
addReg(
MI->getOperand(0).getReg())
1349 ImmBranches.push_back(ImmBranch(&
MBB->
back(), MaxDisp,
false, Br.UncondBr));
1352 BBInfo[
MI->getParent()->getNumber()].Size -=
TII->getInstSizeInBytes(*
MI);
1353 MI->eraseFromParent();
1354 adjustBBOffsetsAfter(
MBB);
1360 return new CSKYConstantIslands();
1364 "CSKY constant island placement and branch shortening pass",
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static unsigned getUnconditionalBrDisp(int Opc)
getUnconditionalBrDisp - Returns the maximum displacement that can fit in the specific unconditional ...
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool bbHasFallthrough(MachineBasicBlock *MBB)
BBHasFallthrough - Return true if the specified basic block can fallthrough into the block immediatel...
static bool bbIsJumpedOver(MachineBasicBlock *MBB)
BBIsJumpedOver - Return true of the specified basic block's only predecessor unconditionally branches...
static bool compareMbbNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)
CompareMBBNumbers - Little predicate function to sort the WaterList by MBB ID.
#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 ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
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)
const CSKYInstrInfo * getInstrInfo() const override
FunctionPass class - This class is used to implement most global optimizations.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
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.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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
Align getConstantPoolAlign() const
Return the alignment required by the whole constant pool, of which the first element must be aligned.
const std::vector< MachineConstantPoolEntry > & getConstants() const
bool isEmpty() const
isEmpty - Return true if this constant pool contains no constants.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void ensureAlignment(Align A)
ensureAlignment - Make sure the function is at least A bytes aligned.
void push_back(MachineBasicBlock *MBB)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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.
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
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
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
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
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
void setMBB(MachineBasicBlock *MBB)
static MachineOperand CreateImm(int64_t Val)
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
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.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
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)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
FunctionPass * createCSKYConstantIslandPass()
Returns a pass that converts branches to long branches.
DWARFExpression::Operation Op
unsigned Log2(Align A)
Returns the log2 of the alignment.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
constexpr 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.