aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/MachineBasicBlock.cpp97
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 {};
}