@@ -42,6 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4242#include < llvm/IR/Constants.h>
4343#include < llvm/IR/DataLayout.h>
4444#include < llvm/IR/Type.h>
45+ #include < llvm/IR/Value.h>
4546
4647#include < cctype>
4748#include < functional>
@@ -467,6 +468,13 @@ class SymbolTableBuilder final {
467468 }
468469};
469470
471+ struct GVEncodingInfo {
472+ const GlobalVariable *GV;
473+ // Alignment requirments of a global variable that will be encoded after
474+ // the considered GV variable.
475+ unsigned NextGVAlignment;
476+ };
477+
470478} // namespace
471479
472480// Appends the binary of function/kernel represented by \p Func and \p BuiltFunc
@@ -503,11 +511,18 @@ getGenBinary(const FunctionGroup &FG, VISABuilder &VB) {
503511
504512static void appendGlobalVariableData (
505513 genx::BinaryDataAccumulator<const GlobalVariable *> &Accumulator,
506- const GlobalVariable &GV , const DataLayout &DL) {
514+ GVEncodingInfo GVInfo , const DataLayout &DL) {
507515 std::vector<char > Data;
508- vc::encodeConstant (*GV.getInitializer (), DL, std::back_inserter (Data));
509- // FIXME: alignment
510- Accumulator.append (&GV, Data.begin (), Data.end ());
516+ vc::encodeConstant (*GVInfo.GV ->getInitializer (), DL, std::back_inserter (Data));
517+
518+ // Pad before the next global.
519+ auto UnalignedNextGVAddress = Accumulator.getFullSize () + Data.size ();
520+ auto AlignedNextGVAddress =
521+ alignTo (UnalignedNextGVAddress, GVInfo.NextGVAlignment );
522+ std::fill_n (std::back_inserter (Data),
523+ AlignedNextGVAddress - UnalignedNextGVAddress, 0 );
524+
525+ Accumulator.append (GVInfo.GV , Data.begin (), Data.end ());
511526}
512527
513528// Not every global variable is a real global variable and should be encoded
@@ -521,16 +536,34 @@ static bool isRealGlobalVariable(const GlobalVariable &GV) {
521536 });
522537}
523538
539+ template <typename GlobalsRangeT>
540+ std::vector<GVEncodingInfo>
541+ prepareGlobalInfosForEncoding (GlobalsRangeT &&Globals) {
542+ auto RealGlobals = make_filter_range (Globals, [](const GlobalVariable &GV) {
543+ return isRealGlobalVariable (GV);
544+ });
545+ if (RealGlobals.begin () == RealGlobals.end ())
546+ return {};
547+ std::vector<GVEncodingInfo> Infos;
548+ std::transform (RealGlobals.begin (), std::prev (RealGlobals.end ()),
549+ std::next (RealGlobals.begin ()), std::back_inserter (Infos),
550+ [](const GlobalVariable &GV, const GlobalVariable &NextGV) {
551+ return GVEncodingInfo{&GV, NextGV.getAlignment ()};
552+ });
553+ Infos.push_back ({&*std::prev (RealGlobals.end ()), 1u });
554+ return std::move (Infos);
555+ }
556+
524557static ModuleDataT getModuleData (const Module &M) {
525558 genx::BinaryDataAccumulator<const GlobalVariable *> ConstantData;
526559 genx::BinaryDataAccumulator<const GlobalVariable *> GlobalData;
527- for ( auto &GV : M. globals ()) {
528- if (! isRealGlobalVariable (GV))
529- continue ;
530- if (GV. isConstant ())
531- appendGlobalVariableData (ConstantData, GV , M.getDataLayout ());
560+ std::vector<GVEncodingInfo> GVInfos =
561+ prepareGlobalInfosForEncoding (M. globals ());
562+ for ( auto GVInfo : GVInfos) {
563+ if (GVInfo. GV -> isConstant ())
564+ appendGlobalVariableData (ConstantData, GVInfo , M.getDataLayout ());
532565 else
533- appendGlobalVariableData (GlobalData, GV , M.getDataLayout ());
566+ appendGlobalVariableData (GlobalData, GVInfo , M.getDataLayout ());
534567 }
535568 return {std::move (ConstantData), std::move (GlobalData)};
536569}
0 commit comments