mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
some minor tidying of -O gen-C++ sources
This commit is contained in:
parent
44a3ed676b
commit
769a3d958a
9 changed files with 56 additions and 46 deletions
|
@ -37,11 +37,12 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
// previously compiled instances of those if present.
|
||||
for ( auto& func : funcs ) {
|
||||
const auto& f = func.Func();
|
||||
auto& body = func.Body();
|
||||
|
||||
auto& ofiles = analysis_options.only_files;
|
||||
auto allow_cond = analysis_options.allow_cond;
|
||||
|
||||
string fn = func.Body()->GetLocationInfo()->filename;
|
||||
string fn = body->GetLocationInfo()->filename;
|
||||
|
||||
if ( ! allow_cond && ! func.ShouldSkip() && ! ofiles.empty() && files_with_conditionals.count(fn) > 0 ) {
|
||||
if ( report_uncompilable )
|
||||
|
@ -184,8 +185,8 @@ void CPPCompile::GenProlog() {
|
|||
Emit("namespace CPP_%s { // %s\n", Fmt(total_hash), string(working_dir));
|
||||
|
||||
// The following might-or-might-not wind up being populated/used.
|
||||
Emit("std::vector<int> field_mapping;");
|
||||
Emit("std::vector<int> enum_mapping;");
|
||||
Emit("std::vector<zeek_int_t> field_mapping;");
|
||||
Emit("std::vector<zeek_int_t> enum_mapping;");
|
||||
NL();
|
||||
|
||||
const_info[TYPE_BOOL] = CreateConstInitInfo("Bool", "ValPtr", "bool");
|
||||
|
|
|
@ -1248,7 +1248,7 @@ string CPPCompile::GenEnum(const TypePtr& t, const ValPtr& ev) {
|
|||
|
||||
if ( ! et->HasRedefs() )
|
||||
// Can use direct access.
|
||||
return std::to_string(v);
|
||||
return "zeek_int_t(" + std::to_string(v) + ")";
|
||||
|
||||
// Need to dynamically map the access.
|
||||
int mapping_slot;
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
#include "zeek/Func.h"
|
||||
#include "zeek/script_opt/ProfileFunc.h"
|
||||
|
||||
namespace zeek {
|
||||
|
||||
namespace detail {
|
||||
namespace zeek::detail {
|
||||
|
||||
// A subclass of Func used for lambdas that the compiler creates for
|
||||
// complex initializations (expressions used in type attributes).
|
||||
|
@ -42,11 +40,6 @@ public:
|
|||
|
||||
const std::string& Name() { return name; }
|
||||
|
||||
// Sets/returns a hash associated with this statement. A value
|
||||
// of 0 means "not set".
|
||||
p_hash_type GetHash() const { return hash; }
|
||||
void SetHash(p_hash_type h) { hash = h; }
|
||||
|
||||
// The following only get defined by lambda bodies.
|
||||
virtual void SetLambdaCaptures(Frame* f) {}
|
||||
virtual std::vector<ValPtr> SerializeLambdaCaptures() const { return std::vector<ValPtr>{}; }
|
||||
|
@ -64,7 +57,6 @@ protected:
|
|||
TraversalCode Traverse(TraversalCallback* cb) const override { return TC_CONTINUE; }
|
||||
|
||||
std::string name;
|
||||
p_hash_type hash = 0ULL;
|
||||
|
||||
// A pseudo AST "call" node, used to support error localization.
|
||||
CallExprPtr ce;
|
||||
|
@ -117,6 +109,4 @@ extern std::unordered_map<p_hash_type, void (*)()> standalone_callbacks;
|
|||
// Callbacks to finalize initialization of standalone compiled scripts.
|
||||
extern std::vector<void (*)()> standalone_finalizations;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace zeek
|
||||
} // namespace zeek::detail
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// standalone globals (for example, one for each BiF that a compiled script
|
||||
// may call).
|
||||
//
|
||||
// For each of these types of initialization, our general approach is to a
|
||||
// For each of these types of initialization, our general approach is to have a
|
||||
// class that manages a single instance of that type, and an an object that
|
||||
// manages all of those instances collectively. The latter object will, for
|
||||
// example, attend to determining the offset into the run-time vector associated
|
||||
|
@ -48,8 +48,15 @@
|
|||
// safely use cohort(X) = cohort(Y).) We then execute run-time initialization
|
||||
// in waves, one cohort at a time.
|
||||
//
|
||||
// Many forms of initialization are specified in terms of indices into globals
|
||||
// that hold items of various types. Thus, the most common initialization
|
||||
// information is a vector of integers/indices. These data structures can
|
||||
// be recursive, too, namely we sometimes associate an index with a vector
|
||||
// of integers/indices and then we can track multiple such vectors using
|
||||
// another vector of integers/indices.
|
||||
//
|
||||
// Because C++ compilers can struggle when trying to optimize large quantities
|
||||
// of code - clang in particular could take many CPU *hours* back when our
|
||||
// of code - clang in particular could take many CPU *hours* back when the
|
||||
// compiler just generated C++ code snippets for each initialization - rather
|
||||
// than producing code that directly executes each given initialization, we
|
||||
// instead employ a table-driven approach. The C++ initializers for the
|
||||
|
@ -58,12 +65,14 @@
|
|||
// cohort at a time) to obtain the information needed to initialize any given
|
||||
// item.
|
||||
//
|
||||
// Many forms of initialization are specified in terms of indices into globals
|
||||
// that hold items of various types. Thus, the most common initialization
|
||||
// information is a vector of integers/indices. These data structures can
|
||||
// be recursive, too, namely we sometimes associate an index with a vector
|
||||
// of integers/indices and then we can track multiple such vectors using
|
||||
// another vector of integers/indices.
|
||||
// Even this has headaches for very large initializations: both clang and g++
|
||||
// are *much* slower to initialize large vectors of simple template types
|
||||
// (such as std::pair) than non-template types (such as a struct with two
|
||||
// fields, which is all std::pair is, at the end of the day). A similar problem
|
||||
// holds for initializing vectors-of-vectors-of-vectors, so we reduce these
|
||||
// cases to simpler forms (structs for the first example, a single vector
|
||||
// with information embedded within it for how to expand its values into
|
||||
// a vector-of-vector-of-vector fr the second).
|
||||
|
||||
#include "zeek/File.h"
|
||||
#include "zeek/Val.h"
|
||||
|
|
|
@ -91,7 +91,7 @@ ValPtr when_index_slice__CPP(VectorVal* vec, const ListVal* lv) {
|
|||
return v;
|
||||
}
|
||||
|
||||
ValPtr when_invoke__CPP(Func* f, std::vector<ValPtr> args, Frame* frame, void* caller_addr) {
|
||||
ValPtr when_invoke__CPP(Func* f, ValVec args, Frame* frame, void* caller_addr) {
|
||||
auto trigger = frame->GetTrigger();
|
||||
|
||||
if ( trigger ) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
namespace zeek {
|
||||
|
||||
using IntVec = std::vector<int>;
|
||||
using ValVec = std::vector<ValPtr>;
|
||||
using SubNetValPtr = IntrusivePtr<zeek::SubNetVal>;
|
||||
|
||||
namespace detail {
|
||||
|
@ -27,21 +29,21 @@ extern bool str_in__CPP(const String* s1, const String* s2);
|
|||
|
||||
// Converts a vector of individual ValPtr's into a single ListValPtr
|
||||
// suitable for indexing an aggregate.
|
||||
extern ListValPtr index_val__CPP(std::vector<ValPtr> indices);
|
||||
extern ListValPtr index_val__CPP(ValVec indices);
|
||||
|
||||
// Returns the value corresponding to indexing the given table/vector/string
|
||||
// with the given set of indices. These are functions rather than something
|
||||
// generated directly so that they can package up the error handling for
|
||||
// the case where there's no such index. "patstr" refers to indexing a
|
||||
// table[pattern] of X with a string value.
|
||||
extern ValPtr index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
|
||||
extern ValPtr index_patstr_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
|
||||
extern ValPtr index_table__CPP(const TableValPtr& t, ValVec indices);
|
||||
extern ValPtr index_patstr_table__CPP(const TableValPtr& t, ValVec indices);
|
||||
extern ValPtr index_vec__CPP(const VectorValPtr& vec, int index);
|
||||
extern ValPtr index_string__CPP(const StringValPtr& svp, std::vector<ValPtr> indices);
|
||||
extern ValPtr index_string__CPP(const StringValPtr& svp, ValVec indices);
|
||||
|
||||
// The same, but for indexing happening inside a "when" clause.
|
||||
extern ValPtr when_index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
|
||||
extern ValPtr when_index_patstr__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
|
||||
extern ValPtr when_index_table__CPP(const TableValPtr& t, ValVec indices);
|
||||
extern ValPtr when_index_patstr__CPP(const TableValPtr& t, ValVec indices);
|
||||
extern ValPtr when_index_vec__CPP(const VectorValPtr& vec, int index);
|
||||
|
||||
// For vector slices, we use the existing index_slice(), but we need a
|
||||
|
@ -50,7 +52,7 @@ extern ValPtr when_index_slice__CPP(VectorVal* vec, const ListVal* lv);
|
|||
|
||||
// Calls out to the given script or BiF function, which does not return
|
||||
// a value.
|
||||
inline ValPtr invoke_void__CPP(Func* f, std::vector<ValPtr> args, Frame* frame) { return f->Invoke(&args, frame); }
|
||||
inline ValPtr invoke_void__CPP(Func* f, ValVec args, Frame* frame) { return f->Invoke(&args, frame); }
|
||||
|
||||
// Used for error propagation by failed calls.
|
||||
class CPPInterpreterException : public InterpreterException {};
|
||||
|
@ -58,7 +60,7 @@ class CPPInterpreterException : public InterpreterException {};
|
|||
// Calls out to the given script or BiF function. A separate function because
|
||||
// of the need to (1) construct the "args" vector using {} initializers,
|
||||
// but (2) needing to have the address of that vector.
|
||||
inline ValPtr invoke__CPP(Func* f, std::vector<ValPtr> args, Frame* frame) {
|
||||
inline ValPtr invoke__CPP(Func* f, ValVec args, Frame* frame) {
|
||||
auto v = f->Invoke(&args, frame);
|
||||
if ( ! v )
|
||||
throw CPPInterpreterException();
|
||||
|
@ -71,7 +73,7 @@ inline ValPtr invoke__CPP(Func* f, std::vector<ValPtr> args, Frame* frame) {
|
|||
// last argument is the address of the calling function; we just need
|
||||
// it to be distinct to the call, so we can associate a Trigger cache
|
||||
// with it.
|
||||
extern ValPtr when_invoke__CPP(Func* f, std::vector<ValPtr> args, Frame* frame, void* caller_addr);
|
||||
extern ValPtr when_invoke__CPP(Func* f, ValVec args, Frame* frame, void* caller_addr);
|
||||
|
||||
// Thrown when a call inside a "when" delays.
|
||||
class CPPDelayedCallException : public InterpreterException {};
|
||||
|
@ -201,29 +203,35 @@ inline VectorValPtr vector_coerce__CPP(const ValPtr& v, const TypePtr& t) {
|
|||
return make_intrusive<VectorVal>(cast_intrusive<VectorType>(t));
|
||||
}
|
||||
|
||||
// Takes parallel vectors of attribute tags and values and returns a
|
||||
// collective AttributesPtr corresponding to those instantiated attributes.
|
||||
// For attributes that don't have associated expressions, the corresponding
|
||||
// value should be nil.
|
||||
|
||||
extern AttributesPtr build_attrs__CPP(IntVec attr_tags, std::vector<ValPtr> attr_vals);
|
||||
|
||||
// Constructs a set of the given type, containing the given elements, and
|
||||
// with the associated attributes.
|
||||
extern TableValPtr set_constructor__CPP(std::vector<ValPtr> elements, TableTypePtr t, std::vector<int> attr_tags,
|
||||
std::vector<ValPtr> attr_vals);
|
||||
extern TableValPtr set_constructor__CPP(ValVec elements, TableTypePtr t, IntVec attr_tags, ValVec attr_vals);
|
||||
|
||||
// Constructs a table of the given type, containing the given elements
|
||||
// (specified as parallel index/value vectors), and with the associated
|
||||
// attributes.
|
||||
extern TableValPtr table_constructor__CPP(std::vector<ValPtr> indices, std::vector<ValPtr> vals, TableTypePtr t,
|
||||
std::vector<int> attr_tags, std::vector<ValPtr> attr_vals);
|
||||
extern TableValPtr table_constructor__CPP(ValVec indices, ValVec vals, TableTypePtr t, IntVec attr_tags,
|
||||
ValVec attr_vals);
|
||||
|
||||
// Assigns a set of attributes to an identifier.
|
||||
extern void assign_attrs__CPP(IDPtr id, std::vector<int> attr_tags, std::vector<ValPtr> attr_vals);
|
||||
extern void assign_attrs__CPP(IDPtr id, IntVec attr_tags, ValVec attr_vals);
|
||||
|
||||
// Constructs a record of the given type, whose (ordered) fields are
|
||||
// assigned to the corresponding elements of the given vector of values.
|
||||
extern RecordValPtr record_constructor__CPP(std::vector<ValPtr> vals, RecordTypePtr t);
|
||||
extern RecordValPtr record_constructor__CPP(ValVec vals, RecordTypePtr t);
|
||||
|
||||
// Same, but with a map when using a named constructor.
|
||||
extern RecordValPtr record_constructor_map__CPP(std::vector<ValPtr> vals, std::vector<int> map, RecordTypePtr t);
|
||||
extern RecordValPtr record_constructor_map__CPP(ValVec vals, IntVec map, RecordTypePtr t);
|
||||
|
||||
// Constructs a vector of the given type, populated with the given values.
|
||||
extern VectorValPtr vector_constructor__CPP(std::vector<ValPtr> vals, VectorTypePtr t);
|
||||
extern VectorValPtr vector_constructor__CPP(ValVec vals, VectorTypePtr t);
|
||||
|
||||
// For patterns, executes p1 += p2.
|
||||
inline PatternValPtr re_append__CPP(const PatternValPtr& p1, const PatternValPtr& p2) {
|
||||
|
@ -234,7 +242,7 @@ inline PatternValPtr re_append__CPP(const PatternValPtr& p1, const PatternValPtr
|
|||
// Schedules an event to occur at the given absolute time, parameterized
|
||||
// with the given set of values. A separate function to facilitate avoiding
|
||||
// the scheduling if Zeek is terminating.
|
||||
extern ValPtr schedule__CPP(double dt, EventHandlerPtr event, std::vector<ValPtr> args);
|
||||
extern ValPtr schedule__CPP(double dt, EventHandlerPtr event, ValVec args);
|
||||
|
||||
// Simple helper functions for supporting absolute value.
|
||||
inline zeek_uint_t iabs__CPP(zeek_int_t v) { return v < 0 ? -v : v; }
|
||||
|
|
|
@ -109,7 +109,7 @@ VEC_OP1(comp, ~, )
|
|||
}
|
||||
|
||||
// Analogous to VEC_OP1, instantiates a function for a given binary operation,
|
||||
// with customimzable kernels for "int" and "double" operations.
|
||||
// with customizable kernels for "int" and "double" operations.
|
||||
// This version is for operations whose result type is the same as the
|
||||
// operand type.
|
||||
#define VEC_OP2(name, op, int_kernel, double_kernel, zero_check, is_bool) \
|
||||
|
|
|
@ -352,7 +352,7 @@ void CPPCompile::GenWhenStmt(const WhenStmt* w) {
|
|||
|
||||
if ( ret_type && ret_type->Tag() != TYPE_VOID ) {
|
||||
// Note, ret_type can be active but we *still* don't have
|
||||
// a return type, due to the faked-up "any" return type
|
||||
// a return value, due to the faked-up "any" return type
|
||||
// associated with "when" lambdas, so check for that case.
|
||||
Emit("if ( curr_t )");
|
||||
StartBlock();
|
||||
|
|
|
@ -401,7 +401,6 @@ static void use_CPP() {
|
|||
++num_used;
|
||||
|
||||
auto b = s->second.body;
|
||||
b->SetHash(hash);
|
||||
|
||||
// We may have already updated the body if
|
||||
// we're using code compiled for standalone.
|
||||
|
@ -532,6 +531,9 @@ static void analyze_scripts_for_ZAM() {
|
|||
}
|
||||
|
||||
void clear_script_analysis() {
|
||||
if ( analysis_options.gen_CPP )
|
||||
return;
|
||||
|
||||
IDOptInfo::ClearGlobalInitExprs();
|
||||
|
||||
// We need to explicitly clear out the optimization information
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue