Rename some GC classes so that their roll will hopefully be clearer.
authorGordon Henriksen <gordonhenriksen@mac.com>
Sun, 17 Aug 2008 18:44:35 +0000 (18:44 +0000)
committerGordon Henriksen <gordonhenriksen@mac.com>
Sun, 17 Aug 2008 18:44:35 +0000 (18:44 +0000)
In particular, Collector was confusing to implementors. Several
thought that this compile-time class was the place to implement
their runtime GC heap. Of course, it doesn't even exist at runtime.
Specifically, the renames are:

  Collector               -> GCStrategy
  CollectorMetadata       -> GCFunctionInfo
  CollectorModuleMetadata -> GCModuleInfo
  CollectorRegistry       -> GCRegistry
  Function::getCollector  -> getGC (setGC, hasGC, clearGC)

Several accessors and nested types have also been renamed to be
consistent. These changes should be obvious.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54899 91177308-0d34-0410-b5e6-96231b3b80d8

38 files changed:
bindings/ocaml/llvm/llvm.ml
bindings/ocaml/llvm/llvm.mli
bindings/ocaml/llvm/llvm_ocaml.c
include/llvm-c/Core.h
include/llvm/Bitcode/LLVMBitCodes.h
include/llvm/CodeGen/AsmPrinter.h
include/llvm/CodeGen/GCMedataPrinter.h [deleted file]
include/llvm/CodeGen/GCMetadata.h
include/llvm/CodeGen/GCMetadataPrinter.h [new file with mode: 0644]
include/llvm/CodeGen/GCStrategy.h
include/llvm/CodeGen/GCs.h
include/llvm/CodeGen/LinkAllAsmWriterComponents.h
include/llvm/CodeGen/LinkAllCodegenComponents.h
include/llvm/CodeGen/Passes.h
include/llvm/CodeGen/SelectionDAGISel.h
include/llvm/Function.h
lib/AsmParser/llvmAsmParser.y
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
lib/CodeGen/GCMetadata.cpp
lib/CodeGen/GCMetadataPrinter.cpp
lib/CodeGen/GCStrategy.cpp
lib/CodeGen/GCs.cpp [deleted file]
lib/CodeGen/LLVMTargetMachine.cpp
lib/CodeGen/OcamlGC.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/CodeGen/ShadowStackGC.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/CppBackend/CPPBackend.cpp
lib/Target/MSIL/MSILWriter.cpp
lib/Transforms/Utils/InlineFunction.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Core.cpp
lib/VMCore/Function.cpp
lib/VMCore/Verifier.cpp
test/Bindings/Ocaml/vmcore.ml

index 67bb232..ded6380 100644 (file)
@@ -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
index 1f4c4a5..fc2919e 100644 (file)
@@ -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} *)
index 94bd374..f09d6cd 100644 (file)
@@ -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;
 }
 
index 7fa91cd..9ff1251 100644 (file)
@@ -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);
index 50af9d5..12607dc 100644 (file)
@@ -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.
index 27ea221..5292153 100644 (file)
@@ -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 (file)
index 20b4702..0000000
+++ /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
index 1fb3b50..e94aba3 100644 (file)
@@ -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 (file)
index 0000000..1ab138a
--- /dev/null
@@ -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
index dea0785..80249bc 100644 (file)
@@ -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
 //   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() const { return CustomWriteBarriers; }
     
-    /// By default, read barriers are replaced with simple load instructions.
-    /// If true, then addPassesToCustomLowerIntrinsics must instead process
-    /// them.
+    /// customReadBarrier - By default, read barriers are replaced with simple
+    ///                     load instructions. If true, then
+    ///                     performCustomLowering must instead lower 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.
+    /// customRoots - By default, roots are left for the code generator so it
+    ///               can generate a stack map. If true, then
+    //                performCustomLowering must delete them.
     bool customRoots() const { return CustomRoots; }
     
-    /// If set, gcroot intrinsics should initialize their allocas to null. This
-    /// is necessary for most collectors.
+    /// initializeRoots - If set, gcroot intrinsics should initialize their
+    //                    allocas to null before the first use. This is
+    //                    necessary for most GCs and is enabled by default.
     bool initializeRoots() const { return InitRoots; }
     
