Bug Summary

File:llvm/include/llvm/ADT/FunctionExtras.h
Warning:line 190, column 3
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name OrcMCJITReplacement.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/ExecutionEngine/Orc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp

1//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "OrcMCJITReplacement.h"
10#include "llvm/ExecutionEngine/GenericValue.h"
11
12namespace {
13
14static struct RegisterJIT {
15 RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
16} JITRegistrator;
17
18}
19
20extern "C" void LLVMLinkInOrcMCJITReplacement() {}
21
22namespace llvm {
23namespace orc {
24
25GenericValue
26OrcMCJITReplacement::runFunction(Function *F,
27 ArrayRef<GenericValue> ArgValues) {
28 assert(F && "Function *F was null at entry to run()")((F && "Function *F was null at entry to run()") ? static_cast
<void> (0) : __assert_fail ("F && \"Function *F was null at entry to run()\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 28, __PRETTY_FUNCTION__))
;
1
Assuming 'F' is non-null
2
'?' condition is true
29
30 void *FPtr = getPointerToFunction(F);
3
Calling 'OrcMCJITReplacement::getPointerToFunction'
31 assert(FPtr && "Pointer to fn's code was null after getPointerToFunction")((FPtr && "Pointer to fn's code was null after getPointerToFunction"
) ? static_cast<void> (0) : __assert_fail ("FPtr && \"Pointer to fn's code was null after getPointerToFunction\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 31, __PRETTY_FUNCTION__))
;
32 FunctionType *FTy = F->getFunctionType();
33 Type *RetTy = FTy->getReturnType();
34
35 assert((FTy->getNumParams() == ArgValues.size() ||(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
36 (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
37 "Wrong number of arguments passed into function!")(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
;
38 assert(FTy->getNumParams() == ArgValues.size() &&((FTy->getNumParams() == ArgValues.size() && "This doesn't support passing arguments through varargs (yet)!"
) ? static_cast<void> (0) : __assert_fail ("FTy->getNumParams() == ArgValues.size() && \"This doesn't support passing arguments through varargs (yet)!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 39, __PRETTY_FUNCTION__))
39 "This doesn't support passing arguments through varargs (yet)!")((FTy->getNumParams() == ArgValues.size() && "This doesn't support passing arguments through varargs (yet)!"
) ? static_cast<void> (0) : __assert_fail ("FTy->getNumParams() == ArgValues.size() && \"This doesn't support passing arguments through varargs (yet)!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 39, __PRETTY_FUNCTION__))
;
40
41 // Handle some common cases first. These cases correspond to common `main'
42 // prototypes.
43 if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
44 switch (ArgValues.size()) {
45 case 3:
46 if (FTy->getParamType(0)->isIntegerTy(32) &&
47 FTy->getParamType(1)->isPointerTy() &&
48 FTy->getParamType(2)->isPointerTy()) {
49 int (*PF)(int, char **, const char **) =
50 (int (*)(int, char **, const char **))(intptr_t)FPtr;
51
52 // Call the function.
53 GenericValue rv;
54 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
55 (char **)GVTOP(ArgValues[1]),
56 (const char **)GVTOP(ArgValues[2])));
57 return rv;
58 }
59 break;
60 case 2:
61 if (FTy->getParamType(0)->isIntegerTy(32) &&
62 FTy->getParamType(1)->isPointerTy()) {
63 int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
64
65 // Call the function.
66 GenericValue rv;
67 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
68 (char **)GVTOP(ArgValues[1])));
69 return rv;
70 }
71 break;
72 case 1:
73 if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
74 GenericValue rv;
75 int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
76 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
77 return rv;
78 }
79 break;
80 }
81 }
82
83 // Handle cases where no arguments are passed first.
84 if (ArgValues.empty()) {
85 GenericValue rv;
86 switch (RetTy->getTypeID()) {
87 default:
88 llvm_unreachable("Unknown return type for function call!")::llvm::llvm_unreachable_internal("Unknown return type for function call!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 88)
;
89 case Type::IntegerTyID: {
90 unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
91 if (BitWidth == 1)
92 rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
93 else if (BitWidth <= 8)
94 rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
95 else if (BitWidth <= 16)
96 rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
97 else if (BitWidth <= 32)
98 rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
99 else if (BitWidth <= 64)
100 rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
101 else
102 llvm_unreachable("Integer types > 64 bits not supported")::llvm::llvm_unreachable_internal("Integer types > 64 bits not supported"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 102)
;
103 return rv;
104 }
105 case Type::VoidTyID:
106 rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
107 return rv;
108 case Type::FloatTyID:
109 rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
110 return rv;
111 case Type::DoubleTyID:
112 rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
113 return rv;
114 case Type::X86_FP80TyID:
115 case Type::FP128TyID:
116 case Type::PPC_FP128TyID:
117 llvm_unreachable("long double not supported yet")::llvm::llvm_unreachable_internal("long double not supported yet"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 117)
;
118 case Type::PointerTyID:
119 return PTOGV(((void *(*)())(intptr_t)FPtr)());
120 }
121 }
122
123 llvm_unreachable("Full-featured argument passing not supported yet!")::llvm::llvm_unreachable_internal("Full-featured argument passing not supported yet!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 123)
;
124}
125
126void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
127 auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors;
128
129 for (auto &KV : CtorDtorsMap)
130 cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(
131 AcknowledgeORCv1Deprecation, std::move(KV.second), KV.first)
132 .runViaLayer(LazyEmitLayer));
133
134 CtorDtorsMap.clear();
135}
136
137} // End namespace orc.
138} // End namespace llvm.

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h

1//===- OrcMCJITReplacement.h - Orc based MCJIT replacement ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Orc based MCJIT replacement.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
14#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ExecutionEngine/ExecutionEngine.h"
20#include "llvm/ExecutionEngine/GenericValue.h"
21#include "llvm/ExecutionEngine/JITSymbol.h"
22#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
23#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
24#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
25#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
26#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
27#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
28#include "llvm/ExecutionEngine/RuntimeDyld.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/Function.h"
31#include "llvm/IR/Mangler.h"
32#include "llvm/IR/Module.h"
33#include "llvm/Object/Archive.h"
34#include "llvm/Object/Binary.h"
35#include "llvm/Object/ObjectFile.h"
36#include "llvm/Support/Error.h"
37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/raw_ostream.h"
39#include "llvm/Target/TargetMachine.h"
40#include <algorithm>
41#include <cassert>
42#include <cstddef>
43#include <cstdint>
44#include <map>
45#include <memory>
46#include <set>
47#include <string>
48#include <vector>
49
50namespace llvm {
51
52class ObjectCache;
53
54namespace orc {
55
56class OrcMCJITReplacement : public ExecutionEngine {
57
58 // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
59 // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
60 // expecting - see finalizeMemory.
61 class MCJITReplacementMemMgr : public MCJITMemoryManager {
62 public:
63 MCJITReplacementMemMgr(OrcMCJITReplacement &M,
64 std::shared_ptr<MCJITMemoryManager> ClientMM)
65 : M(M), ClientMM(std::move(ClientMM)) {}
66
67 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
68 unsigned SectionID,
69 StringRef SectionName) override {
70 uint8_t *Addr =
71 ClientMM->allocateCodeSection(Size, Alignment, SectionID,
72 SectionName);
73 M.SectionsAllocatedSinceLastLoad.insert(Addr);
74 return Addr;
75 }
76
77 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
78 unsigned SectionID, StringRef SectionName,
79 bool IsReadOnly) override {
80 uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
81 SectionName, IsReadOnly);
82 M.SectionsAllocatedSinceLastLoad.insert(Addr);
83 return Addr;
84 }
85
86 void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
87 uintptr_t RODataSize, uint32_t RODataAlign,
88 uintptr_t RWDataSize,
89 uint32_t RWDataAlign) override {
90 return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign,
91 RODataSize, RODataAlign,
92 RWDataSize, RWDataAlign);
93 }
94
95 bool needsToReserveAllocationSpace() override {
96 return ClientMM->needsToReserveAllocationSpace();
97 }
98
99 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
100 size_t Size) override {
101 return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
102 }
103
104 void deregisterEHFrames() override {
105 return ClientMM->deregisterEHFrames();
106 }
107
108 void notifyObjectLoaded(RuntimeDyld &RTDyld,
109 const object::ObjectFile &O) override {
110 return ClientMM->notifyObjectLoaded(RTDyld, O);
111 }
112
113 void notifyObjectLoaded(ExecutionEngine *EE,
114 const object::ObjectFile &O) override {
115 return ClientMM->notifyObjectLoaded(EE, O);
116 }
117
118 bool finalizeMemory(std::string *ErrMsg = nullptr) override {
119 // Each set of objects loaded will be finalized exactly once, but since
120 // symbol lookup during relocation may recursively trigger the
121 // loading/relocation of other modules, and since we're forwarding all
122 // finalizeMemory calls to a single underlying memory manager, we need to
123 // defer forwarding the call on until all necessary objects have been
124 // loaded. Otherwise, during the relocation of a leaf object, we will end
125 // up finalizing memory, causing a crash further up the stack when we
126 // attempt to apply relocations to finalized memory.
127 // To avoid finalizing too early, look at how many objects have been
128 // loaded but not yet finalized. This is a bit of a hack that relies on
129 // the fact that we're lazily emitting object files: The only way you can
130 // get more than one set of objects loaded but not yet finalized is if
131 // they were loaded during relocation of another set.
132 if (M.UnfinalizedSections.size() == 1)
133 return ClientMM->finalizeMemory(ErrMsg);
134 return false;
135 }
136
137 private:
138 OrcMCJITReplacement &M;
139 std::shared_ptr<MCJITMemoryManager> ClientMM;
140 };
141
142 class LinkingORCResolver : public orc::SymbolResolver {
143 public:
144 LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {}
145
146 SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) override {
147 SymbolNameSet Result;
148
149 for (auto &S : Symbols) {
150 if (auto Sym = M.findMangledSymbol(*S)) {
151 if (!Sym.getFlags().isStrong())
152 Result.insert(S);
153 } else if (auto Err = Sym.takeError()) {
154 M.reportError(std::move(Err));
155 return SymbolNameSet();
156 } else {
157 if (auto Sym2 =
158 M.ClientResolver->findSymbolInLogicalDylib(std::string(*S))) {
159 if (!Sym2.getFlags().isStrong())
160 Result.insert(S);
161 } else if (auto Err = Sym2.takeError()) {
162 M.reportError(std::move(Err));
163 return SymbolNameSet();
164 } else
165 Result.insert(S);
166 }
167 }
168
169 return Result;
170 }
171
172 SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
173 SymbolNameSet Symbols) override {
174 SymbolNameSet UnresolvedSymbols;
175 bool NewSymbolsResolved = false;
176
177 for (auto &S : Symbols) {
178 if (auto Sym = M.findMangledSymbol(*S)) {
179 if (auto Addr = Sym.getAddress()) {
180 Query->notifySymbolMetRequiredState(
181 S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
182 NewSymbolsResolved = true;
183 } else {
184 M.ES.legacyFailQuery(*Query, Addr.takeError());
185 return SymbolNameSet();
186 }
187 } else if (auto Err = Sym.takeError()) {
188 M.ES.legacyFailQuery(*Query, std::move(Err));
189 return SymbolNameSet();
190 } else {
191 if (auto Sym2 = M.ClientResolver->findSymbol(std::string(*S))) {
192 if (auto Addr = Sym2.getAddress()) {
193 Query->notifySymbolMetRequiredState(
194 S, JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
195 NewSymbolsResolved = true;
196 } else {
197 M.ES.legacyFailQuery(*Query, Addr.takeError());
198 return SymbolNameSet();
199 }
200 } else if (auto Err = Sym2.takeError()) {
201 M.ES.legacyFailQuery(*Query, std::move(Err));
202 return SymbolNameSet();
203 } else
204 UnresolvedSymbols.insert(S);
205 }
206 }
207
208 if (NewSymbolsResolved && Query->isComplete())
209 Query->handleComplete();
210
211 return UnresolvedSymbols;
212 }
213
214 private:
215 OrcMCJITReplacement &M;
216 };
217
218private:
219 static ExecutionEngine *
220 createOrcMCJITReplacement(std::string *ErrorMsg,
221 std::shared_ptr<MCJITMemoryManager> MemMgr,
222 std::shared_ptr<LegacyJITSymbolResolver> Resolver,
223 std::unique_ptr<TargetMachine> TM) {
224 return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
225 std::move(TM));
226 }
227
228 void reportError(Error Err) {
229 logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: ");
230 }
231
232public:
233 OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
234 std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
235 std::unique_ptr<TargetMachine> TM)
236 : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
237 MemMgr(
238 std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
239 Resolver(std::make_shared<LinkingORCResolver>(*this)),
240 ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
241 NotifyFinalized(*this),
242 ObjectLayer(
243 AcknowledgeORCv1Deprecation, ES,
244 [this](VModuleKey K) {
245 return ObjectLayerT::Resources{this->MemMgr, this->Resolver};
246 },
247 NotifyObjectLoaded, NotifyFinalized),
248 CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer,
249 SimpleCompiler(*this->TM),
250 [this](VModuleKey K, std::unique_ptr<Module> M) {
251 Modules.push_back(std::move(M));
252 }),
253 LazyEmitLayer(AcknowledgeORCv1Deprecation, CompileLayer) {}
254
255 static void Register() {
256 OrcMCJITReplacementCtor = createOrcMCJITReplacement;
257 }
258
259 void addModule(std::unique_ptr<Module> M) override {
260 // If this module doesn't have a DataLayout attached then attach the
261 // default.
262 if (M->getDataLayout().isDefault()) {
263 M->setDataLayout(getDataLayout());
264 } else {
265 assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch")((M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"
) ? static_cast<void> (0) : __assert_fail ("M->getDataLayout() == getDataLayout() && \"DataLayout Mismatch\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h"
, 265, __PRETTY_FUNCTION__))
;
266 }
267
268 // Rename, bump linkage and record static constructors and destructors.
269 // We have to do this before we hand over ownership of the module to the
270 // JIT.
271 std::vector<std::string> CtorNames, DtorNames;
272 {
273 unsigned CtorId = 0, DtorId = 0;
274 for (auto Ctor : orc::getConstructors(*M)) {
275 std::string NewCtorName = ("__ORCstatic_ctor." + Twine(CtorId++)).str();
276 Ctor.Func->setName(NewCtorName);
277 Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
278 Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
279 CtorNames.push_back(mangle(NewCtorName));
280 }
281 for (auto Dtor : orc::getDestructors(*M)) {
282 std::string NewDtorName = ("__ORCstatic_dtor." + Twine(DtorId++)).str();
283 dbgs() << "Found dtor: " << NewDtorName << "\n";
284 Dtor.Func->setName(NewDtorName);
285 Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
286 Dtor.Func->setVisibility(GlobalValue::HiddenVisibility);
287 DtorNames.push_back(mangle(NewDtorName));
288 }
289 }
290
291 auto K = ES.allocateVModule();
292
293 UnexecutedConstructors[K] = std::move(CtorNames);
294 UnexecutedDestructors[K] = std::move(DtorNames);
295
296 cantFail(LazyEmitLayer.addModule(K, std::move(M)));
297 }
298
299 void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
300 cantFail(ObjectLayer.addObject(
301 ES.allocateVModule(), MemoryBuffer::getMemBufferCopy(O->getData())));
302 }
303
304 void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
305 std::unique_ptr<object::ObjectFile> Obj;
306 std::unique_ptr<MemoryBuffer> ObjBuffer;
307 std::tie(Obj, ObjBuffer) = O.takeBinary();
308 cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(ObjBuffer)));
309 }
310
311 void addArchive(object::OwningBinary<object::Archive> A) override {
312 Archives.push_back(std::move(A));
313 }
314
315 bool removeModule(Module *M) override {
316 auto I = Modules.begin();
317 for (auto E = Modules.end(); I != E; ++I)
318 if (I->get() == M)
319 break;
320 if (I == Modules.end())
321 return false;
322 Modules.erase(I);
323 return true;
324 }
325
326 uint64_t getSymbolAddress(StringRef Name) {
327 return cantFail(findSymbol(Name).getAddress());
5
Calling 'OrcMCJITReplacement::findSymbol'
328 }
329
330 JITSymbol findSymbol(StringRef Name) {
331 return findMangledSymbol(mangle(Name));
6
Calling 'OrcMCJITReplacement::findMangledSymbol'
332 }
333
334 void finalizeObject() override {
335 // This is deprecated - Aim to remove in ExecutionEngine.
336 // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
337 }
338
339 void mapSectionAddress(const void *LocalAddress,
340 uint64_t TargetAddress) override {
341 for (auto &P : UnfinalizedSections)
342 if (P.second.count(LocalAddress))
343 ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
344 }
345
346 uint64_t getGlobalValueAddress(const std::string &Name) override {
347 return getSymbolAddress(Name);
348 }
349
350 uint64_t getFunctionAddress(const std::string &Name) override {
351 return getSymbolAddress(Name);
352 }
353
354 void *getPointerToFunction(Function *F) override {
355 uint64_t FAddr = getSymbolAddress(F->getName());
4
Calling 'OrcMCJITReplacement::getSymbolAddress'
356 return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
357 }
358
359 void *getPointerToNamedFunction(StringRef Name,
360 bool AbortOnFailure = true) override {
361 uint64_t Addr = getSymbolAddress(Name);
362 if (!Addr && AbortOnFailure)
363 llvm_unreachable("Missing symbol!")::llvm::llvm_unreachable_internal("Missing symbol!", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h"
, 363)
;
364 return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
365 }
366
367 GenericValue runFunction(Function *F,
368 ArrayRef<GenericValue> ArgValues) override;
369
370 void setObjectCache(ObjectCache *NewCache) override {
371 CompileLayer.getCompiler().setObjectCache(NewCache);
372 }
373
374 void setProcessAllSections(bool ProcessAllSections) override {
375 ObjectLayer.setProcessAllSections(ProcessAllSections);
376 }
377
378 void runStaticConstructorsDestructors(bool isDtors) override;
379
380private:
381 JITSymbol findMangledSymbol(StringRef Name) {
382 if (auto Sym = LazyEmitLayer.findSymbol(std::string(Name), false))
7
Calling 'LazyEmittingLayer::findSymbol'
383 return Sym;
384 if (auto Sym = ClientResolver->findSymbol(std::string(Name)))
385 return Sym;
386 if (auto Sym = scanArchives(Name))
387 return Sym;
388
389 return nullptr;
390 }
391
392 JITSymbol scanArchives(StringRef Name) {
393 for (object::OwningBinary<object::Archive> &OB : Archives) {
394 object::Archive *A = OB.getBinary();
395 // Look for our symbols in each Archive
396 auto OptionalChildOrErr = A->findSym(Name);
397 if (!OptionalChildOrErr)
398 report_fatal_error(OptionalChildOrErr.takeError());
399 auto &OptionalChild = *OptionalChildOrErr;
400 if (OptionalChild) {
401 // FIXME: Support nested archives?
402 Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
403 OptionalChild->getAsBinary();
404 if (!ChildBinOrErr) {
405 // TODO: Actually report errors helpfully.
406 consumeError(ChildBinOrErr.takeError());
407 continue;
408 }
409 std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
410 if (ChildBin->isObject()) {
411 cantFail(ObjectLayer.addObject(
412 ES.allocateVModule(),
413 MemoryBuffer::getMemBufferCopy(ChildBin->getData())));
414 if (auto Sym = ObjectLayer.findSymbol(Name, true))
415 return Sym;
416 }
417 }
418 }
419 return nullptr;
420 }
421
422 class NotifyObjectLoadedT {
423 public:
424 using LoadedObjInfoListT =
425 std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>;
426
427 NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
428
429 void operator()(VModuleKey K, const object::ObjectFile &Obj,
430 const RuntimeDyld::LoadedObjectInfo &Info) const {
431 M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad);
432 M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
433 M.MemMgr->notifyObjectLoaded(&M, Obj);
434 }
435 private:
436 OrcMCJITReplacement &M;
437 };
438
439 class NotifyFinalizedT {
440 public:
441 NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
442
443 void operator()(VModuleKey K, const object::ObjectFile &Obj,
444 const RuntimeDyld::LoadedObjectInfo &Info) {
445 M.UnfinalizedSections.erase(K);
446 }
447
448 private:
449 OrcMCJITReplacement &M;
450 };
451
452 std::string mangle(StringRef Name) {
453 std::string MangledName;
454 {
455 raw_string_ostream MangledNameStream(MangledName);
456 Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
457 }
458 return MangledName;
459 }
460
461 using ObjectLayerT = LegacyRTDyldObjectLinkingLayer;
462 using CompileLayerT = LegacyIRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
463 using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
464
465 ExecutionSession ES;
466
467 std::unique_ptr<TargetMachine> TM;
468 std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
469 std::shared_ptr<LinkingORCResolver> Resolver;
470 std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
471 Mangler Mang;
472
473 // IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr
474 // delete blocks in LocalModules refer to the ShouldDelete map, so
475 // LocalModules needs to be destructed before ShouldDelete.
476 std::map<Module*, bool> ShouldDelete;
477
478 NotifyObjectLoadedT NotifyObjectLoaded;
479 NotifyFinalizedT NotifyFinalized;
480
481 ObjectLayerT ObjectLayer;
482 CompileLayerT CompileLayer;
483 LazyEmitLayerT LazyEmitLayer;
484
485 std::map<VModuleKey, std::vector<std::string>> UnexecutedConstructors;
486 std::map<VModuleKey, std::vector<std::string>> UnexecutedDestructors;
487
488 // We need to store ObjLayerT::ObjSetHandles for each of the object sets
489 // that have been emitted but not yet finalized so that we can forward the
490 // mapSectionAddress calls appropriately.
491 using SectionAddrSet = std::set<const void *>;
492 SectionAddrSet SectionsAllocatedSinceLastLoad;
493 std::map<VModuleKey, SectionAddrSet> UnfinalizedSections;
494
495 std::vector<object::OwningBinary<object::Archive>> Archives;
496};
497
498} // end namespace orc
499
500} // end namespace llvm
501
502#endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h

