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 contains the implementation of the generalized operand class
22 sym_node_list
*read_once
;
23 sym_node_list
*read_multiple
;
26 const char *k_sequence_point
;
27 const char *k_bit_field_info
;
28 const char *k_type_name
;
29 const char *k_type_source_coordinates
;
30 const char *k_field_table
;
31 const char *k_type_alignment
;
32 const char *k_C_comment
;
33 const char *k_source_coordinates
;
34 const char *k_is_declared_reg
;
35 const char *k_source_references
;
36 const char *k_builtin_args
;
37 const char *k_typedef_name
;
39 boolean option_keep_comments
= FALSE
;
40 boolean option_mark_execution_points
= FALSE
;
41 boolean option_null_check
= FALSE
;
42 boolean option_keep_typedef_info
= FALSE
;
43 boolean option_force_enum_is_int
= FALSE
;
45 static proc_sym
*bit_ref_symbol
;
47 static void side_effect_list(tree_node_list
*the_list
,
48 tree_node_list_e
*position
, operand the_operand
);
49 static void written_and_not_read(sym_node_list
*sym_list
,
50 tree_node_list
*node_list
);
51 static void find_temps_read_once(sym_node_list
*sym_list
,
52 tree_node_list
*node_list
);
53 static void prune_once_read_on_node_list(sym_node_list
*read_once
,
54 sym_node_list
*read_multiple
,
55 tree_node_list
*node_list
);
56 static void prune_once_read_on_node(tree_node
*the_node
, void *data
);
57 static void prune_once_read_on_instr(instruction
*the_instr
, void *data
);
58 static void remove_sym_from_list(sym_node_list
*the_list
, sym_node
*symbol
);
59 static void attempt_combination(sym_node_list
*read_once
,
60 tree_node_list
*node_list
);
61 static boolean
instr_uses_var(instruction
*the_instr
, var_sym
*the_var
);
62 static void replace_operand(instruction
*the_instr
, operand old_operand
,
64 static void prune_out_reads(sym_node_list
*sym_list
, instruction
*the_instr
);
65 static void remove_writes(sym_node_list
*sym_list
, tree_node_list
*node_list
);
66 static boolean
symbol_in_list(sym_node_list
*sym_list
, sym_node
*the_symbol
);
67 static void eliminate_write(tree_instr
*writer
);
68 static void remove_symbols(sym_node_list
*sym_list
);
69 static void clean_field_refs_on_tree_node(tree_node
*the_node
, void *);
70 static operand
clean_field_refs_on_operand(operand to_clean
);
71 static instruction
*clean_field_refs_on_instr(instruction
*to_clean
);
72 static operand
expand_bit_field_ref(instruction
*to_undo
);
73 static operand
undo_bit_field_on_instr(instruction
*to_undo
,
76 type_node
**result_type
);
77 static boolean
instr_is_bit_field_ref(instruction
*to_test
);
79 boolean
genop::is_addressable(void)
81 if (suif_operand().is_expr())
83 instruction
*the_instr
= suif_operand().instr();
84 assert(the_instr
!= NULL
);
85 return (the_instr
->opcode() == io_lod
);
87 else if (suif_operand().is_symbol())
89 sym_node
*symbol
= suif_operand().symbol();
90 assert(symbol
!= NULL
);
91 return symbol
->is_userdef();
99 type_node
*genop::type(void)
101 return suif_operand().type();
104 tree_node_list
*genop::side_effects_only(void)
106 tree_node_list
*the_list
= precomputation();
107 side_effect_list(the_list
, NULL
, suif_operand());
111 void genop::make_temporary(void)
113 type_node
*this_type
= type();
115 if (suif_operand().is_symbol())
117 sym_node
*symbol
= suif_operand().symbol();
118 assert(symbol
!= NULL
);
119 if (!symbol
->is_userdef())
122 else if (suif_operand().is_expr())
124 instruction
*the_instr
= suif_operand().instr();
125 assert(the_instr
!= NULL
);
126 if (the_instr
->opcode() == io_ldc
)
137 eval_status status
= evaluate_as_const(&const_value
);
138 boolean need_default_value
= FALSE
;
142 warning("overflow in constant expression\n");
147 error("expression must be constant\n");
148 need_default_value
= TRUE
;
150 case EVAL_DIV_BY_ZERO
:
151 error("division by zero in constant expression\n");
152 need_default_value
= TRUE
;
154 case EVAL_UNKNOWN_AT_LINK
:
155 error("constant expression cannot be computed at link time\n");
156 need_default_value
= TRUE
;
162 if (need_default_value
)
164 if (type()->unqual()->op() == TYPE_FLOAT
)
165 const_value
= immed(0.0);
167 const_value
= immed(0);
170 if (suif_operand().is_expr())
171 delete suif_operand().instr();
173 in_ldc
*new_ldc
= new in_ldc(type(), operand(), const_value
);
174 the_suif_operand
= operand(new_ldc
);
178 if (is_boolean_type())
179 this_type
= booleantype
;
181 var_sym
*temporary
= get_current_symtab()->new_unique_var(this_type
);
182 temporary
->reset_userdef();
184 precomputation()->append(create_assignment(temporary
, suif_operand()));
185 the_suif_operand
= operand(temporary
);
188 boolean
genop::is_int_const(void)
190 if (!suif_operand().is_expr())
192 instruction
*the_instr
= suif_operand().instr();
193 assert(the_instr
!= NULL
);
194 if (the_instr
->opcode() != io_ldc
)
196 in_ldc
*the_ldc
= (in_ldc
*)the_instr
;
197 return the_ldc
->value().is_int_const();
200 boolean
genop::is_boolean_type(void)
202 if (suif_operand().is_expr())
204 instruction
*the_instr
= suif_operand().instr();
205 switch(the_instr
->opcode())
216 else if (suif_operand().is_symbol())
218 sym_node
*symbol
= suif_operand().symbol();
219 assert(symbol
!= NULL
);
220 if (symbol
->is_userdef())
223 assert(symbol
->is_var());
224 var_sym
*the_var
= (var_sym
*)symbol
;
225 return (the_var
->type() == booleantype
);
233 /* Checks for a ``null pointer constant'' as defined by ANSI/ISO 9899,
234 * Section 6.2.2.3, paragraph 3. */
235 boolean
genop::is_null_pointer_constant(void)
237 if (!precomputation()->is_empty())
239 if (!suif_operand().is_expr())
241 instruction
*the_instr
= suif_operand().instr();
242 assert(the_instr
!= NULL
);
243 while (the_instr
->opcode() == io_cvt
)
245 in_rrr
*the_cvt
= (in_rrr
*)the_instr
;
246 type_node
*cvt_result
= the_cvt
->result_type();
247 if (!cvt_result
->is_ptr())
249 ptr_type
*result_ptr
= (ptr_type
*)cvt_result
;
250 type_node
*result_ref
= result_ptr
->ref_type();
251 if (result_ref
->op() != TYPE_VOID
)
253 operand new_op
= the_cvt
->src_op();
254 if (!new_op
.is_expr())
256 the_instr
= new_op
.instr();
258 if (the_instr
->opcode() == io_ldc
)
260 in_ldc
*the_ldc
= (in_ldc
*)the_instr
;
261 if (the_ldc
->value() == immed(0))
265 #ifndef DEAL_WITH_GCC_BRAIN_DAMAGE
266 genop
test_genop(operand(the_instr
), precomputation());
269 // gcc version 2.7.2 gets a parse error on the code above. It looks
270 // like the same parsing bug in gcc as noted other places where the
271 // DEAL_WITH_GCC_BRAIN_DAMAGE flag is used. A work-around folows.
273 operand
instr_op(the_instr
);
274 genop
test_genop(instr_op
, precomputation());
276 if (!test_genop
.is_integral_constant_expression())
279 eval_status result
= evaluate_as_const(&immed_value
);
280 return ((result
== EVAL_OK
) && (immed_value
== immed(0)));
283 /* Checks for an ``integral constant expression'' as defined by
284 * ANSI/ISO 9899, Section 6.4, sub-section ``Semantics'', paragraph
286 boolean
genop::is_integral_constant_expression(void)
288 if (!precomputation()->is_empty())
290 if (!suif_operand().is_expr())
292 instruction
*the_instr
= suif_operand().instr();
293 assert(the_instr
!= NULL
);
294 while (the_instr
->opcode() == io_cvt
)
296 in_rrr
*the_cvt
= (in_rrr
*)the_instr
;
297 if (the_cvt
->result_type()->op() != TYPE_INT
)
299 operand new_op
= the_cvt
->src_op();
300 if (!new_op
.is_expr())
302 the_instr
= new_op
.instr();
303 if (new_op
.type()->op() == TYPE_FLOAT
)
305 if (the_instr
->opcode() != io_ldc
)
307 in_ldc
*the_ldc
= (in_ldc
*)the_instr
;
308 return the_ldc
->value().is_float_const();
310 if (new_op
.type()->op() != TYPE_INT
)
313 if (the_instr
->opcode() != io_ldc
)
315 in_ldc
*the_ldc
= (in_ldc
*)the_instr
;
316 return the_ldc
->value().is_int_const();
319 void genop::make_bit_field_ref(unsigned short from
, unsigned short to
,
320 type_node
*result_type
)
322 instruction
*function
=
323 new in_ldc(voidtype
->ptr_to(), operand(), immed(bit_ref_symbol
));
325 new in_cal(result_type
, operand(), operand(function
), 3);
326 the_call
->set_argument(0, suif_operand());
327 the_call
->set_argument(1, operand(new in_ldc(inttype
, operand(),
329 the_call
->set_argument(2, operand(new in_ldc(inttype
, operand(),
331 the_suif_operand
= operand(the_call
);
334 boolean
genop::is_bit_field_ref(void)
336 if (!suif_operand().is_expr())
338 instruction
*the_instr
= suif_operand().instr();
339 assert(the_instr
!= NULL
);
341 return instr_is_bit_field_ref(the_instr
);
344 void genop::undo_bit_field_ref(unsigned short *from
, unsigned short *to
,
345 type_node
**result_type
)
347 assert(suif_operand().is_expr());
348 instruction
*the_instr
= suif_operand().instr();
349 assert(the_instr
!= NULL
);
352 undo_bit_field_on_instr(the_instr
, from
, to
, result_type
);
355 void genop::double_bit_field_ref(genop
*op1
, genop
*op2
)
357 assert(is_bit_field_ref());
359 assert(suif_operand().is_expr());
360 instruction
*the_instr
= suif_operand().instr();
361 assert(the_instr
!= NULL
);
362 assert(the_instr
->opcode() == io_cal
);
363 in_cal
*old_call
= (in_cal
*)the_instr
;
365 assert(old_call
->num_args() == 3);
366 operand base_pointer
= old_call
->argument(0);
367 base_pointer
.remove();
368 genop
base_genop(base_pointer
, precomputation());
369 base_genop
.make_temporary();
372 new in_cal(old_call
->result_type(), operand(),
373 old_call
->addr_op().clone(), 3);
374 new_call
->set_argument(0, base_genop
.suif_operand().clone());
375 new_call
->set_argument(1, old_call
->argument(1).clone());
376 new_call
->set_argument(2, old_call
->argument(2).clone());
378 old_call
->set_argument(0, base_genop
.suif_operand());
380 *op1
= genop(operand(old_call
), base_genop
.precomputation());
381 *op2
= genop(operand(new_call
), new tree_node_list
);
384 void genop::deallocate(void)
386 delete precomputation();
387 if (suif_operand().is_expr())
388 delete suif_operand().instr();
391 void genop::clean_up_bit_field_refs(void)
393 precomputation()->map(&clean_field_refs_on_tree_node
, NULL
);
394 the_suif_operand
= clean_field_refs_on_operand(suif_operand());
397 eval_status
genop::evaluate_as_const(immed
*result
)
399 if (!precomputation()->is_empty())
400 return EVAL_NOT_CONST
;
402 suppress_array_folding
= FALSE
;
403 eval_status status
= evaluate_const_expr(suif_operand(), result
);
404 suppress_array_folding
= TRUE
;
408 extern void init_annotes(void)
410 k_type_alignment
= lexicon
->enter("type alignment")->sp
;
412 ANNOTE(k_sequence_point
, "sequence point", TRUE
);
413 ANNOTE(k_bit_field_info
, "bit field info", FALSE
);
414 ANNOTE(k_type_name
, "type name", FALSE
);
415 ANNOTE(k_type_source_coordinates
, "type source coordinates", FALSE
);
416 ANNOTE(k_field_table
, "field table", FALSE
);
417 ANNOTE(k_C_comment
, "C comment", TRUE
);
418 ANNOTE(k_source_coordinates
, "source coordinates", TRUE
);
419 ANNOTE(k_is_declared_reg
, "is declared reg", FALSE
);
420 ANNOTE(k_source_references
, "source references", TRUE
);
421 ANNOTE(k_builtin_args
, "builtin args", TRUE
);
422 ANNOTE(k_typedef_name
, "typedef name", TRUE
);
425 extern void init_bit_ref(void)
427 /* Note that we don't install this since it will never be written out --
428 it's just a placeholder */
430 new proc_sym(func(inttype
), src_unknown
, "00bit_field_ref");
433 extern tree_node
*last_action_node(tree_node_list
*the_node_list
)
435 return last_action_before(the_node_list
, NULL
);
438 extern tree_node
*last_action_before(tree_node_list
*the_node_list
,
441 if (the_node_list
== NULL
)
444 if (the_node_list
->is_empty())
447 tree_node_list_e
*current_element
= the_node_list
->tail();
449 if (the_node
!= NULL
)
451 while (current_element
!= NULL
)
453 tree_node_list_e
*old_element
= current_element
;
454 current_element
= current_element
->prev();
455 if (old_element
->contents
== the_node
)
460 while (current_element
!= NULL
)
462 tree_node
*this_node
= current_element
->contents
;
463 switch (this_node
->kind())
467 tree_instr
*the_tree_instr
= (tree_instr
*)this_node
;
468 instruction
*the_instr
= the_tree_instr
->instr();
469 assert(the_instr
!= NULL
);
470 if ((the_instr
->opcode() != io_mrk
) &&
471 (the_instr
->opcode() != io_nop
))
479 tree_block
*the_block
= (tree_block
*)this_node
;
480 tree_node
*last_in_block
= last_action_node(the_block
->body());
481 if (last_in_block
!= NULL
)
482 return last_in_block
;
487 current_element
= current_element
->prev();
492 extern boolean
operand_may_have_side_effects(operand the_operand
)
494 if (the_operand
.is_symbol())
496 sym_node
*the_symbol
= the_operand
.symbol();
497 assert(the_symbol
!= NULL
);
498 if (!the_symbol
->is_var())
500 var_sym
*the_var
= (var_sym
*)the_symbol
;
501 return any_part_volatile(the_var
->type());
503 else if (the_operand
.is_expr())
505 instruction
*the_instr
= the_operand
.instr();
506 if (the_instr
->opcode() == io_cal
)
510 else if (the_instr
->opcode() == io_lod
)
512 in_rrr
*the_rrr
= (in_rrr
*)the_instr
;
513 operand address
= the_rrr
->src_addr_op();
514 type_node
*addr_type
= address
.type();
515 addr_type
= addr_type
->unqual();
516 if (!addr_type
->is_ptr())
518 ptr_type
*the_ptr_type
= (ptr_type
*)addr_type
;
519 if (any_part_volatile(the_ptr_type
->ref_type()))
522 else if (the_instr
->opcode() == io_str
)
526 else if (the_instr
->opcode() == io_memcpy
)
531 int num_srcs
= the_instr
->num_srcs();
532 for (int src_num
= 0; src_num
< num_srcs
; ++src_num
)
534 if (operand_may_have_side_effects(the_instr
->src_op(src_num
)))
539 else if (the_operand
.is_null())
549 extern boolean
is_same_operand(operand op1
, operand op2
)
553 if (!op2
.is_symbol())
555 return (op1
.symbol() == op2
.symbol());
557 else if (op1
.is_expr())
561 instruction
*instr1
= op1
.instr();
562 instruction
*instr2
= op2
.instr();
563 assert(instr1
!= NULL
);
564 assert(instr2
!= NULL
);
565 if (instr1
->opcode() != instr2
->opcode())
567 if (!instr1
->result_type()->is_same(instr2
->result_type()))
569 if (instr1
->opcode() == io_ldc
)
571 in_ldc
*ldc1
= (in_ldc
*)instr1
;
572 in_ldc
*ldc2
= (in_ldc
*)instr2
;
573 return (ldc1
->value() == ldc2
->value());
577 unsigned num_srcs
= instr1
->num_srcs();
578 if (num_srcs
!= instr2
->num_srcs())
580 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
582 if (!is_same_operand(instr1
->src_op(src_num
),
583 instr2
->src_op(src_num
)))
597 extern void comment_text(char *comment_string
)
599 if (!option_keep_comments
)
602 suif_object
*mark_object
;
603 if (curr_list
== NULL
)
609 in_rrr
*new_mark
= new in_rrr(io_mrk
);
610 curr_list
->append(new tree_instr(new_mark
));
611 mark_object
= new_mark
;
614 immed_list
*new_annote
= new immed_list
;
615 new_annote
->append(immed(comment_string
));
616 mark_object
->append_annote(k_C_comment
, new_annote
);
619 extern immed_list
*coordinate_to_immeds(Coordinate the_coordinate
)
621 immed_list
*result
= new immed_list
;
622 result
->append(immed((the_coordinate
.file
== NULL
) ?
623 "" : the_coordinate
.file
));
624 result
->append(immed((int)the_coordinate
.x
));
625 result
->append(immed((int)the_coordinate
.y
));
629 extern Coordinate
*immeds_to_coordinate(immed_list
*the_immeds
)
631 static Coordinate result
;
633 if (the_immeds
== NULL
)
636 immed_list_iter
the_iter(the_immeds
);
638 if (the_iter
.is_empty())
640 immed file_immed
= the_iter
.step();
641 if (!file_immed
.is_string())
643 result
.file
= file_immed
.string();
645 if (the_iter
.is_empty())
647 immed x_immed
= the_iter
.step();
648 if (!x_immed
.is_integer())
650 result
.x
= x_immed
.integer();
652 if (the_iter
.is_empty())
654 immed y_immed
= the_iter
.step();
655 if (!y_immed
.is_integer())
657 result
.y
= y_immed
.integer();
659 if (!the_iter
.is_empty())
664 extern void remove_unused_temps(tree_node_list
*the_list
)
666 assert(the_list
!= NULL
);
668 sym_node_list unused
;
669 written_and_not_read(&unused
, the_list
);
670 remove_writes(&unused
, the_list
);
671 remove_symbols(&unused
);
673 sym_node_list read_once
;
674 find_temps_read_once(&read_once
, the_list
);
675 attempt_combination(&read_once
, the_list
);
677 while (!read_once
.is_empty())
679 sym_node_list_e
*this_element
= read_once
.head();
680 read_once
.remove(this_element
);
685 extern immed
immed_and_type_for_C_intconst(char *C_intconst
,
686 type_node
**the_type
)
688 char *digit_start
= C_intconst
;
690 if (*digit_start
== '0')
693 if ((*digit_start
== 'X') || (*digit_start
== 'x'))
708 i_integer
const_value(digit_start
, radix
);
709 immed result_value
= ii_to_immed(const_value
);
711 if (the_type
!= NULL
)
713 char *follow
= digit_start
;
716 if (((*follow
>= '0') && (*follow
<= '9')) ||
717 ((*follow
>= 'a') && (*follow
<= 'f')) ||
718 ((*follow
>= 'A') && (*follow
<= 'F')))
729 boolean u_suffix
= FALSE
;
733 if ((!u_suffix
) && ((*follow
== 'u') || (*follow
== 'U')))
735 else if ((l_count
< 2) && ((*follow
== 'l') || (*follow
== 'L')))
743 * See ANSI/ISO 9899-1990, section 6.1.3.2, second paragraph
744 * of ``Semantics'' section.
746 if ((l_count
== 2) && u_suffix
)
748 *the_type
= unsignedlonglong
;
750 else if (l_count
== 2)
752 if (immed_fits(result_value
, longlong
))
753 *the_type
= longlong
;
755 *the_type
= unsignedlonglong
;
757 else if ((l_count
>= 1) && u_suffix
)
759 if (immed_fits(result_value
, unsignedlong
))
760 *the_type
= unsignedlong
;
762 *the_type
= unsignedlonglong
;
764 else if (l_count
>= 1)
766 if (immed_fits(result_value
, longtype
))
767 *the_type
= longtype
;
768 else if (immed_fits(result_value
, unsignedlong
))
769 *the_type
= unsignedlong
;
770 else if (immed_fits(result_value
, longlong
))
771 *the_type
= longlong
;
773 *the_type
= unsignedlonglong
;
777 if (immed_fits(result_value
, unsignedtype
))
778 *the_type
= unsignedtype
;
779 else if (immed_fits(result_value
, unsignedlong
))
780 *the_type
= unsignedlong
;
782 *the_type
= unsignedlonglong
;
788 if (immed_fits(result_value
, inttype
))
790 else if (immed_fits(result_value
, longtype
))
791 *the_type
= longtype
;
792 else if (immed_fits(result_value
, unsignedlong
))
793 *the_type
= unsignedlong
;
794 else if (immed_fits(result_value
, longlong
))
795 *the_type
= longlong
;
797 *the_type
= unsignedlonglong
;
801 if (immed_fits(result_value
, inttype
))
803 else if (immed_fits(result_value
, unsignedtype
))
804 *the_type
= unsignedtype
;
805 else if (immed_fits(result_value
, longtype
))
806 *the_type
= longtype
;
807 else if (immed_fits(result_value
, unsignedlong
))
808 *the_type
= unsignedlong
;
809 else if (immed_fits(result_value
, longlong
))
810 *the_type
= longlong
;
812 *the_type
= unsignedlonglong
;
816 if (!immed_fits(result_value
, *the_type
))
818 warning("overflow in constant `%s'\n", C_intconst
);
819 eval_status status
= fit_immed(&result_value
, *the_type
);
820 assert(status
== EVAL_OVERFLOW
);
827 extern immed
immed_and_type_for_C_floatconst(char *C_floatconst
,
828 type_node
**the_type
)
830 char *follow
= (char *)cp
;
831 assert(follow
> C_floatconst
);
833 type_node
*result_type
;
834 if ((*follow
== 'f') || (*follow
== 'F'))
835 result_type
= floattype
;
836 else if ((*follow
== 'l') || (*follow
== 'L'))
837 result_type
= longdouble
;
839 result_type
= doubletype
;
841 if (the_type
!= NULL
)
842 *the_type
= result_type
;
844 assert(result_type
->op() == TYPE_FLOAT
);
845 if (native_floating_arithmetic_ok((base_type
*)result_type
))
847 double double_value
= 0;
848 follow
= C_floatconst
;
850 double_value
= strtod(C_floatconst
, NULL
);
851 return immed(double_value
);
855 char *mantissa
= new char[((char *)cp
- C_floatconst
) + 1];
856 i_integer
additional_exponent(0);
858 follow
= C_floatconst
;
859 char *follow_mantissa
= mantissa
;
861 while ((*follow
>= '0') && (*follow
<= '9'))
863 *follow_mantissa
= *follow
;
865 ++additional_exponent
;
872 while ((*follow
>= '0') && (*follow
<= '9'))
874 *follow_mantissa
= *follow
;
880 while ((follow_mantissa
> mantissa
) && (*(follow_mantissa
- 1) == '0'))
883 *follow_mantissa
= 0;
885 follow_mantissa
= mantissa
;
886 while (*follow_mantissa
== '0')
889 --additional_exponent
;
892 i_integer
exponent(0);
894 if ((*follow
== 'e') || (*follow
== 'E'))
897 exponent
.read(follow
);
900 exponent
+= (additional_exponent
- 1);
902 unsigned long exponent_length
=
903 exponent
.written_length().c_unsigned_long();
904 char *result_string
=
905 new char[strlen(follow_mantissa
) + exponent_length
+ 8];
907 char *follow_result
= result_string
;
908 if (*follow_mantissa
== 0)
910 *follow_result
= '0';
914 *follow_result
= *follow_mantissa
;
919 *follow_result
= '.';
922 if (*follow_mantissa
== 0)
924 *follow_result
= '0';
929 while (*follow_mantissa
!= 0)
931 *follow_result
= *follow_mantissa
;
937 *follow_result
= 'e';
940 if (!exponent
.is_negative())
942 *follow_result
= '+';
946 exponent
.write(follow_result
);
948 immed result_value
= immed(im_extended_float
, result_string
);
950 delete[] result_string
;
957 static void side_effect_list(tree_node_list
*the_list
,
958 tree_node_list_e
*position
, operand the_operand
)
960 assert(the_list
!= NULL
);
962 tree_node_list
*side_effects
= reduce_to_side_effects(the_operand
);
963 if (side_effects
!= NULL
)
965 the_list
->insert_before(side_effects
, position
);
970 static void written_and_not_read(sym_node_list
*sym_list
,
971 tree_node_list
*node_list
)
973 assert(sym_list
!= NULL
);
974 if (node_list
== NULL
)
977 tree_node_list_iter
the_iter(node_list
);
978 while (!the_iter
.is_empty())
980 tree_node
*this_node
= the_iter
.step();
981 switch (this_node
->kind())
985 tree_instr
*this_tree_instr
= (tree_instr
*)this_node
;
986 instruction
*this_instr
= this_tree_instr
->instr();
987 assert(this_instr
!= NULL
);
988 prune_out_reads(sym_list
, this_instr
);
990 operand destination
= this_instr
->dst_op();
991 if (!destination
.is_symbol())
994 sym_node
*this_symbol
= destination
.symbol();
995 assert(this_symbol
!= NULL
);
996 if (this_symbol
->is_userdef())
999 if (sym_list
->lookup(this_symbol
) == NULL
)
1000 sym_list
->append(this_symbol
);
1006 tree_if
*the_if
= (tree_if
*)this_node
;
1007 written_and_not_read(sym_list
, the_if
->header());
1008 written_and_not_read(sym_list
, the_if
->then_part());
1009 written_and_not_read(sym_list
, the_if
->else_part());
1014 * This should never happen since this function should only be
1015 * called on lists of instructions and tree_if's.
1022 static void find_temps_read_once(sym_node_list
*sym_list
,
1023 tree_node_list
*node_list
)
1025 sym_node_list read_multiple
;
1026 prune_once_read_on_node_list(sym_list
, &read_multiple
, node_list
);
1028 while (!read_multiple
.is_empty())
1030 sym_node_list_e
*this_element
= read_multiple
.head();
1031 read_multiple
.remove(this_element
);
1032 delete this_element
;
1036 static void prune_once_read_on_node_list(sym_node_list
*read_once
,
1037 sym_node_list
*read_multiple
,
1038 tree_node_list
*node_list
)
1040 read_once_data read_data
;
1041 read_data
.read_once
= read_once
;
1042 read_data
.read_multiple
= read_multiple
;
1044 node_list
->map(&prune_once_read_on_node
, &read_data
);
1047 static void prune_once_read_on_node(tree_node
*the_node
, void *data
)
1049 assert(the_node
!= NULL
);
1050 if (!the_node
->is_instr())
1053 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
1054 the_tree_instr
->instr_map(&prune_once_read_on_instr
, data
);
1057 static void prune_once_read_on_instr(instruction
*the_instr
, void *data
)
1059 assert(the_instr
!= NULL
);
1060 assert(data
!= NULL
);
1062 read_once_data
*read_data
= (read_once_data
*)data
;
1064 unsigned num_srcs
= the_instr
->num_srcs();
1065 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
1067 operand source
= the_instr
->src_op(src_num
);
1068 if (source
.is_symbol())
1070 var_sym
*the_var
= source
.symbol();
1071 if (!the_var
->is_userdef())
1073 sym_node_list_e
*the_element
=
1074 read_data
->read_multiple
->lookup(the_var
);
1075 if (the_element
== NULL
)
1077 the_element
= read_data
->read_once
->lookup(the_var
);
1078 if (the_element
== NULL
)
1080 read_data
->read_once
->append(the_var
);
1084 read_data
->read_once
->remove(the_element
);
1086 read_data
->read_multiple
->append(the_var
);
1093 if (the_instr
->opcode() == io_ldc
)
1095 in_ldc
*the_ldc
= (in_ldc
*)the_instr
;
1096 immed value
= the_ldc
->value();
1097 if (value
.is_symbol())
1099 sym_node
*the_symbol
= value
.symbol();
1100 if (!the_symbol
->is_userdef())
1102 remove_sym_from_list(read_data
->read_once
, the_symbol
);
1103 read_data
->read_multiple
->append(the_symbol
);
1109 static void remove_sym_from_list(sym_node_list
*the_list
, sym_node
*symbol
)
1111 assert(symbol
!= NULL
);
1112 sym_node_list_e
*the_element
= the_list
->lookup(symbol
);
1113 if (the_element
!= NULL
)
1115 the_list
->remove(the_element
);
1121 static void attempt_combination(sym_node_list
*read_once
,
1122 tree_node_list
*node_list
)
1124 assert(read_once
!= NULL
);
1125 assert(node_list
!= NULL
);
1127 tree_node_list_iter
node_iter(node_list
);
1128 while (!node_iter
.is_empty())
1130 tree_node
*first_node
= node_iter
.step();
1131 assert(first_node
!= NULL
);
1132 if (!first_node
->is_instr())
1134 tree_instr
*first_instr_node
= (tree_instr
*)first_node
;
1135 instruction
*first_instr
= first_instr_node
->instr();
1136 assert(first_instr
!= NULL
);
1138 if (node_iter
.is_empty())
1140 tree_node
*second_node
= node_iter
.peek();
1141 assert(second_node
!= NULL
);
1142 if (!second_node
->is_instr())
1144 tree_instr
*second_instr_node
= (tree_instr
*)second_node
;
1145 instruction
*second_instr
= second_instr_node
->instr();
1146 assert(second_instr
!= NULL
);
1148 operand first_destination
= first_instr
->dst_op();
1149 if (!first_destination
.is_symbol())
1151 var_sym
*the_var
= first_destination
.symbol();
1152 assert(the_var
!= NULL
);
1153 sym_node_list_e
*the_list_e
= read_once
->lookup(the_var
);
1154 if (the_list_e
== NULL
)
1157 if (!instr_uses_var(second_instr
, the_var
))
1160 first_instr_node
->remove_instr(first_instr
);
1161 node_list
->remove(first_instr_node
->list_e());
1162 delete first_instr_node
->list_e();
1163 delete first_instr_node
;
1165 first_instr
->set_dst(operand());
1166 operand
new_operand(first_instr
);
1167 if (first_instr
->opcode() == io_cpy
)
1169 in_rrr
*first_rrr
= (in_rrr
*)first_instr
;
1170 new_operand
= first_rrr
->src_op();
1171 new_operand
.remove();
1175 replace_operand(second_instr
, operand(the_var
), new_operand
);
1177 read_once
->remove(the_list_e
);
1179 the_var
->parent()->remove_sym(the_var
);
1184 static boolean
instr_uses_var(instruction
*the_instr
, var_sym
*the_var
)
1186 assert(the_instr
!= NULL
);
1188 unsigned num_srcs
= the_instr
->num_srcs();
1189 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
1191 operand this_source
= the_instr
->src_op(src_num
);
1192 if (this_source
== operand(the_var
))
1194 if (this_source
.is_expr())
1196 if (instr_uses_var(this_source
.instr(), the_var
))
1203 static void replace_operand(instruction
*the_instr
, operand old_operand
,
1204 operand new_operand
)
1206 assert(the_instr
!= NULL
);
1208 unsigned num_srcs
= the_instr
->num_srcs();
1209 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
1211 operand this_source
= the_instr
->src_op(src_num
);
1212 if (this_source
== old_operand
)
1214 the_instr
->set_src_op(src_num
, new_operand
);
1217 if (this_source
.is_expr())
1218 replace_operand(this_source
.instr(), old_operand
, new_operand
);
1222 static void prune_out_reads(sym_node_list
*sym_list
, instruction
*the_instr
)
1224 assert(sym_list
!= NULL
);
1225 assert(the_instr
!= NULL
);
1227 if (sym_list
->is_empty())
1230 int num_srcs
= the_instr
->num_srcs();
1231 for (int src_num
= 0; src_num
< num_srcs
; ++src_num
)
1233 operand this_op
= the_instr
->src_op(src_num
);
1234 if (this_op
.is_symbol())
1236 sym_node
*this_symbol
= this_op
.symbol();
1237 assert(this_symbol
!= NULL
);
1238 sym_node_list_e
*this_element
;
1239 sym_node_list_e
*next_element
= sym_list
->head();
1240 while (next_element
!= NULL
)
1242 this_element
= next_element
;
1243 next_element
= this_element
->next();
1244 sym_node
*test_sym
= this_element
->contents
;
1245 if (test_sym
== this_symbol
)
1247 sym_list
->remove(this_element
);
1248 delete this_element
;
1251 if (sym_list
->is_empty())
1254 else if (this_op
.is_expr())
1256 instruction
*this_instr
= this_op
.instr();
1257 assert(this_instr
!= NULL
);
1258 prune_out_reads(sym_list
, this_instr
);
1260 if (this_instr
->opcode() == io_ldc
)
1262 in_ldc
*this_ldc
= (in_ldc
*)this_instr
;
1263 immed value
= this_ldc
->value();
1264 if (value
.is_symbol())
1266 sym_node_list_e
*this_element
=
1267 sym_list
->lookup(value
.symbol());
1268 if (this_element
!= NULL
)
1270 sym_list
->remove(this_element
);
1271 delete this_element
;
1279 static void remove_writes(sym_node_list
*sym_list
, tree_node_list
*node_list
)
1281 assert(sym_list
!= NULL
);
1282 if (node_list
== NULL
)
1285 if (sym_list
->is_empty())
1288 tree_node_list_iter
the_iter(node_list
);
1289 while (!the_iter
.is_empty())
1291 tree_node
*this_node
= the_iter
.step();
1292 switch (this_node
->kind())
1296 tree_instr
*this_tree_instr
= (tree_instr
*)this_node
;
1297 instruction
*this_instr
= this_tree_instr
->instr();
1298 assert(this_instr
!= NULL
);
1300 operand destination
= this_instr
->dst_op();
1301 if (!destination
.is_symbol())
1304 sym_node
*this_symbol
= destination
.symbol();
1305 assert(this_symbol
!= NULL
);
1306 if (!symbol_in_list(sym_list
, this_symbol
))
1309 eliminate_write(this_tree_instr
);
1314 tree_if
*the_if
= (tree_if
*)this_node
;
1315 remove_writes(sym_list
, the_if
->header());
1316 remove_writes(sym_list
, the_if
->then_part());
1317 remove_writes(sym_list
, the_if
->else_part());
1322 * This should never happen since this function should only be
1323 * called on lists of instructions and tree_if's.
1330 static boolean
symbol_in_list(sym_node_list
*sym_list
, sym_node
*the_symbol
)
1332 return (sym_list
->lookup(the_symbol
) != NULL
);
1335 static void eliminate_write(tree_instr
*writer
)
1337 tree_node_list_e
*the_element
= writer
->list_e();
1338 assert(the_element
!= NULL
);
1339 tree_node_list
*the_list
= writer
->parent();
1340 assert(the_list
!= NULL
);
1341 instruction
*the_instr
= writer
->instr();
1342 assert(the_instr
!= NULL
);
1344 writer
->remove_instr(the_instr
);
1345 the_instr
->set_dst(operand());
1346 side_effect_list(the_list
, the_element
, operand(the_instr
));
1347 the_list
->remove(the_element
);
1352 static void remove_symbols(sym_node_list
*sym_list
)
1354 assert(sym_list
!= NULL
);
1356 sym_node_list_e
*this_element
;
1357 sym_node_list_e
*next_element
= sym_list
->head();
1358 while (next_element
!= NULL
)
1360 this_element
= next_element
;
1361 next_element
= this_element
->next();
1362 sym_node
*the_symbol
= this_element
->contents
;
1363 assert(the_symbol
!= NULL
);
1364 the_symbol
->parent()->remove_sym(the_symbol
);
1366 sym_list
->remove(this_element
);
1367 delete this_element
;
1369 assert(sym_list
->is_empty());
1372 static void clean_field_refs_on_tree_node(tree_node
*the_node
, void *)
1374 assert(the_node
!= NULL
);
1375 if (!the_node
->is_instr())
1378 tree_instr
*the_tree_instr
= (tree_instr
*)the_node
;
1379 instruction
*old_instr
= the_tree_instr
->instr();
1380 assert(old_instr
!= NULL
);
1381 the_tree_instr
->remove_instr(old_instr
);
1382 instruction
*new_instr
= clean_field_refs_on_instr(old_instr
);
1383 the_tree_instr
->set_instr(new_instr
);
1386 static operand
clean_field_refs_on_operand(operand to_clean
)
1388 if (!to_clean
.is_expr())
1390 return operand(clean_field_refs_on_instr(to_clean
.instr()));
1393 static instruction
*clean_field_refs_on_instr(instruction
*to_clean
)
1395 operand destination
= to_clean
->dst_op();
1397 unsigned num_srcs
= to_clean
->num_srcs();
1398 for (unsigned src_num
= 0; src_num
< num_srcs
; ++src_num
)
1400 operand old_operand
= to_clean
->src_op(src_num
);
1401 old_operand
.remove();
1402 to_clean
->set_src_op(src_num
,
1403 clean_field_refs_on_operand(old_operand
));
1406 if (instr_is_bit_field_ref(to_clean
))
1408 operand new_operand
= expand_bit_field_ref(to_clean
);
1409 instruction
*new_instr
;
1410 if (new_operand
.is_expr())
1412 new_instr
= new_operand
.instr();
1416 new_instr
= new in_rrr(io_cpy
, new_operand
.type(), operand(),
1419 if (destination
.is_symbol())
1421 new_instr
->set_dst(destination
);
1431 static operand
expand_bit_field_ref(instruction
*to_undo
)
1433 unsigned short bit_field_from
;
1434 unsigned short bit_field_to
;
1435 type_node
*result_type
;
1437 undo_bit_field_on_instr(to_undo
, &bit_field_from
, &bit_field_to
,
1439 int right_amount
= result_type
->size() - (bit_field_to
- bit_field_from
);
1440 int left_amount
= right_amount
- field_right
;
1443 new in_rrr(io_lod
, unsignedtype
, operand(), address
);
1445 new in_rrr(io_lsl
, unsignedtype
, operand(), operand(the_load
),
1446 operand(new in_ldc(unsignedtype
, operand(),
1447 immed(left_amount
))));
1449 if_ops right_shift_op
;
1450 if (result_type
== unsignedtype
)
1453 right_shift_op
= io_lsr
;
1457 pre_asr
= new in_rrr(io_cvt
, result_type
, operand(), operand(the_lsl
));
1458 right_shift_op
= io_asr
;
1461 new in_rrr(right_shift_op
, result_type
, operand(),
1463 operand(new in_ldc(unsignedtype
, operand(),
1464 immed(right_amount
))));
1465 return operand(the_asr
);
1468 static operand
undo_bit_field_on_instr(instruction
*to_undo
,
1469 unsigned short *from
,
1471 type_node
**result_type
)
1473 assert(to_undo
!= NULL
);
1474 assert(to_undo
->opcode() == io_cal
);
1475 in_cal
*the_call
= (in_cal
*)to_undo
;
1477 operand result
= the_call
->argument(0);
1480 operand from_operand
= the_call
->argument(1);
1481 assert(from_operand
.is_expr());
1482 instruction
*from_instr
= from_operand
.instr();
1483 assert(from_instr
!= NULL
);
1484 assert(from_instr
->opcode() == io_ldc
);
1485 in_ldc
*from_ldc
= (in_ldc
*)from_instr
;
1486 immed from_value
= from_ldc
->value();
1487 assert(from_value
.is_integer());
1488 *from
= from_value
.integer();
1490 operand to_operand
= the_call
->argument(2);
1491 assert(to_operand
.is_expr());
1492 instruction
*to_instr
= to_operand
.instr();
1493 assert(to_instr
!= NULL
);
1494 assert(to_instr
->opcode() == io_ldc
);
1495 in_ldc
*to_ldc
= (in_ldc
*)to_instr
;
1496 immed to_value
= to_ldc
->value();
1497 assert(to_value
.is_integer());
1498 *to
= to_value
.integer();
1500 *result_type
= the_call
->result_type();
1506 static boolean
instr_is_bit_field_ref(instruction
*to_test
)
1508 assert(to_test
!= NULL
);
1510 if (to_test
->opcode() != io_cal
)
1512 in_cal
*the_call
= (in_cal
*)to_test
;
1513 operand address
= the_call
->addr_op();
1515 if (!address
.is_expr())
1517 instruction
*addr_instr
= address
.instr();
1518 assert(addr_instr
!= NULL
);
1520 if (addr_instr
->opcode() != io_ldc
)
1522 in_ldc
*the_ldc
= (in_ldc
*)addr_instr
;
1523 immed value
= the_ldc
->value();
1525 if (!value
.is_symbol())
1528 return (value
.symbol() == bit_ref_symbol
);