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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/beignet
