diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp | 97 |
1 files changed, 86 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp index 5ef377f2a1c0..231544494c32 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -12,12 +12,14 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SlotIndexes.h" @@ -664,6 +666,15 @@ void MachineBasicBlock::moveAfter(MachineBasicBlock *NewBefore) { getParent()->splice(++NewBefore->getIterator(), getIterator()); } +static int findJumpTableIndex(const MachineBasicBlock &MBB) { + MachineBasicBlock::const_iterator TerminatorI = MBB.getFirstTerminator(); + if (TerminatorI == MBB.end()) + return -1; + const MachineInstr &Terminator = *TerminatorI; + const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); + return TII->getJumpTableIndex(Terminator); +} + void MachineBasicBlock::updateTerminator( MachineBasicBlock *PreviousLayoutSuccessor) { LLVM_DEBUG(dbgs() << "Updating terminators on " << printMBBReference(*this) @@ -975,8 +986,8 @@ MachineBasicBlock *MachineBasicBlock::getFallThrough(bool JumpToFallThrough) { // If there is some explicit branch to the fallthrough block, it can obviously // reach, even though the branch should get folded to fall through implicitly. - if (!JumpToFallThrough && (MachineFunction::iterator(TBB) == Fallthrough || - MachineFunction::iterator(FBB) == Fallthrough)) + if (JumpToFallThrough && (MachineFunction::iterator(TBB) == Fallthrough || + MachineFunction::iterator(FBB) == Fallthrough)) return &*Fallthrough; // If it's an unconditional branch to some block not the fall through, it @@ -1033,6 +1044,50 @@ MachineBasicBlock *MachineBasicBlock::splitAt(MachineInstr &MI, return SplitBB; } +// Returns `true` if there are possibly other users of the jump table at +// `JumpTableIndex` except for the ones in `IgnoreMBB`. +static bool jumpTableHasOtherUses(const MachineFunction &MF, + const MachineBasicBlock &IgnoreMBB, + int JumpTableIndex) { + assert(JumpTableIndex >= 0 && "need valid index"); + const MachineJumpTableInfo &MJTI = *MF.getJumpTableInfo(); + const MachineJumpTableEntry &MJTE = MJTI.getJumpTables()[JumpTableIndex]; + // Take any basic block from the table; every user of the jump table must + // show up in the predecessor list. + const MachineBasicBlock *MBB = nullptr; + for (MachineBasicBlock *B : MJTE.MBBs) { + if (B != nullptr) { + MBB = B; + break; + } + } + if (MBB == nullptr) + return true; // can't rule out other users if there isn't any block. + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + SmallVector<MachineOperand, 4> Cond; + for (MachineBasicBlock *Pred : MBB->predecessors()) { + if (Pred == &IgnoreMBB) + continue; + MachineBasicBlock *DummyT = nullptr; + MachineBasicBlock *DummyF = nullptr; + Cond.clear(); + if (!TII.analyzeBranch(*Pred, DummyT, DummyF, Cond, + /*AllowModify=*/false)) { + // analyzable direct jump + continue; + } + int PredJTI = findJumpTableIndex(*Pred); + if (PredJTI >= 0) { + if (PredJTI == JumpTableIndex) + return true; + continue; + } + // Be conservative for unanalyzable jumps. + return true; + } + return false; +} + MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( MachineBasicBlock *Succ, Pass &P, std::vector<SparseBitVector<>> *LiveInSets) { @@ -1044,6 +1099,16 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( DebugLoc DL; // FIXME: this is nowhere MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); + + // Is there an indirect jump with jump table? + bool ChangedIndirectJump = false; + int JTI = findJumpTableIndex(*this); + if (JTI >= 0) { + MachineJumpTableInfo &MJTI = *MF->getJumpTableInfo(); + MJTI.ReplaceMBBInJumpTable(JTI, Succ, NMBB); + ChangedIndirectJump = true; + } + MF->insert(std::next(MachineFunction::iterator(this)), NMBB); LLVM_DEBUG(dbgs() << "Splitting critical edge: " << printMBBReference(*this) << " -- " << printMBBReference(*NMBB) << " -- " @@ -1066,9 +1131,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( if (LV) for (MachineInstr &MI : llvm::make_range(getFirstInstrTerminator(), instr_end())) { - for (MachineOperand &MO : MI.operands()) { - if (!MO.isReg() || MO.getReg() == 0 || !MO.isUse() || !MO.isKill() || - MO.isUndef()) + for (MachineOperand &MO : MI.all_uses()) { + if (MO.getReg() == 0 || !MO.isKill() || MO.isUndef()) continue; Register Reg = MO.getReg(); if (Reg.isPhysical() || LV->getVarInfo(Reg).removeKill(MI)) { @@ -1109,7 +1173,9 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( // as the fallthrough successor if (Succ == PrevFallthrough) PrevFallthrough = NMBB; - updateTerminator(PrevFallthrough); + + if (!ChangedIndirectJump) + updateTerminator(PrevFallthrough); if (Indexes) { SmallVector<MachineInstr*, 4> NewTerminators; @@ -1284,8 +1350,13 @@ bool MachineBasicBlock::canSplitCriticalEdge( if (MF->getTarget().requiresStructuredCFG()) return false; + // Do we have an Indirect jump with a jumptable that we can rewrite? + int JTI = findJumpTableIndex(*this); + if (JTI >= 0 && !jumpTableHasOtherUses(*MF, *this, JTI)) + return true; + // We may need to update this's terminator, but we can't do that if - // analyzeBranch fails. If this uses a jump table, we won't touch it. + // analyzeBranch fails. const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); MachineBasicBlock *TBB = nullptr, *FBB = nullptr; SmallVector<MachineOperand, 4> Cond; @@ -1391,7 +1462,7 @@ void MachineBasicBlock::replacePhiUsesWith(MachineBasicBlock *Old, } } -/// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE +/// Find the next valid DebugLoc starting at MBBI, skipping any debug /// instructions. Return UnknownLoc if there is none. DebugLoc MachineBasicBlock::findDebugLoc(instr_iterator MBBI) { @@ -1403,6 +1474,8 @@ MachineBasicBlock::findDebugLoc(instr_iterator MBBI) { } DebugLoc MachineBasicBlock::rfindDebugLoc(reverse_instr_iterator MBBI) { + if (MBBI == instr_rend()) + return findDebugLoc(instr_begin()); // Skip debug declarations, we don't want a DebugLoc from them. MBBI = skipDebugInstructionsBackward(MBBI, instr_rbegin()); if (!MBBI->isDebugInstr()) @@ -1410,13 +1483,15 @@ DebugLoc MachineBasicBlock::rfindDebugLoc(reverse_instr_iterator MBBI) { return {}; } -/// Find the previous valid DebugLoc preceding MBBI, skipping and DBG_VALUE +/// Find the previous valid DebugLoc preceding MBBI, skipping any debug /// instructions. Return UnknownLoc if there is none. DebugLoc MachineBasicBlock::findPrevDebugLoc(instr_iterator MBBI) { - if (MBBI == instr_begin()) return {}; + if (MBBI == instr_begin()) + return {}; // Skip debug instructions, we don't want a DebugLoc from them. MBBI = prev_nodbg(MBBI, instr_begin()); - if (!MBBI->isDebugInstr()) return MBBI->getDebugLoc(); + if (!MBBI->isDebugInstr()) + return MBBI->getDebugLoc(); return {}; } |