summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2012-10-26 07:56:26 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2012-10-30 10:26:25 +0100
commitb40f0ce40a6c015ff5dd38ef212d617b67e5fde5 (patch)
tree39a56f91bfff79bcc0a9c5dc222f2212bcc0742b
parent296ba6e16420b89723d1a5b1217d6ecfc2fb0c7d (diff)
Add jump_targets as general mechanism to avoid unnecessary basic blocks.
-rw-r--r--Makefile1
-rw-r--r--jump_target.c47
-rw-r--r--jump_target.h26
3 files changed, 74 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index f7c6431..9f0401b 100644
--- 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
index 0000000..6781d67
--- /dev/null
+++ b/jump_target.c
@@ -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
index 0000000..f7fa57b
--- /dev/null
+++ b/jump_target.h
@@ -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