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