1 /* file "test_modification.cc" */
3 /* Copyright (c) 1994,1995 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 is the implementation of routines to test for potential
14 * modification of variables or expressions by SUIF code, for the
15 * SUIF library of miscellaneous useful routines.
18 #define _MODULE_ "libsueful.a"
20 #define RCS_BASE_FILE test_modification_cc
22 #include "useful_internal.h"
25 "$Id: test_modification.cc,v 1.1.1.1 1998/06/16 15:15:37 brm Exp $")
27 /*----------------------------------------------------------------------*
28 Begin Type Declarations
29 *----------------------------------------------------------------------*/
31 /*----------------------------------------------------------------------*
33 *----------------------------------------------------------------------*/
34 /*----------------------------------------------------------------------*
35 Begin Private Function Declarations
36 *----------------------------------------------------------------------*/
38 static boolean
node_might_modify(var_sym
*the_var
, tree_node
*the_node
);
39 static boolean
expr_might_modify(var_sym
*the_var
, instruction
*the_instr
);
40 static boolean
op_might_modify(var_sym
*the_var
, operand the_op
);
42 /*----------------------------------------------------------------------*
43 End Private Function Declarations
44 *----------------------------------------------------------------------*/
45 /*----------------------------------------------------------------------*
46 Begin Public Function Implementations
47 *----------------------------------------------------------------------*/
49 extern boolean
might_modify(var_sym
*the_variable
, tree_node_list
*node_list
)
51 if (the_variable
->type()->is_volatile())
54 tree_node_list_iter
the_iter(node_list
);
55 while (!the_iter
.is_empty())
57 tree_node
*this_node
= the_iter
.step();
58 if (node_might_modify(the_variable
, this_node
))
65 extern boolean
might_modify(operand the_operand
, tree_node_list
*node_list
)
67 switch (the_operand
.kind())
73 var_sym
*the_var
= the_operand
.symbol();
74 if ((node_list
->parent() != NULL
) &&
75 (node_list
->parent()->scope() != NULL
) &&
76 (!node_list
->parent()->scope()->is_ancestor(
81 return might_modify(the_var
, node_list
);
85 instruction
*instr
= the_operand
.instr();
86 return might_modify(instr
, node_list
);
94 extern boolean
might_modify(instruction
*the_instr
, tree_node_list
*node_list
)
96 if (instr_is_impure_call(the_instr
) || (the_instr
->opcode() == io_gen
))
99 if ((the_instr
->opcode() == io_lod
) || (the_instr
->opcode() == io_cal
))
101 unsigned num_srcs
= the_instr
->num_srcs();
102 unsigned src_num
= 0;
103 if (the_instr
->opcode() == io_cal
)
105 for (; src_num
< num_srcs
; ++src_num
)
107 operand this_op
= the_instr
->src_op(src_num
);
108 if (this_op
.type()->unqual()->is_ptr())
110 sym_node
*addr_symbol
= operand_address_root_symbol(this_op
);
111 if (addr_symbol
== NULL
)
113 if ((node_list
->parent() != NULL
) &&
114 (node_list
->parent()->scope() != NULL
) &&
115 (!node_list
->parent()->scope()->is_ancestor(
116 addr_symbol
->parent())))
120 if (addr_symbol
->is_var())
122 var_sym
*addr_var
= (var_sym
*)addr_symbol
;
123 if (might_modify(addr_var
, node_list
))
130 unsigned num_srcs
= the_instr
->num_srcs();
131 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
133 if (might_modify(the_instr
->src_op(src_num
), node_list
))
140 /*----------------------------------------------------------------------*
141 End Public Function Implementations
142 *----------------------------------------------------------------------*/
143 /*----------------------------------------------------------------------*
144 Begin Private Function Implementations
145 *----------------------------------------------------------------------*/
147 static boolean
node_might_modify(var_sym
*the_var
, tree_node
*the_node
)
149 switch (the_node
->kind())
153 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
154 return expr_might_modify(the_var
, the_tree_instr
->instr());
158 tree_loop
*the_loop
= (tree_loop
*)the_node
;
159 if (might_modify(the_var
, the_loop
->body()))
161 return might_modify(the_var
, the_loop
->test());
165 tree_for
*the_for
= (tree_for
*)the_node
;
166 if (the_var
->overlaps(the_for
->index()))
168 if (op_might_modify(the_var
, the_for
->lb_op()))
170 if (op_might_modify(the_var
, the_for
->ub_op()))
172 if (op_might_modify(the_var
, the_for
->step_op()))
174 if (might_modify(the_var
, the_for
->body()))
176 return might_modify(the_var
, the_for
->landing_pad());
180 tree_if
*the_if
= (tree_if
*)the_node
;
181 if (might_modify(the_var
, the_if
->header()))
183 if (might_modify(the_var
, the_if
->then_part()))
185 return might_modify(the_var
, the_if
->else_part());
189 tree_block
*the_block
= (tree_block
*)the_node
;
190 return might_modify(the_var
, the_block
->body());
198 static boolean
expr_might_modify(var_sym
*the_var
, instruction
*the_instr
)
200 operand dest_op
= the_instr
->dst_op();
201 if (dest_op
.is_symbol() && (dest_op
.symbol() == the_var
))
204 switch (the_instr
->opcode())
207 if (!instr_is_impure_call(the_instr
))
212 if (!the_var
->is_auto())
215 boolean is_fortran
= FALSE
;
216 if ((the_instr
->owner() != NULL
) &&
217 (the_instr
->owner()->proc()->src_lang() == src_fortran
))
223 if (the_var
->root_ancestor()->is_addr_taken())
227 unsigned num_srcs
= the_instr
->num_srcs();
228 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
230 operand this_op
= the_instr
->src_op(src_num
);
231 if (this_op
.type()->unqual()->is_ptr())
233 sym_node
*modified_sym
=
234 operand_address_root_symbol(this_op
);
235 if ((modified_sym
!= NULL
) && (modified_sym
->is_var()))
237 var_sym
*modified_var
= (var_sym
*)modified_sym
;
238 if (modified_var
->overlaps(the_var
))
248 in_rrr
*the_rrr
= (in_rrr
*)the_instr
;
249 operand dest_addr
= the_rrr
->dst_addr_op();
250 sym_node
*modified_sym
= operand_address_root_symbol(dest_addr
);
251 if (modified_sym
!= NULL
)
253 if (modified_sym
->is_var())
255 var_sym
*modified_var
= (var_sym
*)modified_sym
;
256 if (modified_var
->overlaps(the_var
))
262 if (the_var
->root_ancestor()->is_addr_taken())
271 unsigned num_srcs
= the_instr
->num_srcs();
272 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
274 if (op_might_modify(the_var
, the_instr
->src_op(src_num
)))
281 static boolean
op_might_modify(var_sym
*the_var
, operand the_op
)
283 if (the_op
.is_expr())
284 return expr_might_modify(the_var
, the_op
.instr());
289 /*----------------------------------------------------------------------*
290 End Private Function Implementations
291 *----------------------------------------------------------------------*/