24 #define DEBUG_TYPE "mips-constant-islands"
50 STATISTIC(NumCPEs,
"Number of constpool entries");
51 STATISTIC(NumSplit,
"Number of uncond branches inserted");
52 STATISTIC(NumCBrFixed,
"Number of cond branches fixed");
53 STATISTIC(NumUBrFixed,
"Number of uncond branches fixed");
58 cl::desc(
"Align constant islands in code"));
65 "mips-constant-islands-small-offset",
67 cl::desc(
"Make small offsets be this amount for testing purposes"),
75 "mips-constant-islands-no-load-relaxation",
77 cl::desc(
"Don't relax loads to long loads - for testing purposes"),
103 struct BasicBlockInfo {
124 unsigned postOffset(
unsigned LogAlign = 0)
const {
125 unsigned PO = Offset + Size;
129 BasicBlockInfo() : Offset(0), Size(0) {}
133 std::vector<BasicBlockInfo> BBInfo;
138 std::vector<MachineBasicBlock*> WaterList;
144 typedef std::vector<MachineBasicBlock*>::iterator water_iterator;
164 unsigned LongFormMaxDisp;
166 unsigned LongFormOpcode;
171 unsigned longformmaxdisp,
unsigned longformopcode)
172 :
MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
173 LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
175 HighWaterMark = CPEMI->getParent();
178 unsigned getMaxDisp()
const {
183 void setMaxDisp(
unsigned val) {
186 unsigned getLongFormMaxDisp()
const {
187 return LongFormMaxDisp;
189 unsigned getLongFormOpcode()
const {
190 return LongFormOpcode;
196 std::vector<CPUser> CPUsers;
205 CPEntry(
MachineInstr *cpemi,
unsigned cpi,
unsigned rc = 0)
206 : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
214 std::vector<std::vector<CPEntry> > CPEntries;
222 unsigned MaxDisp : 31;
225 ImmBranch(
MachineInstr *mi,
unsigned maxdisp,
bool cond,
int ubr)
226 :
MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
231 std::vector<ImmBranch> ImmBranches;
246 unsigned PICLabelUId;
247 bool PrescannedForConstants;
249 void initPICLabelUId(
unsigned UId) {
254 unsigned createPICLabelUId() {
255 return PICLabelUId++;
262 IsPIC(
TM.getRelocationModel() == Reloc::
PIC_),
265 PrescannedForConstants(
false){}
267 virtual const char *getPassName()
const {
268 return "Mips Constant Islands";
273 void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
274 CPEntry *findConstPoolEntry(
unsigned CPI,
const MachineInstr *CPEMI);
276 void initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs);
278 unsigned getUserOffset(CPUser&)
const;
282 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
283 unsigned Disp,
bool NegativeOK);
284 bool isOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
287 bool isLongFormOffsetInRange(
unsigned UserOffset,
unsigned TrialOffset,
294 bool decrementCPEReferenceCount(
unsigned CPI,
MachineInstr* CPEMI);
295 int findInRangeCPEntry(CPUser& U,
unsigned UserOffset);
296 int findLongFormInRangeCPEntry(CPUser& U,
unsigned UserOffset);
297 bool findAvailableWater(CPUser&U,
unsigned UserOffset,
298 water_iterator &WaterIter);
299 void createNewWater(
unsigned CPUserIndex,
unsigned UserOffset,
301 bool handleConstantPoolUser(
unsigned CPUserIndex);
303 bool removeUnusedCPEntries();
306 bool DoDump =
false);
308 CPUser &U,
unsigned &Growth);
310 bool fixupImmediateBr(ImmBranch &Br);
311 bool fixupConditionalBr(ImmBranch &Br);
312 bool fixupUnconditionalBr(ImmBranch &Br);
314 void prescanForConstants();
324 bool MipsConstantIslands::isLongFormOffsetInRange
325 (
unsigned UserOffset,
unsigned TrialOffset,
327 return isOffsetInRange(UserOffset, TrialOffset,
328 U.getLongFormMaxDisp(), U.NegOk);
331 bool MipsConstantIslands::isOffsetInRange
332 (
unsigned UserOffset,
unsigned TrialOffset,
334 return isOffsetInRange(UserOffset, TrialOffset,
335 U.getMaxDisp(), U.NegOk);
338 void MipsConstantIslands::dumpBBs() {
340 for (
unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
341 const BasicBlockInfo &BBI = BBInfo[J];
342 dbgs() <<
format(
"%08x BB#%u\t", BBI.Offset, J)
343 <<
format(
" size=%#x\n", BBInfo[J].Size);
350 return new MipsConstantIslands(tm);
358 DEBUG(
dbgs() <<
"constant island machine function " <<
"\n");
365 DEBUG(
dbgs() <<
"constant island processing " <<
"\n");
370 if (!PrescannedForConstants) prescanForConstants();
374 MF->getRegInfo().invalidateLiveness();
378 MF->RenumberBlocks();
380 bool MadeChange =
false;
384 std::vector<MachineInstr*> CPEMIs;
386 doInitialPlacement(CPEMIs);
389 initPICLabelUId(CPEMIs.size());
394 initializeFunctionInfo(CPEMIs);
399 MadeChange |= removeUnusedCPEntries();
403 unsigned NoCPIters = 0, NoBRIters = 0;
406 DEBUG(
dbgs() <<
"Beginning CP iteration #" << NoCPIters <<
'\n');
407 bool CPChange =
false;
408 for (
unsigned i = 0, e = CPUsers.size(); i != e; ++i)
409 CPChange |= handleConstantPoolUser(i);
410 if (CPChange && ++NoCPIters > 30)
416 NewWaterList.clear();
418 DEBUG(
dbgs() <<
"Beginning BR iteration #" << NoBRIters <<
'\n');
419 bool BRChange =
false;
420 for (
unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
421 BRChange |= fixupImmediateBr(ImmBranches[i]);
422 if (BRChange && ++NoBRIters > 30)
425 if (!CPChange && !BRChange)
443 MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
450 unsigned MaxAlign =
Log2_32(MCP->getConstantPoolAlignment());
468 const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
470 const DataLayout &
TD = *MF->getTarget().getDataLayout();
471 for (
unsigned i = 0, e = CPs.
size(); i != e; ++i) {
473 assert(Size >= 4 &&
"Too small constant pool entry");
474 unsigned Align = CPs[i].getAlignment();
478 assert((Size % Align) == 0 &&
"CP Entry not multiple of 4 bytes!");
481 unsigned LogAlign =
Log2_32(Align);
488 CPEMIs.push_back(CPEMI);
492 for (
unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
493 if (InsPoint[a] == InsAt)
496 std::vector<CPEntry> CPEs;
497 CPEs.push_back(CPEntry(CPEMI, i));
498 CPEntries.push_back(CPEs);
500 DEBUG(
dbgs() <<
"Moved CPI#" << i <<
" to end of function, size = "
501 << Size <<
", align = " << Align <<
'\n');
526 MipsConstantIslands::CPEntry
527 *MipsConstantIslands::findConstPoolEntry(
unsigned CPI,
529 std::vector<CPEntry> &CPEs = CPEntries[CPI];
532 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
533 if (CPEs[i].CPEMI == CPEMI)
541 unsigned MipsConstantIslands::getCPELogAlign(
const MachineInstr *CPEMI) {
542 assert(CPEMI && CPEMI->
getOpcode() == Mips::CONSTPOOL_ENTRY);
549 assert(CPI < MCP->getConstants().size() &&
"Invalid constant pool index.");
550 unsigned Align = MCP->getConstants()[CPI].getAlignment();
558 void MipsConstantIslands::
559 initializeFunctionInfo(
const std::vector<MachineInstr*> &CPEMIs) {
561 BBInfo.resize(MF->getNumBlockIDs());
572 adjustBBOffsetsAfter(MF->begin());
585 if (
I->isDebugValue())
588 int Opc =
I->getOpcode();
608 unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
609 ImmBranches.push_back(ImmBranch(
I, MaxOffs, isCond, UOpc));
612 if (Opc == Mips::CONSTPOOL_ENTRY)
617 for (
unsigned op = 0, e =
I->getNumOperands(); op != e; ++op)
618 if (
I->getOperand(op).isCPI()) {
627 unsigned LongFormBits = 0;
628 unsigned LongFormScale = 0;
629 unsigned LongFormOpcode = 0;
633 case Mips::LwRxPcTcp16:
636 LongFormOpcode = Mips::LwRxPcTcpX16;
640 case Mips::LwRxPcTcpX16:
647 unsigned CPI =
I->getOperand(op).getIndex();
649 unsigned MaxOffs = ((1 <<
Bits)-1) * Scale;
650 unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
651 CPUsers.push_back(CPUser(
I, CPEMI, MaxOffs, NegOk,
652 LongFormMaxOffs, LongFormOpcode));
655 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
656 assert(CPE &&
"Cannot find a corresponding CPEntry!");
673 BasicBlockInfo &BBI = BBInfo[MBB->
getNumber()];
678 BBI.Size +=
TII->GetInstSizeInBytes(
I);
685 unsigned MipsConstantIslands::getOffsetOf(
MachineInstr *
MI)
const {
691 unsigned Offset = BBInfo[MBB->
getNumber()].Offset;
695 assert(
I != MBB->
end() &&
"Didn't find MI in its own basic block?");
696 Offset +=
TII->GetInstSizeInBytes(
I);
711 void MipsConstantIslands::updateForInsertedWaterBlock
718 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
723 std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,
725 WaterList.insert(IP, NewBB);
728 unsigned MipsConstantIslands::getUserOffset(CPUser &U)
const {
729 return getOffsetOf(U.MI);
764 MF->RenumberBlocks(NewBB);
768 BBInfo.insert(BBInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
775 std::lower_bound(WaterList.begin(), WaterList.end(), OrigBB,
778 if (WaterBB == OrigBB)
781 WaterList.insert(IP, OrigBB);
782 NewWaterList.insert(OrigBB);
789 computeBlockSize(OrigBB);
793 computeBlockSize(NewBB);
796 adjustBBOffsetsAfter(OrigBB);
806 bool MipsConstantIslands::isOffsetInRange(
unsigned UserOffset,
807 unsigned TrialOffset,
unsigned MaxDisp,
809 if (UserOffset <= TrialOffset) {
811 if (TrialOffset - UserOffset <= MaxDisp)
813 }
else if (NegativeOK) {
814 if (UserOffset - TrialOffset <= MaxDisp)
824 bool MipsConstantIslands::isWaterInRange(
unsigned UserOffset,
827 unsigned CPELogAlign = getCPELogAlign(U.CPEMI);
828 unsigned CPEOffset = BBInfo[Water->
getNumber()].postOffset(CPELogAlign);
829 unsigned NextBlockOffset, NextBlockAlignment;
831 if (++NextBlock == MF->end()) {
832 NextBlockOffset = BBInfo[Water->
getNumber()].postOffset();
833 NextBlockAlignment = 0;
835 NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
836 NextBlockAlignment = NextBlock->getAlignment();
838 unsigned Size = U.CPEMI->getOperand(2).getImm();
839 unsigned CPEEnd = CPEOffset + Size;
844 if (CPEEnd > NextBlockOffset) {
845 Growth = CPEEnd - NextBlockOffset;
853 if (CPEOffset < UserOffset)
854 UserOffset += Growth;
859 return isOffsetInRange(UserOffset, CPEOffset, U);
864 bool MipsConstantIslands::isCPEntryInRange
867 bool NegOk,
bool DoDump) {
868 unsigned CPEOffset = getOffsetOf(CPEMI);
873 const BasicBlockInfo &BBI = BBInfo[Block];
875 <<
" max delta=" << MaxDisp
876 <<
format(
" insn address=%#x", UserOffset)
877 <<
" in BB#" << Block <<
": "
878 <<
format(
"%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
879 <<
format(
"CPE address=%#x offset=%+d: ", CPEOffset,
880 int(CPEOffset-UserOffset));
884 return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
904 for(
unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
907 unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
908 BBInfo[i].Offset = Offset;
917 bool MipsConstantIslands::decrementCPEReferenceCount(
unsigned CPI,
920 CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
921 assert(CPE &&
"Unexpected!");
922 if (--CPE->RefCount == 0) {
923 removeDeadCPEMI(CPEMI);
937 int MipsConstantIslands::findInRangeCPEntry(CPUser& U,
unsigned UserOffset)
943 if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk,
951 std::vector<CPEntry> &CPEs = CPEntries[CPI];
952 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
954 if (CPEs[i].CPEMI == CPEMI)
957 if (CPEs[i].CPEMI == NULL)
959 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getMaxDisp(),
961 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
962 << CPEs[i].CPI <<
"\n");
964 U.CPEMI = CPEs[i].CPEMI;
975 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
989 int MipsConstantIslands::findLongFormInRangeCPEntry
990 (CPUser& U,
unsigned UserOffset)
996 if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
997 U.getLongFormMaxDisp(), U.NegOk,
1000 UserMI->
setDesc(
TII->get(U.getLongFormOpcode()));
1001 U.setMaxDisp(U.getLongFormMaxDisp());
1007 std::vector<CPEntry> &CPEs = CPEntries[CPI];
1008 for (
unsigned i = 0, e = CPEs.size(); i != e; ++i) {
1010 if (CPEs[i].CPEMI == CPEMI)
1013 if (CPEs[i].CPEMI == NULL)
1015 if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
1016 U.getLongFormMaxDisp(), U.NegOk)) {
1017 DEBUG(
dbgs() <<
"Replacing CPE#" << CPI <<
" with CPE#"
1018 << CPEs[i].CPI <<
"\n");
1020 U.CPEMI = CPEs[i].CPEMI;
1031 return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1;
1042 return ((1<<10)-1)*2;
1044 return ((1<<16)-1)*2;
1048 return ((1<<16)-1)*2;
1059 bool MipsConstantIslands::findAvailableWater(CPUser &U,
unsigned UserOffset,
1060 water_iterator &WaterIter) {
1061 if (WaterList.empty())
1064 unsigned BestGrowth = ~0u;
1065 for (water_iterator IP =
prior(WaterList.end()), B = WaterList.begin();;
1077 if (isWaterInRange(UserOffset, WaterBB, U, Growth) &&
1078 (WaterBB->
getNumber() < U.HighWaterMark->getNumber() ||
1079 NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
1081 BestGrowth = Growth;
1084 <<
" Growth=" << Growth <<
'\n');
1087 if (BestGrowth == 0)
1093 return BestGrowth != ~0u;
1103 void MipsConstantIslands::createNewWater(
unsigned CPUserIndex,
1104 unsigned UserOffset,
1106 CPUser &U = CPUsers[CPUserIndex];
1109 unsigned CPELogAlign = getCPELogAlign(CPEMI);
1111 const BasicBlockInfo &UserBBI = BBInfo[UserMBB->
getNumber()];
1119 unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;
1121 if (isOffsetInRange(UserOffset, CPEOffset, U)) {
1123 <<
format(
", expected CPE offset %#x\n", CPEOffset));
1130 int UncondBr = Mips::Bimm16;
1133 ImmBranches.push_back(ImmBranch(&UserMBB->
back(),
1134 MaxDisp,
false, UncondBr));
1135 BBInfo[UserMBB->
getNumber()].Size += Delta;
1136 adjustBBOffsetsAfter(UserMBB);
1146 unsigned LogAlign = MF->getAlignment();
1147 assert(LogAlign >= CPELogAlign &&
"Over-aligned constant pool entry");
1148 unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
1155 BaseInsertOffset -= 4;
1158 <<
" la=" << LogAlign <<
'\n');
1164 if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
1165 BaseInsertOffset = UserBBI.postOffset() - 8;
1166 DEBUG(
dbgs() <<
format(
"Move inside block: %#x\n", BaseInsertOffset));
1168 unsigned EndInsertOffset = BaseInsertOffset + 4 +
1172 unsigned CPUIndex = CPUserIndex+1;
1173 unsigned NumCPUsers = CPUsers.size();
1175 for (
unsigned Offset = UserOffset+
TII->GetInstSizeInBytes(UserMI);
1176 Offset < BaseInsertOffset;
1177 Offset +=
TII->GetInstSizeInBytes(MI),
1179 assert(MI != UserMBB->
end() &&
"Fell off end of block");
1180 if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
1181 CPUser &U = CPUsers[CPUIndex];
1182 if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
1184 BaseInsertOffset -= 1u << LogAlign;
1185 EndInsertOffset -= 1u << LogAlign;
1191 EndInsertOffset += U.CPEMI->getOperand(2).getImm();
1197 NewMBB = splitBlockBeforeInstr(MI);
1204 bool MipsConstantIslands::handleConstantPoolUser(
unsigned CPUserIndex) {
1205 CPUser &U = CPUsers[CPUserIndex];
1211 unsigned UserOffset = getUserOffset(U);
1215 int result = findInRangeCPEntry(U, UserOffset);
1216 if (result==1)
return false;
1217 else if (result==2)
return true;
1224 if (findAvailableWater(U, UserOffset, IP)) {
1225 DEBUG(
dbgs() <<
"Found water in range\n");
1231 if (NewWaterList.erase(WaterBB))
1232 NewWaterList.
insert(NewIsland);
1242 result = findLongFormInRangeCPEntry(U, UserOffset);
1243 if (result != 0)
return true;
1246 createNewWater(CPUserIndex, UserOffset, NewMBB);
1254 IP = std::find(WaterList.begin(), WaterList.end(), WaterBB);
1255 if (IP != WaterList.end())
1256 NewWaterList.erase(WaterBB);
1259 NewWaterList.insert(NewIsland);
1266 if (IP != WaterList.end())
1267 WaterList.erase(IP);
1270 MF->insert(NewMBB, NewIsland);
1273 updateForInsertedWaterBlock(NewIsland);
1276 decrementCPEReferenceCount(CPI, CPEMI);
1280 U.HighWaterMark = NewIsland;
1283 CPEntries[CPI].push_back(CPEntry(U.CPEMI,
ID, 1));
1290 BBInfo[NewIsland->
getNumber()].Size += Size;
1295 unsigned ID = createPICLabelUId();
1304 DEBUG(
dbgs() <<
" Moved CPE to #" << ID <<
" CPI=" << CPI
1312 void MipsConstantIslands::removeDeadCPEMI(
MachineInstr *CPEMI) {
1316 BBInfo[CPEBB->
getNumber()].Size -= Size;
1318 if (CPEBB->
empty()) {
1327 adjustBBOffsetsAfter(CPEBB);
1337 bool MipsConstantIslands::removeUnusedCPEntries() {
1338 unsigned MadeChange =
false;
1339 for (
unsigned i = 0, e = CPEntries.size(); i != e; ++i) {
1340 std::vector<CPEntry> &CPEs = CPEntries[i];
1341 for (
unsigned j = 0, ee = CPEs.size(); j != ee; ++j) {
1342 if (CPEs[j].RefCount == 0 && CPEs[j].CPEMI) {
1343 removeDeadCPEMI(CPEs[j].CPEMI);
1344 CPEs[j].CPEMI = NULL;
1354 bool MipsConstantIslands::isBBInRange
1359 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
1360 unsigned DestOffset = BBInfo[DestBB->
getNumber()].Offset;
1364 <<
" max delta=" << MaxDisp
1365 <<
" from " << getOffsetOf(MI) <<
" to " << DestOffset
1366 <<
" offset " << int(DestOffset-BrOffset) <<
"\t" << *
MI);
1368 if (BrOffset <= DestOffset) {
1370 if (DestOffset-BrOffset <= MaxDisp)
1373 if (BrOffset-DestOffset <= MaxDisp)
1381 bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) {
1386 if (isBBInRange(MI, DestBB, Br.MaxDisp))
1390 return fixupUnconditionalBr(Br);
1391 return fixupConditionalBr(Br);
1399 MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
1403 Br.MaxDisp = ((1 << 16)-1) * 2;
1406 adjustBBOffsetsAfter(MBB);
1410 DEBUG(
dbgs() <<
" Changed B to long jump " << *MI);
1419 MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
1452 if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
1453 DEBUG(
dbgs() <<
" Invert Bcc condition and swap its destination with "
1463 splitBlockBeforeInstr(MI);
1466 int delta =
TII->GetInstSizeInBytes(&MBB->
back());
1474 <<
" also invert condition and change dest. to BB#"
1481 Br.MI = &MBB->
back();
1486 ImmBranches.push_back(ImmBranch(&MBB->
back(), MaxDisp,
false, Br.UncondBr));
1491 adjustBBOffsetsAfter(MBB);
1496 void MipsConstantIslands::prescanForConstants() {
1499 PrescannedForConstants =
true;
1501 MF->begin(), E = MF->end(); B != E; ++B) {
1503 B->instr_begin(), EB = B->instr_end();
I != EB; ++
I) {
1504 switch(
I->getDesc().getOpcode()) {
1505 case Mips::LwConstant32: {
1506 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1507 J =
I->getNumOperands();
1508 DEBUG(
dbgs() <<
"num operands " << J <<
"\n");
1510 if (Literal.
isImm()) {
1511 int64_t V = Literal.
getImm();
1512 DEBUG(
dbgs() <<
"literal " << V <<
"\n");
1516 unsigned index = MCP->getConstantPoolIndex(C, 4);
1517 I->getOperand(2).ChangeToImmediate(index);
1518 DEBUG(
dbgs() <<
"constant island constant " << *
I <<
"\n");
1519 I->setDesc(
TII->get(Mips::LwRxPcTcp16));
1520 I->RemoveOperand(1);
1521 I->RemoveOperand(1);
unsigned succ_size() const
const MachineFunction * getParent() const
The machine constant pool.
static bool CompareMBBNumbers(const MachineBasicBlock *LHS, const MachineBasicBlock *RHS)
MachineBasicBlock * getMBB() const
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Instructions::iterator instr_iterator
void setAlignment(unsigned Align)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
static bool BBHasFallthrough(MachineBasicBlock *MBB)
std::vector< MachineBasicBlock * >::iterator succ_iterator
static cl::opt< bool > AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code"))
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
format_object1< T > format(const char *Fmt, const T &Val)
void transferSuccessors(MachineBasicBlock *fromMBB)
STATISTIC(NumCPEs,"Number of constpool entries")
void RenumberBlocks(MachineBasicBlock *MBBFrom=0)
const BasicBlock * getBasicBlock() const
const MachineBasicBlock * getParent() const
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)
bundle_iterator< MachineInstr, instr_iterator > iterator
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)
initializer< Ty > init(const Ty &Val)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned char TargetFlags=0)
static bool BBIsJumpedOver(MachineBasicBlock *MBB)
LLVM Constant Representation.
const MachineOperand & getOperand(unsigned i) const
void setMBB(MachineBasicBlock *MBB)
ItTy next(ItTy it, Dist n)
MachineConstantPool * getConstantPool()
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
succ_iterator succ_begin()
pred_iterator pred_begin()
static unsigned getUnconditionalBrDisp(int Opc)
static bool useConstantIslands()
void setDesc(const MCInstrDesc &tid)
uint64_t getTypeAllocSize(Type *Ty) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
unsigned Log2_32(uint32_t Value)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
FunctionPass * createMipsConstantIslandPass(MipsTargetMachine &tm)
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
static IntegerType * getInt32Ty(LLVMContext &C)
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
static MachineOperand CreateImm(int64_t Val)
void push_back(MachineInstr *MI)
instr_iterator insert(instr_iterator I, MachineInstr *M)
std::reverse_iterator< iterator > reverse_iterator
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
BasicBlockListType::iterator iterator
ItTy prior(ItTy it, Dist n)
bool isPowerOf2_32(uint32_t Value)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
unsigned pred_size() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
unsigned getAlignment() const