summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/IPConstantPropagation.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-23 06:16:27 +0000
committerChris Lattner <sabre@nondot.org>2008-04-23 06:16:27 +0000
commit4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b (patch)
tree6e953523c4f36eb201aefce94171d8907829386e /lib/Transforms/IPO/IPConstantPropagation.cpp
parente9625c6c88477382d7b4db6c16108ab2db2b1326 (diff)
downloadllvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.tar.gz
llvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.tar.bz2
llvm-4af6ad37898bcda9e29fe1c7abbb1b9899af3b5b.tar.xz
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/IPConstantPropagation.cpp')
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp95
1 files changed, 49 insertions, 46 deletions
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index ad812fd2ca..c51c023c68 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;
}