38#include "llvm/Config/llvm-config.h"
59#define DEBUG_TYPE "CSKY-constant-islands"
62STATISTIC(NumSplit,
"Number of uncond branches inserted");
63STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
64STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
107 unsigned postOffset()
const {
return Offset +
Size; }
110 std::vector<BasicBlockInfo> BBInfo;
115 std::vector<MachineBasicBlock *> WaterList;
119 SmallPtrSet<MachineBasicBlock *, 4> NewWaterList;
121 using water_iterator = std::vector<MachineBasicBlock *>::iterator;
138 MachineBasicBlock *HighWaterMark;
146 CPUser(MachineInstr *Mi, MachineInstr *Cpemi,
unsigned Maxdisp,
bool Neg)
147 : MI(Mi), CPEMI(Cpemi), MaxDisp(Maxdisp), NegOk(Neg) {
148 HighWaterMark = CPEMI->getParent();
152 unsigned getMaxDisp()
const {
return MaxDisp - 16; }
154 void setMaxDisp(
unsigned Val) { MaxDisp = Val; }
159 std::vector<CPUser> CPUsers;
169 CPEntry(MachineInstr *Cpemi,
unsigned Cpi,
unsigned Rc = 0)
170 : CPEMI(Cpemi), CPI(Cpi), RefCount(Rc) {}
178 std::vector<std::vector<CPEntry>> CPEntries;
186 unsigned MaxDisp : 31;
191 ImmBranch(MachineInstr *Mi,
unsigned Maxdisp,
bool Cond,
int Ubr)
192 : MI(Mi), MaxDisp(Maxdisp), IsCond(
Cond), UncondBr(Ubr) {}
197 std::vector<ImmBranch> ImmBranches;
199 const CSKYSubtarget *STI =
nullptr;
200 const CSKYInstrInfo *TII;
201 CSKYMachineFunctionInfo *MFI;
202 MachineFunction *MF =
nullptr;
203 MachineConstantPool *MCP =
nullptr;
205 unsigned PICLabelUId;
207 void initPICLabelUId(
unsigned UId) { PICLabelUId = UId; }
209 unsigned createPICLabelUId() {
return PICLabelUId++; }
214 CSKYConstantIslands() : MachineFunctionPass(ID) {}
216 StringRef getPassName()
const override {
return "CSKY Constant Islands"; }
218 bool runOnMachineFunction(MachineFunction &
F)
override;
220 MachineFunctionProperties getRequiredProperties()
const override {
221 return MachineFunctionProperties().setNoVRegs();
224 void doInitialPlacement(std::vector<MachineInstr *> &CPEMIs);
225 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
226 Align getCPEAlign(
const MachineInstr &CPEMI);
227 void initializeFunctionInfo(
const std::vector<MachineInstr *> &CPEMIs);
228 unsigned getOffsetOf(MachineInstr *
MI)
const;
229 unsigned getUserOffset(CPUser &)
const;
232 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
unsigned Disp,
234 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
237 void computeBlockSize(MachineBasicBlock *
MBB);
238 MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &
MI);
239 void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
240 void adjustBBOffsetsAfter(MachineBasicBlock *BB);
241 bool decrementCPEReferenceCount(
unsigned CPI, MachineInstr *CPEMI);
242 int findInRangeCPEntry(CPUser &U,
unsigned UserOffset);
243 bool findAvailableWater(CPUser &U,
unsigned UserOffset,
244 water_iterator &WaterIter);
245 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
246 MachineBasicBlock *&NewMBB);
247 bool handleConstantPoolUser(
unsigned CPUserIndex);
248 void removeDeadCPEMI(MachineInstr *CPEMI);
249 bool removeUnusedCPEntries();
250 bool isCPEntryInRange(MachineInstr *
MI,
unsigned UserOffset,
251 MachineInstr *CPEMI,
unsigned Disp,
bool NegOk,
252 bool DoDump =
false);
253 bool isWaterInRange(
unsigned UserOffset, MachineBasicBlock *Water, CPUser &U,
255 bool isBBInRange(MachineInstr *
MI, MachineBasicBlock *BB,
unsigned Disp);
256 bool fixupImmediateBr(ImmBranch &Br);
257 bool fixupConditionalBr(ImmBranch &Br);
258 bool fixupUnconditionalBr(ImmBranch &Br);
262char CSKYConstantIslands::ID = 0;
264bool CSKYConstantIslands::isOffsetInRange(
unsigned UserOffset,
265 unsigned TrialOffset,
267 return isOffsetInRange(UserOffset, TrialOffset,
U.getMaxDisp(),
U.NegOk);
270#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
273 for (
unsigned J = 0,
E = BBInfo.size(); J !=
E; ++J) {
274 const BasicBlockInfo &BBI = BBInfo[J];
281bool CSKYConstantIslands::runOnMachineFunction(MachineFunction &Mf) {
287 << MCP->
getConstants().size() <<
" CP entries, aligned to "
291 MFI = MF->
getInfo<CSKYMachineFunctionInfo>();
300 bool MadeChange =
false;
304 std::vector<MachineInstr *> CPEMIs;
306 doInitialPlacement(CPEMIs);
309 initPICLabelUId(CPEMIs.size());
314 initializeFunctionInfo(CPEMIs);
319 MadeChange |= removeUnusedCPEntries();
323 unsigned NoCPIters = 0, NoBRIters = 0;
326 LLVM_DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
327 bool CPChange =
false;
328 for (
unsigned I = 0,
E = CPUsers.size();
I !=
E; ++
I)
329 CPChange |= handleConstantPoolUser(
I);
330 if (CPChange && ++NoCPIters > 30)
336 NewWaterList.
clear();
338 LLVM_DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
339 bool BRChange =
false;
340 for (
unsigned I = 0,
E = ImmBranches.size();
I !=
E; ++
I)
341 BRChange |= fixupImmediateBr(ImmBranches[
I]);
342 if (BRChange && ++NoBRIters > 30)
345 if (!CPChange && !BRChange)
362void CSKYConstantIslands::doInitialPlacement(
363 std::vector<MachineInstr *> &CPEMIs) {
387 const std::vector<MachineConstantPoolEntry> &CPs = MCP->
getConstants();
390 for (
unsigned I = 0,
E = CPs.size();
I !=
E; ++
I) {
391 unsigned Size = CPs[
I].getSizeInBytes(TD);
392 assert(
Size >= 4 &&
"Too small constant pool entry");
393 Align Alignment = CPs[
I].getAlign();
399 unsigned LogAlign =
Log2(Alignment);
402 MachineInstr *CPEMI =
408 CPEMIs.push_back(CPEMI);
412 for (
unsigned A = LogAlign + 1;
A <=
Log2(MaxAlign); ++
A)
413 if (InsPoint[
A] == InsAt)
416 CPEntries.emplace_back(1, CPEntry(CPEMI,
I));
418 LLVM_DEBUG(
dbgs() <<
"Moved CPI#" <<
I <<
" to end of function, size = "
419 <<
Size <<
", align = " << Alignment.
value() <<
'\n');
430 if (std::next(
MBBI) ==
MBB->getParent()->end())
445CSKYConstantIslands::CPEntry *
446CSKYConstantIslands::findConstPoolEntry(
unsigned CPI,
447 const MachineInstr *CPEMI) {
448 std::vector<CPEntry> &CPEs = CPEntries[CPI];
451 for (
unsigned I = 0,
E = CPEs.size();
I !=
E; ++
I) {
452 if (CPEs[
I].CPEMI == CPEMI)
460Align CSKYConstantIslands::getCPEAlign(
const MachineInstr &CPEMI) {
464 assert(CPI < MCP->getConstants().
size() &&
"Invalid constant pool index.");
471void CSKYConstantIslands::initializeFunctionInfo(
472 const std::vector<MachineInstr *> &CPEMIs) {
481 computeBlockSize(&*
I);
484 adjustBBOffsetsAfter(&MF->
front());
487 for (MachineBasicBlock &
MBB : *MF) {
491 WaterList.push_back(&
MBB);
492 for (MachineInstr &
MI :
MBB) {
493 if (
MI.isDebugInstr())
496 int Opc =
MI.getOpcode();
497 if (
MI.isBranch() && !
MI.isIndirectBranch()) {
498 bool IsCond =
MI.isConditionalBranch();
501 int UOpc = CSKY::BR32;
503 switch (
MI.getOpcode()) {
517 unsigned MaxOffs = ((1 << (
Bits - 1)) - 1) * Scale;
518 ImmBranches.push_back(ImmBranch(&
MI, MaxOffs, IsCond, UOpc));
521 if (
Opc == CSKY::CONSTPOOL_ENTRY)
525 for (
unsigned Op = 0,
E =
MI.getNumOperands();
Op !=
E; ++
Op)
526 if (
MI.getOperand(
Op).isCPI()) {
541 case CSKY::PseudoTLSLA32:
545 case CSKY::LRW32_Gen:
561 unsigned CPI =
MI.getOperand(
Op).getIndex();
562 MachineInstr *CPEMI = CPEMIs[CPI];
563 unsigned MaxOffs = ((1 <<
Bits) - 1) * Scale;
564 CPUsers.push_back(CPUser(&
MI, CPEMI, MaxOffs, NegOk));
567 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
568 assert(CPE &&
"Cannot find a corresponding CPEntry!");
577void CSKYConstantIslands::computeBlockSize(MachineBasicBlock *
MBB) {
581 for (
const MachineInstr &
MI : *
MBB)
588unsigned CSKYConstantIslands::getOffsetOf(MachineInstr *
MI)
const {
589 MachineBasicBlock *
MBB =
MI->getParent();
598 assert(
I !=
MBB->
end() &&
"Didn't find MI in its own basic block?");
608 return LHS->getNumber() <
RHS->getNumber();
614void CSKYConstantIslands::updateForInsertedWaterBlock(
615 MachineBasicBlock *NewBB) {
621 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
626 WaterList.insert(IP, NewBB);
629unsigned CSKYConstantIslands::getUserOffset(CPUser &U)
const {
630 unsigned UserOffset = getOffsetOf(
U.MI);
641CSKYConstantIslands::splitBlockBeforeInstr(MachineInstr &
MI) {
642 MachineBasicBlock *OrigBB =
MI.getParent();
645 MachineBasicBlock *NewBB =
648 MF->insert(
MBBI, NewBB);
671 MF->RenumberBlocks(NewBB);
675 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
682 MachineBasicBlock *WaterBB = *IP;
683 if (WaterBB == OrigBB)
684 WaterList.insert(std::next(IP), NewBB);
686 WaterList.insert(IP, OrigBB);
687 NewWaterList.
insert(OrigBB);
694 computeBlockSize(OrigBB);
698 computeBlockSize(NewBB);
701 adjustBBOffsetsAfter(OrigBB);
709bool CSKYConstantIslands::isOffsetInRange(
unsigned UserOffset,
710 unsigned TrialOffset,
711 unsigned MaxDisp,
bool NegativeOK) {
712 if (UserOffset <= TrialOffset) {
714 if (TrialOffset - UserOffset <= MaxDisp)
716 }
else if (NegativeOK) {
717 if (UserOffset - TrialOffset <= MaxDisp)
727bool CSKYConstantIslands::isWaterInRange(
unsigned UserOffset,
728 MachineBasicBlock *Water, CPUser &U,
730 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset();
731 unsigned NextBlockOffset;
732 Align NextBlockAlignment;
734 if (NextBlock == MF->end()) {
735 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
736 NextBlockAlignment =
Align(4);
738 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
739 NextBlockAlignment = NextBlock->getAlignment();
741 unsigned Size =
U.CPEMI->getOperand(2).getImm();
742 unsigned CPEEnd = CPEOffset +
Size;
747 if (CPEEnd > NextBlockOffset) {
748 Growth = CPEEnd - NextBlockOffset;
756 if (CPEOffset < UserOffset)
757 UserOffset += Growth;
762 return isOffsetInRange(UserOffset, CPEOffset, U);
767bool CSKYConstantIslands::isCPEntryInRange(MachineInstr *
MI,
770 unsigned MaxDisp,
bool NegOk,
772 unsigned CPEOffset = getOffsetOf(CPEMI);
776 unsigned Block =
MI->getParent()->getNumber();
777 const BasicBlockInfo &BBI = BBInfo[
Block];
779 <<
" max delta=" << MaxDisp
780 <<
format(
" insn address=%#x", UserOffset) <<
" in "
783 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
784 int(CPEOffset - UserOffset));
788 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
795 if (
MBB->pred_size() != 1 ||
MBB->succ_size() != 1)
806void CSKYConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
808 for (
unsigned I = BBNum + 1,
E = MF->getNumBlockIDs();
I <
E; ++
I) {
811 unsigned Offset = BBInfo[
I - 1].Offset + BBInfo[
I - 1].Size;
820bool CSKYConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
821 MachineInstr *CPEMI) {
823 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
824 assert(CPE &&
"Unexpected!");
825 if (--CPE->RefCount == 0) {
826 removeDeadCPEMI(CPEMI);
827 CPE->CPEMI =
nullptr;
840int CSKYConstantIslands::findInRangeCPEntry(CPUser &U,
unsigned UserOffset) {
841 MachineInstr *UserMI =
U.MI;
842 MachineInstr *CPEMI =
U.CPEMI;
845 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
U.getMaxDisp(),
U.NegOk,
853 std::vector<CPEntry> &CPEs = CPEntries[CPI];
854 for (
unsigned I = 0,
E = CPEs.size();
I !=
E; ++
I) {
856 if (CPEs[
I].CPEMI == CPEMI)
859 if (CPEs[
I].CPEMI ==
nullptr)
861 if (isCPEntryInRange(UserMI, UserOffset, CPEs[
I].CPEMI,
U.getMaxDisp(),
864 << CPEs[
I].CPI <<
"\n");
866 U.CPEMI = CPEs[
I].CPEMI;
877 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
886 unsigned Bits, Scale;
901 unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale;
913bool CSKYConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
914 water_iterator &WaterIter) {
915 if (WaterList.empty())
918 unsigned BestGrowth = ~0
u;
919 for (water_iterator IP = std::prev(WaterList.end()),
B = WaterList.begin();;
921 MachineBasicBlock *WaterBB = *IP;
931 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
932 (WaterBB->
getNumber() <
U.HighWaterMark->getNumber() ||
933 NewWaterList.
count(WaterBB)) &&
934 Growth < BestGrowth) {
939 <<
" Growth=" << Growth <<
'\n');
948 return BestGrowth != ~0
u;
958void CSKYConstantIslands::createNewWater(
unsigned CPUserIndex,
960 MachineBasicBlock *&NewMBB) {
961 CPUser &
U = CPUsers[CPUserIndex];
962 MachineInstr *UserMI =
U.MI;
963 MachineInstr *CPEMI =
U.CPEMI;
964 MachineBasicBlock *UserMBB = UserMI->
getParent();
965 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->
getNumber()];
973 unsigned CPEOffset = UserBBI.
postOffset() + Delta;
975 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
977 <<
format(
", expected CPE offset %#x\n", CPEOffset));
986 int UncondBr = CSKY::BR32;
991 ImmBranches.push_back(
992 ImmBranch(&UserMBB->
back(), MaxDisp,
false, UncondBr));
993 BBInfo[UserMBB->
getNumber()].Size +=
TII->getInstSizeInBytes(*NewMI);
994 adjustBBOffsetsAfter(UserMBB);
1005 unsigned BaseInsertOffset = UserOffset +
U.getMaxDisp();
1012 BaseInsertOffset -= 4;
1015 <<
" la=" <<
Log2(Align) <<
'\n');
1021 if (BaseInsertOffset + 8 >= UserBBI.
postOffset()) {
1025 unsigned EndInsertOffset =
1029 unsigned CPUIndex = CPUserIndex + 1;
1030 unsigned NumCPUsers = CPUsers.size();
1031 for (
unsigned Offset = UserOffset +
TII->getInstSizeInBytes(*UserMI);
1032 Offset < BaseInsertOffset;
1034 assert(
MI != UserMBB->
end() &&
"Fell off end of block");
1035 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].
MI ==
MI) {
1036 CPUser &
U = CPUsers[CPUIndex];
1037 if (!isOffsetInRange(
Offset, EndInsertOffset, U)) {
1039 BaseInsertOffset -=
Align.value();
1040 EndInsertOffset -=
Align.value();
1046 EndInsertOffset +=
U.CPEMI->getOperand(2).getImm();
1051 NewMBB = splitBlockBeforeInstr(*--
MI);
1058bool CSKYConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1059 CPUser &
U = CPUsers[CPUserIndex];
1060 MachineInstr *UserMI =
U.MI;
1061 MachineInstr *CPEMI =
U.CPEMI;
1065 unsigned UserOffset = getUserOffset(U);
1069 int result = findInRangeCPEntry(U, UserOffset);
1076 MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
1077 MachineBasicBlock *NewMBB;
1079 if (findAvailableWater(U, UserOffset, IP)) {
1081 MachineBasicBlock *WaterBB = *IP;
1086 if (NewWaterList.
erase(WaterBB))
1087 NewWaterList.
insert(NewIsland);
1093 createNewWater(CPUserIndex, UserOffset, NewMBB);
1100 MachineBasicBlock *WaterBB = &*--NewMBB->
getIterator();
1102 if (IP != WaterList.end())
1103 NewWaterList.
erase(WaterBB);
1106 NewWaterList.
insert(NewIsland);
1113 if (IP != WaterList.end())
1114 WaterList.erase(IP);
1120 updateForInsertedWaterBlock(NewIsland);
1123 decrementCPEReferenceCount(CPI, CPEMI);
1127 unsigned ID = createPICLabelUId();
1131 U.HighWaterMark = NewIsland;
1136 CPEntries[CPI].push_back(CPEntry(
U.CPEMI,
ID, 1));
1144 adjustBBOffsetsAfter(&*--NewIsland->
getIterator());
1154 dbgs() <<
" Moved CPE to #" <<
ID <<
" CPI=" << CPI
1162void CSKYConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
1163 MachineBasicBlock *CPEBB = CPEMI->
getParent();
1168 if (CPEBB->
empty()) {
1178 adjustBBOffsetsAfter(CPEBB);
1188bool CSKYConstantIslands::removeUnusedCPEntries() {
1189 unsigned MadeChange =
false;
1190 for (
unsigned I = 0,
E = CPEntries.size();
I !=
E; ++
I) {
1191 std::vector<CPEntry> &CPEs = CPEntries[
I];
1192 for (
unsigned J = 0, Ee = CPEs.size(); J != Ee; ++J) {
1193 if (CPEs[J].RefCount == 0 && CPEs[J].CPEMI) {
1194 removeDeadCPEMI(CPEs[J].CPEMI);
1195 CPEs[J].CPEMI =
nullptr;
1205bool CSKYConstantIslands::isBBInRange(MachineInstr *
MI,
1206 MachineBasicBlock *DestBB,
1208 unsigned BrOffset = getOffsetOf(
MI);
1209 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1213 <<
" max delta=" << MaxDisp <<
" from " << getOffsetOf(
MI)
1214 <<
" to " << DestOffset <<
" offset "
1215 <<
int(DestOffset - BrOffset) <<
"\t" << *
MI);
1217 if (BrOffset <= DestOffset) {
1219 if (DestOffset - BrOffset <= MaxDisp)
1222 if (BrOffset - DestOffset <= MaxDisp)
1230bool CSKYConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1231 MachineInstr *
MI = Br.MI;
1232 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(*
MI);
1235 if (isBBInRange(
MI, DestBB, Br.MaxDisp))
1239 return fixupUnconditionalBr(Br);
1240 return fixupConditionalBr(Br);
1247bool CSKYConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1248 MachineInstr *
MI = Br.MI;
1249 MachineBasicBlock *
MBB =
MI->getParent();
1255 Br.MaxDisp = ((1 << (26 - 1)) - 1) * 2;
1256 MI->setDesc(
TII->get(CSKY::BSR32_BR));
1258 adjustBBOffsetsAfter(
MBB);
1269bool CSKYConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1270 MachineInstr *
MI = Br.MI;
1271 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(*
MI);
1275 Cond.push_back(
MI->getOperand(0));
1289 MachineBasicBlock *
MBB =
MI->getParent();
1290 MachineInstr *BMI = &
MBB->
back();
1304 MachineBasicBlock *NewDest =
TII->getBranchDestBlock(*BMI);
1305 if (isBBInRange(
MI, NewDest, Br.MaxDisp)) {
1307 dbgs() <<
" Invert Bcc condition and swap its destination with "
1310 MI->getOperand(
MI->getNumExplicitOperands() - 1).setMBB(NewDest);
1312 MI->setDesc(
TII->get(
Cond[0].getImm()));
1319 splitBlockBeforeInstr(*
MI);
1322 int Delta =
TII->getInstSizeInBytes(
MBB->
back());
1335 <<
" also invert condition and change dest. to "
1342 .
addReg(
MI->getOperand(0).getReg())
1350 ImmBranches.push_back(ImmBranch(&
MBB->
back(), MaxDisp,
false, Br.UncondBr));
1353 BBInfo[
MI->getParent()->getNumber()].Size -=
TII->getInstSizeInBytes(*
MI);
1354 MI->eraseFromParent();
1355 adjustBBOffsetsAfter(
MBB);
1361 return new CSKYConstantIslands();
1365 "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.
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.