llvm.org GIT mirror llvm / 1a4021a
Teach RecursivelyDeleteDeadPHINodes to handle multiple self-references. Patch by Andrew Clinton! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126077 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 8 years ago
3 changed file(s) with 71 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
259259 return true;
260260 }
261261
262 /// areAllUsesEqual - Check whether the uses of a value are all the same.
263 /// This is similar to Instruction::hasOneUse() except this will also return
264 /// true when there are multiple uses that all refer to the same value.
265 static bool areAllUsesEqual(Instruction *I) {
266 Value::use_iterator UI = I->use_begin();
267 Value::use_iterator UE = I->use_end();
268 if (UI == UE)
269 return false;
270
271 User *TheUse = *UI;
272 for (++UI; UI != UE; ++UI) {
273 if (*UI != TheUse)
274 return false;
275 }
276 return true;
277 }
278
262279 /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
263280 /// dead PHI node, due to being a def-use chain of single-use nodes that
264281 /// either forms a cycle or is terminated by a trivially dead instruction,
265282 /// delete it. If that makes any of its operands trivially dead, delete them
266283 /// too, recursively. Return true if the PHI node is actually deleted.
267 bool
268 llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) {
284 bool llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) {
269285 // We can remove a PHI if it is on a cycle in the def-use graph
270286 // where each node in the cycle has degree one, i.e. only one use,
271287 // and is an instruction with no side effects.
272 if (!PN->hasOneUse())
288 if (!areAllUsesEqual(PN))
273289 return false;
274290
275291 bool Changed = false;
276292 SmallPtrSet PHIs;
277293 PHIs.insert(PN);
278294 for (Instruction *J = cast(*PN->use_begin());
279 J->hasOneUse() && !J->mayHaveSideEffects();
295 areAllUsesEqual(J) && !J->mayHaveSideEffects();
280296 J = cast(*J->use_begin()))
281297 // If we find a PHI more than once, we're on a cycle that
282298 // won't prove fruitful.
283299 if (PHINode *JP = dyn_cast(J))
284 if (!PHIs.insert(cast(JP))) {
300 if (!PHIs.insert(JP)) {
285301 // Break the cycle and delete the PHI and its operands.
286302 JP->replaceAllUsesWith(UndefValue::get(JP->getType()));
287303 (void)RecursivelyDeleteTriviallyDeadInstructions(JP);
None ; RUN: opt < %s -loop-reduce -S | grep {phi\\>} | count 10
0 ; RUN: opt < %s -loop-reduce -S | grep {phi\\>} | count 8
11 ; PR2570
22
33 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
0 //===- Local.cpp - Unit tests for Local -----------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "gtest/gtest.h"
10 #include "llvm/BasicBlock.h"
11 #include "llvm/Instructions.h"
12 #include "llvm/LLVMContext.h"
13 #include "llvm/Support/IRBuilder.h"
14 #include "llvm/Transforms/Utils/Local.h"
15
16 using namespace llvm;
17
18 TEST(Local, RecursivelyDeleteDeadPHINodes) {
19 LLVMContext &C(getGlobalContext());
20
21 IRBuilder<> builder(C);
22
23 // Make blocks
24 BasicBlock *bb0 = BasicBlock::Create(C);
25 BasicBlock *bb1 = BasicBlock::Create(C);
26
27 builder.SetInsertPoint(bb0);
28 PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C));
29 BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
30
31 builder.SetInsertPoint(bb1);
32 BranchInst *br1 = builder.CreateBr(bb0);
33
34 phi->addIncoming(phi, bb0);
35 phi->addIncoming(phi, bb1);
36
37 // The PHI will be removed
38 EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
39
40 // Make sure the blocks only contain the branches
41 EXPECT_EQ(&bb0->front(), br0);
42 EXPECT_EQ(&bb1->front(), br1);
43
44 bb0->dropAllReferences();
45 bb1->dropAllReferences();
46 delete bb0;
47 delete bb1;
48 }