OSDN Git Service

Move ownership of GCStrategy objects to LLVMContext
authorPhilip Reames <listmail@philipreames.com>
Fri, 16 Jan 2015 20:07:33 +0000 (20:07 +0000)
committerPhilip Reames <listmail@philipreames.com>
Fri, 16 Jan 2015 20:07:33 +0000 (20:07 +0000)
Note: This change ended up being slightly more controversial than expected.  Chandler has tentatively okayed this for the moment, but I may be revisiting this in the near future after we settle some high level questions.

Rather than have the GCStrategy object owned by the GCModuleInfo - which is an immutable analysis pass used mainly by gc.root - have it be owned by the LLVMContext. This simplifies the ownership logic (i.e. can you have two instances of the same strategy at once?), but more importantly, allows us to access the GCStrategy in the middle end optimizer. To this end, I add an accessor through Function which becomes the canonical way to get at a GCStrategy instance.

In the near future, this will allows me to move some of the checks from http://reviews.llvm.org/D6808 into the Verifier itself, and to introduce optimization legality predicates for some of the recent additions to InstCombine. (These will follow as separate changes.)

Differential Revision: http://reviews.llvm.org/D6811

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

21 files changed:
include/llvm/CodeGen/GCMetadata.h
include/llvm/CodeGen/GCMetadataPrinter.h
include/llvm/IR/Function.h
include/llvm/IR/GCStrategy.h [moved from include/llvm/CodeGen/GCStrategy.h with 90% similarity]
include/llvm/Support/Registry.h
lib/CodeGen/CMakeLists.txt
lib/CodeGen/ErlangGC.cpp
lib/CodeGen/GCMetadata.cpp
lib/CodeGen/GCRootLowering.cpp
lib/CodeGen/OcamlGC.cpp
lib/CodeGen/Passes.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/CodeGen/SelectionDAG/StatepointLowering.cpp
lib/CodeGen/ShadowStackGC.cpp
lib/CodeGen/StatepointExampleGC.cpp
lib/IR/CMakeLists.txt
lib/IR/Function.cpp
lib/IR/GCStrategy.cpp [moved from lib/CodeGen/GCStrategy.cpp with 95% similarity]
lib/IR/LLVMContextImpl.cpp
lib/IR/LLVMContextImpl.h

