From abbc2dd77908f146f73f4cd1abfdfe47faacf43d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 19 Dec 2003 05:56:28 +0000 Subject: [PATCH] Add new function git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10529 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/Local.h | 10 ++++++ lib/Transforms/Utils/Local.cpp | 51 +++++++++++++++++++++------ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 2f83174249c..c786c965126 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -20,6 +20,7 @@ namespace llvm { class Pass; +class PHINode; //===----------------------------------------------------------------------===// // Local constant propagation... @@ -55,6 +56,15 @@ bool isInstructionTriviallyDead(Instruction *I); /// bool dceInstruction(BasicBlock::iterator &BBI); +//===----------------------------------------------------------------------===// +// PHI Instruction Simplification +// + +/// hasConstantValue - If the specified PHI node always merges together the same +/// value, return the value, otherwise return null. +/// +Value *hasConstantValue(PHINode *PN); + //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring... diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 894699596e1..5ec6ff90633 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -15,18 +15,18 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/iTerminators.h" #include "llvm/iOperators.h" +#include "llvm/iPHINode.h" #include "llvm/ConstantHandling.h" - -namespace llvm { +using namespace llvm; //===----------------------------------------------------------------------===// // Local constant propagation... // -// ConstantFoldInstruction - If an instruction references constants, try to fold -// them together... -// -bool doConstantPropagation(BasicBlock::iterator &II) { +/// doConstantPropagation - If an instruction references constants, try to fold +/// them together... +/// +bool llvm::doConstantPropagation(BasicBlock::iterator &II) { if (Constant *C = ConstantFoldInstruction(II)) { // Replaces all of the uses of a variable with uses of the constant. II->replaceAllUsesWith(C); @@ -43,7 +43,7 @@ bool doConstantPropagation(BasicBlock::iterator &II) { // constant value, convert it into an unconditional branch to the constant // destination. // -bool ConstantFoldTerminator(BasicBlock *BB) { +bool llvm::ConstantFoldTerminator(BasicBlock *BB) { TerminatorInst *T = BB->getTerminator(); // Branch - See if we are conditional jumping on constant @@ -165,7 +165,7 @@ bool ConstantFoldTerminator(BasicBlock *BB) { // Local dead code elimination... // -bool isInstructionTriviallyDead(Instruction *I) { +bool llvm::isInstructionTriviallyDead(Instruction *I) { return I->use_empty() && !I->mayWriteToMemory() && !isa(I); } @@ -174,7 +174,7 @@ bool isInstructionTriviallyDead(Instruction *I) { // to point to the instruction that immediately succeeded the original // instruction. // -bool dceInstruction(BasicBlock::iterator &BBI) { +bool llvm::dceInstruction(BasicBlock::iterator &BBI) { // Look for un"used" definitions... if (isInstructionTriviallyDead(BBI)) { BBI = BBI->getParent()->getInstList().erase(BBI); // Bye bye @@ -183,4 +183,35 @@ bool dceInstruction(BasicBlock::iterator &BBI) { return false; } -} // End llvm namespace +//===----------------------------------------------------------------------===// +// PHI Instruction Simplification +// + +/// hasConstantValue - If the specified PHI node always merges together the same +/// value, return the value, otherwise return null. +/// +Value *llvm::hasConstantValue(PHINode *PN) { + // If the PHI node only has one incoming value, eliminate the PHI node... + if (PN->getNumIncomingValues() == 1) + return PN->getIncomingValue(0); + + // Otherwise if all of the incoming values are the same for the PHI, replace + // the PHI node with the incoming value. + // + Value *InVal = 0; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) != PN) // Not the PHI node itself... + if (InVal && PN->getIncomingValue(i) != InVal) + return 0; // Not the same, bail out. + else + InVal = PN->getIncomingValue(i); + + // The only case that could cause InVal to be null is if we have a PHI node + // that only has entries for itself. In this case, there is no entry into the + // loop, so kill the PHI. + // + if (InVal == 0) InVal = Constant::getNullValue(PN->getType()); + + // All of the incoming values are the same, return the value now. + return InVal; +}