Revamp the backend classes to be easily able to output Gen or simulator code
authorBenjamin Segovia <segovia.benjamin@gmail.com>
Thu, 5 Apr 2012 19:25:29 +0000 (19:25 +0000)
committerKeith Packard <keithp@keithp.com>
Fri, 10 Aug 2012 23:16:06 +0000 (16:16 -0700)
15 files changed:
backend/src/CMakeLists.txt
backend/src/backend/context.cpp [new file with mode: 0644]
backend/src/backend/context.hpp [new file with mode: 0644]
backend/src/backend/gen_context.cpp [new file with mode: 0644]
backend/src/backend/gen_context.hpp [new file with mode: 0644]
backend/src/backend/gen_program.cpp
backend/src/backend/gen_program.hpp
backend/src/backend/program.cpp
backend/src/backend/program.h
backend/src/backend/program.hpp
backend/src/backend/sim_context.cpp [new file with mode: 0644]
backend/src/backend/sim_context.hpp [new file with mode: 0644]
backend/src/backend/sim_program.cpp
backend/src/backend/sim_program.hpp
backend/src/ir/function.hpp

index 614ccff..e5712db 100644 (file)
@@ -42,11 +42,18 @@ else (GBE_USE_BLOB)
     ir/function.hpp
     ir/value.cpp
     ir/value.hpp
+    backend/context.cpp
+    backend/context.hpp
     backend/program.cpp
+    backend/program.hpp
     backend/program.h
+    backend/sim_context.cpp
+    backend/sim_context.hpp
     backend/sim_program.cpp
     backend/sim_program.hpp
     backend/sim_program.h
+    backend/gen_context.cpp
+    backend/gen_context.hpp
     backend/gen_program.cpp
     backend/gen_program.hpp
     backend/gen_program.h
@@ -90,5 +97,5 @@ if (GBE_COMPILE_UTESTS)
 endif (GBE_COMPILE_UTESTS)
 
 install (TARGETS gbe LIBRARY DESTINATION lib)
