1//===- BuiltinGCs.cpp - Boilerplate for our built in GC types -------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file contains the boilerplate required to define our various built in 10// gc lowering strategies. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/CodeGen/BuiltinGCs.h" 15#include "llvm/CodeGen/GCStrategy.h" 16#include "llvm/IR/DerivedTypes.h" 17#include "llvm/Support/Casting.h" 18 19using namespace llvm; 20 21namespace { 22 23/// An example GC which attempts to be compatibile with Erlang/OTP garbage 24/// collector. 25/// 26/// The frametable emitter is in ErlangGCPrinter.cpp. 27class ErlangGC : public GCStrategy { 28public: 29 ErlangGC() { 30 NeededSafePoints = true; 31 UsesMetadata = true; 32 } 33}; 34 35/// An example GC which attempts to be compatible with Objective Caml 3.10.0 36/// 37/// The frametable emitter is in OcamlGCPrinter.cpp. 38class OcamlGC : public GCStrategy { 39public: 40 OcamlGC() { 41 NeededSafePoints = true; 42 UsesMetadata = true; 43 } 44}; 45 46/// A GC strategy for uncooperative targets. This implements lowering for the 47/// llvm.gc* intrinsics for targets that do not natively support them (which 48/// includes the C backend). Note that the code generated is not quite as 49/// efficient as algorithms which generate stack maps to identify roots. 50/// 51/// In order to support this particular transformation, all stack roots are 52/// coallocated in the stack. This allows a fully target-independent stack map 53/// while introducing only minor runtime overhead. 54class ShadowStackGC : public GCStrategy { 55public: 56 ShadowStackGC() {} 57}; 58 59/// A GCStrategy which serves as an example for the usage of a statepoint based 60/// lowering strategy. This GCStrategy is intended to suitable as a default 61/// implementation usable with any collector which can consume the standard 62/// stackmap format generated by statepoints, uses the default addrespace to 63/// distinguish between gc managed and non-gc managed pointers, and has 64/// reasonable relocation semantics. 65class StatepointGC : public GCStrategy { 66public: 67 StatepointGC() { 68 UseStatepoints = true; 69 // These options are all gc.root specific, we specify them so that the 70 // gc.root lowering code doesn't run. 71 NeededSafePoints = false; 72 UsesMetadata = false; 73 } 74 75 Optional<bool> isGCManagedPointer(const Type *Ty) const override { 76 // Method is only valid on pointer typed values. 77 const PointerType *PT = cast<PointerType>(Ty); 78 // For the sake of this example GC, we arbitrarily pick addrspace(1) as our 79 // GC managed heap. We know that a pointer into this heap needs to be 80 // updated and that no other pointer does. Note that addrspace(1) is used 81 // only as an example, it has no special meaning, and is not reserved for 82 // GC usage. 83 return (1 == PT->getAddressSpace()); 84 } 85}; 86 87/// A GCStrategy for the CoreCLR Runtime. The strategy is similar to 88/// Statepoint-example GC, but differs from it in certain aspects, such as: 89/// 1) Base-pointers need not be explicitly tracked and reported for 90/// interior pointers 91/// 2) Uses a different format for encoding stack-maps 92/// 3) Location of Safe-point polls: polls are only needed before loop-back 93/// edges and before tail-calls (not needed at function-entry) 94/// 95/// The above differences in behavior are to be implemented in upcoming 96/// checkins. 97class CoreCLRGC : public GCStrategy { 98public: 99 CoreCLRGC() { 100 UseStatepoints = true; 101 // These options are all gc.root specific, we specify them so that the 102 // gc.root lowering code doesn't run. 103 NeededSafePoints = false; 104 UsesMetadata = false; 105 } 106 107 Optional<bool> isGCManagedPointer(const Type *Ty) const override { 108 // Method is only valid on pointer typed values. 109 const PointerType *PT = cast<PointerType>(Ty); 110 // We pick addrspace(1) as our GC managed heap. 111 return (1 == PT->getAddressSpace()); 112 } 113}; 114 115} // end anonymous namespace 116 117// Register all the above so that they can be found at runtime. Note that 118// these static initializers are important since the registration list is 119// constructed from their storage. 120static GCRegistry::Add<ErlangGC> A("erlang", 121 "erlang-compatible garbage collector"); 122static GCRegistry::Add<OcamlGC> B("ocaml", "ocaml 3.10-compatible GC"); 123static GCRegistry::Add<ShadowStackGC> 124 C("shadow-stack", "Very portable GC for uncooperative code generators"); 125static GCRegistry::Add<StatepointGC> D("statepoint-example", 126 "an example strategy for statepoint"); 127static GCRegistry::Add<CoreCLRGC> E("coreclr", "CoreCLR-compatible GC"); 128 129// Provide hook to ensure the containing library is fully loaded. 130void llvm::linkAllBuiltinGCs() {} 131