• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 *
23 * @file JitManager.h
24 *
25 * @brief JitManager contains the LLVM data structures used for JIT generation
26 *
27 * Notes:
28 *
29 ******************************************************************************/
30 #pragma once
31 
32 #include "common/os.h"
33 #include "common/isa.hpp"
34 
35 #if defined(_WIN32)
36 #pragma warning(disable : 4146 4244 4267 4800 4996)
37 #endif
38 
39 // llvm 3.7+ reuses "DEBUG" as an enum value
40 #pragma push_macro("DEBUG")
41 #undef DEBUG
42 
43 #include "llvm/IR/DataLayout.h"
44 #include "llvm/IR/Instructions.h"
45 #include "llvm/IR/LLVMContext.h"
46 #include "llvm/IR/Module.h"
47 #include "llvm/IR/Type.h"
48 #include "llvm/IR/IRBuilder.h"
49 #include "llvm/IR/IntrinsicInst.h"
50 
51 #include "llvm/Config/llvm-config.h"
52 #ifndef LLVM_VERSION_MAJOR
53 #include "llvm/Config/config.h"
54 #endif
55 
56 #ifndef HAVE_LLVM
57 #define HAVE_LLVM ((LLVM_VERSION_MAJOR << 8) | LLVM_VERSION_MINOR)
58 #endif
59 
60 #include "llvm/IR/Verifier.h"
61 #include "llvm/ExecutionEngine/MCJIT.h"
62 #include "llvm/Support/FileSystem.h"
63 #define LLVM_F_NONE sys::fs::F_None
64 
65 #include "llvm/Analysis/Passes.h"
66 
67 #if HAVE_LLVM == 0x306
68 #include "llvm/PassManager.h"
69 using FunctionPassManager = llvm::FunctionPassManager;
70 using PassManager = llvm::PassManager;
71 #else
72 #include "llvm/IR/LegacyPassManager.h"
73 using FunctionPassManager = llvm::legacy::FunctionPassManager;
74 using PassManager = llvm::legacy::PassManager;
75 #endif
76 
77 #include "llvm/CodeGen/Passes.h"
78 #include "llvm/ExecutionEngine/ExecutionEngine.h"
79 #include "llvm/Support/raw_ostream.h"
80 #include "llvm/Support/TargetSelect.h"
81 #include "llvm/Transforms/IPO.h"
82 #include "llvm/Transforms/Scalar.h"
83 #include "llvm/Support/Host.h"
84 #include "llvm/Support/DynamicLibrary.h"
85 
86 
87 #pragma pop_macro("DEBUG")
88 
89 //////////////////////////////////////////////////////////////////////////
90 /// JitInstructionSet
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
97 {
98 public:
JitInstructionSet(const char * requestedIsa)99     JitInstructionSet(const char* requestedIsa) : isaRequest(requestedIsa)
100     {
101         std::transform(isaRequest.begin(), isaRequest.end(), isaRequest.begin(), ::tolower);
102 
103         if(isaRequest == "avx")
104         {
105             bForceAVX = true;
106             bForceAVX2 = false;
107             bForceAVX512 = false;
108         }
109         else if(isaRequest == "avx2")
110         {
111             bForceAVX = false;
112             bForceAVX2 = true;
113             bForceAVX512 = false;
114         }
115         #if 0
116         else if(isaRequest == "avx512")
117         {
118             bForceAVX = false;
119             bForceAVX2 = false;
120             bForceAVX512 = true;
121         }
122         #endif
123     };
124 
AVX2(void)125     bool AVX2(void) { return bForceAVX ? 0 : InstructionSet::AVX2(); }
AVX512F(void)126     bool AVX512F(void) { return (bForceAVX | bForceAVX2) ? 0 : InstructionSet::AVX512F(); }
BMI2(void)127     bool BMI2(void) { return bForceAVX ? 0 : InstructionSet::BMI2(); }
128 
129 private:
130     bool bForceAVX = false;
131     bool bForceAVX2 = false;
132     bool bForceAVX512 = false;
133     std::string isaRequest;
134 };
135 
136 
137 
138 struct JitLLVMContext : llvm::LLVMContext
139 {
140 };
141 
142 
143 //////////////////////////////////////////////////////////////////////////
144 /// JitManager
145 //////////////////////////////////////////////////////////////////////////
146 struct JitManager
147 {
148     JitManager(uint32_t w, const char* arch, const char* core);
~JitManagerJitManager149     ~JitManager(){};
150 
151     JitLLVMContext          mContext;   ///< LLVM compiler
152     llvm::IRBuilder<>       mBuilder;   ///< LLVM IR Builder
153     llvm::ExecutionEngine*  mpExec;
154 
155     // Need to be rebuilt after a JIT and before building new IR
156     llvm::Module* mpCurrentModule;
157     bool mIsModuleFinalized;
158     uint32_t mJitNumber;
159 
160     uint32_t                 mVWidth;
161 
162     // Built in types.
163     llvm::Type*                mInt8Ty;
164     llvm::Type*                mInt32Ty;
165     llvm::Type*                mInt64Ty;
166     llvm::Type*                mFP32Ty;
167     llvm::StructType*          mV4FP32Ty;
168     llvm::StructType*          mV4Int32Ty;
169 
170     llvm::Type* mSimtFP32Ty;
171     llvm::Type* mSimtInt32Ty;
172 
173     llvm::Type* mSimdVectorInt32Ty;
174     llvm::Type* mSimdVectorTy;
175 
176     // fetch shader types
177     llvm::FunctionType*        mFetchShaderTy;
178 
179     JitInstructionSet mArch;
180     std::string mCore;
181 
182     void SetupNewModule();
183     bool SetupModuleFromIR(const uint8_t *pIR);
184 
185     void DumpAsm(llvm::Function* pFunction, const char* fileName);
186     static void DumpToFile(llvm::Function *f, const char *fileName);
187 };
188