X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FIPConstantPropagation.cpp;h=8684796b4e7835b729c89301650ca2af680c7824;hp=c51c023c686127aab00ccc8bf8f1673cfd138ea1;hb=36b699f2b139a30a2dfa4448223d6985b55daa8a;hpb=4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp index c51c023c686..8684796b4e7 100644 --- a/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -17,14 +17,14 @@ #define DEBUG_TYPE "ipconstprop" #include "llvm/Transforms/IPO.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/Compiler.h" -#include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" using namespace llvm; STATISTIC(NumArgumentsProped, "Number of args turned into constants"); @@ -33,19 +33,23 @@ STATISTIC(NumReturnValProped, "Number of return values turned into constants"); namespace { /// IPCP - The interprocedural constant propagation pass /// - struct VISIBILITY_HIDDEN IPCP : public ModulePass { + struct IPCP : public ModulePass { static char ID; // Pass identification, replacement for typeid - IPCP() : ModulePass((intptr_t)&ID) {} + IPCP() : ModulePass(ID) { + initializeIPCPPass(*PassRegistry::getPassRegistry()); + } - bool runOnModule(Module &M); + bool runOnModule(Module &M) override; private: bool PropagateConstantsIntoArguments(Function &F); bool PropagateConstantReturn(Function &F); }; - char IPCP::ID = 0; - RegisterPass X("ipconstprop", "Interprocedural constant propagation"); } +char IPCP::ID = 0; +INITIALIZE_PASS(IPCP, "ipconstprop", + "Interprocedural constant propagation", false, false) + ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); } bool IPCP::runOnModule(Module &M) { @@ -60,7 +64,7 @@ bool IPCP::runOnModule(Module &M) { if (!I->isDeclaration()) { // Delete any klingons. I->removeDeadConstantUsers(); - if (I->hasInternalLinkage()) + if (I->hasLocalLinkage()) LocalChange |= PropagateConstantsIntoArguments(*I); Changed |= PropagateConstantReturn(*I); } @@ -82,14 +86,19 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) { ArgumentConstants.resize(F.arg_size()); unsigned NumNonconstant = 0; - for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) { + for (Use &U : F.uses()) { + User *UR = U.getUser(); + // Ignore blockaddress uses. + if (isa(UR)) continue; + // Used by a non-instruction, or not the callee of a function, do not // transform. - if (UI.getOperandNo() != 0 || - (!isa(*UI) && !isa(*UI))) + if (!isa(UR) && !isa(UR)) return false; - CallSite CS = CallSite::get(cast(*UI)); + CallSite CS(cast(UR)); + if (!CS.isCallee(&U)) + return false; // Check out all of the potentially constant arguments. Note that we don't // inspect varargs here. @@ -125,7 +134,8 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) { Function::arg_iterator AI = F.arg_begin(); for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) { // Do we have a constant argument? - if (ArgumentConstants[i].second || AI->use_empty()) + if (ArgumentConstants[i].second || AI->use_empty() || + AI->hasInAllocaAttr() || (AI->hasByValAttr() && !F.onlyReadsMemory())) continue; Value *V = ArgumentConstants[i].first; @@ -138,95 +148,126 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) { } -// Check to see if this function returns a constant. If so, replace all callers -// that user the return value with the returned valued. If we can replace ALL -// callers, +// Check to see if this function returns one or more constants. If so, replace +// all callers that use those return values with the constant value. This will +// leave in the actual return values and instructions, but deadargelim will +// clean that up. +// +// Additionally if a function always returns one of its arguments directly, +// callers will be updated to use the value they pass in directly instead of +// using the return value. bool IPCP::PropagateConstantReturn(Function &F) { - if (F.getReturnType() == Type::VoidTy) + if (F.getReturnType()->isVoidTy()) return false; // No return value. + // If this function could be overridden later in the link stage, we can't + // propagate information about its results into callers. + if (F.mayBeOverridden()) + return false; + // Check to see if this function returns a constant. SmallVector RetVals; - const StructType *STy = dyn_cast(F.getReturnType()); + StructType *STy = dyn_cast(F.getReturnType()); if (STy) - RetVals.assign(STy->getNumElements(), 0); + for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i) + RetVals.push_back(UndefValue::get(STy->getElementType(i))); else - RetVals.push_back(0); + RetVals.push_back(UndefValue::get(F.getReturnType())); + unsigned NumNonConstant = 0; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { - assert(RetVals.size() == RI->getNumOperands() && - "Invalid ReturnInst operands!"); for (unsigned i = 0, e = RetVals.size(); i != e; ++i) { - if (isa(RI->getOperand(i))) - continue; // Ignore - Constant *C = dyn_cast(RI->getOperand(i)); - if (C == 0) - return false; // Does not return a constant. - + // Already found conflicting return values? Value *RV = RetVals[i]; - if (RV == 0) - RetVals[i] = C; - else if (RV != C) - return false; // Does not return the same constant. + if (!RV) + continue; + + // Find the returned value + Value *V; + if (!STy) + V = RI->getOperand(0); + else + V = FindInsertedValue(RI->getOperand(0), i); + + if (V) { + // Ignore undefs, we can change them into anything + if (isa(V)) + continue; + + // Try to see if all the rets return the same constant or argument. + if (isa(V) || isa(V)) { + if (isa(RV)) { + // No value found yet? Try the current one. + RetVals[i] = V; + continue; + } + // Returning the same value? Good. + if (RV == V) + continue; + } + } + // Different or no known return value? Don't propagate this return + // value. + RetVals[i] = 0; + // All values non-constant? Stop looking. + if (++NumNonConstant == RetVals.size()) + return false; } } - if (STy) { - for (unsigned i = 0, e = RetVals.size(); i < e; ++i) - if (RetVals[i] == 0) - RetVals[i] = UndefValue::get(STy->getElementType(i)); - } else { - assert(RetVals.size() == 1); - if (RetVals[0] == 0) - RetVals[0] = UndefValue::get(F.getReturnType()); - } - - // If we got here, the function returns a constant value. Loop over all - // users, replacing any uses of the return value with the returned constant. - bool ReplacedAllUsers = true; + // If we got here, the function returns at least one constant value. Loop + // over all users, replacing any uses of the return value with the returned + // constant. bool MadeChange = false; - for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) { - // Make sure this is an invoke or call and that the use is for the callee. - if (!(isa(*UI) || isa(*UI)) || - UI.getOperandNo() != 0) { - ReplacedAllUsers = false; + for (Use &U : F.uses()) { + CallSite CS(U.getUser()); + Instruction* Call = CS.getInstruction(); + + // Not a call instruction or a call instruction that's not calling F + // directly? + if (!Call || !CS.isCallee(&U)) continue; - } - Instruction *Call = cast(*UI); + // Call result not used? if (Call->use_empty()) continue; MadeChange = true; if (STy == 0) { - Call->replaceAllUsesWith(RetVals[0]); + Value* New = RetVals[0]; + if (Argument *A = dyn_cast(New)) + // Was an argument returned? Then find the corresponding argument in + // the call instruction and use that. + New = CS.getArgument(A->getArgNo()); + Call->replaceAllUsesWith(New); continue; } - - while (!Call->use_empty()) { - GetResultInst *GR = cast(Call->use_back()); - GR->replaceAllUsesWith(RetVals[GR->getIndex()]); - GR->eraseFromParent(); - } - } - - // If we replace all users with the returned constant, and there can be no - // other callers of the function, replace the constant being returned in the - // function with an undef value. - if (ReplacedAllUsers && F.hasInternalLinkage()) { - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { - for (unsigned i = 0, e = RetVals.size(); i < e; ++i) { - Value *RetVal = RetVals[i]; - if (isa(RetVal)) - continue; - Value *RV = UndefValue::get(RetVal->getType()); - if (RI->getOperand(i) != RV) { - RI->setOperand(i, RV); - MadeChange = true; - } + + for (auto I = Call->user_begin(), E = Call->user_end(); I != E;) { + Instruction *Ins = cast(*I); + + // Increment now, so we can remove the use + ++I; + + // Find the index of the retval to replace with + int index = -1; + if (ExtractValueInst *EV = dyn_cast(Ins)) + if (EV->hasIndices()) + index = *EV->idx_begin(); + + // If this use uses a specific return value, and we have a replacement, + // replace it. + if (index != -1) { + Value *New = RetVals[index]; + if (New) { + if (Argument *A = dyn_cast(New)) + // Was an argument returned? Then find the corresponding argument in + // the call instruction and use that. + New = CS.getArgument(A->getArgNo()); + Ins->replaceAllUsesWith(New); + Ins->eraseFromParent(); } } }