aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp b/contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
index 4e9a23d077da..a4fa0792a998 100644
--- a/contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
@@ -36,7 +36,8 @@
///
/// Regarding compact branch hazard prevention:
///
-/// Hazards handled: forbidden slots for MIPSR6, FPU slots for MIPS3 and below.
+/// Hazards handled: forbidden slots for MIPSR6, FPU slots for MIPS3 and below,
+/// load delay slots for MIPS1.
///
/// A forbidden slot hazard occurs when a compact branch instruction is executed
/// and the adjacent instruction in memory is a control transfer instruction
@@ -164,6 +165,7 @@ private:
bool handleSlot(Pred Predicate, Safe SafeInSlot);
bool handleForbiddenSlot();
bool handleFPUDelaySlot();
+ bool handleLoadDelaySlot();
bool handlePossibleLongBranch();
const MipsSubtarget *STI;
@@ -532,7 +534,7 @@ void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) {
}
if (hasDelaySlot) {
if (STI->isTargetNaCl()) {
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
+ TII->insertNop(*BalTgtMBB, Pos, DL);
} else {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
.addReg(Mips::SP)
@@ -675,9 +677,8 @@ void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) {
// nop
// $fallthrough:
//
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MFp, DL, TII->get(Mips::J)).addMBB(TgtMBB))
- .append(BuildMI(*MFp, DL, TII->get(Mips::NOP)));
+ BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::J)).addMBB(TgtMBB);
+ TII->insertNop(*LongBrMBB, Pos, DL)->bundleWithPred();
} else {
// At this point, offset where we need to branch does not fit into
// immediate field of the branch instruction and is not in the same
@@ -722,7 +723,7 @@ void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) {
if (I.Br->isUnconditionalBranch()) {
// Change branch destination.
assert(I.Br->getDesc().getNumOperands() == 1);
- I.Br->RemoveOperand(0);
+ I.Br->removeOperand(0);
I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
} else
// Change branch destination and reverse condition.
@@ -762,13 +763,12 @@ bool MipsBranchExpansion::handleSlot(Pred Predicate, Safe SafeInSlot) {
}
if (LastInstInFunction || !SafeInSlot(*IInSlot, *I)) {
-
MachineBasicBlock::instr_iterator Iit = I->getIterator();
if (std::next(Iit) == FI->end() ||
std::next(Iit)->getOpcode() != Mips::NOP) {
Changed = true;
- MIBundleBuilder(&*I).append(
- BuildMI(*MFp, I->getDebugLoc(), TII->get(Mips::NOP)));
+ TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())
+ ->bundleWithPred();
NumInsertedNops++;
}
}
@@ -801,6 +801,18 @@ bool MipsBranchExpansion::handleFPUDelaySlot() {
});
}
+bool MipsBranchExpansion::handleLoadDelaySlot() {
+ // Load delay slot hazards are only for MIPS1.
+ if (STI->hasMips2())
+ return false;
+
+ return handleSlot(
+ [this](auto &I) -> bool { return TII->HasLoadDelaySlot(I); },
+ [this](auto &IInSlot, auto &I) -> bool {
+ return TII->SafeInLoadDelaySlot(IInSlot, I);
+ });
+}
+
bool MipsBranchExpansion::handlePossibleLongBranch() {
if (STI->inMips16Mode() || !STI->enableLongBranchPass())
return false;
@@ -867,7 +879,7 @@ bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) {
const TargetMachine &TM = MF.getTarget();
IsPIC = TM.isPositionIndependent();
ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
- STI = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
+ STI = &MF.getSubtarget<MipsSubtarget>();
TII = static_cast<const MipsInstrInfo *>(STI->getInstrInfo());
if (IsPIC && ABI.IsO32() &&
@@ -877,19 +889,21 @@ bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) {
MFp = &MF;
ForceLongBranchFirstPass = ForceLongBranch;
- // Run these two at least once
+ // Run these at least once.
bool longBranchChanged = handlePossibleLongBranch();
bool forbiddenSlotChanged = handleForbiddenSlot();
bool fpuDelaySlotChanged = handleFPUDelaySlot();
+ bool loadDelaySlotChanged = handleLoadDelaySlot();
- bool Changed =
- longBranchChanged || forbiddenSlotChanged || fpuDelaySlotChanged;
+ bool Changed = longBranchChanged || forbiddenSlotChanged ||
+ fpuDelaySlotChanged || loadDelaySlotChanged;
- // Then run them alternatively while there are changes
+ // Then run them alternatively while there are changes.
while (forbiddenSlotChanged) {
longBranchChanged = handlePossibleLongBranch();
fpuDelaySlotChanged = handleFPUDelaySlot();
- if (!longBranchChanged && !fpuDelaySlotChanged)
+ loadDelaySlotChanged = handleLoadDelaySlot();
+ if (!longBranchChanged && !fpuDelaySlotChanged && !loadDelaySlotChanged)
break;
forbiddenSlotChanged = handleForbiddenSlot();
}