IPConstantPropagation.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===// 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// The LLVM Compiler Infrastructure 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// This file is distributed under the University of Illinois Open Source 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// License. See LICENSE.TXT for details. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//===----------------------------------------------------------------------===// 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// This pass implements an _extremely_ simple interprocedural constant 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// propagation pass. It could certainly be improved in many different ways, 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// like using a worklist. This pass makes arguments dead, but does not remove 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// them. The existing dead argument elimination pass should be run after this 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// to clean up the mess. 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//===----------------------------------------------------------------------===// 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define DEBUG_TYPE "ipconstprop" 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "llvm/Transforms/IPO.h" 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "llvm/ADT/SmallVector.h" 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "llvm/ADT/Statistic.h" 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "llvm/Analysis/ValueTracking.h" 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "llvm/IR/CallSite.h" 24ffa5c93d455f33af1be3b04d39520413dc24afd5Zhihai Xu#include "llvm/IR/Constants.h" 25ffa5c93d455f33af1be3b04d39520413dc24afd5Zhihai Xu#include "llvm/IR/Instructions.h" 26ffa5c93d455f33af1be3b04d39520413dc24afd5Zhihai Xu#include "llvm/IR/Module.h" 27ffa5c93d455f33af1be3b04d39520413dc24afd5Zhihai Xu#include "llvm/Pass.h" 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectusing namespace llvm; 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectSTATISTIC(NumArgumentsProped, "Number of args turned into constants"); 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectSTATISTIC(NumReturnValProped, "Number of return values turned into constants"); 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectnamespace { 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /// IPCP - The interprocedural constant propagation pass 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /// 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct IPCP : public ModulePass { 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project static char ID; // Pass identification, replacement for typeid 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project IPCP() : ModulePass(ID) { 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project initializeIPCPPass(*PassRegistry::getPassRegistry()); 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool runOnModule(Module &M) override; 432154e12efeec88780933d47b3c3686ff9f6fe84dZhihai Xu private: 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool PropagateConstantsIntoArguments(Function &F); 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool PropagateConstantReturn(Function &F); 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project }; 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectchar IPCP::ID = 0; 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectINITIALIZE_PASS(IPCP, "ipconstprop", 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "Interprocedural constant propagation", false, false) 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); } 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbool IPCP::runOnModule(Module &M) { 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool Changed = false; 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool LocalChange = true; 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // FIXME: instead of using smart algorithms, we just iterate until we stop 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // making changes. 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (LocalChange) { 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project LocalChange = false; 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!I->isDeclaration()) { 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Delete any klingons. 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project I->removeDeadConstantUsers(); 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (I->hasLocalLinkage()) 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project LocalChange |= PropagateConstantsIntoArguments(*I); 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Changed |= PropagateConstantReturn(*I); 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Changed |= LocalChange; 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return Changed; 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/// PropagateConstantsIntoArguments - Look at all uses of the specified 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/// function. If all uses are direct call sites, and all pass a particular 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/// constant in for an argument, propagate that constant in as the argument. 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/// 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbool IPCP::PropagateConstantsIntoArguments(Function &F) { 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit. 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // For each argument, keep track of its constant value and whether it is a 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // constant or not. The bool is driven to true when found to be non-constant. 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants; 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ArgumentConstants.resize(F.arg_size()); 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned NumNonconstant = 0; 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (Use &U : F.uses()) { 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project User *UR = U.getUser(); 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Ignore blockaddress uses. 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (isa<BlockAddress>(UR)) continue; 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Used by a non-instruction, or not the callee of a function, do not 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // transform. 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!isa<CallInst>(UR) && !isa<InvokeInst>(UR)) 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CallSite CS(cast<Instruction>(UR)); 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!CS.isCallee(&U)) 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Check out all of the potentially constant arguments. Note that we don't 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // inspect varargs here. 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CallSite::arg_iterator AI = CS.arg_begin(); 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Function::arg_iterator Arg = F.arg_begin(); 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (unsigned i = 0, e = ArgumentConstants.size(); i != e; 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ++i, ++AI, ++Arg) { 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // If this argument is known non-constant, ignore it. 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ArgumentConstants[i].second) 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Constant *C = dyn_cast<Constant>(*AI); 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (C && ArgumentConstants[i].first == 0) { 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ArgumentConstants[i].first = C; // First constant seen. 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } else if (C && ArgumentConstants[i].first == C) { 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Still the constant value we think it is. 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } else if (*AI == &*Arg) { 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Ignore recursive calls passing argument down. 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } else { 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Argument became non-constant. If all arguments are non-constant now, 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // give up on this function. 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (++NumNonconstant == ArgumentConstants.size()) 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ArgumentConstants[i].second = true; 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // If we got to this point, there is a constant argument! 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project assert(NumNonconstant != ArgumentConstants.size()); 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool MadeChange = false; 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Function::arg_iterator AI = F.arg_begin(); 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) { 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Do we have a constant argument? 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ArgumentConstants[i].second || AI->use_empty() || 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AI->hasInAllocaAttr() || (AI->hasByValAttr() && !F.onlyReadsMemory())) 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Value *V = ArgumentConstants[i].first; 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (V == 0) V = UndefValue::get(AI->getType()); 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AI->replaceAllUsesWith(V); 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ++NumArgumentsProped; 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MadeChange = true; 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return MadeChange; 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Check to see if this function returns one or more constants. If so, replace 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// all callers that use those return values with the constant value. This will 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// leave in the actual return values and instructions, but deadargelim will 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// clean that up. 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Additionally if a function always returns one of its arguments directly, 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// callers will be updated to use the value they pass in directly instead of 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// using the return value. 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbool IPCP::PropagateConstantReturn(Function &F) { 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (F.getReturnType()->isVoidTy()) 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; // No return value. 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // If this function could be overridden later in the link stage, we can't 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // propagate information about its results into callers. 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (F.mayBeOverridden()) 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Check to see if this function returns a constant. 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SmallVector<Value *,4> RetVals; 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project StructType *STy = dyn_cast<StructType>(F.getReturnType()); 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (STy) 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i) 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RetVals.push_back(UndefValue::get(STy->getElementType(i))); 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RetVals.push_back(UndefValue::get(F.getReturnType())); 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned NumNonConstant = 0; 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (unsigned i = 0, e = RetVals.size(); i != e; ++i) { 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Already found conflicting return values? 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Value *RV = RetVals[i]; 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!RV) 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Find the returned value 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Value *V; 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!STy) 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project V = RI->getOperand(0); 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project V = FindInsertedValue(RI->getOperand(0), i); 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (V) { 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Ignore undefs, we can change them into anything 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (isa<UndefValue>(V)) 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Try to see if all the rets return the same constant or argument. 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (isa<Constant>(V) || isa<Argument>(V)) { 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (isa<UndefValue>(RV)) { 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // No value found yet? Try the current one. 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RetVals[i] = V; 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Returning the same value? Good. 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (RV == V) 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Different or no known return value? Don't propagate this return 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // value. 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RetVals[i] = 0; 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // All values non-constant? Stop looking. 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (++NumNonConstant == RetVals.size()) 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return false; 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // If we got here, the function returns at least one constant value. Loop 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // over all users, replacing any uses of the return value with the returned 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // constant. 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bool MadeChange = false; 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (Use &U : F.uses()) { 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CallSite CS(U.getUser()); 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Instruction* Call = CS.getInstruction(); 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Not a call instruction or a call instruction that's not calling F 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // directly? 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!Call || !CS.isCallee(&U)) 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Call result not used? 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (Call->use_empty()) 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MadeChange = true; 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (STy == 0) { 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Value* New = RetVals[0]; 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (Argument *A = dyn_cast<Argument>(New)) 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Was an argument returned? Then find the corresponding argument in 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // the call instruction and use that. 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project New = CS.getArgument(A->getArgNo()); 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Call->replaceAllUsesWith(New); 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (auto I = Call->user_begin(), E = Call->user_end(); I != E;) { 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Instruction *Ins = cast<Instruction>(*I); 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Increment now, so we can remove the use 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ++I; 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Find the index of the retval to replace with 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int index = -1; 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins)) 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (EV->hasIndices()) 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project index = *EV->idx_begin(); 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // If this use uses a specific return value, and we have a replacement, 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // replace it. 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (index != -1) { 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Value *New = RetVals[index]; 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (New) { 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (Argument *A = dyn_cast<Argument>(New)) 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Was an argument returned? Then find the corresponding argument in 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // the call instruction and use that. 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project New = CS.getArgument(A->getArgNo()); 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Ins->replaceAllUsesWith(New); 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project Ins->eraseFromParent(); 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (MadeChange) ++NumReturnValProped; 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return MadeChange; 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project