-    /// If set, appropriate metadata tables must be emitted by the back-end
-    /// (assembler, JIT, or otherwise).
+    /// usesMetadata - 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.
@@ -115,53 +127,17 @@ namespace llvm {
 
     /// insertFunctionMetadata - Creates metadata for a function.
     /// 
-    CollectorMetadata *insertFunctionMetadata(const Function &F);
+    GCFunctionInfo *insertFunctionInfo(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
+    /// are set to custom, performCustomLowering must be overriden to transform
+    /// the corresponding actions to LLVM IR. initializeCustomLowering is
+    /// optional to override. These are the only GCStrategy 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
index 7850ddc..c407b61 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Collectors.h - Garbage collector registry -------------------------===//
+//===-- GCs.h - Garbage collector linkage hacks ---------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,41 +7,29 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file declares the CollectorRegistry class, which is used to discover
-// pluggable garbage collectors.
+// This file contains hack functions to force linking in the GC components.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CODEGEN_GCS_H
 #define LLVM_CODEGEN_GCS_H
 
-#include "llvm/Support/Registry.h"
-
 namespace llvm {
-
-  class Collector;
+  class GCStrategy;
   class GCMetadataPrinter;
   
-  /// The collector registry uses all the defaults from Registry.
-  /// 
-  typedef Registry<Collector> CollectorRegistry;
-  
-  /// The GC assembly printer registry uses all the defaults from Registry.
-  /// 
-  typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
-  
   /// FIXME: Collector instances are not useful on their own. These no longer
   ///        serve any purpose except to link in the plugins.
   
   /// Creates an ocaml-compatible garbage collector.
-  Collector *createOcamlCollector();
+  void linkOcamlGC();
   
   /// Creates an ocaml-compatible metadata printer.
-  GCMetadataPrinter *createOcamlMetadataPrinter();
+  void linkOcamlGCPrinter();
   
   /// Creates a shadow stack garbage collector. This collector requires no code
   /// generator support.
-  Collector *createShadowStackCollector();
+  void linkShadowStackGC();
 }
 
 #endif
index 0dc94ea..a1ba565 100644 (file)
 namespace {
   struct ForceAsmWriterLinking {
     ForceAsmWriterLinking() {
-      // We must reference the passes in such a way that compilers will not
+      // We must reference the plug-ins in such a way that compilers will not
       // delete it all as dead code, even with whole program optimization,
       // yet is effectively a NO-OP. As the compiler isn't smart enough
       // to know that getenv() never returns -1, this will do the job.
       if (std::getenv("bar") != (char*) -1)
         return;
 
-      (void) llvm::createOcamlMetadataPrinter();
+      llvm::linkOcamlGCPrinter();
 
     }
   } ForceAsmWriterLinking; // Force link by creating a global definition.
index 2fb01bf..9ee22d4 100644 (file)
@@ -36,8 +36,8 @@ namespace {
 
       (void) llvm::createSimpleRegisterCoalescer();
       
-      (void) llvm::createOcamlCollector();
-      (void) llvm::createShadowStackCollector();
+      llvm::linkOcamlGC();
+      llvm::linkShadowStackGC();
       
       (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL, false);
       (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL, false);
index 412e9e3..ff1f505 100644 (file)
@@ -152,7 +152,7 @@ namespace llvm {
   FunctionPass *getRegisterAllocator(TargetMachine &T);
 
   /// IntrinsicLowering Pass - Performs target-independent LLVM IR
-  /// transformations for highly portable collectors.
+  /// transformations for highly portable strategies.
   FunctionPass *createGCLoweringPass();
   
   /// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in
@@ -161,13 +161,13 @@ namespace llvm {
   /// folding).
   FunctionPass *createGCMachineCodeAnalysisPass();
   
-  /// Deleter Pass - Releases collector metadata.
+  /// Deleter Pass - Releases GC metadata.
   /// 
-  FunctionPass *createCollectorMetadataDeleter();
+  FunctionPass *createGCInfoDeleter();
   
-  /// Creates a pass to print collector metadata.
+  /// Creates a pass to print GC metadata.
   /// 
-  FunctionPass *createCollectorMetadataPrinter(std::ostream &OS);
+  FunctionPass *createGCInfoPrinter(std::ostream &OS);
   
   /// createMachineLICMPass - This pass performs LICM on machine instructions.
   /// 
index 7471039..77e75c0 100644 (file)
@@ -29,7 +29,7 @@ namespace llvm {
   class TargetLowering;
   class FunctionLoweringInfo;
   class HazardRecognizer;
-  class CollectorMetadata;
+  class GCFunctionInfo;
   class ScheduleDAG;
  
 /// SelectionDAGISel - This is the common base class used for SelectionDAG-based
@@ -41,13 +41,13 @@ public:
   SelectionDAG *CurDAG;
   MachineBasicBlock *BB;
   AliasAnalysis *AA;
-  CollectorMetadata *GCI;
+  GCFunctionInfo *GFI;
   bool Fast;
   std::vector<SDNode*> TopOrder;
   static char ID;
 
   explicit SelectionDAGISel(TargetLowering &tli, bool fast = false) : 
-    FunctionPass((intptr_t)&ID), TLI(tli), GCI(0), Fast(fast), DAGSize(0) {}
+    FunctionPass((intptr_t)&ID), TLI(tli), GFI(), Fast(fast), DAGSize(0) {}
   
   TargetLowering &getTargetLowering() { return TLI; }
 
index 9954418..04e0535 100644 (file)
@@ -148,12 +148,12 @@ public:
   ///
   void setParamAttrs(const PAListPtr &attrs) { ParamAttrs = attrs; }
 
-  /// hasCollector/getCollector/setCollector/clearCollector - The name of the
-  /// garbage collection algorithm to use during code generation.
-  bool hasCollector() const;
-  const char *getCollector() const;
-  void setCollector(const char *Str);
-  void clearCollector();
+  /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
+  ///                             to use during code generation.
+  bool hasGC() const;
+  const char *getGC() const;
+  void setGC(const char *Str);
+  void clearGC();
 
   /// @brief Determine whether the function has the given attribute.
   bool paramHasAttr(unsigned i, ParameterAttributes attr) const {
index 9f317d8..d9b8499 100644 (file)
@@ -2393,7 +2393,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     delete $8;
   }
   if ($10) {
-    Fn->setCollector($10->c_str());
+    Fn->setGC($10->c_str());
     delete $10;
   }
 
index f7796a6..a842bd3 100644 (file)
@@ -892,7 +892,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
   
   SmallVector<uint64_t, 64> Record;
   std::vector<std::string> SectionTable;
-  std::vector<std::string> CollectorTable;
+  std::vector<std::string> GCTable;
 
   // Read all the records for this module.
   while (!Stream.AtEndOfStream()) {
@@ -1019,11 +1019,11 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
       SectionTable.push_back(S);
       break;
     }
-    case bitc::MODULE_CODE_COLLECTORNAME: {  // SECTIONNAME: [strchr x N]
+    case bitc::MODULE_CODE_GCNAME: {  // SECTIONNAME: [strchr x N]
       std::string S;
       if (ConvertToString(Record, 0, S))
-        return Error("Invalid MODULE_CODE_COLLECTORNAME record");
-      CollectorTable.push_back(S);
+        return Error("Invalid MODULE_CODE_GCNAME record");
+      GCTable.push_back(S);
       break;
     }
     // GLOBALVAR: [pointer type, isconst, initid,
@@ -1070,7 +1070,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
       break;
     }
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
-    //             alignment, section, visibility, collector]
+    //             alignment, section, visibility, gc]
     case bitc::MODULE_CODE_FUNCTION: {
       if (Record.size() < 8)
         return Error("Invalid MODULE_CODE_FUNCTION record");
@@ -1098,9 +1098,9 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
       }
       Func->setVisibility(GetDecodedVisibility(Record[7]));
       if (Record.size() > 8 && Record[8]) {
-        if (Record[8]-1 > CollectorTable.size())
-          return Error("Invalid collector ID");
-        Func->setCollector(CollectorTable[Record[8]-1].c_str());
+        if (Record[8]-1 > GCTable.size())
+          return Error("Invalid GC ID");
+        Func->setGC(GCTable[Record[8]-1].c_str());
       }
       
       ValueList.push_back(Func);
index 2c585b1..b5fb607 100644 (file)
@@ -303,10 +303,10 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
     WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
                       0/*TODO*/, Stream);
 
-  // Emit information about sections and collectors, computing how many there
-  // are.  Also compute the maximum alignment value.
+  // Emit information about sections and GC, computing how many there are. Also
+  // compute the maximum alignment value.
   std::map<std::string, unsigned> SectionMap;
-  std::map<std::string, unsigned> CollectorMap;
+  std::map<std::string, unsigned> GCMap;
   unsigned MaxAlignment = 0;
   unsigned MaxGlobalType = 0;
   for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
@@ -333,13 +333,13 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
         Entry = SectionMap.size();
       }
     }
-    if (F->hasCollector()) {
-      // Same for collector names.
-      unsigned &Entry = CollectorMap[F->getCollector()];
+    if (F->hasGC()) {
+      // Same for GC names.
+      unsigned &Entry = GCMap[F->getGC()];
       if (!Entry) {
-        WriteStringRecord(bitc::MODULE_CODE_COLLECTORNAME, F->getCollector(),
+        WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
                           0/*TODO*/, Stream);
-        Entry = CollectorMap.size();
+        Entry = GCMap.size();
       }
     }
   }
@@ -401,7 +401,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
   // Emit the function proto information.
   for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
     // FUNCTION:  [type, callingconv, isproto, paramattr,
-    //             linkage, alignment, section, visibility, collector]
+    //             linkage, alignment, section, visibility, gc]
     Vals.push_back(VE.getTypeID(F->getType()));
     Vals.push_back(F->getCallingConv());
     Vals.push_back(F->isDeclaration());
@@ -410,7 +410,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
     Vals.push_back(Log2_32(F->getAlignment())+1);
     Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
     Vals.push_back(getEncodedVisibility(F));
-    Vals.push_back(F->hasCollector() ? CollectorMap[F->getCollector()] : 0);
+    Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
     
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
index de31840..380b3bc 100644 (file)
@@ -16,9 +16,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/GCMetadataPrinter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -110,18 +108,17 @@ void AsmPrinter::SwitchToDataSection(const char *NewSection,
 
 void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 bool AsmPrinter::doInitialization(Module &M) {
   Mang = new Mangler(M, TAI->getGlobalPrefix());
   
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
-  for (CollectorModuleMetadata::iterator I = CMM->begin(),
-                                         E = CMM->end(); I != E; ++I)
-    if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*I))
-      GCP->beginAssembly(O, *this, *TAI);
+  GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
+    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
+      MP->beginAssembly(O, *this, *TAI);
   
   if (!M.getModuleInlineAsm().empty())
     O << TAI->getCommentString() << " Start of file scope inline assembly\n"
@@ -192,12 +189,11 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
   }
 
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
-  for (CollectorModuleMetadata::iterator I = CMM->end(),
-                                         E = CMM->begin(); I != E; )
-    if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*--I))
-      GCP->finishAssembly(O, *this, *TAI);
+  GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+  for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
+    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
+      MP->finishAssembly(O, *this, *TAI);
 
   // If we don't have any trampolines, then we don't require stack memory
   // to be executable. Some targets have a directive to declare this.
@@ -1466,26 +1462,26 @@ void AsmPrinter::printVisibility(const std::string& Name,
   }
 }
 
-GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(Collector *C) {
-  if (!C->usesMetadata())
+GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
+  if (!S->usesMetadata())
     return 0;
   
-  gcp_iterator GCPI = GCMetadataPrinters.find(C);
+  gcp_iterator GCPI = GCMetadataPrinters.find(S);
   if (GCPI != GCMetadataPrinters.end())
     return GCPI->second;
   
-  const char *Name = C->getName().c_str();
+  const char *Name = S->getName().c_str();
   
   for (GCMetadataPrinterRegistry::iterator
          I = GCMetadataPrinterRegistry::begin(),
          E = GCMetadataPrinterRegistry::end(); I != E; ++I)
     if (strcmp(Name, I->getName()) == 0) {
-      GCMetadataPrinter *GCP = I->instantiate();
-      GCP->Coll = C;
-      GCMetadataPrinters.insert(std::make_pair(C, GCP));
-      return GCP;
+      GCMetadataPrinter *GMP = I->instantiate();
+      GMP->S = S;
+      GCMetadataPrinters.insert(std::make_pair(S, GMP));
+      return GMP;
     }
   
-  cerr << "no GCMetadataPrinter registered for collector: " << Name << "\n";
+  cerr << "no GCMetadataPrinter registered for GC: " << Name << "\n";
   abort();
 }
index efa7f67..42f1a0f 100644 (file)
@@ -1,4 +1,4 @@
-//===-- OcamlCollector.cpp - Ocaml frametable emitter ---------------------===//
+//===-- OcamlGCPrinter.cpp - Ocaml frametable emitter ---------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,13 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements lowering for the llvm.gc* intrinsics compatible with
-// Objective Caml 3.10.0, which uses a liveness-accurate static stack map.
+// This file implements printing the assembly code for an Ocaml frametable.
 //
 //===----------------------------------------------------------------------===//
                         
 #include "llvm/CodeGen/GCs.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/GCMetadataPrinter.h"
 #include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/Module.h"
 #include "llvm/Target/TargetAsmInfo.h"
