diff options
author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2019-01-19 05:19:12 +0000 |
---|---|---|
committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2019-01-19 05:19:12 +0000 |
commit | 36872b5db9f5a2a808ddd71df24017b7a9c0064c (patch) | |
tree | 0bccdb2c2ecb71e63b82dabd9f4f3bd1d939beae /llvm/lib/Transforms/IPO/IPConstantPropagation.cpp | |
parent | 18251842c6781ddcd74d785da1235593ad7613dc (diff) | |
download | bcm5719-llvm-36872b5db9f5a2a808ddd71df24017b7a9c0064c.tar.gz bcm5719-llvm-36872b5db9f5a2a808ddd71df24017b7a9c0064c.zip |
Enable IPConstantPropagation to work with abstract call sites
This modification of the currently unused inter-procedural constant
propagation pass (IPConstantPropagation) shows how abstract call sites
enable optimization of callback calls alongside direct and indirect
calls. Through minimal changes, mostly dealing with the partial mapping
of callbacks, inter-procedural constant propagation was enabled for
callbacks, e.g., OpenMP runtime calls or pthreads_create.
Differential Revision: https://reviews.llvm.org/D56447
llvm-svn: 351628
Diffstat (limited to 'llvm/lib/Transforms/IPO/IPConstantPropagation.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/IPConstantPropagation.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp index 7d55ebecbf9..fecbc809f8b 100644 --- a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -62,32 +62,43 @@ static bool PropagateConstantsIntoArguments(Function &F) { // Ignore blockaddress uses. if (isa<BlockAddress>(UR)) continue; - // Used by a non-instruction, or not the callee of a function, do not - // transform. - if (!isa<CallInst>(UR) && !isa<InvokeInst>(UR)) - return false; - - CallSite CS(cast<Instruction>(UR)); - if (!CS.isCallee(&U)) + // If no abstract call site was created we did not understand the use, bail. + AbstractCallSite ACS(&U); + if (!ACS) return false; // 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) { + for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++Arg) { // If this argument is known non-constant, ignore it. if (ArgumentConstants[i].second) continue; - Constant *C = dyn_cast<Constant>(*AI); + Value *V = ACS.getCallArgOperand(i); + Constant *C = dyn_cast_or_null<Constant>(V); + + // We can only propagate thread independent values through callbacks. + // This is different to direct/indirect call sites because for them we + // know the thread executing the caller and callee is the same. For + // callbacks this is not guaranteed, thus a thread dependent value could + // be different for the caller and callee, making it invalid to propagate. + if (C && ACS.isCallbackCall() && C->isThreadDependent()) { + // 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; + continue; + } + if (C && ArgumentConstants[i].first == nullptr) { 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) { + } else if (V == &*Arg) { // Ignore recursive calls passing argument down. } else { // Argument became non-constant. If all arguments are non-constant now, |