From b18f03aba5d7238b1c9f0135ef0f90193d4b0f17 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Thu, 8 Oct 2015 23:18:30 +0000 Subject: [PATCH] [PlaceSafeopints] Extract out `callsGCLeafFunction`, NFC Summary: This will be used in a later change to RewriteStatepointsForGC. Reviewers: reames, swaroop.sridhar Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D13490 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249777 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/Local.h | 12 ++++++++++ lib/Transforms/Scalar/PlaceSafepoints.cpp | 29 +---------------------- lib/Transforms/Utils/Local.cpp | 17 +++++++++++++ 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index bdcbe7551cb..b7d67eaea3a 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -304,6 +304,18 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, /// the given BasicBlock. Returns the number of replacements made. unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlock *BB); + + +/// \brief Return true if the CallSite CS calls a gc leaf function. +/// +/// A leaf function is a function that does not safepoint the thread during its +/// execution. During a call or invoke to such a function, the callers stack +/// does not have to be made parseable. +/// +/// Most passes can and should ignore this information, and it is only used +/// during lowering by the GC infrastructure. +bool callsGCLeafFunction(ImmutableCallSite CS); + } // End llvm namespace #endif diff --git a/lib/Transforms/Scalar/PlaceSafepoints.cpp b/lib/Transforms/Scalar/PlaceSafepoints.cpp index 1473e3db7c7..3552dcdfa73 100644 --- a/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -192,10 +192,8 @@ static void InsertSafepointPoll(Instruction *InsertBefore, std::vector &ParsePointsNeeded /*rval*/); -static bool isGCLeafFunction(const CallSite &CS); - static bool needsStatepoint(const CallSite &CS) { - if (isGCLeafFunction(CS)) + if (callsGCLeafFunction(CS)) return false; if (CS.isCall()) { CallInst *call = cast(CS.getInstruction()); @@ -752,31 +750,6 @@ INITIALIZE_PASS_BEGIN(PlaceSafepoints, "place-safepoints", "Place Safepoints", INITIALIZE_PASS_END(PlaceSafepoints, "place-safepoints", "Place Safepoints", false, false) -static bool isGCLeafFunction(const CallSite &CS) { - Instruction *inst = CS.getInstruction(); - if (isa(inst)) { - // Most LLVM intrinsics are things which can never take a safepoint. - // As a result, we don't need to have the stack parsable at the - // callsite. This is a highly useful optimization since intrinsic - // calls are fairly prevalent, particularly in debug builds. - return true; - } - - // If this function is marked explicitly as a leaf call, we don't need to - // place a safepoint of it. In fact, for correctness we *can't* in many - // cases. Note: Indirect calls return Null for the called function, - // these obviously aren't runtime functions with attributes - // TODO: Support attributes on the call site as well. - const Function *F = CS.getCalledFunction(); - bool isLeaf = - F && - F->getFnAttribute("gc-leaf-function").getValueAsString().equals("true"); - if (isLeaf) { - return true; - } - return false; -} - static void InsertSafepointPoll(Instruction *InsertBefore, std::vector &ParsePointsNeeded /*rval*/) { diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 5be5a7df26b..de04ea506ce 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1480,3 +1480,20 @@ unsigned llvm::replaceDominatedUsesWith(Value *From, Value *To, } return Count; } + +bool llvm::callsGCLeafFunction(ImmutableCallSite CS) { + if (isa(CS.getInstruction())) + // Most LLVM intrinsics are things which can never take a safepoint. + // As a result, we don't need to have the stack parsable at the + // callsite. This is a highly useful optimization since intrinsic + // calls are fairly prevalent, particularly in debug builds. + return true; + + // Check if the function is specifically marked as a gc leaf function. + // + // TODO: we should be checking the attributes on the call site as well. + if (const Function *F = CS.getCalledFunction()) + return F->hasFnAttribute("gc-leaf-function"); + + return false; +} -- 2.34.1