xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/PlaceSafepoints.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1*06c3fb27SDimitry Andric //===- PlaceSafepoints.h - Place GC Safepoints ----------------------------===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric //
9*06c3fb27SDimitry Andric // Place garbage collection safepoints at appropriate locations in the IR. This
10*06c3fb27SDimitry Andric // does not make relocation semantics or variable liveness explicit.  That's
11*06c3fb27SDimitry Andric // done by RewriteStatepointsForGC.
12*06c3fb27SDimitry Andric //
13*06c3fb27SDimitry Andric // Terminology:
14*06c3fb27SDimitry Andric // - A call is said to be "parseable" if there is a stack map generated for the
15*06c3fb27SDimitry Andric // return PC of the call.  A runtime can determine where values listed in the
16*06c3fb27SDimitry Andric // deopt arguments and (after RewriteStatepointsForGC) gc arguments are located
17*06c3fb27SDimitry Andric // on the stack when the code is suspended inside such a call.  Every parse
18*06c3fb27SDimitry Andric // point is represented by a call wrapped in an gc.statepoint intrinsic.
19*06c3fb27SDimitry Andric // - A "poll" is an explicit check in the generated code to determine if the
20*06c3fb27SDimitry Andric // runtime needs the generated code to cooperate by calling a helper routine
21*06c3fb27SDimitry Andric // and thus suspending its execution at a known state. The call to the helper
22*06c3fb27SDimitry Andric // routine will be parseable.  The (gc & runtime specific) logic of a poll is
23*06c3fb27SDimitry Andric // assumed to be provided in a function of the name "gc.safepoint_poll".
24*06c3fb27SDimitry Andric //
25*06c3fb27SDimitry Andric // We aim to insert polls such that running code can quickly be brought to a
26*06c3fb27SDimitry Andric // well defined state for inspection by the collector.  In the current
27*06c3fb27SDimitry Andric // implementation, this is done via the insertion of poll sites at method entry
28*06c3fb27SDimitry Andric // and the backedge of most loops.  We try to avoid inserting more polls than
29*06c3fb27SDimitry Andric // are necessary to ensure a finite period between poll sites.  This is not
30*06c3fb27SDimitry Andric // because the poll itself is expensive in the generated code; it's not.  Polls
31*06c3fb27SDimitry Andric // do tend to impact the optimizer itself in negative ways; we'd like to avoid
32*06c3fb27SDimitry Andric // perturbing the optimization of the method as much as we can.
33*06c3fb27SDimitry Andric //
34*06c3fb27SDimitry Andric // We also need to make most call sites parseable.  The callee might execute a
35*06c3fb27SDimitry Andric // poll (or otherwise be inspected by the GC).  If so, the entire stack
36*06c3fb27SDimitry Andric // (including the suspended frame of the current method) must be parseable.
37*06c3fb27SDimitry Andric //
38*06c3fb27SDimitry Andric // This pass will insert:
39*06c3fb27SDimitry Andric // - Call parse points ("call safepoints") for any call which may need to
40*06c3fb27SDimitry Andric // reach a safepoint during the execution of the callee function.
41*06c3fb27SDimitry Andric // - Backedge safepoint polls and entry safepoint polls to ensure that
42*06c3fb27SDimitry Andric // executing code reaches a safepoint poll in a finite amount of time.
43*06c3fb27SDimitry Andric //
44*06c3fb27SDimitry Andric // We do not currently support return statepoints, but adding them would not
45*06c3fb27SDimitry Andric // be hard.  They are not required for correctness - entry safepoints are an
46*06c3fb27SDimitry Andric // alternative - but some GCs may prefer them.  Patches welcome.
47*06c3fb27SDimitry Andric //
48*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
49*06c3fb27SDimitry Andric 
50*06c3fb27SDimitry Andric #ifndef LLVM_TRANSFORMS_SCALAR_PLACESAFEPOINTS_H
51*06c3fb27SDimitry Andric #define LLVM_TRANSFORMS_SCALAR_PLACESAFEPOINTS_H
52*06c3fb27SDimitry Andric 
53*06c3fb27SDimitry Andric #include "llvm/IR/PassManager.h"
54*06c3fb27SDimitry Andric 
55*06c3fb27SDimitry Andric namespace llvm {
56*06c3fb27SDimitry Andric 
57*06c3fb27SDimitry Andric class TargetLibraryInfo;
58*06c3fb27SDimitry Andric 
59*06c3fb27SDimitry Andric class PlaceSafepointsPass : public PassInfoMixin<PlaceSafepointsPass> {
60*06c3fb27SDimitry Andric public:
61*06c3fb27SDimitry Andric   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
62*06c3fb27SDimitry Andric 
63*06c3fb27SDimitry Andric   bool runImpl(Function &F, const TargetLibraryInfo &TLI);
64*06c3fb27SDimitry Andric 
cleanup()65*06c3fb27SDimitry Andric   void cleanup() {}
66*06c3fb27SDimitry Andric 
67*06c3fb27SDimitry Andric private:
68*06c3fb27SDimitry Andric };
69*06c3fb27SDimitry Andric } // namespace llvm
70*06c3fb27SDimitry Andric 
71*06c3fb27SDimitry Andric #endif // LLVM_TRANSFORMS_SCALAR_PLACESAFEPOINTS_H
72