[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