IPConstantPropagation.cpp revision 4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                     The LLVM Compiler Infrastructure
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This file is distributed under the University of Illinois Open Source
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// License. See LICENSE.TXT for details.
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//===----------------------------------------------------------------------===//
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This pass implements an _extremely_ simple interprocedural constant
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// propagation pass.  It could certainly be improved in many different ways,
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// like using a worklist.  This pass makes arguments dead, but does not remove
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// them.  The existing dead argument elimination pass should be run after this
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// to clean up the mess.
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//===----------------------------------------------------------------------===//
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DEBUG_TYPE "ipconstprop"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "llvm/Transforms/IPO.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "llvm/Constants.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "llvm/Instructions.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "llvm/Module.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "llvm/Pass.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "llvm/Support/CallSite.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "llvm/Support/Compiler.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "llvm/ADT/Statistic.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "llvm/ADT/SmallVector.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing namespace llvm;
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSTATISTIC(NumArgumentsProped, "Number of args turned into constants");
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSTATISTIC(NumReturnValProped, "Number of return values turned into constants");
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  /// IPCP - The interprocedural constant propagation pass
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ///
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct VISIBILITY_HIDDEN IPCP : public ModulePass {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static char ID; // Pass identification, replacement for typeid
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPCP() : ModulePass((intptr_t)&ID) {}
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool runOnModule(Module &M);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  private:
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool PropagateConstantsIntoArguments(Function &F);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool PropagateConstantReturn(Function &F);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  char IPCP::ID = 0;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RegisterPass<IPCP> X("ipconstprop", "Interprocedural constant propagation");
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IPCP::runOnModule(Module &M) {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool Changed = false;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool LocalChange = true;
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // FIXME: instead of using smart algorithms, we just iterate until we stop
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // making changes.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (LocalChange) {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LocalChange = false;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!I->isDeclaration()) {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Delete any klingons.
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        I->removeDeadConstantUsers();
63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (I->hasInternalLinkage())
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          LocalChange |= PropagateConstantsIntoArguments(*I);
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        Changed |= PropagateConstantReturn(*I);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Changed |= LocalChange;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Changed;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/// PropagateConstantsIntoArguments - Look at all uses of the specified
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/// function.  If all uses are direct call sites, and all pass a particular
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/// constant in for an argument, propagate that constant in as the argument.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IPCP::PropagateConstantsIntoArguments(Function &F) {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For each argument, keep track of its constant value and whether it is a
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // constant or not.  The bool is driven to true when found to be non-constant.
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ArgumentConstants.resize(F.arg_size());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unsigned NumNonconstant = 0;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Used by a non-instruction, or not the callee of a function, do not
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // transform.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (UI.getOperandNo() != 0 ||
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (!isa<CallInst>(*UI) && !isa<InvokeInst>(*UI)))
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallSite CS = CallSite::get(cast<Instruction>(*UI));
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Check out all of the potentially constant arguments.  Note that we don't
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // inspect varargs here.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CallSite::arg_iterator AI = CS.arg_begin();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Function::arg_iterator Arg = F.arg_begin();
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         ++i, ++AI, ++Arg) {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // If this argument is known non-constant, ignore it.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (ArgumentConstants[i].second)
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      Constant *C = dyn_cast<Constant>(*AI);
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (C && ArgumentConstants[i].first == 0) {
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ArgumentConstants[i].first = C;   // First constant seen.
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (C && ArgumentConstants[i].first == C) {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Still the constant value we think it is.
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else if (*AI == &*Arg) {
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Ignore recursive calls passing argument down.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Argument became non-constant.  If all arguments are non-constant now,
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // give up on this function.
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (++NumNonconstant == ArgumentConstants.size())
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return false;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ArgumentConstants[i].second = true;
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // If we got to this point, there is a constant argument!
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  assert(NumNonconstant != ArgumentConstants.size());
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool MadeChange = false;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Function::arg_iterator AI = F.arg_begin();
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Do we have a constant argument?
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ArgumentConstants[i].second || AI->use_empty())
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value *V = ArgumentConstants[i].first;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (V == 0) V = UndefValue::get(AI->getType());
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    AI->replaceAllUsesWith(V);
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ++NumArgumentsProped;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MadeChange = true;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return MadeChange;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Check to see if this function returns a constant.  If so, replace all callers
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// that user the return value with the returned valued.  If we can replace ALL
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callers,
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IPCP::PropagateConstantReturn(Function &F) {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (F.getReturnType() == Type::VoidTy)
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false; // No return value.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check to see if this function returns a constant.
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SmallVector<Value *,4> RetVals;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const StructType *STy = dyn_cast<StructType>(F.getReturnType());
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (STy)
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RetVals.assign(STy->getNumElements(), 0);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RetVals.push_back(0);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      assert(RetVals.size() == RI->getNumOperands() &&
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick             "Invalid ReturnInst operands!");
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (isa<UndefValue>(RI->getOperand(i)))
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          continue; // Ignore
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        Constant *C = dyn_cast<Constant>(RI->getOperand(i));
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (C == 0)
165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          return false; // Does not return a constant.
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        Value *RV = RetVals[i];
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (RV == 0)
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          RetVals[i] = C;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        else if (RV != C)
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return false; // Does not return the same constant.
172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (STy) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (unsigned i = 0, e = RetVals.size(); i < e; ++i)
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (RetVals[i] == 0)
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        RetVals[i] = UndefValue::get(STy->getElementType(i));
179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    assert(RetVals.size() == 1);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (RetVals[0] == 0)
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RetVals[0] = UndefValue::get(F.getReturnType());
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we got here, the function returns a constant value.  Loop over all
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // users, replacing any uses of the return value with the returned constant.
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ReplacedAllUsers = true;
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool MadeChange = false;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure this is an invoke or call and that the use is for the callee.
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!(isa<InvokeInst>(*UI) || isa<CallInst>(*UI)) ||
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UI.getOperandNo() != 0) {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ReplacedAllUsers = false;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Instruction *Call = cast<Instruction>(*UI);
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (Call->use_empty())
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MadeChange = true;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (STy == 0) {
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Call->replaceAllUsesWith(RetVals[0]);
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      continue;
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    while (!Call->use_empty()) {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetResultInst *GR = cast<GetResultInst>(Call->use_back());
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GR->replaceAllUsesWith(RetVals[GR->getIndex()]);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GR->eraseFromParent();
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // If we replace all users with the returned constant, and there can be no
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // other callers of the function, replace the constant being returned in the
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // function with an undef value.
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (ReplacedAllUsers && F.hasInternalLinkage()) {
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        for (unsigned i = 0, e = RetVals.size(); i < e; ++i) {
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          Value *RetVal = RetVals[i];
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          if (isa<UndefValue>(RetVal))
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            continue;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Value *RV = UndefValue::get(RetVal->getType());
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          if (RI->getOperand(i) != RV) {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            RI->setOperand(i, RV);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            MadeChange = true;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (MadeChange) ++NumReturnValProped;
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return MadeChange;
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick