mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
streamline generated -O C++ code by relying on per-function profiles rather than aggregate profile
This commit is contained in:
parent
79c5790bbf
commit
612d99e751
3 changed files with 43 additions and 12 deletions
|
@ -29,6 +29,7 @@ CPPCompile::CPPCompile(vector<FuncInfo>& _funcs, std::shared_ptr<ProfileFuncs> _
|
|||
CPPCompile::~CPPCompile() { fclose(write_file); }
|
||||
|
||||
void CPPCompile::Compile(bool report_uncompilable) {
|
||||
unordered_set<const Type*> rep_types;
|
||||
unordered_set<string> filenames_reported_as_skipped;
|
||||
bool had_to_skip = false;
|
||||
|
||||
|
@ -63,6 +64,24 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
continue;
|
||||
}
|
||||
|
||||
auto pf = func.Profile();
|
||||
total_hash = merge_p_hashes(total_hash, pf->HashVal());
|
||||
|
||||
for ( auto t : pf->UnorderedTypes() )
|
||||
rep_types.insert(pfs->TypeRep(t));
|
||||
|
||||
auto& pf_all_gl = pf->AllGlobals();
|
||||
all_accessed_globals.insert(pf_all_gl.begin(), pf_all_gl.end());
|
||||
|
||||
auto& pf_gl = pf->Globals();
|
||||
accessed_globals.insert(pf_gl.begin(), pf_gl.end());
|
||||
|
||||
auto& pf_events = pf->Events();
|
||||
accessed_events.insert(pf_events.begin(), pf_events.end());
|
||||
|
||||
auto& pf_lambdas = pf->Lambdas();
|
||||
accessed_lambdas.insert(pf_lambdas.begin(), pf_lambdas.end());
|
||||
|
||||
if ( is_lambda(f) || is_when_lambda(f) ) {
|
||||
// We deal with these separately.
|
||||
func.SetSkip(true);
|
||||
|
@ -85,35 +104,35 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( standalone && had_to_skip )
|
||||
reporter->FatalError("aborting standalone compilation to C++ due to having to skip some functions");
|
||||
|
||||
// Generate a hash unique for this compilation.
|
||||
for ( const auto& func : funcs )
|
||||
if ( ! func.ShouldSkip() )
|
||||
total_hash = merge_p_hashes(total_hash, func.Profile()->HashVal());
|
||||
|
||||
if ( standalone && had_to_skip )
|
||||
reporter->FatalError("aborting standalone compilation to C++ due to having to skip some functions");
|
||||
|
||||
auto t = util::current_time();
|
||||
total_hash = merge_p_hashes(total_hash, hash<double>{}(t));
|
||||
|
||||
GenProlog();
|
||||
|
||||
// Track all of the types we'll be using.
|
||||
for ( const auto& t : pfs->RepTypes() ) {
|
||||
for ( const auto& t : rep_types ) {
|
||||
TypePtr tp{NewRef{}, (Type*)(t)};
|
||||
types.AddKey(tp, pfs->HashType(t));
|
||||
}
|
||||
|
||||
NL();
|
||||
|
||||
for ( auto& g : pfs->AllGlobals() )
|
||||
for ( auto& g : all_accessed_globals )
|
||||
CreateGlobal(g);
|
||||
|
||||
for ( const auto& e : pfs->Events() )
|
||||
for ( const auto& e : accessed_events )
|
||||
if ( AddGlobal(e, "gl") )
|
||||
Emit("EventHandlerPtr %s_ev;", globals[string(e)]);
|
||||
|
||||
for ( const auto& t : pfs->RepTypes() ) {
|
||||
for ( const auto& t : rep_types ) {
|
||||
ASSERT(types.HasKey(t));
|
||||
TypePtr tp{NewRef{}, (Type*)(t)};
|
||||
RegisterType(tp);
|
||||
|
@ -131,7 +150,7 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
// be identical. In that case, we don't want to generate the lambda
|
||||
// twice, but we do want to map the second one to the same body name.
|
||||
unordered_map<string, const Stmt*> lambda_ASTs;
|
||||
for ( const auto& l : pfs->Lambdas() ) {
|
||||
for ( const auto& l : accessed_lambdas ) {
|
||||
const auto& n = l->Name();
|
||||
const auto body = l->Ingredients()->Body().get();
|
||||
if ( lambda_ASTs.count(n) > 0 )
|
||||
|
@ -151,7 +170,7 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
CompileFunc(func);
|
||||
|
||||
lambda_ASTs.clear();
|
||||
for ( const auto& l : pfs->Lambdas() ) {
|
||||
for ( const auto& l : accessed_lambdas ) {
|
||||
const auto& n = l->Name();
|
||||
if ( lambda_ASTs.count(n) > 0 )
|
||||
continue;
|
||||
|
|
|
@ -308,9 +308,8 @@ string CPPCompile::GenCallExpr(const CallExpr* c, GenType gt, bool top_level) {
|
|||
if ( pfs->BiFGlobals().count(f_id) == 0 )
|
||||
gen += +"->AsFunc()";
|
||||
|
||||
else if ( pfs->Globals().count(f_id) > 0 )
|
||||
// The BiF version has an extra "_", per
|
||||
// AddBiF(..., true).
|
||||
else if ( accessed_globals.count(f_id) > 0 )
|
||||
// The BiF version has an extra "_", per AddBiF(..., true).
|
||||
gen = globals[string(id_name) + "_"];
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,19 @@ std::string Canonicalize(const std::string& name) const;
|
|||
// be a EXPR_NAME).
|
||||
std::string GlobalName(const ExprPtr& e) { return globals[e->AsNameExpr()->Id()->Name()]; }
|
||||
|
||||
// Globals that are used (appear in the profiles) of the bodies we're
|
||||
// compiling. Includes globals just used as functions to call.
|
||||
std::unordered_set<const ID*> all_accessed_globals;
|
||||
|
||||
// Same, but just the globals used in contexts beyond function calls.
|
||||
std::unordered_set<const ID*> accessed_globals;
|
||||
|
||||
// Lambdas that are accessed.
|
||||
std::unordered_set<const LambdaExpr*> accessed_lambdas;
|
||||
|
||||
// Events that are accessed.
|
||||
std::unordered_set<std::string> accessed_events;
|
||||
|
||||
// Maps global names (not identifiers) to the names we use for them.
|
||||
std::unordered_map<std::string, std::string> globals;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue