Revert GCStrategy ownership changes

This change reverts the interesting parts of 226311 (and 227046).  This change introduced two problems, and I've been convinced that an alternate approach is preferrable anyways.

The bugs were:
- Registery appears to require all users be within the same linkage unit.  After this change, asking for "statepoint-example" in Transform/ would sometimes get you nullptr, whereas asking the same question in CodeGen would return the right GCStrategy.  The correct long term fix is to get rid of the utter hack which is Registry, but I don't have time for that right now.  227046 appears to have been an attempt to fix this, but I don't believe it does so completely.
- GCMetadataPrinter::finishAssembly was being called more than once per GCStrategy.  Each Strategy was being added to the GCModuleInfo multiple times.

Once I get time again, I'm going to split GCModuleInfo into the gc.root specific part and a GCStrategy owning Analysis pass.  I'm probably also going to kill off the Registry.  Once that's done, I'll move the new GCStrategyAnalysis and all built in GCStrategies into Analysis.  (As original suggested by Chandler.)  This will accomplish my original goal of being able to access GCStrategy from Transform/  without adding all of the builtin GCs to IR/.  

llvm-svn: 227109
diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index 19aa0b0..357b2d8 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -34,9 +34,10 @@
 #define LLVM_CODEGEN_GCMETADATA_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/GCStrategy.h"
 #include "llvm/Pass.h"
 #include <memory>
 
@@ -151,11 +152,17 @@
 /// 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 {
-  /// A list of GCStrategies which are active in this Module.  These are
-  /// not owning pointers.
-  std::vector<GCStrategy *> StrategyList;
+  /// 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;
 
 public:
+  /// Lookup the GCStrategy object associated with the given gc name.
+  /// Objects are owned internally; No caller should attempt to delete the
+  /// returned objects. 
+  GCStrategy *getGCStrategy(const StringRef Name);
+  
   /// List of per function info objects.  In theory, Each of these
   /// may be associated with a different GC.
   typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec;
@@ -173,7 +180,7 @@
   finfo_map_type FInfoMap;
 
 public:
-  typedef std::vector<GCStrategy *>::const_iterator iterator;
+  typedef SmallVector<std::unique_ptr<GCStrategy>,1>::const_iterator iterator;
 
   static char ID;
 
@@ -186,8 +193,8 @@
 
   /// begin/end - Iterators for used strategies.
   ///
-  iterator begin() const { return StrategyList.begin(); }
-  iterator end() const { return StrategyList.end(); }
+  iterator begin() const { return GCStrategyList.begin(); }
+  iterator end() const { return GCStrategyList.end(); }
 
   /// get - Look up function metadata.  This is currently assumed
   /// have the side effect of initializing the associated GCStrategy.  That
diff --git a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index 3e7d64c..e07bb24 100644
--- a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -21,7 +21,7 @@
 #define LLVM_CODEGEN_GCMETADATAPRINTER_H
 
 #include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/IR/GCStrategy.h"
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/Support/Registry.h"
 
 namespace llvm {
diff --git a/llvm/include/llvm/IR/GCStrategy.h b/llvm/include/llvm/CodeGen/GCStrategy.h
similarity index 97%
rename from llvm/include/llvm/IR/GCStrategy.h
rename to llvm/include/llvm/CodeGen/GCStrategy.h
index c9b0a84..fbf4eac 100644
--- a/llvm/include/llvm/IR/GCStrategy.h
+++ b/llvm/include/llvm/CodeGen/GCStrategy.h
@@ -1,4 +1,4 @@
-//===-- llvm/IR/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
+//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -78,7 +78,7 @@
 class GCStrategy {
 private:
   std::string Name;
-  friend class LLVMContextImpl;
+  friend class GCModuleInfo;
 
 protected:
   bool UseStatepoints; /// Uses gc.statepoints as opposed to gc.roots,
@@ -188,9 +188,6 @@
 /// register your GCMetadataPrinter subclass with the
 /// GCMetadataPrinterRegistery as well.
 typedef Registry<GCStrategy> GCRegistry;
-
-/// GCStrategy is instantiated in GCStrategy.cpp.
-extern template class Registry<GCStrategy>;
 }
 
 #endif
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index e9d0806..5140328 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -29,7 +29,6 @@
 namespace llvm {
 
 class FunctionType;
-class GCStrategy;  
 class LLVMContext;
 
 // Traits for intrusive list of basic blocks...
@@ -226,10 +225,6 @@
   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);
 
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 7f7f522..f0b2dfe 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -23,6 +23,7 @@
   GCMetadata.cpp
   GCMetadataPrinter.cpp
   GCRootLowering.cpp
+  GCStrategy.cpp
   GlobalMerge.cpp
   IfConversion.cpp
   InlineSpiller.cpp
diff --git a/llvm/lib/CodeGen/ErlangGC.cpp b/llvm/lib/CodeGen/ErlangGC.cpp
index 30af07f..a40bbb5 100644
--- a/llvm/lib/CodeGen/ErlangGC.cpp
+++ b/llvm/lib/CodeGen/ErlangGC.cpp
@@ -16,7 +16,7 @@
 
 #include "llvm/CodeGen/GCs.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/IR/GCStrategy.h"
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Target/TargetInstrInfo.h"
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index 7a61d61..ab8383a 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -14,8 +14,8 @@
 #include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/GCStrategy.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"
@@ -66,15 +66,7 @@
   if (I != FInfoMap.end())
     return *I->second;
 
-  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);
+  GCStrategy *S = getGCStrategy(F.getGC());
   Functions.push_back(make_unique<GCFunctionInfo>(F, *S));
   GCFunctionInfo *GFI = Functions.back().get();
   FInfoMap[&F] = GFI;
