1 /* Copyright (c) 2002 by Universität Karlsruhe (TH). All Rights Reserved */
3 // Time-stamp: <Monday, 13.05.2002, 16:00:06 goetz@i44pc2.info.uni-karlsruhe.de>
10 Helper functions for exceptions
14 liekweg - Mar 4, 2002: Created.
21 static char* exc_strings [] = {
22 "Invalid", /* invalid */
23 "Normal", /* normal */
24 "Entry", /* entry to region */
25 "Exit", /* exit of region */
26 "Handler", /* entry to handler */
32 Return true iff (block b is a handler entry AND a dominates b) OR
33 (b has a CFG successor that is both a handler entry AND is dominated
36 static bool has_handler (ir_graph *graph, ir_node *b, ir_node *a)
39 int n = get_irn_n_outs (b);
42 assert (0 && "Wrongly implemented");
43 // must check for _immediate_ dominance !!!
45 if (is_handler_entry (graph, b) && dominates (graph, a, b))
48 for (i = 0; i < n; i ++)
50 succ = get_irn_out (b, i);
52 if (has_handler (graph, succ, a))
60 Return true iff the given node represents an exception jump
62 static bool is_exc_jmp (ir_node *node)
64 ir_op *op = get_irn_op (node);
66 // Proj_X (Load), Proj_X (Sto), Proj_X (Div_Int),
67 // Proj_X (Raise), Proj_X (Call), Proj_X (Alloc)
70 op = get_irn_op (get_Proj_pred (node));
72 assert ((is_fragile_op(get_Proj_pred(node))) &&
73 (op != op_Bad) /*&& (op != op_Unknown)*/ &&
74 (get_irn_mode(node) == mode_X));// Check for proper Proj attr
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);
114 if (exc_invalid == get_Block_exc (block))
116 for (i = 0; (i < n) && is_entry; i ++)
117 if (is_exc_jmp (get_irn_n (block, i)))
122 if (true == is_entry)
123 set_Block_exc (block, exc_handler);
126 return (exc_handler == get_Block_exc (block));
130 Return true iff a new exception region must be started upon entry of this block.
132 If this block immediately dominates a handler entry, we must return true.
134 bool is_region_entry (ir_graph *graph, ir_node *block)
136 assert (0 && "Not implemented");
138 if (exc_invalid == get_Block_exc (block))
141 int n = get_irn_n_outs (block);
144 bool no_handler = true;
146 for (i = 0; (i < n) && no_handler; i ++)
148 succ = get_irn_out (block, i);
150 if (has_handler (graph, succ, block))
154 if (false == no_handler)
155 set_Block_exc (block, exc_region);
158 return (exc_region == get_Block_exc (block));
164 Return true iff this block is part of handler code.
166 If this block is dominated by a block for which {@link
167 is_handler_entry} is true, then this block is part of the handler.
169 bool is_handler_block (ir_graph *graph, ir_node *block)
171 assert (0 && "Not implemented");
173 if (exc_invalid == get_Block_exc (block))
175 bool no_handler = true;
176 dom_env_t *env = get_dom_env (graph, block);
177 int block_index = env->index_a;
178 bs_t block_mask = 0x00000001 << block_index;
179 int n_blocks = env->dt->n_blocks;
182 for (i = 0; (i < n_blocks) && no_handler; i ++)
183 if (0 != (env->dt->masks [i] & block_mask)) /* if dominator */
184 if (is_handler_entry (graph, env->dt->blocks [i])) /* is handler entry */
187 delete_dom_env (env);
189 if (false == no_handler)
190 set_Block_exc (block, exc_handler);
193 return (exc_handler == get_Block_exc (block));
197 Convert a value of type exc_t to a descriptive string.
198 Returns a reference to a statically allocated, constant string.
201 const char *exc_to_string (exc_t exc)
203 int exc_val = (int) exc;
205 assert ((0 <= (int) exc_val) && (exc_val < (int) exc_max));
207 return (exc_strings [exc_val]);