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