@@ -38,9 +38,7 @@ namespace {
 static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter>
 Y("ocaml", "ocaml 3.10-compatible collector");
 
-GCMetadataPrinter *llvm::createOcamlMetadataPrinter() {
-  return new OcamlGCMetadataPrinter();
-}
+void llvm::linkOcamlGCPrinter() { }
 
 static void EmitCamlGlobal(const Module &M, std::ostream &OS, AsmPrinter &AP,
                            const TargetAsmInfo &TAI, const char *Id) {
@@ -85,7 +83,7 @@ void OcamlGCMetadataPrinter::beginAssembly(std::ostream &OS, AsmPrinter &AP,
 /// 
 /// Note that this precludes programs from stack frames larger than 64K
 /// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
-/// either condition is detected in a function which uses the collector.
+/// either condition is detected in a function which uses the GC.
 /// 
 void OcamlGCMetadataPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP,
                                             const TargetAsmInfo &TAI) {
@@ -111,33 +109,32 @@ void OcamlGCMetadataPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP,
   AP.SwitchToDataSection(TAI.getDataSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "frametable");
   
-  for (iterator FI = begin(), FE = end(); FI != FE; ++FI) {
-    CollectorMetadata &MD = **FI;
+  for (iterator I = begin(), IE = end(); I != IE; ++I) {
+    GCFunctionInfo &FI = **I;
+    
+    uint64_t FrameSize = FI.getFrameSize();
+    if (FrameSize >= 1<<16) {
+      cerr << "Function '" << FI.getFunction().getNameStart()
+           << "' is too large for the ocaml GC! "
+           << "Frame size " << FrameSize << " >= 65536.\n";
+      cerr << "(" << uintptr_t(&FI) << ")\n";
+      abort(); // Very rude!
+    }
     
     OS << "\t" << TAI.getCommentString() << " live roots for "
-       << MD.getFunction().getNameStart() << "\n";
+       << FI.getFunction().getNameStart() << "\n";
     
-    for (CollectorMetadata::iterator PI = MD.begin(),
-                                     PE = MD.end(); PI != PE; ++PI) {
-      
-      uint64_t FrameSize = MD.getFrameSize();
-      if (FrameSize >= 1<<16) {
-        cerr << "Function '" << MD.getFunction().getNameStart()
-             << "' is too large for the ocaml collector! "
-             << "Frame size " << FrameSize << " >= 65536.\n";
-        abort(); // Very rude!
-      }
-      
-      size_t LiveCount = MD.live_size(PI);
+    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
+      size_t LiveCount = FI.live_size(J);
       if (LiveCount >= 1<<16) {
-        cerr << "Function '" << MD.getFunction().getNameStart()
-             << "' is too large for the ocaml collector! "
+        cerr << "Function '" << FI.getFunction().getNameStart()
+             << "' is too large for the ocaml GC! "
              << "Live root count " << LiveCount << " >= 65536.\n";
         abort(); // Very rude!
       }
       
       OS << AddressDirective
-         << TAI.getPrivateGlobalPrefix() << "label" << PI->Num;
+         << TAI.getPrivateGlobalPrefix() << "label" << J->Num;
       AP.EOL("call return address");
       
       AP.EmitInt16(FrameSize);
@@ -146,14 +143,13 @@ void OcamlGCMetadataPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP,
       AP.EmitInt16(LiveCount);
       AP.EOL("live root count");
       
-      for (CollectorMetadata::live_iterator LI = MD.live_begin(PI),
-                                            LE = MD.live_end(PI);
-                                            LI != LE; ++LI) {
-        assert(LI->StackOffset < 1<<16 &&
+      for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
+                                         KE = FI.live_end(J); K != KE; ++K) {
+        assert(K->StackOffset < 1<<16 &&
                "GC root stack offset is outside of fixed stack frame and out "
-               "of range for Ocaml collector!");
+               "of range for ocaml GC!");
         
-        OS << "\t.word\t" << LI->StackOffset;
+        OS << "\t.word\t" << K->StackOffset;
         AP.EOL("stack offset");
       }
       
index 0b5c6f0..efb89e1 100644 (file)
@@ -1,4 +1,4 @@
-//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===//
+//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,14 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the CollectorMetadata and CollectorModuleMetadata
-// classes.
+// This file implements the GCFunctionInfo class and GCModuleInfo pass.
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/GCs.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/Pass.h"
 #include "llvm/CodeGen/Passes.h"
@@ -53,79 +51,80 @@ namespace {
   
 }
 
-static RegisterPass<CollectorModuleMetadata>
+static RegisterPass<GCModuleInfo>
 X("collector-metadata", "Create Garbage Collector Module Metadata");
 
 // -----------------------------------------------------------------------------
 
-CollectorMetadata::CollectorMetadata(const Function &F, Collector &C)
-  : F(F), C(C), FrameSize(~0LL) {}
+GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
+  : F(F), S(S), FrameSize(~0LL) {}
 
-CollectorMetadata::~CollectorMetadata() {}
+GCFunctionInfo::~GCFunctionInfo() {}
 
 // -----------------------------------------------------------------------------
 
-char CollectorModuleMetadata::ID = 0;
+char GCModuleInfo::ID = 0;
 
-CollectorModuleMetadata::CollectorModuleMetadata()
+GCModuleInfo::GCModuleInfo()
   : ImmutablePass((intptr_t)&ID) {}
 
-CollectorModuleMetadata::~CollectorModuleMetadata() {
+GCModuleInfo::~GCModuleInfo() {
   clear();
 }
 
-Collector *CollectorModuleMetadata::
-getOrCreateCollector(const Module *M, const std::string &Name) {
+GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
+                                              const std::string &Name) {
   const char *Start = Name.c_str();
   
-  collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size());
-  if (NMI != NameMap.end())
+  strategy_map_type::iterator NMI =
+    StrategyMap.find(Start, Start + Name.size());
+  if (NMI != StrategyMap.end())
     return NMI->getValue();
   
-  for (CollectorRegistry::iterator I = CollectorRegistry::begin(),
-                                   E = CollectorRegistry::end(); I != E; ++I) {
+  for (GCRegistry::iterator I = GCRegistry::begin(),
+                            E = GCRegistry::end(); I != E; ++I) {
     if (strcmp(Start, I->getName()) == 0) {
-      Collector *C = I->instantiate();
-      C->M = M;
-      C->Name = Name;
-      NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C);
-      Collectors.push_back(C);
-      return C;
+      GCStrategy *S = I->instantiate();
+      S->M = M;
+      S->Name = Name;
+      StrategyMap.GetOrCreateValue(Start, Start + Name.size()).setValue(S);
+      StrategyList.push_back(S);
+      return S;
     }
   }
   
-  cerr << "unsupported collector: " << Name << "\n";
+  cerr << "unsupported GC: " << Name << "\n";
   abort();
 }
 
-CollectorMetadata &CollectorModuleMetadata::get(const Function &F) {
+GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
   assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
-  assert(F.hasCollector());
+  assert(F.hasGC());
   
-  function_map_type::iterator I = Map.find(&F);
-  if (I != Map.end())
+  finfo_map_type::iterator I = FInfoMap.find(&F);
+  if (I != FInfoMap.end())
     return *I->second;
-    
-  Collector *C = getOrCreateCollector(F.getParent(), F.getCollector());
-  CollectorMetadata *MD = C->insertFunctionMetadata(F);
-  Map[&F] = MD;
-  return *MD;
+  
+  GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
+  GCFunctionInfo *GFI = S->insertFunctionInfo(F);
+  FInfoMap[&F] = GFI;
+  return *GFI;
 }
 
-void CollectorModuleMetadata::clear() {
-  Map.clear();
-  NameMap.clear();
+void GCModuleInfo::clear() {
+  FInfoMap.clear();
+  StrategyMap.clear();
   
   for (iterator I = begin(), E = end(); I != E; ++I)
     delete *I;
-  Collectors.clear();
+  StrategyList.clear();
 }
 
 // -----------------------------------------------------------------------------
 
 char Printer::ID = 0;
 
-FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
+FunctionPass *llvm::createGCInfoPrinter(std::ostream &OS) {
   return new Printer(OS);
 }
 
@@ -139,7 +138,7 @@ const char *Printer::getPassName() const {
 void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
   FunctionPass::getAnalysisUsage(AU);
   AU.setPreservesAll();
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 static const char *DescKind(GC::PointKind Kind) {
@@ -153,23 +152,22 @@ static const char *DescKind(GC::PointKind Kind) {
 }
 
 bool Printer::runOnFunction(Function &F) {
-  if (F.hasCollector()) {
-    CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F);
+  if (!F.hasGC()) {
+    GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
     
     OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
-    for (CollectorMetadata::roots_iterator RI = FD->roots_begin(),
-                                           RE = FD->roots_end();
-                                           RI != RE; ++RI)
+    for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
+                                        RE = FD->roots_end(); RI != RE; ++RI)
       OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
     
     OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n";
-    for (CollectorMetadata::iterator PI = FD->begin(),
-                                     PE = FD->end(); PI != PE; ++PI) {
+    for (GCFunctionInfo::iterator PI = FD->begin(),
+                                  PE = FD->end(); PI != PE; ++PI) {
       
       OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
       
-      for (CollectorMetadata::live_iterator RI = FD->live_begin(PI),
-                                            RE = FD->live_end(PI);;) {
+      for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
+                                         RE = FD->live_end(PI);;) {
         OS << " " << RI->Num;
         if (++RI == RE)
           break;
@@ -187,7 +185,7 @@ bool Printer::runOnFunction(Function &F) {
 
 char Deleter::ID = 0;
 
-FunctionPass *llvm::createCollectorMetadataDeleter() {
+FunctionPass *llvm::createGCInfoDeleter() {
   return new Deleter();
 }
 
@@ -199,7 +197,7 @@ const char *Deleter::getPassName() const {
 
 void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesAll();
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 bool Deleter::runOnFunction(Function &MF) {
@@ -207,8 +205,8 @@ bool Deleter::runOnFunction(Function &MF) {
 }
 
 bool Deleter::doFinalization(Module &M) {
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "Deleter didn't require CollectorModuleMetadata?!");
-  CMM->clear();
+  GCModuleInfo *GMI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(GMI && "Deleter didn't require GCModuleInfo?!");
+  GMI->clear();
   return false;
 }
index b16d873..07ec0bd 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Collector.cpp - Garbage collection infrastructure -----------------===//
+//===-- GCMetadataPrinter.cpp - Garbage collection infrastructure ---------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,15 +7,25 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements target- and collector-independent garbage collection
-// infrastructure.
+// This file implements the abstract base class GCMetadataPrinter.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/CodeGen/GCMetadataPrinter.h"
 
 using namespace llvm;
 
+// -----------------------------------------------------------------------------
+
+template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Head = 0;
+template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Tail = 0;
+template<> GCMetadataPrinterRegistry::listener *
+GCMetadataPrinterRegistry::ListenerHead = 0;
+template<> GCMetadataPrinterRegistry::listener *
+GCMetadataPrinterRegistry::ListenerTail = 0;
+
+// -----------------------------------------------------------------------------
+
 GCMetadataPrinter::GCMetadataPrinter() { }
 
 GCMetadataPrinter::~GCMetadataPrinter() { }
index f5cb9ab..2666775 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Collector.cpp - Garbage collection infrastructure -----------------===//
+//===-- GCStrategy.cpp - Garbage collection infrastructure -----------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,6 +10,9 @@
 // This file implements target- and collector-independent garbage collection
 // infrastructure.
 //
+// MachineCodeAnalysis identifies the GC safe points in the machine code. Roots
+// are identified in SelectionDAGISel.
+//
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCStrategy.h"
@@ -31,13 +34,13 @@ namespace {
   
   /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
   /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as 
-  /// directed by the Collector. It also performs automatic root initialization
+  /// directed by the GCStrategy. It also performs automatic root initialization
   /// and custom intrinsic lowering.
   class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
-    static bool NeedsDefaultLoweringPass(const Collector &C);
-    static bool NeedsCustomLoweringPass(const Collector &C);
+    static bool NeedsDefaultLoweringPass(const GCStrategy &C);
+    static bool NeedsCustomLoweringPass(const GCStrategy &C);
     static bool CouldBecomeSafePoint(Instruction *I);
-    bool PerformDefaultLowering(Function &F, Collector &Coll);
+    bool PerformDefaultLowering(Function &F, GCStrategy &Coll);
     static bool InsertRootInitializers(Function &F,
                                        AllocaInst **Roots, unsigned Count);
     
@@ -56,10 +59,10 @@ namespace {
   /// MachineCodeAnalysis - This is a target-independent pass over the machine 
   /// function representation to identify safe points for the garbage collector
   /// in the machine code. It inserts labels at safe points and populates a
-  /// CollectorMetadata record for each function.
+  /// GCMetadata record for each function.
   class VISIBILITY_HIDDEN MachineCodeAnalysis : public MachineFunctionPass {
     const TargetMachine *TM;
-    CollectorMetadata *MD;
+    GCFunctionInfo *FI;
     MachineModuleInfo *MMI;
     const TargetInstrInfo *TII;
     MachineFrameInfo *MFI;
@@ -85,7 +88,14 @@ namespace {
 
 // -----------------------------------------------------------------------------
 
-Collector::Collector() :
+template<> GCRegistry::node *GCRegistry::Head = 0;
+template<> GCRegistry::node *GCRegistry::Tail = 0;
+template<> GCRegistry::listener *GCRegistry::ListenerHead = 0;
+template<> GCRegistry::listener *GCRegistry::ListenerTail = 0;
+
+// -----------------------------------------------------------------------------
+
+GCStrategy::GCStrategy() :
   NeededSafePoints(0),
   CustomReadBarriers(false),
   CustomWriteBarriers(false),
@@ -94,26 +104,26 @@ Collector::Collector() :
   UsesMetadata(false)
 {}
 
-Collector::~Collector() {
+GCStrategy::~GCStrategy() {
   for (iterator I = begin(), E = end(); I != E; ++I)
     delete *I;
   
   Functions.clear();
 }
  
-bool Collector::initializeCustomLowering(Module &M) { return false; }
+bool GCStrategy::initializeCustomLowering(Module &M) { return false; }
  
-bool Collector::performCustomLowering(Function &F) {
+bool GCStrategy::performCustomLowering(Function &F) {
   cerr << "gc " << getName() << " must override performCustomLowering.\n";
   abort();
   return 0;
 }
-    
-CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) {
-  CollectorMetadata *CM = new CollectorMetadata(F, *this);
-  Functions.push_back(CM);
-  return CM;
-} 
+
+GCFunctionInfo *GCStrategy::insertFunctionInfo(const Function &F) {
+  GCFunctionInfo *FI = new GCFunctionInfo(F, *this);
+  Functions.push_back(FI);
+  return FI;
+}
 
 // -----------------------------------------------------------------------------
 
@@ -132,7 +142,7 @@ const char *LowerIntrinsics::getPassName() const {
     
 void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
   FunctionPass::getAnalysisUsage(AU);
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 /// doInitialization - If this module uses the GC intrinsics, find them now.
@@ -141,15 +151,14 @@ bool LowerIntrinsics::doInitialization(Module &M) {
   //        work against the entire module. But this cannot be done at
   //        runFunction time (initializeCustomLowering likely needs to change
   //        the module).
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "LowerIntrinsics didn't require CollectorModuleMetadata!?");
+  GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && I->hasCollector())
-      CMM->get(*I); // Instantiate the Collector.
+    if (!I->isDeclaration() && I->hasGC())
+      MI->getFunctionInfo(*I); // Instantiate the GC strategy.
   
   bool MadeChange = false;
-  for (CollectorModuleMetadata::iterator I = CMM->begin(),
-                                         E = CMM->end(); I != E; ++I)
+  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
     if (NeedsCustomLoweringPass(**I))
       if ((*I)->initializeCustomLowering(M))
         MadeChange = true;
@@ -185,7 +194,7 @@ bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots,
   return MadeChange;
 }
 
-bool LowerIntrinsics::NeedsDefaultLoweringPass(const Collector &C) {
+bool LowerIntrinsics::NeedsDefaultLoweringPass(const GCStrategy &C) {
   // Default lowering is necessary only if read or write barriers have a default
   // action. The default for roots is no action.
   return !C.customWriteBarrier()
@@ -193,7 +202,7 @@ bool LowerIntrinsics::NeedsDefaultLoweringPass(const Collector &C) {
       || C.initializeRoots();
 }
 
-bool LowerIntrinsics::NeedsCustomLoweringPass(const Collector &C) {
+bool LowerIntrinsics::NeedsCustomLoweringPass(const GCStrategy &C) {
   // Custom lowering is only necessary if enabled for some action.
   return C.customWriteBarrier()
       || C.customReadBarrier()
@@ -232,26 +241,27 @@ bool LowerIntrinsics::CouldBecomeSafePoint(Instruction *I) {
 /// Leave gcroot intrinsics; the code generator needs to see those.
 bool LowerIntrinsics::runOnFunction(Function &F) {
   // Quick exit for functions that do not use GC.
-  if (!F.hasCollector()) return false;
+  if (!F.hasGC())
+    return false;
   
-  CollectorMetadata &MD = getAnalysis<CollectorModuleMetadata>().get(F);
-  Collector &Coll = MD.getCollector();
+  GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
+  GCStrategy &S = FI.getStrategy();
   
   bool MadeChange = false;
   
-  if (NeedsDefaultLoweringPass(Coll))
-    MadeChange |= PerformDefaultLowering(F, Coll);
+  if (NeedsDefaultLoweringPass(S))
+    MadeChange |= PerformDefaultLowering(F, S);
   
-  if (NeedsCustomLoweringPass(Coll))
-    MadeChange |= Coll.performCustomLowering(F);
+  if (NeedsCustomLoweringPass(S))
+    MadeChange |= S.performCustomLowering(F);
   
   return MadeChange;
 }
 
-bool LowerIntrinsics::PerformDefaultLowering(Function &F, Collector &Coll) {
-  bool LowerWr = !Coll.customWriteBarrier();
-  bool LowerRd = !Coll.customReadBarrier();
-  bool InitRoots = Coll.initializeRoots();
+bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) {
+  bool LowerWr = !S.customWriteBarrier();
+  bool LowerRd = !S.customReadBarrier();
+  bool InitRoots = S.initializeRoots();
   
   SmallVector<AllocaInst*,32> Roots;
   
@@ -320,7 +330,7 @@ void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
   AU.setPreservesAll();
   AU.addRequired<MachineModuleInfo>();
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 unsigned MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, 
@@ -336,11 +346,11 @@ void MachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
   MachineBasicBlock::iterator RAI = CI; 
   ++RAI;                                
   
-  if (MD->getCollector().needsSafePoint(GC::PreCall))
-    MD->addSafePoint(GC::PreCall, InsertLabel(*CI->getParent(), CI));
+  if (FI->getStrategy().needsSafePoint(GC::PreCall))
+    FI->addSafePoint(GC::PreCall, InsertLabel(*CI->getParent(), CI));
   
-  if (MD->getCollector().needsSafePoint(GC::PostCall))
-    MD->addSafePoint(GC::PostCall, InsertLabel(*CI->getParent(), RAI));
+  if (FI->getStrategy().needsSafePoint(GC::PostCall))
+    FI->addSafePoint(GC::PostCall, InsertLabel(*CI->getParent(), RAI));
 }
 
 void MachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
@@ -357,18 +367,19 @@ void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
   uint64_t OffsetAdjustment = MFI->getOffsetAdjustment();
   uint64_t OffsetOfLocalArea = TM->getFrameInfo()->getOffsetOfLocalArea();
   
-  for (CollectorMetadata::roots_iterator RI = MD->roots_begin(),
-                                         RE = MD->roots_end(); RI != RE; ++RI)
+  for (GCFunctionInfo::roots_iterator RI = FI->roots_begin(),
+                                      RE = FI->roots_end(); RI != RE; ++RI)
     RI->StackOffset = MFI->getObjectOffset(RI->Num) + StackSize
                       - OffsetOfLocalArea + OffsetAdjustment;
 }
 
 bool MachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
   // Quick exit for functions that do not use GC.
-  if (!MF.getFunction()->hasCollector()) return false;
+  if (!MF.getFunction()->hasGC())
+    return false;
   
-  MD = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction());
-  if (!MD->getCollector().needsSafePoints())
+  FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
+  if (!FI->getStrategy().needsSafePoints())
     return false;
   
   TM = &MF.getTarget();
@@ -377,7 +388,7 @@ bool MachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
   MFI = MF.getFrameInfo();
   
   // Find the size of the stack frame.
-  MD->setFrameSize(MFI->getStackSize());
+  FI->setFrameSize(MFI->getStackSize());
   
   // Find all safe points.
   FindSafePoints(MF);
diff --git a/lib/CodeGen/GCs.cpp b/lib/CodeGen/GCs.cpp
deleted file mode 100644 (file)
index 1247253..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-//===-- Collectors.cpp - Garbage collector registry -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the static data members of the CollectorRegistry class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCs.h"
-
-using namespace llvm;
-
-template<> CollectorRegistry::node *CollectorRegistry::Head = 0;
-template<> CollectorRegistry::node *CollectorRegistry::Tail = 0;
-template<> CollectorRegistry::listener *CollectorRegistry::ListenerHead = 0;
-template<> CollectorRegistry::listener *CollectorRegistry::ListenerTail = 0;
-
-template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Head = 0;
-template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Tail = 0;
-template<> GCMetadataPrinterRegistry::listener *
-GCMetadataPrinterRegistry::ListenerHead = 0;
-template<> GCMetadataPrinterRegistry::listener *
-GCMetadataPrinterRegistry::ListenerTail = 0;
index d420ffb..938e1ae 100644 (file)
@@ -133,7 +133,7 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
     PM.add(createMachineFunctionPrinterPass(cerr));
   
   if (PrintGCInfo)
-    PM.add(createCollectorMetadataPrinter(*cerr));
+    PM.add(createGCInfoPrinter(*cerr));
   
   // Fold redundant debug labels.
   PM.add(createDebugLabelFoldingPass());
@@ -173,7 +173,7 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
   if (MCE)
     addSimpleCodeEmitter(PM, Fast, PrintEmittedAsm, *MCE);
     
-  PM.add(createCollectorMetadataDeleter());
+  PM.add(createGCInfoDeleter());
 
   // Delete machine code for this function
   PM.add(createMachineCodeDeleter());
@@ -274,14 +274,14 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
     PM.add(createMachineFunctionPrinterPass(cerr));
   
   if (PrintGCInfo)
-    PM.add(createCollectorMetadataPrinter(*cerr));
+    PM.add(createGCInfoPrinter(*cerr));
   
   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
     PM.add(createMachineFunctionPrinterPass(cerr));
 
   addCodeEmitter(PM, Fast, PrintEmittedAsm, MCE);
   
-  PM.add(createCollectorMetadataDeleter());
+  PM.add(createGCInfoDeleter());
   
   // Delete machine code for this function
   PM.add(createMachineCodeDeleter());
index 88499cb..0b90444 100644 (file)
@@ -1,4 +1,4 @@
-//===-- OcamlCollector.cpp - Ocaml frametable emitter ---------------------===//
+//===-- OcamlGC.cpp - Ocaml frametable GC strategy ------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -9,38 +9,29 @@
 //
 // This file implements lowering for the llvm.gc* intrinsics compatible with
 // Objective Caml 3.10.0, which uses a liveness-accurate static stack map.
+// 
+// The frametable emitter is in OcamlGCPrinter.cpp.
 //
 //===----------------------------------------------------------------------===//
                         
 #include "llvm/CodeGen/GCs.h"
-#include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
 
 using namespace llvm;
 
 namespace {
-
-  class VISIBILITY_HIDDEN OcamlCollector : public Collector {
+  class VISIBILITY_HIDDEN OcamlGC : public GCStrategy {
   public:
-    OcamlCollector();
+    OcamlGC();
   };
-  
 }
 
-static CollectorRegistry::Add<OcamlCollector>
-X("ocaml", "ocaml 3.10-compatible collector");
-
-// -----------------------------------------------------------------------------
+static GCRegistry::Add<OcamlGC>
+X("ocaml", "ocaml 3.10-compatible GC");
 
-Collector *llvm::createOcamlCollector() {
-  return new OcamlCollector();
-}
+void llvm::linkOcamlGC() { }
 
-OcamlCollector::OcamlCollector() {
+OcamlGC::OcamlGC() {
   NeededSafePoints = 1 << GC::PostCall;
   UsesMetadata = true;
 }
index 012e7d0..f4e31f7 100644 (file)
@@ -27,6 +27,7 @@
 #include "llvm/IntrinsicInst.h"
 #include "llvm/ParameterAttributes.h"
 #include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -601,15 +602,15 @@ public:
   ///
   FunctionLoweringInfo &FuncInfo;
   
-  /// GCI - Garbage collection metadata for the function.
-  CollectorMetadata *GCI;
+  /// GFI - Garbage collection metadata for the function.
+  GCFunctionInfo *GFI;
 
   SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
                        AliasAnalysis &aa,
                        FunctionLoweringInfo &funcinfo,
-                       CollectorMetadata *gci)
+                       GCFunctionInfo *gfi)
     : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa),
-      FuncInfo(funcinfo), GCI(gci) {
+      FuncInfo(funcinfo), GFI(gfi) {
   }
 
   /// getRoot - Return the current virtual root of the Selection DAG,
@@ -3485,18 +3486,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
   }
 
   case Intrinsic::gcroot:
-    if (GCI) {
+    if (GFI) {
       Value *Alloca = I.getOperand(1);
       Constant *TypeMap = cast<Constant>(I.getOperand(2));
       
       FrameIndexSDNode *FI = cast<FrameIndexSDNode>(getValue(Alloca).Val);
-      GCI->addStackRoot(FI->getIndex(), TypeMap);
+      GFI->addStackRoot(FI->getIndex(), TypeMap);
     }
     return 0;
 
   case Intrinsic::gcread:
   case Intrinsic::gcwrite:
-    assert(0 && "Collector failed to lower gcread/gcwrite intrinsics!");
+    assert(0 && "GC failed to lower gcread/gcwrite intrinsics!");
     return 0;
 
   case Intrinsic::flt_rounds: {
@@ -4878,7 +4879,7 @@ unsigned SelectionDAGISel::MakeReg(MVT VT) {
 
 void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<AliasAnalysis>();
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
   AU.setPreservesAll();
 }
 
@@ -4887,10 +4888,10 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
   AA = &getAnalysis<AliasAnalysis>();
 
   MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
-  if (MF.getFunction()->hasCollector())
-    GCI = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction());
+  if (MF.getFunction()->hasGC())
+    GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
   else
-    GCI = 0;
+    GFI = 0;
   RegInfo = &MF.getRegInfo();
   DOUT << "\n\n\n=== " << Fn.getName() << "\n";
 
@@ -5089,7 +5090,7 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG,
 void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
        std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
                                          FunctionLoweringInfo &FuncInfo) {
-  SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI);
+  SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GFI);
 
   // Lower any arguments needed in this block if this is the entry block.
   if (LLVMBB == &LLVMBB->getParent()->getEntryBlock())
@@ -5504,7 +5505,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                          getAnalysisToUpdate<MachineModuleInfo>(),
                          NodeAllocator);
       CurDAG = &HSDAG;
-      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
+      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GFI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = BitTestCases[i].Parent;
       HSDL.setCurrentBasicBlock(BB);
@@ -5519,7 +5520,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                          getAnalysisToUpdate<MachineModuleInfo>(),
                          NodeAllocator);
       CurDAG = &BSDAG;
-      SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
+      SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GFI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = BitTestCases[i].Cases[j].ThisBB;
       BSDL.setCurrentBasicBlock(BB);
@@ -5578,7 +5579,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                          getAnalysisToUpdate<MachineModuleInfo>(),
                          NodeAllocator);
       CurDAG = &HSDAG;
-      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
+      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GFI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = JTCases[i].first.HeaderBB;
       HSDL.setCurrentBasicBlock(BB);
@@ -5592,7 +5593,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                        getAnalysisToUpdate<MachineModuleInfo>(),
                        NodeAllocator);
     CurDAG = &JSDAG;
-    SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
+    SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GFI);
     // Set the current basic block to the mbb we wish to insert the code into
     BB = JTCases[i].second.MBB;
     JSDL.setCurrentBasicBlock(BB);
@@ -5642,7 +5643,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                       getAnalysisToUpdate<MachineModuleInfo>(),
                       NodeAllocator);
     CurDAG = &SDAG;
-    SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
+    SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GFI);
     
     // Set the current basic block to the mbb we wish to insert the code into
     BB = SwitchCases[i].ThisBB;
index 850c005..cf0e6dd 100644 (file)
@@ -1,4 +1,4 @@
-//===-- ShadowStackCollector.cpp - GC support for uncooperative targets ---===//
+//===-- ShadowStackGC.cpp - GC support for uncooperative targets ----------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -9,7 +9,7 @@
 //
 // This file implements lowering for the llvm.gc* intrinsics for targets that do
 // not natively support them (which includes the C backend). Note that the code
-// generated is not quite as efficient as collectors which generate stack maps
+// generated is not quite as efficient as algorithms which generate stack maps
 // to identify roots.
 //
 // This pass implements the code transformation described in this paper:
@@ -17,7 +17,7 @@
 //   Fergus Henderson, ISMM, 2002
 //
 // In runtime/GC/SemiSpace.cpp is a prototype runtime which is compatible with
-// this collector.
+// ShadowStackGC.
 //
 // In order to support this particular transformation, all stack roots are
 // coallocated in the stack. This allows a fully target-independent stack map
@@ -37,7 +37,7 @@ using namespace llvm;
 
 namespace {
   
-  class VISIBILITY_HIDDEN ShadowStackCollector : public Collector {
+  class VISIBILITY_HIDDEN ShadowStackGC : public GCStrategy {
     /// RootChain - This is the global linked-list that contains the chain of GC
     /// roots.
     GlobalVariable *Head;
@@ -51,7 +51,7 @@ namespace {
     std::vector<std::pair<CallInst*,AllocaInst*> > Roots;
     
   public:
-    ShadowStackCollector();
+    ShadowStackGC();
     
     bool initializeCustomLowering(Module &M);
     bool performCustomLowering(Function &F);
@@ -69,9 +69,8 @@ namespace {
 
 }
   
-static CollectorRegistry::Add<ShadowStackCollector>
-Y("shadow-stack",
-  "Very portable collector for uncooperative code generators");
+static GCRegistry::Add<ShadowStackGC>
+X("shadow-stack", "Very portable GC for uncooperative code generators");
   
 namespace {
   /// EscapeEnumerator - This is a little algorithm to find all escape points
@@ -173,21 +172,18 @@ namespace {
       }
     }
   };
-
 }
 
 // -----------------------------------------------------------------------------
 
-Collector *llvm::createShadowStackCollector() {
-  return new ShadowStackCollector();
-}
+void llvm::linkShadowStackGC() { }
 
-ShadowStackCollector::ShadowStackCollector() : Head(0), StackEntryTy(0) {
+ShadowStackGC::ShadowStackGC() : Head(0), StackEntryTy(0) {
   InitRoots = true;
   CustomRoots = true;
 }
 
-Constant *ShadowStackCollector::GetFrameMap(Function &F) {
+Constant *ShadowStackGC::GetFrameMap(Function &F) {
   // doInitialization creates the abstract type of this value.
   
   Type *VoidPtr = PointerType::getUnqual(Type::Int8Ty);
@@ -242,7 +238,7 @@ Constant *ShadowStackCollector::GetFrameMap(Function &F) {
   return ConstantExpr::getGetElementPtr(GV, GEPIndices, 2);
 }
 
-const Type* ShadowStackCollector::GetConcreteStackEntryType(Function &F) {
+const Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) {
   // doInitialization creates the generic version of this type.
   std::vector<const Type*> EltTys;
   EltTys.push_back(StackEntryTy);
@@ -259,7 +255,7 @@ const Type* ShadowStackCollector::GetConcreteStackEntryType(Function &F) {
 
 /// doInitialization - If this module uses the GC intrinsics, find them now. If
 /// not, exit fast.
-bool ShadowStackCollector::initializeCustomLowering(Module &M) {
+bool ShadowStackGC::initializeCustomLowering(Module &M) {
   // struct FrameMap {
   //   int32_t NumRoots; // Number of roots in stack frame.
   //   int32_t NumMeta;  // Number of metadata descriptors. May be < NumRoots.
@@ -307,13 +303,13 @@ bool ShadowStackCollector::initializeCustomLowering(Module &M) {
   return true;
 }
 
-bool ShadowStackCollector::IsNullValue(Value *V) {
+bool ShadowStackGC::IsNullValue(Value *V) {
   if (Constant *C = dyn_cast<Constant>(V))
     return C->isNullValue();
   return false;
 }
 
-void ShadowStackCollector::CollectRoots(Function &F) {
+void ShadowStackGC::CollectRoots(Function &F) {
   // FIXME: Account for original alignment. Could fragment the root array.
   //   Approach 1: Null initialize empty slots at runtime. Yuck.
   //   Approach 2: Emit a map of the array instead of just a count.
@@ -341,8 +337,8 @@ void ShadowStackCollector::CollectRoots(Function &F) {
 }
 
 GetElementPtrInst *
-ShadowStackCollector::CreateGEP(IRBuilder<> &B, Value *BasePtr,
-                                int Idx, int Idx2, const char *Name) {
+ShadowStackGC::CreateGEP(IRBuilder<> &B, Value *BasePtr,
+                         int Idx, int Idx2, const char *Name) {
   Value *Indices[] = { ConstantInt::get(Type::Int32Ty, 0),
                        ConstantInt::get(Type::Int32Ty, Idx),
                        ConstantInt::get(Type::Int32Ty, Idx2) };
@@ -354,8 +350,8 @@ ShadowStackCollector::CreateGEP(IRBuilder<> &B, Value *BasePtr,
 }
 
 GetElementPtrInst *
-ShadowStackCollector::CreateGEP(IRBuilder<> &B, Value *BasePtr,
-                                int Idx, const char *Name) {
+ShadowStackGC::CreateGEP(IRBuilder<> &B, Value *BasePtr,
+                         int Idx, const char *Name) {
   Value *Indices[] = { ConstantInt::get(Type::Int32Ty, 0),
                        ConstantInt::get(Type::Int32Ty, Idx) };
   Value *Val = B.CreateGEP(BasePtr, Indices, Indices + 2, Name);
@@ -366,7 +362,7 @@ ShadowStackCollector::CreateGEP(IRBuilder<> &B, Value *BasePtr,
 }
 
 /// runOnFunction - Insert code to maintain the shadow stack.
-bool ShadowStackCollector::performCustomLowering(Function &F) {
+bool ShadowStackGC::performCustomLowering(Function &F) {
   // Find calls to llvm.gcroot.
   CollectRoots(F);
   
@@ -405,9 +401,10 @@ bool ShadowStackCollector::performCustomLowering(Function &F) {
     OriginalAlloca->replaceAllUsesWith(SlotPtr);
   }
   
-  // Move past the original stores inserted by Collector::InitRoots. This isn't
-  // really necessary (the collector would never see the intermediate state),
-  // but it's nicer not to push the half-initialized entry onto the stack.
+  // Move past the original stores inserted by GCStrategy::InitRoots. This isn't
+  // really necessary (the collector would never see the intermediate state at
+  // runtime), but it's nicer not to push the half-initialized entry onto the
+  // shadow stack.
   while (isa<StoreInst>(IP)) ++IP;
   AtEntry.SetInsertPoint(IP->getParent(), IP);
   
index 0017eb9..2661b1b 100644 (file)
@@ -3386,6 +3386,6 @@ bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
   PM.add(createCFGSimplificationPass());   // clean up after lower invoke.
   PM.add(new CBackendNameAllUsedStructsAndMergeFunctions());
   PM.add(new CWriter(o));
-  PM.add(createCollectorMetadataDeleter());
+  PM.add(createGCInfoDeleter());
   return false;
 }
index ce86452..b359659 100644 (file)
@@ -1603,9 +1603,9 @@ namespace {
       Out << ");";
       nl(Out);
     }
-    if (F->hasCollector()) {
+    if (F->hasGC()) {
       printCppName(F);
-      Out << "->setCollector(\"" << F->getCollector() << "\");";
+      Out << "->setGC(\"" << F->getGC() << "\");";
       nl(Out);
     }
     if (is_inline) {
index 2b7e69e..99c1e9f 100644 (file)
@@ -1660,6 +1660,6 @@ bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
   PM.add(createCFGSimplificationPass());
   PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
   PM.add(Writer);
-  PM.add(createCollectorMetadataDeleter());
+  PM.add(createGCInfoDeleter());
   return false;
 }
index a198356..fe82073 100644 (file)
@@ -208,10 +208,10 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
   //  1. If the caller has no GC, then the callee's GC must be propagated to the
   //     caller.
   //  2. If the caller has a differing GC, it is invalid to inline.
-  if (CalledFunc->hasCollector()) {
-    if (!Caller->hasCollector())
-      Caller->setCollector(CalledFunc->getCollector());
-    else if (CalledFunc->getCollector() != Caller->getCollector())
+  if (CalledFunc->hasGC()) {
+    if (!Caller->hasGC())
+      Caller->setGC(CalledFunc->getGC());
+    else if (CalledFunc->getGC() != Caller->getGC())
       return false;
   }
   
index 282f47b..f16ae08 100644 (file)
@@ -1184,8 +1184,8 @@ void AssemblyWriter::printFunction(const Function *F) {
     Out << " section \"" << F->getSection() << '"';
   if (F->getAlignment())
     Out << " align " << F->getAlignment();
-  if (F->hasCollector())
-    Out << " gc \"" << F->getCollector() << '"';
+  if (F->hasGC())
+    Out << " gc \"" << F->getGC() << '"';
 
   if (F->isDeclaration()) {
     Out << "\n";
index bc7137b..8517a41 100644 (file)
@@ -719,17 +719,17 @@ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) {
   return unwrap<Function>(Fn)->setCallingConv(CC);
 }
 
-const char *LLVMGetCollector(LLVMValueRef Fn) {
+const char *LLVMGetGC(LLVMValueRef Fn) {
   Function *F = unwrap<Function>(Fn);
-  return F->hasCollector()? F->getCollector() : 0;
+  return F->hasGC()? F->getGC() : 0;
 }
 
-void LLVMSetCollector(LLVMValueRef Fn, const char *Coll) {
+void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
   Function *F = unwrap<Function>(Fn);
-  if (Coll)
-    F->setCollector(Coll);
+  if (GC)
+    F->setGC(GC);
   else
-    F->clearCollector();
+    F->clearGC();
 }
 
 /*--.. Operations on parameters ............................................--*/
index f819a18..c1a96de 100644 (file)
@@ -182,8 +182,8 @@ Function::~Function() {
   ArgumentList.clear();
   delete SymTab;
 
-  // Remove the function from the on-the-side collector table.
-  clearCollector();
+  // Remove the function from the on-the-side GC table.
+  clearGC();
 }
 
 void Function::BuildLazyArguments() const {
@@ -240,39 +240,39 @@ void Function::removeParamAttr(unsigned i, ParameterAttributes attr) {
   setParamAttrs(PAL);
 }
 
-// Maintain the collector name for each function in an on-the-side table. This
-// saves allocating an additional word in Function for programs which do not use
-// GC (i.e., most programs) at the cost of increased overhead for clients which
-// do use GC.
-static DenseMap<const Function*,PooledStringPtr> *CollectorNames;
-static StringPool *CollectorNamePool;
+// Maintain the GC name for each function in an on-the-side table. This saves
+// allocating an additional word in Function for programs which do not use GC
+// (i.e., most programs) at the cost of increased overhead for clients which do
+// use GC.
+static DenseMap<const Function*,PooledStringPtr> *GCNames;
+static StringPool *GCNamePool;
 
-bool Function::hasCollector() const {
-  return CollectorNames && CollectorNames->count(this);
+bool Function::hasGC() const {
+  return GCNames && GCNames->count(this);
 }
 
-const char *Function::getCollector() const {
-  assert(hasCollector() && "Function has no collector");
-  return *(*CollectorNames)[this];
+const char *Function::getGC() const {
+  assert(hasGC() && "Function has no collector");
+  return *(*GCNames)[this];
 }
 
-void Function::setCollector(const char *Str) {
-  if (!CollectorNamePool)
-    CollectorNamePool = new StringPool();
-  if (!CollectorNames)
-    CollectorNames = new DenseMap<const Function*,PooledStringPtr>();
-  (*CollectorNames)[this] = CollectorNamePool->intern(Str);
+void Function::setGC(const char *Str) {
+  if (!GCNamePool)
+    GCNamePool = new StringPool();
+  if (!GCNames)
+    GCNames = new DenseMap<const Function*,PooledStringPtr>();
+  (*GCNames)[this] = GCNamePool->intern(Str);
 }
 
-void Function::clearCollector() {
-  if (CollectorNames) {
-    CollectorNames->erase(this);
-    if (CollectorNames->empty()) {
-      delete CollectorNames;
-      CollectorNames = 0;
-      if (CollectorNamePool->empty()) {
-        delete CollectorNamePool;
-        CollectorNamePool = 0;
+void Function::clearGC() {
+  if (GCNames) {
+    GCNames->erase(this);
+    if (GCNames->empty()) {
+      delete GCNames;
+      GCNames = 0;
+      if (GCNamePool->empty()) {
+        delete GCNamePool;
+        GCNamePool = 0;
       }
     }
   }
@@ -286,8 +286,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) {
   const Function *SrcF = cast<Function>(Src);
   setCallingConv(SrcF->getCallingConv());
   setParamAttrs(SrcF->getParamAttrs());
-  if (SrcF->hasCollector())
-    setCollector(SrcF->getCollector());
+  if (SrcF->hasGC())
+    setGC(SrcF->getGC());
+  else
+    clearGC();
 }
 
 /// getIntrinsicID - This method returns the ID number of the specified
index b1b413c..fb48814 100644 (file)
@@ -1308,8 +1308,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
         break;
       }
       
-      Assert1(CI.getParent()->getParent()->hasCollector(),
-              "Enclosing function does not specify a collector algorithm.",
+      Assert1(CI.getParent()->getParent()->hasGC(),
+              "Enclosing function does not use GC.",
               &CI);
     } break;
   case Intrinsic::init_trampoline:
index 24846b6..4dc1965 100644 (file)
@@ -569,16 +569,16 @@ let test_functions () =
   insist (CallConv.fast = function_call_conv fn);
   ignore (build_unreachable (builder_at_end (entry_block fn)));
   
-  begin group "collector";
+  begin group "gc";
     (* RUN: grep {Fn6.*gc.*shadowstack} < %t.ll
      *)
     let fn = define_function "Fn6" ty m in
-    insist (None = collector fn);
-    set_collector (Some "ocaml") fn;
-    insist (Some "ocaml" = collector fn);
-    set_collector None fn;
-    insist (None = collector fn);
-    set_collector (Some "shadowstack") fn;
+    insist (None = gc fn);
+    set_gc (Some "ocaml") fn;
+    insist (Some "ocaml" = gc fn);
+    set_gc None fn;
+    insist (None = gc fn);
+    set_gc (Some "shadowstack") fn;
     ignore (build_unreachable (builder_at_end (entry_block fn)));
   end;