mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-11 18:42:01 +00:00
[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
This commit is contained in:
parent
33e2662596
commit
b18f03aba5
@ -304,6 +304,18 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
|
|||||||
/// the given BasicBlock. Returns the number of replacements made.
|
/// the given BasicBlock. Returns the number of replacements made.
|
||||||
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
|
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
|
||||||
const BasicBlock *BB);
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -192,10 +192,8 @@ static void
|
|||||||
InsertSafepointPoll(Instruction *InsertBefore,
|
InsertSafepointPoll(Instruction *InsertBefore,
|
||||||
std::vector<CallSite> &ParsePointsNeeded /*rval*/);
|
std::vector<CallSite> &ParsePointsNeeded /*rval*/);
|
||||||
|
|
||||||
static bool isGCLeafFunction(const CallSite &CS);
|
|
||||||
|
|
||||||
static bool needsStatepoint(const CallSite &CS) {
|
static bool needsStatepoint(const CallSite &CS) {
|
||||||
if (isGCLeafFunction(CS))
|
if (callsGCLeafFunction(CS))
|
||||||
return false;
|
return false;
|
||||||
if (CS.isCall()) {
|
if (CS.isCall()) {
|
||||||
CallInst *call = cast<CallInst>(CS.getInstruction());
|
CallInst *call = cast<CallInst>(CS.getInstruction());
|
||||||
@ -752,31 +750,6 @@ INITIALIZE_PASS_BEGIN(PlaceSafepoints, "place-safepoints", "Place Safepoints",
|
|||||||
INITIALIZE_PASS_END(PlaceSafepoints, "place-safepoints", "Place Safepoints",
|
INITIALIZE_PASS_END(PlaceSafepoints, "place-safepoints", "Place Safepoints",
|
||||||
false, false)
|
false, false)
|
||||||
|
|
||||||
static bool isGCLeafFunction(const CallSite &CS) {
|
|
||||||
Instruction *inst = CS.getInstruction();
|
|
||||||
if (isa<IntrinsicInst>(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
|
static void
|
||||||
InsertSafepointPoll(Instruction *InsertBefore,
|
InsertSafepointPoll(Instruction *InsertBefore,
|
||||||
std::vector<CallSite> &ParsePointsNeeded /*rval*/) {
|
std::vector<CallSite> &ParsePointsNeeded /*rval*/) {
|
||||||
|
@ -1480,3 +1480,20 @@ unsigned llvm::replaceDominatedUsesWith(Value *From, Value *To,
|
|||||||
}
|
}
|
||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool llvm::callsGCLeafFunction(ImmutableCallSite CS) {
|
||||||
|
if (isa<IntrinsicInst>(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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user