From b405b91a11df9c75e44bc49edc76a4249d258f53 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 7 Dec 2017 17:54:36 +0000 Subject: [PATCH] Constant folding for param upref instruction. Fixes #345 --- src/eval.c | 16 +++++++++++++ test/simp/issue345.vhd | 51 ++++++++++++++++++++++++++++++++++++++++++ test/test_simp.c | 11 +++++++++ 3 files changed, 78 insertions(+) create mode 100644 test/simp/issue345.vhd diff --git a/src/eval.c b/src/eval.c index d0571be5..2e0831fe 100644 --- a/src/eval.c +++ b/src/eval.c @@ -961,6 +961,18 @@ static void eval_op_fcall(int op, eval_state_t *state) eval_free_context(context); } +static void eval_op_param_upref(int op, eval_state_t *state) +{ + context_t *where = state->context; + const int hops = vcode_get_hops(op); + for (int i = 0; i < hops; i++) + where = where->parent; + + value_t *src = &(where->regs[vcode_get_arg(op, 0)]); + value_t *dst = eval_get_reg(vcode_get_result(op), state); + *dst = *src; +} + static void eval_op_bounds(int op, eval_state_t *state) { value_t *reg = eval_get_reg(vcode_get_arg(op, 0), state); @@ -2053,6 +2065,10 @@ static void eval_vcode(eval_state_t *state) eval_op_addi(i, state); break; + case VCODE_OP_PARAM_UPREF: + eval_op_param_upref(i, state); + break; + default: vcode_dump(); fatal("cannot evaluate vcode op %s", vcode_op_string(vcode_get_op(i))); diff --git a/test/simp/issue345.vhd b/test/simp/issue345.vhd new file mode 100644 index 00000000..0b297dc0 --- /dev/null +++ b/test/simp/issue345.vhd @@ -0,0 +1,51 @@ +package pkg is + function func (s : string) return natural; + function func2 (s : natural) return natural; + function func3(x : integer) return integer; +end package; + +package body pkg is + function func(s : string) return natural is + function inner_func return natural is + begin + return s'length; + end; + begin + return inner_func; + end; + + function func2(s : natural) return natural is + function inner_func return natural is + begin + return s; + end; + begin + return inner_func; + end; + + function func3(x : integer) return integer is + function inner(n : integer) return integer is + begin + return x + n; + end function; + begin + return inner(2); + end function; +end; + +use work.pkg.all; + +entity bug is +end entity; + +architecture a of bug is +begin + main : process + begin + assert func("") = 0; + assert func("abc") = 3; + assert func2(10) = 10; + assert func3(5) = 7; + wait; + end process; +end; diff --git a/test/test_simp.c b/test/test_simp.c index 3ac235f4..1b9651ba 100644 --- a/test/test_simp.c +++ b/test/test_simp.c @@ -566,6 +566,16 @@ START_TEST(test_issue344) } END_TEST +START_TEST(test_issue345) +{ + input_from_file(TESTDIR "/simp/issue345.vhd"); + + tree_t top = run_elab(); + + fail_unless(tree_stmts(top) == 0); +} +END_TEST + int main(void) { Suite *s = suite_create("simplify"); @@ -589,6 +599,7 @@ int main(void) tcase_add_test(tc_core, test_issue331); tcase_add_test(tc_core, test_issue332); tcase_add_test(tc_core, test_issue344); + tcase_add_test(tc_core, test_issue345); suite_add_tcase(s, tc_core); return nvc_run_test(s); -- 2.39.2