//===----------------------------------------------------------------------===//
#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"
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;
void GCModuleInfo::clear() {
Functions.clear();
FInfoMap.clear();
- StrategyList.clear();
+ GCStrategyList.clear();
}
// -----------------------------------------------------------------------------
static const char *DescKind(GC::PointKind Kind) {
switch (Kind) {
- case GC::Loop:
- return "loop";
- case GC::Return:
- return "return";
case GC::PreCall:
return "pre-call";
case GC::PostCall:
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();
+ }
+ }
+
+ if (GCRegistry::begin() == GCRegistry::end()) {
+ // In normal operation, the registry should not be empty. There should
+ // be the builtin GCs if nothing else. The most likely scenario here is
+ // that we got here without running the initializers used by the Registry
+ // itself and it's registration mechanism.
+ const std::string error = ("unsupported GC: " + Name).str() +
+ " (did you remember to link and initialize the CodeGen library?)";
+ report_fatal_error(error);
+ } else
+ report_fatal_error(std::string("unsupported GC: ") + Name);
+}