[Mesa-dev] [PATCH 05/14] swr: [rasterizer jitter] cleanup supporting different llvm versions

Tim Rowley timothy.o.rowley at intel.com
Fri Jun 17 19:25:45 UTC 2016


---
 src/gallium/drivers/swr/Makefile.am                |  2 +
 .../drivers/swr/rasterizer/jitter/JitManager.cpp   | 33 +---------------
 .../drivers/swr/rasterizer/jitter/JitManager.h     | 22 ++++++++---
 .../drivers/swr/rasterizer/jitter/blend_jit.cpp    | 13 ++-----
 .../drivers/swr/rasterizer/jitter/builder_misc.cpp | 44 ++++++++++++++++++----
 .../drivers/swr/rasterizer/jitter/builder_misc.h   |  8 +++-
 .../drivers/swr/rasterizer/jitter/fetch_jit.cpp    | 18 ++-------
 .../jitter/scripts/gen_llvm_ir_macros.py           | 11 +++++-
 .../swr/rasterizer/jitter/streamout_jit.cpp        |  9 +----
 9 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/src/gallium/drivers/swr/Makefile.am b/src/gallium/drivers/swr/Makefile.am
index d896154..92e03fb 100644
--- a/src/gallium/drivers/swr/Makefile.am
+++ b/src/gallium/drivers/swr/Makefile.am
@@ -98,6 +98,7 @@ rasterizer/jitter/builder_x86.h: rasterizer/jitter/scripts/gen_llvm_ir_macros.py
 	$(MKDIR_GEN)
 	$(PYTHON_GEN) \
 		$(srcdir)/rasterizer/jitter/scripts/gen_llvm_ir_macros.py \
+		--llvm-version $(LLVM_VERSION) \
 		--output rasterizer/jitter/builder_x86.h \
 		--gen_x86_h
 
@@ -105,6 +106,7 @@ rasterizer/jitter/builder_x86.cpp: rasterizer/jitter/scripts/gen_llvm_ir_macros.
 	$(MKDIR_GEN)
 	$(PYTHON_GEN) \
 		$(srcdir)/rasterizer/jitter/scripts/gen_llvm_ir_macros.py \
+		--llvm-version $(LLVM_VERSION) \
 		--output rasterizer/jitter/builder_x86.cpp \
 		--gen_x86_cpp
 
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/JitManager.cpp b/src/gallium/drivers/swr/rasterizer/jitter/JitManager.cpp
index 4bbd9ad..03b616e 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/JitManager.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/JitManager.cpp
@@ -31,8 +31,8 @@
 #pragma warning(disable: 4800 4146 4244 4267 4355 4996)
 #endif
 
-#include "jit_api.h"
 #include "JitManager.h"
+#include "jit_api.h"
 #include "fetch_jit.h"
 
 #if defined(_WIN32)
@@ -222,35 +222,6 @@ void JitManager::SetupNewModule()
     mIsModuleFinalized = false;
 }
 
-//////////////////////////////////////////////////////////////////////////
-/// @brief Create new LLVM module from IR.
-bool JitManager::SetupModuleFromIR(const uint8_t *pIR)
-{
-    std::unique_ptr<MemoryBuffer> pMem = MemoryBuffer::getMemBuffer(StringRef((const char*)pIR), "");
-
-    SMDiagnostic Err;
-    std::unique_ptr<Module> newModule = parseIR(pMem.get()->getMemBufferRef(), Err, mContext);
-
-    if (newModule == nullptr)
-    {
-        SWR_ASSERT(0, "Parse failed! Check Err for details.");
-        return false;
-    }
-
-    mpCurrentModule = newModule.get();
-#if defined(_WIN32)
-    // Needed for MCJIT on windows
-    Triple hostTriple(sys::getProcessTriple());
-    hostTriple.setObjectFormat(Triple::ELF);
-    newModule->setTargetTriple(hostTriple.getTriple());
-#endif // _WIN32
-
-    mpExec->addModule(std::move(newModule));
-    mIsModuleFinalized = false;
-
-    return true;
-}
-
 
 //////////////////////////////////////////////////////////////////////////
 /// @brief Dump function x86 assembly to file.
@@ -281,7 +252,7 @@ void JitManager::DumpAsm(Function* pFunction, const char* fileName)
         sprintf(fName, "%s.%s.asm", funcName, fileName);
 #endif
 
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
         raw_fd_ostream fd(fName, EC, llvm::sys::fs::F_None);
         formatted_raw_ostream filestream(fd);
 #else
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/JitManager.h b/src/gallium/drivers/swr/rasterizer/jitter/JitManager.h
index 14ba893..aaedf89 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/JitManager.h
+++ b/src/gallium/drivers/swr/rasterizer/jitter/JitManager.h
@@ -29,16 +29,16 @@
 ******************************************************************************/
 #pragma once
 
