aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineCSE.cpp
diff options
context:
space:
mode:
authorMichael Kitzan <mkitzan@apple.com>2021-04-30 19:50:54 -0700
committerMichael Kitzan <mkitzan@apple.com>2021-05-05 14:22:03 -0700
commita11489ae3e36063c64921439cbab89d1f3280f4a (patch)
treeced9cf24c66bf643807e1dbdf05ae92338d0957b /llvm/lib/CodeGen/MachineCSE.cpp
parent78a7d8c4dd1076dccfde2c48fc924d8f5529f4d1 (diff)
downloadllvm-a11489ae3e36063c64921439cbab89d1f3280f4a.zip
llvm-a11489ae3e36063c64921439cbab89d1f3280f4a.tar.gz
llvm-a11489ae3e36063c64921439cbab89d1f3280f4a.tar.bz2
[MachineCSE][NFC]: Refactor and comment on preventing CSE for isConvergent instrs
- Move the code preventing CSE of `isConvergent` instrs into `ProcessBlockCSE` (from `isProfitableToCSE`) - Add comments explaining why `isConvergent` is used to prevent CSE of non-local instrs in MachineCSE and the new test
Diffstat (limited to 'llvm/lib/CodeGen/MachineCSE.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineCSE.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index de90d0f..cb2e18e 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -433,11 +433,6 @@ bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg,
MachineBasicBlock *CSBB, MachineInstr *MI) {
// FIXME: Heuristics that works around the lack the live range splitting.
- MachineBasicBlock *BB = MI->getParent();
- // Prevent CSE-ing non-local convergent instructions.
- if (MI->isConvergent() && CSBB != BB)
- return false;
-
// If CSReg is used at all uses of Reg, CSE should not increase register
// pressure of CSReg.
bool MayIncreasePressure = true;
@@ -460,6 +455,7 @@ bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg,
// an immediate predecessor. We don't want to increase register pressure and
// end up causing other computation to be spilled.
if (TII->isAsCheapAsAMove(*MI)) {
+ MachineBasicBlock *BB = MI->getParent();
if (CSBB != BB && !CSBB->isSuccessor(BB))
return false;
}
@@ -592,6 +588,23 @@ bool MachineCSE::ProcessBlockCSE(MachineBasicBlock *MBB) {
LLVM_DEBUG(dbgs() << "Examining: " << *MI);
LLVM_DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI);
+ // Prevent CSE-ing non-local convergent instructions.
+ // LLVM's current definition of `isConvergent` does not necessarily prove
+ // that non-local CSE is illegal. The following check extends the definition
+ // of `isConvergent` to assume a convergent instruction is dependent not
+ // only on additional conditions, but also on fewer conditions. LLVM does
+ // not have a MachineInstr attribute which expresses this extended
+ // definition, so it's necessary to use `isConvergent` to prevent illegally
+ // CSE-ing the subset of `isConvergent` instructions which do fall into this
+ // extended definition.
+ if (MI->isConvergent() && MI->getParent() != CSMI->getParent()) {
+ LLVM_DEBUG(dbgs() << "*** Convergent MI and subexpression exist in "
+ "different BBs, avoid CSE!\n");
+ VNT.insert(MI, CurrVN++);
+ Exps.push_back(MI);
+ continue;
+ }
+
// Check if it's profitable to perform this CSE.
bool DoCSE = true;
unsigned NumDefs = MI->getNumDefs();
@@ -824,6 +837,15 @@ bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT,
if (BB != nullptr && BB1 != nullptr &&
(isPotentiallyReachable(BB1, BB) ||
isPotentiallyReachable(BB, BB1))) {
+ // The following check extends the definition of `isConvergent` to
+ // assume a convergent instruction is dependent not only on additional
+ // conditions, but also on fewer conditions. LLVM does not have a
+ // MachineInstr attribute which expresses this extended definition, so
+ // it's necessary to use `isConvergent` to prevent illegally PRE-ing the
+ // subset of `isConvergent` instructions which do fall into this
+ // extended definition.
+ if (MI->isConvergent() && CMBB != MBB)
+ continue;
assert(MI->getOperand(0).isDef() &&
"First operand of instr with one explicit def must be this def");