1//===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Contains the definition for a lazy-emitting layer for the JIT.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
14#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
15
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ExecutionEngine/JITSymbol.h"
20#include "llvm/ExecutionEngine/Orc/Core.h"
21#include "llvm/IR/GlobalValue.h"
22#include "llvm/IR/Mangler.h"
23#include "llvm/IR/Module.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/raw_ostream.h"
26#include <algorithm>
27#include <cassert>
28#include <list>
29#include <memory>
30#include <string>
31
32namespace llvm {
33namespace orc {
34
35/// Lazy-emitting IR layer.
36///
37/// This layer accepts LLVM IR Modules (via addModule) but does not
38/// immediately emit them the layer below. Instead, emission to the base layer
39/// is deferred until the first time the client requests the address (via
40/// JITSymbol::getAddress) for a symbol contained in this layer.
41template <typename BaseLayerT> class LazyEmittingLayer {
42private:
43 class EmissionDeferredModule {
44 public:
45 EmissionDeferredModule(VModuleKey K, std::unique_ptr<Module> M)
46 : K(std::move(K)), M(std::move(M)) {}
47
48 JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
49 switch (EmitState) {
10
Control jumps to 'case NotEmitted:' at line 50
50 case NotEmitted:
51 if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
11
Assuming 'GV' is non-null
12
Taking true branch
52 JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
53 auto GetAddress = [this, ExportedSymbolsOnly, Name = Name.str(),
54 &B]() -> Expected<JITTargetAddress> {
55 if (this->EmitState == Emitting)
56 return 0;
57 else if (this->EmitState == NotEmitted) {
58 this->EmitState = Emitting;
59 if (auto Err = this->emitToBaseLayer(B))
60 return std::move(Err);
61 this->EmitState = Emitted;
62 }
63 if (auto Sym = B.findSymbolIn(K, Name, ExportedSymbolsOnly))
64 return Sym.getAddress();
65 else if (auto Err = Sym.takeError())
66 return std::move(Err);
67 else
68 llvm_unreachable("Successful symbol lookup should return "::llvm::llvm_unreachable_internal("Successful symbol lookup should return "
"definition address here", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 69)
69 "definition address here")::llvm::llvm_unreachable_internal("Successful symbol lookup should return "
"definition address here", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 69)
;
70 };
71 return JITSymbol(std::move(GetAddress), Flags);
13
Calling constructor for 'unique_function<llvm::Expected<unsigned long> ()>'
17
Returning from constructor for 'unique_function<llvm::Expected<unsigned long> ()>'
18
Calling '~unique_function'
72 } else
73 return nullptr;
74 case Emitting:
75 // Calling "emit" can trigger a recursive call to 'find' (e.g. to check
76 // for pre-existing definitions of common-symbol), but any symbol in
77 // this module would already have been found internally (in the
78 // RuntimeDyld that did the lookup), so just return a nullptr here.
79 return nullptr;
80 case Emitted:
81 return B.findSymbolIn(K, std::string(Name), ExportedSymbolsOnly);
82 }
83 llvm_unreachable("Invalid emit-state.")::llvm::llvm_unreachable_internal("Invalid emit-state.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 83)
;
84 }
85
86 Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
87 return EmitState != NotEmitted ? BaseLayer.removeModule(K)
88 : Error::success();
89 }
90
91 void emitAndFinalize(BaseLayerT &BaseLayer) {
92 assert(EmitState != Emitting &&((EmitState != Emitting && "Cannot emitAndFinalize while already emitting"
) ? static_cast<void> (0) : __assert_fail ("EmitState != Emitting && \"Cannot emitAndFinalize while already emitting\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 93, __PRETTY_FUNCTION__))
93 "Cannot emitAndFinalize while already emitting")((EmitState != Emitting && "Cannot emitAndFinalize while already emitting"
) ? static_cast<void> (0) : __assert_fail ("EmitState != Emitting && \"Cannot emitAndFinalize while already emitting\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 93, __PRETTY_FUNCTION__))
;
94 if (EmitState == NotEmitted) {
95 EmitState = Emitting;
96 emitToBaseLayer(BaseLayer);
97 EmitState = Emitted;
98 }
99 BaseLayer.emitAndFinalize(K);
100 }
101
102 private:
103
104 const GlobalValue* searchGVs(StringRef Name,
105 bool ExportedSymbolsOnly) const {
106 // FIXME: We could clean all this up if we had a way to reliably demangle
107 // names: We could just demangle name and search, rather than
108 // mangling everything else.
109
110 // If we have already built the mangled name set then just search it.
111 if (MangledSymbols) {
112 auto VI = MangledSymbols->find(Name);
113 if (VI == MangledSymbols->end())
114 return nullptr;
115 auto GV = VI->second;
116 if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
117 return GV;
118 return nullptr;
119 }
120
121 // If we haven't built the mangled name set yet, try to build it. As an
122 // optimization this will leave MangledNames set to nullptr if we find
123 // Name in the process of building the set.
124 return buildMangledSymbols(Name, ExportedSymbolsOnly);
125 }
126
127 Error emitToBaseLayer(BaseLayerT &BaseLayer) {
128 // We don't need the mangled names set any more: Once we've emitted this
129 // to the base layer we'll just look for symbols there.
130 MangledSymbols.reset();
131 return BaseLayer.addModule(std::move(K), std::move(M));
132 }
133
134 // If the mangled name of the given GlobalValue matches the given search
135 // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
136 // return the symbol. Otherwise, add the mangled name to the Names map and
137 // return nullptr.
138 const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
139 const GlobalValue &GV,
140 const Mangler &Mang, StringRef SearchName,
141 bool ExportedSymbolsOnly) const {
142 // Modules don't "provide" decls or common symbols.
143 if (GV.isDeclaration() || GV.hasCommonLinkage())
144 return nullptr;
145
146 // Mangle the GV name.
147 std::string MangledName;
148 {
149 raw_string_ostream MangledNameStream(MangledName);
150 Mang.getNameWithPrefix(MangledNameStream, &GV, false);
151 }
152
153 // Check whether this is the name we were searching for, and if it is then
154 // bail out early.
155 if (MangledName == SearchName)
156 if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
157 return &GV;
158
159 // Otherwise add this to the map for later.
160 Names[MangledName] = &GV;
161 return nullptr;
162 }
163
164 // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
165 // to nullptr) if the given SearchName is found while building the map.
166 const GlobalValue* buildMangledSymbols(StringRef SearchName,
167 bool ExportedSymbolsOnly) const {
168 assert(!MangledSymbols && "Mangled symbols map already exists?")((!MangledSymbols && "Mangled symbols map already exists?"
) ? static_cast<void> (0) : __assert_fail ("!MangledSymbols && \"Mangled symbols map already exists?\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 168, __PRETTY_FUNCTION__))
;
169
170 auto Symbols = std::make_unique<StringMap<const GlobalValue*>>();
171
172 Mangler Mang;
173
174 for (const auto &GO : M->global_objects())
175 if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
176 ExportedSymbolsOnly))
177 return GV;
178
179 MangledSymbols = std::move(Symbols);
180 return nullptr;
181 }
182
183 enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
184 VModuleKey K;
185 std::unique_ptr<Module> M;
186 mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
187 };
188
189 BaseLayerT &BaseLayer;
190 std::map<VModuleKey, std::unique_ptr<EmissionDeferredModule>> ModuleMap;
191
192public:
193
194 /// Construct a lazy emitting layer.
195 LLVM_ATTRIBUTE_DEPRECATED(LazyEmittingLayer(BaseLayerT &BaseLayer) __attribute__((deprecated
("ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "
"ORCv2, where lazy emission is the default")))
196 LazyEmittingLayer(BaseLayerT &BaseLayer),LazyEmittingLayer(BaseLayerT &BaseLayer) __attribute__((deprecated
("ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "
"ORCv2, where lazy emission is the default")))
197 "ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "LazyEmittingLayer(BaseLayerT &BaseLayer) __attribute__((deprecated
("ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "
"ORCv2, where lazy emission is the default")))
198 "ORCv2, where lazy emission is the default")LazyEmittingLayer(BaseLayerT &BaseLayer) __attribute__((deprecated
("ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use "
"ORCv2, where lazy emission is the default")))
;
199
200 /// Construct a lazy emitting layer.
201 LazyEmittingLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer)
202 : BaseLayer(BaseLayer) {}
203
204 /// Add the given module to the lazy emitting layer.
205 Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
206 assert(!ModuleMap.count(K) && "VModuleKey K already in use")((!ModuleMap.count(K) && "VModuleKey K already in use"
) ? static_cast<void> (0) : __assert_fail ("!ModuleMap.count(K) && \"VModuleKey K already in use\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 206, __PRETTY_FUNCTION__))
;
207 ModuleMap[K] =
208 std::make_unique<EmissionDeferredModule>(std::move(K), std::move(M));
209 return Error::success();
210 }
211
212 /// Remove the module represented by the given handle.
213 ///
214 /// This method will free the memory associated with the given module, both
215 /// in this layer, and the base layer.
216 Error removeModule(VModuleKey K) {
217 auto I = ModuleMap.find(K);
218 assert(I != ModuleMap.end() && "VModuleKey K not valid here")((I != ModuleMap.end() && "VModuleKey K not valid here"
) ? static_cast<void> (0) : __assert_fail ("I != ModuleMap.end() && \"VModuleKey K not valid here\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 218, __PRETTY_FUNCTION__))
;
219 auto EDM = std::move(I.second);
220 ModuleMap.erase(I);
221 return EDM->removeModuleFromBaseLayer(BaseLayer);
222 }
223
224 /// Search for the given named symbol.
225 /// @param Name The name of the symbol to search for.
226 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
227 /// @return A handle for the given named symbol, if it exists.
228 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
229 // Look for the symbol among existing definitions.
230 if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
8
Taking false branch
231 return Symbol;
232
233 // If not found then search the deferred modules. If any of these contain a
234 // definition of 'Name' then they will return a JITSymbol that will emit
235 // the corresponding module when the symbol address is requested.
236 for (auto &KV : ModuleMap)
237 if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
9
Calling 'EmissionDeferredModule::find'
238 return Symbol;
239
240 // If no definition found anywhere return a null symbol.
241 return nullptr;
242 }
243
244 /// Get the address of the given symbol in the context of the of
245 /// compiled modules represented by the key K.
246 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
247 bool ExportedSymbolsOnly) {
248 assert(ModuleMap.count(K) && "VModuleKey K not valid here")((ModuleMap.count(K) && "VModuleKey K not valid here"
) ? static_cast<void> (0) : __assert_fail ("ModuleMap.count(K) && \"VModuleKey K not valid here\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 248, __PRETTY_FUNCTION__))
;
249 return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
250 }
251
252 /// Immediately emit and finalize the module represented by the given
253 /// key.
254 Error emitAndFinalize(VModuleKey K) {
255 assert(ModuleMap.count(K) && "VModuleKey K not valid here")((ModuleMap.count(K) && "VModuleKey K not valid here"
) ? static_cast<void> (0) : __assert_fail ("ModuleMap.count(K) && \"VModuleKey K not valid here\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
, 255, __PRETTY_FUNCTION__))
;
256 return ModuleMap[K]->emitAndFinalize(BaseLayer);
257 }
258};
259
260template <typename BaseLayerT>
261LazyEmittingLayer<BaseLayerT>::LazyEmittingLayer(BaseLayerT &BaseLayer)
262 : BaseLayer(BaseLayer) {}
263
264} // end namespace orc
265} // end namespace llvm
266
267#endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/FunctionExtras.h

1//===- FunctionExtras.h - Function type erasure utilities -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file provides a collection of function (or more generally, callable)
10/// type erasure utilities supplementing those provided by the standard library
11/// in `<function>`.
12///
13/// It provides `unique_function`, which works like `std::function` but supports
14/// move-only callable objects.
15///
16/// Future plans:
17/// - Add a `function` that provides const, volatile, and ref-qualified support,
18/// which doesn't work with `std::function`.
19/// - Provide support for specifying multiple signatures to type erase callable
20/// objects with an overload set, such as those produced by generic lambdas.
21/// - Expand to include a copyable utility that directly replaces std::function
22/// but brings the above improvements.
23///
24/// Note that LLVM's utilities are greatly simplified by not supporting
25/// allocators.
26///
27/// If the standard library ever begins to provide comparable facilities we can
28/// consider switching to those.
29///
30//===----------------------------------------------------------------------===//
31
32#ifndef LLVM_ADT_FUNCTION_EXTRAS_H
33#define LLVM_ADT_FUNCTION_EXTRAS_H
34
35#include "llvm/ADT/PointerIntPair.h"
36#include "llvm/ADT/PointerUnion.h"
37#include "llvm/Support/type_traits.h"
38#include <memory>
39
40namespace llvm {
41
42template <typename FunctionT> class unique_function;
43
44template <typename ReturnT, typename... ParamTs>
45class unique_function<ReturnT(ParamTs...)> {
46 static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
47
48 // MSVC has a bug and ICEs if we give it a particular dependent value
49 // expression as part of the `std::conditional` below. To work around this,
50 // we build that into a template struct's constexpr bool.
51 template <typename T> struct IsSizeLessThanThresholdT {
52 static constexpr bool value = sizeof(T) <= (2 * sizeof(void *));
53 };
54
55 // Provide a type function to map parameters that won't observe extra copies
56 // or moves and which are small enough to likely pass in register to values
57 // and all other types to l-value reference types. We use this to compute the
58 // types used in our erased call utility to minimize copies and moves unless
59 // doing so would force things unnecessarily into memory.
60 //
61 // The heuristic used is related to common ABI register passing conventions.
62 // It doesn't have to be exact though, and in one way it is more strict
63 // because we want to still be able to observe either moves *or* copies.
64 template <typename T>
65 using AdjustedParamT = typename std::conditional<
66 !std::is_reference<T>::value &&
67 llvm::is_trivially_copy_constructible<T>::value &&
68 llvm::is_trivially_move_constructible<T>::value &&
69 IsSizeLessThanThresholdT<T>::value,
70 T, T &>::type;
71
72 // The type of the erased function pointer we use as a callback to dispatch to
73 // the stored callable when it is trivial to move and destroy.
74 using CallPtrT = ReturnT (*)(void *CallableAddr,
75 AdjustedParamT<ParamTs>... Params);
76 using MovePtrT = void (*)(void *LHSCallableAddr, void *RHSCallableAddr);
77 using DestroyPtrT = void (*)(void *CallableAddr);
78
79 /// A struct to hold a single trivial callback with sufficient alignment for
80 /// our bitpacking.
81 struct alignas(8) TrivialCallback {
82 CallPtrT CallPtr;
83 };
84
85 /// A struct we use to aggregate three callbacks when we need full set of
86 /// operations.
87 struct alignas(8) NonTrivialCallbacks {
88 CallPtrT CallPtr;
89 MovePtrT MovePtr;
90 DestroyPtrT DestroyPtr;
91 };
92
93 // Create a pointer union between either a pointer to a static trivial call
94 // pointer in a struct or a pointer to a static struct of the call, move, and
95 // destroy pointers.
96 using CallbackPointerUnionT =
97 PointerUnion<TrivialCallback *, NonTrivialCallbacks *>;
98
99 // The main storage buffer. This will either have a pointer to out-of-line
100 // storage or an inline buffer storing the callable.
101 union StorageUnionT {
102 // For out-of-line storage we keep a pointer to the underlying storage and
103 // the size. This is enough to deallocate the memory.
104 struct OutOfLineStorageT {
105 void *StoragePtr;
106 size_t Size;
107 size_t Alignment;
108 } OutOfLineStorage;
109 static_assert(
110 sizeof(OutOfLineStorageT) <= InlineStorageSize,
111 "Should always use all of the out-of-line storage for inline storage!");
112
113 // For in-line storage, we just provide an aligned character buffer. We
114 // provide three pointers worth of storage here.
115 typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type
116 InlineStorage;
117 } StorageUnion;
118
119 // A compressed pointer to either our dispatching callback or our table of
120 // dispatching callbacks and the flag for whether the callable itself is
121 // stored inline or not.
122 PointerIntPair<CallbackPointerUnionT, 1, bool> CallbackAndInlineFlag;
123
124 bool isInlineStorage() const { return CallbackAndInlineFlag.getInt(); }
125
126 bool isTrivialCallback() const {
127 return CallbackAndInlineFlag.getPointer().template is<TrivialCallback *>();
128 }
129
130 CallPtrT getTrivialCallback() const {
131 return CallbackAndInlineFlag.getPointer().template get<TrivialCallback *>()->CallPtr;
132 }
133
134 NonTrivialCallbacks *getNonTrivialCallbacks() const {
135 return CallbackAndInlineFlag.getPointer()
136 .template get<NonTrivialCallbacks *>();
137 }
138
139 void *getInlineStorage() { return &StorageUnion.InlineStorage; }
140
141 void *getOutOfLineStorage() {
142 return StorageUnion.OutOfLineStorage.StoragePtr;
143 }
144 size_t getOutOfLineStorageSize() const {
145 return StorageUnion.OutOfLineStorage.Size;
146 }
147 size_t getOutOfLineStorageAlignment() const {
148 return StorageUnion.OutOfLineStorage.Alignment;
149 }
150
151 void setOutOfLineStorage(void *Ptr, size_t Size, size_t Alignment) {
152 StorageUnion.OutOfLineStorage = {Ptr, Size, Alignment};
153 }
154
155 template <typename CallableT>
156 static ReturnT CallImpl(void *CallableAddr, AdjustedParamT<ParamTs>... Params) {
157 return (*reinterpret_cast<CallableT *>(CallableAddr))(
158 std::forward<ParamTs>(Params)...);
159 }
160
161 template <typename CallableT>
162 static void MoveImpl(void *LHSCallableAddr, void *RHSCallableAddr) noexcept {
163 new (LHSCallableAddr)
164 CallableT(std::move(*reinterpret_cast<CallableT *>(RHSCallableAddr)));
165 }
166
167 template <typename CallableT>
168 static void DestroyImpl(void *CallableAddr) noexcept {
169 reinterpret_cast<CallableT *>(CallableAddr)->~CallableT();
170 }
171
172public:
173 unique_function() = default;
174 unique_function(std::nullptr_t /*null_callable*/) {}
175
176 ~unique_function() {
177 if (!CallbackAndInlineFlag.getPointer())
19
Taking true branch
178 return;
179
180 // Cache this value so we don't re-check it after type-erased operations.
181 bool IsInlineStorage = isInlineStorage();
182
183 if (!isTrivialCallback())
184 getNonTrivialCallbacks()->DestroyPtr(
185 IsInlineStorage ? getInlineStorage() : getOutOfLineStorage());
186
187 if (!IsInlineStorage)
188 deallocate_buffer(getOutOfLineStorage(), getOutOfLineStorageSize(),
189 getOutOfLineStorageAlignment());
190 }
20
Potential memory leak
191
192 unique_function(unique_function &&RHS) noexcept {
193 // Copy the callback and inline flag.
194 CallbackAndInlineFlag = RHS.CallbackAndInlineFlag;
195
196 // If the RHS is empty, just copying the above is sufficient.
197 if (!RHS)
198 return;
199
200 if (!isInlineStorage()) {
201 // The out-of-line case is easiest to move.
202 StorageUnion.OutOfLineStorage = RHS.StorageUnion.OutOfLineStorage;
203 } else if (isTrivialCallback()) {
204 // Move is trivial, just memcpy the bytes across.
205 memcpy(getInlineStorage(), RHS.getInlineStorage(), InlineStorageSize);
206 } else {
207 // Non-trivial move, so dispatch to a type-erased implementation.
208 getNonTrivialCallbacks()->MovePtr(getInlineStorage(),
209 RHS.getInlineStorage());
210 }
211
212 // Clear the old callback and inline flag to get back to as-if-null.
213 RHS.CallbackAndInlineFlag = {};
214
215#ifndef NDEBUG
216 // In debug builds, we also scribble across the rest of the storage.
217 memset(RHS.getInlineStorage(), 0xAD, InlineStorageSize);
218#endif
219 }
220
221 unique_function &operator=(unique_function &&RHS) noexcept {
222 if (this == &RHS)
223 return *this;
224
225 // Because we don't try to provide any exception safety guarantees we can
226 // implement move assignment very simply by first destroying the current
227 // object and then move-constructing over top of it.
228 this->~unique_function();
229 new (this) unique_function(std::move(RHS));
230 return *this;
231 }
232
233 template <typename CallableT> unique_function(CallableT Callable) {
234 bool IsInlineStorage = true;
235 void *CallableAddr = getInlineStorage();
236 if (sizeof(CallableT) > InlineStorageSize ||
237 alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
238 IsInlineStorage = false;
239 // Allocate out-of-line storage. FIXME: Use an explicit alignment
240 // parameter in C++17 mode.
241 auto Size = sizeof(CallableT);
242 auto Alignment = alignof(CallableT);
243 CallableAddr = allocate_buffer(Size, Alignment);
14
Calling 'allocate_buffer'
16
Returned allocated memory
244 setOutOfLineStorage(CallableAddr, Size, Alignment);
245 }
246
247 // Now move into the storage.
248 new (CallableAddr) CallableT(std::move(Callable));
249
250 // See if we can create a trivial callback. We need the callable to be
251 // trivially moved and trivially destroyed so that we don't have to store
252 // type erased callbacks for those operations.
253 //
254 // FIXME: We should use constexpr if here and below to avoid instantiating
255 // the non-trivial static objects when unnecessary. While the linker should
256 // remove them, it is still wasteful.
257 if (llvm::is_trivially_move_constructible<CallableT>::value
16.1
'value' is false
16.1
'value' is false
16.1
'value' is false
16.1
'value' is false
16.1
'value' is false
&&
258 std::is_trivially_destructible<CallableT>::value) {
259 // We need to create a nicely aligned object. We use a static variable
260 // for this because it is a trivial struct.
261 static TrivialCallback Callback = { &CallImpl<CallableT> };
262
263 CallbackAndInlineFlag = {&Callback, IsInlineStorage};
264 return;
265 }
266
267 // Otherwise, we need to point at an object that contains all the different
268 // type erased behaviors needed. Create a static instance of the struct type
269 // here and then use a pointer to that.
270 static NonTrivialCallbacks Callbacks = {
271 &CallImpl<CallableT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
272
273 CallbackAndInlineFlag = {&Callbacks, IsInlineStorage};
274 }
275
276 ReturnT operator()(ParamTs... Params) {
277 void *CallableAddr =
278 isInlineStorage() ? getInlineStorage() : getOutOfLineStorage();
279
280 return (isTrivialCallback()
281 ? getTrivialCallback()
282 : getNonTrivialCallbacks()->CallPtr)(CallableAddr, Params...);
283 }
284
285 explicit operator bool() const {
286 return (bool)CallbackAndInlineFlag.getPointer();
287 }
288};
289
290} // end namespace llvm
291
292#endif // LLVM_ADT_FUNCTION_H

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Compiler.h

1//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines several macros, based on the current compiler. This allows
10// use of compiler-specific features in a way that remains portable. This header
11// can be included from either C or C++.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_COMPILER_H
16#define LLVM_SUPPORT_COMPILER_H
17
18#include "llvm/Config/llvm-config.h"
19
20#ifdef __cplusplus201402L
21#include <new>
22#endif
23#include <stddef.h>
24
25#if defined(_MSC_VER)
26#include <sal.h>
27#endif
28
29#ifndef __has_feature
30# define0 __has_feature(x)0 0
31#endif
32
33#ifndef __has_extension
34# define0 __has_extension(x)0 0
35#endif
36
37#ifndef __has_attribute
38# define0 __has_attribute(x)0 0
39#endif
40
41#ifndef __has_builtin
42# define0 __has_builtin(x)0 0
43#endif
44
45// Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in
46// C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid.
47#ifndef LLVM_HAS_CPP_ATTRIBUTE
48#if defined(__cplusplus201402L) && defined(__has_cpp_attribute)0
49# define LLVM_HAS_CPP_ATTRIBUTE(x)0 __has_cpp_attribute(x)0
50#else
51# define LLVM_HAS_CPP_ATTRIBUTE(x)0 0
52#endif
53#endif
54
55/// \macro LLVM_GNUC_PREREQ
56/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
57/// available.
58#ifndef LLVM_GNUC_PREREQ
59# if defined(__GNUC__4) && defined(__GNUC_MINOR__2) && defined(__GNUC_PATCHLEVEL__1)
60# define LLVM_GNUC_PREREQ(maj, min, patch)((4 << 20) + (2 << 10) + 1 >= ((maj) << 20
) + ((min) << 10) + (patch))
\
61 ((__GNUC__4 << 20) + (__GNUC_MINOR__2 << 10) + __GNUC_PATCHLEVEL__1 >= \
62 ((maj) << 20) + ((min) << 10) + (patch))
63# elif defined(__GNUC__4) && defined(__GNUC_MINOR__2)
64# define LLVM_GNUC_PREREQ(maj, min, patch)((4 << 20) + (2 << 10) + 1 >= ((maj) << 20
) + ((min) << 10) + (patch))
\
65 ((__GNUC__4 << 20) + (__GNUC_MINOR__2 << 10) >= ((maj) << 20) + ((min) << 10))
66# else
67# define LLVM_GNUC_PREREQ(maj, min, patch)((4 << 20) + (2 << 10) + 1 >= ((maj) << 20
) + ((min) << 10) + (patch))
0
68# endif
69#endif
70
71/// \macro LLVM_MSC_PREREQ
72/// Is the compiler MSVC of at least the specified version?
73/// The common \param version values to check for are:
74/// * 1910: VS2017, version 15.1 & 15.2
75/// * 1911: VS2017, version 15.3 & 15.4
76/// * 1912: VS2017, version 15.5
77/// * 1913: VS2017, version 15.6
78/// * 1914: VS2017, version 15.7
79/// * 1915: VS2017, version 15.8
80/// * 1916: VS2017, version 15.9
81/// * 1920: VS2019, version 16.0
82/// * 1921: VS2019, version 16.1
83#ifdef _MSC_VER
84#define LLVM_MSC_PREREQ(version)0 (_MSC_VER >= (version))
85
86// We require at least MSVC 2017.
87#if !LLVM_MSC_PREREQ(1910)0
88#error LLVM requires at least MSVC 2017.
89#endif
90
91#else
92#define LLVM_MSC_PREREQ(version)0 0
93#endif
94
95/// Does the compiler support ref-qualifiers for *this?
96///
97/// Sadly, this is separate from just rvalue reference support because GCC
98/// and MSVC implemented this later than everything else. This appears to be
99/// corrected in MSVC 2019 but not MSVC 2017.
100#if __has_feature(cxx_rvalue_references)1 || LLVM_GNUC_PREREQ(4, 8, 1)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((8) << 10) + (1))
101#define LLVM_HAS_RVALUE_REFERENCE_THIS1 1
102#else
103#define LLVM_HAS_RVALUE_REFERENCE_THIS1 0
104#endif
105
106/// Expands to '&' if ref-qualifiers for *this are supported.
107///
108/// This can be used to provide lvalue/rvalue overrides of member functions.
109/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
110#if LLVM_HAS_RVALUE_REFERENCE_THIS1
111#define LLVM_LVALUE_FUNCTION& &
112#else
113#define LLVM_LVALUE_FUNCTION&
114#endif
115
116/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
117/// into a shared library, then the class should be private to the library and
118/// not accessible from outside it. Can also be used to mark variables and
119/// functions, making them private to any shared library they are linked into.
120/// On PE/COFF targets, library visibility is the default, so this isn't needed.
121///
122/// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with
123/// this attribute will be made public and visible outside of any shared library
124/// they are linked in to.
125#if (__has_attribute(visibility)1 || LLVM_GNUC_PREREQ(4, 0, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((0) << 10) + (0))
) && \
126 !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)
127#define LLVM_LIBRARY_VISIBILITY__attribute__ ((visibility("hidden"))) __attribute__ ((visibility("hidden")))
128#define LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default"))) __attribute__ ((visibility("default")))
129#else
130#define LLVM_LIBRARY_VISIBILITY__attribute__ ((visibility("hidden")))
131#define LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default")))
132#endif
133
134#if defined(__GNUC__4)
135#define LLVM_PREFETCH(addr, rw, locality)__builtin_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
136#else
137#define LLVM_PREFETCH(addr, rw, locality)__builtin_prefetch(addr, rw, locality)
138#endif
139
140#if __has_attribute(used)1 || LLVM_GNUC_PREREQ(3, 1, 0)((4 << 20) + (2 << 10) + 1 >= ((3) << 20
) + ((1) << 10) + (0))
141#define LLVM_ATTRIBUTE_USED__attribute__((__used__)) __attribute__((__used__))
142#else
143#define LLVM_ATTRIBUTE_USED__attribute__((__used__))
144#endif
145
146/// LLVM_NODISCARD - Warn if a type or return value is discarded.
147
148// Use the 'nodiscard' attribute in C++17 or newer mode.
149#if __cplusplus201402L > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard)201907L
150#define LLVM_NODISCARD[[clang::warn_unused_result]] [[nodiscard]]
151#elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result)201907L
152#define LLVM_NODISCARD[[clang::warn_unused_result]] [[clang::warn_unused_result]]
153// Clang in C++14 mode claims that it has the 'nodiscard' attribute, but also
154// warns in the pedantic mode that 'nodiscard' is a C++17 extension (PR33518).
155// Use the 'nodiscard' attribute in C++14 mode only with GCC.
156// TODO: remove this workaround when PR33518 is resolved.
157#elif defined(__GNUC__4) && LLVM_HAS_CPP_ATTRIBUTE(nodiscard)201907L
158#define LLVM_NODISCARD[[clang::warn_unused_result]] [[nodiscard]]
159#else
160#define LLVM_NODISCARD[[clang::warn_unused_result]]
161#endif
162
163// Indicate that a non-static, non-const C++ member function reinitializes
164// the entire object to a known state, independent of the previous state of
165// the object.
166//
167// The clang-tidy check bugprone-use-after-move recognizes this attribute as a
168// marker that a moved-from object has left the indeterminate state and can be
169// reused.
170#if LLVM_HAS_CPP_ATTRIBUTE(clang::reinitializes)1
171#define LLVM_ATTRIBUTE_REINITIALIZES[[clang::reinitializes]] [[clang::reinitializes]]
172#else
173#define LLVM_ATTRIBUTE_REINITIALIZES[[clang::reinitializes]]
174#endif
175
176// Some compilers warn about unused functions. When a function is sometimes
177// used or not depending on build settings (e.g. a function only called from
178// within "assert"), this attribute can be used to suppress such warnings.
179//
180// However, it shouldn't be used for unused *variables*, as those have a much
181// more portable solution:
182// (void)unused_var_name;
183// Prefer cast-to-void wherever it is sufficient.
184#if __has_attribute(unused)1 || LLVM_GNUC_PREREQ(3, 1, 0)((4 << 20) + (2 << 10) + 1 >= ((3) << 20
) + ((1) << 10) + (0))
185#define LLVM_ATTRIBUTE_UNUSED__attribute__((__unused__)) __attribute__((__unused__))
186#else
187#define LLVM_ATTRIBUTE_UNUSED__attribute__((__unused__))
188#endif
189
190// FIXME: Provide this for PE/COFF targets.
191#if (__has_attribute(weak)1 || LLVM_GNUC_PREREQ(4, 0, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((0) << 10) + (0))
) && \
192 (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32))
193#define LLVM_ATTRIBUTE_WEAK__attribute__((__weak__)) __attribute__((__weak__))
194#else
195#define LLVM_ATTRIBUTE_WEAK__attribute__((__weak__))
196#endif
197
198// Prior to clang 3.2, clang did not accept any spelling of
199// __has_attribute(const), so assume it is supported.
200#if defined(__clang__1) || defined(__GNUC__4)
201// aka 'CONST' but following LLVM Conventions.
202#define LLVM_READNONE__attribute__((__const__)) __attribute__((__const__))
203#else
204#define LLVM_READNONE__attribute__((__const__))
205#endif
206
207#if __has_attribute(pure)1 || defined(__GNUC__4)
208// aka 'PURE' but following LLVM Conventions.
209#define LLVM_READONLY__attribute__((__pure__)) __attribute__((__pure__))
210#else
211#define LLVM_READONLY__attribute__((__pure__))
212#endif
213
214#if __has_builtin(__builtin_expect)1 || LLVM_GNUC_PREREQ(4, 0, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((0) << 10) + (0))
215#define LLVM_LIKELY(EXPR)__builtin_expect((bool)(EXPR), true) __builtin_expect((bool)(EXPR), true)
216#define LLVM_UNLIKELY(EXPR)__builtin_expect((bool)(EXPR), false) __builtin_expect((bool)(EXPR), false)
217#else
218#define LLVM_LIKELY(EXPR)__builtin_expect((bool)(EXPR), true) (EXPR)
219#define LLVM_UNLIKELY(EXPR)__builtin_expect((bool)(EXPR), false) (EXPR)
220#endif
221
222/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
223/// mark a method "not for inlining".
224#if __has_attribute(noinline)1 || LLVM_GNUC_PREREQ(3, 4, 0)((4 << 20) + (2 << 10) + 1 >= ((3) << 20
) + ((4) << 10) + (0))
225#define LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) __attribute__((noinline))
226#elif defined(_MSC_VER)
227#define LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) __declspec(noinline)
228#else
229#define LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline))
230#endif
231
232/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
233/// so, mark a method "always inline" because it is performance sensitive. GCC
234/// 3.4 supported this but is buggy in various cases and produces unimplemented
235/// errors, just use it in GCC 4.0 and later.
236#if __has_attribute(always_inline)1 || LLVM_GNUC_PREREQ(4, 0, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((0) << 10) + (0))
237#define LLVM_ATTRIBUTE_ALWAYS_INLINE__attribute__((always_inline)) __attribute__((always_inline))
238#elif defined(_MSC_VER)
239#define LLVM_ATTRIBUTE_ALWAYS_INLINE__attribute__((always_inline)) __forceinline
240#else
241#define LLVM_ATTRIBUTE_ALWAYS_INLINE__attribute__((always_inline))
242#endif
243
244#ifdef __GNUC__4
245#define LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) __attribute__((noreturn))
246#elif defined(_MSC_VER)
247#define LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) __declspec(noreturn)
248#else
249#define LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
250#endif
251
252#if __has_attribute(returns_nonnull)1 || LLVM_GNUC_PREREQ(4, 9, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((9) << 10) + (0))
253#define LLVM_ATTRIBUTE_RETURNS_NONNULL__attribute__((returns_nonnull)) __attribute__((returns_nonnull))
254#elif defined(_MSC_VER)
255#define LLVM_ATTRIBUTE_RETURNS_NONNULL__attribute__((returns_nonnull)) _Ret_notnull_
256#else
257#define LLVM_ATTRIBUTE_RETURNS_NONNULL__attribute__((returns_nonnull))
258#endif
259
260/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
261/// pointer that does not alias any other valid pointer.
262#ifdef __GNUC__4
263#define LLVM_ATTRIBUTE_RETURNS_NOALIAS__attribute__((__malloc__)) __attribute__((__malloc__))
264#elif defined(_MSC_VER)
265#define LLVM_ATTRIBUTE_RETURNS_NOALIAS__attribute__((__malloc__)) __declspec(restrict)
266#else
267#define LLVM_ATTRIBUTE_RETURNS_NOALIAS__attribute__((__malloc__))
268#endif
269
270/// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
271#if __cplusplus201402L > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)201603L
272#define LLVM_FALLTHROUGH[[gnu::fallthrough]] [[fallthrough]]
273#elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough)201603L
274#define LLVM_FALLTHROUGH[[gnu::fallthrough]] [[gnu::fallthrough]]
275#elif __has_attribute(fallthrough)1
276#define LLVM_FALLTHROUGH[[gnu::fallthrough]] __attribute__((fallthrough))
277#elif LLVM_HAS_CPP_ATTRIBUTE(clang::fallthrough)201603L
278#define LLVM_FALLTHROUGH[[gnu::fallthrough]] [[clang::fallthrough]]
279#else
280#define LLVM_FALLTHROUGH[[gnu::fallthrough]]
281#endif
282
283/// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
284/// they are constant initialized.
285#if LLVM_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization)1
286#define LLVM_REQUIRE_CONSTANT_INITIALIZATION[[clang::require_constant_initialization]] \
287 [[clang::require_constant_initialization]]
288#else
289#define LLVM_REQUIRE_CONSTANT_INITIALIZATION[[clang::require_constant_initialization]]
290#endif
291
292/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
293/// pedantic diagnostics.
294#ifdef __GNUC__4
295#define LLVM_EXTENSION__extension__ __extension__
296#else
297#define LLVM_EXTENSION__extension__
298#endif
299
300// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
301#if __has_feature(attribute_deprecated_with_message)1
302# define LLVM_ATTRIBUTE_DEPRECATED(decl, message)decl __attribute__((deprecated(message))) \
303 decl __attribute__((deprecated(message)))
304#elif defined(__GNUC__4)
305# define LLVM_ATTRIBUTE_DEPRECATED(decl, message)decl __attribute__((deprecated(message))) \
306 decl __attribute__((deprecated))
307#elif defined(_MSC_VER)
308# define LLVM_ATTRIBUTE_DEPRECATED(decl, message)decl __attribute__((deprecated(message))) \
309 __declspec(deprecated(message)) decl
310#else
311# define LLVM_ATTRIBUTE_DEPRECATED(decl, message)decl __attribute__((deprecated(message))) \
312 decl
313#endif
314
315/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
316/// to an expression which states that it is undefined behavior for the
317/// compiler to reach this point. Otherwise is not defined.
318#if __has_builtin(__builtin_unreachable)1 || LLVM_GNUC_PREREQ(4, 5, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((5) << 10) + (0))
319# define LLVM_BUILTIN_UNREACHABLE__builtin_unreachable() __builtin_unreachable()
320#elif defined(_MSC_VER)
321# define LLVM_BUILTIN_UNREACHABLE__builtin_unreachable() __assume(false)
322#endif
323
324/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
325/// which causes the program to exit abnormally.
326#if __has_builtin(__builtin_trap)1 || LLVM_GNUC_PREREQ(4, 3, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((3) << 10) + (0))
327# define LLVM_BUILTIN_TRAP__builtin_trap() __builtin_trap()
328#elif defined(_MSC_VER)
329// The __debugbreak intrinsic is supported by MSVC, does not require forward
330// declarations involving platform-specific typedefs (unlike RaiseException),
331// results in a call to vectored exception handlers, and encodes to a short
332// instruction that still causes the trapping behavior we want.
333# define LLVM_BUILTIN_TRAP__builtin_trap() __debugbreak()
334#else
335# define LLVM_BUILTIN_TRAP__builtin_trap() *(volatile int*)0x11 = 0
336#endif
337
338/// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
339/// an expression which causes the program to break while running
340/// under a debugger.
341#if __has_builtin(__builtin_debugtrap)1
342# define LLVM_BUILTIN_DEBUGTRAP__builtin_debugtrap() __builtin_debugtrap()
343#elif defined(_MSC_VER)
344// The __debugbreak intrinsic is supported by MSVC and breaks while
345// running under the debugger, and also supports invoking a debugger
346// when the OS is configured appropriately.
347# define LLVM_BUILTIN_DEBUGTRAP__builtin_debugtrap() __debugbreak()
348#else
349// Just continue execution when built with compilers that have no
350// support. This is a debugging aid and not intended to force the
351// program to abort if encountered.
352# define LLVM_BUILTIN_DEBUGTRAP__builtin_debugtrap()
353#endif
354
355/// \macro LLVM_ASSUME_ALIGNED
356/// Returns a pointer with an assumed alignment.
357#if __has_builtin(__builtin_assume_aligned)1 || LLVM_GNUC_PREREQ(4, 7, 0)((4 << 20) + (2 << 10) + 1 >= ((4) << 20
) + ((7) << 10) + (0))
358# define LLVM_ASSUME_ALIGNED(p, a)__builtin_assume_aligned(p, a) __builtin_assume_aligned(p, a)
359#elif defined(LLVM_BUILTIN_UNREACHABLE__builtin_unreachable())
360// As of today, clang does not support __builtin_assume_aligned.
361# define LLVM_ASSUME_ALIGNED(p, a)__builtin_assume_aligned(p, a) \
362 (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE__builtin_unreachable(), (p)))
363#else
364# define LLVM_ASSUME_ALIGNED(p, a)__builtin_assume_aligned(p, a) (p)
365#endif
366
367/// \macro LLVM_PACKED
368/// Used to specify a packed structure.
369/// LLVM_PACKED(
370/// struct A {
371/// int i;
372/// int j;
373/// int k;
374/// long long l;
375/// });
376///
377/// LLVM_PACKED_START
378/// struct B {
379/// int i;
380/// int j;
381/// int k;
382/// long long l;
383/// };
384/// LLVM_PACKED_END
385#ifdef _MSC_VER
386# define LLVM_PACKED(d)d __attribute__((packed)) __pragma(pack(push, 1)) d __pragma(pack(pop))
387# define LLVM_PACKED_STARTpack(push, 1) __pragma(pack(push, 1))
388# define LLVM_PACKED_ENDpack(pop) __pragma(pack(pop))
389#else
390# define LLVM_PACKED(d)d __attribute__((packed)) d __attribute__((packed))
391# define LLVM_PACKED_STARTpack(push, 1) _Pragma("pack(push, 1)")pack(push, 1)
392# define LLVM_PACKED_ENDpack(pop) _Pragma("pack(pop)")pack(pop)
393#endif
394
395/// \macro LLVM_PTR_SIZE
396/// A constant integer equivalent to the value of sizeof(void*).
397/// Generally used in combination with alignas or when doing computation in the
398/// preprocessor.
399#ifdef __SIZEOF_POINTER__8
400# define LLVM_PTR_SIZE8 __SIZEOF_POINTER__8
401#elif defined(_WIN64)
402# define LLVM_PTR_SIZE8 8
403#elif defined(_WIN32)
404# define LLVM_PTR_SIZE8 4
405#elif defined(_MSC_VER)
406# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
407#else
408# define LLVM_PTR_SIZE8 sizeof(void *)
409#endif
410
411/// \macro LLVM_MEMORY_SANITIZER_BUILD
412/// Whether LLVM itself is built with MemorySanitizer instrumentation.
413#if __has_feature(memory_sanitizer)0
414# define LLVM_MEMORY_SANITIZER_BUILD0 1
415# include <sanitizer/msan_interface.h>
416# define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE __attribute__((no_sanitize_memory))
417#else
418# define LLVM_MEMORY_SANITIZER_BUILD0 0
419# define __msan_allocated_memory(p, size)
420# define __msan_unpoison(p, size)
421# define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
422#endif
423
424/// \macro LLVM_ADDRESS_SANITIZER_BUILD
425/// Whether LLVM itself is built with AddressSanitizer instrumentation.
426#if __has_feature(address_sanitizer)0 || defined(__SANITIZE_ADDRESS__)
427# define LLVM_ADDRESS_SANITIZER_BUILD0 1
428# include <sanitizer/asan_interface.h>
429#else
430# define LLVM_ADDRESS_SANITIZER_BUILD0 0
431# define __asan_poison_memory_region(p, size)
432# define __asan_unpoison_memory_region(p, size)
433#endif
434
435/// \macro LLVM_THREAD_SANITIZER_BUILD
436/// Whether LLVM itself is built with ThreadSanitizer instrumentation.
437#if __has_feature(thread_sanitizer)0 || defined(__SANITIZE_THREAD__)
438# define LLVM_THREAD_SANITIZER_BUILD0 1
439#else
440# define LLVM_THREAD_SANITIZER_BUILD0 0
441#endif
442
443#if LLVM_THREAD_SANITIZER_BUILD0
444// Thread Sanitizer is a tool that finds races in code.
445// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
446// tsan detects these exact functions by name.
447#ifdef __cplusplus201402L
448extern "C" {
449#endif
450void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
451void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
452void AnnotateIgnoreWritesBegin(const char *file, int line);
453void AnnotateIgnoreWritesEnd(const char *file, int line);
454#ifdef __cplusplus201402L
455}
456#endif
457
458// This marker is used to define a happens-before arc. The race detector will
459// infer an arc from the begin to the end when they share the same pointer
460// argument.
461# define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Compiler.h", __LINE__461, cv)
462
463// This marker defines the destination of a happens-before arc.
464# define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Compiler.h", __LINE__464, cv)
465
466// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
467# define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Compiler.h", __LINE__467)
468
469// Resume checking for racy writes.
470# define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Compiler.h", __LINE__470)
471#else
472# define TsanHappensBefore(cv)
473# define TsanHappensAfter(cv)
474# define TsanIgnoreWritesBegin()
475# define TsanIgnoreWritesEnd()
476#endif
477
478/// \macro LLVM_NO_SANITIZE
479/// Disable a particular sanitizer for a function.
480#if __has_attribute(no_sanitize)1
481#define LLVM_NO_SANITIZE(KIND)__attribute__((no_sanitize(KIND))) __attribute__((no_sanitize(KIND)))
482#else
483#define LLVM_NO_SANITIZE(KIND)__attribute__((no_sanitize(KIND)))
484#endif
485
486/// Mark debug helper function definitions like dump() that should not be
487/// stripped from debug builds.
488/// Note that you should also surround dump() functions with
489/// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
490/// get stripped in release builds.
491// FIXME: Move this to a private config.h as it's not usable in public headers.
492#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
493#define LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) LLVM_ATTRIBUTE_USED__attribute__((__used__))
494#else
495#define LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline))
496#endif
497
498/// \macro LLVM_PRETTY_FUNCTION
499/// Gets a user-friendly looking function signature for the current scope
500/// using the best available method on each platform. The exact format of the
501/// resulting string is implementation specific and non-portable, so this should
502/// only be used, for example, for logging or diagnostics.
503#if defined(_MSC_VER)
504#define LLVM_PRETTY_FUNCTION__PRETTY_FUNCTION__ __FUNCSIG__
505#elif defined(__GNUC__4) || defined(__clang__1)
506#define LLVM_PRETTY_FUNCTION__PRETTY_FUNCTION__ __PRETTY_FUNCTION__
507#else
508#define LLVM_PRETTY_FUNCTION__PRETTY_FUNCTION__ __func__
509#endif
510
511/// \macro LLVM_THREAD_LOCAL
512/// A thread-local storage specifier which can be used with globals,
513/// extern globals, and static globals.
514///
515/// This is essentially an extremely restricted analog to C++11's thread_local
516/// support. It uses thread_local if available, falling back on gcc __thread
517/// if not. __thread doesn't support many of the C++11 thread_local's
518/// features. You should only use this for PODs that you can statically
519/// initialize to some constant value. In almost all circumstances this is most
520/// appropriate for use with a pointer, integer, or small aggregation of
521/// pointers and integers.
522#if LLVM_ENABLE_THREADS1
523#if __has_feature(cxx_thread_local)1 || defined(_MSC_VER)
524#define LLVM_THREAD_LOCALthread_local thread_local
525#else
526// Clang, GCC, and other compatible compilers used __thread prior to C++11 and
527// we only need the restricted functionality that provides.
528#define LLVM_THREAD_LOCALthread_local __thread
529#endif
530#else // !LLVM_ENABLE_THREADS
531// If threading is disabled entirely, this compiles to nothing and you get
532// a normal global variable.
533#define LLVM_THREAD_LOCALthread_local
534#endif
535
536/// \macro LLVM_ENABLE_EXCEPTIONS
537/// Whether LLVM is built with exception support.
538#if __has_feature(cxx_exceptions)0
539#define LLVM_ENABLE_EXCEPTIONS 1
540#elif defined(__GNUC__4) && defined(__EXCEPTIONS)
541#define LLVM_ENABLE_EXCEPTIONS 1
542#elif defined(_MSC_VER) && defined(_CPPUNWIND)
543#define LLVM_ENABLE_EXCEPTIONS 1
544#endif
545
546#ifdef __cplusplus201402L
547namespace llvm {
548
549/// Allocate a buffer of memory with the given size and alignment.
550///
551/// When the compiler supports aligned operator new, this will use it to to
552/// handle even over-aligned allocations.
553///
554/// However, this doesn't make any attempt to leverage the fancier techniques
555/// like posix_memalign due to portability. It is mostly intended to allow
556/// compatibility with platforms that, after aligned allocation was added, use
557/// reduced default alignment.
558inline void *allocate_buffer(size_t Size, size_t Alignment) {
559 return ::operator new(Size
15
Memory is allocated
560#ifdef __cpp_aligned_new
561 ,
562 std::align_val_t(Alignment)
563#endif
564 );
565}
566
567/// Deallocate a buffer of memory with the given size and alignment.
568///
569/// If supported, this will used the sized delete operator. Also if supported,
570/// this will pass the alignment to the delete operator.
571///
572/// The pointer must have been allocated with the corresponding new operator,
573/// most likely using the above helper.
574inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
575 ::operator delete(Ptr
576#ifdef __cpp_sized_deallocation
577 ,
578 Size
579#endif
580#ifdef __cpp_aligned_new
581 ,
582 std::align_val_t(Alignment)
583#endif
584 );
585}
586
587} // End namespace llvm
588
589#endif // __cplusplus
590#endif