3 * File name: ir/st/exc.c
4 * Purpose: Helper functions for jack exceptions.
5 * Author: Florian Liekweg
9 * Copyright: (c) 2002-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
17 Helper functions for exceptions
25 static char* exc_strings [] = {
26 "Invalid", /* invalid */
27 "Normal", /* normal */
28 "Entry", /* entry to region */
29 "Exit", /* exit of region */
30 "Handler", /* entry to handler */
36 Return true iff (block b is a handler entry AND a dominates b) OR
37 (b has a CFG successor that is both a handler entry AND is dominated
40 static bool has_handler (ir_graph *graph, ir_node *b, ir_node *a)
43 int n = get_irn_n_outs (b);
46 assert (0 && "Wrongly implemented");
47 /* must check for _immediate_ dominance !!! */
49 if (is_handler_entry (graph, b) && dominates (graph, a, b))
52 for (i = 0; i < n; i ++)
54 succ = get_irn_out (b, i);
56 if (has_handler (graph, succ, a))
64 Return true iff the given node represents an exception jump
66 static bool is_exc_jmp (ir_node *node)
68 ir_op *op = get_irn_op (node);
70 /* Proj_X (Load), Proj_X (Sto), Proj_X (Div_Int),
71 Proj_X (Raise), Proj_X (Call), Proj_X (Alloc) */
74 op = get_irn_op (get_Proj_pred (node));
76 assert ((is_fragile_op(get_Proj_pred(node))) &&
77 (op != op_Bad) /*&& (op != op_Unknown)*/ &&
78 (get_irn_mode(node) == mode_X));/* Check for proper Proj attr */
88 Return true iff the given node represents a normal cfg jump
91 static bool is_cfg_jmp (ir_node *node)
93 ir_op *op = get_irn_op (node);
97 op = get_irn_op (get_Proj_pred (node));
99 /* Proj_X (Proj_Cmp (Cond)) */
101 return (true); /* check for op == op_Cmp and op == op_Cond */
108 void set_Block_exc(ir_node *n, exc_t exc) {
111 exc_t get_Block_exc(ir_node *n) {
116 /* handler handling for Blocks */
118 set_Block_handler (ir_node *block, ir_node *handler) {
119 assert (is_Block(block));
120 assert (is_Block(handler));
124 get_Block_handler (ir_node *block) {
125 assert (is_Block(block));
129 /* handler handling for Nodes */
131 set_Node_handler (ir_node *node, ir_node *handler) {
136 get_Node_handler (ir_node *node) {
142 Return true iff a new exception region must be left upon entry of this block.
144 If all CFG preds of this block are exception jumps, then we must
147 bool is_handler_entry (ir_graph *graph, ir_node *block)
149 bool is_entry = true;
151 int n = get_irn_arity (block);
153 if (exc_invalid == get_Block_exc (block))
155 for (i = 0; (i < n) && (is_entry == true); i ++)
156 if (is_exc_jmp (get_irn_n (block, i)))
161 if (true == is_entry)
162 set_Block_exc (block, exc_handler);
165 return (exc_handler == get_Block_exc (block));
169 Return true iff a new exception region must be started upon entry of this block.
171 If this block immediately dominates a handler entry, we must return true.
173 bool is_region_entry (ir_graph *graph, ir_node *block)
175 assert (0 && "Not implemented");
177 if (exc_invalid == get_Block_exc (block))
180 int n = get_irn_n_outs (block);
183 bool no_handler = true;
185 for (i = 0; (i < n) && (no_handler == true); i ++)
187 succ = get_irn_out (block, i);
189 if (has_handler (graph, succ, block))
193 if (false == no_handler)
194 set_Block_exc (block, exc_region);
197 return (exc_region == get_Block_exc (block));
203 Return true iff this block is part of handler code.
205 If this block is dominated by a block for which {@link
206 is_handler_entry} is true, then this block is part of the handler.
208 bool is_handler_block (ir_graph *graph, ir_node *block)
210 assert (0 && "Not implemented");
212 if (exc_invalid == get_Block_exc (block))
214 bool no_handler = true;
215 dom_env_t *env = get_dom_env (graph, block);
216 int block_index = env->index_a;
217 bs_t block_mask = 0x00000001 << block_index;
218 int n_blocks = env->dt->n_blocks;
221 for (i = 0; (i < n_blocks) && (no_handler == true); i ++)
222 if (0 != (env->dt->masks [i] & block_mask)) /* if dominator */
223 if (is_handler_entry (graph, env->dt->blocks [i])) /* is handler entry */
226 delete_dom_env (env);
228 if (false == no_handler)
229 set_Block_exc (block, exc_handler);
232 return (exc_handler == get_Block_exc (block));
236 Convert a value of type exc_t to a descriptive string.
237 Returns a reference to a statically allocated, constant string.
240 const char *exc_to_string (exc_t exc)
242 int exc_val = (int) exc;
244 assert ((0 <= (int) exc_val) && (exc_val < (int) exc_max));
246 return (exc_strings [exc_val]);