@@ -84,7 +76,7 @@
 void GCModuleInfo::clear() {
   Functions.clear();
   FInfoMap.clear();
-  StrategyList.clear();
+  GCStrategyList.clear();
 }
 
 // -----------------------------------------------------------------------------
@@ -159,3 +151,23 @@
   GMI->clear();
   return false;
 }
+
+
+GCStrategy *GCModuleInfo::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();
+    }
+  }
+
+  report_fatal_error(std::string("unsupported GC: ") + Name);
+}
diff --git a/llvm/lib/CodeGen/GCRootLowering.cpp b/llvm/lib/CodeGen/GCRootLowering.cpp
index 7cb4598..ee89ac4 100644
--- a/llvm/lib/CodeGen/GCRootLowering.cpp
+++ b/llvm/lib/CodeGen/GCRootLowering.cpp
@@ -16,9 +16,9 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/GCStrategy.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"
diff --git a/llvm/lib/IR/GCStrategy.cpp b/llvm/lib/CodeGen/GCStrategy.cpp
similarity index 90%
rename from llvm/lib/IR/GCStrategy.cpp
rename to llvm/lib/CodeGen/GCStrategy.cpp
index b451310..554d326 100644
--- a/llvm/lib/IR/GCStrategy.cpp
+++ b/llvm/lib/CodeGen/GCStrategy.cpp
@@ -12,9 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/GCStrategy.h"
-
-template class llvm::Registry<llvm::GCStrategy>;
+#include "llvm/CodeGen/GCStrategy.h"
 
 using namespace llvm;
 
diff --git a/llvm/lib/CodeGen/OcamlGC.cpp b/llvm/lib/CodeGen/OcamlGC.cpp
index 164e370..17654a6 100644
--- a/llvm/lib/CodeGen/OcamlGC.cpp
+++ b/llvm/lib/CodeGen/OcamlGC.cpp
@@ -15,7 +15,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCs.h"
-#include "llvm/IR/GCStrategy.h"
+#include "llvm/CodeGen/GCStrategy.h"
 
 using namespace llvm;
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 8c25783..699e2bb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -26,6 +26,7 @@
 #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"
@@ -40,7 +41,6 @@
 #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"
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c56973a..63f3d5e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "ScheduleDAGSDNodes.h"
 #include "SelectionDAGBuilder.h"
@@ -35,7 +36,6 @@
 #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"
diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index 94f09bd..d3090a9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -18,10 +18,10 @@
 #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"
diff --git a/llvm/lib/CodeGen/ShadowStackGC.cpp b/llvm/lib/CodeGen/ShadowStackGC.cpp
index 163d0ef..e4a3891 100644
--- a/llvm/lib/CodeGen/ShadowStackGC.cpp
+++ b/llvm/lib/CodeGen/ShadowStackGC.cpp
@@ -26,9 +26,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/ADT/StringExtras.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"
diff --git a/llvm/lib/CodeGen/StatepointExampleGC.cpp b/llvm/lib/CodeGen/StatepointExampleGC.cpp
index 67f40c8..95dfd75 100644
--- a/llvm/lib/CodeGen/StatepointExampleGC.cpp
+++ b/llvm/lib/CodeGen/StatepointExampleGC.cpp
@@ -16,7 +16,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/GCStrategy.h"
+#include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Value.h"
 
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 621c7ca..1a210e0 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -17,7 +17,6 @@
   Dominators.cpp
   Function.cpp
   GCOV.cpp
-  GCStrategy.cpp
   GVMaterializer.cpp
   Globals.cpp
   IRBuilder.cpp
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index ddfbaf7..070513e 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -386,12 +386,6 @@
   }
 }
 
-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) {
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 3370bdb..d717b92 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -15,7 +15,6 @@
 #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;
@@ -239,25 +238,3 @@
 
 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;
-}
-
-
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 12b1507..e4e9f8f 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -457,17 +457,6 @@
   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();