-install (FILES backend/gbe_program.h DESTINATION include/gen)
+install (FILES backend/program.h DESTINATION include/gen)
 
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
new file mode 100644 (file)
index 0000000..6d7fd64
--- /dev/null
@@ -0,0 +1,65 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file context.cpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+#include "backend/context.hpp"
+#include "backend/program.hpp"
+#include "ir/unit.hpp"
+#include "ir/function.hpp"
+#include <algorithm>
+
+namespace gbe
+{
+  Context::Context(const ir::Unit &unit, const std::string &name) :
+    unit(unit), fn(*unit.getFunction(name)), name(name), liveness(NULL), dag(NULL)
+  { GBE_ASSERT(unit.getPointerSize() == ir::POINTER_32_BITS); }
+  Context::~Context(void) {}
+
+  Kernel *Context::compileKernel(void) {
+    this->kernel = this->allocateKernel();
+    this->buildPatchList();
+    this->emitCode();
+    return this->kernel;
+  }
+
+  void Context::buildPatchList(void) {
+    const uint32_t inputNum = fn.inputNum();
+    uint32_t curbeSize = 0u;
+    uint32_t ptrSize = unit.getPointerSize() == ir::POINTER_32_BITS ? 4u : 8u;
+    for (uint32_t inputID = 0u; inputID < inputNum; ++inputID) {
+      const ir::FunctionInput &input = fn.getInput(inputID);
+      // This is a pointer -> 4 bytes to patch
+      if (input.type == ir::FunctionInput::GLOBAL_POINTER ||
+          input.type == ir::FunctionInput::CONSTANT_POINTER) {
+        const PatchInfo patch(GBE_CURBE_BUFFER_ADDRESS, 0u, curbeSize);
+        kernel->patches.push_back(patch);
+        curbeSize += ptrSize;
+      }
+    }
+
+    // After this point the vector is immutable. so, Sorting is will make
+    // research faster
+    std::sort(kernel->patches.begin(), kernel->patches.end());
+  }
+
+} /* namespace gbe */
+
diff --git a/backend/src/backend/context.hpp b/backend/src/backend/context.hpp
new file mode 100644 (file)
index 0000000..cd45b9a
--- /dev/null
@@ -0,0 +1,78 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file context.hpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#ifndef __GBE_CONTEXT_HPP__
+#define __GBE_CONTEXT_HPP__
+
+#include "sys/platform.hpp"
+#include <string>
+
+namespace gbe {
+namespace ir {
+
+  class Unit;        // Contains the complete program
+  class Function;    // We compile a function into a kernel
+  class Liveness;    // Describes liveness of each ir function register
+  class FunctionDAG; // Describes the instruction dependencies
+
+} /* namespace ir */
+} /* namespace gbe */
+
+namespace gbe
+{
+  struct Kernel; // we build this structure
+
+  /*! Context is the helper structure to build the Gen ISA or simulation code
+   *  from GenIR
+   */
+  class Context : public NonCopyable
+  {
+  public:
+    /*! Create a new context. name is the name of the function we want to
+     *  compile
+     */
+    Context(const ir::Unit &unit, const std::string &name);
+    /*! Release everything needed */
+    ~Context(void);
+    /*! Compile the code */
+    Kernel *compileKernel(void);
+  protected:
+    /*! Build the curbe patch list for the given kernel */
+    void buildPatchList(void);
+    /*! Build the instruction stream */
+    virtual void emitCode(void) = 0;
+    /*! Allocate a new empty kernel */
+    virtual Kernel *allocateKernel(void) = 0;
+    const ir::Unit &unit;    //!< Unit that contains the kernel
+    const ir::Function &fn;  //!< Function to compile
+    std::string name;        //!< Name of the kernel to compile
+    Kernel *kernel;          //!< Kernel we are building
+    ir::Liveness *liveness;  //!< Liveness info for the variables
+    ir::FunctionDAG *dag;    //!< Complete DAG of values on the function
+  };
+
+} /* namespace gbe */
+
+#endif /* __GBE_CONTEXT_HPP__ */
+
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
new file mode 100644 (file)
index 0000000..01e6520
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file gen_context.cpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#include "backend/gen_context.hpp"
+#include "backend/gen_program.hpp"
+#include "backend/gen/brw_eu.h"
+#include <cstring>
+
+namespace gbe
+{
+  GenContext::GenContext(const ir::Unit &unit, const std::string &name) :
+    Context(unit, name) {}
+  GenContext::~GenContext(void) {}
+
+  void GenContext::emitCode(void) {
+    GenKernel *genKernel = static_cast<GenKernel*>(this->kernel);
+    brw_compile *p = (brw_compile*) GBE_MALLOC(sizeof(brw_compile));
+    std::memset(p, 0, sizeof(*p));
+    brw_EOT(p, 127);
+    genKernel->insnNum = p->nr_insn;
+    genKernel->insns = GBE_NEW_ARRAY(brw_instruction, genKernel->insnNum);
+    std::memcpy(genKernel->insns, p->store, genKernel->insnNum * sizeof(brw_instruction));
+    GBE_FREE(p);
+  }
+  Kernel *GenContext::allocateKernel(void) {
+    return GBE_NEW(GenKernel, name);
+  }
+
+} /* namespace gbe */
+
+
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
new file mode 100644 (file)
index 0000000..9827502
--- /dev/null
@@ -0,0 +1,57 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file context.hpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#ifndef __GBE_GEN_CONTEXT_HPP__
+#define __GBE_GEN_CONTEXT_HPP__
+
+#include <string>
+#include "backend/context.hpp"
+
+namespace gbe
+{
+  struct Kernel; // we build this structure
+
+  /*! Context is the helper structure to build the Gen ISA or simulation code
+   *  from GenIR
+   */
+  class GenContext : public Context
+  {
+  public:
+    /*! Create a new context. name is the name of the function we want to
+     *  compile
+     */
+    GenContext(const ir::Unit &unit, const std::string &name);
+    /*! Release everything needed */
+    ~GenContext(void);
+    /*! Implements base class */
+    virtual void emitCode(void);
+    /*! Implements base class */
+    virtual Kernel *allocateKernel(void);
+    GBE_CLASS(GenContext);
+  };
+
+} /* namespace gbe */
+
+#endif /* __GBE_GEN_CONTEXT_HPP__ */
+
index c7db99a..5029f34 100644 (file)
 #include "backend/gen_program.h"
 #include "backend/gen_program.hpp"
 #include "backend/gen_program.hpp"
