summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-06-18 19:28:26 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-06-18 19:28:26 +0000
commitc65d43e64926c9f868213f453bb4cdc3d4ab7879 (patch)
tree2620519c537d573b07605b61b396df72d46e3752 /llvm/lib
parent5c38440b2b6866bf622ed5e81840587873455f96 (diff)
downloadbcm5719-llvm-c65d43e64926c9f868213f453bb4cdc3d4ab7879.tar.gz
bcm5719-llvm-c65d43e64926c9f868213f453bb4cdc3d4ab7879.zip
[CallGraph] Teach the CallGraph about non-leaf intrinsics.
Summary: Currently intrinsics don't affect the creation of the call graph. This is not accurate with respect to statepoint and patchpoint intrinsics -- these do call (or invoke) LLVM level functions. This change fixes this inconsistency by adding a call to the external node for call sites that call these non-leaf intrinsics. This coupled with the fact that these intrinsics also escape the function pointer they call gives us a conservatively correct call graph. Reviewers: reames, chandlerc, atrick, pgavlin Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10526 llvm-svn: 240039
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/IPA/CallGraph.cpp4
-rw-r--r--llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp6
-rw-r--r--llvm/lib/IR/Function.cpp12
3 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/IPA/CallGraph.cpp b/llvm/lib/Analysis/IPA/CallGraph.cpp
index ee276393964..77c36033b47 100644
--- a/llvm/lib/Analysis/IPA/CallGraph.cpp
+++ b/llvm/lib/Analysis/IPA/CallGraph.cpp
@@ -79,8 +79,10 @@ void CallGraph::addToCallGraph(Function *F) {
CallSite CS(cast<Value>(II));
if (CS) {
const Function *Callee = CS.getCalledFunction();
- if (!Callee)
+ if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
// Indirect calls of intrinsics are not allowed so no need to check.
+ // We can be more precise here by using TargetArg returned by
+ // Intrinsic::isLeaf.
Node->addCalledFunction(CS, CallsExternalNode);
else if (!Callee->isIntrinsic())
Node->addCalledFunction(CS, getOrInsertFunction(Callee));
diff --git a/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp b/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp
index 65ba1c7c6c4..6b3e0634626 100644
--- a/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp
@@ -217,8 +217,10 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC,
// another value. This can happen when constant folding happens
// of well known functions etc.
!CallSite(I->first) ||
- (CallSite(I->first).getCalledFunction() &&
- CallSite(I->first).getCalledFunction()->isIntrinsic())) {
+ (CallSite(I->first).getCalledFunction() &&
+ CallSite(I->first).getCalledFunction()->isIntrinsic() &&
+ Intrinsic::isLeaf(
+ CallSite(I->first).getCalledFunction()->getIntrinsicID()))) {
assert(!CheckingMode &&
"CallGraphSCCPass did not update the CallGraph correctly!");
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index bc57dee0af0..b50ad1262c6 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -846,6 +846,18 @@ bool Intrinsic::isOverloaded(ID id) {
#undef GET_INTRINSIC_OVERLOAD_TABLE
}
+bool Intrinsic::isLeaf(ID id) {
+ switch (id) {
+ default:
+ return true;
+
+ case Intrinsic::experimental_gc_statepoint:
+ case Intrinsic::experimental_patchpoint_void:
+ case Intrinsic::experimental_patchpoint_i64:
+ return false;
+ }
+}
+
/// This defines the "Intrinsic::getAttributes(ID id)" method.
#define GET_INTRINSIC_ATTRIBUTES
#include "llvm/IR/Intrinsics.gen"
OpenPOWER on IntegriCloud