first cut of switching over compound initializations to flat arrays

This commit is contained in:
Vern Paxson 2024-08-09 18:19:02 -07:00
parent d1a5f0f0ff
commit df7b346337
4 changed files with 93 additions and 27 deletions

View file

@ -38,6 +38,13 @@ void CPP_InitsInfo::GenerateInitializers(CPPCompile* c) {
c->Emit("%s %s = %s(%s, %s,", gt, InitializersName(), gt, base_name, Fmt(offset_set)); c->Emit("%s %s = %s(%s, %s,", gt, InitializersName(), gt, base_name, Fmt(offset_set));
c->IndentUp(); c->IndentUp();
GenerateCohorts(c);
c->IndentDown();
c->Emit(");");
}
void CPP_InitsInfo::GenerateCohorts(CPPCompile* c) {
c->Emit("{"); c->Emit("{");
int n = 0; int n = 0;
@ -47,7 +54,7 @@ void CPP_InitsInfo::GenerateInitializers(CPPCompile* c) {
if ( ++n > 1 ) if ( ++n > 1 )
c->Emit(""); c->Emit("");
if ( cohort.size() == 1 && ! IsCompound() ) if ( cohort.size() == 1 && ! UsesCompoundVectors() )
BuildCohort(c, cohort); BuildCohort(c, cohort);
else { else {
c->Emit("{"); c->Emit("{");
@ -57,8 +64,6 @@ void CPP_InitsInfo::GenerateInitializers(CPPCompile* c) {
} }
c->Emit("}"); c->Emit("}");
c->IndentDown();
c->Emit(");");
} }
void CPP_InitsInfo::BuildOffsetSet(CPPCompile* c) { void CPP_InitsInfo::BuildOffsetSet(CPPCompile* c) {
@ -117,12 +122,36 @@ void CPP_InitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<s
c->Emit("std::make_shared<%s>(%s),", init_type, full_init); c->Emit("std::make_shared<%s>(%s),", init_type, full_init);
} }
void CPP_CompoundInitsInfo::GenerateInitializers(CPPCompile* c) {
c->Emit("static int %s_init[] = {", tag);
int n = 0;
c->IndentUp();
for ( auto& cohort : instances ) {
if ( ++n > 1 )
c->Emit("");
c->Emit(Fmt(int(cohort.size())) + ",");
BuildCohort(c, cohort);
c->Emit("-1,");
}
c->Emit("-2,");
c->IndentDown();
c->Emit("};");
CPP_InitsInfo::GenerateInitializers(c);
}
void CPP_CompoundInitsInfo::GenerateCohorts(CPPCompile* c) { c->Emit("%s_init", tag); }
void CPP_CompoundInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) { void CPP_CompoundInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {
string init_line; string init_line;
for ( auto& iv : ivs ) for ( auto& iv : ivs )
init_line += iv + ", "; init_line += iv;
c->Emit("{ %s},", init_line); c->Emit("%s,", init_line);
} }
void CPP_BasicConstInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) { void CPP_BasicConstInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {

View file

@ -133,10 +133,10 @@ public:
// Sets the associated C++ type. // Sets the associated C++ type.
virtual void SetCPPType(std::string ct) { CPP_type = std::move(ct); } virtual void SetCPPType(std::string ct) { CPP_type = std::move(ct); }
// Whether this initializer is in terms of compound objects. Used // Whether this initializer is in terms of compound vectors. Used
// for avoiding compiler warnings about singleton initializations in // for avoiding compiler warnings about singleton initializations in
// braces. // braces.
virtual bool IsCompound() const { return false; } virtual bool UsesCompoundVectors() const { return false; }
// Returns the type associated with the table used for initialization // Returns the type associated with the table used for initialization
// (i.e., this is the type of the global returned by InitializersName()). // (i.e., this is the type of the global returned by InitializersName()).
@ -146,9 +146,11 @@ public:
void AddInstance(std::shared_ptr<CPP_InitInfo> g); void AddInstance(std::shared_ptr<CPP_InitInfo> g);
// Emit code to populate the table used to initialize this collection. // Emit code to populate the table used to initialize this collection.
void GenerateInitializers(CPPCompile* c); virtual void GenerateInitializers(CPPCompile* c);
protected: protected:
virtual void GenerateCohorts(CPPCompile* c);
// Computes offset_set - see below. // Computes offset_set - see below.
void BuildOffsetSet(CPPCompile* c); void BuildOffsetSet(CPPCompile* c);
@ -214,7 +216,7 @@ public:
BuildInitType(); BuildInitType();
} }
bool IsCompound() const override { return true; } bool UsesCompoundVectors() const override { return true; }
private: private:
void BuildInitType() { inits_type = std::string("CPP_CustomInits<") + CPPType() + ">"; } void BuildInitType() { inits_type = std::string("CPP_CustomInits<") + CPPType() + ">"; }
@ -236,7 +238,7 @@ public:
inits_type = std::string("CPP_BasicConsts<") + CPP_type + ", " + c_type + ", " + tag + "Val>"; inits_type = std::string("CPP_BasicConsts<") + CPP_type + ", " + c_type + ", " + tag + "Val>";
} }
bool IsCompound() const override { return false; } bool UsesCompoundVectors() const override { return false; }
void BuildCohortElement(CPPCompile* c, std::string init_type, std::vector<std::string>& ivs) override; void BuildCohortElement(CPPCompile* c, std::string init_type, std::vector<std::string>& ivs) override;
}; };
@ -254,7 +256,12 @@ public:
inits_type = std::string("CPP_IndexedInits<") + CPPType() + ">"; inits_type = std::string("CPP_IndexedInits<") + CPPType() + ">";
} }
bool IsCompound() const override { return true; } // This isn't true (anymore) because we separately build up the compound
// vectors needed for the initialization.
bool UsesCompoundVectors() const override { return false; }
void GenerateInitializers(CPPCompile* c) override;
void GenerateCohorts(CPPCompile* c) override;
void BuildCohortElement(CPPCompile* c, std::string init_type, std::vector<std::string>& ivs) override; void BuildCohortElement(CPPCompile* c, std::string init_type, std::vector<std::string>& ivs) override;
}; };

