Path: blob/main/contrib/llvm-project/llvm/lib/IR/BuiltinGCs.cpp
35233 views
//===- BuiltinGCs.cpp - Boilerplate for our built in GC types -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the boilerplate required to define our various built in9// gc lowering strategies.10//11//===----------------------------------------------------------------------===//1213#include "llvm/IR/BuiltinGCs.h"14#include "llvm/IR/GCStrategy.h"15#include "llvm/IR/DerivedTypes.h"16#include "llvm/Support/Casting.h"1718using namespace llvm;1920namespace {2122/// An example GC which attempts to be compatible with Erlang/OTP garbage23/// collector.24///25/// The frametable emitter is in ErlangGCPrinter.cpp.26class ErlangGC : public GCStrategy {27public:28ErlangGC() {29NeededSafePoints = true;30UsesMetadata = true;31}32};3334/// An example GC which attempts to be compatible with Objective Caml 3.10.035///36/// The frametable emitter is in OcamlGCPrinter.cpp.37class OcamlGC : public GCStrategy {38public:39OcamlGC() {40NeededSafePoints = true;41UsesMetadata = true;42}43};4445/// A GC strategy for uncooperative targets. This implements lowering for the46/// llvm.gc* intrinsics for targets that do not natively support them (which47/// includes the C backend). Note that the code generated is not quite as48/// efficient as algorithms which generate stack maps to identify roots.49///50/// In order to support this particular transformation, all stack roots are51/// coallocated in the stack. This allows a fully target-independent stack map52/// while introducing only minor runtime overhead.53class ShadowStackGC : public GCStrategy {54public:55ShadowStackGC() = default;56};5758/// A GCStrategy which serves as an example for the usage of a statepoint based59/// lowering strategy. This GCStrategy is intended to suitable as a default60/// implementation usable with any collector which can consume the standard61/// stackmap format generated by statepoints, uses the default addrespace to62/// distinguish between gc managed and non-gc managed pointers, and has63/// reasonable relocation semantics.64class StatepointGC : public GCStrategy {65public:66StatepointGC() {67UseStatepoints = true;68UseRS4GC = true;69// These options are all gc.root specific, we specify them so that the70// gc.root lowering code doesn't run.71NeededSafePoints = false;72UsesMetadata = false;73}7475std::optional<bool> isGCManagedPointer(const Type *Ty) const override {76// Method is only valid on pointer typed values.77const PointerType *PT = cast<PointerType>(Ty);78// For the sake of this example GC, we arbitrarily pick addrspace(1) as our79// GC managed heap. We know that a pointer into this heap needs to be80// updated and that no other pointer does. Note that addrspace(1) is used81// only as an example, it has no special meaning, and is not reserved for82// GC usage.83return (1 == PT->getAddressSpace());84}85};8687/// A GCStrategy for the CoreCLR Runtime. The strategy is similar to88/// Statepoint-example GC, but differs from it in certain aspects, such as:89/// 1) Base-pointers need not be explicitly tracked and reported for90/// interior pointers91/// 2) Uses a different format for encoding stack-maps92/// 3) Location of Safe-point polls: polls are only needed before loop-back93/// edges and before tail-calls (not needed at function-entry)94///95/// The above differences in behavior are to be implemented in upcoming96/// checkins.97class CoreCLRGC : public GCStrategy {98public:99CoreCLRGC() {100UseStatepoints = true;101UseRS4GC = true;102// These options are all gc.root specific, we specify them so that the103// gc.root lowering code doesn't run.104NeededSafePoints = false;105UsesMetadata = false;106}107108std::optional<bool> isGCManagedPointer(const Type *Ty) const override {109// Method is only valid on pointer typed values.110const PointerType *PT = cast<PointerType>(Ty);111// We pick addrspace(1) as our GC managed heap.112return (1 == PT->getAddressSpace());113}114};115116} // end anonymous namespace117118// Register all the above so that they can be found at runtime. Note that119// these static initializers are important since the registration list is120// constructed from their storage.121static GCRegistry::Add<ErlangGC> A("erlang",122"erlang-compatible garbage collector");123static GCRegistry::Add<OcamlGC> B("ocaml", "ocaml 3.10-compatible GC");124static GCRegistry::Add<ShadowStackGC>125C("shadow-stack", "Very portable GC for uncooperative code generators");126static GCRegistry::Add<StatepointGC> D("statepoint-example",127"an example strategy for statepoint");128static GCRegistry::Add<CoreCLRGC> E("coreclr", "CoreCLR-compatible GC");129130// Provide hook to ensure the containing library is fully loaded.131void llvm::linkAllBuiltinGCs() {}132133134