diff options
author | Chris Lattner <sabre@nondot.org> | 2008-04-23 06:16:27 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-04-23 06:16:27 +0000 |
commit | 4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b (patch) | |
tree | 6e953523c4f36eb201aefce94171d8907829386e /lib/Transforms/IPO | |
parent | e9625c6c88477382d7b4db6c16108ab2db2b1326 (diff) | |
download | external_llvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.zip external_llvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.tar.gz external_llvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.tar.bz2 |
simplify code for propagation of constant arguments into
callees.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50142 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r-- | lib/Transforms/IPO/IPConstantPropagation.cpp | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp index ad812fd..c51c023 100644 --- a/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -76,61 +76,64 @@ bool IPCP::runOnModule(Module &M) { bool IPCP::PropagateConstantsIntoArguments(Function &F) { if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit. - std::vector<std::pair<Constant*, bool> > ArgumentConstants; + // For each argument, keep track of its constant value and whether it is a + // constant or not. The bool is driven to true when found to be non-constant. + SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants; ArgumentConstants.resize(F.arg_size()); unsigned NumNonconstant = 0; - - for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) - if (!isa<Instruction>(*I)) - return false; // Used by a non-instruction, do not transform - else { - CallSite CS = CallSite::get(cast<Instruction>(*I)); - if (CS.getInstruction() == 0 || - CS.getCalledFunction() != &F) - return false; // Not a direct call site? - - // Check out all of the potentially constant arguments - CallSite::arg_iterator AI = CS.arg_begin(); - Function::arg_iterator Arg = F.arg_begin(); - for (unsigned i = 0, e = ArgumentConstants.size(); i != e; - ++i, ++AI, ++Arg) { - if (*AI == &F) return false; // Passes the function into itself - - if (!ArgumentConstants[i].second) { - if (Constant *C = dyn_cast<Constant>(*AI)) { - if (!ArgumentConstants[i].first) - ArgumentConstants[i].first = C; - else if (ArgumentConstants[i].first != C) { - // Became non-constant - ArgumentConstants[i].second = true; - ++NumNonconstant; - if (NumNonconstant == ArgumentConstants.size()) return false; - } - } else if (*AI != &*Arg) { // Ignore recursive calls with same arg - // This is not a constant argument. Mark the argument as - // non-constant. - ArgumentConstants[i].second = true; - ++NumNonconstant; - if (NumNonconstant == ArgumentConstants.size()) return false; - } - } + for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) { + // Used by a non-instruction, or not the callee of a function, do not + // transform. + if (UI.getOperandNo() != 0 || + (!isa<CallInst>(*UI) && !isa<InvokeInst>(*UI))) + return false; + + CallSite CS = CallSite::get(cast<Instruction>(*UI)); + + // Check out all of the potentially constant arguments. Note that we don't + // inspect varargs here. + CallSite::arg_iterator AI = CS.arg_begin(); + Function::arg_iterator Arg = F.arg_begin(); + for (unsigned i = 0, e = ArgumentConstants.size(); i != e; + ++i, ++AI, ++Arg) { + + // If this argument is known non-constant, ignore it. + if (ArgumentConstants[i].second) + continue; + + Constant *C = dyn_cast<Constant>(*AI); + if (C && ArgumentConstants[i].first == 0) { + ArgumentConstants[i].first = C; // First constant seen. + } else if (C && ArgumentConstants[i].first == C) { + // Still the constant value we think it is. + } else if (*AI == &*Arg) { + // Ignore recursive calls passing argument down. + } else { + // Argument became non-constant. If all arguments are non-constant now, + // give up on this function. + if (++NumNonconstant == ArgumentConstants.size()) + return false; + ArgumentConstants[i].second = true; } } + } // If we got to this point, there is a constant argument! assert(NumNonconstant != ArgumentConstants.size()); - Function::arg_iterator AI = F.arg_begin(); bool MadeChange = false; - for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) - // Do we have a constant argument!? - if (!ArgumentConstants[i].second && !AI->use_empty()) { - Value *V = ArgumentConstants[i].first; - if (V == 0) V = UndefValue::get(AI->getType()); - AI->replaceAllUsesWith(V); - ++NumArgumentsProped; - MadeChange = true; - } + 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()) + continue; + + Value *V = ArgumentConstants[i].first; + if (V == 0) V = UndefValue::get(AI->getType()); + AI->replaceAllUsesWith(V); + ++NumArgumentsProped; + MadeChange = true; + } return MadeChange; } |