Grrrr Hmph @#$%#%@
[libfirm] / ir / st / exc.c
1 /* Copyright (c) 2002 by Universität Karlsruhe (TH).  All Rights Reserved */
2 //
3 // Time-stamp: <Monday, 13.05.2002, 16:00:06 goetz@i44pc2.info.uni-karlsruhe.de>
4 //
5
6 /***
7    NAME
8      exc
9    PURPOSE
10      Helper functions for exceptions
11    NOTES
12      not quite complete
13    HISTORY
14      liekweg - Mar 4, 2002: Created.
15    CVS:
16      $Id$
17 ***/
18
19 # include "exc.h"
20
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 */
27   "Cont"
28 };
29
30
31 /*
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
34   by a)
35 */
36 static bool has_handler (ir_graph *graph, ir_node *b, ir_node *a)
37 {
38   int i         = 0;
39   int n         = get_irn_n_outs (b);
40   ir_node *succ = 0;
41
42   assert (0 && "Wrongly implemented");
43   // must check for _immediate_ dominance !!!
44
45   if (is_handler_entry (graph, b) && dominates (graph, a, b))
46         return (true);
47
48   for (i = 0; i < n; i ++)
49         {
50           succ = get_irn_out (b, i);
51
52           if (has_handler (graph, succ, a))
53                 return (true);
54         }
55
56   return (false);
57 }
58
59 /*
60   Return true iff the given node represents an exception jump
61 */
62 static bool is_exc_jmp (ir_node *node)
63 {
64   ir_op *op = get_irn_op (node);
65
66   // Proj_X (Load), Proj_X (Sto), Proj_X (Div_Int),
67   // Proj_X (Raise), Proj_X (Call), Proj_X (Alloc)
68   if (op == op_Proj)
69         {
70           op = get_irn_op (get_Proj_pred (node));
71
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
75           return (true);
76         }
77   else
78         {
79           return (false);
80         }
81 }
82
83 /*
84 Return true iff the given node represents a normal cfg jump
85 */
86 static bool is_cfg_jmp (ir_node *node)
87 {
88   ir_op *op = get_irn_op (node);
89
90   if (op == op_Proj)
91         {
92           op = get_irn_op (get_Proj_pred (node));
93
94           // Proj_X (Proj_Cmp (Cond))
95           if (op_Proj == op)
96                 return (true);                  /* check for op == op_Cmp and op == op_Cond */
97         }
98
99   return (false);
100 }
101
102 /*
103  Return true iff a new exception region must be left upon entry of this block.
104
105  If all CFG preds of this block are exception jumps, then we must
106  return true.
107 */
108 bool is_handler_entry (ir_graph *graph, ir_node *block)
109 {
110   bool is_entry = true;
111   int  i        = 0;
112   int  n        = get_irn_arity (block);
113   ir_node *node = 0;
114   ir_op* op     = op_Bad;
115
116   if (exc_invalid == get_Block_exc (block))
117         {
118           for (i = 0; (i < n) && is_entry; i ++)
119                 if (is_exc_jmp (get_irn_n (block, i)))
120                   continue;
121                 else
122                   is_entry = false;
123
124           if (true == is_entry)
125                 set_Block_exc (block, exc_handler);
126         }
127
128   return (exc_handler == get_Block_exc (block));
129 }
130
131 /*
132  Return true iff a new exception region must be started upon entry of this block.
133
134  If this block immediately dominates a handler entry, we must return true.
135 */
136 bool is_region_entry  (ir_graph *graph, ir_node *block)
137 {
138   assert (0 && "Not implemented");
139
140   if (exc_invalid == get_Block_exc (block))
141         {
142           int i         = 0;
143           int n         = get_irn_n_outs (block);
144           ir_node *succ = 0;
145
146           bool no_handler = true;
147
148           for (i = 0; (i < n) && no_handler; i ++)
149                 {
150                   succ = get_irn_out (block, i);
151
152                   if (has_handler (graph, succ, block))
153                         no_handler = false;
154                 }
155
156           if (false == no_handler)
157                 set_Block_exc (block, exc_region);
158         }
159
160   return (exc_region == get_Block_exc (block));
161
162   return (TRUE);
163 }
164
165 /*
166  Return true iff this block is part of handler code.
167
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.
170 */
171 bool is_handler_block (ir_graph *graph, ir_node *block)
172 {
173   assert (0 && "Not implemented");
174
175   if (exc_invalid == get_Block_exc (block))
176         {
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;
182           int i           = 0;
183
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 */
187                         no_handler = false;
188
189           delete_dom_env (env);
190
191           if (false == no_handler)
192                 set_Block_exc (block, exc_handler);
193         }
194
195   return (exc_handler == get_Block_exc (block));
196 }
197
198 /*
199   Convert a value of type exc_t to a descriptive string.
200   Returns a reference to a statically allocated, constant string.
201 */
202
203 const char *exc_to_string (exc_t exc)
204 {
205   int exc_val = (int) exc;
206
207   assert ((0 <= (int) exc_val) && (exc_val < (int) exc_max));
208
209   return (exc_strings [exc_val]);
210 }