[Beignet] [PATCH V2 5/5] Backend: Add support for LLVM 3.9 release

Xiuli Pan xiuli.pan at intel.com
Tue Sep 27 05:11:09 UTC 2016


From: Pan Xiuli <xiuli.pan at intel.com>

LLVM 3.9 changes a lot from 3.8, modify on:
1. API getGlobalContext was removed, add GBEGetLLVMContext instead
2. API LLVMLinkModules was removed, use LLVMLinkModules2 instead.
3. LLVMLinkModules2 now will delete src module for default, clone all
src module and kernel names.
4. Few LLVM pass refine, change include headers and creadpass API.
5. clang refine image type name, change llvminfo check for image.
6. clang change kernel arg info metadata and some other metadata to
function metadata, refine metedata query function logic.
7. clang default define most cl_khr_* macro, need to undef them first.
8. SPIR mangle was changed by a fix patch for Itanium mangle, now most
SPIR can not be recognized by LLVM 3.9.

V2: Merge some code.
Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
---
 backend/src/backend/gen_program.cpp        |  13 +++-
 backend/src/backend/program.cpp            |  10 +++
 backend/src/ir/function.hpp                |  12 +--
 backend/src/libocl/include/ocl.h           |  75 ++++++++++++++++++
 backend/src/libocl/tmpl/ocl_defines.tmpl.h |  11 ---
 backend/src/llvm/llvm_bitcode_link.cpp     |  26 ++++++-
 backend/src/llvm/llvm_gen_backend.cpp      | 119 ++++++++++++++++++++++++++---
 backend/src/llvm/llvm_includes.hpp         |   5 ++
 backend/src/llvm/llvm_passes.cpp           |   6 +-
 backend/src/llvm/llvm_to_gen.cpp           |  19 ++++-
 backend/src/llvm/llvm_to_gen.hpp           |   6 ++
 11 files changed, 272 insertions(+), 30 deletions(-)

diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 32f7794..4ef82d1 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -334,7 +334,11 @@ namespace gbe {
     //the first byte stands for binary_type.
     binary_content.assign(binary+1, size-1);
     llvm::StringRef llvm_bin_str(binary_content);
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    llvm::LLVMContext& c = GBEGetLLVMContext();
+#else
     llvm::LLVMContext& c = llvm::getGlobalContext();
+#endif
     llvm::SMDiagnostic Err;
 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6
     std::unique_ptr<llvm::MemoryBuffer> memory_buffer = llvm::MemoryBuffer::getMemBuffer(llvm_bin_str, "llvm_bin_str");
@@ -488,10 +492,17 @@ namespace gbe {
 #endif
       errSize = 0;
     }else{
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+      // Src now will be removed automatically. So clone it.
+      llvm::Module* src = llvm::CloneModule((llvm::Module*)((GenProgram*)src_program)->module).release();
+#else
       llvm::Module* src = (llvm::Module*)((GenProgram*)src_program)->module;
+#endif
       llvm::Module* dst = (llvm::Module*)((GenProgram*)dst_program)->module;
 
-#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+      if (LLVMLinkModules2(wrap(dst), wrap(src))) {
+#elif LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
       if (LLVMLinkModules(wrap(dst), wrap(src), LLVMLinkerPreserveSource_Removed, &errMsg)) {
 #else
       if (LLVMLinkModules(wrap(dst), wrap(src), LLVMLinkerPreserveSource, &errMsg)) {
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index b7dc00e..2224880 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -133,7 +133,13 @@ namespace gbe {
     bool strictMath = true;
     if (fast_relaxed_math || !OCL_STRICT_CONFORMANCE)
       strictMath = false;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    llvm::Module * linked_module = module ? llvm::CloneModule((llvm::Module*)module).release() : NULL;
+    // Src now will be removed automatically. So clone it.
+    if (llvmToGen(*unit, fileName, linked_module, optLevel, strictMath, OCL_PROFILING_LOG, error) == false) {
+#else
     if (llvmToGen(*unit, fileName, module, optLevel, strictMath, OCL_PROFILING_LOG, error) == false) {
+#endif
       if (fileName)
         error = std::string(fileName) + " not found";
       delete unit;
@@ -1057,7 +1063,11 @@ EXTEND_QUOTE:
     //FIXME: if use new allocated context to link two modules there would be context mismatch
     //for some functions, so we use global context now, need switch to new context later.
     llvm::Module * out_module;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    llvm::LLVMContext* llvm_ctx = &GBEGetLLVMContext();
+#else
     llvm::LLVMContext* llvm_ctx = &llvm::getGlobalContext();
+#endif
 
     if (buildModuleFromSource(source, &out_module, llvm_ctx, dumpLLVMFileName, dumpSPIRBinaryName, clOpt,
                               stringSize, err, errSize)) {
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index ae0a702..71a6d07 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -208,22 +208,22 @@ namespace ir {
       }
 #else
       bool isImage1dT() const {
-        return typeBaseName.compare("image1d_t") == 0;
+        return typeBaseName.find("image1d_t") !=std::string::npos;
       }
       bool isImage1dArrayT() const {
-        return typeBaseName.compare("image1d_array_t") == 0;
+        return typeBaseName.find("image1d_array_t") !=std::string::npos;
       }
       bool isImage1dBufferT() const {
-        return typeBaseName.compare("image1d_buffer_t") == 0;
+        return typeBaseName.find("image1d_buffer_t") !=std::string::npos;
       }
       bool isImage2dT() const {
-        return typeBaseName.compare("image2d_t") == 0;
+        return typeBaseName.find("image2d_t") !=std::string::npos;
       }
       bool isImage2dArrayT() const {
-        return typeBaseName.compare("image2d_array_t") == 0;
+        return typeBaseName.find("image2d_array_t") !=std::string::npos;
       }
       bool isImage3dT() const {
-        return typeBaseName.compare("image3d_t") == 0;
+        return typeBaseName.find("image3d_t") !=std::string::npos;
       }
       bool isSamplerType() const {
         return typeBaseName.compare("sampler_t") == 0;
diff --git a/backend/src/libocl/include/ocl.h b/backend/src/libocl/include/ocl.h
index abb2bd4..5e3a788 100644
--- a/backend/src/libocl/include/ocl.h
+++ b/backend/src/libocl/include/ocl.h
@@ -18,6 +18,67 @@
 #ifndef __OCL_H__
 #define __OCL_H__
 
+/* LLVM 3.9 has these pre defined undef them first */
+#ifdef cl_khr_3d_image_writes
+#undef cl_khr_3d_image_writes
+#endif
+#ifdef cl_khr_byte_addressable_store
+#undef cl_khr_byte_addressable_store
+#endif
+#ifdef cl_khr_fp16
+#undef cl_khr_fp16
+#endif
+#ifdef cl_khr_fp64
+#undef cl_khr_fp64
+#endif
+#ifdef cl_khr_global_int32_base_atomics
+#undef cl_khr_global_int32_base_atomics
+#endif
+#ifdef cl_khr_global_int32_extended_atomics
+#undef cl_khr_global_int32_extended_atomics
+#endif
+#ifdef cl_khr_gl_sharing
+#undef cl_khr_gl_sharing
+#endif
+#ifdef cl_khr_icd
+#undef cl_khr_icd
+#endif
+#ifdef cl_khr_local_int32_base_atomics
+#undef cl_khr_local_int32_base_atomics
+#endif
+#ifdef cl_khr_local_int32_extended_atomics
+#undef cl_khr_local_int32_extended_atomics
+#endif
+
+#ifdef cl_khr_d3d10_sharing
+#undef cl_khr_d3d10_sharing
+#endif
+#ifdef cl_khr_gl_event
+#undef cl_khr_gl_event
+#endif
+#ifdef cl_khr_int64_base_atomics
+#undef cl_khr_int64_base_atomics
+#endif
+#ifdef cl_khr_int64_extended_atomics
+#undef cl_khr_int64_extended_atomics
+#endif
+
+#ifdef cl_khr_d3d11_sharing
+#undef cl_khr_d3d11_sharing
+#endif
+#ifdef cl_khr_depth_images
+#undef cl_khr_depth_images
+#endif
+#ifdef cl_khr_dx9_media_sharing
+#undef cl_khr_dx9_media_sharing
+#endif
+#ifdef cl_khr_gl_depth_images
+#undef cl_khr_gl_depth_images
+#endif
+#ifdef cl_khr_spir
+#undef cl_khr_spir
+#endif
+
 #include "ocl_defines.h"
 #include "ocl_types.h"
 #include "ocl_as.h"
@@ -40,6 +101,20 @@
 #include "ocl_workitem.h"
 #include "ocl_simd.h"
 #include "ocl_work_group.h"
+
+/* Move these out from ocl_defines.h for only one define */
+#define cl_khr_global_int32_base_atomics
+#define cl_khr_global_int32_extended_atomics
+#define cl_khr_local_int32_base_atomics
+#define cl_khr_local_int32_extended_atomics
+#define cl_khr_byte_addressable_store
+#define cl_khr_icd
+#define cl_khr_gl_sharing
+#define cl_khr_spir
+#define cl_khr_fp16
+#define cl_khr_3d_image_writes
+#define cl_intel_subgroups
+
 #pragma OPENCL EXTENSION cl_khr_fp64 : disable
 #pragma OPENCL EXTENSION cl_khr_fp16 : disable
 #endif
diff --git a/backend/src/libocl/tmpl/ocl_defines.tmpl.h b/backend/src/libocl/tmpl/ocl_defines.tmpl.h
index 8c7d08f..f840a82 100644
--- a/backend/src/libocl/tmpl/ocl_defines.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_defines.tmpl.h
@@ -27,16 +27,5 @@
 #define __kernel_exec(X, TYPE) __kernel __attribute__((work_group_size_hint(X,1,1))) \
                                         __attribute__((vec_type_hint(TYPE)))
 #define kernel_exec(X, TYPE) __kernel_exec(X, TYPE)
-#define cl_khr_global_int32_base_atomics
-#define cl_khr_global_int32_extended_atomics
-#define cl_khr_local_int32_base_atomics
-#define cl_khr_local_int32_extended_atomics
-#define cl_khr_byte_addressable_store
-#define cl_khr_icd
-#define cl_khr_gl_sharing
-#define cl_khr_spir
-#define cl_khr_fp16
-#define cl_khr_3d_image_writes
-#define cl_intel_subgroups
 
 #endif /* end of __OCL_COMMON_DEF_H__ */
diff --git a/backend/src/llvm/llvm_bitcode_link.cpp b/backend/src/llvm/llvm_bitcode_link.cpp
index 748a7fe..a3f9886 100644
--- a/backend/src/llvm/llvm_bitcode_link.cpp
+++ b/backend/src/llvm/llvm_bitcode_link.cpp
@@ -145,6 +145,7 @@ namespace gbe
       return NULL;
 
     std::vector<const char *> kernels;
+    std::vector<const char *> kerneltmp;
     std::vector<const char *> builtinFuncs;
     /* Add the memset and memcpy functions here. */
     builtinFuncs.push_back("__gen_memcpy_gg");
@@ -184,7 +185,12 @@ namespace gbe
     for (Module::iterator SF = mod->begin(), E = mod->end(); SF != E; ++SF) {
       if (SF->isDeclaration()) continue;
       if (!isKernelFunction(*SF)) continue;
-      kernels.push_back(SF->getName().data());
+      // mod will be deleted after link, copy the names.
+      const char *funcName = SF->getName().data();
+      char * tmp = new char[strlen(funcName)+1];
+      strcpy(tmp,funcName);
+      kernels.push_back(tmp);
+      kerneltmp.push_back(tmp);
 
       if (!materializedFuncCall(*mod, *clonedLib, *SF, materializedFuncs, Gvs)) {
         delete clonedLib;
@@ -273,7 +279,11 @@ namespace gbe
     /* We use beignet's bitcode as dst because it will have a lot of
        lazy functions which will not be loaded. */
     char* errorMsg;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    if(LLVMLinkModules2(wrap(clonedLib), wrap(mod))) {
+#else
     if(LLVMLinkModules(wrap(clonedLib), wrap(mod), LLVMLinkerDestroySource, &errorMsg)) {
+#endif
       delete clonedLib;
       printf("Fatal Error: link the bitcode error:\n%s\n", errorMsg);
       return NULL;
@@ -284,11 +294,25 @@ namespace gbe
     llvm::PassManager passes;
 #endif
 
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >=9
+    auto PreserveKernel = [=](const GlobalValue &GV) {
+      for(size_t i = 0;i < kernels.size(); ++i)
+        if(strcmp(GV.getName().data(), kernels[i]))
+          return true;
+      return false;
+    };
+
+    passes.add(createInternalizePass(PreserveKernel));
+#else
     passes.add(createInternalizePass(kernels));
+#endif
     passes.add(createGlobalDCEPass());
 
     passes.run(*clonedLib);
 
+    for(size_t i = 0;i < kerneltmp.size(); i++)
+      delete[] kerneltmp[i];
+
     return clonedLib;
   }
 
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 7005d60..0570766 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1230,6 +1230,10 @@ namespace gbe
     }
     MDNode *typeNameNode = NULL;
     MDNode *typeBaseNameNode = NULL;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    typeNameNode = F.getMetadata("kernel_arg_type");
+    typeBaseNameNode = F.getMetadata("kernel_arg_base_type");
+#else
     MDNode *node = getKernelFunctionMetadata(&F);
     for(uint j = 0;node && j < node->getNumOperands() - 1; j++) {
       MDNode *attrNode = dyn_cast_or_null<MDNode>(node->getOperand(1 + j));
@@ -1243,15 +1247,21 @@ namespace gbe
         typeBaseNameNode = attrNode;
       }
     }
+#endif
 
     unsigned argID = 0;
     ir::FunctionArgument::InfoFromLLVM llvmInfo;
     for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, argID++) {
+      unsigned opID = argID;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 9
+      opID += 1;
+#endif
+
       if(typeNameNode) {
-        llvmInfo.typeName= (cast<MDString>(typeNameNode->getOperand(1 + argID)))->getString();
+        llvmInfo.typeName= (cast<MDString>(typeNameNode->getOperand(opID)))->getString();
       }
       if(typeBaseNameNode) {
-        llvmInfo.typeBaseName= (cast<MDString>(typeBaseNameNode->getOperand(1 + argID)))->getString();
+        llvmInfo.typeBaseName= (cast<MDString>(typeBaseNameNode->getOperand(opID)))->getString();
       }
       bool isImage = llvmInfo.isImageType();
       if (I->getType()->isPointerTy() || isImage) {
@@ -1974,6 +1984,92 @@ namespace gbe
 
     std::string functionAttributes;
 
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    /* LLVM 3.9 change kernel arg info as function metadata */
+    addrSpaceNode = F.getMetadata("kernel_arg_addr_space");
+    accessQualNode = F.getMetadata("kernel_arg_access_qual");
+    typeNameNode = F.getMetadata("kernel_arg_type");
+    typeBaseNameNode = F.getMetadata("kernel_arg_base_type");
+    typeQualNode = F.getMetadata("kernel_arg_type_qual");
+    argNameNode = F.getMetadata("kernel_arg_name");
+    MDNode *attrNode;
+    if ((attrNode = F.getMetadata("vec_type_hint"))) {
+      GBE_ASSERT(attrNode->getNumOperands() == 2);
+      functionAttributes += "vec_type_hint";
+      auto *Op1 = cast<ValueAsMetadata>(attrNode->getOperand(0));
+      Value *V = Op1 ? Op1->getValue() : NULL;
+      ConstantInt *sign =
+          mdconst::extract<ConstantInt>(attrNode->getOperand(1));
+      size_t signValue = sign->getZExtValue();
+      Type *vtype = V->getType();
+      Type *stype = vtype;
+      uint32_t elemNum = 0;
+      if (vtype->isVectorTy()) {
+        VectorType *vectorType = cast<VectorType>(vtype);
+        stype = vectorType->getElementType();
+        elemNum = vectorType->getNumElements();
+      }
+
+      std::string typeName = getTypeName(ctx, stype, signValue);
+
+      std::stringstream param;
+      char buffer[100] = {0};
+      param << "(";
+      param << typeName;
+      if (vtype->isVectorTy())
+        param << elemNum;
+      param << ")";
+      param >> buffer;
+      functionAttributes += buffer;
+      functionAttributes += " ";
+    }
+    if ((attrNode = F.getMetadata("reqd_work_group_size"))) {
+      GBE_ASSERT(attrNode->getNumOperands() == 3);
+      ConstantInt *x = mdconst::extract<ConstantInt>(attrNode->getOperand(0));
+      ConstantInt *y = mdconst::extract<ConstantInt>(attrNode->getOperand(1));
+      ConstantInt *z = mdconst::extract<ConstantInt>(attrNode->getOperand(2));
+      GBE_ASSERT(x && y && z);
+      reqd_wg_sz[0] = x->getZExtValue();
+      reqd_wg_sz[1] = y->getZExtValue();
+      reqd_wg_sz[2] = z->getZExtValue();
+      functionAttributes += "reqd_work_group_size";
+      std::stringstream param;
+      char buffer[100] = {0};
+      param << "(";
+      param << reqd_wg_sz[0];
+      param << ",";
+      param << reqd_wg_sz[1];
+      param << ",";
+      param << reqd_wg_sz[2];
+      param << ")";
+      param >> buffer;
+      functionAttributes += buffer;
+      functionAttributes += " ";
+    }
+    if ((attrNode = F.getMetadata("work_group_size_hint"))) {
+      GBE_ASSERT(attrNode->getNumOperands() == 3);
+      ConstantInt *x = mdconst::extract<ConstantInt>(attrNode->getOperand(0));
+      ConstantInt *y = mdconst::extract<ConstantInt>(attrNode->getOperand(1));
+      ConstantInt *z = mdconst::extract<ConstantInt>(attrNode->getOperand(2));
+      GBE_ASSERT(x && y && z);
+      hint_wg_sz[0] = x->getZExtValue();
+      hint_wg_sz[1] = y->getZExtValue();
+      hint_wg_sz[2] = z->getZExtValue();
+      functionAttributes += "work_group_size_hint";
+      std::stringstream param;
+      char buffer[100] = {0};
+      param << "(";
+      param << hint_wg_sz[0];
+      param << ",";
+      param << hint_wg_sz[1];
+      param << ",";
+      param << hint_wg_sz[2];
+      param << ")";
+      param >> buffer;
+      functionAttributes += buffer;
+      functionAttributes += " ";
+    }
+#else
     /* First find the meta data belong to this function. */
     MDNode *node = getKernelFunctionMetadata(&F);
 
@@ -2095,6 +2191,7 @@ namespace gbe
         functionAttributes += " ";
       }
     }
+#endif /* LLVM 3.9 Function metadata */
 
     ctx.getFunction().setCompileWorkGroupSize(reqd_wg_sz[0], reqd_wg_sz[1], reqd_wg_sz[2]);
 
@@ -2110,29 +2207,33 @@ namespace gbe
       const AttrListPtr &PAL = F.getAttributes();
 #endif /* LLVM_VERSION_MINOR <= 1 */
       for (; I != E; ++I, ++argID) {
+        uint32_t opID = argID;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 9
+        opID += 1;
+#endif
         const std::string &argName = I->getName().str();
         Type *type = I->getType();
         if(addrSpaceNode) {
 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR <= 5
-          llvmInfo.addrSpace = (cast<ConstantInt>(addrSpaceNode->getOperand(1 + argID)))->getZExtValue();
+          llvmInfo.addrSpace = (cast<ConstantInt>(addrSpaceNode->getOperand(opID)))->getZExtValue();
 #else
-          llvmInfo.addrSpace = (mdconst::extract<ConstantInt>(addrSpaceNode->getOperand(1 + argID)))->getZExtValue();
+          llvmInfo.addrSpace = (mdconst::extract<ConstantInt>(addrSpaceNode->getOperand(opID)))->getZExtValue();
 #endif
         }
         if(typeNameNode) {
-          llvmInfo.typeName = (cast<MDString>(typeNameNode->getOperand(1 + argID)))->getString();
+          llvmInfo.typeName = (cast<MDString>(typeNameNode->getOperand(opID)))->getString();
         }
         if(typeBaseNameNode){
-          llvmInfo.typeBaseName = (cast<MDString>(typeBaseNameNode->getOperand(1 + argID)))->getString();
+          llvmInfo.typeBaseName = (cast<MDString>(typeBaseNameNode->getOperand(opID)))->getString();
         }
         if(accessQualNode) {
-          llvmInfo.accessQual = (cast<MDString>(accessQualNode->getOperand(1 + argID)))->getString();
+          llvmInfo.accessQual = (cast<MDString>(accessQualNode->getOperand(opID)))->getString();
         }
         if(typeQualNode) {
-          llvmInfo.typeQual = (cast<MDString>(typeQualNode->getOperand(1 + argID)))->getString();
+          llvmInfo.typeQual = (cast<MDString>(typeQualNode->getOperand(opID)))->getString();
         }
         if(argNameNode){
-          llvmInfo.argName = (cast<MDString>(argNameNode->getOperand(1 + argID)))->getString();
+          llvmInfo.argName = (cast<MDString>(argNameNode->getOperand(opID)))->getString();
         }
 
         // function arguments are uniform values.
diff --git a/backend/src/llvm/llvm_includes.hpp b/backend/src/llvm/llvm_includes.hpp
index d2deb90..0b80979 100644
--- a/backend/src/llvm/llvm_includes.hpp
+++ b/backend/src/llvm/llvm_includes.hpp
@@ -127,4 +127,9 @@
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
 #endif
 
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+#include "llvm/Transforms/IPO/FunctionAttrs.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#endif
+
 #endif /* __GBE_IR_LLVM_INCLUDES_HPP__ */
diff --git a/backend/src/llvm/llvm_passes.cpp b/backend/src/llvm/llvm_passes.cpp
index b925e5f..02dd4bf 100644
--- a/backend/src/llvm/llvm_passes.cpp
+++ b/backend/src/llvm/llvm_passes.cpp
@@ -41,9 +41,12 @@ using namespace llvm;
 namespace gbe
 {
   bool isKernelFunction(const llvm::Function &F) {
+    bool bKernel = false;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    bKernel = F.getMetadata("kernel_arg_name") != NULL;
+#else
     const Module *module = F.getParent();
     const Module::NamedMDListType& globalMD = module->getNamedMDList();
-    bool bKernel = false;
     for(auto i = globalMD.begin(); i != globalMD.end(); i++) {
       const NamedMDNode &md = *i;
       if(strcmp(md.getName().data(), "opencl.kernels") != 0) continue;
@@ -58,6 +61,7 @@ namespace gbe
         if(op == &F) bKernel = true;
       }
     }
+#endif
     return bKernel;
   }
 
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index 02a69ec..e108810 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -46,6 +46,13 @@ namespace gbe
   BVAR(OCL_OUTPUT_CFG_GEN_IR, false);
   using namespace llvm;
 
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+  llvm::LLVMContext& GBEGetLLVMContext() {
+    static llvm::LLVMContext GBEContext;
+    return GBEContext;
+  }
+#endif
+
 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
   #define TARGETLIBRARY  TargetLibraryInfoImpl
 #else
@@ -142,7 +149,9 @@ namespace gbe
     MPM.add(createBarrierNodupPass(false));   // remove noduplicate fnAttr before inlining.
     MPM.add(createFunctionInliningPass(20000));
     MPM.add(createBarrierNodupPass(true));    // restore noduplicate fnAttr after inlining.
-#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+    MPM.add(createPostOrderFunctionAttrsLegacyPass());
+#elif LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8
     MPM.add(createPostOrderFunctionAttrsPass());       // Set readonly/readnone attrs
 #else
     MPM.add(createFunctionAttrsPass());       // Set readonly/readnone attrs
@@ -294,7 +303,11 @@ namespace gbe
     if (module) {
       cl_mod = reinterpret_cast<Module*>(const_cast<void*>(module));
     } else if (fileName){
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+      llvm::LLVMContext& c = GBEGetLLVMContext();
+#else
       llvm::LLVMContext& c = llvm::getGlobalContext();
+#endif
 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6
       cl_mod = parseIRFile(fileName, Err, c).release();
 #else
@@ -349,7 +362,11 @@ namespace gbe
     passes.add(createIntrinsicLoweringPass());
     passes.add(createStripAttributesPass());     // Strip unsupported attributes and calling conventions.
     passes.add(createFunctionInliningPass(20000));
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
+    passes.add(createSROAPass());
+#else
     passes.add(createScalarReplAggregatesPass(64, true, -1, -1, 64));
+#endif
     passes.add(createLoadStoreOptimizationPass());
     passes.add(createConstantPropagationPass());
     passes.add(createPromoteMemoryToRegisterPass());
diff --git a/backend/src/llvm/llvm_to_gen.hpp b/backend/src/llvm/llvm_to_gen.hpp
index e0a6145..d3928c6 100644
--- a/backend/src/llvm/llvm_to_gen.hpp
+++ b/backend/src/llvm/llvm_to_gen.hpp
@@ -23,6 +23,9 @@
  */
 #ifndef __GBE_IR_LLVM_TO_GEN_HPP__
 #define __GBE_IR_LLVM_TO_GEN_HPP__
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+#include "llvm/IR/LLVMContext.h"
+#endif
 
 namespace gbe {
   namespace ir {
@@ -34,6 +37,9 @@ namespace gbe {
 		  optLevel 0 equal to clang -O1 and 1 equal to clang -O2*/
   bool llvmToGen(ir::Unit &unit, const char *fileName, const void* module,
                  int optLevel, bool strictMath, int profiling, std::string &errors);
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9
+  extern llvm::LLVMContext& GBEGetLLVMContext();
+#endif
 
 } /* namespace gbe */
 
-- 
2.7.4



More information about the Beignet mailing list