1321369Sdim//===- llvm/CodeGen/GCStrategy.h - Garbage collection -----------*- C++ -*-===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// GCStrategy coordinates code generation algorithms and implements some itself 10193323Sed// in order to generate code compatible with a target code generator as 11193323Sed// specified in a function's 'gc' attribute. Algorithms are enabled by setting 12193323Sed// flags in a subclass's constructor, and some virtual methods can be 13193323Sed// overridden. 14280031Sdim// 15280031Sdim// GCStrategy is relevant for implementations using either gc.root or 16280031Sdim// gc.statepoint based lowering strategies, but is currently focused mostly on 17280031Sdim// options for gc.root. This will change over time. 18288943Sdim// 19280031Sdim// When requested by a subclass of GCStrategy, the gc.root implementation will 20280031Sdim// populate GCModuleInfo and GCFunctionInfo with that about each Function in 21280031Sdim// the Module that opts in to garbage collection. Specifically: 22288943Sdim// 23193323Sed// - Safe points 24193323Sed// Garbage collection is generally only possible at certain points in code. 25193323Sed// GCStrategy can request that the collector insert such points: 26193323Sed// 27193323Sed// - At and after any call to a subroutine 28193323Sed// - Before returning from the current function 29193323Sed// - Before backwards branches (loops) 30288943Sdim// 31193323Sed// - Roots 32193323Sed// When a reference to a GC-allocated object exists on the stack, it must be 33193323Sed// stored in an alloca registered with llvm.gcoot. 34193323Sed// 35193323Sed// This information can used to emit the metadata tables which are required by 36193323Sed// the target garbage collector runtime. 37193323Sed// 38280031Sdim// When used with gc.statepoint, information about safepoint and roots can be 39280031Sdim// found in the binary StackMap section after code generation. Safepoint 40280031Sdim// placement is currently the responsibility of the frontend, though late 41280031Sdim// insertion support is planned. gc.statepoint does not currently support 42280031Sdim// custom stack map formats; such can be generated by parsing the standard 43280031Sdim// stack map section if desired. 44288943Sdim// 45280031Sdim// The read and write barrier support can be used with either implementation. 46280031Sdim// 47193323Sed//===----------------------------------------------------------------------===// 48193323Sed 49321369Sdim#ifndef LLVM_CODEGEN_GCSTRATEGY_H 50321369Sdim#define LLVM_CODEGEN_GCSTRATEGY_H 51193323Sed 52321369Sdim#include "llvm/ADT/None.h" 53280031Sdim#include "llvm/ADT/Optional.h" 54193323Sed#include "llvm/Support/Registry.h" 55193323Sed#include <string> 56193323Sed 57193323Sednamespace llvm { 58321369Sdim 59321369Sdimclass Type; 60321369Sdim 61288943Sdim/// GCStrategy describes a garbage collector algorithm's code generation 62288943Sdim/// requirements, and provides overridable hooks for those needs which cannot 63288943Sdim/// be abstractly described. GCStrategy objects must be looked up through 64288943Sdim/// the Function. The objects themselves are owned by the Context and must 65288943Sdim/// be immutable. 66288943Sdimclass GCStrategy { 67288943Sdimprivate: 68288943Sdim friend class GCModuleInfo; 69193323Sed 70321369Sdim std::string Name; 71321369Sdim 72288943Sdimprotected: 73321369Sdim bool UseStatepoints = false; /// Uses gc.statepoints as opposed to gc.roots, 74321369Sdim /// if set, none of the other options can be 75321369Sdim /// anything but their default values. 76193323Sed 77344779Sdim bool NeededSafePoints = false; ///< if set, calls are inferred to be safepoints 78321369Sdim bool UsesMetadata = false; ///< If set, backend must emit metadata tables. 79280031Sdim 80288943Sdimpublic: 81288943Sdim GCStrategy(); 82321369Sdim virtual ~GCStrategy() = default; 83280031Sdim 84288943Sdim /// Return the name of the GC strategy. This is the value of the collector 85288943Sdim /// name string specified on functions which use this strategy. 86288943Sdim const std::string &getName() const { return Name; } 87280031Sdim 88288943Sdim /// Returns true if this strategy is expecting the use of gc.statepoints, 89288943Sdim /// and false otherwise. 90288943Sdim bool useStatepoints() const { return UseStatepoints; } 91280031Sdim 92288943Sdim /** @name Statepoint Specific Properties */ 93288943Sdim ///@{ 94280031Sdim 95296417Sdim /// If the type specified can be reliably distinguished, returns true for 96288943Sdim /// pointers to GC managed locations and false for pointers to non-GC 97288943Sdim /// managed locations. Note a GCStrategy can always return 'None' (i.e. an 98288943Sdim /// empty optional indicating it can't reliably distinguish. 99296417Sdim virtual Optional<bool> isGCManagedPointer(const Type *Ty) const { 100288943Sdim return None; 101288943Sdim } 102288943Sdim ///@} 103288943Sdim 104288943Sdim /** @name GCRoot Specific Properties 105288943Sdim * These properties and overrides only apply to collector strategies using 106288943Sdim * GCRoot. 107288943Sdim */ 108288943Sdim ///@{ 109288943Sdim 110344779Sdim /// True if safe points need to be inferred on call sites 111344779Sdim bool needsSafePoints() const { return NeededSafePoints; } 112288943Sdim 113288943Sdim /// If set, appropriate metadata tables must be emitted by the back-end 114288943Sdim /// (assembler, JIT, or otherwise). For statepoint, this method is 115288943Sdim /// currently unsupported. The stackmap information can be found in the 116288943Sdim /// StackMap section as described in the documentation. 117288943Sdim bool usesMetadata() const { return UsesMetadata; } 118288943Sdim 119288943Sdim ///@} 120288943Sdim}; 121288943Sdim 122288943Sdim/// Subclasses of GCStrategy are made available for use during compilation by 123288943Sdim/// adding them to the global GCRegistry. This can done either within the 124288943Sdim/// LLVM source tree or via a loadable plugin. An example registeration 125288943Sdim/// would be: 126288943Sdim/// static GCRegistry::Add<CustomGC> X("custom-name", 127288943Sdim/// "my custom supper fancy gc strategy"); 128288943Sdim/// 129288943Sdim/// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also 130288943Sdim/// register your GCMetadataPrinter subclass with the 131288943Sdim/// GCMetadataPrinterRegistery as well. 132321369Sdimusing GCRegistry = Registry<GCStrategy>; 133193323Sed 134321369Sdim} // end namespace llvm 135321369Sdim 136321369Sdim#endif // LLVM_CODEGEN_GCSTRATEGY_H 137