1 /* file "labinfo.cc" */
3 /* Copyright (c) 1994 Stanford University
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
18 #define _MODULE_ "libuseful.a"
20 #define RCS_BASE_FILE useful_labinfo_cc
22 #include "useful_internal.h"
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 /*----------------------------------------------------------------------*
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())
83 if (parent_node
->is_proc())
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())
104 if (parent_node
->is_proc())
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
];
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())
185 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
186 instruction
*the_instr
= the_tree_instr
->instr();
187 switch (the_instr
->opcode())
191 in_lab
*the_label_instr
= (in_lab
*)the_instr
;
192 add_data_for_label_instr(the_label_instr
);
199 in_bj
*the_branch
= (in_bj
*)the_instr
;
200 add_data_for_branch(the_branch
);
205 in_mbr
*the_mbr
= (in_mbr
*)the_instr
;
206 add_data_for_mbr(the_mbr
);
216 tree_block
*the_block
= (tree_block
*)the_node
;
217 add_data_for_list(the_block
->body());
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
);
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
;
277 info_block
->backward_jumps
.append(the_mbr
);
278 backward_table
[lab_num
] = TRUE
;
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
;
291 info_block
->backward_jumps
.append(the_mbr
);
292 backward_table
[num_labs
] = TRUE
;
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())
306 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
307 instruction
*the_instr
= the_tree_instr
->instr();
308 switch (the_instr
->opcode())
312 in_lab
*the_label_instr
= (in_lab
*)the_instr
;
313 delete_label_info(the_label_instr
->label());
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
));
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
));
352 tree_block
*the_block
= (tree_block
*)the_node
;
353 remove_data_for_list(the_block
->body());
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
);
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 *----------------------------------------------------------------------*/