cl::desc("Make small offsets be this amount for testing purposes"),
cl::Hidden);
+//
+// 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 {
ConstantIslandsSmallOffset: MaxDisp;
return xMaxDisp;
}
+ void setMaxDisp(unsigned val) {
+ MaxDisp = val;
+ }
unsigned getLongFormMaxDisp() const {
return LongFormMaxDisp;
}
continue;
int Opc = I->getOpcode();
+#ifdef IN_PROGRESS
if (I->isBranch()) {
bool isCond = false;
unsigned Bits = 0;
unsigned Scale = 1;
int UOpc = Opc;
-
switch (Opc) {
default:
continue; // Ignore other JT branches
// Record this immediate branch.
unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale;
ImmBranches.push_back(ImmBranch(I, MaxOffs, isCond, UOpc));
-
}
-
+#endif
if (Opc == Mips::CONSTPOOL_ENTRY)
continue;
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;
+ Scale = 1;
+ NegOk = true;
break;
}
// Remember that this is a user of a CP entry.
// 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);
+ BuildMI(OrigBB, DebugLoc(), TII->get(Mips::Bimm16)).addMBB(NewBB);
++NumSplit;
// Update the CFG. All succs of OrigBB are now succs of NewBB.
/// 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) {
MachineBasicBlock *Succ = *MBB->succ_begin();
MachineBasicBlock *Pred = *MBB->pred_begin();
MachineInstr *PredMI = &Pred->back();
- if (PredMI->getOpcode() == Mips::BimmX16)
+ if (PredMI->getOpcode() == Mips::Bimm16)
return PredMI->getOperand(0).getMBB() == Succ;
return false;
}
true)) {
DEBUG(dbgs() << "In range\n");
UserMI->setDesc(TII->get(U.getLongFormOpcode()));
+ U.setMaxDisp(U.getLongFormMaxDisp());
return 2; // instruction is longer length now
}
/// the specific unconditional branch instruction.
static inline unsigned getUnconditionalBrDisp(int Opc) {
switch (Opc) {
+ case Mips::Bimm16:
+ return ((1<<10)-1)*2;
case Mips::BimmX16:
return ((1<<16)-1)*2;
default:
// 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.
- int UncondBr = Mips::BimmX16;
+ int UncondBr = Mips::Bimm16;
BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
ImmBranches.push_back(ImmBranch(&UserMBB->back(),
// 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
+ if (!NoLoadRelaxation) {
+ result = findLongFormInRangeCPEntry(U, UserOffset);
+ if (result != 0) return true;
+ }
DEBUG(dbgs() << "No water found\n");
createNewWater(CPUserIndex, UserOffset, NewMBB);