[PATCH] D63934: [MIR] Improve PRE condition of MachineCSE optimization

Anton Afanasyev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 28 08:09:30 PDT 2019


anton-afanasyev created this revision.
anton-afanasyev added reviewers: asbirlea, aymanmus, igorb.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Two equal instrs are partially redundant if their basic blocks are reachable
from one to another but one doesn't dominate another. For this case
one can hoist them to their common dominator block. But such hoisting makes
optimization sense only if their blocks are reachable from one to another
without passing through their common dominator. This change makes this check
preventing PRE from useless instr duplication (leading to hoisting after CSE
elimination).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63934

Files:
  llvm/lib/CodeGen/MachineCSE.cpp


Index: llvm/lib/CodeGen/MachineCSE.cpp
===================================================================
--- llvm/lib/CodeGen/MachineCSE.cpp
+++ llvm/lib/CodeGen/MachineCSE.cpp
@@ -130,6 +130,12 @@
                          DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren);
     bool PerformCSE(MachineDomTreeNode *Node);
 
+    bool isPotentiallyReachableWithoutPassing(const BasicBlock *BBA,
+                                              const BasicBlock *BBB,
+                                              const BasicBlock *ExclusionBB,
+                                              const DominatorTree *DT,
+                                              const LoopInfo *LI);
+
     bool isPRECandidate(MachineInstr *MI);
     bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *MBB);
     bool PerformSimplePRE(MachineDominatorTree *DT);
@@ -779,6 +785,22 @@
   return true;
 }
 
+/// Determine whether block 'To' is reachable from 'From', without passing
+/// through ExclusionBB block, returning true if uncertain.
+bool MachineCSE::isPotentiallyReachableWithoutPassing(
+    const BasicBlock *From, const BasicBlock *To, const BasicBlock *ExclusionBB,
+    const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr) {
+
+  SmallVector<BasicBlock *, 32> Worklist;
+  SmallPtrSet<BasicBlock *, 1> ExclusionSet;
+  Worklist.push_back(const_cast<BasicBlock *>(From));
+  if (ExclusionBB != nullptr)
+    ExclusionSet.insert(const_cast<BasicBlock *>(ExclusionBB));
+
+  return llvm::isPotentiallyReachableFromMany(
+      Worklist, const_cast<BasicBlock *>(To), &ExclusionSet, DT, LI);
+}
+
 bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT,
                                  MachineBasicBlock *MBB) {
   bool Changed = false;
@@ -802,13 +824,14 @@
     if (!CMBB->isLegalToHoistInto())
       continue;
 
-    // Two instrs are partial redundant if their basic blocks are reachable
-    // from one to another but one doesn't dominate another.
+    // Two equal instrs are partially redundant if their basic blocks are
+    // reachable from one to another but one doesn't dominate another.
     if (CMBB != MBB1) {
-      auto BB = MBB->getBasicBlock(), BB1 = MBB1->getBasicBlock();
+      auto BB = MBB->getBasicBlock(), BB1 = MBB1->getBasicBlock(),
+           CBB = CMBB->getBasicBlock();
       if (BB != nullptr && BB1 != nullptr &&
-          (isPotentiallyReachable(BB1, BB) ||
-           isPotentiallyReachable(BB, BB1))) {
+          (MachineCSE::isPotentiallyReachableWithoutPassing(BB1, BB, CBB) ||
+           MachineCSE::isPotentiallyReachableWithoutPassing(BB, BB1, CBB))) {
 
         assert(MI->getOperand(0).isDef() &&
                "First operand of instr with one explicit def must be this def");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63934.207066.patch
Type: text/x-patch
Size: 2764 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190628/2d6f7167/attachment.bin>


More information about the llvm-commits mailing list