swr: [rasterizer jitter] support llvm-svn
[mesa.git] / src / gallium / drivers / swr / rasterizer / jitter / JitManager.h
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 #else
70 #include "llvm/IR/LegacyPassManager.h"
71 #endif
72
73 #include "llvm/CodeGen/Passes.h"
74 #include "llvm/ExecutionEngine/ExecutionEngine.h"
75 #include "llvm/Support/raw_ostream.h"
76 #include "llvm/Support/TargetSelect.h"
77 #include "llvm/Transforms/IPO.h"
78 #include "llvm/Transforms/Scalar.h"
79 #include "llvm/Support/Host.h"
80
81
82 #pragma pop_macro("DEBUG")
83
84 using namespace llvm;
85 //////////////////////////////////////////////////////////////////////////
86 /// JitInstructionSet
87 /// @brief Subclass of InstructionSet that allows users to override
88 /// the reporting of support for certain ISA features. This allows capping
89 /// the jitted code to a certain feature level, e.g. jit AVX level code on
90 /// a platform that supports AVX2.
91 //////////////////////////////////////////////////////////////////////////
92 class JitInstructionSet : public InstructionSet
93 {
94 public:
95 JitInstructionSet(const char* requestedIsa) : isaRequest(requestedIsa)
96 {
97 std::transform(isaRequest.begin(), isaRequest.end(), isaRequest.begin(), ::tolower);
98
99 if(isaRequest == "avx")
100 {
101 bForceAVX = true;
102 bForceAVX2 = false;
103 bForceAVX512 = false;
104 }
105 else if(isaRequest == "avx2")
106 {
107 bForceAVX = false;
108 bForceAVX2 = true;
109 bForceAVX512 = false;
110 }
111 #if 0
112 else if(isaRequest == "avx512")
113 {
114 bForceAVX = false;
115 bForceAVX2 = false;
116 bForceAVX512 = true;
117 }
118 #endif
119 };
120
121 bool AVX2(void) { return bForceAVX ? 0 : InstructionSet::AVX2(); }
122 bool AVX512F(void) { return (bForceAVX | bForceAVX2) ? 0 : InstructionSet::AVX512F(); }
123 bool BMI2(void) { return bForceAVX ? 0 : InstructionSet::BMI2(); }
124
125 private:
126 bool bForceAVX = false;
127 bool bForceAVX2 = false;
128 bool bForceAVX512 = false;
129 std::string isaRequest;
130 };
131
132
133
134 struct JitLLVMContext : LLVMContext
135 {
136 };
137
138
139 //////////////////////////////////////////////////////////////////////////
140 /// JitManager
141 //////////////////////////////////////////////////////////////////////////
142 struct JitManager
143 {
144 JitManager(uint32_t w, const char *arch);
145 ~JitManager(){};
146
147 JitLLVMContext mContext; ///< LLVM compiler
148 IRBuilder<> mBuilder; ///< LLVM IR Builder
149 ExecutionEngine* mpExec;
150
151 // Need to be rebuilt after a JIT and before building new IR
152 Module* mpCurrentModule;
153 bool mIsModuleFinalized;
154 uint32_t mJitNumber;
155
156 uint32_t mVWidth;
157
158 // Built in types.
159 Type* mInt8Ty;
160 Type* mInt32Ty;
161 Type* mInt64Ty;
162 Type* mFP32Ty;
163 StructType* mV4FP32Ty;
164 StructType* mV4Int32Ty;
165
166 // helper scalar function types
167 FunctionType* mUnaryFPTy;
168 FunctionType* mBinaryFPTy;
169 FunctionType* mTrinaryFPTy;
170 FunctionType* mUnaryIntTy;
171 FunctionType* mBinaryIntTy;
172
173 Type* mSimtFP32Ty;
174 Type* mSimtInt32Ty;
175
176 Type* mSimdVectorInt32Ty;
177 Type* mSimdVectorTy;
178
179 // fetch shader types
180 FunctionType* mFetchShaderTy;
181
182 JitInstructionSet mArch;
183
184 void SetupNewModule();
185 bool SetupModuleFromIR(const uint8_t *pIR);
186
187 static void DumpToFile(Function *f, const char *fileName);
188 };