brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 163b038 Raw
133 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the boilerplate required to define our various built in10// gc lowering strategies.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/IR/BuiltinGCs.h"15#include "llvm/IR/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 compatible with Erlang/OTP garbage24/// 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.036///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 the47/// llvm.gc* intrinsics for targets that do not natively support them (which48/// includes the C backend). Note that the code generated is not quite as49/// efficient as algorithms which generate stack maps to identify roots.50///51/// In order to support this particular transformation, all stack roots are52/// coallocated in the stack. This allows a fully target-independent stack map53/// while introducing only minor runtime overhead.54class ShadowStackGC : public GCStrategy {55public:56  ShadowStackGC() = default;57};58 59/// A GCStrategy which serves as an example for the usage of a statepoint based60/// lowering strategy.  This GCStrategy is intended to suitable as a default61/// implementation usable with any collector which can consume the standard62/// stackmap format generated by statepoints, uses the default addrespace to63/// distinguish between gc managed and non-gc managed pointers, and has64/// reasonable relocation semantics.65class StatepointGC : public GCStrategy {66public:67  StatepointGC() {68    UseStatepoints = true;69    UseRS4GC = true;70    // These options are all gc.root specific, we specify them so that the71    // gc.root lowering code doesn't run.72    NeededSafePoints = false;73    UsesMetadata = false;74  }75 76  std::optional<bool> isGCManagedPointer(const Type *Ty) const override {77    // Method is only valid on pointer typed values.78    const PointerType *PT = cast<PointerType>(Ty);79    // For the sake of this example GC, we arbitrarily pick addrspace(1) as our80    // GC managed heap.  We know that a pointer into this heap needs to be81    // updated and that no other pointer does.  Note that addrspace(1) is used82    // only as an example, it has no special meaning, and is not reserved for83    // GC usage.84    return (1 == PT->getAddressSpace());85  }86};87 88/// A GCStrategy for the CoreCLR Runtime. The strategy is similar to89/// Statepoint-example GC, but differs from it in certain aspects, such as:90/// 1) Base-pointers need not be explicitly tracked and reported for91///    interior pointers92/// 2) Uses a different format for encoding stack-maps93/// 3) Location of Safe-point polls: polls are only needed before loop-back94///    edges and before tail-calls (not needed at function-entry)95///96/// The above differences in behavior are to be implemented in upcoming97/// checkins.98class CoreCLRGC : public GCStrategy {99public:100  CoreCLRGC() {101    UseStatepoints = true;102    UseRS4GC = true;103    // These options are all gc.root specific, we specify them so that the104    // gc.root lowering code doesn't run.105    NeededSafePoints = false;106    UsesMetadata = false;107  }108 109  std::optional<bool> isGCManagedPointer(const Type *Ty) const override {110    // Method is only valid on pointer typed values.111    const PointerType *PT = cast<PointerType>(Ty);112    // We pick addrspace(1) as our GC managed heap.113    return (1 == PT->getAddressSpace());114  }115};116 117} // end anonymous namespace118 119// Register all the above so that they can be found at runtime.  Note that120// these static initializers are important since the registration list is121// constructed from their storage.122static GCRegistry::Add<ErlangGC> A("erlang",123                                   "erlang-compatible garbage collector");124static GCRegistry::Add<OcamlGC> B("ocaml", "ocaml 3.10-compatible GC");125static GCRegistry::Add<ShadowStackGC>126    C("shadow-stack", "Very portable GC for uncooperative code generators");127static GCRegistry::Add<StatepointGC> D("statepoint-example",128                                       "an example strategy for statepoint");129static GCRegistry::Add<CoreCLRGC> E("coreclr", "CoreCLR-compatible GC");130 131// Provide hook to ensure the containing library is fully loaded.132void llvm::linkAllBuiltinGCs() {}133