2 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
3 ** All rights reserved.
5 ** Authors: Martin Trapp, Christian Schaefer
7 ** irgmod: ir graph modification
14 # include "irnode_t.h"
15 # include "irgraph_t.h"
20 /* Turns a node into a "useless" Tuple. The Tuple just forms a tuple
22 This is useful if a node returning a tuple is removed, but the Projs
23 extracting values from the tuple are not available. */
25 turn_into_tuple (ir_node *node, int arity)
28 set_irn_op(node, op_Tuple);
29 if (get_irn_arity(node) == arity) {
32 /* Allocate new array, don't free old in_array, it's on the obstack. */
33 ir_node *block = get_nodes_Block(node);
34 node->in = NEW_ARR_D (ir_node *, current_ir_graph->obst, arity+1);
35 set_nodes_Block(node, block);
39 /* Insert irnode `new' in place of irnode `old'
40 Since `new' may be bigger than `old' replace `old'
41 by an op_Id which is smaller than everything */
43 exchange (ir_node *old, ir_node *new)
45 ir_node *block = old->in[0];
48 old->in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 2);
54 /**********************************************************************/
55 /* Funcionality for collect_phis */
56 /**********************************************************************/
59 clear_link (ir_node *n, void *env) {
60 set_irn_link(n, NULL);
64 collect (ir_node *n, void *env) {
66 if (get_irn_op(n) == op_Phi) {
67 set_irn_link(n, get_irn_link(get_nodes_Block(n)));
68 set_irn_link(get_nodes_Block(n), n);
70 if (get_irn_op(n) == op_Proj) {
72 while (get_irn_op(pred) == op_Proj)
73 pred = get_Proj_pred(pred);
74 set_irn_link(n, get_irn_link(pred));
75 set_irn_link(pred, n);
79 void collect_phiprojs(ir_graph *irg) {
82 /* Remember external state of current_ir_graph. */
83 rem = current_ir_graph;
84 current_ir_graph = irg;
86 irg_walk(get_irg_end(current_ir_graph), clear_link, collect, NULL);
88 current_ir_graph = rem;
92 /**********************************************************************/
93 /* Funcionality for part_block */
94 /**********************************************************************/
96 /* Moves node and all predecessors of node from from_bl to to_bl.
97 Does not move predecessors of Phi nodes (or block nodes). */
99 void move (ir_node *node, ir_node *from_bl, ir_node *to_bl) {
101 ir_node *proj, *pred;
104 set_nodes_Block(node, to_bl);
107 if (get_irn_mode(node) == mode_T) {
108 proj = get_irn_link(node);
110 if (get_nodes_Block(proj) == from_bl)
111 set_nodes_Block(proj, to_bl);
112 proj = get_irn_link(proj);
117 if (get_irn_op(node) == op_Phi) return;
119 for (i = 0; i < get_irn_arity(node); i++) {
120 pred = get_irn_n(node, i);
121 if (get_nodes_Block(pred) == from_bl)
122 move(pred, from_bl, to_bl);
126 void part_block(ir_node *node) {
131 /* Transform the control flow */
132 old_block = get_nodes_Block(node);
133 new_block = new_Block(get_Block_n_cfgpreds(old_block),
134 get_Block_cfgpred_arr(old_block));
135 set_irg_current_block(current_ir_graph, new_block);
139 set_irn_in(old_block, 1, in);
143 /* move node and its predecessors to new_block */
144 move(node, old_block, new_block);
146 /* move Phi nodes to new_block */
147 phi = get_irn_link(old_block);
148 set_irn_link(new_block, phi);
149 set_irn_link(old_block, NULL);
151 set_nodes_Block(phi, new_block);
152 phi = get_irn_link(phi);