summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-08-14 20:57:17 +0000
committerChris Lattner <sabre@nondot.org>2004-08-14 20:57:17 +0000
commit61391347154a67968733dc99d556b497009113fa (patch)
treed11e07bb1db4a5c260369bd04fbed63ac3494d9c /llvm/lib
parent22bef5979ab242c3c05e242135f47b544a4c89b7 (diff)
downloadbcm5719-llvm-61391347154a67968733dc99d556b497009113fa.tar.gz
bcm5719-llvm-61391347154a67968733dc99d556b497009113fa.zip
Implement test/Regression/Transforms/GlobalConstifier/phi-select.llx
This allows more globals to be marked constant, particularly global arrays. llvm-svn: 15735
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/IPO/GlobalConstifier.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalConstifier.cpp b/llvm/lib/Transforms/IPO/GlobalConstifier.cpp
index 97518a34fab..f9be0ad2460 100644
--- a/llvm/lib/Transforms/IPO/GlobalConstifier.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalConstifier.cpp
@@ -25,6 +25,7 @@
#include "llvm/Pass.h"
#include "Support/Debug.h"
#include "Support/Statistic.h"
+#include <set>
using namespace llvm;
namespace {
@@ -52,16 +53,23 @@ static bool ContainingFunctionIsTriviallyDead(Instruction *I) {
/// isStoredThrough - Return false if the specified pointer is provably never
/// stored through. If we can't tell, we must conservatively assume it might.
///
-static bool isStoredThrough(Value *V) {
+static bool isStoredThrough(Value *V, std::set<PHINode*> &PHIUsers) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
- if (isStoredThrough(CE))
+ if (isStoredThrough(CE, PHIUsers))
return true;
} else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
if (!ContainingFunctionIsTriviallyDead(I)) {
- if (I->getOpcode() == Instruction::GetElementPtr) {
- if (isStoredThrough(I)) return true;
- } else if (!isa<LoadInst>(*UI) && !isa<SetCondInst>(*UI)) {
+ if (I->getOpcode() == Instruction::GetElementPtr ||
+ I->getOpcode() == Instruction::Select) {
+ if (isStoredThrough(I, PHIUsers)) return true;
+ } else if (PHINode *PN = dyn_cast<PHINode>(I)) {
+ // PHI nodes we can check just like select or GEP instructions, but we
+ // have to be careful about infinite recursion.
+ if (PHIUsers.insert(PN).second) // Not already visited.
+ if (isStoredThrough(I, PHIUsers)) return true;
+
+ } else if (!isa<LoadInst>(I) && !isa<SetCondInst>(I)) {
return true; // Any other non-load instruction might store!
}
}
@@ -75,14 +83,16 @@ static bool isStoredThrough(Value *V) {
bool Constifier::run(Module &M) {
bool Changed = false;
+ std::set<PHINode*> PHIUsers;
for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
- if (!isStoredThrough(GV)) {
+ if (!isStoredThrough(GV, PHIUsers)) {
DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
GV->setConstant(true);
++NumMarked;
Changed = true;
}
+ PHIUsers.clear();
}
return Changed;
}
OpenPOWER on IntegriCloud