1 /* Copyright (c) 2002 by Universität Karlsruhe (TH). All Rights Reserved */
3 // Time-stamp: <02/03/04 17:24:07 liekweg>
10 Helper functions for exceptions
14 liekweg - Mar 4, 2002: Created.
27 Return true iff (block b is a handler entry AND a dominates b) OR
28 (b has a CFG successor that is both a handler entry AND is dominated
31 static bool has_handler (ir_graph *graph, ir_node *b, ir_node *a)
34 int n = get_irn_n_outs (b);
37 assert (0 && "Wrongly implemented");
38 // must check for _immediate_ dominance !!!
40 if (is_handler_entry (graph, b) && dominates (graph, a, b))
43 for (i = 0; i < n; i ++)
45 succ = get_irn_out (b, i);
47 if (has_handler (graph, succ, a))
55 Return true iff the given node represents an exception jump
57 static bool is_exc_jmp (ir_node *node)
59 ir_op *op = get_irn_op (node);
61 // Proj_X (Load), Proj_X (Sto), Proj_X (Div_Int),
62 // Proj_X (Raise), Proj_X (Call), Proj_X (Alloc)
65 op = get_irn_op (get_Proj_pred (node));
67 // ToDo: Check for proper Proj attr?!?
68 if ((op == op_Load) || (op == op_Store) ||
69 (op == op_Div ) || (op == op_Raise) ||
70 (op == op_Call) || (op == op_Alloc))
80 Return true iff the given node represents a normal cfg jump
82 static bool is_cfg_jmp (ir_node *node)
84 ir_op *op = get_irn_op (node);
88 op = get_irn_op (get_Proj_pred (node));
90 // Proj_X (Proj_Cmp (Cond))
92 return (true); /* check for op == op_Cmp and op == op_Cond */
99 Return true iff a new exception region must be left upon entry of this block.
101 If all CFG preds of this block are exception jumps, then we must
104 bool is_handler_entry (ir_graph *graph, ir_node *block)
106 bool is_entry = true;
108 int n = get_irn_arity (block);
112 if (exc_invalid == get_Block_exc (block))
114 for (i = 0; (i < n) && is_entry; i ++)
115 if (is_exc_jmp (get_irn_n (block, i)))
120 if (true == is_entry)
121 set_Block_exc (block, exc_entry);
124 return (exc_entry == get_Block_exc (block));
128 Return true iff a new exception region must be started upon entry of this block.
130 If this block immediately dominates a handler entry, we must return true.
132 bool is_region_entry (ir_graph *graph, ir_node *block)
134 assert (0 && "Not implemented");
136 if (exc_invalid == get_Block_exc (block))
139 int n = get_irn_n_outs (block);
142 bool no_handler = true;
144 for (i = 0; (i < n) && no_handler; i ++)
146 succ = get_irn_out (block, i);
148 if (has_handler (graph, succ, block))
152 if (false == no_handler)
153 set_Block_exc (block, exc_region);
156 return (exc_region == get_Block_exc (block));
162 Return true iff this block is part of handler code.
164 If this block is dominated by a block for which {@link
165 is_handler_entry} is true, then this block is part of the handler.
167 bool is_handler_block (ir_graph *graph, ir_node *block)
169 assert (0 && "Not implemented");
171 if (exc_invalid == get_Block_exc (block))
173 bool no_handler = true;
174 dom_env_t *env = get_dom_env (graph, block);
175 int block_index = env->index_a;
176 bs_t block_mask = 0x00000001 << block_index;
177 int n_blocks = env->dt->n_blocks;
180 for (i = 0; (i < n_blocks) && no_handler; i ++)
181 if (0 != (env->dt->masks [i] & block_mask)) /* if dominator */
182 if (is_handler_entry (graph, env->dt->blocks [i])) /* is handler entry */
185 delete_dom_env (env);
187 if (false == no_handler)
188 set_Block_exc (block, exc_handler);
191 return (exc_handler == get_Block_exc (block));
195 Return true iff a new exception region must be left upon exit of the
196 non-exception blocks among the CFG predecessors of this block.
198 If this block has CFG predecessors that are partly handler blocks and
199 partly normal blocks, then we must return true.
201 bool is_cont_entry (ir_graph *graph, ir_node *block)
203 assert (0 && "Not implemented");
205 if (exc_invalid == get_Block_exc (block))
207 bool has_exc = false; /* wether we have exception cfg predecessors */
208 bool has_cfg = false; /* wether we have normal cfg predecessors */
211 int n = get_irn_arity (block);
215 for (i = 0; (i < n) && (!has_exc && !has_cfg); i ++)
217 pred = get_irn_n (block, i);
219 if (is_exc_jmp (pred))
221 else if (is_cfg_jmp (pred))
225 if (has_cfg && has_exc)
226 set_Block_exc (block, exc_cont);
229 return (exc_cont == get_Block_exc (block));