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.
21 static char* exc_strings [] = {
31 Return true iff (block b is a handler entry AND a dominates b) OR
32 (b has a CFG successor that is both a handler entry AND is dominated
35 static bool has_handler (ir_graph *graph, ir_node *b, ir_node *a)
38 int n = get_irn_n_outs (b);
41 assert (0 && "Wrongly implemented");
42 // must check for _immediate_ dominance !!!
44 if (is_handler_entry (graph, b) && dominates (graph, a, b))
47 for (i = 0; i < n; i ++)
49 succ = get_irn_out (b, i);
51 if (has_handler (graph, succ, a))
59 Return true iff the given node represents an exception jump
61 static bool is_exc_jmp (ir_node *node)
63 ir_op *op = get_irn_op (node);
65 // Proj_X (Load), Proj_X (Sto), Proj_X (Div_Int),
66 // Proj_X (Raise), Proj_X (Call), Proj_X (Alloc)
69 op = get_irn_op (get_Proj_pred (node));
71 // ToDo: Check for proper Proj attr?!?
72 if ((op == op_Load) || (op == op_Store) ||
73 (op == op_Div ) || (op == op_Raise) ||
74 (op == op_Call) || (op == op_Alloc))
84 Return true iff the given node represents a normal cfg jump
86 static bool is_cfg_jmp (ir_node *node)
88 ir_op *op = get_irn_op (node);
92 op = get_irn_op (get_Proj_pred (node));
94 // Proj_X (Proj_Cmp (Cond))
96 return (true); /* check for op == op_Cmp and op == op_Cond */
103 Return true iff a new exception region must be left upon entry of this block.
105 If all CFG preds of this block are exception jumps, then we must
108 bool is_handler_entry (ir_graph *graph, ir_node *block)
110 bool is_entry = true;
112 int n = get_irn_arity (block);
116 if (exc_invalid == get_Block_exc (block))
118 for (i = 0; (i < n) && is_entry; i ++)
119 if (is_exc_jmp (get_irn_n (block, i)))
124 if (true == is_entry)
125 set_Block_exc (block, exc_handler);
128 return (exc_handler == get_Block_exc (block));
132 Return true iff a new exception region must be started upon entry of this block.
134 If this block immediately dominates a handler entry, we must return true.
136 bool is_region_entry (ir_graph *graph, ir_node *block)
138 assert (0 && "Not implemented");
140 if (exc_invalid == get_Block_exc (block))
143 int n = get_irn_n_outs (block);
146 bool no_handler = true;
148 for (i = 0; (i < n) && no_handler; i ++)
150 succ = get_irn_out (block, i);
152 if (has_handler (graph, succ, block))
156 if (false == no_handler)
157 set_Block_exc (block, exc_region);
160 return (exc_region == get_Block_exc (block));
166 Return true iff this block is part of handler code.
168 If this block is dominated by a block for which {@link
169 is_handler_entry} is true, then this block is part of the handler.
171 bool is_handler_block (ir_graph *graph, ir_node *block)
173 assert (0 && "Not implemented");
175 if (exc_invalid == get_Block_exc (block))
177 bool no_handler = true;
178 dom_env_t *env = get_dom_env (graph, block);
179 int block_index = env->index_a;
180 bs_t block_mask = 0x00000001 << block_index;
181 int n_blocks = env->dt->n_blocks;
184 for (i = 0; (i < n_blocks) && no_handler; i ++)
185 if (0 != (env->dt->masks [i] & block_mask)) /* if dominator */
186 if (is_handler_entry (graph, env->dt->blocks [i])) /* is handler entry */
189 delete_dom_env (env);
191 if (false == no_handler)
192 set_Block_exc (block, exc_handler);
195 return (exc_handler == get_Block_exc (block));
199 Return true iff a new exception region must be left upon exit of the
200 non-exception blocks among the CFG predecessors of this block.
202 If this block has CFG predecessors that are partly handler blocks and
203 partly normal blocks, then we must return true.
205 bool is_cont_entry (ir_graph *graph, ir_node *block)
207 assert (0 && "Not implemented");
209 if (exc_invalid == get_Block_exc (block))
211 bool has_exc = false; /* wether we have exception cfg predecessors */
212 bool has_cfg = false; /* wether we have normal cfg predecessors */
215 int n = get_irn_arity (block);
219 for (i = 0; (i < n) && (!has_exc && !has_cfg); i ++)
221 pred = get_irn_n (block, i);
223 if (is_exc_jmp (pred))
225 else if (is_cfg_jmp (pred))
229 if (has_cfg && has_exc)
230 set_Block_exc (block, exc_cont);
233 return (exc_cont == get_Block_exc (block));
237 Convert a value of type exc_t to a descriptive string.
238 Returns a reference to a statically allocated, constant string.
241 const char *exc_to_string (exc_t exc)
243 int exc_val = (int) exc;
245 assert ((0 <= (int) exc_val) && (exc_val < (int) exc_max));
247 return (exc_strings [exc_val]);