Avoid casts from pointers to integers
[suif.git] / src / basesuif / useful / labinfo.cc
blob3a1bc0bfe616ab921e23a825998fbf6e6d107cb1
1 /* file "labinfo.cc" */
3 /* Copyright (c) 1994 Stanford University
5 All rights reserved.
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
13 * This file implements routines to get information about how labels
14 * are used in the SUIF code for the SUIF library of miscellaneous
15 * useful routines.
18 #define _MODULE_ "libuseful.a"
20 #define RCS_BASE_FILE useful_labinfo_cc
22 #include "useful_internal.h"
24 RCS_BASE(
25 "$Id: labinfo.cc,v 1.1.1.1 1998/06/16 15:15:32 brm Exp $")
27 /*----------------------------------------------------------------------*
28 Begin Constant Declarations
29 *----------------------------------------------------------------------*/
31 /*----------------------------------------------------------------------*
32 End Constant Declarations
33 *----------------------------------------------------------------------*/
34 /*----------------------------------------------------------------------*
35 Begin Type Declarations
36 *----------------------------------------------------------------------*/
38 /*----------------------------------------------------------------------*
39 End Type Declarations
40 *----------------------------------------------------------------------*/
41 /*----------------------------------------------------------------------*
42 Begin Private Global Variables
43 *----------------------------------------------------------------------*/
45 static const char *k_useful_labinfo_info;
46 static const char *k_useful_labinfo_backward;
47 static const char *k_useful_labinfo_num_back;
49 /*----------------------------------------------------------------------*
50 End Private Global Variables
51 *----------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------*
53 Begin Private Function Declarations
54 *----------------------------------------------------------------------*/
56 static void add_data_for_node(tree_node *the_node);
57 static void add_data_for_list(tree_node_list *the_list);
58 static void add_data_for_label_instr(in_lab *the_label_instr);
59 static void add_data_for_branch(in_bj *the_branch);
60 static void add_data_for_mbr(in_mbr *the_mbr);
61 static void remove_data_for_node(tree_node *the_node);
62 static void remove_data_for_list(tree_node_list *the_list);
63 static label_info *create_or_get_info(label_sym *the_label);
64 static void delete_label_info(label_sym *the_label);
66 /*----------------------------------------------------------------------*
67 End Private Function Declarations
68 *----------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------*
70 Begin Public Function Implementations
71 *----------------------------------------------------------------------*/
73 extern void build_label_info(tree_node_list *node_list)
75 tree_node *parent_node = node_list->parent();
76 switch (parent_node->kind())
78 case TREE_LOOP:
79 case TREE_FOR:
80 case TREE_IF:
81 break;
82 case TREE_BLOCK:
83 if (parent_node->is_proc())
84 break;
85 /* fall through */
86 case TREE_INSTR:
87 default:
88 assert(FALSE);
91 add_data_for_list(node_list);
94 extern void remove_label_info(tree_node_list *node_list)
96 tree_node *parent_node = node_list->parent();
97 switch (parent_node->kind())
99 case TREE_LOOP:
100 case TREE_FOR:
101 case TREE_IF:
102 break;
103 case TREE_BLOCK:
104 if (parent_node->is_proc())
105 break;
106 /* fall through */
107 case TREE_INSTR:
108 default:
109 assert(FALSE);
112 remove_data_for_list(node_list);
115 extern label_info *get_lab_info(label_sym *the_label)
117 void *data = the_label->peek_annote(k_useful_labinfo_info);
118 assert(data != NULL);
119 return (label_info *)data;
122 extern boolean is_backward_branch(in_bj *the_bj)
124 return (the_bj->annotes()->peek_annote(k_useful_labinfo_backward) != NULL);
127 extern boolean mbr_lab_is_backward(in_mbr *the_mbr, label_sym *the_label)
129 void *backward_data = the_mbr->peek_annote(k_useful_labinfo_backward);
130 assert(backward_data != NULL);
131 boolean *backward_table = (boolean *)backward_data;
133 unsigned num_labs = the_mbr->num_labs();
135 if (the_label == the_mbr->default_lab())
136 return backward_table[num_labs];
138 for (unsigned lab_num = 0; lab_num < num_labs; ++lab_num)
140 if (the_label == the_mbr->label(lab_num))
141 return backward_table[lab_num];
143 assert(FALSE);
144 return FALSE;
147 extern int num_mbr_back_labs(in_mbr *the_mbr)
149 void *num_back_data = the_mbr->peek_annote(k_useful_labinfo_num_back);
150 return (int)(long)num_back_data;
153 extern void create_info_for_new_lab_instr(in_lab *new_lab_instr)
155 add_data_for_label_instr(new_lab_instr);
158 /*----------------------------------------------------------------------*
159 End Public Function Implementations
160 *----------------------------------------------------------------------*/
161 /*----------------------------------------------------------------------*
162 Begin Internal Function Implementations
163 *----------------------------------------------------------------------*/
165 extern void init_labinfo(void)
167 k_useful_labinfo_info = lexicon->enter("useful labinfo info")->sp;
168 k_useful_labinfo_backward = lexicon->enter("useful labinfo backward")->sp;
169 k_useful_labinfo_num_back = lexicon->enter("useful labinfo num back")->sp;
172 /*----------------------------------------------------------------------*
173 End Internal Function Implementations
174 *----------------------------------------------------------------------*/
175 /*----------------------------------------------------------------------*
176 Begin Private Function Implementations
177 *----------------------------------------------------------------------*/
179 static void add_data_for_node(tree_node *the_node)
181 switch (the_node->kind())
183 case TREE_INSTR:
185 tree_instr *the_tree_instr = (tree_instr *)the_node;
186 instruction *the_instr = the_tree_instr->instr();
187 switch (the_instr->opcode())
189 case io_lab:
191 in_lab *the_label_instr = (in_lab *)the_instr;
192 add_data_for_label_instr(the_label_instr);
193 break;
195 case io_btrue:
196 case io_bfalse:
197 case io_jmp:
199 in_bj *the_branch = (in_bj *)the_instr;
200 add_data_for_branch(the_branch);
201 break;
203 case io_mbr:
205 in_mbr *the_mbr = (in_mbr *)the_instr;
206 add_data_for_mbr(the_mbr);
207 break;
209 default:
210 break;
212 break;
214 case TREE_BLOCK:
216 tree_block *the_block = (tree_block *)the_node;
217 add_data_for_list(the_block->body());
218 break;
220 default:
221 break;
225 static void add_data_for_list(tree_node_list *the_list)
227 tree_node_list_iter node_iter(the_list);
228 while (!node_iter.is_empty())
230 tree_node *this_node = node_iter.step();
231 add_data_for_node(this_node);
235 static void add_data_for_label_instr(in_lab *the_label_instr)
237 label_sym *the_label_sym = the_label_instr->label();
238 label_info *info_block = create_or_get_info(the_label_sym);
239 if (info_block->definition != NULL)
241 error_line(1, the_label_instr, "label `%s' is multiply defined",
242 the_label_sym->name());
244 info_block->definition = the_label_instr;
247 static void add_data_for_branch(in_bj *the_branch)
249 label_info *info_block = create_or_get_info(the_branch->target());
250 if (info_block->definition == NULL)
252 info_block->forward_jumps.append(the_branch);
254 else
256 info_block->backward_jumps.append(the_branch);
257 the_branch->append_annote(k_useful_labinfo_backward, NULL);
261 static void add_data_for_mbr(in_mbr *the_mbr)
263 unsigned num_labs = the_mbr->num_labs();
264 boolean *backward_table = new boolean[num_labs + 1];
265 int back_counter = 0;
266 for (unsigned lab_num = 0; lab_num < num_labs; ++lab_num)
268 label_sym *this_label_sym = the_mbr->label(lab_num);
269 label_info *info_block = create_or_get_info(this_label_sym);
270 if (info_block->definition == NULL)
272 info_block->forward_jumps.append(the_mbr);
273 backward_table[lab_num] = FALSE;
275 else
277 info_block->backward_jumps.append(the_mbr);
278 backward_table[lab_num] = TRUE;
279 ++back_counter;
283 label_info *info_block = create_or_get_info(the_mbr->default_lab());
284 if (info_block->definition == NULL)
286 info_block->forward_jumps.append(the_mbr);
287 backward_table[num_labs] = FALSE;
289 else
291 info_block->backward_jumps.append(the_mbr);
292 backward_table[num_labs] = TRUE;
293 ++back_counter;
296 the_mbr->append_annote(k_useful_labinfo_backward, backward_table);
297 the_mbr->append_annote(k_useful_labinfo_num_back, (void *)back_counter);
300 static void remove_data_for_node(tree_node *the_node)
302 switch (the_node->kind())
304 case TREE_INSTR:
306 tree_instr *the_tree_instr = (tree_instr *)the_node;
307 instruction *the_instr = the_tree_instr->instr();
308 switch (the_instr->opcode())
310 case io_lab:
312 in_lab *the_label_instr = (in_lab *)the_instr;
313 delete_label_info(the_label_instr->label());
314 break;
316 case io_btrue:
317 case io_bfalse:
318 case io_jmp:
320 in_bj *the_branch = (in_bj *)the_instr;
321 delete_label_info(the_branch->target());
322 if (the_branch->annotes()->peek_annote(
323 k_useful_labinfo_backward) != NULL)
325 (void)(the_branch->get_annote(
326 k_useful_labinfo_backward));
328 break;
330 case io_mbr:
332 in_mbr *the_mbr = (in_mbr *)the_instr;
333 unsigned num_labs = the_mbr->num_labs();
334 for (unsigned lab_num = 0; lab_num < num_labs; ++lab_num)
335 delete_label_info(the_mbr->label(lab_num));
336 delete_label_info(the_mbr->default_lab());
337 void *backward_data =
338 the_mbr->get_annote(k_useful_labinfo_backward);
339 assert(backward_data != NULL);
340 boolean *backward_table = (boolean *)backward_data;
341 delete[] backward_table;
342 (void)(the_mbr->get_annote(k_useful_labinfo_num_back));
343 break;
345 default:
346 break;
348 break;
350 case TREE_BLOCK:
352 tree_block *the_block = (tree_block *)the_node;
353 remove_data_for_list(the_block->body());
354 break;
356 default:
357 break;
361 static void remove_data_for_list(tree_node_list *the_list)
363 tree_node_list_iter node_iter(the_list);
364 while (!node_iter.is_empty())
366 tree_node *this_node = node_iter.step();
367 remove_data_for_node(this_node);
371 static label_info *create_or_get_info(label_sym *the_label)
373 void *data = the_label->peek_annote(k_useful_labinfo_info);
374 if (data != NULL)
375 return (label_info *)data;
377 label_info *new_info_block = new label_info;
378 new_info_block->definition = NULL;
379 the_label->append_annote(k_useful_labinfo_info, new_info_block);
380 return new_info_block;
383 static void delete_label_info(label_sym *the_label)
385 if (the_label->peek_annote(k_useful_labinfo_info) != NULL)
387 void *old_data = the_label->get_annote(k_useful_labinfo_info);
388 label_info *old_info_block = (label_info *)old_data;
389 delete old_info_block;
393 /*----------------------------------------------------------------------*
394 End Private Function Implementations
395 *----------------------------------------------------------------------*/