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