authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-21 16:46:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-21 16:46:33-04:00
logc1642355f0b05f182c0b6d81d294d12be79ad0a8
tree350987257f118c809dc3bca09c02331c537504c8
parenta1af7cbf007f61e8fea06e1497b93c05bd989e74

parse-c: improve performance

previously we did linear search to find existing global declarations; now we index using a hash map. building tetris went from taking 5.3 sec to 0.76 sec

1 files changed, 17 insertions(+), 20 deletions(-)

src/parsec.cpp+17-20
...@@ -41,6 +41,7 @@ struct Context {...@@ -41,6 +41,7 @@ struct Context {
41 AstNode *root;41 AstNode *root;
42 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;42 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
43 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;43 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
44 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
44 SourceManager *source_manager;45 SourceManager *source_manager;
45 ZigList<Alias> aliases;46 ZigList<Alias> aliases;
46 ZigList<MacroSymbol> macro_symbols;47 ZigList<MacroSymbol> macro_symbols;
...@@ -296,20 +297,10 @@ static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child) {...@@ -296,20 +297,10 @@ static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child) {
296}297}
297298
298static AstNode *get_global(Context *c, Buf *name) {299static AstNode *get_global(Context *c, Buf *name) {
299 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {300 {
300 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];301 auto entry = c->global_table.maybe_get(name);
301 if (decl_node->type == NodeTypeVariableDeclaration) {302 if (entry) {
302 if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {303 return entry->value;
303 return decl_node;
304 }
305 } else if (decl_node->type == NodeTypeFnDef) {
306 if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
307 return decl_node;
308 }
309 } else if (decl_node->type == NodeTypeFnProto) {
310 if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
311 return decl_node;
312 }
313 }304 }
314 }305 }
315 {306 {
...@@ -320,11 +311,16 @@ static AstNode *get_global(Context *c, Buf *name) {...@@ -320,11 +311,16 @@ static AstNode *get_global(Context *c, Buf *name) {
320 return nullptr;311 return nullptr;
321}312}
322313
314static void add_top_level_decl(Context *c, Buf *name, AstNode *node) {
315 c->global_table.put(name, node);
316 c->root->data.root.top_level_decls.append(node);
317}
318
323static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {319static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
324 bool is_const = true;320 bool is_const = true;
325 AstNode *type_node = nullptr;321 AstNode *type_node = nullptr;
326 AstNode *node = trans_create_node_var_decl_global(c, is_const, var_name, type_node, value_node);322 AstNode *node = trans_create_node_var_decl_global(c, is_const, var_name, type_node, value_node);
327 c->root->data.root.top_level_decls.append(node);323 add_top_level_decl(c, var_name, node);
328 return node;324 return node;
329}325}
330326
...@@ -2519,7 +2515,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2519,7 +2515,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
25192515
2520 if (!fn_decl->hasBody()) {2516 if (!fn_decl->hasBody()) {
2521 // just a prototype2517 // just a prototype
2522 c->root->data.root.top_level_decls.append(proto_node);2518 add_top_level_decl(c, proto_node->data.fn_proto.name, proto_node);
2523 return;2519 return;
2524 }2520 }
25252521
...@@ -2563,7 +2559,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2563,7 +2559,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2563 fn_def_node->data.fn_def.body = body_node_with_param_inits;2559 fn_def_node->data.fn_def.body = body_node_with_param_inits;
25642560
2565 proto_node->data.fn_proto.fn_def_node = fn_def_node;2561 proto_node->data.fn_proto.fn_def_node = fn_def_node;
2566 c->root->data.root.top_level_decls.append(fn_def_node);2562 add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node);
2567}2563}
25682564
2569static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {2565static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {
...@@ -2911,14 +2907,14 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {...@@ -2911,14 +2907,14 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
2911 }2907 }
29122908
2913 AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, init_node);2909 AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, init_node);
2914 c->root->data.root.top_level_decls.append(var_node);2910 add_top_level_decl(c, name, var_node);
2915 return;2911 return;
2916 }2912 }
29172913
2918 if (is_extern) {2914 if (is_extern) {
2919 AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, nullptr);2915 AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, nullptr);
2920 var_node->data.variable_declaration.is_extern = true;2916 var_node->data.variable_declaration.is_extern = true;
2921 c->root->data.root.top_level_decls.append(var_node);2917 add_top_level_decl(c, name, var_node);
2922 return;2918 return;
2923 }2919 }
29242920
...@@ -2976,7 +2972,7 @@ static void render_macros(Context *c) {...@@ -2976,7 +2972,7 @@ static void render_macros(Context *c) {
29762972
2977 AstNode *value_node = entry->value;2973 AstNode *value_node = entry->value;
2978 if (value_node->type == NodeTypeFnDef) {2974 if (value_node->type == NodeTypeFnDef) {
2979 c->root->data.root.top_level_decls.append(value_node);2975 add_top_level_decl(c, value_node->data.fn_def.fn_proto->data.fn_proto.name, value_node);
2980 } else {2976 } else {
2981 add_global_var(c, entry->key, value_node);2977 add_global_var(c, entry->key, value_node);
2982 }2978 }
...@@ -3183,6 +3179,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch...@@ -3183,6 +3179,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
3183 }3179 }
3184 c->decl_table.init(8);3180 c->decl_table.init(8);
3185 c->macro_table.init(8);3181 c->macro_table.init(8);
3182 c->global_table.init(8);
3186 c->ptr_params.init(8);3183 c->ptr_params.init(8);
3187 c->codegen = codegen;3184 c->codegen = codegen;
3188 c->source_node = source_node;3185 c->source_node = source_node;