xref: /freebsd/contrib/llvm-project/llvm/lib/IR/GCStrategy.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1fe6060f1SDimitry Andric //===- GCStrategy.cpp - Garbage Collector Description ---------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // This file implements the policy object GCStrategy which describes the
10fe6060f1SDimitry Andric // behavior of a given garbage collector.
11fe6060f1SDimitry Andric //
12fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
13fe6060f1SDimitry Andric 
14fe6060f1SDimitry Andric #include "llvm/IR/GCStrategy.h"
15fcaf7f86SDimitry Andric #include "llvm/ADT/Twine.h"
16*bdd1243dSDimitry Andric #include "llvm/IR/BuiltinGCs.h"
17fe6060f1SDimitry Andric 
18fe6060f1SDimitry Andric using namespace llvm;
19fe6060f1SDimitry Andric 
20fe6060f1SDimitry Andric LLVM_INSTANTIATE_REGISTRY(GCRegistry)
21fe6060f1SDimitry Andric 
22fe6060f1SDimitry Andric GCStrategy::GCStrategy() = default;
23349cc55cSDimitry Andric 
getGCStrategy(const StringRef Name)24349cc55cSDimitry Andric std::unique_ptr<GCStrategy> llvm::getGCStrategy(const StringRef Name) {
25349cc55cSDimitry Andric   for (auto &S : GCRegistry::entries())
26349cc55cSDimitry Andric     if (S.getName() == Name)
27349cc55cSDimitry Andric       return S.instantiate();
28349cc55cSDimitry Andric 
29*bdd1243dSDimitry Andric   // We need to link all the builtin GCs when LLVM is used as a static library.
30*bdd1243dSDimitry Andric   // The linker will quite happily remove the static constructors that register
31*bdd1243dSDimitry Andric   // the builtin GCs if we don't use a function from that object. This function
32*bdd1243dSDimitry Andric   // does nothing but we need to make sure it is (or at least could be, even
33*bdd1243dSDimitry Andric   // with all optimisations enabled) called *somewhere*, and this is a good
34*bdd1243dSDimitry Andric   // place to do that: if the GC strategies are being used then this function
35*bdd1243dSDimitry Andric   // obviously can't be removed by the linker, and here it won't affect
36*bdd1243dSDimitry Andric   // performance, since there's about to be a fatal error anyway.
37*bdd1243dSDimitry Andric   llvm::linkAllBuiltinGCs();
38*bdd1243dSDimitry Andric 
39349cc55cSDimitry Andric   if (GCRegistry::begin() == GCRegistry::end()) {
40349cc55cSDimitry Andric     // In normal operation, the registry should not be empty.  There should
41349cc55cSDimitry Andric     // be the builtin GCs if nothing else.  The most likely scenario here is
42349cc55cSDimitry Andric     // that we got here without running the initializers used by the Registry
43349cc55cSDimitry Andric     // itself and it's registration mechanism.
44349cc55cSDimitry Andric     const std::string error =
45349cc55cSDimitry Andric         std::string("unsupported GC: ") + Name.str() +
46349cc55cSDimitry Andric         " (did you remember to link and initialize the library?)";
47fcaf7f86SDimitry Andric     report_fatal_error(Twine(error));
48349cc55cSDimitry Andric   } else
49fcaf7f86SDimitry Andric     report_fatal_error(Twine(std::string("unsupported GC: ") + Name.str()));
50349cc55cSDimitry Andric }
51