diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/Mips/MipsBranchExpansion.cpp | 44 |
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(); } |