//
//
// This pass is used to make Pc relative loads of constants.
-// For now, only Mips16 will use this. While it has the same name and
-// uses many ideas from the LLVM ARM Constant Island Pass, it's not intended
-// to reuse any of the code from the ARM version.
+// For now, only Mips16 will use this.
//
// Loading constants inline is expensive on Mips16 and it's in general better
// to place the constant nearby in code space and then it can be loaded with a
#include "Mips.h"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "Mips16InstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/Statistic.h"
STATISTIC(NumCPEs, "Number of constpool entries");
STATISTIC(NumSplit, "Number of uncond branches inserted");
-#ifdef IN_PROGRESS
STATISTIC(NumCBrFixed, "Number of cond branches fixed");
-#endif
STATISTIC(NumUBrFixed, "Number of uncond branches fixed");
// FIXME: This option should be removed once it has received sufficient testing.
cl::desc("Make small offsets be this amount for testing purposes"),
cl::Hidden);
-/// UnknownPadding - Return the worst case padding that could result from
-/// unknown offset bits. This does not include alignment padding caused by
-/// known offset bits.
-///
-/// @param LogAlign log2(alignment)
-/// @param KnownBits Number of known low offset bits.
-static inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) {
- if (KnownBits < LogAlign)
- return (1u << LogAlign) - (1u << KnownBits);
- return 0;
-}
+//
+// For testing purposes we tell it to not use relaxed load forms so that it
+// will split blocks.
+//
+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);
+
namespace {
/// beginning of the block, or from an aligned jump table at the end.
unsigned Size;
- /// KnownBits - The number of low bits in Offset that are known to be
- /// exact. The remaining bits of Offset are an upper bound.
- uint8_t KnownBits;
-
- /// Unalign - When non-zero, the block contains instructions (inline asm)
- /// of unknown size. The real size may be smaller than Size bytes by a
- /// multiple of 1 << Unalign.
- uint8_t Unalign;
-
- /// PostAlign - When non-zero, the block terminator contains a .align
- /// directive, so the end of the block is aligned to 1 << PostAlign
- /// bytes.
- uint8_t PostAlign;
-
- BasicBlockInfo() : Offset(0), Size(0), KnownBits(0), Unalign(0),
- PostAlign(0) {}
-
- /// Compute the number of known offset bits internally to this block.
- /// This number should be used to predict worst case padding when
- /// splitting the block.
- unsigned internalKnownBits() const {
- unsigned Bits = Unalign ? Unalign : KnownBits;
- // If the block size isn't a multiple of the known bits, assume the
- // worst case padding.
- if (Size & ((1u << Bits) - 1))
- Bits = countTrailingZeros(Size);
- return Bits;
- }
-
- /// Compute the offset immediately following this block. If LogAlign is
- /// specified, return the offset the successor block will get if it has
- /// this alignment.
+ // FIXME: ignore LogAlign for this patch
+ //
unsigned postOffset(unsigned LogAlign = 0) const {
unsigned PO = Offset + Size;
return PO;
}
- /// Compute the number of known low bits of postOffset. If this block
- /// contains inline asm, the number of known bits drops to the
- /// instruction alignment. An aligned terminator may increase the number
- /// of know bits.
- /// If LogAlign is given, also consider the alignment of the next block.
- unsigned postKnownBits(unsigned LogAlign = 0) const {
- return std::max(std::max(unsigned(PostAlign), LogAlign),
- internalKnownBits());
- }
+ BasicBlockInfo() : Offset(0), Size(0) {}
+
};
std::vector<BasicBlockInfo> BBInfo;
unsigned LongFormOpcode;
public:
bool NegOk;
- bool IsSoImm;
- bool KnownAlignment;
CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,
- bool neg, bool soimm, unsigned longformmaxdisp, unsigned longformopcode)
- : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
+ bool neg,
+ unsigned longformmaxdisp, unsigned longformopcode)
+ : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp),
LongFormMaxDisp(longformmaxdisp), LongFormOpcode(longformopcode),
- NegOk(neg), IsSoImm(soimm), KnownAlignment(false) {
+ NegOk(neg){
HighWaterMark = CPEMI->getParent();
}
/// getMaxDisp - Returns the maximum displacement supported by MI.
- /// Correct for unknown alignment.
- /// Conservatively subtract 2 bytes to handle weird alignment effects.
unsigned getMaxDisp() const {
- unsigned xMaxDisp = ConstantIslandsSmallOffset? ConstantIslandsSmallOffset: MaxDisp;
- return (KnownAlignment ? xMaxDisp : xMaxDisp - 2) - 2;
+ unsigned xMaxDisp = ConstantIslandsSmallOffset?
+ ConstantIslandsSmallOffset: MaxDisp;
+ return xMaxDisp;
+ }
+ void setMaxDisp(unsigned val) {
+ MaxDisp = val;
}
unsigned getLongFormMaxDisp() const {
- return (KnownAlignment ? LongFormMaxDisp : LongFormMaxDisp - 2) - 2;
+ return LongFormMaxDisp;
}
unsigned getLongFormOpcode() const {
return LongFormOpcode;
bool IsPIC;
unsigned ABI;
const MipsSubtarget *STI;
- const MipsInstrInfo *TII;
+ const Mips16InstrInfo *TII;
MipsFunctionInfo *MFI;
MachineFunction *MF;
MachineConstantPool *MCP;
: MachineFunctionPass(ID), TM(tm),
IsPIC(TM.getRelocationModel() == Reloc::PIC_),
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
- STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0), PrescannedForConstants(false){}
+ STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0),
+ PrescannedForConstants(false){}
virtual const char *getPassName() const {
return "Mips Constant Islands";
void verify();
bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
- unsigned Disp, bool NegativeOK, bool IsSoImm = false);
+ unsigned Disp, bool NegativeOK);
bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
- const CPUser &U) {
- return isOffsetInRange(UserOffset, TrialOffset,
- U.getMaxDisp(), U.NegOk, U.IsSoImm);
- }
+ const CPUser &U);
+
bool isLongFormOffsetInRange(unsigned UserOffset, unsigned TrialOffset,
- const CPUser &U) {
- return isOffsetInRange(UserOffset, TrialOffset,
- U.getLongFormMaxDisp(), U.NegOk, U.IsSoImm);
- }
+ const CPUser &U);
+
void computeBlockSize(MachineBasicBlock *MBB);
MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI);
void updateForInsertedWaterBlock(MachineBasicBlock *NewBB);
char MipsConstantIslands::ID = 0;
} // end of anonymous namespace
+
+bool MipsConstantIslands::isLongFormOffsetInRange
+ (unsigned UserOffset, unsigned TrialOffset,
+ const CPUser &U) {
+ return isOffsetInRange(UserOffset, TrialOffset,
+ U.getLongFormMaxDisp(), U.NegOk);
+}
+
+bool MipsConstantIslands::isOffsetInRange
+ (unsigned UserOffset, unsigned TrialOffset,
+ const CPUser &U) {
+ return isOffsetInRange(UserOffset, TrialOffset,
+ U.getMaxDisp(), U.NegOk);
+}
/// print block size and offset information - debugging
void MipsConstantIslands::dumpBBs() {
DEBUG({
for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
const BasicBlockInfo &BBI = BBInfo[J];
dbgs() << format("%08x BB#%u\t", BBI.Offset, J)
- << " kb=" << unsigned(BBI.KnownBits)
- << " ua=" << unsigned(BBI.Unalign)
- << " pa=" << unsigned(BBI.PostAlign)
<< format(" size=%#x\n", BBInfo[J].Size);
}
});
!MipsSubtarget::useConstantIslands()) {
return false;
}
- TII = (const MipsInstrInfo*)MF->getTarget().getInstrInfo();
+ TII = (const Mips16InstrInfo*)MF->getTarget().getInstrInfo();
MFI = MF->getInfo<MipsFunctionInfo>();
DEBUG(dbgs() << "constant island processing " << "\n");
//
// Iteratively place constant pool entries and fix up branches until there
// is no change.
unsigned NoCPIters = 0, NoBRIters = 0;
+ (void)NoBRIters;
while (true) {
DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n');
bool CPChange = false;
DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n');
bool BRChange = false;
-#ifdef IN_PROGRESS
for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i)
BRChange |= fixupImmediateBr(ImmBranches[i]);
if (BRChange && ++NoBRIters > 30)
report_fatal_error("Branch Fix Up pass failed to converge!");
DEBUG(dumpBBs());
-#endif
if (!CPChange && !BRChange)
break;
MadeChange = true;
for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)
computeBlockSize(I);
- // The known bits of the entry block offset are determined by the function
- // alignment.
- BBInfo.front().KnownBits = MF->getAlignment();
// Compute block offsets.
adjustBBOffsetsAfter(MF->begin());
unsigned Bits = 0;
unsigned Scale = 1;
int UOpc = Opc;
-
switch (Opc) {
default:
- continue; // Ignore other JT branches
-#ifdef IN_PROGRESS
- case ARM::t2BR_JT:
- T2JumpTables.push_back(I);
- continue; // Does not get an entry in ImmBranches
- case ARM::Bcc:
- isCond = true;
- UOpc = ARM::B;
- // Fallthrough
- case ARM::B:
- Bits = 24;
- Scale = 4;
- break;
- case ARM::tBcc:
- isCond = true;
- UOpc = ARM::tB;
- Bits = 8;
- Scale = 2;
- break;
- case ARM::tB:
+ continue; // Ignore other branches for now
+ case Mips::Bimm16:
Bits = 11;
Scale = 2;
+ isCond = false;
break;
- case ARM::t2Bcc:
- isCond = true;
- UOpc = ARM::t2B;
- Bits = 20;
+ case Mips::BimmX16:
+ Bits = 16;
Scale = 2;
- break;
- case ARM::t2B:
- Bits = 24;
- Scale = 2;
- break;
-#endif
+ isCond = false;
}
// Record this immediate branch.
unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
ImmBranches.push_back(ImmBranch(I, MaxOffs, isCond, UOpc));
-
}
-
if (Opc == Mips::CONSTPOOL_ENTRY)
continue;
unsigned Bits = 0;
unsigned Scale = 1;
bool NegOk = false;
- bool IsSoImm = false;
unsigned LongFormBits = 0;
unsigned LongFormScale = 0;
unsigned LongFormOpcode = 0;
llvm_unreachable("Unknown addressing mode for CP reference!");
case Mips::LwRxPcTcp16:
Bits = 8;
- Scale = 2;
+ Scale = 4;
LongFormOpcode = Mips::LwRxPcTcpX16;
+ LongFormBits = 16;
+ LongFormScale = 1;
break;
case Mips::LwRxPcTcpX16:
Bits = 16;
- Scale = 2;
- break;
-#ifdef IN_PROGRESS
- // Taking the address of a CP entry.
- case ARM::LEApcrel:
- // This takes a SoImm, which is 8 bit immediate rotated. We'll
- // pretend the maximum offset is 255 * 4. Since each instruction
- // 4 byte wide, this is always correct. We'll check for other
- // displacements that fits in a SoImm as well.
- Bits = 8;
- Scale = 4;
- NegOk = true;
- IsSoImm = true;
- break;
- case ARM::t2LEApcrel:
- Bits = 12;
- NegOk = true;
- break;
- case ARM::tLEApcrel:
- Bits = 8;
- Scale = 4;
- break;
-
- case ARM::LDRBi12:
- case ARM::LDRi12:
- case ARM::LDRcp:
- case ARM::t2LDRpci:
- Bits = 12; // +-offset_12
+ Scale = 1;
NegOk = true;
break;
-
- case ARM::tLDRpci:
- Bits = 8;
- Scale = 4; // +(offset_8*4)
- break;
-
- case ARM::VLDRD:
- case ARM::VLDRS:
- Bits = 8;
- Scale = 4; // +-(offset_8*4)
- NegOk = true;
- break;
-#endif
}
// Remember that this is a user of a CP entry.
unsigned CPI = I->getOperand(op).getIndex();
MachineInstr *CPEMI = CPEMIs[CPI];
unsigned MaxOffs = ((1 << Bits)-1) * Scale;
unsigned LongFormMaxOffs = ((1 << LongFormBits)-1) * LongFormScale;
- CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm, LongFormMaxOffs,
- LongFormOpcode));
+ CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk,
+ LongFormMaxOffs, LongFormOpcode));
// Increment corresponding CPEntry reference count.
CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
void MipsConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {
BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
BBI.Size = 0;
- BBI.Unalign = 0;
- BBI.PostAlign = 0;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
++I)
/// updateForInsertedWaterBlock - When a block is newly inserted into the
/// machine function, it upsets all of the block numbers. Renumber the blocks
/// and update the arrays that parallel this numbering.
-void MipsConstantIslands::updateForInsertedWaterBlock(MachineBasicBlock *NewBB) {
+void MipsConstantIslands::updateForInsertedWaterBlock
+ (MachineBasicBlock *NewBB) {
// Renumber the MBB's to keep them consecutive.
NewBB->getParent()->RenumberBlocks(NewBB);
WaterList.insert(IP, NewBB);
}
-/// getUserOffset - Compute the offset of U.MI as seen by the hardware
-/// displacement computation. Update U.KnownAlignment to match its current
-/// basic block location.
unsigned MipsConstantIslands::getUserOffset(CPUser &U) const {
- unsigned UserOffset = getOffsetOf(U.MI);
- const BasicBlockInfo &BBI = BBInfo[U.MI->getParent()->getNumber()];
- unsigned KnownBits = BBI.internalKnownBits();
-
- // The value read from PC is offset from the actual instruction address.
-#ifdef IN_PROGRESS
- UserOffset += (isThumb ? 4 : 8);
-#endif
-
- // Because of inline assembly, we may not know the alignment (mod 4) of U.MI.
- // Make sure U.getMaxDisp() returns a constrained range.
- U.KnownAlignment = (KnownBits >= 2);
-
- // On Thumb, offsets==2 mod 4 are rounded down by the hardware for
- // purposes of the displacement computation; compensate for that here.
- // For unknown alignments, getMaxDisp() constrains the range instead.
-#ifdef IN_PROGRESS
- if (isThumb && U.KnownAlignment)
- UserOffset &= ~3u;
-#endif
-
- return UserOffset;
+ return getOffsetOf(U.MI);
}
/// Split the basic block containing MI into two blocks, which are joined by
/// an unconditional branch. Update data structures and renumber blocks to
/// account for this change and returns the newly created block.
-MachineBasicBlock *MipsConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) {
+MachineBasicBlock *MipsConstantIslands::splitBlockBeforeInstr
+ (MachineInstr *MI) {
MachineBasicBlock *OrigBB = MI->getParent();
// Create a new MBB for the code after the OrigBB.
// Note the new unconditional branch is not being recorded.
// There doesn't seem to be meaningful DebugInfo available; this doesn't
// correspond to anything in the source.
- BuildMI(OrigBB, DebugLoc(), TII->get(Mips::BimmX16)).addMBB(NewBB);
-#ifdef IN_PROGRESS
- unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B;
- if (!isThumb)
- BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB);
- else
- BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB)
- .addImm(ARMCC::AL).addReg(0);
-#endif
+ BuildMI(OrigBB, DebugLoc(), TII->get(Mips::Bimm16)).addMBB(NewBB);
++NumSplit;
// Update the CFG. All succs of OrigBB are now succs of NewBB.
return NewBB;
}
-#ifndef NDEBUG
/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool
/// reference) is within MaxDisp of TrialOffset (a proposed location of a
/// constant pool entry).
-/// UserOffset is computed by getUserOffset above to include PC adjustments. If
-/// the mod 4 alignment of UserOffset is not known, the uncertainty must be
-/// subtracted from MaxDisp instead. CPUser::getMaxDisp() does that.
bool MipsConstantIslands::isOffsetInRange(unsigned UserOffset,
unsigned TrialOffset, unsigned MaxDisp,
- bool NegativeOK, bool IsSoImm) {
+ bool NegativeOK) {
if (UserOffset <= TrialOffset) {
// User before the Trial.
if (TrialOffset - UserOffset <= MaxDisp)
return true;
- // FIXME: Make use full range of soimm values.
} else if (NegativeOK) {
if (UserOffset - TrialOffset <= MaxDisp)
return true;
- // FIXME: Make use full range of soimm values.
}
return false;
}
// the offset of the instruction. Also account for unknown alignment padding
// in blocks between CPE and the user.
if (CPEOffset < UserOffset)
- UserOffset += Growth + UnknownPadding(MF->getAlignment(), CPELogAlign);
+ UserOffset += Growth;
} else
// CPE fits in existing padding.
Growth = 0;
/// isCPEntryInRange - Returns true if the distance between specific MI and
/// specific ConstPool entry instruction can fit in MI's displacement field.
-bool MipsConstantIslands::isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,
- MachineInstr *CPEMI, unsigned MaxDisp,
- bool NegOk, bool DoDump) {
+bool MipsConstantIslands::isCPEntryInRange
+ (MachineInstr *MI, unsigned UserOffset,
+ MachineInstr *CPEMI, unsigned MaxDisp,
+ bool NegOk, bool DoDump) {
unsigned CPEOffset = getOffsetOf(CPEMI);
if (DoDump) {
return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk);
}
+#ifndef NDEBUG
/// BBIsJumpedOver - Return true of the specified basic block's only predecessor
/// unconditionally branches to its only successor.
static bool BBIsJumpedOver(MachineBasicBlock *MBB) {
if (MBB->pred_size() != 1 || MBB->succ_size() != 1)
return false;
-
-#ifdef IN_PROGRESS
MachineBasicBlock *Succ = *MBB->succ_begin();
MachineBasicBlock *Pred = *MBB->pred_begin();
MachineInstr *PredMI = &Pred->back();
- if (PredMI->getOpcode() == ARM::B || PredMI->getOpcode() == ARM::tB
- || PredMI->getOpcode() == ARM::t2B)
+ if (PredMI->getOpcode() == Mips::Bimm16)
return PredMI->getOperand(0).getMBB() == Succ;
-#endif
return false;
}
-#endif // NDEBUG
+#endif
void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
unsigned BBNum = BB->getNumber();
for(unsigned i = BBNum + 1, e = MF->getNumBlockIDs(); i < e; ++i) {
// Get the offset and known bits at the end of the layout predecessor.
// Include the alignment of the current block.
- unsigned Offset = BBInfo[i - 1].postOffset();
+ unsigned Offset = BBInfo[i - 1].Offset + BBInfo[i - 1].Size;
BBInfo[i].Offset = Offset;
}
}
/// 0 = no existing entry found
/// 1 = entry found, and there were no code insertions or deletions
/// 2 = entry found, and there were code insertions or deletions
-int MipsConstantIslands::findLongFormInRangeCPEntry(CPUser& U, unsigned UserOffset)
+int MipsConstantIslands::findLongFormInRangeCPEntry
+ (CPUser& U, unsigned UserOffset)
{
MachineInstr *UserMI = U.MI;
MachineInstr *CPEMI = U.CPEMI;
// Check to see if the CPE is already in-range.
- if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getLongFormMaxDisp(), U.NegOk,
+ if (isCPEntryInRange(UserMI, UserOffset, CPEMI,
+ U.getLongFormMaxDisp(), U.NegOk,
true)) {
DEBUG(dbgs() << "In range\n");
UserMI->setDesc(TII->get(U.getLongFormOpcode()));
+ U.setMaxDisp(U.getLongFormMaxDisp());
return 2; // instruction is longer length now
}
// Removing CPEs can leave empty entries, skip
if (CPEs[i].CPEMI == NULL)
continue;
- if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI, U.getLongFormMaxDisp(),
- U.NegOk)) {
+ if (isCPEntryInRange(UserMI, UserOffset, CPEs[i].CPEMI,
+ U.getLongFormMaxDisp(), U.NegOk)) {
DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#"
<< CPEs[i].CPI << "\n");
// Point the CPUser node to the replacement
/// getUnconditionalBrDisp - Returns the maximum displacement that can fit in
/// the specific unconditional branch instruction.
static inline unsigned getUnconditionalBrDisp(int Opc) {
-#ifdef IN_PROGRESS
switch (Opc) {
- case ARM::tB:
+ case Mips::Bimm16:
return ((1<<10)-1)*2;
- case ARM::t2B:
- return ((1<<23)-1)*2;
+ case Mips::BimmX16:
+ return ((1<<16)-1)*2;
default:
break;
}
-#endif
- return ((1<<23)-1)*4;
+ return ((1<<16)-1)*2;
}
/// findAvailableWater - Look for an existing entry in the WaterList in which
/// we can place the CPE referenced from U so it's within range of U's MI.
/// Returns true if found, false if not. If it returns true, WaterIter
-/// is set to the WaterList entry. For Thumb, prefer water that will not
-/// introduce padding to water that will. To ensure that this pass
+/// is set to the WaterList entry.
+/// To ensure that this pass
/// terminates, the CPE location for a particular CPUser is only allowed to
/// move to a lower address, so search backward from the end of the list and
/// prefer the first water that is in range.
const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];
// If the block does not end in an unconditional branch already, and if the
- // end of the block is within range, make new water there. (The addition
- // below is for the unconditional branch we will be adding: 4 bytes on ARM +
- // Thumb2, 2 on Thumb1.
+ // end of the block is within range, make new water there.
if (BBHasFallthrough(UserMBB)) {
// Size of branch to insert.
-#ifdef IN_PROGRESS
- unsigned Delta = isThumb1 ? 2 : 4;
-#else
- unsigned Delta = 4;
-#endif
+ unsigned Delta = 2;
// Compute the offset where the CPE will begin.
unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;
// but if the preceding conditional branch is out of range, the targets
// will be exchanged, and the altered branch may be out of range, so the
// machinery has to know about it.
-#ifdef IN_PROGRESS
- int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B;
- if (!isThumb)
- BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
- else
- BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB)
- .addImm(ARMCC::AL).addReg(0);
-#else
- int UncondBr = 1;
-#endif
+ int UncondBr = Mips::Bimm16;
+ BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
ImmBranches.push_back(ImmBranch(&UserMBB->back(),
MaxDisp, false, UncondBr));
}
}
- // What a big block. Find a place within the block to split it. This is a
- // little tricky on Thumb1 since instructions are 2 bytes and constant pool
- // entries are 4 bytes: if instruction I references island CPE, and
- // instruction I+1 references CPE', it will not work well to put CPE as far
- // forward as possible, since then CPE' cannot immediately follow it (that
- // location is 2 bytes farther away from I+1 than CPE was from I) and we'd
- // need to create a new island. So, we make a first guess, then walk through
- // the instructions between the one currently being looked at and the
- // possible insertion point, and make sure any other instructions that
- // reference CPEs will be able to use the same island area; if not, we back
- // up the insertion point.
+ // What a big block. Find a place within the block to split it.
// Try to split the block so it's fully aligned. Compute the latest split
// point where we can add a 4-byte branch instruction, and then align to
// LogAlign which is the largest possible alignment in the function.
unsigned LogAlign = MF->getAlignment();
assert(LogAlign >= CPELogAlign && "Over-aligned constant pool entry");
- unsigned KnownBits = UserBBI.internalKnownBits();
- unsigned UPad = UnknownPadding(LogAlign, KnownBits);
- unsigned BaseInsertOffset = UserOffset + U.getMaxDisp() - UPad;
+ unsigned BaseInsertOffset = UserOffset + U.getMaxDisp();
DEBUG(dbgs() << format("Split in middle of big block before %#x",
BaseInsertOffset));
// The 4 in the following is for the unconditional branch we'll be inserting
- // (allows for long branch on Thumb1). Alignment of the island is handled
+ // Alignment of the island is handled
// inside isOffsetInRange.
BaseInsertOffset -= 4;
DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset)
- << " la=" << LogAlign
- << " kb=" << KnownBits
- << " up=" << UPad << '\n');
+ << " la=" << LogAlign << '\n');
// This could point off the end of the block if we've already got constant
// pool entries following this block; only the last one is in the water list.
// Back past any possible branches (allow for a conditional and a maximally
// long unconditional).
if (BaseInsertOffset + 8 >= UserBBI.postOffset()) {
- BaseInsertOffset = UserBBI.postOffset() - UPad - 8;
+ BaseInsertOffset = UserBBI.postOffset() - 8;
DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));
}
- unsigned EndInsertOffset = BaseInsertOffset + 4 + UPad +
+ unsigned EndInsertOffset = BaseInsertOffset + 4 +
CPEMI->getOperand(2).getImm();
MachineBasicBlock::iterator MI = UserMI;
++MI;
unsigned CPUIndex = CPUserIndex+1;
unsigned NumCPUsers = CPUsers.size();
- MachineInstr *LastIT = 0;
+ //MachineInstr *LastIT = 0;
for (unsigned Offset = UserOffset+TII->GetInstSizeInBytes(UserMI);
Offset < BaseInsertOffset;
Offset += TII->GetInstSizeInBytes(MI),
EndInsertOffset += U.CPEMI->getOperand(2).getImm();
CPUIndex++;
}
-#ifdef IN_PROGRESS
- // Remember the last IT instruction.
- if (MI->getOpcode() == ARM::t2IT)
- LastIT = MI;
-#endif
}
--MI;
-
- // Avoid splitting an IT block.
- if (LastIT) {
-#ifdef IN_PROGRESS
- unsigned PredReg = 0;
- ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
- if (CC != ARMCC::AL)
- MI = LastIT;
-#endif
- }
NewMBB = splitBlockBeforeInstr(MI);
}
} else {
// No water found.
- // we first see if a longer form of the instrucion could have reached the constant.
- // in that case we won't bother to split
-#ifdef IN_PROGRESS
- result = findLongFormInRangeCPEntry(U, UserOffset);
-#endif
+ // we first see if a longer form of the instrucion could have reached
+ // the constant. in that case we won't bother to split
+ if (!NoLoadRelaxation) {
+ result = findLongFormInRangeCPEntry(U, UserOffset);
+ if (result != 0) return true;
+ }
DEBUG(dbgs() << "No water found\n");
createNewWater(CPUserIndex, UserOffset, NewMBB);
/// isBBInRange - Returns true if the distance between specific MI and
/// specific BB can fit in MI's displacement field.
-bool MipsConstantIslands::isBBInRange(MachineInstr *MI,MachineBasicBlock *DestBB,
- unsigned MaxDisp) {
-#ifdef IN_PROGRESS
- unsigned PCAdj = isThumb ? 4 : 8;
-#else
- unsigned PCAdj = 4;
-#endif
+bool MipsConstantIslands::isBBInRange
+ (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {
+
+unsigned PCAdj = 4;
+
unsigned BrOffset = getOffsetOf(MI) + PCAdj;
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
MachineInstr *MI = Br.MI;
MachineBasicBlock *MBB = MI->getParent();
-#ifdef IN_PROGRESS
- if (!isThumb1)
- llvm_unreachable("fixupUnconditionalBr is Thumb1 only!");
-#endif
// Use BL to implement far jump.
- Br.MaxDisp = (1 << 21) * 2;
-#ifdef IN_PROGRESS
- MI->setDesc(TII->get(ARM::tBfar));
-#endif
+ Br.MaxDisp = ((1 << 16)-1) * 2;
+ MI->setDesc(TII->get(Mips::BimmX16));
BBInfo[MBB->getNumber()].Size += 2;
adjustBBOffsetsAfter(MBB);
HasFarJump = true;
/// conditional branch + an unconditional branch to the destination.
bool
MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
-#ifdef IN_PROGRESS
MachineInstr *MI = Br.MI;
MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
// bge L2
// b L1
// L2:
- ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(1).getImm();
- CC = ARMCC::getOppositeCondition(CC);
- unsigned CCReg = MI->getOperand(2).getReg();
+ unsigned CCReg = 0; // FIXME
+ unsigned CC=0; //FIXME
// If the branch is at the end of its MBB and that has a fall-through block,
// direct the updated conditional branch to the fall-through block. Otherwise,
<< *BMI);
BMI->getOperand(0).setMBB(DestBB);
MI->getOperand(0).setMBB(NewDest);
- MI->getOperand(1).setImm(CC);
return true;
}
}
.addMBB(NextBB).addImm(CC).addReg(CCReg);
Br.MI = &MBB->back();
BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
- if (isThumb)
- BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB)
- .addImm(ARMCC::AL).addReg(0);
- else
- BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
+ BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);
ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
BBInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(MI);
MI->eraseFromParent();
adjustBBOffsetsAfter(MBB);
-#endif
return true;
}
void MipsConstantIslands::prescanForConstants() {
- unsigned int J;
+ unsigned J = 0;
+ (void)J;
PrescannedForConstants = true;
for (MachineFunction::iterator B =
MF->begin(), E = MF->end(); B != E; ++B) {