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