libjit.git - libjit

index : libjit.git
libjit
summary refs log tree commit diff
path: root/tests/unit/cfg-tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/cfg-tests.c')
-rw-r--r--tests/unit/cfg-tests.c 106
1 files changed, 106 insertions, 0 deletions
diff --git a/tests/unit/cfg-tests.c b/tests/unit/cfg-tests.c
new file mode 100644
index 0000000..7cc5307
--- /dev/null
+++ b/tests/unit/cfg-tests.c
@@ -0,0 +1,106 @@
+/*
+ * cfg-tests.c - Simple CFG tests
+ *
+ * Copyright (C) 2020 Free Software Foundation
+ *
+ * This file is part of the libjit library.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <jit/jit.h>
+#include "unit-tests.h"
+
+/* Make a block like
+
+ x = INCOMING
+ if INCOMING != 0 then goto .L0
+ goto .L1
+ .L0:
+ x = 23
+ .L1:
+ return x
+
+ Then, check that the optimized CFG removes the unnecessary block,
+ inverting the condition. */
+
+static void test_block_removal(void)
+{
+ jit_init();
+ jit_context_t ctx = jit_context_create ();
+
+ jit_type_t params[1] = { jit_type_sys_int };
+ jit_type_t sig = jit_type_create_signature (jit_abi_cdecl,
+ jit_type_sys_int,
+ params, 1, 1);
+
+ jit_label_t l0 = jit_label_undefined;
+ jit_label_t l1 = jit_label_undefined;
+
+ jit_function_t func = jit_function_create (ctx, sig);
+ jit_value_t incoming = jit_value_get_param (func, 0);
+
+ jit_value_t x = jit_value_create (func, jit_type_int);
+ jit_insn_store (func, x, incoming);
+
+ jit_value_t zero = jit_value_create_nint_constant (func,
+ jit_type_sys_int,
+ 0);
+ jit_value_t compare = jit_insn_ne (func, x, zero);
+ jit_block_t saved_block = jit_function_get_current (func);
+ jit_insn_branch_if (func, compare, &l1);
+
+ jit_insn_branch (func, &l0);
+
+ jit_insn_label (func, &l1);
+ jit_value_t twenty_three
+ = jit_value_create_nint_constant (func, jit_type_sys_int, 23);
+ jit_insn_store (func, x, twenty_three);
+
+ jit_insn_label (func, &l0);
+ jit_insn_return (func, x);
+
+ /* Test that optimization removes the unnecessary block. We
+ do this by examining the instruction rather than the CFG,
+ because there didn't seem to be a reliable way to do the
+ latter. */
+ unsigned max = jit_function_get_max_optimization_level ();
+ jit_function_set_optimization_level (func, max);
+ // jit_dump_function (stderr, func, "test_block_removal");
+ jit_function_compile (func);
+ jit_insn_iter_t iter;
+ jit_insn_iter_init_last (&iter, saved_block);
+ jit_insn_t insn = jit_insn_iter_previous (&iter);
+ CHECK (insn != NULL);
+ CHECK (jit_insn_get_opcode (insn) == JIT_OP_BR_IEQ);
+
+ /* Test that the result is still correct. */
+ int result = -1;
+ int arg = 0;
+ void *args[] = { &arg };
+ CHECK (jit_function_apply (func, args, &result));
+ CHECK (result == 0);
+
+ arg = 72;
+ CHECK (jit_function_apply (func, args, &result));
+ CHECK (result == 23);
+}
+
+int main()
+{
+ test_block_removal ();
+
+ return 0;
+}
generated by cgit v1.2.3 (git 2.25.1) at 2025年09月07日 01:27:26 +0000

AltStyle によって変換されたページ (->オリジナル) /