-#include "common/os.h"
-#include "common/isa.hpp"
-
 #if defined(_WIN32)
 #pragma warning(disable : 4146 4244 4267 4800 4996)
 #endif
 
 // llvm 3.7+ reuses "DEBUG" as an enum value
+#if defined(DEBUG)
 #pragma push_macro("DEBUG")
 #undef DEBUG
+#define _DEBUG_COLLISSION
+#endif // DEBUG
 
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Instructions.h"
@@ -54,7 +54,7 @@
 #endif
 
 #ifndef HAVE_LLVM
-#define HAVE_LLVM (LLVM_VERSION_MAJOR << 8) || LLVM_VERSION_MINOR
+#define HAVE_LLVM ((LLVM_VERSION_MAJOR << 8) | LLVM_VERSION_MINOR)
 #endif
 
 #include "llvm/IR/Verifier.h"
@@ -64,10 +64,14 @@
 
 #include "llvm/Analysis/Passes.h"
 
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
 #include "llvm/PassManager.h"
+using FunctionPassManager = llvm::FunctionPassManager;
+using PassManager = llvm::PassManager;
 #else
 #include "llvm/IR/LegacyPassManager.h"
+using FunctionPassManager = llvm::legacy::FunctionPassManager;
+using PassManager = llvm::legacy::PassManager;
 #endif
 
 #include "llvm/CodeGen/Passes.h"
@@ -79,7 +83,14 @@
 #include "llvm/Support/Host.h"
 
 
+#if defined(_DEBUG_COLLISION)
 #pragma pop_macro("DEBUG")
+#undef _DEBUG_COLLISION
+#endif
+
+// This MUST be listed after the LLVM includes above due to name collisions in the LLVM COFF.h header.
+#include "common/os.h"
+#include "common/isa.hpp"
 
 using namespace llvm;
 //////////////////////////////////////////////////////////////////////////
@@ -175,7 +186,6 @@ struct JitManager
     JitInstructionSet mArch;
 
     void SetupNewModule();
-    bool SetupModuleFromIR(const uint8_t *pIR);
 
     void DumpAsm(Function* pFunction, const char* fileName);
     static void DumpToFile(Function *f, const char *fileName);
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp b/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp
index 1b5290c..c6a4259 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp
@@ -27,11 +27,11 @@
 * Notes:
 *
 ******************************************************************************/
-#include "jit_api.h"
-#include "blend_jit.h"
+#include "llvm/IR/DataLayout.h" // MUST be first to avoid platform header conflicts
 #include "builder.h"
+#include "blend_jit.h"
 #include "state_llvm.h"
-#include "llvm/IR/DataLayout.h"
+#include "jit_api.h"
 
 #include <sstream>
 
@@ -725,12 +725,7 @@ struct BlendJit : public Builder
 
         JitManager::DumpToFile(blendFunc, "");
 