-#include "backend/gen/brw_eu.h"
-#include "ir/liveness.hpp"
-#include "ir/value.hpp"
-#include "ir/unit.hpp"
+#include "backend/gen_context.hpp"
 #include "llvm/llvm_to_gen.hpp"
 #include <cstring>
 
@@ -43,16 +40,11 @@ namespace gbe {
   GenProgram::GenProgram(void) {}
   GenProgram::~GenProgram(void) {}
 
-  Kernel *GenProgram::compileKernel(const std::string &name) {
-    GenKernel *kernel = GBE_NEW(GenKernel, name);
-    brw_compile *p = (brw_compile*) GBE_MALLOC(sizeof(brw_compile));
-    std::memset(p, 0, sizeof(*p));
-    brw_EOT(p, 127);
-    kernel->insnNum = p->nr_insn;
-    kernel->insns = GBE_NEW_ARRAY(brw_instruction, kernel->insnNum);
-    std::memcpy(kernel->insns, p->store, kernel->insnNum * sizeof(brw_instruction));
-    GBE_FREE(p);
-    return kernel;
+  Kernel *GenProgram::compileKernel(const ir::Unit &unit, const std::string &name) {
+    Context *ctx = GBE_NEW(GenContext, unit, name);
+    Kernel *ker = ctx->compileKernel();
+    GBE_DELETE(ctx);
+    return ker;
   }
 
   static gbe_program genProgramNewFromSource(const char *source) {
index 653b5b2..219a1ee 100644 (file)
@@ -57,7 +57,7 @@ namespace gbe {
     /*! Destroy the program */
     virtual ~GenProgram(void);
     /*! Implements base class */
-    Kernel *compileKernel(const std::string &name);
+    Kernel *compileKernel(const ir::Unit &unit, const std::string &name);
     GBE_STRUCT(GenProgram);   //!< Use gbe allocators
   };
 
index 390bf7b..d3ef8a7 100644 (file)
 #include "ir/unit.hpp"
 #include "llvm/llvm_to_gen.hpp"
 #include <cstring>
+#include <algorithm>
 
 namespace gbe {
 
   Kernel::Kernel(const std::string &name) :
-    name(name), args(NULL), argNum(0), liveness(NULL), dag(NULL)
+    name(name), args(NULL), argNum(0)
   {}
   Kernel::~Kernel(void) {
     GBE_SAFE_DELETE_ARRAY(args);
-    GBE_SAFE_DELETE(liveness);
-    GBE_SAFE_DELETE(dag);
+  }
+  int32_t Kernel::getCurbeOffset(gbe_curbe_value type, uint32_t subType) const {
+    const PatchInfo patch(type, subType);
+    const auto it = std::lower_bound(patches.begin(), patches.end(), patch);
+    if (it == patches.end()) return -1; // nothing found
+    if (patch < *it) return -1; // they are not equal
+    return it->offset; // we found it!
   }
 
   Program::Program(void) {}
@@ -66,7 +72,7 @@ namespace gbe {
     if (kernelNum == 0) return true;
     for (auto it = set.begin(); it != set.end(); ++it) {
       const std::string &name = it->first;
-      Kernel *kernel = this->compileKernel(name);
+      Kernel *kernel = this->compileKernel(unit, name);
       kernels.insert(std::make_pair(name, kernel));
     }
     return true;
@@ -135,6 +141,10 @@ namespace gbe {
     return 16u;
   }
 
+  static int32_t kernelGetCurbeOffset(gbe_arg_type type, uint32_t sub_type) {
+    return -1;
+  }
+
   static uint32_t kernelGetRequiredWorkGroupSize(gbe_kernel kernel, uint32_t dim) {
     return 0u;
   }
@@ -154,6 +164,7 @@ GBE_EXPORT_SYMBOL gbe_kernel_get_arg_num_cb *gbe_kernel_get_arg_num = NULL;
 GBE_EXPORT_SYMBOL gbe_kernel_get_arg_size_cb *gbe_kernel_get_arg_size = NULL;
 GBE_EXPORT_SYMBOL gbe_kernel_get_arg_type_cb *gbe_kernel_get_arg_type = NULL;
 GBE_EXPORT_SYMBOL gbe_kernel_get_simd_width_cb *gbe_kernel_get_simd_width = NULL;
+GBE_EXPORT_SYMBOL gbe_kernel_get_curbe_offset_cb *gbe_kernel_get_curbe_offset = NULL;
 GBE_EXPORT_SYMBOL gbe_kernel_get_required_work_group_size_cb *gbe_kernel_get_required_work_group_size = NULL;
 
 /* Use pre-main to setup the call backs */
@@ -171,6 +182,7 @@ struct CallBackInitializer
     gbe_kernel_get_arg_size = gbe::kernelGetArgSize;
     gbe_kernel_get_arg_type = gbe::kernelGetArgType;
     gbe_kernel_get_simd_width = gbe::kernelGetSIMDWidth;
+    gbe_kernel_get_curbe_offset = gbe::kernelGetCurbeOffset;
     gbe_kernel_get_required_work_group_size = gbe::kernelGetRequiredWorkGroupSize;
     const char *run_it = getenv("OCL_SIMULATOR");
     if (run_it != NULL && !strcmp(run_it, "2"))
index 6dc65b8..02a1161 100644 (file)
@@ -126,6 +126,10 @@ extern gbe_kernel_get_arg_type_cb *gbe_kernel_get_arg_type;
 typedef uint32_t (gbe_kernel_get_simd_width_cb)(gbe_kernel);
 extern gbe_kernel_get_simd_width_cb *gbe_kernel_get_simd_width;
 
+/*! Get the curbe offset where to put the data. Returns -1 if not required */
+typedef int32_t (gbe_kernel_get_curbe_offset_cb)(enum gbe_arg_type type, uint32_t sub_type);
+extern gbe_kernel_get_curbe_offset_cb *gbe_kernel_get_curbe_offset;
+
 /*! Indicates if a work group size is required. Return the required width or 0
  *  if none
  */
index f5f1ddf..9e0a84f 100644 (file)
 
 #include "backend/program.h"
 #include "sys/hash_map.hpp"
+#include "sys/vector.hpp"
 #include <string>
 
 namespace gbe {
 namespace ir {
-
-  class Unit;        // Compilation unit. Contains the program to compile
-  class Liveness;    // Describes liveness of each ir function register
-  class FunctionDAG; // Describes the instruction dependencies
-
+  class Unit; // Compilation unit. Contains the program to compile
 } /* namespace ir */
 } /* namespace gbe */
 
@@ -43,10 +40,26 @@ namespace gbe {
 
   /*! Info for the kernel argument */
   struct KernelArgument {
-    gbe_arg_type type; //!< Pointer, structure, regular value?
-    size_t size;       //!< Size of each argument
+    gbe_arg_type type; //!< Pointer, structure, image, regular value?
+    uint32_t size;     //!< Size of the argument
   };
 
+  /*! Stores the offset where to patch where to patch */
+  struct PatchInfo {
+    INLINE PatchInfo(gbe_curbe_value type, uint32_t subType = 0u, uint32_t offset = 0u) :
+      type(uint32_t(type)), subType(subType), offset(offset) {}
+    INLINE PatchInfo(void) {}
+    uint32_t type : 8;
+    uint32_t subType : 8;
+    uint32_t offset : 16;
+  };
+
+  /*! We will sort PatchInfo to make binary search */
+  INLINE bool operator< (PatchInfo i0, PatchInfo i1) {
+    if (i0.type != i1.type) return i0.type < i1.type;
+    return i0.subType < i1.subType;
+  }
+
   /*! Describe a compiled kernel */
   struct Kernel : public NonCopyable
   {
@@ -64,27 +77,20 @@ namespace gbe {
     INLINE uint32_t getArgNum(void) const { return argNum; }
     /*! Return the size of the given argument */
     INLINE uint32_t getArgSize(uint32_t argID) const {
-      if (argID >= argNum)
-        return 0u;
-      else
-        return args[argID].size;
+      return argID >= argNum ? 0u : args[argID].size;
     }
     /*! Return the type of the given argument */
     INLINE gbe_arg_type getArgType(uint32_t argID) const {
-      if (argID >= argNum)
-        return GBE_ARG_INVALID;
-      else
-        return args[argID].type;
+      return argID >= argNum ? GBE_ARG_INVALID : args[argID].type;
     }
-    /*! Return where to put the address of a buffer argument */
-    
+    /*! Get the offset where to patch. Returns -1 if no patch needed */
+    int32_t getCurbeOffset(gbe_curbe_value value, uint32_t subvalue) const;
   protected:
-    friend class Program;    //!< Owns the kernels
-    const std::string name;  //!< Kernel name
-    KernelArgument *args;    //!< Each argument
-    uint32_t argNum;         //!< Number of function arguments
-    ir::Liveness *liveness;  //!< Used only for the build
-    ir::FunctionDAG *dag;    //!< Used only for the build
+    friend class Context;       //!< Owns the kernels
+    const std::string name;     //!< Kernel name
+    KernelArgument *args;       //!< Each argument
+    uint32_t argNum;            //!< Number of function arguments
+    vector<PatchInfo> patches;  //!< Indicates how to build the curbe
   };
 
   /*! Describe a compiled program */
@@ -122,9 +128,9 @@ namespace gbe {
     bool buildFromLLVMFile(const char *fileName, std::string &error);
     /*! Buils a program from a OCL string */
     bool buildFromSource(const char *source, std::string &error);
-    /*! Compile a kernel */
-    virtual Kernel *compileKernel(const std::string &name) = 0;
   protected:
+    /*! Compile a kernel */
+    virtual Kernel *compileKernel(const ir::Unit &unit, const std::string &name) = 0;
     /*! Kernels sorted by their name */
     hash_map<std::string, Kernel*> kernels;
   };
diff --git a/backend/src/backend/sim_context.cpp b/backend/src/backend/sim_context.cpp
new file mode 100644 (file)
index 0000000..98f5475
--- /dev/null
@@ -0,0 +1,74 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file sim_context.cpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+#include "backend/sim_context.hpp"
+#include "backend/sim_program.hpp"
+#include <cstring>
+#include <cstdio>
+#include <fstream>
+#include <dlfcn.h>
+
+namespace gbe
+{
+  SimContext::SimContext(const ir::Unit &unit, const std::string &name) :
+    Context(unit, name) {}
+  SimContext::~SimContext(void) {}
+
+  Kernel *SimContext::allocateKernel(void) {
+    return GBE_NEW(SimKernel, name);
+  }
+
+  void SimContext::emitCode(void) {
+    SimKernel *simKernel = static_cast<SimKernel*>(this->kernel);
+    char srcStr[L_tmpnam+1], libStr[L_tmpnam+1];
+    const std::string srcName = std::string(tmpnam_r(srcStr)) + ".cpp"; /* unsecure but we don't care */
+    const std::string libName = std::string(tmpnam_r(libStr)) + ".so";  /* unsecure but we don't care */
+
+    /* Output the code first */
+    std::ofstream ostream;
+    ostream.open(srcName);
+    ostream << "extern \"C\" void " << name << "() {}" << std::endl;
+    ostream.close();
+
+    /* Compile the function */
+    std::cout << srcName << " " << libName;
+    std::string compileCmd = "g++ -shared -O3 -o ";
+    compileCmd += libName;
+    compileCmd += " ";
+    compileCmd += srcName;
+    printf(compileCmd.c_str());
+    if (UNLIKELY(system(compileCmd.c_str()) != 0))
+      FATAL("Simulation program compilation failed");
+
+    /* Load it and get the function pointer */
+    simKernel->handle = dlopen(libName.c_str(), RTLD_NOW);
+    if (UNLIKELY(simKernel->handle == NULL))
+      FATAL("Failed to open the compiled shared object");
+    simKernel->fn = (SimKernelCallBack*) dlsym(simKernel->handle, name.c_str());
+    if (UNLIKELY(simKernel->fn == NULL))
+      FATAL("Failed to get the symbol from the compiled shared object");
+  }
+
+} /* namespace gbe */
+
+
diff --git a/backend/src/backend/sim_context.hpp b/backend/src/backend/sim_context.hpp
new file mode 100644 (file)
index 0000000..c46acff
--- /dev/null
@@ -0,0 +1,57 @@
+/* 
+ * 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/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file context.hpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#ifndef __GBE_SIM_CONTEXT_HPP__
+#define __GBE_SIM_CONTEXT_HPP__
+
+#include <string>
+#include "backend/context.hpp"
+
+namespace gbe
+{
+  struct Kernel; // we build this structure
+
+  /*! Context is the helper structure to build the Gen ISA or simulation code
+   *  from GenIR
+   */
+  class SimContext : public Context
+  {
+  public:
+    /*! Create a new context. name is the name of the function we want to
+     *  compile
+     */
+    SimContext(const ir::Unit &unit, const std::string &name);
+    /*! Release everything needed */
+    ~SimContext(void);
+    /*! Implements base class */
+    virtual void emitCode(void);
+    /*! Implements base class */
+    virtual Kernel *allocateKernel(void);
+    GBE_CLASS(SimContext);
+  };
+
+} /* namespace gbe */
+
+#endif /* __GBE_SIM_CONTEXT_HPP__ */
+
index cbd5503..4df627d 100644 (file)
 #include "backend/program.h"
 #include "backend/sim_program.h"
 #include "backend/sim_program.hpp"
+#include "backend/sim_context.hpp"
 #include <cstring>
-#include <cstdio>
-#include <fstream>
-#include "dlfcn.h"
+#include <dlfcn.h>
 
 namespace gbe {
 
@@ -39,36 +38,11 @@ namespace gbe {
   SimProgram::SimProgram(void) {}
   SimProgram::~SimProgram(void) {}
 
-  Kernel *SimProgram::compileKernel(const std::string &name) {
-    SimKernel *kernel = GBE_NEW(SimKernel, name);
-    char srcStr[L_tmpnam+1], libStr[L_tmpnam+1];
-    const std::string srcName = std::string(tmpnam_r(srcStr)) + ".cpp"; /* unsecure but we don't care */
-    const std::string libName = std::string(tmpnam_r(libStr)) + ".so";  /* unsecure but we don't care */
-
-    /* Output the code first */
-    std::ofstream ostream;
-    ostream.open(srcName);
-    ostream << "extern \"C\" void " << name << "() {}" << std::endl;
-    ostream.close();
-
-    /* Compile the function */
-    std::cout << srcName << " " << libName;
-    std::string compileCmd = "g++ -shared -O3 -o ";
-    compileCmd += libName;
-    compileCmd += " ";
-    compileCmd += srcName;
-    printf(compileCmd.c_str());
-    if (UNLIKELY(system(compileCmd.c_str()) != 0))
-      FATAL("Simulation program compilation failed");
-
-    /* Load it and get the function pointer */
-    kernel->handle = dlopen(libName.c_str(), RTLD_NOW);
-    if (UNLIKELY(kernel->handle == NULL))
-      FATAL("Failed to open the compiled shared object");
-    kernel->fn = (SimKernelCallBack*) dlsym(kernel->handle, name.c_str());
-    if (UNLIKELY(kernel->fn == NULL))
-      FATAL("Failed to get the symbol from the compiled shared object");
-    return kernel;
+  Kernel *SimProgram::compileKernel(const ir::Unit &unit, const std::string &name) {
+    Context *ctx = GBE_NEW(SimContext, unit, name);
+    Kernel *ker = ctx->compileKernel();
+    GBE_DELETE(ctx);
+    return ker;
   }
 
   static gbe_program simProgramNewFromSource(const char *source) {
@@ -82,9 +56,9 @@ namespace gbe {
   }
 
   static gbe_program simProgramNewFromLLVM(const char *fileName,
-      size_t stringSize,
-      char *err,
-      size_t *errSize)
+                                           size_t stringSize,
+                                           char *err,
+                                           size_t *errSize)
   {
     using namespace gbe;
     SimProgram *program = GBE_NEW(SimProgram);
index a31877c..005221d 100644 (file)
@@ -58,7 +58,7 @@ namespace gbe {
     /*! Destroy the program */
     virtual ~SimProgram(void);
     /*! Implements base class */
-    virtual Kernel *compileKernel(const std::string &name);
+    virtual Kernel *compileKernel(const ir::Unit &unit, const std::string &name);
     GBE_STRUCT(SimProgram); //!< Use gbe allocators
   };
 
index cb0abd7..16cd781 100644 (file)
@@ -234,7 +234,6 @@ namespace ir {
       for (auto it = blocks.begin(); it != blocks.end(); ++it)
         (*it)->foreach(functor);
     }
-
   private:
     friend class Context;         //!< Can freely modify a function
     std::string name;             //!< Function name