[Beignet] [PATCH 03/18] Add the bit code linker into the module pass.

Song, Ruiling ruiling.song at intel.com
Wed Aug 27 19:50:50 PDT 2014


This patch does not work with llvm 3.5. it is better we fix it in the patch.
One thing is:
#if LLVM_VERSION_MINOR >= 5
#include "llvm/Linker/Linker.h"
#else
#include "llvm/Linker.h"
#endif

Another one is llvm 3.5 change some APIs. Doing same job in llvm3.5 should be something like below:
(OwningPtr is deprecated from llvm3.5)
   llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer
        = MemoryBuffer::getFile(bitCodeFile);

    if(is_error(Buffer.getError())) {
      return NULL;
    }

    sys::fs::file_magic magic = sys::fs::identify_magic(Buffer.get()->getBuffer());
    if (magic != sys::fs::file_magic::bitcode) {
      printf("Fatal Error: ocl lib %s is not a bitcode file\n", bitCodeFile.c_str());
      return NULL;
    }

    std::string errorMessage;
    llvm::ErrorOr<std::unique_ptr<Module>> oclLib = parseBitcodeFile(Buffer.get().get(), ctx);

    if (is_error(oclLib.getError())) {
      return NULL;
    }

    return oclLib->release();
and error_code must be qualified with namespace std::error_code. I am not sure what namespace of error_code in llvm 3.3.

-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of junyan.he at inbox.com
Sent: Tuesday, August 12, 2014 3:31 PM
To: beignet at lists.freedesktop.org
Cc: Junyan He
Subject: [Beignet] [PATCH 03/18] Add the bit code linker into the module pass.

From: Junyan He <junyan.he at linux.intel.com>

The bit code linker will load the beignet.bc as a lib module and link the module of the kernel together.
Then we will filter out all the dead bit code by create an InternalizePass for the module.
After this stage, the ir will include the bitcode just used by the cl kernel.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/CMakeLists.txt             |   1 +
 backend/src/llvm/llvm_bitcode_link.cpp | 123 +++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 backend/src/llvm/llvm_bitcode_link.cpp

diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt index 63eb0f0..262815c 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -154,6 +154,7 @@ else (GBE_USE_BLOB)
     backend/program.cpp
     backend/program.hpp
     backend/program.h
+    llvm/llvm_bitcode_link.cpp
     llvm/llvm_gen_backend.cpp
     llvm/llvm_passes.cpp
     llvm/llvm_scalarize.cpp
diff --git a/backend/src/llvm/llvm_bitcode_link.cpp b/backend/src/llvm/llvm_bitcode_link.cpp
new file mode 100644
index 0000000..90ab4e1
--- /dev/null
+++ b/backend/src/llvm/llvm_bitcode_link.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+#include "sys/cvar.hpp"
+#include "src/GBEConfig.h"
+#include "llvm/llvm_gen_backend.hpp"
+#include "llvm/Linker.h"
+
+using namespace llvm;
+
+SVAR(OCL_BITCODE_LIB_PATH, OCL_BITCODE_BIN);
+
+namespace gbe
+{
+  static bool is_error(error_code ec)
+  {
+    if (ec) {
+      printf("Bitcode Link Error: %s\n", ec.message().c_str());
+      return true;
+    }
+    return false;
+  }
+
+  static Module* createOclBitCodeModule(LLVMContext& ctx)  {
+    error_code err;
+    std::string bitCodeFile = OCL_BITCODE_LIB_PATH;
+    Module* oclLib = NULL;
+
+    if (!sys::fs::exists(bitCodeFile)) {
+      printf("Fatal Error: can not open the bitcode ocl lib in %s\n",
+             bitCodeFile.c_str());
+      return NULL;
+    }
+
+    OwningPtr<MemoryBuffer> Buffer;
+    if (is_error(MemoryBuffer::getFile(bitCodeFile, Buffer))) {
+      return NULL;
+    }
+
+    sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
+    if (magic != sys::fs::file_magic::bitcode) {
+      printf("Fatal Error: ocl lib %s is not a bitcode file\n", bitCodeFile.c_str());
+      return NULL;
+    }
+
+    std::string errorMessage;
+    oclLib = ParseBitcodeFile(Buffer.get(), ctx, &errorMessage);
+    if (!oclLib) {
+      printf("Fatal Error: ocl lib %s can not be opened, because %s\n",
+             bitCodeFile.c_str(), errorMessage.c_str());
+      return NULL;
+    }
+
+    return oclLib;
+  }
+
+  Module* runBitCodeLinker(Module *mod)  {
+    LLVMContext& ctx = mod->getContext();
+
+    std::vector<const char *> kernels;
+    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());
+    }
+
+    if (kernels.empty()) {
+      printf("One module without kernel function!\n");
+      return NULL;
+    }
+
+    Module* clonedLib = createOclBitCodeModule(ctx);
+    assert(clonedLib && "Can not create the beignet bitcode\n");
+
+    /* We use beignet's bitcode as dst because it will have a lot of
+       lazy functions which will not be loaded. */
+    if(Linker::LinkModules(clonedLib, mod, Linker::DestroySource, NULL)) {
+      delete clonedLib;
+      printf("Fatal Error: link the bitcode error\n");
+      return NULL;
+    }
+
+    llvm::PassManager passes;
+
+    passes.add(createInternalizePass(kernels));
+    passes.add(createGlobalDCEPass());
+
+    passes.run(*clonedLib);
+
+    return clonedLib;
+  }
+
+} // end namespace
--
1.8.3.2

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list