simpler workflow for -O gen-C++ ; also some hooks for -O gen-standalone-C++

This commit is contained in:
Vern Paxson 2021-06-04 17:01:53 -07:00
parent 98f549d65d
commit e1dc3e7b08
4 changed files with 57 additions and 16 deletions

View file

@ -134,8 +134,8 @@ namespace zeek::detail {
class CPPCompile { class CPPCompile {
public: public:
CPPCompile(std::vector<FuncInfo>& _funcs, ProfileFuncs& pfs, CPPCompile(std::vector<FuncInfo>& _funcs, ProfileFuncs& pfs,
const char* gen_name, CPPHashManager& hm, const std::string& gen_name, const std::string& addl_name,
bool update, bool standalone); CPPHashManager& _hm, bool _update, bool _standalone);
~CPPCompile(); ~CPPCompile();
private: private:
@ -390,9 +390,14 @@ private:
// function. // function.
std::string GenArgs(const RecordTypePtr& params, const Expr* e); std::string GenArgs(const RecordTypePtr& params, const Expr* e);
// Functions that we've declared/compiled. // Functions that we've declared/compiled. Indexed by full C++ name.
std::unordered_set<std::string> compiled_funcs; std::unordered_set<std::string> compiled_funcs;
// "Simple" functions that we've compiled, i.e., those that have
// a single body and thus can be called dirctly. Indexed by
// function name, and maps to the C++ name.
std::unordered_map<std::string, std::string> compiled_simple_funcs;
// Maps those to their associated files - used to make add-C++ body // Maps those to their associated files - used to make add-C++ body
// hashes distinct. // hashes distinct.
std::unordered_map<std::string, std::string> cf_locs; std::unordered_map<std::string, std::string> cf_locs;
@ -858,6 +863,12 @@ private:
void AddInit(const IntrusivePtr<Obj>& o) { AddInit(o.get()); } void AddInit(const IntrusivePtr<Obj>& o) { AddInit(o.get()); }
void AddInit(const Obj* o); void AddInit(const Obj* o);
// This is akin to an initialization, but done separately
// (upon "activation") so it can include initializations that
// rely on parsing having finished (in particular, BiFs having
// been registered). Only used when generating standalone code.
void AddActivation(std::string a) { activations.emplace_back(a); }
// Records the fact that the initialization of object o1 depends // Records the fact that the initialization of object o1 depends
// on that of object o2. // on that of object o2.
void NoteInitDependency(const IntrusivePtr<Obj>& o1, void NoteInitDependency(const IntrusivePtr<Obj>& o1,
@ -922,6 +933,10 @@ private:
// other initializations, and that themselves have no dependencies). // other initializations, and that themselves have no dependencies).
std::vector<std::string> pre_inits; std::vector<std::string> pre_inits;
// A list of "activations" (essentially, post-initializations).
// See AddActivation() above.
std::vector<std::string> activations;
// Expressions for which we need to generate initialization-time // Expressions for which we need to generate initialization-time
// code. Currently, these are only expressions appearing in // code. Currently, these are only expressions appearing in
// attributes. // attributes.
@ -1010,6 +1025,9 @@ private:
// File to which we're generating code. // File to which we're generating code.
FILE* write_file; FILE* write_file;
// Name of file holding potential "additional" code.
std::string addl_name;
// Indentation level. // Indentation level.
int block_level = 0; int block_level = 0;

View file

@ -24,6 +24,9 @@ void CPPCompile::DeclareFunc(const FuncInfo& func)
DeclareSubclass(f->GetType(), pf, fname, body, priority, nullptr, DeclareSubclass(f->GetType(), pf, fname, body, priority, nullptr,
f->Flavor()); f->Flavor());
if ( f->GetBodies().size() == 1 )
compiled_simple_funcs[f->Name()] = fname;
} }
void CPPCompile::DeclareLambda(const LambdaExpr* l, const ProfileFunc* pf) void CPPCompile::DeclareLambda(const LambdaExpr* l, const ProfileFunc* pf)

View file

@ -13,20 +13,24 @@ using namespace std;
CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs, CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
const char* gen_name, CPPHashManager& _hm, const string& gen_name, const string& _addl_name,
bool _update, bool _standalone) CPPHashManager& _hm, bool _update, bool _standalone)
: funcs(_funcs), pfs(_pfs), hm(_hm), update(_update), standalone(_standalone) : funcs(_funcs), pfs(_pfs), hm(_hm),
update(_update), standalone(_standalone)
{ {
auto mode = hm.IsAppend() ? "a" : "w"; addl_name = _addl_name;
bool is_addl = hm.IsAppend();
auto target_name = is_addl ? addl_name.c_str() : gen_name.c_str();
auto mode = is_addl ? "a" : "w";
write_file = fopen(gen_name, mode); write_file = fopen(target_name, mode);
if ( ! write_file ) if ( ! write_file )
{ {
reporter->Error("can't open C++ target file %s", gen_name); reporter->Error("can't open C++ target file %s", target_name);
exit(1); exit(1);
} }
if ( hm.IsAppend() ) if ( is_addl )
{ {
// We need a unique number to associate with the name // We need a unique number to associate with the name
// space for the code we're adding. A convenient way to // space for the code we're adding. A convenient way to
@ -39,7 +43,7 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
{ {
char buf[256]; char buf[256];
util::zeek_strerror_r(errno, buf, sizeof(buf)); util::zeek_strerror_r(errno, buf, sizeof(buf));
reporter->Error("fstat failed on %s: %s", gen_name, buf); reporter->Error("fstat failed on %s: %s", target_name, buf);
exit(1); exit(1);
} }
@ -49,6 +53,20 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, ProfileFuncs& _pfs,
addl_tag = st.st_size + 1; addl_tag = st.st_size + 1;
} }
else
{
// Create an empty "additional" file.
auto addl_f = fopen(addl_name.c_str(), "w");
if ( ! addl_f )
{
reporter->Error("can't open C++ additional file %s",
addl_name.c_str());
exit(1);
}
fclose(addl_f);
}
Compile(); Compile();
} }
@ -313,7 +331,7 @@ void CPPCompile::GenEpilog()
if ( addl_tag > 0 ) if ( addl_tag > 0 )
return; return;
Emit("#include \"CPP-gen-addl.h\"\n"); Emit("#include \"" + addl_name + "\"\n");
Emit("} // zeek::detail"); Emit("} // zeek::detail");
} }

