Skip to content

Commit 23bba56

Browse files
committedJul 2, 2018
[CodeGen] Make block removal order deterministic in CodeGenPrepare
Summary: Replace use of a SmallPtrSet with a SmallSetVector to make the worklist iteration order deterministic. This is done as the order the blocks are removed may affect whether or not PHI nodes in successor blocks are removed. For example, consider the following case where %bb1 and %bb2 are removed: bb1: br i1 undef, label %bb3, label %bb4 bb2: br i1 undef, label %bb4, label %bb3 bb3: pv1 = phi type [ undef, %bb1 ], [ undef, %bb2], [ v0, %other ] br label %bb4 bb4: pv2 = phi type [ undef, %bb1 ], [ undef, %bb2 ], [ pv1, %bb3 ], [ v0, %other ] If %bb2 is removed before %bb1, the incoming values from %bb1 and %bb2 to pv1 will be removed before %bb1 is removed as a predecessor to %bb4. The pv1 node will thus be optimized out (to v0) at the time %bb1 is removed as a predecessor to %bb4, leaving the blocks as following when the incoming value from %bb1 has been removed: bb3: ; pv1 optimized out, incoming value to pv2 is v0 br label %bb4 bb4: pv2 = phi type [ v0, %bb3 ], [ v0, %other ] The pv2 PHI node will be optimized away by removePredecessor() as all incoming values are identical. In case %bb2 is removed after %bb1, pv1 will not be optimized out at the time %bb2 is removed as a predecessor to %bb4, leaving the blocks as following when the incoming value from %bb2 to pv2 has been removed: bb3: pv1 = phi type [ undef, %bb2 ], [ v0, %other ] br label %bb4 bb4: pv2 = phi type [ pv1, %bb3 ], [ v0, %other ] The pv2 PHI node will thus not be removed in this case, ultimately leading to the following output bb3: ; pv1 optimized out, incoming value to pv2 is v0 br label %bb4 bb4: pv2 = phi type [ v0, %bb3 ], [ v0, %other ] I have not looked into changing DeleteDeadBlock() so that the redundant PHI nodes are removed. I have not added a test case, as I was not able to create a particularly small and (not messy) reproducer. This is likely due to SmallPtrSet behaving deterministically when in small mode. Reviewers: void, dexonsmith, spatel, skatkov, fhahn, bkramer, nhaehnle Reviewed By: fhahn Subscribers: mgrang, llvm-commits Differential Revision: https://reviews.llvm.org/D48369 llvm-svn: 336109
1 parent 21f938c commit 23bba56

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed
 

‎llvm/lib/CodeGen/CodeGenPrepare.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,10 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
462462

463463
if (!DisableBranchOpts) {
464464
MadeChange = false;
465-
SmallPtrSet<BasicBlock*, 8> WorkList;
465+
// Use a set vector to get deterministic iteration order. The order the
466+
// blocks are removed may affect whether or not PHI nodes in successors
467+
// are removed.
468+
SmallSetVector<BasicBlock*, 8> WorkList;
466469
for (BasicBlock &BB : F) {
467470
SmallVector<BasicBlock *, 2> Successors(succ_begin(&BB), succ_end(&BB));
468471
MadeChange |= ConstantFoldTerminator(&BB, true);
@@ -477,8 +480,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
477480
// Delete the dead blocks and any of their dead successors.
478481
MadeChange |= !WorkList.empty();
479482
while (!WorkList.empty()) {
480-
BasicBlock *BB = *WorkList.begin();
481-
WorkList.erase(BB);
483+
BasicBlock *BB = WorkList.pop_back_val();
482484
SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
483485

484486
DeleteDeadBlock(BB);

0 commit comments

Comments
 (0)
Please sign in to comment.