diff options
38 files changed, 524 insertions, 678 deletions
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index 67bb2322a5..ded6380549 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -366,8 +366,8 @@ external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic" external function_call_conv : llvalue -> int = "llvm_function_call_conv" external set_function_call_conv : int -> llvalue -> unit = "llvm_set_function_call_conv" -external collector : llvalue -> string option = "llvm_collector" -external set_collector : string option -> llvalue -> unit = "llvm_set_collector" +external gc : llvalue -> string option = "llvm_gc" +external set_gc : string option -> llvalue -> unit = "llvm_set_gc" external function_begin : llmodule -> (llmodule, llvalue) llpos = "llvm_function_begin" external function_succ : llvalue -> (llmodule, llvalue) llpos diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 1f4c4a5d6e..fc2919e328 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -921,14 +921,14 @@ external function_call_conv : llvalue -> int = "llvm_function_call_conv" external set_function_call_conv : int -> llvalue -> unit = "llvm_set_function_call_conv" -(** [collector f] returns [Some name] if the function [f] has a garbage +(** [gc f] returns [Some name] if the function [f] has a garbage collection algorithm specified and [None] otherwise. - See the method [llvm::Function::getCollector]. *) -external collector : llvalue -> string option = "llvm_collector" + See the method [llvm::Function::getGC]. *) +external gc : llvalue -> string option = "llvm_gc" -(** [set_collector gc f] sets the collection algorithm for the function [f] to - [gc]. See the method [llvm::Function::setCollector]. *) -external set_collector : string option -> llvalue -> unit = "llvm_set_collector" +(** [set_gc gc f] sets the collection algorithm for the function [f] to + [gc]. See the method [llvm::Function::setGC]. *) +external set_gc : string option -> llvalue -> unit = "llvm_set_gc" (** {7 Operations on params} *) diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 94bd374594..f09d6cd91c 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -643,13 +643,13 @@ CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) { } /* llvalue -> string option */ -CAMLprim value llvm_collector(LLVMValueRef Fn) { - const char *Collector; +CAMLprim value llvm_gc(LLVMValueRef Fn) { + const char *GC; CAMLparam0(); CAMLlocal2(Name, Option); - if ((Collector = LLVMGetCollector(Fn))) { - Name = copy_string(Collector); + if ((GC = LLVMGetGC(Fn))) { + Name = copy_string(GC); Option = alloc(1, 0); Field(Option, 0) = Name; @@ -660,8 +660,8 @@ CAMLprim value llvm_collector(LLVMValueRef Fn) { } /* string option -> llvalue -> unit */ -CAMLprim value llvm_set_collector(value GC, LLVMValueRef Fn) { - LLVMSetCollector(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0))); +CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) { + LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0))); return Val_unit; } diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 7fa91cdb7a..9ff125199f 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -411,8 +411,8 @@ void LLVMDeleteFunction(LLVMValueRef Fn); unsigned LLVMGetIntrinsicID(LLVMValueRef Fn); unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn); void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); -const char *LLVMGetCollector(LLVMValueRef Fn); -void LLVMSetCollector(LLVMValueRef Fn, const char *Coll); +const char *LLVMGetGC(LLVMValueRef Fn); +void LLVMSetGC(LLVMValueRef Fn, const char *Name); /* Operations on parameters */ unsigned LLVMCountParams(LLVMValueRef Fn); diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 50af9d5dd6..12607dcd32 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -60,7 +60,7 @@ namespace bitc { /// MODULE_CODE_PURGEVALS: [numvals] MODULE_CODE_PURGEVALS = 10, - MODULE_CODE_COLLECTORNAME = 11 // COLLECTORNAME: [strchr x N] + MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N] }; /// PARAMATTR blocks have code for defining a parameter attribute set. diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 27ea22140d..52921531f2 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -22,7 +22,7 @@ #include <set> namespace llvm { - class Collector; + class GCStrategy; class Constant; class ConstantArray; class GCMetadataPrinter; @@ -53,7 +53,7 @@ namespace llvm { MachineModuleInfo *MMI; // GCMetadataPrinters - The garbage collection metadata printer table. - typedef DenseMap<Collector*,GCMetadataPrinter*> gcp_map_type; + typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; typedef gcp_map_type::iterator gcp_iterator; gcp_map_type GCMetadataPrinters; @@ -366,7 +366,7 @@ namespace llvm { void EmitXXStructorList(Constant *List); void EmitConstantPool(unsigned Alignment, const char *Section, std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP); - GCMetadataPrinter *GetOrCreateGCPrinter(Collector *C); + GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; } diff --git a/include/llvm/CodeGen/GCMedataPrinter.h b/include/llvm/CodeGen/GCMedataPrinter.h deleted file mode 100644 index 20b470296e..0000000000 --- a/include/llvm/CodeGen/GCMedataPrinter.h +++ /dev/null @@ -1,167 +0,0 @@ -//===-- llvm/CodeGen/Collector.h - Garbage collection -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Collector records sufficient information about a machine function to enable -// accurate garbage collectors. Specifically: -// -// - Safe points -// Garbage collection is only possible at certain points in code. Code -// generators should record points: -// -// - At and after any call to a subroutine -// - Before returning from the current function -// - Before backwards branches (loops) -// -// - Roots -// When a reference to a GC-allocated object exists on the stack, it must be -// stored in an alloca registered with llvm.gcoot. -// -// This generic information should used by ABI-specific passes to emit support -// tables for the runtime garbage collector. -// -// MachineCodeAnalysis identifies the GC safe points in the machine code. (Roots -// are identified in SelectionDAGISel.) -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_COLLECTOR_H -#define LLVM_CODEGEN_COLLECTOR_H - -#include "llvm/CodeGen/CollectorMetadata.h" -#include <iosfwd> -#include <string> - -namespace llvm { - - /// Collector describes a garbage collector's code generation requirements, - /// and provides overridable hooks for those needs which cannot be abstractly - /// described. - class Collector { - public: - typedef std::vector<CollectorMetadata*> list_type; - typedef list_type::iterator iterator; - - private: - friend class CollectorModuleMetadata; - const Module *M; - std::string Name; - - list_type Functions; - - protected: - unsigned NeededSafePoints; //< Bitmask of required safe points. - bool CustomReadBarriers; //< Default is to insert loads. - bool CustomWriteBarriers; //< Default is to insert stores. - bool CustomRoots; //< Default is to pass through to backend. - bool InitRoots; //< If set, roots are nulled during lowering. - bool UsesMetadata; //< If set, backend must emit metadata tables. - - public: - Collector(); - - virtual ~Collector(); - - - /// getName - The name of the collector, for debugging. - /// - const std::string &getName() const { return Name; } - - /// getModule - The module upon which the collector is operating. - /// - const Module &getModule() const { return *M; } - - /// True if this collector requires safe points of any kind. By default, - /// none are recorded. - bool needsSafePoints() const { return NeededSafePoints != 0; } - - /// True if the collector requires the given kind of safe point. By default, - /// none are recorded. - bool needsSafePoint(GC::PointKind Kind) const { - return (NeededSafePoints & 1 << Kind) != 0; - } - - /// By default, write barriers are replaced with simple store instructions. - /// If true, then addPassesToCustomLowerIntrinsics must instead process - /// them. - bool customWriteBarrier() const { return CustomWriteBarriers; } - - /// By default, read barriers are replaced with simple load instructions. - /// If true, then addPassesToCustomLowerIntrinsics must instead process - /// them. - bool customReadBarrier() const { return CustomReadBarriers; } - - /// By default, roots are left for the code generator. If Custom, then - /// addPassesToCustomLowerIntrinsics must add passes to delete them. - bool customRoots() const { return CustomRoots; } - - /// If set, gcroot intrinsics should initialize their allocas to null. This - /// is necessary for most collectors. - bool initializeRoots() const { return InitRoots; } - - /// If set, appropriate metadata tables must be emitted by the back-end - /// (assembler, JIT, or otherwise). - bool usesMetadata() const { return UsesMetadata; } - - /// begin/end - Iterators for function metadata. - /// - iterator begin() { return Functions.begin(); } - iterator end() { return Functions.end(); } - - /// insertFunctionMetadata - Creates metadata for a function. - /// - CollectorMetadata *insertFunctionMetadata(const Function &F); - - /// initializeCustomLowering/performCustomLowering - If any of the actions - /// are set to custom, performCustomLowering must be overriden to create a - /// transform to lower those actions to LLVM IR. initializeCustomLowering - /// is optional to override. These are the only Collector methods through - /// which the LLVM IR can be modified. - virtual bool initializeCustomLowering(Module &F); - virtual bool performCustomLowering(Function &F); - }; - - // GCMetadataPrinter - Emits GC metadata as assembly code. - class GCMetadataPrinter { - public: - typedef Collector::list_type list_type; - typedef Collector::iterator iterator; - - private: - Collector *Coll; - - friend class AsmPrinter; - - protected: - // May only be subclassed. - GCMetadataPrinter(); - - // Do not implement. - GCMetadataPrinter(const GCMetadataPrinter &); - GCMetadataPrinter &operator=(const GCMetadataPrinter &); - - public: - Collector &getCollector() { return *Coll; } - const Module &getModule() const { return Coll->getModule(); } - - iterator begin() { return Coll->begin(); } - iterator end() { return Coll->end(); } - - /// beginAssembly/finishAssembly - Emit module metadata as assembly code. - virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI); - - virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI); - - virtual ~GCMetadataPrinter(); - }; - -} - -#endif diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 1fb3b502ee..e94aba388a 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -1,4 +1,4 @@ -//===-- CollectorMetadata.h - Garbage collector metadata ------------------===// +//===-- GCMetadata.h - Garbage collector metadata -------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,33 +7,31 @@ // //===----------------------------------------------------------------------===// // -// This file declares the CollectorMetadata and CollectorModuleMetadata classes, -// which are used as a communication channel from the target code generator -// to the target garbage collectors. This interface allows code generators and -// garbage collectors to be developed independently. +// This file declares the GCFunctionInfo and GCModuleInfo classes, which are +// used as a communication channel from the target code generator to the target +// garbage collectors. This interface allows code generators and garbage +// collectors to be developed independently. // -// The CollectorMetadata class records the data necessary to build a type -// accurate stack map. Roots are specified in the LLVM IR using the llvm.gcroot -// intrinsic, which the code generator understands. The code generator records -// the stack offset for each GC root. Safe points are generated by the code -// generator according to the collector's declared needs (generally at function -// calls). +// The GCFunctionInfo class logs the data necessary to build a type accurate +// stack map. The code generator outputs: +// +// - Safe points as specified by the GCStrategy's NeededSafePoints. +// - Stack offsets for GC roots, as specified by calls to llvm.gcroot // -// Safe points and roots are sufficient to build type-accurate stack maps. As a -// refinement, liveness analysis calculates the set of live roots at each safe -// point. Liveness analysis is not presently performed, so all roots are assumed -// live. +// As a refinement, liveness analysis calculates the set of live roots at each +// safe point. Liveness analysis is not presently performed by the code +// generator, so all roots are assumed live. // -// CollectorModuleMetadata simply collects CollectorMetadata structures for each -// Function as it is compiled. This is necessary for collectors which must emit -// a stack map for the entire compilation unit. CollectorMetadata outlives the -// MachineFunction from which it is derived, so must not refer to any code -// generator data structures. +// GCModuleInfo simply collects GCFunctionInfo instances for each Function as +// they are compiled. This accretion is necessary for collectors which must emit +// a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo +// outlives the MachineFunction from which it is derived and must not refer to +// any code generator data structures. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_COLLECTORMETADATA_H -#define LLVM_CODEGEN_COLLECTORMETADATA_H +#ifndef LLVM_CODEGEN_GCMETADATA_H +#define LLVM_CODEGEN_GCMETADATA_H #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" @@ -42,7 +40,7 @@ namespace llvm { class AsmPrinter; - class Collector; + class GCStrategy; class Constant; class TargetAsmInfo; @@ -78,9 +76,9 @@ namespace llvm { }; - /// CollectorMetadata - Garbage collection metadata for a function. + /// GCFunctionInfo - Garbage collection metadata for a single function. /// - class CollectorMetadata { + class GCFunctionInfo { public: typedef std::vector<GCPoint>::iterator iterator; typedef std::vector<GCRoot>::iterator roots_iterator; @@ -88,7 +86,7 @@ namespace llvm { private: const Function &F; - Collector &C; + GCStrategy &S; uint64_t FrameSize; std::vector<GCRoot> Roots; std::vector<GCPoint> SafePoints; @@ -104,20 +102,20 @@ namespace llvm { // are live per safe point (1.5% on 64-bit hosts). public: - CollectorMetadata(const Function &F, Collector &C); - ~CollectorMetadata(); + GCFunctionInfo(const Function &F, GCStrategy &S); + ~GCFunctionInfo(); /// getFunction - Return the function to which this metadata applies. /// const Function &getFunction() const { return F; } - /// getCollector - Return the collector for the function. + /// getStrategy - Return the GC strategy for the function. /// - Collector &getCollector() { return C; } + GCStrategy &getStrategy() { return S; } /// addStackRoot - Registers a root that lives on the stack. Num is the - /// stack object ID for the alloca (if the code generator is using - /// MachineFrameInfo). + /// stack object ID for the alloca (if the code generator is + // using MachineFrameInfo). void addStackRoot(int Num, Constant *Metadata) { Roots.push_back(GCRoot(Num, Metadata)); } @@ -154,39 +152,39 @@ namespace llvm { }; - /// CollectorModuleMetadata - Garbage collection metadata for a whole module. + /// GCModuleInfo - Garbage collection metadata for a whole module. /// - class CollectorModuleMetadata : public ImmutablePass { - typedef StringMap<Collector*> collector_map_type; - typedef std::vector<Collector*> list_type; - typedef DenseMap<const Function*,CollectorMetadata*> function_map_type; + class GCModuleInfo : public ImmutablePass { + typedef StringMap<GCStrategy*> strategy_map_type; + typedef std::vector<GCStrategy*> list_type; + typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type; - collector_map_type NameMap; - list_type Collectors; - function_map_type Map; + strategy_map_type StrategyMap; + list_type StrategyList; + finfo_map_type FInfoMap; - Collector *getOrCreateCollector(const Module *M, const std::string &Name); + GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name); public: typedef list_type::const_iterator iterator; static char ID; - CollectorModuleMetadata(); - ~CollectorModuleMetadata(); + GCModuleInfo(); + ~GCModuleInfo(); - /// clear - Used to delete module metadata. The metadata deleter pass calls - /// this. + /// clear - Resets the pass. The metadata deleter pass calls this. + /// void clear(); - /// begin/end - Iterators for collectors. + /// begin/end - Iterators for used strategies. /// - iterator begin() const { return Collectors.begin(); } - iterator end() const { return Collectors.end(); } + iterator begin() const { return StrategyList.begin(); } + iterator end() const { return StrategyList.end(); } /// get - Look up function metadata. /// - CollectorMetadata &get(const Function &F); + GCFunctionInfo &getFunctionInfo(const Function &F); }; } diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h new file mode 100644 index 0000000000..1ab138adec --- /dev/null +++ b/include/llvm/CodeGen/GCMetadataPrinter.h @@ -0,0 +1,77 @@ +//===-- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The abstract base class GCMetadataPrinter supports writing GC metadata tables +// as assembly code. This is a separate class from GCStrategy in order to allow +// users of the LLVM JIT to avoid linking with the AsmWriter. +// +// Subclasses of GCMetadataPrinter must be registered using the +// GCMetadataPrinterRegistry. This is separate from the GCStrategy itself +// because these subclasses are logically plugins for the AsmWriter. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_GCMETADATAPRINTER_H +#define LLVM_CODEGEN_GCMETADATAPRINTER_H + +#include "llvm/CodeGen/GCMetadata.h" +#include "llvm/CodeGen/GCStrategy.h" +#include "llvm/Support/Registry.h" +#include <iosfwd> +#include <string> + +namespace llvm { + + class GCMetadataPrinter; + + /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the + /// defaults from Registry. + typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry; + + /// GCMetadataPrinter - Emits GC metadata as assembly code. + /// + class GCMetadataPrinter { + public: + typedef GCStrategy::list_type list_type; + typedef GCStrategy::iterator iterator; + + private: + GCStrategy *S; + + friend class AsmPrinter; + + protected: + // May only be subclassed. + GCMetadataPrinter(); + + // Do not implement. + GCMetadataPrinter(const GCMetadataPrinter &); + GCMetadataPrinter &operator=(const GCMetadataPrinter &); + + public: + GCStrategy &getStrategy() { return *S; } + const Module &getModule() const { return S->getModule(); } + + /// begin/end - Iterate over the collected function metadata. + iterator begin() { return S->begin(); } + iterator end() { return S->end(); } + + /// beginAssembly/finishAssembly - Emit module metadata as assembly code. + virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP, + const TargetAsmInfo &TAI); + + virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP, + const TargetAsmInfo &TAI); + + virtual ~GCMetadataPrinter(); + }; + +} + +#endif diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h index dea0785ef8..80249bc29d 100644 --- a/include/llvm/CodeGen/GCStrategy.h +++ b/include/llvm/CodeGen/GCStrategy.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/Collector.h - Garbage collection -----------*- C++ -*-===// +//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,18 @@ // //===----------------------------------------------------------------------===// // -// Collector records sufficient information about a machine function to enable -// accurate garbage collectors. Specifically: +// GCStrategy coordinates code generation algorithms and implements some itself +// in order to generate code compatible with a target code generator as +// specified in a function's 'gc' attribute. Algorithms are enabled by setting +// flags in a subclass's constructor, and some virtual methods can be +// overridden. +// +// When requested, the GCStrategy will be populated with data about each +// function which uses it. Specifically: // // - Safe points -// Garbage collection is only possible at certain points in code. Code -// generators should record points: +// Garbage collection is generally only possible at certain points in code. +// GCStrategy can request that the collector insert such points: // // - At and after any call to a subroutine // - Before returning from the current function @@ -22,33 +28,37 @@ // When a reference to a GC-allocated object exists on the stack, it must be // stored in an alloca registered with llvm.gcoot. // -// This generic information should used by ABI-specific passes to emit support -// tables for the runtime garbage collector. -// -// MachineCodeAnalysis identifies the GC safe points in the machine code. (Roots -// are identified in SelectionDAGISel.) +// This information can used to emit the metadata tables which are required by +// the target garbage collector runtime. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_COLLECTOR_H -#define LLVM_CODEGEN_COLLECTOR_H +#ifndef LLVM_CODEGEN_GCSTRATEGY_H +#define LLVM_CODEGEN_GCSTRATEGY_H #include "llvm/CodeGen/GCMetadata.h" +#include "llvm/Support/Registry.h" #include <iosfwd> #include <string> namespace llvm { - /// Collector describes a garbage collector's code generation requirements, - /// and provides overridable hooks for those needs which cannot be abstractly - /// described. - class Collector { + class GCStrategy; + + /// The GC strategy registry uses all the defaults from Registry. + /// + typedef Registry<GCStrategy> GCRegistry; + + /// GCStrategy describes a garbage collector algorithm's code generation + /// requirements, and provides overridable hooks for those needs which cannot + /// be abstractly described. + class GCStrategy { public: - typedef std::vector<CollectorMetadata*> list_type; + typedef std::vector<GCFunctionInfo*> list_type; typedef list_type::iterator iterator; private: - friend class CollectorModuleMetadata; + friend class GCModuleInfo; const Module *M; std::string Name; @@ -63,49 +73,51 @@ namespace llvm { bool UsesMetadata; //< If set, backend must emit metadata tables. public: - Collector(); + GCStrategy(); - virtual ~Collector(); + virtual ~GCStrategy(); - /// getName - The name of the collector, for debugging. + /// getName - The name of the GC strategy, for debugging. /// const std::string &getName() const { return Name; } - /// getModule - The module upon which the collector is operating. + /// getModule - The module within which the GC strategy is operating. /// const Module &getModule() const { return *M; } - /// True if this collector requires safe points of any kind. By default, - /// none are recorded. + /// needsSafePoitns - True if safe points of any kind are required. By + // default, none are recorded. bool needsSafePoints() const { return NeededSafePoints != 0; } - /// True if the collector requires the given kind of safe point. By default, - /// none are recorded. + /// needsSafePoint(Kind) - True if the given kind of safe point is + // required. By default, none are recorded. bool needsSafePoint(GC::PointKind Kind) const { return (NeededSafePoints & 1 << Kind) != 0; } - /// By default, write barriers are replaced with simple store instructions. - /// If true, then addPassesToCustomLowerIntrinsics must instead process - /// them. + /// customWriteBarrier - By default, write barriers are replaced with simple + /// store instructions. If true, then + /// performCustomLowering must instead lower them. bool customWriteBarrier() |