Be a bit more efficient when processing the active and inactive
[oota-llvm.git] / lib / Transforms / IPO / GlobalOpt.cpp
1 //===- GlobalConstifier.cpp - Mark read-only globals constant -------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass loops over the non-constant internal global variables in the
11 // program.  If it can prove that they are never written to, it marks them
12 // constant.
13 //
14 // NOTE: this should eventually use the alias analysis interfaces to do the
15 // transformation, but for now we just stick with a simple solution. DSA in
16 // particular could give a much more accurate answer to the mod/ref query, but
17 // it's not quite ready for this.
18 //
19 //===----------------------------------------------------------------------===//
20
21 #include "llvm/Transforms/IPO.h"
22 #include "llvm/Constants.h"
23 #include "llvm/Instructions.h"
24 #include "llvm/Module.h"
25 #include "llvm/Pass.h"
26 #include "Support/Debug.h"
27 #include "Support/Statistic.h"
28 #include <set>
29 using namespace llvm;
30
31 namespace {
32   Statistic<> NumMarked("constify", "Number of globals marked constant");
33
34   struct Constifier : public Pass {
35     bool run(Module &M);
36   };
37
38   RegisterOpt<Constifier> X("constify", "Global Constifier");
39 }
40
41 Pass *llvm::createGlobalConstifierPass() { return new Constifier(); }
42
43 /// A lot of global constants are stored only in trivially dead setter
44 /// functions.  Because we don't want to cycle between globaldce and this pass,
45 /// just do a simple check to catch the common case.
46 static bool ContainingFunctionIsTriviallyDead(Instruction *I) {
47   Function *F = I->getParent()->getParent();
48   if (!F->hasInternalLinkage()) return false;
49   F->removeDeadConstantUsers();
50   return F->use_empty();
51 }
52
53 /// isStoredThrough - Return false if the specified pointer is provably never
54 /// stored through.  If we can't tell, we must conservatively assume it might.
55 ///
56 static bool isStoredThrough(Value *V, std::set<PHINode*> &PHIUsers) {
57   for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
58     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
59       if (isStoredThrough(CE, PHIUsers))
60         return true;
61     } else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
62       if (!ContainingFunctionIsTriviallyDead(I)) {
63         if (I->getOpcode() == Instruction::GetElementPtr ||
64             I->getOpcode() == Instruction::Select) {
65           if (isStoredThrough(I, PHIUsers)) return true;
66         } else if (PHINode *PN = dyn_cast<PHINode>(I)) {
67           // PHI nodes we can check just like select or GEP instructions, but we
68           // have to be careful about infinite recursion.
69           if (PHIUsers.insert(PN).second)  // Not already visited.
70             if (isStoredThrough(I, PHIUsers)) return true;
71
72         } else if (!isa<LoadInst>(I) && !isa<SetCondInst>(I)) {
73           return true;  // Any other non-load instruction might store!
74         }
75       }
76     } else {
77       // Otherwise must be a global or some other user.
78       return true;
79     }
80
81   return false;
82 }
83
84 bool Constifier::run(Module &M) {
85   bool Changed = false;
86   std::set<PHINode*> PHIUsers;
87   for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
88     if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
89       if (!isStoredThrough(GV, PHIUsers)) {
90         DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
91         GV->setConstant(true);
92         ++NumMarked;
93         Changed = true;
94       }
95       PHIUsers.clear();
96     }
97   return Changed;
98 }