The vast majority of macros are trivial, simple numbers or identifiers. Substitute them in the fast path, no need to bailout for them to the slow path. --- src/compiler/glsl/glcpp/glcpp-lex.l | 77 +++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-)
diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l b/src/compiler/glsl/glcpp/glcpp-lex.l index 8e916a2..5b3dd5b 100644 --- a/src/compiler/glsl/glcpp/glcpp-lex.l +++ b/src/compiler/glsl/glcpp/glcpp-lex.l @@ -717,6 +717,70 @@ glcpp_fast_flush(glcpp_parser_t *parser, struct string_buffer *out, } static bool +glcpp_fast_try_print_trivial_macro(macro_t *macro, glcpp_parser_t *parser, + struct string_buffer *out) +{ + token_t *tok; + token_node_t *head; + bool success; + + /* If the macro is a function, there is no way we can substitute it + * without tokenization, argument validation and so on. + */ + if (macro->is_function) + return false; + + /* Always substitute empty macro with a single space */ + if (!macro->replacements || !macro->replacements->head) { + glcpp_append_char(parser, out, ' '); + return true; + } + + /* If the macro has more than one non-space token, it's too complex. */ + if (macro->replacements->head != macro->replacements->non_space_tail) + return false; + + head = macro->replacements->head; + tok = head->token; + + switch (tok->type) { + case INTEGER: + glcpp_printf(parser, out, "%" PRIiMAX, tok->value.ival); + success = true; + break; + + case INTEGER_STRING: + glcpp_append(parser, out, tok->value.str); + success = true; + break; + + case IDENTIFIER: + /* We don't accept other macros to avoid recursion and excessive cost + * of macro's analysis in the _fast_ path. + */ + if (!GLCPP_DEFINES_BLOOM_GET(parser, tok->value.str) || + !_mesa_hash_table_search(parser->defines, tok->value.str)) { + glcpp_append(parser, out, tok->value.str); + success = true; + } else { + success = false; + } + break; + + default: + success = false; + break; + } + + /* Print trailing space to match the existing behavior */ + if (success) { + while ((head = head->next) != NULL) + glcpp_append_char(parser, out, ' '); + } + return success; +} + +static bool glcpp_fast_process_identifier(glcpp_parser_t *parser, struct string_buffer *out, struct yyguts_t *yyg, @@ -770,9 +834,16 @@ glcpp_fast_process_identifier(glcpp_parser_t *parser, if (entry) { parser->dont_use_fast_path = true; glcpp_fast_flush(parser, out, id_start, last_printed); - buf = id_start; - success = false; - *last_printed = id_start; + /* Our last chance. Try substitute trivial macro like non-macro + * identifier or single integer. Otherwise we have to fallback. + */ + if (!glcpp_fast_try_print_trivial_macro(entry->data, parser, out)) { + buf = id_start; + success = false; + *last_printed = id_start; + } else { + *last_printed = buf; + } } } } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev