From 7aac1ad2d440c47ea458e6da20f2a83d95f3b08e Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Tue, 29 Mar 2016 15:16:01 +0100 Subject: [PATCH] Optimized pointer arithmetics generated with '-C, --contexts'. If default input API is used and fixed-length context is based on the rightmost context (that is, YYCURSOR), then the following expression (that calculates pointer corresponding to the given context): (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - yyctx)) can be optimized to: (YYCURSOR - yyctx) Note: unfortunately, as of GCC < 7.0, expressions like: (YYCURSOR - 3) - (YYCURSOR - 5) trigger warning: warning: integer overflow in expression [-Woverflow] See this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61240 --- re2c/src/codegen/emit_action.cc | 9 ++--- re2c/src/codegen/input_api.cc | 34 ++++++++++++++----- re2c/src/codegen/input_api.h | 5 +-- re2c/test/contexts/fix2.i--contexts.c | 10 +++--- .../fix2_trail.i--contexts--input(custom).c | 8 ++--- re2c/test/contexts/fix2_trail.i--contexts.c | 8 ++--- re2c/test/contexts/fix4.i--contexts.c | 4 +-- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/re2c/src/codegen/emit_action.cc b/re2c/src/codegen/emit_action.cc index 0b9743ed..1685c1a5 100644 --- a/re2c/src/codegen/emit_action.cc +++ b/re2c/src/codegen/emit_action.cc @@ -275,13 +275,8 @@ static void subst_contexts( for (size_t i = 0; i < rule.ctxfix.size(); ++i) { const CtxFix &ctx = rule.ctxfix[i]; - const std::string basename = (ctx.base == CtxFix::RIGHTMOST) - ? opts->input_api.expr_dist() - : contexts[ctx.base].fullname; - std::ostringstream offs; - offs << "(" << basename << " - " << ctx.dist << ")"; - const std::string ctx_value = opts->input_api.expr_ctx(offs.str()); - rreplace_substr(action, "@" + *ctx.name, ctx_value); + rreplace_substr(action, "@" + *ctx.name, + opts->input_api.expr_ctx_fix(ctx, contexts)); } } diff --git a/re2c/src/codegen/input_api.cc b/re2c/src/codegen/input_api.cc index 9e0f0054..40024d34 100644 --- a/re2c/src/codegen/input_api.cc +++ b/re2c/src/codegen/input_api.cc @@ -117,18 +117,34 @@ std::string InputAPI::stmt_dist (uint32_t ind, const std::set &ctxs, return s + expr_dist() + ";\n"; } -std::string InputAPI::expr_ctx (const std::string &ctx) const +std::string InputAPI::expr_ctx(const std::string &ctx) const { - std::string s; switch (type_) { - case DEFAULT: - s = "(" + opts->yyctxmarker + " + " + ctx + ")"; - break; - case CUSTOM: - s = opts->yyctx + "(" + ctx + ")"; - break; + case DEFAULT: return "(" + opts->yyctxmarker + " + " + ctx + ")"; + case CUSTOM: return opts->yyctx + "(" + ctx + ")"; + default: assert(false); + } +} + +std::string InputAPI::expr_ctx_fix(const CtxFix &ctx, const std::vector &ctxvars) const +{ + std::ostringstream s; + if (ctx.base == CtxFix::RIGHTMOST) { + switch (type_) { + case DEFAULT: + // optimize '(YYCTXMARKER + ((YYCURSOR - YCTXMARKER) - yyctx))' + // to '(YYCURSOR - yyctx)' + s << "(" << opts->yycursor << " - " << ctx.dist << ")"; + break; + case CUSTOM: + s << opts->yyctx << "(" << opts->yydist << "() - " << ctx.dist << ")"; + break; + } + return s.str(); + } else { + s << "(" << ctxvars[ctx.base].fullname << " - " << ctx.dist << ")"; + return expr_ctx(s.str()); } - return s; } std::string InputAPI::stmt_restore (uint32_t ind) const diff --git a/re2c/src/codegen/input_api.h b/re2c/src/codegen/input_api.h index de76f76e..b575e57c 100644 --- a/re2c/src/codegen/input_api.h +++ b/re2c/src/codegen/input_api.h @@ -6,11 +6,11 @@ #include #include +#include "src/ir/ctx.h" + namespace re2c { -struct CtxVar; - class InputAPI { public: @@ -36,6 +36,7 @@ public: std::string stmt_dist (uint32_t ind, const std::set &ctxs, const std::vector &contexts) const; std::string expr_ctx (const std::string &ctx) const; + std::string expr_ctx_fix (const CtxFix &ctx, const std::vector &ctxvars) const; std::string stmt_restore (uint32_t ind) const; std::string stmt_restorectx_fix (uint32_t ind, size_t dist) const; std::string stmt_restorectx_var (uint32_t ind) const; diff --git a/re2c/test/contexts/fix2.i--contexts.c b/re2c/test/contexts/fix2.i--contexts.c index bba01df7..455b3f1e 100644 --- a/re2c/test/contexts/fix2.i--contexts.c +++ b/re2c/test/contexts/fix2.i--contexts.c @@ -110,11 +110,11 @@ yy19: ++YYCURSOR; { printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n", - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)) - YYCTXMARKER, YYCTXMARKER, - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)), - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)), - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), - YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5))); + (YYCURSOR - 14) - YYCTXMARKER, YYCTXMARKER, + (YYCURSOR - 12) - (YYCURSOR - 14), (YYCURSOR - 14), + (YYCURSOR - 9) - (YYCURSOR - 12), (YYCURSOR - 12), + (YYCURSOR - 5) - (YYCURSOR - 9), (YYCURSOR - 9), + YYCURSOR - (YYCURSOR - 5), (YYCURSOR - 5)); return; } } diff --git a/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c b/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c index e695a195..90e209b2 100644 --- a/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c +++ b/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c @@ -126,10 +126,10 @@ yy19: YYRESTORECTX (YYDIST() - 5); { printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n", - YYCTX((YYDIST() - 9)) - YYCTXMARKER, YYCTXMARKER, - YYCTX((YYDIST() - 7)) - YYCTX((YYDIST() - 9)), YYCTX((YYDIST() - 9)), - YYCTX((YYDIST() - 4)) - YYCTX((YYDIST() - 7)), YYCTX((YYDIST() - 7)), - YYCURSOR - YYCTX((YYDIST() - 4)), YYCTX((YYDIST() - 4)), + YYCTX(YYDIST() - 9) - YYCTXMARKER, YYCTXMARKER, + YYCTX(YYDIST() - 7) - YYCTX(YYDIST() - 9), YYCTX(YYDIST() - 9), + YYCTX(YYDIST() - 4) - YYCTX(YYDIST() - 7), YYCTX(YYDIST() - 7), + YYCURSOR - YYCTX(YYDIST() - 4), YYCTX(YYDIST() - 4), YYCURSOR); return; } diff --git a/re2c/test/contexts/fix2_trail.i--contexts.c b/re2c/test/contexts/fix2_trail.i--contexts.c index 380849cf..a7a01401 100644 --- a/re2c/test/contexts/fix2_trail.i--contexts.c +++ b/re2c/test/contexts/fix2_trail.i--contexts.c @@ -111,10 +111,10 @@ yy19: YYCURSOR -= 5; { printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n", - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)) - YYCTXMARKER, YYCTXMARKER, - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)), - YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)), + (YYCURSOR - 9) - YYCTXMARKER, YYCTXMARKER, + (YYCURSOR - 7) - (YYCURSOR - 9), (YYCURSOR - 9), + (YYCURSOR - 4) - (YYCURSOR - 7), (YYCURSOR - 7), + YYCURSOR - (YYCURSOR - 4), (YYCURSOR - 4), YYCURSOR); return; } diff --git a/re2c/test/contexts/fix4.i--contexts.c b/re2c/test/contexts/fix4.i--contexts.c index 57b76c2a..24e9d915 100644 --- a/re2c/test/contexts/fix4.i--contexts.c +++ b/re2c/test/contexts/fix4.i--contexts.c @@ -60,8 +60,8 @@ yy11: (YYCTXMARKER + yyctx0p1) - YYCTXMARKER, YYCTXMARKER, (YYCTXMARKER + (yyctx0p3 - 1)) - (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p3) - (YYCTXMARKER + (yyctx0p3 - 1)), (YYCTXMARKER + (yyctx0p3 - 1)), - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1)) - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3), - YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1))); + (YYCURSOR - 1) - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3), + YYCURSOR - (YYCURSOR - 1), (YYCURSOR - 1)); return; } } -- 2.40.0