1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * @brief JitManager contains the LLVM data structures used for JIT generation
29 ******************************************************************************/
33 #pragma warning(disable : 4146 4244 4267 4800 4996)
36 // llvm 3.7+ reuses "DEBUG" as an enum value
37 #pragma push_macro("DEBUG")
40 #include "llvm/IR/DataLayout.h"
41 #include "llvm/IR/Instructions.h"
42 #include "llvm/IR/LLVMContext.h"
43 #include "llvm/IR/Module.h"
44 #include "llvm/IR/Type.h"
45 #include "llvm/IR/IRBuilder.h"
46 #include "llvm/IR/IntrinsicInst.h"
48 #include "llvm/Config/llvm-config.h"
49 #ifndef LLVM_VERSION_MAJOR
50 #include "llvm/Config/config.h"
54 #define HAVE_LLVM ((LLVM_VERSION_MAJOR << 8) | LLVM_VERSION_MINOR)
57 #include "llvm/IR/Verifier.h"
58 #include "llvm/ExecutionEngine/MCJIT.h"
59 #include "llvm/Support/FileSystem.h"
60 #define LLVM_F_NONE sys::fs::F_None
62 #include "llvm/Analysis/Passes.h"
64 #if HAVE_LLVM == 0x306
65 #include "llvm/PassManager.h"
66 using FunctionPassManager
= llvm::FunctionPassManager
;
67 using PassManager
= llvm::PassManager
;
69 #include "llvm/IR/LegacyPassManager.h"
70 using FunctionPassManager
= llvm::legacy::FunctionPassManager
;
71 using PassManager
= llvm::legacy::PassManager
;
74 #include "llvm/CodeGen/Passes.h"
75 #include "llvm/ExecutionEngine/ExecutionEngine.h"
76 #include "llvm/Support/raw_ostream.h"
77 #include "llvm/Support/TargetSelect.h"
78 #include "llvm/Transforms/IPO.h"
79 #include "llvm/Transforms/Scalar.h"
80 #include "llvm/Support/Host.h"
81 #include "llvm/Support/DynamicLibrary.h"
84 #include "common/os.h"
85 #include "common/isa.hpp"
87 #pragma pop_macro("DEBUG")
89 //////////////////////////////////////////////////////////////////////////
91 /// @brief Subclass of InstructionSet that allows users to override
92 /// the reporting of support for certain ISA features. This allows capping
93 /// the jitted code to a certain feature level, e.g. jit AVX level code on
94 /// a platform that supports AVX2.
95 //////////////////////////////////////////////////////////////////////////
96 class JitInstructionSet
: public InstructionSet
99 JitInstructionSet(const char* requestedIsa
) : isaRequest(requestedIsa
)
101 std::transform(isaRequest
.begin(), isaRequest
.end(), isaRequest
.begin(), ::tolower
);
103 if(isaRequest
== "avx")
107 bForceAVX512
= false;
109 else if(isaRequest
== "avx2")
113 bForceAVX512
= false;
116 else if(isaRequest
== "avx512")
125 bool AVX2(void) { return bForceAVX
? 0 : InstructionSet::AVX2(); }
126 bool AVX512F(void) { return (bForceAVX
| bForceAVX2
) ? 0 : InstructionSet::AVX512F(); }
127 bool BMI2(void) { return bForceAVX
? 0 : InstructionSet::BMI2(); }
130 bool bForceAVX
= false;
131 bool bForceAVX2
= false;
132 bool bForceAVX512
= false;
133 std::string isaRequest
;
138 struct JitLLVMContext
: llvm::LLVMContext
143 //////////////////////////////////////////////////////////////////////////
145 //////////////////////////////////////////////////////////////////////////
148 JitManager(uint32_t w
, const char* arch
, const char* core
);
151 JitLLVMContext mContext
; ///< LLVM compiler
152 llvm::IRBuilder
<> mBuilder
; ///< LLVM IR Builder
153 llvm::ExecutionEngine
* mpExec
;
155 // Need to be rebuilt after a JIT and before building new IR
156 llvm::Module
* mpCurrentModule
;
157 bool mIsModuleFinalized
;
164 llvm::Type
* mInt32Ty
;
165 llvm::Type
* mInt64Ty
;
168 llvm::Type
* mSimtFP32Ty
;
169 llvm::Type
* mSimtInt32Ty
;
171 llvm::Type
* mSimdVectorInt32Ty
;
172 llvm::Type
* mSimdVectorTy
;
174 // fetch shader types
175 llvm::FunctionType
* mFetchShaderTy
;
177 JitInstructionSet mArch
;
180 void SetupNewModule();
181 bool SetupModuleFromIR(const uint8_t *pIR
);
183 void DumpAsm(llvm::Function
* pFunction
, const char* fileName
);
184 static void DumpToFile(llvm::Function
*f
, const char *fileName
);