69 #define DEBUG_TYPE "safepoint-placement"
71 STATISTIC(NumEntrySafepoints,
"Number of entry safepoints inserted");
72 STATISTIC(NumBackedgeSafepoints,
"Number of backedge safepoints inserted");
75 "Number of loops without safepoints due to calls in loop");
77 "Number of loops without safepoints finite execution");
102 struct PlaceBackedgeSafepointsImpl :
public FunctionPass {
107 std::vector<TerminatorInst *> PollLocations;
111 bool CallSafepointsEnabled;
117 PlaceBackedgeSafepointsImpl(
bool CallSafepoints =
false)
122 bool runOnLoop(
Loop *);
123 void runOnLoopAndSubLoops(
Loop *
L) {
126 runOnLoopAndSubLoops(
I);
130 bool runOnFunction(
Function &
F)
override {
131 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
132 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
133 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
134 for (
Loop *
I : *LI) {
135 runOnLoopAndSubLoops(
I);
162 bool runOnFunction(
Function &
F)
override;
177 std::vector<CallSite> &ParsePointsNeeded );
208 assert(DT.
dominates(Header, Pred) &&
"loop latch not dominated by header?");
224 if (Current == Header)
226 Current = DT.
getNode(Current)->getIDom()->getBlock();
262 std::vector<CallInst *> &Calls,
264 std::vector<BasicBlock *> &Worklist) {
267 BBI != BBE0 && BBI != BBE1; BBI++) {
268 if (
CallInst *CI = dyn_cast<CallInst>(&*BBI))
272 assert(!isa<InvokeInst>(&*BBI) &&
273 "support for invokes in poll code needed");
277 if (BBI->isTerminator()) {
280 if (Seen.
insert(Succ).second) {
281 Worklist.push_back(Succ);
289 std::vector<CallInst *> &Calls,
292 std::vector<BasicBlock *> Worklist;
294 scanOneBB(Start, End, Calls, Seen, Worklist);
295 while (!Worklist.empty()) {
302 bool PlaceBackedgeSafepointsImpl::runOnLoop(
Loop *L) {
319 DEBUG(
dbgs() <<
"skipping safepoint placement in finite loop\n");
323 if (CallSafepointsEnabled &&
328 DEBUG(
dbgs() <<
"skipping safepoint placement due to unconditional call\n");
344 DEBUG(
dbgs() <<
"[LSP] terminator instruction: " << *Term);
346 PollLocations.push_back(Term);
357 switch (II->getIntrinsicID()) {
358 case Intrinsic::experimental_gc_statepoint:
359 case Intrinsic::experimental_patchpoint_void:
360 case Intrinsic::experimental_patchpoint_i64:
391 if (!
I->isTerminator())
394 BasicBlock *nextBB =
I->getParent()->getUniqueSuccessor();
399 assert(HasNextInstruction(
I) &&
400 "first check if there is a next instruction!");
402 if (
I->isTerminator())
403 return &
I->getParent()->getUniqueSuccessor()->front();
404 return &*++
I->getIterator();
409 Cursor = NextInstruction(Cursor)) {
426 "either we stopped because of a call, or because of terminator");
443 const auto &FunctionGCName = F.
getGC();
444 const StringRef StatepointExampleName(
"statepoint-example");
446 return (StatepointExampleName == FunctionGCName) ||
447 (CoreCLRName == FunctionGCName);
458 bool PlaceSafepoints::runOnFunction(
Function &
F) {
475 bool Modified =
false;
491 std::vector<CallSite> ParsePointNeeded;
500 auto *PBS =
new PlaceBackedgeSafepointsImpl(CanAssumeCallSafepoints);
508 auto &PollLocations = PBS->PollLocations;
515 std::sort(PollLocations.begin(), PollLocations.end(), OrderByBBName);
520 PollLocations.erase(std::unique(PollLocations.begin(),
521 PollLocations.end()),
522 PollLocations.end());
548 assert(!Headers.
empty() &&
"poll location is not a loop latch?");
557 NumBackedgeSafepoints++;
562 NumBackedgeSafepoints++;
571 NumEntrySafepoints++;
580 std::vector<CallSite> RuntimeCalls;
582 ParsePointNeeded.insert(ParsePointNeeded.end(), RuntimeCalls.begin(),
593 return new PlaceSafepoints();
597 "place-backedge-safepoints-impl",
598 "Place Backedge Safepoints",
false,
false)
613 std::vector<
CallSite> &ParsePointsNeeded ) {
615 Module *M = InsertBefore->getModule();
616 assert(M &&
"must be part of a module");
623 assert(F &&
"gc.safepoint_poll function is missing");
626 "gc.safepoint_poll declared with wrong type");
627 assert(!F->
empty() &&
"gc.safepoint_poll must be a non-empty function");
632 bool IsBegin =
false;
633 if (Before == OrigBB->
begin())
639 assert(After != OrigBB->
end() &&
"must have successor");
644 assert(InlineStatus &&
"inline must succeed");
648 assert(IFI.StaticAllocas.empty() &&
"can't have allocs");
650 std::vector<CallInst *> Calls;
660 "malformed poll function");
663 assert(!Calls.empty() &&
"slow path not found for safepoint poll");
669 assert(ParsePointsNeeded.empty());
670 for (
auto *CI : Calls) {
677 ParsePointsNeeded.push_back(
CallSite(CI));
679 assert(ParsePointsNeeded.size() <= Calls.size());
static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE, BasicBlock *Pred)
Returns true if this loop is known to terminate in a finite number of iterations. ...
void push_back(const T &Elt)
BasicBlock * getUniquePredecessor()
Return the predecessor of this block if it has a unique predecessor block.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool shouldRewriteFunction(Function &F)
Returns true if this function should be rewritten to include safepoint polls and parseable call sites...
const Instruction & back() const
const SCEV * getExitCount(Loop *L, BasicBlock *ExitingBlock)
Get the expression for the number of loop iterations for which this loop is guaranteed not to exit vi...
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
Return all loop latch blocks of this loop.
A Module instance is used to store all the information related to an LLVM module. ...
Implements a dense probed hash-table based set.
The main scalar evolution driver.
Type * getValueType() const
This class represents a function call, abstracting a target machine's calling convention.
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop...
void initializePlaceSafepointsPass(PassRegistry &)
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
InlineFunctionInfo - This class captures the data input to the InlineFunction call, and records the auxiliary results produced by it.
BlockT * getHeader() const
STATISTIC(NumEntrySafepoints,"Number of entry safepoints inserted")
bool isGCRelocate(ImmutableCallSite CS)
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true)
InlineFunction - This function inlines the called function into the basic block of the caller...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
bool isCall() const
isCall - true if a CallInst is enclosed.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
static cl::opt< bool > NoBackedge("spp-no-backedge", cl::Hidden, cl::init(false))
place backedge safepoints impl
static bool doesNotRequireEntrySafepointBefore(const CallSite &CS)
Returns true if an entry safepoint is not required before this callsite in the caller function...
static bool enableCallSafepoints(Function &F)
static bool containsUnconditionalCallSafepoint(Loop *L, BasicBlock *Header, BasicBlock *Pred, DominatorTree &DT)
Returns true if this loop is known to contain a call safepoint which must unconditionally execute on ...
bool insert(const value_type &X)
Insert a new element into the SetVector.
static bool needsStatepoint(const CallSite &CS)
bool empty() const
Determine if the SetVector is empty or not.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
void initializePlaceBackedgeSafepointsImplPass(PassRegistry &)
static const char *const GCSafepointPollName
static cl::opt< bool > SplitBackedge("spp-split-backedge", cl::Hidden, cl::init(false))
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
static Instruction * findLocationForEntrySafepoint(Function &F, DominatorTree &DT)
const SCEV * getCouldNotCompute()
initializer< Ty > init(const Ty &Val)
static bool enableEntrySafepoints(Function &F)
Subclasses of this class are all able to terminate a basic block.
FunctionPass * createPlaceSafepointsPass()
LLVM Basic Block Representation.
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
std::pair< iterator, bool > insert(const ValueT &V)
static cl::opt< bool > NoCall("spp-no-call", cl::Hidden, cl::init(false))
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
static cl::opt< bool > AllBackedges("spp-all-backedges", cl::Hidden, cl::init(false))
const SCEV * getMaxBackedgeTakenCount(const Loop *L)
Similar to getBackedgeTakenCount, except return the least SCEV value that is known never to be less t...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
static void scanOneBB(Instruction *Start, Instruction *End, std::vector< CallInst * > &Calls, DenseSet< BasicBlock * > &Seen, std::vector< BasicBlock * > &Worklist)
bool isGCResult(ImmutableCallSite CS)
FunctionPass class - This class is used to implement most global optimizations.
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', returning true if uncertain.
bool callsGCLeafFunction(ImmutableCallSite CS)
Return true if the CallSite CS calls a gc leaf function.
place backedge safepoints Place Backedge Safepoints
static void InsertSafepointPoll(Instruction *InsertBefore, std::vector< CallSite > &ParsePointsNeeded)
FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
static bool isGCSafepointPoll(Function &F)
bool isTerminator() const
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Iterator for intrusive lists based on ilist_node.
InstrTy * getInstruction() const
bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI=nullptr)
Remove all blocks that can not be reached from the function's entry.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > Bundles=None, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const BasicBlock & getEntryBlock() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void scanInlinedCode(Instruction *Start, Instruction *End, std::vector< CallInst * > &Calls, DenseSet< BasicBlock * > &Seen)
void setPreservesAll()
Set by analyses that do not transform their input at all.
static cl::opt< bool > NoEntry("spp-no-entry", cl::Hidden, cl::init(false))
INITIALIZE_PASS_BEGIN(PlaceBackedgeSafepointsImpl,"place-backedge-safepoints-impl","Place Backedge Safepoints", false, false) INITIALIZE_PASS_END(PlaceBackedgeSafepointsImpl
bool isInlineAsm() const
Check if this call is an inline asm statement.
static cl::opt< int > CountedLoopTripWidth("spp-counted-loop-trip-width", cl::Hidden, cl::init(32))
How narrow does the trip count of a loop have to be to have to be considered "counted"? Counted loops do not get safepoints at backedges.
This class represents an analyzed expression in the program.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Represents a single loop in the control flow graph.
const std::string & getGC() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
place backedge safepoints Place Backedge false place safepoints
bool isStatepoint(ImmutableCallSite CS)
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
static bool enableBackedgeSafepoints(Function &F)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
succ_range successors(BasicBlock *BB)
A vector that has set insertion semantics.
place backedge safepoints Place Backedge false
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the edge connecting specified block.
The legacy pass manager's analysis pass to compute loop information.
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
StringRef - Represent a constant reference to a string, i.e.
Legacy analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
const BasicBlock * getParent() const
InstListType::iterator iterator
Instruction iterators...
A wrapper class for inspecting calls to intrinsic functions.
LLVMContext & getContext() const
Get the global data context.