Skip to content

Commit 8596961

Browse files
committed
[SSAUpdaterBulk] Add PHI simplification pass.
1 parent 541ab52 commit 8596961

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,30 @@ class SSAUpdaterBulk {
7979
/// vector.
8080
void RewriteAllUses(DominatorTree *DT,
8181
SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
82+
83+
/// Rewrite all uses and simplify the inserted PHI nodes.
84+
/// Use this method to preserve behavior when replacing SSAUpdater.
85+
void RewriteAndSimplifyAllUses(DominatorTree *DT) {
86+
SmallVector<PHINode *, 8> NewPHIs;
87+
RewriteAllUses(DT, &NewPHIs);
88+
simplifyPass(NewPHIs);
89+
}
90+
91+
/// Same as previous, but return inserted PHI nodes in InsertedPHIs.
92+
void RewriteAndSimplifyAllUses(DominatorTree *DT,
93+
SmallVectorImpl<PHINode *> &InsertedPHIs) {
94+
RewriteAllUses(DT, &InsertedPHIs);
95+
simplifyPass(InsertedPHIs);
96+
// Remove nullptrs from the worklist
97+
InsertedPHIs.erase(
98+
std::remove(InsertedPHIs.begin(), InsertedPHIs.end(), nullptr),
99+
InsertedPHIs.end());
100+
}
101+
102+
private:
103+
/// Perform a single pass of simplification over the worklist of PHIs.
104+
/// Pointers to replaced phis are nulled out.
105+
static bool simplifyPass(SmallVectorImpl<PHINode *> &Worklist);
82106
};
83107

84108
} // end namespace llvm

llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "llvm/Transforms/Utils/SSAUpdaterBulk.h"
14+
#include "llvm/Analysis/InstructionSimplify.h"
1415
#include "llvm/Analysis/IteratedDominanceFrontier.h"
1516
#include "llvm/IR/BasicBlock.h"
1617
#include "llvm/IR/Dominators.h"
@@ -182,3 +183,49 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
182183
}
183184
}
184185
}
186+
187+
static bool isEquivalentPHI(PHINode *PHI1, PHINode *PHI2) {
188+
if (PHI1->getNumIncomingValues() != PHI2->getNumIncomingValues())
189+
return false;
190+
191+
unsigned I = 0, NumValues = PHI1->getNumIncomingValues();
192+
for (; I != NumValues; ++I) {
193+
if (PHI1->getIncomingBlock(I) != PHI2->getIncomingBlock(I))
194+
break;
195+
if (PHI1->getIncomingValue(I) != PHI2->getIncomingValue(I))
196+
return false;
197+
}
198+
// TODO: add procesing if phis have different order of incoming values.
199+
return I == NumValues;
200+
}
201+
202+
bool SSAUpdaterBulk::simplifyPass(SmallVectorImpl<PHINode *> &Worklist) {
203+
if (Worklist.empty())
204+
return false;
205+
206+
auto findEquivalentPHI = [](PHINode *PHI) -> Value * {
207+
BasicBlock *BB = PHI->getParent();
208+
for (auto &OtherPHI : BB->phis()) {
209+
if (PHI != &OtherPHI && isEquivalentPHI(PHI, &OtherPHI)) {
210+
return &OtherPHI;
211+
}
212+
}
213+
return nullptr;
214+
};
215+
216+
const DataLayout &DL = Worklist.front()->getParent()->getDataLayout();
217+
bool Change = false;
218+
for (PHINode *&PHI : Worklist) {
219+
Value *Replacement = simplifyInstruction(PHI, DL);
220+
if (!Replacement)
221+
Replacement = findEquivalentPHI(PHI);
222+
223+
if (Replacement) {
224+
PHI->replaceAllUsesWith(Replacement);
225+
PHI->eraseFromParent();
226+
PHI = nullptr; // Mark as removed
227+
Change = true;
228+
}
229+
}
230+
return Change;
231+
}

0 commit comments

Comments
 (0)