View file

@ -465,7 +465,7 @@ void CPP_GlobalInit::Generate(InitsManager* im, std::vector<void*>& /* inits_vec
global->SetAttrs(im->Attributes(attrs)); global->SetAttrs(im->Attributes(attrs));
} }
void generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set) { size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set) {
// First figure out how many groups of indices there are, so we // First figure out how many groups of indices there are, so we
// can pre-allocate the outer vector. // can pre-allocate the outer vector.
auto i_ptr = inits; auto i_ptr = inits;
@ -490,6 +490,26 @@ void generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set
indices_set.emplace_back(std::move(indices)); indices_set.emplace_back(std::move(indices));
} }
return i_ptr - inits + 1;
}
std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits) {
// Figure out how many vector-of-vectors there are.
int num_vv = 0;
for ( int i = 0; inits[i] >= -1; ++i )
if ( inits[i] == -1 )
++num_vv;
std::vector<std::vector<std::vector<int>>> indices_set(num_vv);
auto i_ptr = inits;
for ( int i = 0; i < num_vv; ++i )
i_ptr += generate_indices_set(i_ptr, indices_set[i]);
ASSERT(*i_ptr == -2);
return indices_set;
} }
} // namespace zeek::detail } // namespace zeek::detail

View file

@ -19,6 +19,23 @@ using FuncValPtr = IntrusivePtr<FuncVal>;
class InitsManager; class InitsManager;
// Helper function that takes a (large) array of int's and from them
// constructs the corresponding vector-of-vector-of-indices. Each
// vector-of-indices is represented first by an int specifying its
// size, and then that many int's for its values. We recognize the
// end of the array upon encountering a "size" entry of -1.
//
// Returns how many elements were processed out of "inits", including its
// terminator.
extern size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set);
// The same but for one more level of vector construction. The source array
// has sub-arrays terminated with -1 per the above, and the whole shebang
// is terminated with -2.
//
// Returns the vector construction.
extern std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits);
// An abstract helper class used to access elements of an initialization vector. // An abstract helper class used to access elements of an initialization vector.
// We need the abstraction because InitsManager below needs to be able to refer // We need the abstraction because InitsManager below needs to be able to refer
// to any of a range of templated classes. // to any of a range of templated classes.
@ -223,16 +240,16 @@ using ValElemVecVec = std::vector<ValElemVec>;
template<class T> template<class T>
class CPP_IndexedInits : public CPP_AbstractInits<T, ValElemVecVec> { class CPP_IndexedInits : public CPP_AbstractInits<T, ValElemVecVec> {
public: public:
CPP_IndexedInits(std::vector<T>& _inits_vec, int _offsets_set, std::vector<ValElemVecVec> _inits) CPP_IndexedInits(std::vector<T>& _inits_vec, int _offsets_set, int* raw_inits)
: CPP_AbstractInits<T, ValElemVecVec>(_inits_vec, _offsets_set, std::move(_inits)) {} : CPP_AbstractInits<T, ValElemVecVec>(_inits_vec, _offsets_set, generate_indices_set(raw_inits)) {}
protected: protected:
void InitializeCohortWithOffsets(InitsManager* im, int cohort, const std::vector<int>& cohort_offsets) override; void InitializeCohortWithOffsets(InitsManager* im, int cohort, const std::vector<int>& cohort_offsets) override;
// Note, in the following we pass in the inits_vec, even though // Note, in the following we pass in the inits_vec ("ivec", even though
// the method will have direct access to it, because we want to // the method will have direct access to it, because we want to use
// use overloading to dispatch to custom generation for different // overloading to dispatch to custom generation for different types of
// types of values. // values.
void Generate(InitsManager* im, std::vector<EnumValPtr>& ivec, int offset, ValElemVec& init_vals); void Generate(InitsManager* im, std::vector<EnumValPtr>& ivec, int offset, ValElemVec& init_vals);
void Generate(InitsManager* im, std::vector<StringValPtr>& ivec, int offset, ValElemVec& init_vals); void Generate(InitsManager* im, std::vector<StringValPtr>& ivec, int offset, ValElemVec& init_vals);
void Generate(InitsManager* im, std::vector<PatternValPtr>& ivec, int offset, ValElemVec& init_vals); void Generate(InitsManager* im, std::vector<PatternValPtr>& ivec, int offset, ValElemVec& init_vals);
@ -256,8 +273,8 @@ protected:
// on subclasses of TypePtr. // on subclasses of TypePtr.
class CPP_TypeInits : public CPP_IndexedInits<TypePtr> { class CPP_TypeInits : public CPP_IndexedInits<TypePtr> {
public: public:
CPP_TypeInits(std::vector<TypePtr>& _inits_vec, int _offsets_set, std::vector<ValElemVecVec> _inits) CPP_TypeInits(std::vector<TypePtr>& _inits_vec, int _offsets_set, int* raw_inits)
: CPP_IndexedInits<TypePtr>(_inits_vec, _offsets_set, _inits) {} : CPP_IndexedInits<TypePtr>(_inits_vec, _offsets_set, raw_inits) {}
protected: protected:
void DoPreInits(InitsManager* im, const std::vector<int>& offsets_vec) override; void DoPreInits(InitsManager* im, const std::vector<int>& offsets_vec) override;
@ -506,11 +523,4 @@ struct CPP_RegisterBody {
std::vector<std::string> events; std::vector<std::string> events;
}; };
// Helper function that takes a (large) array of int's and from them
// constructs the corresponding vector-of-vector-of-indices. Each
// vector-of-indices is represented first by an int specifying its
// size, and then that many int's for its values. We recognize the
// end of the array upon encountering a "size" entry of -1.
extern void generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set);
} // namespace zeek::detail } // namespace zeek::detail