summaryrefslogtreecommitdiffhomepage
path: root/ir/opt
diff options
context:
space:
mode:
authorElias Aebi <elias.aebi@student.kit.edu>2018-02-22 11:26:18 +0100
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2019-01-24 17:42:00 +0100
commitb74a05bec877bcc81fc1e41b58acbbcf3836b0b2 (patch)
tree9cb04f7dbcea535d0269fa33a1f585e0294f18ce /ir/opt
parenta5c1f590ecf0a960461a638b5842091e9b1346dc (diff)
WIP
Diffstat (limited to 'ir/opt')
-rw-r--r--ir/opt/loop2.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/ir/opt/loop2.c b/ir/opt/loop2.c
index ebabcbd..33c3a04 100644
--- a/ir/opt/loop2.c
+++ b/ir/opt/loop2.c
@@ -1,7 +1,14 @@
#include "lcssa_t.h"
#include "irtools.h"
+#include "xmalloc.h"
#include <assert.h>
+static void set_block_keepalive(ir_node *const block)
+{
+ ir_node *const end = get_irg_end(get_irn_irg(block));
+ add_End_keepalive(end, block);
+}
+
static void duplicate_node(ir_node *const node, ir_node *const new_block)
{
ir_printf("duplicate node %n (%d)\n", node, get_irn_node_nr(node));
@@ -19,16 +26,28 @@ static void rewire_node(ir_node *const node)
ir_node *const new_node = get_irn_link(node);
assert(new_node);
assert(get_irn_arity(node) == get_irn_arity(new_node));
+ if (has_backedges(node)) {
+ // loop header
+ assert(get_irn_arity(node) == 2);
+ assert(is_backedge(node, 1));
+ ir_node *const pred = get_irn_n(new_node, 1);
+ ir_node *const new_pred = get_irn_link(pred);
+ assert(new_pred);
+ // jump to the old node from outside and from the new node
+ set_irn_n(node, 1, new_pred);
+ // jump to the new node only from the old node
+ ir_node **const in = ALLOCAN(ir_node *, 1);
+ in[0] = pred;
+ set_irn_in(new_node, 1, in);
+ return;
+ }
// TODO: use foreach_irn_in
int const arity = get_irn_arity(new_node);
for (int i = 0; i < arity; ++i) {
ir_node *const pred = get_irn_n(new_node, i);
ir_node *const new_pred = get_irn_link(pred);
- if (is_backedge(node, i)) {
- assert(new_pred != NULL);
- set_irn_n(node, i, new_pred);
- }
- else if (new_pred != NULL) {
+ assert(!is_backedge(node, i));
+ if (new_pred != NULL) {
set_irn_n(new_node, i, new_pred);
}
}
@@ -42,6 +61,8 @@ static void duplicate_block(ir_node *const block)
for (unsigned int i = 0; i < n_outs; ++i) {
ir_node *const node = get_irn_out(block, i);
assert(!is_Block(node));
+ if (get_nodes_block(node) != block)
+ continue;
duplicate_node(node, new_block);
}
}
@@ -53,6 +74,8 @@ static void rewire_block(ir_node *const block)
for (unsigned int i = 0; i < n_outs; ++i) {
ir_node *const node = get_irn_out(block, i);
assert(!is_Block(node));
+ if (get_nodes_block(node) != block)
+ continue;
rewire_node(node);
}
}