[llvm] r246694 - [RemoveDuplicatePHINodes] Start over after removing a PHI.

Jonathan Roelofs via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 2 13:51:51 PDT 2015



On 9/2/15 1:52 PM, Benjamin Kramer via llvm-commits wrote:
> Author: d0k
> Date: Wed Sep  2 14:52:23 2015
> New Revision: 246694
>
> URL: http://llvm.org/viewvc/llvm-project?rev=246694&view=rev
> Log:
> [RemoveDuplicatePHINodes] Start over after removing a PHI.

Tom,

I think this ought to go on the 3.7.1 branch when that time comes.


Thoughts?

Jon

>
> This makes RemoveDuplicatePHINodes more effective and fixes an assertion
> failure. Triggering the assertions requires a DenseSet reallocation
> so this change only contains a constructive test.
>
> I'll explain the issue with a small example. In the following function
> there's a duplicate PHI, %4 and %5 are identical. When this is found
> the DenseSet in RemoveDuplicatePHINodes contains %2, %3 and %4.
>
> define void @F() {
>    br label %1
>
> ; <label>:1                                       ; preds = %1, %0
>    %2 = phi i32 [ 42, %0 ], [ %4, %1 ]
>    %3 = phi i32 [ 42, %0 ], [ %5, %1 ]
>    %4 = phi i32 [ 42, %0 ], [ 23, %1 ]
>    %5 = phi i32 [ 42, %0 ], [ 23, %1 ]
>    br label %1
> }
>
> after RemoveDuplicatePHINodes runs the function looks like this. %3 has
> changed and is now identical to %2, but RemoveDuplicatePHINodes never
> saw this.
>
> define void @F() {
>    br label %1
>
> ; <label>:1                                       ; preds = %1, %0
>    %2 = phi i32 [ 42, %0 ], [ %4, %1 ]
>    %3 = phi i32 [ 42, %0 ], [ %4, %1 ]
>    %4 = phi i32 [ 42, %0 ], [ 23, %1 ]
>    br label %1
> }
>
> If the DenseSet does a reallocation now it will reinsert all
> keys and stumble over %3 now having a different hash value than it had
> when inserted into the map for the first time. This change clears the
> set whenever a PHI is deleted and starts the progress from the
> beginning, allowing %3 to be deleted and avoiding inconsistent DenseSet
> state. This potentially has a negative performance impact because
> it rescans all PHIs, but I don't think that this ever makes a difference
> in practice.
>
> Modified:
>      llvm/trunk/lib/Transforms/Utils/Local.cpp
>      llvm/trunk/unittests/Transforms/Utils/Local.cpp
>
> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=246694&r1=246693&r2=246694&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed Sep  2 14:52:23 2015
> @@ -874,6 +874,11 @@ bool llvm::EliminateDuplicatePHINodes(Ba
>         PN->replaceAllUsesWith(*Inserted.first);
>         PN->eraseFromParent();
>         Changed = true;
> +
> +      // The RAUW can change PHIs that we already visited. Start over from the
> +      // beginning.
> +      PHISet.clear();
> +      I = BB->begin();
>       }
>     }
>
>
> Modified: llvm/trunk/unittests/Transforms/Utils/Local.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Local.cpp?rev=246694&r1=246693&r2=246694&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/Transforms/Utils/Local.cpp (original)
> +++ llvm/trunk/unittests/Transforms/Utils/Local.cpp Wed Sep  2 14:52:23 2015
> @@ -58,3 +58,40 @@ TEST(Local, RecursivelyDeleteDeadPHINode
>     delete bb0;
>     delete bb1;
>   }
> +
> +TEST(Local, RemoveDuplicatePHINodes) {
> +  LLVMContext &C(getGlobalContext());
> +  IRBuilder<> B(C);
> +
> +  std::unique_ptr<Function> F(
> +      Function::Create(FunctionType::get(B.getVoidTy(), false),
> +                       GlobalValue::ExternalLinkage, "F"));
> +  BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
> +  BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
> +  BranchInst::Create(BB, Entry);
> +
> +  B.SetInsertPoint(BB);
> +
> +  AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
> +  P1->addIncoming(B.getInt32(42), Entry);
> +
> +  PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
> +  P2->addIncoming(B.getInt32(42), Entry);
> +
> +  AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
> +  P3->addIncoming(B.getInt32(42), Entry);
> +  P3->addIncoming(B.getInt32(23), BB);
> +
> +  PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
> +  P4->addIncoming(B.getInt32(42), Entry);
> +  P4->addIncoming(B.getInt32(23), BB);
> +
> +  P1->addIncoming(P3, BB);
> +  P2->addIncoming(P4, BB);
> +  BranchInst::Create(BB, BB);
> +
> +  // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
> +  // downstream.
> +  EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
> +  EXPECT_EQ(3U, BB->size());
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>

-- 
Jon Roelofs
jonathan at codesourcery.com
CodeSourcery / Mentor Embedded


More information about the llvm-commits mailing list