index c7f1ab8..6922b70 100644 (file)
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/Pass.h"
 #include <memory>
 
 namespace llvm {
   class AsmPrinter;
-  class GCStrategy;
   class Constant;
   class MCSymbol;
 
-  namespace GC {
-    /// PointKind - The type of a collector-safe point.
-    ///
-    enum PointKind {
-      Loop,    ///< Instr is a loop (backwards branch).
-      Return,  ///< Instr is a return instruction.
-      PreCall, ///< Instr is a call instruction.
-      PostCall ///< Instr is the return address of a call.
-    };
-  }
-
   /// GCPoint - Metadata for a collector-safe point in machine code.
   ///
   struct GCPoint {
@@ -163,14 +152,9 @@ namespace llvm {
   /// Records both the function level information used by GCRoots and a
   /// cache of the 'active' gc strategy objects for the current Module.
   class GCModuleInfo : public ImmutablePass {
-    typedef StringMap<GCStrategy*> strategy_map_type;
-    typedef std::vector<std::unique_ptr<GCStrategy>> list_type;
-
-    strategy_map_type StrategyMap;
-    list_type StrategyList;
-
-    GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);
-
+    /// A list of GCStrategies which are active in this Module.  These are
+    /// not owning pointers.
+    std::vector<GCStrategy*> StrategyList;
   public:
     /// List of per function info objects.  In theory, Each of these
     /// may be associated with a different GC.
@@ -190,7 +174,7 @@ namespace llvm {
     finfo_map_type FInfoMap;
   public:
 
-    typedef list_type::const_iterator iterator;
+    typedef std::vector<GCStrategy*>::const_iterator iterator;
 
     static char ID;
 
index 25fafba..6010cb8 100644 (file)
@@ -21,7 +21,7 @@
 #define LLVM_CODEGEN_GCMETADATAPRINTER_H
 
 #include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/Support/Registry.h"
 
 namespace llvm {
index 5140328..e9d0806 100644 (file)
@@ -29,6 +29,7 @@
 namespace llvm {
 
 class FunctionType;
+class GCStrategy;  
 class LLVMContext;
 
 // Traits for intrusive list of basic blocks...
@@ -225,6 +226,10 @@ public:
   void setGC(const char *Str);
   void clearGC();
 
+  /// Returns the GCStrategy associated with the specified garbage collector
+  /// algorithm or nullptr if one is not set.
+  GCStrategy *getGCStrategy() const;
+
   /// @brief adds the attribute to the list of attributes.
   void addAttribute(unsigned i, Attribute::AttrKind attr);
 
similarity index 90%
rename from include/llvm/CodeGen/GCStrategy.h
rename to include/llvm/IR/GCStrategy.h
index bdd1446..1cd107b 100644 (file)
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
+//===-- llvm/IR/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CODEGEN_GCSTRATEGY_H
-#define LLVM_CODEGEN_GCSTRATEGY_H
+#ifndef LLVM_IR_GCSTRATEGY_H
+#define LLVM_IR_GCSTRATEGY_H
 
 #include "llvm/ADT/Optional.h"
-#include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/Value.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Registry.h"
 #include <string>
 
 namespace llvm {
+  namespace GC {
+    /// PointKind - The type of a collector-safe point.
+    ///
+    enum PointKind {
+      Loop,    ///< Instr is a loop (backwards branch).
+      Return,  ///< Instr is a return instruction.
+      PreCall, ///< Instr is a call instruction.
+      PostCall ///< Instr is the return address of a call.
+    };
+  }
+
+  
   /// GCStrategy describes a garbage collector algorithm's code generation
   /// requirements, and provides overridable hooks for those needs which cannot
-  /// be abstractly described.  GCStrategy objects currently must be looked up
-  /// through the GCModuleInfo analysis pass.  They are owned by the analysis
-  /// pass and recreated every time that pass is invalidated.
+  /// be abstractly described.  GCStrategy objects must be looked up through
+  /// the Function.  The objects themselves are owned by the Context and must
+  /// be immutable.
   class GCStrategy {
   private:
     std::string Name;
-    friend class GCModuleInfo;
+    friend class LLVMContextImpl;
     
   protected:
     bool UseStatepoints;       /// Uses gc.statepoints as opposed to gc.roots,
index e21269b..51db8cf 100644 (file)
@@ -120,6 +120,10 @@ namespace llvm {
     static iterator begin() { return iterator(Head); }
     static iterator end()   { return iterator(nullptr); }
 
+    static iterator_range<iterator> entries() {
+      return iterator_range<iterator>(begin(), end());
+    }
+
 
     /// Abstract base class for registry listeners, which are informed when new
     /// entries are added to the registry. Simply subclass and instantiate:
index f0b2dfe..7f7f522 100644 (file)
@@ -23,7 +23,6 @@ add_llvm_library(LLVMCodeGen
   GCMetadata.cpp
   GCMetadataPrinter.cpp
   GCRootLowering.cpp
-  GCStrategy.cpp
   GlobalMerge.cpp
   IfConversion.cpp
   InlineSpiller.cpp
index 5f2b3a0..ec2c2e8 100644 (file)
@@ -15,8 +15,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCs.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Target/TargetInstrInfo.h"
index 6101c67..6f4fa11 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
@@ -61,27 +61,6 @@ GCModuleInfo::GCModuleInfo()
   initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
 }
 
-GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
-                                              const std::string &Name) {
-  strategy_map_type::iterator NMI = StrategyMap.find(Name);
-  if (NMI != StrategyMap.end())
-    return NMI->getValue();
-  
-  for (GCRegistry::iterator I = GCRegistry::begin(),
-                            E = GCRegistry::end(); I != E; ++I) {
-    if (Name == I->getName()) {
-      std::unique_ptr<GCStrategy> S = I->instantiate();
-      S->Name = Name;
-      StrategyMap[Name] = S.get();
-      StrategyList.push_back(std::move(S));
-      return StrategyList.back().get();
-    }
-  }
-  dbgs() << "unsupported GC: " << Name << "\n";
-  llvm_unreachable(nullptr);
-}
-
 GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
   assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
   assert(F.hasGC());
@@ -90,7 +69,15 @@ GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
   if (I != FInfoMap.end())
     return *I->second;
   
-  GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
+  GCStrategy *S = F.getGCStrategy();
+  if (!S) {
+    std::string error = std::string("unsupported GC: ") + F.getGC();
+    report_fatal_error(error);
+  }
+  // Save the fact this strategy is associated with this module.  Note that
+  // these are non-owning references, the GCStrategy remains owned by the
+  // Context. 
+  StrategyList.push_back(S);
   Functions.push_back(make_unique<GCFunctionInfo>(F, *S));
   GCFunctionInfo *GFI = Functions.back().get();
   FInfoMap[&F] = GFI;
@@ -100,7 +87,6 @@ GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
 void GCModuleInfo::clear() {
   Functions.clear();
   FInfoMap.clear();
-  StrategyMap.clear();
   StrategyList.clear();
 }
 
index 9bda7b8..8ff08ec 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/Dominators.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
index 48db200..c5c7852 100644 (file)
@@ -15,7 +15,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCs.h"
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/IR/GCStrategy.h"
 
 using namespace llvm;
 
index 28e9f84..88cee03 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/Analysis/Passes.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/IR/IRPrintingPasses.h"
index 6b3ad5f..a8db35c 100644 (file)
@@ -26,7 +26,6 @@
 #include "llvm/CodeGen/FastISel.h"
 #include "llvm/CodeGen/FunctionLoweringInfo.h"
 #include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -41,6 +40,7 @@
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
index 7ee06fc..6a0a079 100644 (file)
@@ -24,7 +24,6 @@
 #include "llvm/CodeGen/FastISel.h"
 #include "llvm/CodeGen/FunctionLoweringInfo.h"
 #include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -36,6 +35,7 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
index 33c20d3..94f09bd 100644 (file)
 #include "SelectionDAGBuilder.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/FunctionLoweringInfo.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/StackMaps.h"
 #include "llvm/IR/CallingConv.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
index 0be00f0..181cb8c 100644 (file)
@@ -27,8 +27,8 @@
 
 #include "llvm/CodeGen/GCs.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/IR/CallSite.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
index 09b74ca..e20b270 100644 (file)
@@ -16,7 +16,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Value.h"
 
index 1a210e0..621c7ca 100644 (file)
@@ -17,6 +17,7 @@ add_llvm_library(LLVMCore
   Dominators.cpp
   Function.cpp
   GCOV.cpp
+  GCStrategy.cpp
   GVMaterializer.cpp
   Globals.cpp
   IRBuilder.cpp
index 070513e..ddfbaf7 100644 (file)
@@ -386,6 +386,12 @@ void Function::clearGC() {
   }
 }
 
+GCStrategy *Function::getGCStrategy() const {
+  // Lookup the GCStrategy (which is owned by the Context), given the name of
+  // the GC in question.
+  return getContext().pImpl->getGCStrategy(getGC());
+}
+
 /// copyAttributesFrom - copy all additional attributes (those not needed to
 /// create a Function) from the Function Src to this one.
 void Function::copyAttributesFrom(const GlobalValue *Src) {
similarity index 95%
rename from lib/CodeGen/GCStrategy.cpp
rename to lib/IR/GCStrategy.cpp
index 2b687d9..18723a0 100644 (file)
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/IR/GCStrategy.h"
 
 using namespace llvm;
 
index 01a0e6c..01a786d 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/GCStrategy.h"
 #include "llvm/IR/Module.h"
 #include <algorithm>
 using namespace llvm;
@@ -182,3 +183,26 @@ void InsertValueConstantExpr::anchor() { }
 void GetElementPtrConstantExpr::anchor() { }
 
 void CompareConstantExpr::anchor() { }
+
+GCStrategy *LLVMContextImpl::getGCStrategy(const StringRef Name) {
+  // TODO: Arguably, just doing a linear search would be faster for small N
+  auto NMI = GCStrategyMap.find(Name);
+  if (NMI != GCStrategyMap.end())
+    return NMI->getValue();
+  
+  for (auto& Entry : GCRegistry::entries()) {
+    if (Name == Entry.getName()) {
+      std::unique_ptr<GCStrategy> S = Entry.instantiate();
+      S->Name = Name;
+      GCStrategyMap[Name] = S.get();
+      GCStrategyList.push_back(std::move(S));
+      return GCStrategyList.back().get();
+    }
+  }
+
+  // No GCStrategy found for that name, error reporting is the job of our
+  // callers. 
+  return nullptr;
+}
+
+
index 6ebc567..45f8609 100644 (file)
@@ -41,6 +41,7 @@ class ConstantFP;
 class DiagnosticInfoOptimizationRemark;
 class DiagnosticInfoOptimizationRemarkMissed;
 class DiagnosticInfoOptimizationRemarkAnalysis;
+class GCStrategy;
 class LLVMContext;
 class Type;
 class Value;
@@ -389,6 +390,17 @@ public:
 
   int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
   int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
+
+  /// An owning list of all GCStrategies which have been created
+  SmallVector<std::unique_ptr<GCStrategy>, 1> GCStrategyList;
+  /// A helper map to speedup lookups into the above list
+  StringMap<GCStrategy*> GCStrategyMap;
+
+  /// Lookup the GCStrategy object associated with the given gc name.  If one
+  /// can't be found, returns nullptr.  The lifetime of the returned objects
+  /// is dictated by the lifetime of the associated context.  No caller should
+  /// attempt to delete the returned objects.
+  GCStrategy *getGCStrategy(const StringRef Name);
   
   LLVMContextImpl(LLVMContext &C);
   ~LLVMContextImpl();