|
21 | 21 | #include "llvm/CodeGen/TargetInstrInfo.h"
|
22 | 22 | #include "llvm/CodeGen/TargetPassConfig.h"
|
23 | 23 | #include "llvm/CodeGen/TargetSubtargetInfo.h"
|
24 |
| -#include "llvm/ExecutionEngine/SectionMemoryManager.h" |
| 24 | +#include "llvm/ExecutionEngine/Orc/LLJIT.h" |
25 | 25 | #include "llvm/IR/BasicBlock.h"
|
26 | 26 | #include "llvm/IR/Instructions.h"
|
27 | 27 | #include "llvm/IR/LegacyPassManager.h"
|
28 | 28 | #include "llvm/MC/MCInstrInfo.h"
|
| 29 | +#include "llvm/Object/SymbolSize.h" |
29 | 30 | #include "llvm/Support/Alignment.h"
|
30 | 31 | #include "llvm/Support/MemoryBuffer.h"
|
31 | 32 | #include "llvm/Support/raw_ostream.h"
|
@@ -105,7 +106,7 @@ MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionName,
|
105 | 106 | FunctionType *FunctionType =
|
106 | 107 | FunctionType::get(ReturnType, {MemParamType}, false);
|
107 | 108 | Function *const F = Function::Create(
|
108 |
| - FunctionType, GlobalValue::InternalLinkage, FunctionName, Module); |
| 109 | + FunctionType, GlobalValue::ExternalLinkage, FunctionName, Module); |
109 | 110 | BasicBlock *BB = BasicBlock::Create(Module->getContext(), "", F);
|
110 | 111 | new UnreachableInst(Module->getContext(), BB);
|
111 | 112 | return MMI->getOrCreateMachineFunction(*F);
|
@@ -324,66 +325,48 @@ object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename) {
|
324 | 325 | return cantFail(object::ObjectFile::createObjectFile(Filename));
|
325 | 326 | }
|
326 | 327 |
|
327 |
| -namespace { |
328 |
| - |
329 |
| -// Implementation of this class relies on the fact that a single object with a |
330 |
| -// single function will be loaded into memory. |
331 |
| -class TrackingSectionMemoryManager : public SectionMemoryManager { |
332 |
| -public: |
333 |
| - explicit TrackingSectionMemoryManager(uintptr_t *CodeSize) |
334 |
| - : CodeSize(CodeSize) {} |
335 |
| - |
336 |
| - uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, |
337 |
| - unsigned SectionID, |
338 |
| - StringRef SectionName) override { |
339 |
| - *CodeSize = Size; |
340 |
| - return SectionMemoryManager::allocateCodeSection(Size, Alignment, SectionID, |
341 |
| - SectionName); |
342 |
| - } |
343 |
| - |
344 |
| -private: |
345 |
| - uintptr_t *const CodeSize = nullptr; |
346 |
| -}; |
347 |
| - |
348 |
| -} // namespace |
349 |
| - |
350 | 328 | Expected<ExecutableFunction> ExecutableFunction::create(
|
351 | 329 | std::unique_ptr<LLVMTargetMachine> TM,
|
352 | 330 | object::OwningBinary<object::ObjectFile> &&ObjectFileHolder) {
|
353 | 331 | assert(ObjectFileHolder.getBinary() && "cannot create object file");
|
354 | 332 | std::unique_ptr<LLVMContext> Ctx = std::make_unique<LLVMContext>();
|
355 |
| - // Initializing the execution engine. |
356 |
| - // We need to use the JIT EngineKind to be able to add an object file. |
357 |
| - LLVMLinkInMCJIT(); |
358 |
| - uintptr_t CodeSize = 0; |
359 |
| - std::string Error; |
360 |
| - std::unique_ptr<ExecutionEngine> EE( |
361 |
| - EngineBuilder(createModule(Ctx, TM->createDataLayout())) |
362 |
| - .setErrorStr(&Error) |
363 |
| - .setMCPU(TM->getTargetCPU()) |
364 |
| - .setEngineKind(EngineKind::JIT) |
365 |
| - .setMCJITMemoryManager( |
366 |
| - std::make_unique<TrackingSectionMemoryManager>(&CodeSize)) |
367 |
| - .create(TM.release())); |
368 |
| - if (!EE) |
369 |
| - return make_error<StringError>(Twine(Error), inconvertibleErrorCode()); |
370 |
| - // Adding the generated object file containing the assembled function. |
371 |
| - // The ExecutionEngine makes sure the object file is copied into an |
372 |
| - // executable page. |
373 |
| - EE->addObjectFile(std::move(ObjectFileHolder)); |
374 |
| - // Fetching function bytes. |
375 |
| - const uint64_t FunctionAddress = EE->getFunctionAddress(FunctionID); |
| 333 | + |
| 334 | + auto SymbolSizes = object::computeSymbolSizes(*ObjectFileHolder.getBinary()); |
| 335 | + // Get the size of the function that we want to call into (with the name of |
| 336 | + // FunctionID). This should always be the third symbol returned by |
| 337 | + // calculateSymbolSizes. |
| 338 | + assert(SymbolSizes.size() == 3); |
| 339 | + assert(cantFail(std::get<0>(SymbolSizes[2]).getName()) == FunctionID); |
| 340 | + uintptr_t CodeSize = std::get<1>(SymbolSizes[2]); |
| 341 | + |
| 342 | + auto EJITOrErr = orc::LLJITBuilder().create(); |
| 343 | + if (!EJITOrErr) |
| 344 | + return EJITOrErr.takeError(); |
| 345 | + |
| 346 | + auto EJIT = std::move(*EJITOrErr); |
| 347 | + |
| 348 | + if (auto ObjErr = |
| 349 | + EJIT->addObjectFile(std::get<1>(ObjectFileHolder.takeBinary()))) |
| 350 | + return std::move(ObjErr); |
| 351 | + |
| 352 | + auto FunctionAddressOrErr = EJIT->lookup(FunctionID); |
| 353 | + if (!FunctionAddressOrErr) |
| 354 | + return FunctionAddressOrErr.takeError(); |
| 355 | + |
| 356 | + const uint64_t FunctionAddress = FunctionAddressOrErr->getValue(); |
| 357 | + |
376 | 358 | assert(isAligned(kFunctionAlignment, FunctionAddress) &&
|
377 | 359 | "function is not properly aligned");
|
| 360 | + |
378 | 361 | StringRef FBytes =
|
379 | 362 | StringRef(reinterpret_cast<const char *>(FunctionAddress), CodeSize);
|
380 |
| - return ExecutableFunction(std::move(Ctx), std::move(EE), FBytes); |
| 363 | + return ExecutableFunction(std::move(Ctx), std::move(EJIT), FBytes); |
381 | 364 | }
|
382 | 365 |
|
383 | 366 | ExecutableFunction::ExecutableFunction(std::unique_ptr<LLVMContext> Ctx,
|
384 |
| - std::unique_ptr<ExecutionEngine> EE, |
| 367 | + std::unique_ptr<orc::LLJIT> EJIT, |
385 | 368 | StringRef FB)
|
386 |
| - : FunctionBytes(FB), Context(std::move(Ctx)), ExecEngine(std::move(EE)) {} |
| 369 | + : FunctionBytes(FB), Context(std::move(Ctx)), ExecJIT(std::move(EJIT)) {} |
387 | 370 |
|
388 | 371 | Error getBenchmarkFunctionBytes(const StringRef InputData,
|
389 | 372 | std::vector<uint8_t> &Bytes) {
|
|
0 commit comments