Make order of argument addition deterministic. In particular, the layout
[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 using namespace llvm;
29
30 namespace {
31   Statistic<> NumMarked("constify", "Number of globals marked constant");
32
33   struct Constifier : public Pass {
34     bool run(Module &M);
35   };
36
37   RegisterOpt<Constifier> X("constify", "Global Constifier");
38 }
39
40 Pass *llvm::createGlobalConstifierPass() { return new Constifier(); }
41
42 /// isStoredThrough - Return false if the specified pointer is provably never
43 /// stored through.  If we can't tell, we must conservatively assume it might.
44 ///
45 static bool isStoredThrough(Value *V) {
46   for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
47     if (Constant *C = dyn_cast<Constant>(*UI)) {
48       if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
49         if (isStoredThrough(CE))
50           return true;
51       } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
52         if (isStoredThrough(CPR)) return true;
53       } else {
54         // Must be an element of a constant array or something.
55         return true;
56       }
57     } else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
58       if (I->getOpcode() == Instruction::GetElementPtr) {
59         if (isStoredThrough(I)) return true;
60       } else if (!isa<LoadInst>(*UI) && !isa<SetCondInst>(*UI))
61         return true;  // Any other non-load instruction might store!
62     } else {
63       // Otherwise must be a global or some other user.
64       return true;
65     }
66
67   return false;
68 }
69
70 bool Constifier::run(Module &M) {
71   bool Changed = false;
72   for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
73     if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
74       if (!isStoredThrough(GV)) {
75         DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
76         GV->setConstant(true);
77         ++NumMarked;
78         Changed = true;
79       }
80     }
81   return Changed;
82 }