summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/GCSE.cpp
blob: 776ff6603aa4b1af6ec2374293f1411e5c8faad0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
//===-- GCSE.cpp - SSA-based Global Common Subexpression Elimination ------===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This pass is designed to be a very quick global transformation that
// eliminates global common subexpressions from a function.  It does this by
// using an existing value numbering implementation to identify the common
// subexpressions, eliminating them when possible.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h"
#include "llvm/Constant.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/ValueNumbering.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
using namespace llvm;

namespace {
  Statistic<> NumInstRemoved("gcse", "Number of instructions removed");
  Statistic<> NumLoadRemoved("gcse", "Number of loads removed");
  Statistic<> NumCallRemoved("gcse", "Number of calls removed");
  Statistic<> NumNonInsts   ("gcse", "Number of instructions removed due "
                             "to non-instruction values");
  Statistic<> NumArgsRepl   ("gcse", "Number of function arguments replaced "
                             "with constant values");

  struct GCSE : public FunctionPass {
    virtual bool runOnFunction(Function &F);

  private:
    void ReplaceInstructionWith(Instruction *I, Value *V);

    // This transformation requires dominator and immediate dominator info
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
      AU.addRequired<DominatorSet>();
      AU.addRequired<DominatorTree>();
      AU.addRequired<ValueNumbering>();
    }
  };

  RegisterOpt<GCSE> X("gcse", "Global Common Subexpression Elimination");
}

// createGCSEPass - The public interface to this file...
FunctionPass *llvm::createGCSEPass() { return new GCSE(); }

// GCSE::runOnFunction - This is the main transformation entry point for a
// function.
//
bool GCSE::runOnFunction(Function &F) {
  bool Changed = false;

  // Get pointers to the analysis results that we will be using...
  DominatorSet &DS = getAnalysis<DominatorSet>();
  ValueNumbering &VN = getAnalysis<ValueNumbering>();
  DominatorTree &DT = getAnalysis<DominatorTree>();

  std::vector<Value*> EqualValues;

  // Check for value numbers of arguments.  If the value numbering
  // implementation can prove that an incoming argument is a constant or global
  // value address, substitute it, making the argument dead.
  for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI)
    if (!AI->use_empty()) {
      VN.getEqualNumberNodes(AI, EqualValues);
      if (!EqualValues.empty()) {
        for (unsigned i = 0, e = EqualValues.size(); i != e; ++i)
          if (isa<Constant>(EqualValues[i])) {
            AI->replaceAllUsesWith(EqualValues[i]);
            ++NumArgsRepl;
            Changed = true;
            break;
          }
        EqualValues.clear();
      }
    }

  // Traverse the CFG of the function in dominator order, so that we see each
  // instruction after we see its operands.
  for (df_iterator<DominatorTree::Node*> DI = df_begin(DT.getRootNode()),
         E = df_end(DT.getRootNode()); DI != E; ++DI) {
    BasicBlock *BB = DI->getBlock();

    // Remember which instructions we've seen in this basic block as we scan.
    std::set<Instruction*> BlockInsts;

    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
      Instruction *Inst = I++;

      // If this instruction computes a value, try to fold together common
      // instructions that compute it.
      //
      if (Inst->getType() != Type::VoidTy) {
        VN.getEqualNumberNodes(Inst, EqualValues);

        // If this instruction computes a value that is already computed
        // elsewhere, try to recycle the old value.
        if (!EqualValues.empty()) {
          if (Inst == &*BB->begin())
            I = BB->end();
          else {
            I = Inst; --I;
          }
          
          // First check to see if we were able to value number this instruction
          // to a non-instruction value.  If so, prefer that value over other
          // instructions which may compute the same thing.
          for (unsigned i = 0, e = EqualValues.size(); i != e; ++i)
            if (!isa<Instruction>(EqualValues[i])) {
              ++NumNonInsts;      // Keep track of # of insts repl with values

              // Change all users of Inst to use the replacement and remove it
              // from the program.
              ReplaceInstructionWith(Inst, EqualValues[i]);
              Inst = 0;
              EqualValues.clear();  // don't enter the next loop
              break;
            }

          // If there were no non-instruction values that this instruction
          // produces, find a dominating instruction that produces the same
          // value.  If we find one, use it's value instead of ours.
          for (unsigned i = 0, e = EqualValues.size(); i != e; ++i) {
            Instruction *OtherI = cast<Instruction>(EqualValues[i]);
            bool Dominates = false;
            if (OtherI->getParent() == BB)
              Dominates = BlockInsts.count(OtherI);
            else
              Dominates = DS.dominates(OtherI->getParent(), BB);

            if (Dominates) {
              // Okay, we found an instruction with the same value as this one
              // and that dominates this one.  Replace this instruction with the
              // specified one.
              ReplaceInstructionWith(Inst, OtherI);
              Inst = 0;
              break;
            }
          }

          EqualValues.clear();

          if (Inst) {
            I = Inst; ++I;             // Deleted no instructions
          } else if (I == BB->end()) { // Deleted first instruction
            I = BB->begin();
          } else {                     // Deleted inst in middle of block.
            ++I;
          }
        }

        if (Inst)
          BlockInsts.insert(Inst);
      }
    }
  }

  // When the worklist is empty, return whether or not we changed anything...
  return Changed;
}


void GCSE::ReplaceInstructionWith(Instruction *I, Value *V) {
  if (isa<LoadInst>(I))
    ++NumLoadRemoved; // Keep track of loads eliminated
  if (isa<CallInst>(I))
    ++NumCallRemoved; // Keep track of calls eliminated
  ++NumInstRemoved;   // Keep track of number of insts eliminated

  // Update value numbering
  getAnalysis<ValueNumbering>().deleteValue(I);

  // If we are not replacing the instruction with a constant, we cannot do
  // anything special.
  if (!isa<Constant>(V)) {
    I->replaceAllUsesWith(V);

    if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
      // Removing an invoke instruction requires adding a branch to the normal
      // destination and removing PHI node entries in the exception destination.
      new BranchInst(II->getNormalDest(), II);
      II->getUnwindDest()->removePredecessor(II->getParent());
    }
    
    // Erase the instruction from the program.
    I->getParent()->getInstList().erase(I);
    return;
  }

  Constant *C = cast<Constant>(V);
  std::vector<User*> Users(I->use_begin(), I->use_end());

  // Perform the replacement.
  I->replaceAllUsesWith(C);

  if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
    // Removing an invoke instruction requires adding a branch to the normal
    // destination and removing PHI node entries in the exception destination.
    new BranchInst(II->getNormalDest(), II);
    II->getUnwindDest()->removePredecessor(II->getParent());
  }

  // Erase the instruction from the program.
  I->getParent()->getInstList().erase(I);
  
  // Check each user to see if we can constant fold it.
  while (!Users.empty()) {
    Instruction *U = cast<Instruction>(Users.back());
    Users.pop_back();

    if (Constant *C = ConstantFoldInstruction(U)) {
      ReplaceInstructionWith(U, C);

      // If the instruction used I more than once, it could be on the user list
      // multiple times.  Make sure we don't reprocess it.
      std::vector<User*>::iterator It = std::find(Users.begin(), Users.end(),U);
      while (It != Users.end()) {
        Users.erase(It);
        It = std::find(Users.begin(), Users.end(), U);
      }
    }
  }
}