blob: 28a5f08ee439673a0e3ee3d5e2a21998a6797174 [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 Hamesdc4260d2015-04-20 20:41:45 +000020#include "llvm/IR/Function.h"
21#include "llvm/IR/IRBuilder.h"
22#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Module.h"
24#include "llvm/IR/TypeBuilder.h"
Lang Hames859d73c2016-01-09 19:50:40 +000025#include "llvm/Object/ObjectFile.h"
Lang Hames130a7c42015-10-28 02:40:04 +000026#include "llvm/Support/TargetSelect.h"
Lang Hamesdc4260d2015-04-20 20:41:45 +000027#include <memory>
28
29namespace llvm {
30
Lang Hamesd22bade2017-04-04 17:03:49 +000031class OrcNativeTarget {
Lang Hames130a7c42015-10-28 02:40:04 +000032public:
Lang Hamesd22bade2017-04-04 17:03:49 +000033 static void initialize() {
Lang Hames130a7c42015-10-28 02:40:04 +000034 if (!NativeTargetInitialized) {
35 InitializeNativeTarget();
36 InitializeNativeTargetAsmParser();
37 InitializeNativeTargetAsmPrinter();
38 NativeTargetInitialized = true;
39 }
Lang Hamesd22bade2017-04-04 17:03:49 +000040 }
41
42private:
43 static bool NativeTargetInitialized;
44};
45
46// Base class for Orc tests that will execute code.
47class OrcExecutionTest {
48public:
49
50 OrcExecutionTest() {
51
52 // Initialize the native target if it hasn't been done already.
53 OrcNativeTarget::initialize();
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000054
55 // Try to select a TargetMachine for the host.
56 TM.reset(EngineBuilder().selectTarget());
57
58 if (TM) {
59 // If we found a TargetMachine, check that it's one that Orc supports.
60 const Triple& TT = TM->getTargetTriple();
Lang Hames4f8194e2016-02-10 01:02:33 +000061
62 if ((TT.getArch() != Triple::x86_64 && TT.getArch() != Triple::x86) ||
63 TT.isOSWindows())
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000064 TM = nullptr;
65 }
Lang Hames130a7c42015-10-28 02:40:04 +000066 };
67
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000068protected:
Mehdi Amini03b42e42016-04-14 21:59:01 +000069 LLVMContext Context;
Lang Hamesfd6e8dc2015-10-30 03:20:21 +000070 std::unique_ptr<TargetMachine> TM;
Lang Hames130a7c42015-10-28 02:40:04 +000071};
72
Lang Hames4a51e5d2015-10-27 17:45:48 +000073class ModuleBuilder {
74public:
75 ModuleBuilder(LLVMContext &Context, StringRef Triple,
76 StringRef Name);
Lang Hamesdc4260d2015-04-20 20:41:45 +000077
Lang Hames4a51e5d2015-10-27 17:45:48 +000078 template <typename FuncType>
Lang Hames130a7c42015-10-28 02:40:04 +000079 Function* createFunctionDecl(StringRef Name) {
Lang Hames4a51e5d2015-10-27 17:45:48 +000080 return Function::Create(
81 TypeBuilder<FuncType, false>::get(M->getContext()),
Lang Hames130a7c42015-10-28 02:40:04 +000082 GlobalValue::ExternalLinkage, Name, M.get());
Lang Hames4a51e5d2015-10-27 17:45:48 +000083 }
Lang Hamesdc4260d2015-04-20 20:41:45 +000084
Lang Hames4a51e5d2015-10-27 17:45:48 +000085 Module* getModule() { return M.get(); }
86 const Module* getModule() const { return M.get(); }
87 std::unique_ptr<Module> takeModule() { return std::move(M); }
Lang Hamesdc4260d2015-04-20 20:41:45 +000088
Lang Hames4a51e5d2015-10-27 17:45:48 +000089private:
90 std::unique_ptr<Module> M;
Lang Hames4a51e5d2015-10-27 17:45:48 +000091};
Lang Hamesdc4260d2015-04-20 20:41:45 +000092
Lang Hames4a51e5d2015-10-27 17:45:48 +000093// Dummy struct type.
94struct DummyStruct {
95 int X[256];
96};
Lang Hamesdc4260d2015-04-20 20:41:45 +000097
Lang Hames4a51e5d2015-10-27 17:45:48 +000098// TypeBuilder specialization for DummyStruct.
99template <bool XCompile>
100class TypeBuilder<DummyStruct, XCompile> {
101public:
102 static StructType *get(LLVMContext &Context) {
103 return StructType::get(
Serge Gueltone38003f2017-05-09 19:31:13 +0000104 TypeBuilder<types::i<32>[256], XCompile>::get(Context));
Lang Hames4a51e5d2015-10-27 17:45:48 +0000105 }
106};
Lang Hamesdc4260d2015-04-20 20:41:45 +0000107
Lang Hamescf771ad2017-09-28 02:17:35 +0000108template <typename HandleT, typename ModuleT>
Lang Hamesc0056562015-10-20 04:35:02 +0000109class MockBaseLayer {
110public:
111
Lang Hamescf771ad2017-09-28 02:17:35 +0000112 using ModuleHandleT = HandleT;
Lang Hamesc0056562015-10-20 04:35:02 +0000113
Lang Hamescf771ad2017-09-28 02:17:35 +0000114 using AddModuleSignature =
115 Expected<ModuleHandleT>(ModuleT M,
116 std::shared_ptr<JITSymbolResolver> R);
Lang Hamesc0056562015-10-20 04:35:02 +0000117
Lang Hamescf771ad2017-09-28 02:17:35 +0000118 using RemoveModuleSignature = Error(ModuleHandleT H);
119 using FindSymbolSignature = JITSymbol(const std::string &Name,
120 bool ExportedSymbolsOnly);
121 using FindSymbolInSignature = JITSymbol(ModuleHandleT H,
122 const std::string &Name,
123 bool ExportedSymbolsONly);
124 using EmitAndFinalizeSignature = Error(ModuleHandleT H);
125
126 std::function<AddModuleSignature> addModuleImpl;
127 std::function<RemoveModuleSignature> removeModuleImpl;
128 std::function<FindSymbolSignature> findSymbolImpl;
129 std::function<FindSymbolInSignature> findSymbolInImpl;
130 std::function<EmitAndFinalizeSignature> emitAndFinalizeImpl;
131
132 Expected<ModuleHandleT> addModule(ModuleT M,
133 std::shared_ptr<JITSymbolResolver> R) {
134 assert(addModuleImpl &&
135 "addModule called, but no mock implementation was provided");
136 return addModuleImpl(std::move(M), std::move(R));
Lang Hamesc0056562015-10-20 04:35:02 +0000137 }
138
Lang Hames4ce98662017-07-07 02:59:13 +0000139 Error removeModule(ModuleHandleT H) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000140 assert(removeModuleImpl &&
141 "removeModule called, but no mock implementation was provided");
142 return removeModuleImpl(H);
Lang Hamesc0056562015-10-20 04:35:02 +0000143 }
144
Lang Hamesad4a9112016-08-01 20:49:11 +0000145 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000146 assert(findSymbolImpl &&
147 "findSymbol called, but no mock implementation was provided");
148 return findSymbolImpl(Name, ExportedSymbolsOnly);
Lang Hamesc0056562015-10-20 04:35:02 +0000149 }
150
Lang Hamescd9d49b2017-06-23 23:25:28 +0000151 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
Lang Hamesc0056562015-10-20 04:35:02 +0000152 bool ExportedSymbolsOnly) {
Lang Hamescf771ad2017-09-28 02:17:35 +0000153 assert(findSymbolInImpl &&
154 "findSymbolIn called, but no mock implementation was provided");
155 return findSymbolInImpl(H, Name, ExportedSymbolsOnly);
Lang Hamesc0056562015-10-20 04:35:02 +0000156 }
157
Lang Hamescf771ad2017-09-28 02:17:35 +0000158 Error emitAndFinaliez(ModuleHandleT H) {
159 assert(emitAndFinalizeImpl &&
160 "emitAndFinalize called, but no mock implementation was provided");
161 return emitAndFinalizeImpl(H);
162 }
Lang Hamesc0056562015-10-20 04:35:02 +0000163};
164
Lang Hames4ce98662017-07-07 02:59:13 +0000165class ReturnNullJITSymbol {
166public:
167 template <typename... Args>
168 JITSymbol operator()(Args...) const {
169 return nullptr;
170 }
171};
172
Lang Hamesc0056562015-10-20 04:35:02 +0000173template <typename ReturnT>
174class DoNothingAndReturn {
175public:
Lang Hames4ce98662017-07-07 02:59:13 +0000176 DoNothingAndReturn(ReturnT Ret) : Ret(std::move(Ret)) {}
Lang Hamesc0056562015-10-20 04:35:02 +0000177
178 template <typename... Args>
Lang Hames4ce98662017-07-07 02:59:13 +0000179 void operator()(Args...) const { return Ret; }
Lang Hamesc0056562015-10-20 04:35:02 +0000180private:
Lang Hames4ce98662017-07-07 02:59:13 +0000181 ReturnT Ret;
Lang Hamesc0056562015-10-20 04:35:02 +0000182};
183
184template <>
185class DoNothingAndReturn<void> {
186public:
187 template <typename... Args>
188 void operator()(Args...) const { }
189};
Lang Hamesdc4260d2015-04-20 20:41:45 +0000190
191} // namespace llvm
192
193#endif