-#if HAVE_LLVM == 0x306
-        FunctionPassManager
-#else
-        llvm::legacy::FunctionPassManager
-#endif
-            passes(JM()->mpCurrentModule);
+        ::FunctionPassManager passes(JM()->mpCurrentModule);
 
         passes.add(createBreakCriticalEdgesPass());
         passes.add(createCFGSimplificationPass());
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
index 2f4fa38..c81b849 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
@@ -234,7 +234,7 @@ Value *Builder::VUNDEF(Type* t)
     return UndefValue::get(VectorType::get(t, mVWidth));
 }
 
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
 Value *Builder::VINSERT(Value *vec, Value *val, uint64_t index)
 {
     return VINSERT(vec, val, C((int64_t)index));
@@ -322,6 +322,32 @@ CallInst *Builder::CALL(Value *Callee, const std::initializer_list<Value*> &args
     return CALLA(Callee, args);
 }
 
+#if HAVE_LLVM > 0x306
+CallInst *Builder::CALL(Value *Callee, Value* arg)
+{
+	std::vector<Value*> args;
+	args.push_back(arg);
+	return CALLA(Callee, args);
+}
+
+CallInst *Builder::CALL2(Value *Callee, Value* arg1, Value* arg2)
+{
+	std::vector<Value*> args;
+	args.push_back(arg1);
+	args.push_back(arg2);
+	return CALLA(Callee, args);
+}
+
+CallInst *Builder::CALL3(Value *Callee, Value* arg1, Value* arg2, Value* arg3)
+{
+	std::vector<Value*> args;
+	args.push_back(arg1);
+	args.push_back(arg2);
+	args.push_back(arg3);
+	return CALLA(Callee, args);
+}
+#endif
+
 Value *Builder::VRCP(Value *va)
 {
     return FDIV(VIMMED1(1.0f), va);  // 1 / a
@@ -469,7 +495,7 @@ CallInst *Builder::PRINT(const std::string &printStr,const std::initializer_list
 
     // get a pointer to the first character in the constant string array
     std::vector<Constant*> geplist{C(0),C(0)};
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
     Constant *strGEP = ConstantExpr::getGetElementPtr(gvPtr,geplist,false);
 #else
     Constant *strGEP = ConstantExpr::getGetElementPtr(nullptr, gvPtr,geplist,false);
@@ -726,8 +752,12 @@ Value *Builder::PERMD(Value* a, Value* idx)
     // use avx2 permute instruction if available
     if(JM()->mArch.AVX2())
     {
-        // llvm 3.6.0 swapped the order of the args to vpermd
-        res = VPERMD(idx, a);
+#if (HAVE_LLVM == 0x306) && (LLVM_VERSION_PATCH == 0)
+		// llvm 3.6.0 swapped the order of the args to vpermd
+		res = VPERMD(idx, a);
+#else
+		res = VPERMD(a, idx);
+#endif
     }
     else
     {
@@ -1357,7 +1387,7 @@ Value *Builder::FCLAMP(Value* src, float low, float high)
 Value* Builder::STACKSAVE()
 {
     Function* pfnStackSave = Intrinsic::getDeclaration(JM()->mpCurrentModule, Intrinsic::stacksave);
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
     return CALL(pfnStackSave);
 #else
     return CALLA(pfnStackSave);
@@ -1415,7 +1445,7 @@ void __cdecl CallPrint(const char* fmt, ...)
 
 Value *Builder::VEXTRACTI128(Value* a, Constant* imm8)
 {
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
     Function *func =
         Intrinsic::getDeclaration(JM()->mpCurrentModule,
                                   Intrinsic::x86_avx_vextractf128_si_256);
@@ -1432,7 +1462,7 @@ Value *Builder::VEXTRACTI128(Value* a, Constant* imm8)
 
 Value *Builder::VINSERTI128(Value* a, Value* b, Constant* imm8)
 {
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
     Function *func =
         Intrinsic::getDeclaration(JM()->mpCurrentModule,
                                   Intrinsic::x86_avx_vinsertf128_si_256);
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
index f43ef69..58c8d66 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
+++ b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
@@ -59,7 +59,7 @@ Value *VUNDEF_F();
 Value *VUNDEF_I();
 Value *VUNDEF(Type* ty, uint32_t size);
 Value *VUNDEF_IPTR();
-#if HAVE_LLVM == 0x306
+#if HAVE_LLVM <= 0x306
 Value *VINSERT(Value *vec, Value *val, uint64_t index);
 #endif
 Value *VBROADCAST(Value *src);
@@ -72,6 +72,12 @@ int32_t S_IMMED(Value* i);
 Value *GEP(Value* ptr, const std::initializer_list<Value*> &indexList);
 Value *GEP(Value* ptr, const std::initializer_list<uint32_t> &indexList);
 CallInst *CALL(Value *Callee, const std::initializer_list<Value*> &args);
+#if HAVE_LLVM > 0x306
+CallInst *CALL(Value *Callee) { return CALLA(Callee); }
+CallInst *CALL(Value *Callee, Value* arg);
+CallInst *CALL2(Value *Callee, Value* arg1, Value* arg2);
+CallInst *CALL3(Value *Callee, Value* arg1, Value* arg2, Value* arg3);
+#endif
 
 LoadInst *LOAD(Value *BasePtr, const std::initializer_list<uint32_t> &offset, const llvm::Twine& name = "");
 LoadInst *LOADV(Value *BasePtr, const std::initializer_list<Value*> &offset, const llvm::Twine& name = "");
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
index bae0f24..ec873a1 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
@@ -27,11 +27,11 @@
 * Notes:
 *
 ******************************************************************************/
+#include "llvm/IR/DataLayout.h"
+#include "builder.h"
 #include "jit_api.h"
 #include "fetch_jit.h"
-#include "builder.h"
 #include "state_llvm.h"
-#include "llvm/IR/DataLayout.h"
 #include <sstream>
 #include <tuple>
 
@@ -181,12 +181,7 @@ Function* FetchJit::Create(const FETCH_COMPILE_STATE& fetchState)
 
     verifyFunction(*fetch);
 
-#if HAVE_LLVM == 0x306
-        FunctionPassManager
-#else
-        llvm::legacy::FunctionPassManager
-#endif
-            setupPasses(JM()->mpCurrentModule);
+    ::FunctionPassManager setupPasses(JM()->mpCurrentModule);
 
     ///@todo We don't need the CFG passes for fetch. (e.g. BreakCriticalEdges and CFGSimplification)
     setupPasses.add(createBreakCriticalEdgesPass());
@@ -198,12 +193,7 @@ Function* FetchJit::Create(const FETCH_COMPILE_STATE& fetchState)
 
     JitManager::DumpToFile(fetch, "se");
 
-#if HAVE_LLVM == 0x306
-        FunctionPassManager
-#else
-        llvm::legacy::FunctionPassManager
-#endif
-            optPasses(JM()->mpCurrentModule);
+    ::FunctionPassManager optPasses(JM()->mpCurrentModule);
 
     ///@todo Haven't touched these either. Need to remove some of these and add others.
     optPasses.add(createCFGSimplificationPass());
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/scripts/gen_llvm_ir_macros.py b/src/gallium/drivers/swr/rasterizer/jitter/scripts/gen_llvm_ir_macros.py
index a8b101a..62b4662 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/scripts/gen_llvm_ir_macros.py
+++ b/src/gallium/drivers/swr/rasterizer/jitter/scripts/gen_llvm_ir_macros.py
@@ -102,7 +102,7 @@ intrinsics = [
         ["VPSHUFB", "x86_avx2_pshuf_b", ["a", "b"]],
         ["VPMOVSXBD", "x86_avx2_pmovsxbd", ["a"]],  # sign extend packed 8bit components
         ["VPMOVSXWD", "x86_avx2_pmovsxwd", ["a"]],  # sign extend packed 16bit components
-        ["VPERMD", "x86_avx2_permd", ["idx", "a"]],
+        ["VPERMD", "x86_avx2_permd", ["a", "idx"]],
         ["VPERMPS", "x86_avx2_permps", ["idx", "a"]],
         ["VCVTPH2PS", "x86_vcvtph2ps_256", ["a"]],
         ["VCVTPS2PH", "x86_vcvtps2ph_256", ["a", "round"]],
@@ -374,8 +374,17 @@ def main():
     parser.add_argument("--gen_cpp", "-gen_cpp", help="Generate builder_gen.cpp", action="store_true", default=False)
     parser.add_argument("--gen_x86_h", "-gen_x86_h", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
     parser.add_argument("--gen_x86_cpp", "-gen_x86_cpp", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
+    parser.add_argument("--llvm-version", help="What LLVM version to generate for", action="store", default="3.6.0")
+
     args = parser.parse_args()
 
+    if args.llvm_version == "3.6.0":
+        # Swap args for VPERMD
+        for i in range(len(intrinsics)):
+            if intrinsics[i][0] == "VPERMD":
+                intrinsics[i][2] = [intrinsics[i][2][1], intrinsics[i][2][0]]
+                break
+
     if args.input:
         functions = parse_ir_builder(args.input)
 
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/streamout_jit.cpp b/src/gallium/drivers/swr/rasterizer/jitter/streamout_jit.cpp
index d3ac298..7482124 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/streamout_jit.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/streamout_jit.cpp
@@ -27,9 +27,9 @@
 * Notes:
 *
 ******************************************************************************/
+#include "builder.h"
 #include "jit_api.h"
 #include "streamout_jit.h"
-#include "builder.h"
 #include "state_llvm.h"
 #include "llvm/IR/DataLayout.h"
 
@@ -292,12 +292,7 @@ struct StreamOutJit : public Builder
 
         JitManager::DumpToFile(soFunc, "SoFunc");
 
-#if HAVE_LLVM == 0x306
-        FunctionPassManager
-#else
-        llvm::legacy::FunctionPassManager
-#endif
-            passes(JM()->mpCurrentModule);
+        ::FunctionPassManager passes(JM()->mpCurrentModule);
 
         passes.add(createBreakCriticalEdgesPass());
         passes.add(createCFGSimplificationPass());
-- 
1.9.1



More information about the mesa-dev mailing list