blob: c30ec5f47c196875a74b5026de3751b1ff2885a4 [file] [log] [blame]
Chris Lattner8d1da1a2004-02-25 21:34:36 +00001//===- 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"
Chris Lattnere82c2172004-02-27 18:09:25 +000023#include "llvm/Instructions.h"
Chris Lattner8d1da1a2004-02-25 21:34:36 +000024#include "llvm/Module.h"
25#include "llvm/Pass.h"
26#include "Support/Debug.h"
27#include "Support/Statistic.h"
28using namespace llvm;
29
30namespace {
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
40Pass *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///
45static 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;
Chris Lattnere82c2172004-02-27 18:09:25 +000060 } else if (!isa<LoadInst>(*UI) && !isa<SetCondInst>(*UI))
Chris Lattner8d1da1a2004-02-25 21:34:36 +000061 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
70bool 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}