View file

@ -280,9 +280,6 @@ void analyze_scripts()
// Avoid profiling overhead. // Avoid profiling overhead.
return; return;
const auto hash_name = hash_dir + "CPP-hashes";
const auto gen_name = hash_dir + "CPP-gen-addl.h";
// Now that everything's parsed and BiF's have been initialized, // Now that everything's parsed and BiF's have been initialized,
// profile the functions. // profile the functions.
auto pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false); auto pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false);
@ -376,6 +373,8 @@ void analyze_scripts()
if ( generating_CPP ) if ( generating_CPP )
{ {
const auto hash_name = hash_dir + "CPP-hashes";
auto hm = std::make_unique<CPPHashManager>(hash_name.c_str(), auto hm = std::make_unique<CPPHashManager>(hash_name.c_str(),
analysis_options.add_CPP); analysis_options.add_CPP);
@ -394,7 +393,10 @@ void analyze_scripts()
pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false); pfs = std::make_unique<ProfileFuncs>(funcs, is_CPP_compilable, false);
} }
CPPCompile cpp(funcs, *pfs, gen_name.c_str(), *hm, const auto gen_name = hash_dir + "CPP-gen.cc";
const auto addl_name = hash_dir + "CPP-gen-addl.h";
CPPCompile cpp(funcs, *pfs, gen_name, addl_name, *hm,
analysis_options.gen_CPP || analysis_options.gen_CPP ||
analysis_options.update_CPP, analysis_options.update_CPP,
analysis_options.gen_standalone_CPP); analysis_options.gen_standalone_CPP);