[Beignet] [PATCH 5/5] GBE: Refine program scope variable logic.

Ruiling Song ruiling.song at intel.com
Thu Apr 7 06:39:58 UTC 2016


The program scope variable may appear in Module's global list as
unordered. So I choose to split the program scope logic into two
passes. The first pass will just create these constants. The second
pass to initialize the data.

Signed-off-by: Ruiling Song <ruiling.song at intel.com>
---
 backend/src/ir/constant.cpp           |  6 ++--
 backend/src/ir/constant.hpp           |  7 ++++-
 backend/src/ir/unit.cpp               |  5 ++--
 backend/src/ir/unit.hpp               |  2 +-
 backend/src/llvm/llvm_gen_backend.cpp | 52 +++++++++++++++++++++--------------
 5 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/backend/src/ir/constant.cpp b/backend/src/ir/constant.cpp
index fa4e14a..f8d716c 100644
--- a/backend/src/ir/constant.cpp
+++ b/backend/src/ir/constant.cpp
@@ -27,8 +27,7 @@
 namespace gbe {
 namespace ir {
 
-  void ConstantSet::append(const char *data,
-                           const std::string &name,
+  void ConstantSet::append(const std::string &name,
                            uint32_t size,
                            uint32_t alignment)
   {
@@ -36,8 +35,7 @@ namespace ir {
     const uint32_t padding = offset - this->data.size();
     const Constant constant(name, size, alignment, offset);
     constants.push_back(constant);
-    for (uint32_t i = 0; i < padding; ++i) this->data.push_back(0);
-    for (uint32_t i = 0; i < size; ++i) this->data.push_back(data[i]);
+    this->data.resize(padding + size + this->data.size());
   }
 
 #define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)
diff --git a/backend/src/ir/constant.hpp b/backend/src/ir/constant.hpp
index 0891d7b..4d736e1 100644
--- a/backend/src/ir/constant.hpp
+++ b/backend/src/ir/constant.hpp
@@ -69,7 +69,7 @@ namespace ir {
   {
   public:
     /*! Append a new constant in the constant set */
-    void append(const char*, const std::string&, uint32_t size, uint32_t alignment);
+    void append(const std::string&, uint32_t size, uint32_t alignment);
     /*! Number of constants */
     size_t getConstantNum(void) const { return constants.size(); }
     /*! Get a special constant */
@@ -91,6 +91,11 @@ namespace ir {
       for (size_t i = 0; i < data.size(); i ++)
         mem[i] = data[i];
     }
+    void setData(char *mem, int offset, int size) {
+      for (int i = 0; i < size; i++) {
+        data[i+offset] = mem[i];
+      }
+    }
     ConstantSet() {}
     ConstantSet(const ConstantSet& other) : Serializable(other),
                 data(other.data), constants(other.constants) {}
diff --git a/backend/src/ir/unit.cpp b/backend/src/ir/unit.cpp
index 84208e5..a2a1096 100644
--- a/backend/src/ir/unit.cpp
+++ b/backend/src/ir/unit.cpp
@@ -45,12 +45,11 @@ namespace ir {
     functions[name] = fn;
     return fn;
   }
-  void Unit::newConstant(const char *data,
-                         const std::string &name,
+  void Unit::newConstant(const std::string &name,
                          uint32_t size,
                          uint32_t alignment)
   {
-    constantSet.append(data, name, size, alignment);
+    constantSet.append(name, size, alignment);
   }
 
   std::ostream &operator<< (std::ostream &out, const Unit &unit) {
diff --git a/backend/src/ir/unit.hpp b/backend/src/ir/unit.hpp
index ce603a0..cbdab2f 100644
--- a/backend/src/ir/unit.hpp
+++ b/backend/src/ir/unit.hpp
@@ -99,7 +99,7 @@ namespace ir {
     /*! Return NULL if the function already exists */
     Function *newFunction(const std::string &name);
     /*! Create a new constant in the constant set */
-    void newConstant(const char*, const std::string&, uint32_t size, uint32_t alignment);
+    void newConstant(const std::string&, uint32_t size, uint32_t alignment);
     /*! Apply the given functor on all the functions */
     template <typename T>
     INLINE void apply(const T &functor) const {
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 2942fa2..aa61bdd 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1584,38 +1584,48 @@ namespace gbe
                }
     }
   }
-
+  static bool isProgramGlobal(const GlobalVariable &v) {
+    unsigned addrSpace = v.getType()->getAddressSpace();
+    // private/global/constant
+    return (addrSpace == 2 || addrSpace == 1 || addrSpace == 0);
+  }
   void GenWriter::collectGlobalConstant(void) const {
     const Module::GlobalListType &globalList = TheModule->getGlobalList();
+    // The first pass just create the global variable constants
     for(auto i = globalList.begin(); i != globalList.end(); i ++) {
       const GlobalVariable &v = *i;
       const char *name = v.getName().data();
-      unsigned addrSpace = v.getType()->getAddressSpace();
 
-      vector<ir::RelocEntry> relocs;
-      if(addrSpace == 2 /* __constant */
-          || addrSpace == 1
-          || addrSpace == 0) {
+      if(isProgramGlobal(v)) {
         Type * type = v.getValueType();
-
         uint32_t size = getTypeByteSize(unit, type);
-        void* mem = malloc(size);
-        uint32_t offset = 0;
+        uint32_t alignment = getAlignmentByte(unit, type);
+        unit.newConstant(name, size, alignment);
+      }
+    }
+    // the second pass to initialize the data
+    for(auto i = globalList.begin(); i != globalList.end(); i ++) {
+      const GlobalVariable &v = *i;
+      const char *name = v.getName().data();
+
+      if(isProgramGlobal(v)) {
         if (v.hasInitializer()) {
+          vector<ir::RelocEntry> relocs;
+          uint32_t offset = 0;
+          ir::Constant &con = unit.getConstantSet().getConstant(name);
+          void* mem = malloc(con.getSize());
           const Constant *c = v.getInitializer();
           getConstantData(c, mem, offset, relocs);
-        } else {
-          memset(mem, 0, size);
-        }
-        uint32_t alignment = getAlignmentByte(unit, type);
-        unit.newConstant((char *)mem, name, size, alignment);
-        free(mem);
-        uint32_t refOffset = unit.getConstantSet().getConstant(name).getOffset();
-        for (uint32_t k = 0; k < relocs.size(); k++) {
-          unit.getRelocTable().addEntry(
-                               refOffset + relocs[k].refOffset,
-                               relocs[k].defOffset
-                               );
+          unit.getConstantSet().setData((char*)mem, con.getOffset(), con.getSize());
+          free(mem);
+
+          uint32_t refOffset = unit.getConstantSet().getConstant(name).getOffset();
+          for (uint32_t k = 0; k < relocs.size(); k++) {
+            unit.getRelocTable().addEntry(
+                                 refOffset + relocs[k].refOffset,
+                                 relocs[k].defOffset
+                                 );
+          }
         }
       }
     }
-- 
2.4.1



More information about the Beignet mailing list