summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Henriksen <gordonhenriksen@mac.com>2008-08-17 18:44:35 +0000
committerGordon Henriksen <gordonhenriksen@mac.com>2008-08-17 18:44:35 +0000
commit5eca075b74d62c621b160aa216b4cd50829a2cc7 (patch)
tree5406e0182a3a20726e00eec044bbca1199e673b9
parent94fb5f2a7066c427a9d3dac10a33ccbd02aac467 (diff)
downloadllvm-5eca075b74d62c621b160aa216b4cd50829a2cc7.tar.gz
llvm-5eca075b74d62c621b160aa216b4cd50829a2cc7.tar.bz2
llvm-5eca075b74d62c621b160aa216b4cd50829a2cc7.tar.xz
Rename some GC classes so that their roll will hopefully be clearer.
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
-rw-r--r--bindings/ocaml/llvm/llvm.ml4
-rw-r--r--bindings/ocaml/llvm/llvm.mli12
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c12
-rw-r--r--include/llvm-c/Core.h4
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h2
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h6
-rw-r--r--include/llvm/CodeGen/GCMedataPrinter.h167
-rw-r--r--include/llvm/CodeGen/GCMetadata.h96
-rw-r--r--include/llvm/CodeGen/GCMetadataPrinter.h77
-rw-r--r--include/llvm/CodeGen/GCStrategy.h132
-rw-r--r--include/llvm/CodeGen/GCs.h24
-rw-r--r--include/llvm/CodeGen/LinkAllAsmWriterComponents.h4
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h4
-rw-r--r--include/llvm/CodeGen/Passes.h10
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h6
-rw-r--r--include/llvm/Function.h12
-rw-r--r--lib/AsmParser/llvmAsmParser.y2
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp16
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp20
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp46
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp58
-rw-r--r--lib/CodeGen/GCMetadata.cpp104
-rw-r--r--lib/CodeGen/GCMetadataPrinter.cpp18
-rw-r--r--lib/CodeGen/GCStrategy.cpp107
-rw-r--r--lib/CodeGen/GCs.cpp28
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp8
-rw-r--r--lib/CodeGen/OcamlGC.cpp27
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp35
-rw-r--r--lib/CodeGen/ShadowStackGC.cpp49
-rw-r--r--lib/Target/CBackend/CBackend.cpp2
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp4
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp2
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp8
-rw-r--r--lib/VMCore/AsmWriter.cpp4
-rw-r--r--lib/VMCore/Core.cpp12
-rw-r--r--lib/VMCore/Function.cpp62
-rw-r--r--lib/VMCore/Verifier.cpp4
-rw-r--r--test/Bindings/Ocaml/vmcore.ml14
38 files changed, 524 insertions, 678 deletions
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 67bb2322a5..ded6380549 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -366,8 +366,8 @@ external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic"
external function_call_conv : llvalue -> int = "llvm_function_call_conv"
external set_function_call_conv : int -> llvalue -> unit
= "llvm_set_function_call_conv"
-external collector : llvalue -> string option = "llvm_collector"
-external set_collector : string option -> llvalue -> unit = "llvm_set_collector"
+external gc : llvalue -> string option = "llvm_gc"
+external set_gc : string option -> llvalue -> unit = "llvm_set_gc"
external function_begin : llmodule -> (llmodule, llvalue) llpos
= "llvm_function_begin"
external function_succ : llvalue -> (llmodule, llvalue) llpos
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index 1f4c4a5d6e..fc2919e328 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -921,14 +921,14 @@ external function_call_conv : llvalue -> int = "llvm_function_call_conv"
external set_function_call_conv : int -> llvalue -> unit
= "llvm_set_function_call_conv"
-(** [collector f] returns [Some name] if the function [f] has a garbage
+(** [gc f] returns [Some name] if the function [f] has a garbage
collection algorithm specified and [None] otherwise.
- See the method [llvm::Function::getCollector]. *)
-external collector : llvalue -> string option = "llvm_collector"
+ See the method [llvm::Function::getGC]. *)
+external gc : llvalue -> string option = "llvm_gc"
-(** [set_collector gc f] sets the collection algorithm for the function [f] to
- [gc]. See the method [llvm::Function::setCollector]. *)
-external set_collector : string option -> llvalue -> unit = "llvm_set_collector"
+(** [set_gc gc f] sets the collection algorithm for the function [f] to
+ [gc]. See the method [llvm::Function::setGC]. *)
+external set_gc : string option -> llvalue -> unit = "llvm_set_gc"
(** {7 Operations on params} *)
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index 94bd374594..f09d6cd91c 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -643,13 +643,13 @@ CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
}
/* llvalue -> string option */
-CAMLprim value llvm_collector(LLVMValueRef Fn) {
- const char *Collector;
+CAMLprim value llvm_gc(LLVMValueRef Fn) {
+ const char *GC;
CAMLparam0();
CAMLlocal2(Name, Option);
- if ((Collector = LLVMGetCollector(Fn))) {
- Name = copy_string(Collector);
+ if ((GC = LLVMGetGC(Fn))) {
+ Name = copy_string(GC);
Option = alloc(1, 0);
Field(Option, 0) = Name;
@@ -660,8 +660,8 @@ CAMLprim value llvm_collector(LLVMValueRef Fn) {
}
/* string option -> llvalue -> unit */
-CAMLprim value llvm_set_collector(value GC, LLVMValueRef Fn) {
- LLVMSetCollector(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
+CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
+ LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
return Val_unit;
}
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 7fa91cdb7a..9ff125199f 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -411,8 +411,8 @@ void LLVMDeleteFunction(LLVMValueRef Fn);
unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn);
void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC);
-const char *LLVMGetCollector(LLVMValueRef Fn);
-void LLVMSetCollector(LLVMValueRef Fn, const char *Coll);
+const char *LLVMGetGC(LLVMValueRef Fn);
+void LLVMSetGC(LLVMValueRef Fn, const char *Name);
/* Operations on parameters */
unsigned LLVMCountParams(LLVMValueRef Fn);
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 50af9d5dd6..12607dcd32 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -60,7 +60,7 @@ namespace bitc {
/// MODULE_CODE_PURGEVALS: [numvals]
MODULE_CODE_PURGEVALS = 10,
- MODULE_CODE_COLLECTORNAME = 11 // COLLECTORNAME: [strchr x N]
+ MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N]
};
/// PARAMATTR blocks have code for defining a parameter attribute set.
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 27ea22140d..52921531f2 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -22,7 +22,7 @@
#include <set>
namespace llvm {
- class Collector;
+ class GCStrategy;
class Constant;
class ConstantArray;
class GCMetadataPrinter;
@@ -53,7 +53,7 @@ namespace llvm {
MachineModuleInfo *MMI;
// GCMetadataPrinters - The garbage collection metadata printer table.
- typedef DenseMap<Collector*,GCMetadataPrinter*> gcp_map_type;
+ typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
typedef gcp_map_type::iterator gcp_iterator;
gcp_map_type GCMetadataPrinters;
@@ -366,7 +366,7 @@ namespace llvm {
void EmitXXStructorList(Constant *List);
void EmitConstantPool(unsigned Alignment, const char *Section,
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
- GCMetadataPrinter *GetOrCreateGCPrinter(Collector *C);
+ GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
};
}
diff --git a/include/llvm/CodeGen/GCMedataPrinter.h b/include/llvm/CodeGen/GCMedataPrinter.h
deleted file mode 100644
index 20b470296e..0000000000
--- a/include/llvm/CodeGen/GCMedataPrinter.h
+++ /dev/null
@@ -1,167 +0,0 @@
-//===-- llvm/CodeGen/Collector.h - Garbage collection -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Collector records sufficient information about a machine function to enable
-// accurate garbage collectors. Specifically:
-//
-// - Safe points
-// Garbage collection is only possible at certain points in code. Code
-// generators should record points:
-//
-// - At and after any call to a subroutine
-// - Before returning from the current function
-// - Before backwards branches (loops)
-//
-// - Roots
-// When a reference to a GC-allocated object exists on the stack, it must be
-// stored in an alloca registered with llvm.gcoot.
-//
-// This generic information should used by ABI-specific passes to emit support
-// tables for the runtime garbage collector.
-//
-// MachineCodeAnalysis identifies the GC safe points in the machine code. (Roots
-// are identified in SelectionDAGISel.)
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_COLLECTOR_H
-#define LLVM_CODEGEN_COLLECTOR_H
-
-#include "llvm/CodeGen/CollectorMetadata.h"
-#include <iosfwd>
-#include <string>
-
-namespace llvm {
-
- /// Collector describes a garbage collector's code generation requirements,
- /// and provides overridable hooks for those needs which cannot be abstractly
- /// described.
- class Collector {
- public:
- typedef std::vector<CollectorMetadata*> list_type;
- typedef list_type::iterator iterator;
-
- private:
- friend class CollectorModuleMetadata;
- const Module *M;
- std::string Name;
-
- list_type Functions;
-
- protected:
- unsigned NeededSafePoints; //< Bitmask of required safe points.
- bool CustomReadBarriers; //< Default is to insert loads.
- bool CustomWriteBarriers; //< Default is to insert stores.
- bool CustomRoots; //< Default is to pass through to backend.
- bool InitRoots; //< If set, roots are nulled during lowering.
- bool UsesMetadata; //< If set, backend must emit metadata tables.
-
- public:
- Collector();
-
- virtual ~Collector();
-
-
- /// getName - The name of the collector, for debugging.
- ///
- const std::string &getName() const { return Name; }
-
- /// getModule - The module upon which the collector is operating.
- ///
- const Module &getModule() const { return *M; }
-
- /// True if this collector requires safe points of any kind. By default,
- /// none are recorded.
- bool needsSafePoints() const { return NeededSafePoints != 0; }
-
- /// True if the collector requires the given kind of safe point. By default,
- /// none are recorded.
- bool needsSafePoint(GC::PointKind Kind) const {
- return (NeededSafePoints & 1 << Kind) != 0;
- }
-
- /// By default, write barriers are replaced with simple store instructions.
- /// If true, then addPassesToCustomLowerIntrinsics must instead process
- /// them.
- bool customWriteBarrier() const { return CustomWriteBarriers; }
-
- /// By default, read barriers are replaced with simple load instructions.
- /// If true, then addPassesToCustomLowerIntrinsics must instead process
- /// them.
- bool customReadBarrier() const { return CustomReadBarriers; }
-
- /// By default, roots are left for the code generator. If Custom, then
- /// addPassesToCustomLowerIntrinsics must add passes to delete them.
- bool customRoots() const { return CustomRoots; }
-
- /// If set, gcroot intrinsics should initialize their allocas to null. This
- /// is necessary for most collectors.
- bool initializeRoots() const { return InitRoots; }
-
- /// If set, appropriate metadata tables must be emitted by the back-end
- /// (assembler, JIT, or otherwise).
- bool usesMetadata() const { return UsesMetadata; }
-
- /// begin/end - Iterators for function metadata.
- ///
- iterator begin() { return Functions.begin(); }
- iterator end() { return Functions.end(); }
-
- /// insertFunctionMetadata - Creates metadata for a function.
- ///
- CollectorMetadata *insertFunctionMetadata(const Function &F);
-
- /// initializeCustomLowering/performCustomLowering - If any of the actions
- /// are set to custom, performCustomLowering must be overriden to create a
- /// transform to lower those actions to LLVM IR. initializeCustomLowering
- /// is optional to override. These are the only Collector methods through
- /// which the LLVM IR can be modified.
- virtual bool initializeCustomLowering(Module &F);
- virtual bool performCustomLowering(Function &F);
- };
-
- // GCMetadataPrinter - Emits GC metadata as assembly code.
- class GCMetadataPrinter {
- public:
- typedef Collector::list_type list_type;
- typedef Collector::iterator iterator;
-
- private:
- Collector *Coll;
-
- friend class AsmPrinter;
-
- protected:
- // May only be subclassed.
- GCMetadataPrinter();
-
- // Do not implement.
- GCMetadataPrinter(const GCMetadataPrinter &);
- GCMetadataPrinter &operator=(const GCMetadataPrinter &);
-
- public:
- Collector &getCollector() { return *Coll; }
- const Module &getModule() const { return Coll->getModule(); }
-
- iterator begin() { return Coll->begin(); }
- iterator end() { return Coll->end(); }
-
- /// beginAssembly/finishAssembly - Emit module metadata as assembly code.
- virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP,
- const TargetAsmInfo &TAI);
-
- virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP,
- const TargetAsmInfo &TAI);
-
- virtual ~GCMetadataPrinter();
- };
-
-}
-
-#endif
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 1fb3b502ee..e94aba388a 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -1,4 +1,4 @@
-//===-- CollectorMetadata.h - Garbage collector metadata ------------------===//
+//===-- GCMetadata.h - Garbage collector metadata -------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,33 +7,31 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares the CollectorMetadata and CollectorModuleMetadata classes,
-// which are used as a communication channel from the target code generator
-// to the target garbage collectors. This interface allows code generators and
-// garbage collectors to be developed independently.
+// This file declares the GCFunctionInfo and GCModuleInfo classes, which are
+// used as a communication channel from the target code generator to the target
+// garbage collectors. This interface allows code generators and garbage
+// collectors to be developed independently.
//
-// The CollectorMetadata class records the data necessary to build a type
-// accurate stack map. Roots are specified in the LLVM IR using the llvm.gcroot
-// intrinsic, which the code generator understands. The code generator records
-// the stack offset for each GC root. Safe points are generated by the code
-// generator according to the collector's declared needs (generally at function
-// calls).
+// The GCFunctionInfo class logs the data necessary to build a type accurate
+// stack map. The code generator outputs:
+//
+// - Safe points as specified by the GCStrategy's NeededSafePoints.
+// - Stack offsets for GC roots, as specified by calls to llvm.gcroot
//
-// Safe points and roots are sufficient to build type-accurate stack maps. As a
-// refinement, liveness analysis calculates the set of live roots at each safe
-// point. Liveness analysis is not presently performed, so all roots are assumed
-// live.
+// As a refinement, liveness analysis calculates the set of live roots at each
+// safe point. Liveness analysis is not presently performed by the code
+// generator, so all roots are assumed live.
//
-// CollectorModuleMetadata simply collects CollectorMetadata structures for each
-// Function as it is compiled. This is necessary for collectors which must emit
-// a stack map for the entire compilation unit. CollectorMetadata outlives the
-// MachineFunction from which it is derived, so must not refer to any code
-// generator data structures.
+// GCModuleInfo simply collects GCFunctionInfo instances for each Function as
+// they are compiled. This accretion is necessary for collectors which must emit
+// a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo
+// outlives the MachineFunction from which it is derived and must not refer to
+// any code generator data structures.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_COLLECTORMETADATA_H
-#define LLVM_CODEGEN_COLLECTORMETADATA_H
+#ifndef LLVM_CODEGEN_GCMETADATA_H
+#define LLVM_CODEGEN_GCMETADATA_H
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
@@ -42,7 +40,7 @@
namespace llvm {
class AsmPrinter;
- class Collector;
+ class GCStrategy;
class Constant;
class TargetAsmInfo;
@@ -78,9 +76,9 @@ namespace llvm {
};
- /// CollectorMetadata - Garbage collection metadata for a function.
+ /// GCFunctionInfo - Garbage collection metadata for a single function.
///
- class CollectorMetadata {
+ class GCFunctionInfo {
public:
typedef std::vector<GCPoint>::iterator iterator;
typedef std::vector<GCRoot>::iterator roots_iterator;
@@ -88,7 +86,7 @@ namespace llvm {
private:
const Function &F;
- Collector &C;
+ GCStrategy &S;
uint64_t FrameSize;
std::vector<GCRoot> Roots;
std::vector<GCPoint> SafePoints;
@@ -104,20 +102,20 @@ namespace llvm {
// are live per safe point (1.5% on 64-bit hosts).
public:
- CollectorMetadata(const Function &F, Collector &C);
- ~CollectorMetadata();
+ GCFunctionInfo(const Function &F, GCStrategy &S);
+ ~GCFunctionInfo();
/// getFunction - Return the function to which this metadata applies.
///
const Function &getFunction() const { return F; }
- /// getCollector - Return the collector for the function.
+ /// getStrategy - Return the GC strategy for the function.
///
- Collector &getCollector() { return C; }
+ GCStrategy &getStrategy() { return S; }
/// addStackRoot - Registers a root that lives on the stack. Num is the
- /// stack object ID for the alloca (if the code generator is using
- /// MachineFrameInfo).
+ /// stack object ID for the alloca (if the code generator is
+ // using MachineFrameInfo).
void addStackRoot(int Num, Constant *Metadata) {
Roots.push_back(GCRoot(Num, Metadata));
}
@@ -154,39 +152,39 @@ namespace llvm {
};
- /// CollectorModuleMetadata - Garbage collection metadata for a whole module.
+ /// GCModuleInfo - Garbage collection metadata for a whole module.
///
- class CollectorModuleMetadata : public ImmutablePass {
- typedef StringMap<Collector*> collector_map_type;
- typedef std::vector<Collector*> list_type;
- typedef DenseMap<const Function*,CollectorMetadata*> function_map_type;
+ class GCModuleInfo : public ImmutablePass {
+ typedef StringMap<GCStrategy*> strategy_map_type;
+ typedef std::vector<GCStrategy*> list_type;
+ typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
- collector_map_type NameMap;
- list_type Collectors;
- function_map_type Map;
+ strategy_map_type StrategyMap;
+ list_type StrategyList;
+ finfo_map_type FInfoMap;
- Collector *getOrCreateCollector(const Module *M, const std::string &Name);
+ GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);
public:
typedef list_type::const_iterator iterator;
static char ID;
- CollectorModuleMetadata();
- ~CollectorModuleMetadata();
+ GCModuleInfo();
+ ~GCModuleInfo();
- /// clear - Used to delete module metadata. The metadata deleter pass calls
- /// this.
+ /// clear - Resets the pass. The metadata deleter pass calls this.
+ ///
void clear();
- /// begin/end - Iterators for collectors.
+ /// begin/end - Iterators for used strategies.
///
- iterator begin() const { return Collectors.begin(); }
- iterator end() const { return Collectors.end(); }
+ iterator begin() const { return StrategyList.begin(); }
+ iterator end() const { return StrategyList.end(); }
/// get - Look up function metadata.
///
- CollectorMetadata &get(const Function &F);
+ GCFunctionInfo &getFunctionInfo(const Function &F);
};
}
diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h
new file mode 100644
index 0000000000..1ab138adec
--- /dev/null
+++ b/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -0,0 +1,77 @@
+//===-- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The abstract base class GCMetadataPrinter supports writing GC metadata tables
+// as assembly code. This is a separate class from GCStrategy in order to allow
+// users of the LLVM JIT to avoid linking with the AsmWriter.
+//
+// Subclasses of GCMetadataPrinter must be registered using the
+// GCMetadataPrinterRegistry. This is separate from the GCStrategy itself
+// because these subclasses are logically plugins for the AsmWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCMETADATAPRINTER_H
+#define LLVM_CODEGEN_GCMETADATAPRINTER_H
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/Support/Registry.h"
+#include <iosfwd>
+#include <string>
+
+namespace llvm {
+
+ class GCMetadataPrinter;
+
+ /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
+ /// defaults from Registry.
+ typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
+
+ /// GCMetadataPrinter - Emits GC metadata as assembly code.
+ ///
+ class GCMetadataPrinter {
+ public:
+ typedef GCStrategy::list_type list_type;
+ typedef GCStrategy::iterator iterator;
+
+ private:
+ GCStrategy *S;
+
+ friend class AsmPrinter;
+
+ protected:
+ // May only be subclassed.
+ GCMetadataPrinter();
+
+ // Do not implement.
+ GCMetadataPrinter(const GCMetadataPrinter &);
+ GCMetadataPrinter &operator=(const GCMetadataPrinter &);
+
+ public:
+ GCStrategy &getStrategy() { return *S; }
+ const Module &getModule() const { return S->getModule(); }
+
+ /// begin/end - Iterate over the collected function metadata.
+ iterator begin() { return S->begin(); }
+ iterator end() { return S->end(); }
+
+ /// beginAssembly/finishAssembly - Emit module metadata as assembly code.
+ virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP,
+ const TargetAsmInfo &TAI);
+
+ virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP,
+ const TargetAsmInfo &TAI);
+
+ virtual ~GCMetadataPrinter();
+ };
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h
index dea0785ef8..80249bc29d 100644
--- a/include/llvm/CodeGen/GCStrategy.h
+++ b/include/llvm/CodeGen/GCStrategy.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/Collector.h - Garbage collection -----------*- C++ -*-===//
+//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,18 @@
//
//===----------------------------------------------------------------------===//
//
-// Collector records sufficient information about a machine function to enable
-// accurate garbage collectors. Specifically:
+// GCStrategy coordinates code generation algorithms and implements some itself
+// in order to generate code compatible with a target code generator as
+// specified in a function's 'gc' attribute. Algorithms are enabled by setting
+// flags in a subclass's constructor, and some virtual methods can be
+// overridden.
+//
+// When requested, the GCStrategy will be populated with data about each
+// function which uses it. Specifically:
//
// - Safe points
-// Garbage collection is only possible at certain points in code. Code
-// generators should record points:
+// Garbage collection is generally only possible at certain points in code.
+// GCStrategy can request that the collector insert such points:
//
// - At and after any call to a subroutine
// - Before returning from the current function
@@ -22,33 +28,37 @@
// When a reference to a GC-allocated object exists on the stack, it must be
// stored in an alloca registered with llvm.gcoot.
//
-// This generic information should used by ABI-specific passes to emit support
-// tables for the runtime garbage collector.
-//
-// MachineCodeAnalysis identifies the GC safe points in the machine code. (Roots
-// are identified in SelectionDAGISel.)
+// This information can used to emit the metadata tables which are required by
+// the target garbage collector runtime.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_COLLECTOR_H
-#define LLVM_CODEGEN_COLLECTOR_H
+#ifndef LLVM_CODEGEN_GCSTRATEGY_H
+#define LLVM_CODEGEN_GCSTRATEGY_H
#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/Support/Registry.h"
#include <iosfwd>
#include <string>
namespace llvm {
- /// Collector describes a garbage collector's code generation requirements,
- /// and provides overridable hooks for those needs which cannot be abstractly
- /// described.
- class Collector {
+ class GCStrategy;
+
+ /// The GC strategy registry uses all the defaults from Registry.
+ ///
+ typedef Registry<GCStrategy> GCRegistry;
+
+ /// GCStrategy describes a garbage collector algorithm's code generation
+ /// requirements, and provides overridable hooks for those needs which cannot
+ /// be abstractly described.
+ class GCStrategy {
public:
- typedef std::vector<CollectorMetadata*> list_type;
+ typedef std::vector<GCFunctionInfo*> list_type;
typedef list_type::iterator iterator;
private:
- friend class CollectorModuleMetadata;
+ friend class GCModuleInfo;
const Module *M;
std::string Name;
@@ -63,49 +73,51 @@ namespace llvm {
bool UsesMetadata; //< If set, backend must emit metadata tables.
public:
- Collector();
+ GCStrategy();
- virtual ~Collector();
+ virtual ~GCStrategy();
- /// getName - The name of the collector, for debugging.
+ /// getName - The name of the GC strategy, for debugging.
///
const std::string &getName() const { return Name; }
- /// getModule - The module upon which the collector is operating.
+ /// getModule - The module within which the GC strategy is operating.
///
const Module &getModule() const { return *M; }
- /// True if this collector requires safe points of any kind. By default,
- /// none are recorded.
+ /// needsSafePoitns - True if safe points of any kind are required. By
+ // default, none are recorded.
bool needsSafePoints() const { return NeededSafePoints != 0; }
- /// True if the collector requires the given kind of safe point. By default,
- /// none are recorded.
+ /// needsSafePoint(Kind) - True if the given kind of safe point is
+ // required. By default, none are recorded.
bool needsSafePoint(GC::PointKind Kind) const {
return (NeededSafePoints & 1 << Kind) != 0;
}
- /// By default, write barriers are replaced with simple store instructions.
- /// If true, then addPassesToCustomLowerIntrinsics must instead process
- /// them.
+ /// customWriteBarrier - By default, write barriers are replaced with simple
+ /// store instructions. If true, then
+ /// performCustomLowering must instead lower them.
bool customWriteBarrier() 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
diff --git a/include/llvm/CodeGen/GCs.h b/include/llvm/CodeGen/GCs.h
index 7850ddcd82..c407b61674 100644
--- a/include/llvm/CodeGen/GCs.h
+++ b/include/llvm/CodeGen/GCs.h
@@ -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
diff --git a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index 0dc94ea4a8..a1ba565d5d 100644
--- a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -20,14 +20,14 @@
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.
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 2fb01bfefc..9ee22d4926 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -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);
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 412e9e3ad8..ff1f505902 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -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.
///
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 7471039477..77e75c0d86 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -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; }
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
index 9954418ab8..04e0535ace 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/Function.h
@@ -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 {
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 9f317d8703..d9b8499442 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -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;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index f7796a6f9f..a842bd3643 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -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);
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 2c585b1370..b5fb60778a 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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);
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index de31840d70..380b3bc214 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -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();
}
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index efa7f67276..42f1a0fe92 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -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");
}
diff --git a/lib/CodeGen/GCMetadata.cpp b/lib/CodeGen/GCMetadata.cpp
index 0b5c6f0662..efb89e128e 100644
--- a/lib/CodeGen/GCMetadata.cpp
+++ b/lib/CodeGen/GCMetadata.cpp
@@ -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;
}
diff --git a/lib/CodeGen/GCMetadataPrinter.cpp b/lib/CodeGen/GCMetadataPrinter.cpp
index b16d873520..07ec0bd035 100644
--- a/lib/CodeGen/GCMetadataPrinter.cpp
+++ b/lib/CodeGen/GCMetadataPrinter.cpp
@@ -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() { }
diff --git a/lib/CodeGen/GCStrategy.cpp b/lib/CodeGen/GCStrategy.cpp
index f5cb9ab631..2666775996 100644
--- a/lib/CodeGen/GCStrategy.cpp
+++ b/lib/CodeGen/GCStrategy.cpp
@@ -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
index 124725358e..0000000000
--- a/lib/CodeGen/GCs.cpp
+++ /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;
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index d420ffb7d9..938e1ae9cc 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -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());
diff --git a/lib/CodeGen/OcamlGC.cpp b/lib/CodeGen/OcamlGC.cpp
index 88499cbd66..0b90444406 100644
--- a/lib/CodeGen/OcamlGC.cpp
+++ b/lib/CodeGen/OcamlGC.cpp
@@ -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;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 012e7d0992..f4e31f727e 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -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;
diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp
index 850c00542c..cf0e6ddbae 100644
--- a/lib/CodeGen/ShadowStackGC.cpp
+++ b/lib/CodeGen/ShadowStackGC.cpp
@@ -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);
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 0017eb936d..2661b1b39c 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -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;
}
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index ce86452737..b359659bcd 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -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) {
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index 2b7e69e4de..99c1e9f4c9 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -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;
}
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index a198356fd2..fe82073442 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -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;
}
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 282f47bec1..f16ae08ef1 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -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";
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index bc7137b9d0..8517a41d7c 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -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 ............................................--*/
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index f819a18e1e..c1a96de0a7 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -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
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index b1b413c68b..fb48814c00 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -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:
diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml
index 24846b68bb..4dc196579b 100644
--- a/test/Bindings/Ocaml/vmcore.ml
+++ b/test/Bindings/Ocaml/vmcore.ml
@@ -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;