Add jump_targets as general mechanism to avoid unnecessary basic blocks.
authorChristoph Mallon <christoph.mallon@gmx.de>
Fri, 26 Oct 2012 05:56:26 +0000 (07:56 +0200)
committerChristoph Mallon <christoph.mallon@gmx.de>
Tue, 30 Oct 2012 09:26:25 +0000 (10:26 +0100)
Makefile
jump_target.c [new file with mode: 0644]
jump_target.h [new file with mode: 0644]

index f7c6431..9f0401b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,7 @@ SOURCES := \
        entitymap.c \
        format_check.c \
        input.c \
+       jump_target.c \
        main.c \
        mangle.c \
        preprocessor.c \
diff --git a/jump_target.c b/jump_target.c
new file mode 100644 (file)
index 0000000..6781d67
--- /dev/null
@@ -0,0 +1,47 @@
+#include "adt/util.h"
+#include "jump_target.h"
+
+void jump_from_block_to_target(jump_target *const tgt, ir_node *const block)
+{
+       if (!tgt->block) {
+               tgt->block = block;
+               tgt->first = true;
+               return;
+       } else if (tgt->first) {
+               ir_node *const jmp = new_r_Jmp(tgt->block);
+               tgt->block = new_immBlock();
+               tgt->first = false;
+               add_immBlock_pred(tgt->block, jmp);
+       }
+       ir_node *const jmp = new_r_Jmp(block);
+       add_immBlock_pred(tgt->block, jmp);
+}
+
+void jump_to_target(jump_target *const tgt)
+{
+       ir_node *const block = get_cur_block();
+       if (block)
+               jump_from_block_to_target(tgt, block);
+}
+
+void add_pred_to_jump_target(jump_target *const tgt, ir_node *const pred)
+{
+       if (!tgt->block) {
+               tgt->block = new_immBlock();
+       } else if (tgt->first) {
+               ir_node *const jmp = new_r_Jmp(tgt->block);
+               tgt->block = new_immBlock();
+               tgt->first = false;
+               add_immBlock_pred(tgt->block, jmp);
+       }
+       add_immBlock_pred(tgt->block, pred);
+}
+
+ir_node *enter_jump_target(jump_target *const tgt)
+{
+       ir_node *const block = tgt->block;
+       if (block && !tgt->first)
+               mature_immBlock(block);
+       set_cur_block(block);
+       return block;
+}
diff --git a/jump_target.h b/jump_target.h
new file mode 100644 (file)
index 0000000..f7fa57b
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef JUMP_TARGET_H
+#define JUMP_TARGET_H
+
+#include <libfirm/firm.h>
+#include <stdbool.h>
+
+typedef struct jump_target {
+ ir_node *block;
+ bool     first;
+} jump_target;
+
+static inline void init_jump_target(jump_target *const tgt, ir_node *const block)
+{
+       tgt->block = block;
+       tgt->first = false;
+}
+
+void jump_from_block_to_target(jump_target *tgt, ir_node *block);
+
+void jump_to_target(jump_target *tgt);
+
+void add_pred_to_jump_target(jump_target *tgt, ir_node *pred);
+
+ir_node *enter_jump_target(jump_target *tgt);
+
+#endif