summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp
diff options
context:
space:
mode:
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>2019-01-19 05:19:12 +0000
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>2019-01-19 05:19:12 +0000
commit36872b5db9f5a2a808ddd71df24017b7a9c0064c (patch)
tree0bccdb2c2ecb71e63b82dabd9f4f3bd1d939beae /llvm/lib/Transforms/IPO/IPConstantPropagation.cpp
parent18251842c6781ddcd74d785da1235593ad7613dc (diff)
downloadbcm5719-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.cpp35
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,
OpenPOWER on IntegriCloud