blob: 108e2755738a7b02e09aa28c0d25da34d988c651 [file] [log] [blame]
Lang Hamesdc4260d2015-04-20 20:41:45 +00001//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Common utilities for the Orc unit tests.
11//
12//===----------------------------------------------------------------------===//
13
14
15#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
16#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
17
Chandler Carruth9a67b072017-06-06 11:06:56 +000018#include "llvm/ExecutionEngine/ExecutionEngine.h"
19#include "llvm/ExecutionEngine/JITSymbol.h"
Lang Hamesa95b0df2018-03-28 03:41:45 +000020#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
Lang Hamesdc4260d2015-04-20 20:41:45 +000021#include "llvm/IR/Function.h"
22#include "llvm/IR/IRBuilder.h"
23#include "llvm/IR/LLVMContext.h"
24#include "llvm/IR/Module.h"
25#include "llvm/IR/TypeBuilder.h"
Lang Hames859d73c2016-01-09 19:50:40 +000026#include "llvm/Object/ObjectFile.h"
Lang Hames130a7c42015-10-28 02:40:04 +000027#include "llvm/Support/TargetSelect.h"
Lang Hamesa95b0df2018-03-28 03:41:45 +000028#include "llvm/Support/TargetRegistry.h"
Lang Hamesdc4260d2015-04-20 20:41:45 +000029#include <memory>
30
31namespace llvm {
32
Lang Hamesd22bade2017-04-04 17:03:49 +000033class OrcNativeTarget {
Lang Hames130a7c42015-10-28 02:40:04 +000034public:
Lang Hamesd22bade2017-04-04 17:03:49 +000035 static void initialize() {
Lang Hames130a7c42015-10-28 02:40:04 +000036 if (!NativeTargetInitialized) {
37 InitializeNativeTarget();
38 InitializeNativeTargetAsmParser();
39 InitializeNativeTargetAsmPrinter();
40 NativeTargetInitialized = true;
41 }
Lang Hamesd22bade2017-04-04 17:03:49 +000042 }
43
44private:
45 static bool NativeTargetInitialized;
46};
47
48// Base class for Orc tests that will execute code.
49class OrcExecutionTest {
50public:
51
52 OrcExecutionTest() {
53
54 // Initialize the native target if it hasn't been done already.
55 OrcNativeTarget::initialize();
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000056
57 // Try to select a TargetMachine for the host.
58 TM.reset(EngineBuilder().selectTarget());
59
60 if (TM) {
61 // If we found a TargetMachine, check that it's one that Orc supports.
62 const Triple& TT = TM->getTargetTriple();
Lang Hames4f8194e2016-02-10 01:02:33 +000063
Lang Hamesa95b0df2018-03-28 03:41:45 +000064 // Target can JIT?
65 SupportsJIT = TM->getTarget().hasJIT();
66 // Use ability to create callback manager to detect whether Orc
67 // has indirection support on this platform. This way the test
68 // and Orc code do not get out of sync.
69 SupportsIndirection = !!orc::createLocalCompileCallbackManager(TT, 0);
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000070 }
Lang Hames130a7c42015-10-28 02:40:04 +000071 };
72
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000073protected:
Mehdi Amini03b42e42016-04-14 21:59:01 +000074 LLVMContext Context;
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000075 std::unique_ptr<TargetMachine> TM;
Lang Hamesa95b0df2018-03-28 03:41:45 +000076 bool SupportsJIT = false;
77 bool SupportsIndirection = false;
Lang Hames130a7c42015-10-28 02:40:04 +000078};
79
Lang Hames4a51e5d2015-10-27 17:45:48 +000080class ModuleBuilder {
81public:
82 ModuleBuilder(LLVMContext &Context, StringRef Triple,
83 StringRef Name);
Lang Hamesdc4260d2015-04-20 20:41:45 +000084
Lang Hames4a51e5d2015-10-27 17:45:48 +000085 template <typename FuncType>
Lang Hames130a7c42015-10-28 02:40:04 +000086 Function* createFunctionDecl(StringRef Name) {
Lang Hames4a51e5d2015-10-27 17:45:48 +000087 return Function::Create(
88 TypeBuilder<FuncType, false>::get(M->getContext()),
Lang Hames130a7c42015-10-28 02:40:04 +000089 GlobalValue::ExternalLinkage, Name, M.get());
Lang Hames4a51e5d2015-10-27 17:45:48 +000090 }
Lang Hamesdc4260d2015-04-20 20:41:45 +000091
Lang Hames4a51e5d2015-10-27 17:45:48 +000092 Module* getModule() { return M.get(); }
93 const Module* getModule() const { return M.get(); }
94 std::unique_ptr<Module> takeModule() { return std::move(M); }
Lang Hamesdc4260d2015-04-20 20:41:45 +000095
Lang Hames4a51e5d2015-10-27 17:45:48 +000096private:
97 std::unique_ptr<Module> M;
Lang Hames4a51e5d2015-10-27 17:45:48 +000098};
Lang Hamesdc4260d2015-04-20 20:41:45 +000099
Lang Hames4a51e5d2015-10-27 17:45:48 +0000100// Dummy struct type.
101struct DummyStruct {
102 int X[256];
103};
Lang Hamesdc4260d2015-04-20 20:41:45 +0000104
Lang Hames4a51e5d2015-10-27 17:45:48 +0000105// TypeBuilder specialization for DummyStruct.
106template <bool XCompile>
107class TypeBuilder<DummyStruct, XCompile> {
108public:
109 static StructType *get(LLVMContext &Context) {
110 return StructType::get(
Serge Gueltone38003f2017-05-09 19:31:13 +0000111 TypeBuilder<types::i<32>[256], XCompile>::get(Context));
Lang Hames4a51e5d2015-10-27 17:45:48 +0000112 }
113};
Lang Hamesdc4260d2015-04-20 20:41:45 +0000114
Lang Hamescf771ad2017-09-28 02:17:35 +0000115template <typename HandleT, typename ModuleT>
Lang Hamesc0056562015-10-20 04:35:02 +0000116class MockBaseLayer {
117public:
118
Lang Hamescf771ad2017-09-28 02:17:35 +0000119 using ModuleHandleT = HandleT;
Lang Hamesc0056562015-10-20 04:35:02 +0000120
Lang Hamescf771ad2017-09-28 02:17:35 +0000121 using AddModuleSignature =
122 Expected<ModuleHandleT>(ModuleT M,
123 std::shared_ptr<JITSymbolResolver> R);
Lang Hamesc0056562015-10-20 04:35:02 +0000124
Lang Hamescf771ad2017-09-28 02:17:35 +0000125 using RemoveModuleSignature = Error(ModuleHandleT H);
126 using FindSymbolSignature = JITSymbol(const std::string &Name,
127 bool ExportedSymbolsOnly);
128 using FindSymbolInSignature = JITSymbol(ModuleHandleT H,
129 const std::string &Name,
130 bool ExportedSymbolsONly);
131 using EmitAndFinalizeSignature = Error(ModuleHandleT H);
132
133 std::function<AddModuleSignature> addModuleImpl;
134 std::function<RemoveModuleSignature> removeModuleImpl;
135 std::function<FindSymbolSignature> findSymbolImpl;
136 std::function<FindSymbolInSignature> findSymbolInImpl;
137 std::function<EmitAndFinalizeSignature> emitAndFinalizeImpl;
138
139 Expected<ModuleHandleT> addModule(ModuleT M,
140 std::shared_ptr<JITSymbolResolver> R) {
141 assert(addModuleImpl &&
142 "addModule called, but no mock implementation was provided");
143 return addModuleImpl(std::move(M), std::move(R));
Lang Hamesc0056562015-10-20 04:35:02 +0000144 }
145
Lang Hames4ce98662017-07-07 02:59:13 +0000146 Error removeModule(ModuleHandleT H) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000147 assert(removeModuleImpl &&
148 "removeModule called, but no mock implementation was provided");
149 return removeModuleImpl(H);
Lang Hamesc0056562015-10-20 04:35:02 +0000150 }
151
Lang Hamesad4a9112016-08-01 20:49:11 +0000152 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000153 assert(findSymbolImpl &&
154 "findSymbol called, but no mock implementation was provided");
155 return findSymbolImpl(Name, ExportedSymbolsOnly);
Lang Hamesc0056562015-10-20 04:35:02 +0000156 }
157
Lang Hamescd9d49b2017-06-23 23:25:28 +0000158 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
Lang Hamesc0056562015-10-20 04:35:02 +0000159 bool ExportedSymbolsOnly) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000160 assert(findSymbolInImpl &&
161 "findSymbolIn called, but no mock implementation was provided");
162 return findSymbolInImpl(H, Name, ExportedSymbolsOnly);
Lang Hamesc0056562015-10-20 04:35:02 +0000163 }
164
Lang Hamescf771ad2017-09-28 02:17:35 +0000165 Error emitAndFinaliez(ModuleHandleT H) {
166 assert(emitAndFinalizeImpl &&
167 "emitAndFinalize called, but no mock implementation was provided");
168 return emitAndFinalizeImpl(H);
169 }
Lang Hamesc0056562015-10-20 04:35:02 +0000170};
171
Lang Hames4ce98662017-07-07 02:59:13 +0000172class ReturnNullJITSymbol {
173public:
174 template <typename... Args>
175 JITSymbol operator()(Args...) const {
176 return nullptr;
177 }
178};
179
Lang Hamesc0056562015-10-20 04:35:02 +0000180template <typename ReturnT>
181class DoNothingAndReturn {
182public:
Lang Hames4ce98662017-07-07 02:59:13 +0000183 DoNothingAndReturn(ReturnT Ret) : Ret(std::move(Ret)) {}
Lang Hamesc0056562015-10-20 04:35:02 +0000184
185 template <typename... Args>
Lang Hames4ce98662017-07-07 02:59:13 +0000186 void operator()(Args...) const { return Ret; }
Lang Hamesc0056562015-10-20 04:35:02 +0000187private:
Lang Hames4ce98662017-07-07 02:59:13 +0000188 ReturnT Ret;
Lang Hamesc0056562015-10-20 04:35:02 +0000189};
190
191template <>
192class DoNothingAndReturn<void> {
193public:
194 template <typename... Args>
195 void operator()(Args...) const { }
196};
Lang Hamesdc4260d2015-04-20 20:41:45 +0000197
198} // namespace llvm
199
200#endif