[Mesa-dev] [PATCH 12/12] glcpp: Substitute trivial macros in the fast path
Vladislav Egorov
vegorov180 at gmail.com
Sat Jan 7 19:02:13 UTC 2017
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
More information about the mesa-dev
mailing list