summaryrefslogtreecommitdiffhomepage
path: root/ir/opt
diff options
context:
space:
mode:
authorElias Aebi <elias.aebi@student.kit.edu>2018-04-04 14:44:54 +0200
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2019-01-24 17:42:00 +0100
commitf10554a40d83cf9676a56ddea0c2064473b62eba (patch)
tree09c484adb06d11653f97a9a9377c513ec5a936d1 /ir/opt
parentbb129c87fee85d84c694f58f613c0eabf2935f68 (diff)
fix the rewire logic
Diffstat (limited to 'ir/opt')
-rw-r--r--ir/opt/loop2.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/ir/opt/loop2.c b/ir/opt/loop2.c
index b07f9d2..87a28b8 100644
--- a/ir/opt/loop2.c
+++ b/ir/opt/loop2.c
@@ -126,32 +126,50 @@ static void rewire_node(ir_node *const node, ir_node *const header)
// loop header block
if (node == header) {
assert(is_Block(node));
- 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);
+ int const arity = get_irn_arity(node);
+ int new_arity = 0;
+ for (int i = 0; i < arity; ++i) {
+ if (is_backedge(node, i)) {
+ ++new_arity;
+ }
+ }
+ ir_node **const in = ALLOCAN(ir_node *, new_arity);
+ for (int i = 0, j = 0; i < arity; ++i) {
+ if (is_backedge(node, i)) {
+ ir_node *const pred = get_irn_n(new_node, i);
+ 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, i, new_pred);
+ // jump to the new node only from the old node
+ in[j++] = pred;
+ }
+ }
+ set_irn_in(new_node, new_arity, in);
return;
}
// phi node inside loop header
if (is_Phi(node) && get_nodes_block(node) == header) {
- assert(is_backedge(get_nodes_block(node), 1));
- ir_node *const pred = get_irn_n(node, 1);
- ir_node *const new_pred = get_irn_link(pred);
- if (new_pred) {
- set_irn_n(node, 1, new_pred);
- } else {
- assert(get_irn_n(node, 0) == get_irn_n(node, 1));
+ int const arity = get_irn_arity(node);
+ int new_arity = 0;
+ for (int i = 0; i < arity; ++i) {
+ if (is_backedge(get_nodes_block(node), i)) {
+ ++new_arity;
+ }
}
ir_node **const in = ALLOCAN(ir_node *, 1);
- in[0] = pred;
- set_irn_in(new_node, 1, in);
+ for (int i = 0, j = 0; i < arity; ++i) {
+ if (is_backedge(get_nodes_block(node), i)) {
+ ir_node *const pred = get_irn_n(node, i);
+ ir_node *const new_pred = get_irn_link(pred);
+ if (new_pred) {
+ set_irn_n(node, i, new_pred);
+ }
+ in[j++] = pred;
+ }
+ }
+ set_irn_in(new_node, new_arity, in);
return;
}