GlobalOpt.cpp revision 9ce300013d5c5b9e2c7e26626ddbc8f3a42bdb88
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"
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/// A lot of global constants are stored only in trivially dead setter
43/// functions.  Because we don't want to cycle between globaldce and this pass,
44/// just do a simple check to catch the common case.
45static bool ContainingFunctionIsTriviallyDead(Instruction *I) {
46  Function *F = I->getParent()->getParent();
47  if (!F->hasInternalLinkage()) return false;
48  F->removeDeadConstantUsers();
49  return F->use_empty();
50}
51
52/// isStoredThrough - Return false if the specified pointer is provably never
53/// stored through.  If we can't tell, we must conservatively assume it might.
54///
55static bool isStoredThrough(Value *V) {
56  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
57    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
58      if (isStoredThrough(CE))
59        return true;
60    } else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
61      if (!ContainingFunctionIsTriviallyDead(I)) {
62        if (I->getOpcode() == Instruction::GetElementPtr) {
63          if (isStoredThrough(I)) return true;
64        } else if (!isa<LoadInst>(*UI) && !isa<SetCondInst>(*UI)) {
65          return true;  // Any other non-load instruction might store!
66        }
67      }
68    } else {
69      // Otherwise must be a global or some other user.
70      return true;
71    }
72
73  return false;
74}
75
76bool Constifier::run(Module &M) {
77  bool Changed = false;
78  for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV)
79    if (!GV->isConstant() && GV->hasInternalLinkage() && GV->hasInitializer()) {
80      if (!isStoredThrough(GV)) {
81        DEBUG(std::cerr << "MARKING CONSTANT: " << *GV << "\n");
82        GV->setConstant(true);
83        ++NumMarked;
84        Changed = true;
85      }
86    }
87  return Changed;
88}
89