+Mon Aug 9 10:08:50 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * Makefile.in: Update dependencies.
+ * alias.c: Include "function.h"
+ * c-decl.c: Likewise.
+ * caller-save.c: Likewise.
+ * calls.c: Likewise.
+ * combine.c: Likewise.
+ * cse.c: Likewise.
+ * explow.c: Likewise.
+ * final.c: Likewise.
+ * global.c: Likewise.
+ * graph.c: Likewise.
+ * local-alloc.c: Likewise.
+ * loop.c: Likewise.
+ * optabs.c: Likewise.
+ * profile.c: Likewise.
+ * recog.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * reload.c: Likewise.
+ * reorg.c: Likewise.
+ * resource.c: Likewise.
+ * sched.c: Likewise.
+ * stupid.c: Likewise.
+ * config/1750a/1750a.c: Likewise.
+ * config/a29k/a29k.c: Likewise.
+ * config/arc/arc.c: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/thumb.c: Likewise.
+ * config/c4x/c4x.c: Likewise.
+ * config/clipper/clipper.c: Likewise.
+ * config/convex/convex.c: Likewise.
+ * config/fx80/fx80.c: Likewise.
+ * config/i860/i860.c: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/m88k/m88k.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/pdp11/pdp11.c: Likewise.
+ * config/pyr/pyr.c: Likewise.
+ * config/romp/romp.c: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/tahoe/tahoe.c: Likewise.
+ * config/vax/vax.c: Likewise.
+ * config/we32k/we32k.c: Likewise.
+ * config/sparc/sparc.c: Include "function.h".
+ (mem_min_alignment): Test current_function rather than
+ regno_pointer_align.
+ * config/pa/pa.c: Likewise.
+ (compute_frame_size): Delete declaration of
+ current_function_outgoing_args_size.
+ * config/arc/arc.h (current_function_varargs): Delete declaration.
+ * config/elxsi/elxsi.h (current_function_calls_alloca): Delete
+ declaration.
+ * config/i370/i370.h (current_function_outgoing_args_size): Delete
+ declaration.
+ * config/i386/i386.h (FINALIZE_PIC): Delete declaration of
+ current_function_uses_pic_offset_table.
+ * config/m68k/a-ux.h (FUNCTION_EXTRA_EPILOGUE): Delete declaration
+ of current_function_returns_pointer.
+ * config/m68k/altos3068.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m68k/linux.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m68k/m68kv4.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m68k/mot3300.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m68k/pbb.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m68k/tower-as.h (FUNCTION_EXTRA_EPILOGUE): Likewise.
+ * config/m88k/m88k.c: Include "function.h"
+ (call_used_regs, current_function_pretend_args_size,
+ current_function_outgoing_args_size, frame_pointer_needed): Delete
+ declarations.
+ * config/m88k/m88k.h (current_function_pretend_args_size): Delete
+ declaration.
+ * config/mips/mips.h (current_function_calls_alloca): Delete
+ declaration.
+ * config/mn10200/mn10200.h (current_function_needs_context,
+ rtx_equal_function_value_matters): Delete declarations.
+ * config/ns32k/ns32k (current_function_uses_pic_offset_table,
+ flag_pic): Delete declarations.
+ * config/pa/pa.h (current_function_pretend_args_size,
+ current_function_decl): Delete declarations.
+ * config/pa/som.h (current_function_varargs): Delete declaration.
+ * config/pdp11/pdp11.h (current_function_pretend_args_size): Delete
+ declaration.
+ * config/pyr/pyr.h (current_function_pretend_args_size,
+ current_function_args_size, current_function_calls_alloca): Delete
+ declarations.
+ * config/sh/sh.h (current_function_varargs): Delete declaration.
+ * config/sparc/sparc.h (current_function_outgoing_args_size,
+ current_function_calls_alloca, current_function_decl): Delete
+ declarations.
+ * config/spur/spur.h (current_function_pretend_args_size,
+ current_function_calls_alloca): Delete declarations.
+ * config/v850/v850.c (current_function_outgoing_args_size): Delete
+ declaration.
+ * config/vax/vms.h (current_function_name): Delete declaration.
+ * gcse.c: Include "function.h".
+ (current_function_name, current_function_calls_setjmp): Delete
+ declarations.
+ * haifa-sched.c: Include "function.h".
+ (forced_labels): Delete declaration.
+ * jump.c: Likewise.
+ * reg-stack.c: Likewise.
+ * reload1.c: Likewise.
+ * genemit.c (main): Make generated file include function.h.
+ * genoutput.c (output_prologue): Likewise.
+
+ * builtins.c (saveregs_value, apply_args_value): Delete variables.
+ * emit-rtl.c (reg_rtx_no, first_label_num, first_insn, last_insn,
+ sequence_rtl_expr, cur_insn_uid, last_linenum, last_filename,
+ regno_pointer_flag, regno_pointer_flag_length, regno_pointer_align,
+ regno_reg_rtx, sequence_stack): Delete variables. Add accessor
+ macros for some of them.
+ (emit_filename, emit_lineno): Delete declarations.
+ (gen_reg_rtx): Use memset/memcpy instead of bzero/bcopy. Access
+ regno_pointer_* variables through current_function.
+ (gen_inline_header_rtx): Delete function.
+ (save_emit_status): Delete function.
+ (set_new_last_label_num): New function.
+ (clear_emit_caches): New function.
+ (restore_emit_status): Just clear last_labelnum and call
+ clear_emit_caches.
+ (get_last_insn_anywhere): Variable sequence_stack is now accessed
+ through macro seq_stack.
+ (add_insn_after): Likewise.
+ (add_insn_before): Likewise.
+ (remove_insn): Likewise.
+ (pop_topmost_sequence): Likewise.
+ (in_sequence_p): Likewise.
+ (start_sequence_for_rtl_expr): Likewise.
+ (start_sequence): Likewise, and likewise for
+ sequence_rtl_expr/seq_rtl_expr.
+ (push_topmost_sequence): Likewise.
+ (end_sequence): Likewise.
+ (init_virtual_regs): Now takes a "struct emit_status *" argument.
+ All callers changed. Store into that pointer instead of globals.
+ (init_emit): Allocate emit elt of current_function.
+ Changes for sequence_rtl_expr/sequence_stack renaming.
+ Call clear_emit_caches instead of doing it in-line.
+ Access regno_pointer_* variables through current_function.
+ (init_emit_once) Don't clear sequence_stack.
+
+ * expr.c (pending_stack_adjust, inhibit_defer_pop, pending_chain):
+ Delete variables.
+ (arg_pointer_save_area): Delete declaration.
+ (finish_expr_for_function): Renamed from init_queue; no longer static.
+ (init_expr): Don't call init_queue.
+ (save_expr_status, restore_expr_status): Delete functions.
+ (expand_expr): Changes to reflect new layout of struct function.
+ Don't access current_function_check_memory_usage when current_function
+ is 0.
+ * expr.h (forced_labels, save_expr_regs, saveregs_value,
+ apply_args_value, current_function_calls_alloca, inhibit_defer_pop,
+ current_function_outgoing_args_size, current_function_arg_offset_rtx,
+ current_function_uses_const_pool, function_call_count,
+ current_function_uses_pic_offset_table, nonlocal_labels,
+ current_function_internal_arg_pointer, nonlocal_goto_stack_level,
+ current_function_check_memory_usage, nonlocal_goto_handler_slots,
+ pending_stack_adjust, target_temp_slot_level, temp_slot_level): Delete
+ declarations.
+ (finish_expr_for_function): Declare.
+ * flags.h (current_function_has_nonlocal_label,
+ current_function_has_nonlocal_goto, current_function_is_thunk,
+ current_function_has_computed_jump): Delete declarations.
+ * flow.c (forced_labels): Delete declaration.
+ * function.c (current_function_pops_args,
+ current_function_returns_struct, current_function_returns_pcc_struct,
+ current_function_needs_context, current_function_calls_setjmp,
+ current_function_calls_longjmp, current_function_has_nonlocal_label,
+ current_function_has_nonlocal_goto, current_function_is_thunk,
+ current_function_has_computed_jump, current_function_calls_alloca,
+ current_function_contains_functions, current_function_returns_pointer,
+ current_function_epilogue_delay_list, current_function_args_size,
+ current_function_pretend_args_size, current_function_arg_offset_rtx,
+ current_function_outgoing_args_size, current_function_varargs,
+ current_function_stdarg, current_function_args_info, cleanup_label,
+ current_function_name, current_function_uses_const_pool,
+ current_function_instrument_entry_exit, current_function_return_rtx,
+ current_function_uses_pic_offset_table, nonlocal_labels,
+ current_function_internal_arg_pointer, current_function_cannot_inline,
+ current_function_check_memory_usage, function_call_count,
+ nonlocal_goto_handler_slots, nonlocal_goto_handler_labels,
+ nonlocal_goto_stack_level, return_label, save_expr_regs,
+ stack_slot_list, rtl_expr_chain, tail_recursion_label, temp_slots,
+ tail_recursion_reentry, arg_pointer_save_area, frame_offset,
+ context_display, trampoline_list, parm_birth_insn, invalid_stack_slot,
+ last_parm_insn, max_parm_reg, parm_reg_stack_loc, sequence_rtl_expr,
+ temp_slot_level, var_temp_slot_level, target_temp_slot_level):
+ Delete variables.
+ (push_function_context_to): Don't save them. Don't call
+ save_storage_status, save_emit_status or save_expr_status.
+ (pop_function_context_from): Don't restore them. Don't call
+ restore_storage_status or restore_expr_status.
+ (get_func_frame_size): New function.
+ (get_frame_size): Use it.
+ (assign_outer_stack_local): Reflect some member name changes in struct
+ function.
+ (put_reg_into_stack): Likewise.
+ (assign_stack_temp_for_type): sequence_rtl_expr was renamed to
+ seq_rtl_expr.
+ (fixup_var_refs): Likewise.
+ (fix_lexical_addr): Likewise.
+ (trampoline_address): Likewise.
+ (prepare_function_start): Clear field inlinable of current_function.
+ (init_function_for_compilation): New function.
+ (expand_dummy_function_end): New function.
+ (expand_function_end): Call finish_expr_for_function.
+ * function.h (struct emit_status): New; fields moved here from struct
+ function and from global variables. Add accessor macros for some of
+ the fields.
+ (struct expr_status): Likewise.
+ (REGNO_POINTER_ALIGN, REGNO_POINTER_FLAG): Moved here from regs.h.
+ (struct function): Add fields expr and emit, inlinable, inl_emit,
+ original_arg_vector, original_decl_initial, inl_last_parm_insn,
+ inl_max_label_num. Add many comments.
+ Add accessor macros for all elts of struct function that no longer
+ have a global variable.
+ (cleanup_label, return_label, frame_offset, tail_recursion_label,
+ tail_recursion_reentry, arg_pointer_save_area, rtl_expr_chain,
+ stack_slot_list): Delete declarations.
+ (get_func_frame_size): Declare.
+ (save_expr_status, restore_expr_status, save_emit_status,
+ save_storage_status, restore_storage_status): Delete declarations.
+ (init_virtual_regs): Declare.
+ * output.h (current_function_pops_args,
+ current_function_returns_struct, current_function_returns_pcc_struct,
+ current_function_needs_context, current_function_calls_setjmp,
+ current_function_calls_longjmp, current_function_calls_alloca,
+ current_function_has_nonlocal_label, current_function_varargs,
+ current_function_has_computed_jump, current_function_returns_pointer,
+ current_function_contains_functions, current_function_args_size,
+ current_function_pretend_args_size, current_function_stdarg,
+ current_function_outgoing_args_size, current_function_args_info,
+ current_function_name, current_function_return_rtx,
+ current_function_epilogue_delay_list,
+ current_function_uses_const_pool, current_function_cannot_inline):
+ Delete declarations.
+ * regs.h (reg_rtx_no, regno_pointer_flag, regno_pointer_flag_length,
+ regno_reg_rtx): Delete declaration.
+ (REGNO_POINTER_FLAG): Delete macro.
+ * stmt.c (expand_goto): Changes to reflect that some fields in struct
+ function were renamed.
+ * stor-layout.c (save_storage_status, restore_storage_status): Delete
+ functions.
+ * toplev.c: Include "function.h".
+ (current_function_decl): Delete declaration.
+ (compile_file): Call init_dummy_function_start and
+ expand_dummy_function_end around some initializations that need to
+ emit rtl.
+ (rest_of_compilation): Use DECL_SAVED_INSNS properly.
+ Call init_function_for_compilation.
+ * unroll.c: Include "function.h"
+ (unroll_loop): Access regno_pointer_* variables through
+ current_function.
+
+ * tree.h (struct tree_decl): Add elt f to saved_insns member.
+ (DECL_SAVED_INSNS): use it.
+ (expand_dummy_function_end): Declare.
+ (init_function_for_compilation): Declare.
+ * calls.c (calls_function_1): Change use of DECL_SAVED_INSNS now
+ that it's no longer an INLINE_HEADER.
+ (expand_call): Likewise.
+ * integrate.c (finish_inline): Delete function.
+ (max_parm_reg, parm_reg_stack_loc): Delete declarations.
+ (initialize_for_inline): Delete min_labelno, max_labelno and max_reg
+ args. Don't generate an INLINE_HEADER rtx, just return the arg
+ vector. All callers changed.
+ (save_for_inline_copying): Create a duplicate struct emit_status to
+ hold the emit state for compiling the current function. Use this and
+ the other new fields in struct function that are for integration
+ instead of an INLINE_HEADER.
+ Use memcpy instead of bcopy.
+ Store the current struct function in DECL_SAVED_INSNS of fndecl.
+ (save_for_inline_nocopy): Similar changes, except no new emit_status
+ is needed here.
+ (expand_inline_function): Get information from function structure,
+ not from an inline header rtx.
+ (output_inline_function): Lose code to extract the necessary
+ information from an inline header; simply put back the function
+ structure into current_function. Clear its inlinable elt.
+ * rtl.def (INLINE_HEADER): Delete.
+ * rtl.h: Delete all accessors for an INLINE_HEADER.
+ (gen_inline_header_rtx): Delete declaration.
+ (regno_reg_rtx, regno_pointer_align, nonlocal_goto_handler_labels):
+ Delete declarations.
+ (REGNO_POINTER_ALIGN): Delete.
+ (clear_emit_caches): Declare.
+ (set_new_last_label_num): Declare.
+
Mon Aug 9 01:52:24 1999 Jason Merrill <jason@yorick.cygnus.com>
* print-tree.c (print_node): Print base for OFFSET_TYPEs.
$(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h
c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
- c-lex.h flags.h output.h toplev.h defaults.h
+ c-lex.h flags.h function.h output.h toplev.h defaults.h
c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h
c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
c-common.h flags.h toplev.h $(EXPR_H)
mbchar.o: mbchar.c $(CONFIG_H) system.h mbchar.h
graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h $(RTL_H) \
- hard-reg-set.h $(BASIC_BLOCK_H)
+ function.h hard-reg-set.h $(BASIC_BLOCK_H)
sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H)
COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o
function.h $(EXPR_H) $(RTL_H) toplev.h
fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
$(RTL_H)
-toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \
+toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) $(BASIC_BLOCK_H) \
intl.h function.h output.h $(RECOG_H) except.h toplev.h
jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
- insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h \
+ insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
toplev.h insn-attr.h
stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) insn-config.h reload.h flags.h toplev.h
+ $(BASIC_BLOCK_H) insn-config.h reload.h flags.h function.h toplev.h
cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
- real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h \
+ real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h \
$(srcdir)/../include/splay-tree.h
gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
- output.h toplev.h
+ function.h output.h toplev.h
resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h system.h \
- $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h toplev.h
+ $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h function.h toplev.h
lcm.o : lcm.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H)
profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \
- gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h insn-config.h
+ gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h function.h insn-config.h
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \
insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \
- toplev.h varray.h
-unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
+ function.h toplev.h varray.h
+unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h function.h \
integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h varray.h
flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h recog.h \
insn-flags.h function.h
-combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h \
+combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h function.h \
insn-config.h insn-flags.h insn-codes.h insn-attr.h $(REGS_H) $(EXPR_H) \
$(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h
regclass.o : regclass.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h flags.h \
- $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h toplev.h \
- output.h
+ $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \
+ toplev.h function.h output.h
local-alloc.o : local-alloc.c $(CONFIG_H) system.h $(RTL_H) flags.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) output.h \
- insn-attr.h toplev.h
+ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
+ output.h function.h insn-attr.h toplev.h
bitmap.o : bitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H) \
$(REGS_H)
-global.o : global.c $(CONFIG_H) system.h $(RTL_H) flags.h reload.h \
+global.o : global.c $(CONFIG_H) system.h $(RTL_H) flags.h reload.h function.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h toplev.h
varray.o : varray.c $(CONFIG_H) system.h varray.h $(RTL_H) $(TREE_H) bitmap.h
reload.o : reload.c $(CONFIG_H) system.h $(RTL_H) flags.h output.h $(EXPR_H) \
reload.h $(RECOG_H) hard-reg-set.h insn-config.h insn-codes.h $(REGS_H) \
- real.h toplev.h
+ function.h real.h toplev.h
reload1.o : reload1.c $(CONFIG_H) system.h $(RTL_H) real.h flags.h $(EXPR_H) \
reload.h $(REGS_H) hard-reg-set.h insn-config.h insn-flags.h insn-codes.h \
- $(BASIC_BLOCK_H) $(RECOG_H) output.h toplev.h
+ $(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h
caller-save.o : caller-save.c $(CONFIG_H) system.h $(RTL_H) flags.h \
- $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) \
+ $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
$(RECOG_H) reload.h $(EXPR_H) toplev.h
reorg.o : reorg.c $(CONFIG_H) system.h $(RTL_H) conditions.h hard-reg-set.h \
$(BASIC_BLOCK_H) $(REGS_H) insn-config.h insn-attr.h insn-flags.h \
- $(RECOG_H) flags.h output.h $(EXPR_H) toplev.h
+ $(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h
alias.o : alias.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h \
$(REGS_H) toplev.h output.h $(EXPR_H)
regmove.o : regmove.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
- $(RECOG_H) output.h reload.h $(REGS_H) hard-reg-set.h flags.h \
+ $(RECOG_H) output.h reload.h $(REGS_H) hard-reg-set.h flags.h function.h \
$(EXPR_H) insn-flags.h $(BASIC_BLOCK_H) toplev.h
$(SCHED_PREFIX)sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) system.h $(RTL_H) \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h \
+ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
insn-attr.h toplev.h recog.h
final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h intl.h \
- $(REGS_H) $(RECOG_H) conditions.h insn-config.h insn-attr.h except.h real.h \
- output.h hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h \
- defaults.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h
-recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) \
+ $(REGS_H) $(RECOG_H) conditions.h insn-config.h insn-attr.h function.h \
+ real.h output.h hard-reg-set.h insn-flags.h insn-codes.h gstab.h except.h \
+ xcoffout.h defaults.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h \
+ dbxout.h
+recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) function.h \
$(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
insn-flags.h insn-codes.h real.h toplev.h
reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
- $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h
+ $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
+ function.h
dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h
$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
- insn-flags.h output.h insn-attr.h insn-codes.h system.h toplev.h
+ insn-flags.h output.h insn-attr.h insn-codes.h system.h toplev.h function.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(out_file)
# Build auxiliary files that support ecoff format.
touch s-codes
insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) $(EXPR_H) real.h output.h \
- insn-config.h insn-flags.h insn-codes.h system.h reload.h recog.h
+ insn-config.h insn-flags.h insn-codes.h system.h reload.h recog.h function.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-emit.c
insn-emit.c: s-emit ; @true
insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) $(REGS_H) real.h conditions.h \
hard-reg-set.h insn-config.h insn-flags.h insn-attr.h output.h $(RECOG_H) \
- insn-codes.h system.h
+ function.h insn-codes.h system.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-output.c
insn-output.c: s-output ; @true
#include "config.h"
#include "system.h"
#include "rtl.h"
+#include "function.h"
#include "expr.h"
#include "regs.h"
#include "hard-reg-set.h"
#define OUTGOING_REGNO(IN) (IN)
#endif
-/* Nonzero means __builtin_saveregs has already been done in this function.
- The value is the pseudoreg containing the value __builtin_saveregs
- returned. */
-rtx saveregs_value;
-
-/* Similarly for __builtin_apply_args. */
-rtx apply_args_value;
-
static int get_pointer_alignment PROTO((tree, unsigned));
static tree c_strlen PROTO((tree));
static rtx get_memory_rtx PROTO((tree));
#include "system.h"
#include "tree.h"
#include "flags.h"
+#include "function.h"
#include "output.h"
#include "c-tree.h"
#include "c-lex.h"
#include "recog.h"
#include "basic-block.h"
#include "reload.h"
+#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "tree.h"
#include "flags.h"
#include "expr.h"
+#include "function.h"
#include "regs.h"
#include "insn-flags.h"
#include "toplev.h"
if ((DECL_BUILT_IN (fndecl)
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)
|| (DECL_SAVED_INSNS (fndecl)
- && (FUNCTION_FLAGS (DECL_SAVED_INSNS (fndecl))
- & FUNCTION_FLAGS_CALLS_ALLOCA)))
+ && DECL_SAVED_INSNS (fndecl)->calls_alloca))
return 1;
}
&& fndecl != current_function_decl
&& DECL_INLINE (fndecl)
&& DECL_SAVED_INSNS (fndecl)
- && RTX_INTEGRATED_P (DECL_SAVED_INSNS (fndecl)))
+ && DECL_SAVED_INSNS (fndecl)->inlinable)
is_integrable = 1;
else if (! TREE_ADDRESSABLE (fndecl))
{
rtx insn, seq;
/* Look for a call in the inline function code.
- If OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) is
+ If DECL_SAVED_INSNS (fndecl)->outgoing_args_size is
nonzero then there is a call and it is not necessary
to scan the insns. */
- if (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) == 0)
+ if (DECL_SAVED_INSNS (fndecl)->outgoing_args_size == 0)
for (insn = first_insn; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
break;
value of reg_parm_stack_space is wrong, but gives
correct results on all supported machines. */
- int adjust = (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl))
+ int adjust = (DECL_SAVED_INSNS (fndecl)->outgoing_args_size
+ reg_parm_stack_space);
start_sequence ();
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
+#include "function.h"
/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
#include "expr.h"
#include "insn-flags.h"
#include <string.h>
#include "rtl.h"
#include "tree.h"
+#include "function.h"
#include "expr.h"
#define HAVE_cc0
#include "conditions.h"
#include "insn-attr.h"
#include "flags.h"
#include "recog.h"
+#include "function.h"
#include "expr.h"
#include "obstack.h"
#include "tree.h"
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "recog.h"
varargs function we want to treat the last named arg (which is
`__builtin_va_alist') as unnamed.
This macro is only used in this file. */
-extern int current_function_varargs;
#define PASS_IN_REG_P(CUM, MODE, TYPE, NAMED) \
((!current_function_varargs || (NAMED)) \
&& (CUM) < MAX_ARC_PARM_REGS \
#include "flags.h"
#include "reload.h"
#include "tree.h"
+#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "recog.h"
#include "insn-attr.h"
#include "flags.h"
#include "tree.h"
+#include "function.h"
#include "expr.h"
#include "insn-config.h"
#include "recog.h"
#include "insn-flags.h"
#include "output.h"
#include "tree.h"
+#include "function.h"
#include "expr.h"
#include "flags.h"
#include "loop.h"
#include "insn-attr.h"
#include "tree.h"
#include "c-tree.h"
+#include "function.h"
#include "expr.h"
#include "flags.h"
#include "machmode.h"
#include "insn-flags.h"
#include "insn-attr.h"
#include "output.h"
+#include "function.h"
#include "expr.h"
/* Tables used in convex.h */
{ register int regno; \
register int cnt = 0; \
extern char call_used_regs[]; \
- extern int current_function_calls_alloca; \
/* this conditional is ONLY here because there is a BUG; \
- EXIT_IGNORE_STACK is ignored itself when the first part of \
- the condition is true! (at least in version 1.35) */ \
+ EXIT_IGNORE_STACK is ignored itself when the first part of \
+ the condition is true! (at least in version 1.35) */ \
/* the 8*10 is for 64 bits of .r5 - .r14 */ \
if (current_function_calls_alloca || (SIZE)>=(256-8*10)) { \
/* use .r4 as a temporary! Ok for now.... */ \
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
+#include "function.h"
#include "output.h"
#include "insn-attr.h"
extern int mvs_function_name_length;
-/* The amount of space used for outgoing arguments. */
-
-extern int current_function_outgoing_args_size;
-
/* Compile using char instructions (mvc, nc, oc, xc). On 4341 use this since
these are more than twice as fast as load-op-store.
On 3090 don't use this since load-op-store is much faster. */
#define FINALIZE_PIC \
do \
{ \
- extern int current_function_uses_pic_offset_table; \
- \
current_function_uses_pic_offset_table |= profile_flag | profile_block_flag; \
} \
while (0)
#include "output.h"
#include "recog.h"
#include "insn-attr.h"
+#include "function.h"
#include "expr.h"
static rtx find_addr_reg ();
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
{ \
- extern int current_function_returns_pointer; \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
asm_fprintf (FILE, "\t%s %Ra0,%Rd0\n", ASM_MOV_INSN); \
}
/* Return pointer values in both d0 and a0. */
#undef FUNCTION_EXTRA_EPILOGUE
-#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
-{ \
- extern int current_function_returns_pointer; \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode))\
- fprintf (FILE, "\tmovel d0,a0\n"); \
+#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
+{ \
+ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ fprintf (FILE, "\tmovel d0,a0\n"); \
}
callers that have neglected to properly declare the callee can
still find the correct return value. */
-extern int current_function_returns_pointer;
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
do { \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
asm_fprintf (FILE, "\tmove.l %Ra0,%Rd0\n"); \
} while (0);
#include "system.h"
#include "tree.h"
#include "rtl.h"
+#include "function.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "real.h"
neglected to properly declare the callee can still find the correct return
value. */
-extern int current_function_returns_pointer;
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
do { \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
asm_fprintf (FILE, "\tmov.l %Ra0,%Rd0\n"); \
} while (0);
#undef FUNCTION_EXTRA_EPILOGUE
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
- { extern int current_function_returns_pointer; \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
- asm_fprintf (FILE, "\tmov.l %Ra0,%Rd0\n"); }
+{ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ asm_fprintf (FILE, "\tmov.l %Ra0,%Rd0\n"); }
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABEL_NO) \
#undef FUNCTION_EXTRA_EPILOGUE
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
- { extern int current_function_returns_pointer; \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+{ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
asm_fprintf (FILE, "\tmovl %Rd0,%Ra0\n"); }
#define ASM_RETURN_CASE_JUMP \
#undef FUNCTION_EXTRA_EPILOGUE
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
- { extern int current_function_returns_pointer; \
- if ((current_function_returns_pointer) && \
- ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
- asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); }
+{ if (current_function_returns_pointer \
+ && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
+ asm_fprintf (FILE, "\tmov.l %Rd0,%Ra0\n"); }
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
#include "output.h"
#include "insn-attr.h"
#include "tree.h"
+#include "function.h"
#include "c-tree.h"
#include "expr.h"
#include "flags.h"
static int epilogue_marked;
static int prologue_marked;
-extern char call_used_regs[];
-extern int current_function_pretend_args_size;
-extern int current_function_outgoing_args_size;
-extern int frame_pointer_needed;
-
#define FIRST_OCS_PRESERVE_REGISTER 14
#define LAST_OCS_PRESERVE_REGISTER 30
extern int target_flags; /* -m compiler switches */
extern int frame_pointer_needed; /* current function has a FP */
-extern int current_function_pretend_args_size; /* args size without ... */
extern int flag_delayed_branch; /* -fdelayed-branch */
extern int flag_pic; /* -fpic */
extern char * reg_names[];
Redefined in sysv4.h, and luna.h. */
#define VERSION_INFO1 "m88k, "
#ifndef VERSION_INFO2
-#define VERSION_INFO2 "$Revision: 1.14 $"
+#define VERSION_INFO2 "$Revision: 1.15 $"
#endif
#ifndef VERSION_STRING
#define VERSION_STRING version_string
#ifdef __STDC__
-#define TM_RCS_ID "@(#)" __FILE__ " $Revision: 1.14 $ " __DATE__
+#define TM_RCS_ID "@(#)" __FILE__ " $Revision: 1.15 $ " __DATE__
#else
#define TM_RCS_ID "$What: <@(#) m88k.h,v 1.1.1.2.2.2> $"
#endif /* __STDC__ */
#include "insn-codes.h"
#include "recog.h"
#include "toplev.h"
-
#include "tree.h"
+#include "function.h"
#include "expr.h"
#include "flags.h"
#include "reload.h"
extern char *asm_file_name;
extern char call_used_regs[];
-extern int current_function_calls_alloca;
extern char *language_string;
extern int may_call_alloca;
extern char **save_argv;
extern int call_address_operand ();
extern enum reg_class secondary_reload_class ();
extern char *emit_a_shift ();
-extern int current_function_needs_context;
extern char *output_tst ();
extern int extendpsi_operand ();
-extern int rtx_equal_function_value_matters;
extern struct rtx_def *zero_dreg;
extern struct rtx_def *zero_areg;
int used_regs_buf[8], *bufp = used_regs_buf; \
int used_fregs_buf[17], *fbufp = used_fregs_buf; \
extern char call_used_regs[]; \
- extern int current_function_uses_pic_offset_table, flag_pic; \
MAIN_FUNCTION_PROLOGUE; \
for (regno = R0_REGNUM; regno < F0_REGNUM; regno++) \
if (regs_ever_live[regno] \
int used_regs_buf[8], *bufp = used_regs_buf; \
int used_fregs_buf[17], *fbufp = used_fregs_buf; \
extern char call_used_regs[]; \
- extern int current_function_uses_pic_offset_table, flag_pic; \
if (flag_pic && current_function_uses_pic_offset_table) \
fprintf (FILE, "\tlprd sb,tos\n"); \
*fbufp++ = -2; \
{ \
int regno; \
int offset = -4; \
- extern int current_function_uses_pic_offset_table, flag_pic; \
for (regno = 0; regno < L1_REGNUM; regno++) \
if (regs_ever_live[regno] && ! call_used_regs[regno]) \
offset += 4; \
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ register rtx xfooy, xfoo0, xfoo1; \
unsigned xfoo2; \
- extern int current_function_uses_pic_offset_table, flag_pic; \
xfooy = X; \
if (flag_pic && ! current_function_uses_pic_offset_table \
&& global_symbolic_reference_mentioned_p (X, 1)) \
when generating PIC code. It is given that flag_pic is on and
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-extern int current_function_uses_pic_offset_table, flag_pic;
#define LEGITIMATE_PIC_OPERAND_P(X) \
(((! current_function_uses_pic_offset_table \
&& symbolic_reference_mentioned_p (X))? \
#include "tree.h"
#include "reload.h"
#include "c-tree.h"
+#include "function.h"
#include "expr.h"
#include "obstack.h"
#include "toplev.h"
int size;
int *fregs_live;
{
- extern int current_function_outgoing_args_size;
int i, fsize;
/* Space for frame pointer + filler. If any frame is allocated
No definition is equivalent to always zero. */
extern int may_call_alloca;
-extern int current_function_pretend_args_size;
#define EXIT_IGNORE_STACK \
(get_frame_size () != 0 \
of alloca; we also take advantage of it to omit stack adjustments
before returning. */
-/* This declaration is needed due to traditional/ANSI
- incompatibilities which cannot be #ifdefed away
- because they occur inside of macros. Sigh. */
-extern union tree_node *current_function_decl;
-
#define FUNCTION_EPILOGUE(FILE, SIZE) \
output_function_epilogue (FILE, SIZE)
tree parm; \
int i; \
if (TREE_PUBLIC (DECL) || TARGET_GAS) \
- { extern int current_function_varargs; \
+ { \
if (TREE_PUBLIC (DECL)) \
{ \
fputs ("\t.EXPORT ", FILE); \
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
+#include "function.h"
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
No definition is equivalent to always zero. */
extern int may_call_alloca;
-extern int current_function_pretend_args_size;
#define EXIT_IGNORE_STACK 1
#include "output.h"
#include "insn-attr.h"
#include "tree.h"
+#include "function.h"
/*
* Do FUNCTION_ARG.
/* This should return non-zero when we really set up a frame pointer.
Otherwise, GCC is directed to preserve sp by returning zero. */
-extern int current_function_pretend_args_size;
-extern int current_function_args_size;
-extern int current_function_calls_alloca;
#define EXIT_IGNORE_STACK \
(get_frame_size () + current_function_pretend_args_size \
+ current_function_args_size != 0 \
#include "expr.h"
#include "obstack.h"
#include "tree.h"
+#include "function.h"
#define min(A,B) ((A) < (B) ? (A) : (B))
#define max(A,B) ((A) > (B) ? (A) : (B))
#include "flags.h"
#include "insn-flags.h"
#include "expr.h"
+#include "function.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "output.h"
NPARM_REGS words is at least partially passed in a register unless
its data type forbids. */
-extern int current_function_varargs;
-
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
&& ((NAMED) \
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "recog.h"
#include "toplev.h"
/* Check if the compiler has recorded some information
about the alignment of the base REG. If reload has
completed, we already matched with proper alignments. */
- if (((regno_pointer_align != NULL
+ if (((current_function != 0
&& REGNO_POINTER_ALIGN (regno) >= desired)
|| reload_completed)
&& ((INTVAL (offset) & (desired - 1)) == 0))
functions that have frame pointers.
No definition is equivalent to always zero. */
-extern int current_function_calls_alloca;
-extern int current_function_outgoing_args_size;
-
#define EXIT_IGNORE_STACK \
(get_frame_size () != 0 \
|| current_function_calls_alloca || current_function_outgoing_args_size)
of alloca; we also take advantage of it to omit stack adjustments
before returning. */
-/* This declaration is needed due to traditional/ANSI
- incompatibilities which cannot be #ifdefed away
- because they occur inside of macros. Sigh. */
-extern union tree_node *current_function_decl;
-
#define FUNCTION_EPILOGUE(FILE, SIZE) \
(TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)SIZE) \
: output_function_epilogue (FILE, (int)SIZE, \
#define FUNCTION_PROLOGUE(FILE, SIZE) \
{ \
extern char call_used_regs[]; \
- extern int current_function_pretend_args_size; \
int fsize = ((SIZE) + 7) & ~7; \
int nregs, i, fp_used = 0; \
for (i = 32, nregs = 0; i < FIRST_PSEUDO_REGISTER; i++) \
functions that have frame pointers.
No definition is equivalent to always zero. */
-extern int current_function_calls_alloca;
-extern int current_function_pretend_args_size;
-
#define EXIT_IGNORE_STACK \
(get_frame_size () != 0 \
|| current_function_calls_alloca || current_function_pretend_args_size)
#define FUNCTION_EPILOGUE(FILE, SIZE) \
{ \
extern char call_used_regs[]; \
- extern int current_function_calls_alloca; \
- extern int current_function_pretend_args_size; \
int fsize = ((SIZE) + 7) & ~7; \
int nregs, i, fp_used = 0; \
for (i = 32, nregs = 0; i < FIRST_PSEUDO_REGISTER; i++) \
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
+#include "function.h"
#include "output.h"
#include "insn-attr.h"
int size;
long *p_reg_saved;
{
- extern int current_function_outgoing_args_size;
-
return (size
+ compute_register_save_size (p_reg_saved)
+ current_function_outgoing_args_size);
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
+#include "function.h"
#include "output.h"
#include "insn-attr.h"
#ifdef VMS_TARGET
* setting of -4 will end up adding them right back again, but don't bother.
*/
#define MAYBE_VMS_FUNCTION_PROLOGUE(FILE) \
-{ extern char *current_function_name; \
- char *p = current_function_name; \
+{ char *p = current_function_name; \
int is_main = strcmp ("main", p) == 0; \
while (!is_main && *p != '\0') \
{ \
#include "config.h"
#include <stdio.h>
#include "rtl.h"
+#include "function.h"
#include "real.h"
+1999-08-09 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * Makefile.in: Update dependencies.
+ * class.c (finish_struct_1): Don't initialize DECL_SAVED_INSNS with
+ NULL_RTX.
+ * decl.c: Include "function.h"
+ (cleanup_label, return_label): Delete declarations.
+ (store_parm_decls): Don't initialize DECL_SAVED_INSNS with NULL_RTX.
+ (finish_function): Rename last_parm_insn variable to
+ fn_last_parm_insn. Don't compare DECL_SAVED_INSNS to NULL_RTX.
+ * decl2.c: Include "function.h".
+ (rtl_expr_chain): Delete declaration.
+ * method.c: Include "function.h"
+ * tree.c (build_vbase_pointer_fields): Don't initialize
+ DECL_SAVED_INSNS with NULL_RTX.
+ * typeck.c: Include "function.h"
+
1999-08-09 Jason Merrill <jason@yorick.cygnus.com>
* semantics.c (begin_function_try_block, finish_function_try_block,
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
- $(srcdir)/../hash.h
+ $(srcdir)/../hash.h $(srcdir)/../function.h
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
- lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
+ lex.h decl.h $(EXPR_H) $(srcdir)/../except.h $(srcdir)/../function.h \
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \
$(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \
$(srcdir)/../../include/splay-tree.h $(srcdir)/../varray.h
typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
- $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
+ $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h \
+ $(srcdir)/../function.h
class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h \
$(srcdir)/../../include/splay-tree.h
friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../system.h $(srcdir)/../toplev.h
init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
- $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
+ $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h \
+ $(srcdir)/../function.h
method.o : method.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
- $(srcdir)/../toplev.h
+ $(srcdir)/../toplev.h $(srcdir)/../function.h
cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \
$(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
if the insn `r' member and the size `i' member are
different sizes, as on the alpha, the larger of the two
will end up with garbage in it. */
- DECL_SAVED_INSNS (x) = NULL_RTX;
+ DECL_SAVED_INSNS (x) = 0;
DECL_FIELD_SIZE (x) = 0;
check_for_override (x, t);
if (type == error_mark_node)
continue;
- DECL_SAVED_INSNS (x) = NULL_RTX;
+ DECL_SAVED_INSNS (x) = 0;
DECL_FIELD_SIZE (x) = 0;
/* When this goes into scope, it will be a non-local reference. */
DECL_FIELD_CONTEXT (vfield) = t;
DECL_CLASS_CONTEXT (vfield) = t;
DECL_FCONTEXT (vfield) = t;
- DECL_SAVED_INSNS (vfield) = NULL_RTX;
+ DECL_SAVED_INSNS (vfield) = 0;
DECL_FIELD_SIZE (vfield) = 0;
DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
#if 0
#include "system.h"
#include "tree.h"
#include "rtl.h"
+#include "function.h"
#include "flags.h"
#include "cp-tree.h"
#include "decl.h"
tree ctor_label;
-extern rtx cleanup_label, return_label;
-
/* If original DECL_RESULT of current function was a register,
but due to being an addressable named return value, would up
on the stack, this variable holds the named return value's
declare_function_name ();
/* Initialize the RTL code for the function. */
- DECL_SAVED_INSNS (fndecl) = NULL_RTX;
+ DECL_SAVED_INSNS (fndecl) = 0;
if (! processing_template_decl)
expand_function_start (fndecl, parms_have_cleanups);
{
register tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
- rtx last_parm_insn, insns;
+ rtx fn_last_parm_insn, insns;
/* Label to use if this function is supposed to return a value. */
tree no_return_label = NULL_TREE;
tree decls = NULL_TREE;
insns = get_insns ();
end_sequence ();
- last_parm_insn = get_first_nonparm_insn ();
- if (last_parm_insn == NULL_RTX)
- last_parm_insn = get_last_insn ();
+ fn_last_parm_insn = get_first_nonparm_insn ();
+ if (fn_last_parm_insn == NULL_RTX)
+ fn_last_parm_insn = get_last_insn ();
else
- last_parm_insn = previous_insn (last_parm_insn);
+ fn_last_parm_insn = previous_insn (fn_last_parm_insn);
- emit_insns_after (insns, last_parm_insn);
+ emit_insns_after (insns, fn_last_parm_insn);
if (! ok_to_optimize_dtor)
expand_end_cond ();
if (! nested)
permanent_allocation (1);
- if (DECL_SAVED_INSNS (fndecl) == NULL_RTX)
+ if (DECL_SAVED_INSNS (fndecl) == 0)
{
tree t;
#include "lex.h"
#include "output.h"
#include "except.h"
+#include "function.h"
#include "expr.h"
#include "defaults.h"
#include "toplev.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
+#include "function.h"
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
Note that emit_base_init does *not* initialize virtual base
classes. That is done specially, elsewhere. */
-extern tree base_init_expr, rtl_expr_chain;
+extern tree base_init_expr;
void
emit_base_init (t, immediately)
#include "obstack.h"
#include "rtl.h"
#include "expr.h"
+#include "function.h"
#include "output.h"
#include "hard-reg-set.h"
#include "flags.h"
DECL_FIELD_CONTEXT (decl) = rec;
DECL_CLASS_CONTEXT (decl) = rec;
DECL_FCONTEXT (decl) = basetype;
- DECL_SAVED_INSNS (decl) = NULL_RTX;
+ DECL_SAVED_INSNS (decl) = 0;
DECL_FIELD_SIZE (decl) = 0;
DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node);
TREE_CHAIN (decl) = vbase_decls;
#include "flags.h"
#include "output.h"
#include "expr.h"
+#include "function.h"
#include "toplev.h"
#include "defaults.h"
#include "real.h"
#include "insn-config.h"
#include "recog.h"
+#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "output.h"
enum machine_mode double_mode; /* Mode whose width is DOUBLE_TYPE_SIZE. */
enum machine_mode ptr_mode; /* Mode whose width is POINTER_SIZE. */
-/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
- After rtl generation, it is 1 plus the largest register number used. */
-
-int reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
/* This is *not* reset after each function. It gives each CODE_LABEL
in the entire compilation a unique label number. */
static int label_num = 1;
-/* Lowest label number in current function. */
-
-static int first_label_num;
-
/* Highest label number in current function.
Zero means use the value of label_num instead.
This is nonzero only when belatedly compiling an inline function. */
struct rtx_def const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
-/* The ends of the doubly-linked chain of rtl for the current function.
- Both are reset to null at the start of rtl generation for the function.
-
- start_sequence saves both of these on `sequence_stack' along with
- `sequence_rtl_expr' and then starts a new, nested sequence of insns. */
-
-static rtx first_insn = NULL;
-static rtx last_insn = NULL;
-
-/* RTL_EXPR within which the current sequence will be placed. Use to
- prevent reuse of any temporaries within the sequence until after the
- RTL_EXPR is emitted. */
-
-tree sequence_rtl_expr = NULL;
-
-/* INSN_UID for next insn emitted.
- Reset to 1 for each function compiled. */
-
-static int cur_insn_uid = 1;
-
-/* Line number and source file of the last line-number NOTE emitted.
- This is used to avoid generating duplicates. */
-
-static int last_linenum = 0;
-static char *last_filename = 0;
-
-/* A vector indexed by pseudo reg number. The allocated length
- of this vector is regno_pointer_flag_length. Since this
- vector is needed during the expansion phase when the total
- number of registers in the function is not yet known,
- it is copied and made bigger when necessary. */
-
-char *regno_pointer_flag;
-int regno_pointer_flag_length;
-
-/* Indexed by pseudo register number, if nonzero gives the known alignment
- for that pseudo (if regno_pointer_flag is set).
- Allocated in parallel with regno_pointer_flag. */
-char *regno_pointer_align;
-
-/* Indexed by pseudo register number, gives the rtx for that pseudo.
- Allocated in parallel with regno_pointer_flag. */
-
-rtx *regno_reg_rtx;
-
-/* Stack of pending (incomplete) sequences saved by `start_sequence'.
- Each element describes one pending sequence.
- The main insn-chain is saved in the last element of the chain,
- unless the chain is empty. */
-
-struct sequence_stack *sequence_stack;
-
/* start_sequence and gen_sequence can make a lot of rtx expressions which are
shortly thrown away. We use two mechanisms to prevent this waste:
/* During RTL generation, we also keep a list of free INSN rtl codes. */
static rtx free_insn;
-extern int rtx_equal_function_value_matters;
+#define first_insn (current_function->emit->x_first_insn)
+#define last_insn (current_function->emit->x_last_insn)
+#define cur_insn_uid (current_function->emit->x_cur_insn_uid)
+#define last_linenum (current_function->emit->x_last_linenum)
+#define last_filename (current_function->emit->x_last_filename)
+#define first_label_num (current_function->emit->x_first_label_num)
-/* Filename and line number of last line-number note,
- whether we actually emitted it or not. */
-extern char *emit_filename;
-extern int emit_lineno;
+extern int rtx_equal_function_value_matters;
static rtx make_jump_insn_raw PROTO((rtx));
static rtx make_call_insn_raw PROTO((rtx));
gen_reg_rtx (mode)
enum machine_mode mode;
{
+ struct function *f = current_function;
register rtx val;
/* Don't let anything called after initial flow analysis create new
/* Make sure regno_pointer_flag and regno_reg_rtx are large
enough to have an element for this pseudo reg number. */
- if (reg_rtx_no == regno_pointer_flag_length)
+ if (reg_rtx_no == f->emit->regno_pointer_flag_length)
{
+ int old_size = f->emit->regno_pointer_flag_length;
rtx *new1;
- char *new =
- (char *) savealloc (regno_pointer_flag_length * 2);
- bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
- bzero (&new[regno_pointer_flag_length], regno_pointer_flag_length);
- regno_pointer_flag = new;
-
- new = (char *) savealloc (regno_pointer_flag_length * 2);
- bcopy (regno_pointer_align, new, regno_pointer_flag_length);
- bzero (&new[regno_pointer_flag_length], regno_pointer_flag_length);
- regno_pointer_align = new;
-
- new1 = (rtx *) savealloc (regno_pointer_flag_length * 2 * sizeof (rtx));
- bcopy ((char *) regno_reg_rtx, (char *) new1,
- regno_pointer_flag_length * sizeof (rtx));
- bzero ((char *) &new1[regno_pointer_flag_length],
- regno_pointer_flag_length * sizeof (rtx));
+ char *new = (char *) savealloc (old_size * 2);
+ memcpy (new, f->emit->regno_pointer_flag, old_size);
+ memset (new + old_size, 0, old_size);
+ f->emit->regno_pointer_flag = new;
+
+ new = (char *) savealloc (old_size * 2);
+ memcpy (new, f->emit->regno_pointer_align, old_size);
+ memset (new + old_size, 0, old_size);
+ f->emit->regno_pointer_align = new;
+
+ new1 = (rtx *) savealloc (old_size * 2 * sizeof (rtx));
+ memcpy (new1, regno_reg_rtx, old_size * sizeof (rtx));
+ memset (new1 + old_size, 0, old_size * sizeof (rtx));
regno_reg_rtx = new1;
- regno_pointer_flag_length *= 2;
+ f->emit->regno_pointer_flag_length = old_size * 2;
}
val = gen_rtx_raw_REG (mode, reg_rtx_no);
\f
/* For procedure integration. */
-/* Return a newly created INLINE_HEADER rtx. Should allocate this
- from a permanent obstack when the opportunity arises. */
-
-rtx
-gen_inline_header_rtx (first_insn, first_parm_insn, first_labelno,
- last_labelno, max_parm_regnum, max_regnum, args_size,
- pops_args, stack_slots, forced_labels, function_flags,
- outgoing_args_size, original_arg_vector,
- original_decl_initial, regno_rtx, regno_flag,
- regno_align, parm_reg_stack_loc)
- rtx first_insn, first_parm_insn;
- int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size;
- int pops_args;
- rtx stack_slots;
- rtx forced_labels;
- int function_flags;
- int outgoing_args_size;
- rtvec original_arg_vector;
- rtx original_decl_initial;
- rtvec regno_rtx;
- char *regno_flag;
- char *regno_align;
- rtvec parm_reg_stack_loc;
-{
- rtx header = gen_rtx_INLINE_HEADER (VOIDmode,
- cur_insn_uid++, NULL_RTX,
- first_insn, first_parm_insn,
- first_labelno, last_labelno,
- max_parm_regnum, max_regnum, args_size,
- pops_args, stack_slots, forced_labels,
- function_flags, outgoing_args_size,
- original_arg_vector,
- original_decl_initial,
- regno_rtx, regno_flag, regno_align,
- parm_reg_stack_loc);
- return header;
-}
-
/* Install new pointers to the first and last insns in the chain.
Also, set cur_insn_uid to one higher than the last in use.
Used for an inline-procedure after copying the insn chain. */
first_label_num = first;
last_label_num = last;
}
-\f
-/* Save all variables describing the current status into the structure *P.
- This is used before starting a nested function. */
+
+/* Set the last label number found in the current function.
+ This is used when belatedly compiling an inline function. */
void
-save_emit_status (p)
- struct function *p;
+set_new_last_label_num (last)
+ int last;
{
- p->reg_rtx_no = reg_rtx_no;
- p->first_label_num = first_label_num;
- p->first_insn = first_insn;
- p->last_insn = last_insn;
- p->sequence_rtl_expr = sequence_rtl_expr;
- p->sequence_stack = sequence_stack;
- p->cur_insn_uid = cur_insn_uid;
- p->last_linenum = last_linenum;
- p->last_filename = last_filename;
- p->regno_pointer_flag = regno_pointer_flag;
- p->regno_pointer_align = regno_pointer_align;
- p->regno_pointer_flag_length = regno_pointer_flag_length;
- p->regno_reg_rtx = regno_reg_rtx;
+ base_label_num = label_num;
+ last_label_num = last;
}
-
+\f
/* Restore all variables describing the current status from the structure *P.
This is used after a nested function. */
restore_emit_status (p)
struct function *p;
{
- int i;
-
- reg_rtx_no = p->reg_rtx_no;
- first_label_num = p->first_label_num;
last_label_num = 0;
- first_insn = p->first_insn;
- last_insn = p->last_insn;
- sequence_rtl_expr = p->sequence_rtl_expr;
- sequence_stack = p->sequence_stack;
- cur_insn_uid = p->cur_insn_uid;
- last_linenum = p->last_linenum;
- last_filename = p->last_filename;
- regno_pointer_flag = p->regno_pointer_flag;
- regno_pointer_align = p->regno_pointer_align;
- regno_pointer_flag_length = p->regno_pointer_flag_length;
- regno_reg_rtx = p->regno_reg_rtx;
-
- /* Clear our cache of rtx expressions for start_sequence and
- gen_sequence. */
- sequence_element_free_list = 0;
- for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
- sequence_result[i] = 0;
-
- free_insn = 0;
+ clear_emit_caches ();
}
\f
/* Go through all the RTL insn bodies and copy any invalid shared structure.
struct sequence_stack *stack;
if (last_insn)
return last_insn;
- for (stack = sequence_stack; stack; stack = stack->next)
+ for (stack = seq_stack; stack; stack = stack->next)
if (stack->last != 0)
return stack->last;
return 0;
last_insn = insn;
else
{
- struct sequence_stack *stack = sequence_stack;
+ struct sequence_stack *stack = seq_stack;
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
if (after == stack->last)
first_insn = insn;
else
{
- struct sequence_stack *stack = sequence_stack;
+ struct sequence_stack *stack = seq_stack;
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
if (before == stack->first)
first_insn = next;
else
{
- struct sequence_stack *stack = sequence_stack;
+ struct sequence_stack *stack = seq_stack;
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
if (insn == stack->first)
last_insn = prev;
else
{
- struct sequence_stack *stack = sequence_stack;
+ struct sequence_stack *stack = seq_stack;
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
if (insn == stack->last)
else
tem = (struct sequence_stack *) permalloc (sizeof (struct sequence_stack));
- tem->next = sequence_stack;
+ tem->next = seq_stack;
tem->first = first_insn;
tem->last = last_insn;
- tem->sequence_rtl_expr = sequence_rtl_expr;
+ tem->sequence_rtl_expr = seq_rtl_expr;
- sequence_stack = tem;
+ seq_stack = tem;
first_insn = 0;
last_insn = 0;
{
start_sequence ();
- sequence_rtl_expr = t;
+ seq_rtl_expr = t;
}
/* Set up the insn chain starting with FIRST as the current sequence,
start_sequence ();
- for (stack = sequence_stack; stack; stack = stack->next)
+ for (stack = seq_stack; stack; stack = stack->next)
top = stack;
first_insn = top->first;
last_insn = top->last;
- sequence_rtl_expr = top->sequence_rtl_expr;
+ seq_rtl_expr = top->sequence_rtl_expr;
}
/* After emitting to the outer-level insn chain, update the outer-level
{
struct sequence_stack *stack, *top = NULL;
- for (stack = sequence_stack; stack; stack = stack->next)
+ for (stack = seq_stack; stack; stack = stack->next)
top = stack;
top->first = first_insn;
top->last = last_insn;
- /* ??? Why don't we save sequence_rtl_expr here? */
+ /* ??? Why don't we save seq_rtl_expr here? */
end_sequence ();
}
void
end_sequence ()
{
- struct sequence_stack *tem = sequence_stack;
+ struct sequence_stack *tem = seq_stack;
first_insn = tem->first;
last_insn = tem->last;
- sequence_rtl_expr = tem->sequence_rtl_expr;
- sequence_stack = tem->next;
+ seq_rtl_expr = tem->sequence_rtl_expr;
+ seq_stack = tem->next;
tem->next = sequence_element_free_list;
sequence_element_free_list = tem;
int
in_sequence_p ()
{
- return sequence_stack != 0;
+ return seq_stack != 0;
}
/* Generate a SEQUENCE rtx containing the insns already emitted
/* Put the various virtual registers into REGNO_REG_RTX. */
void
-init_virtual_regs ()
+init_virtual_regs (es)
+ struct emit_status *es;
{
- regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
- regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
- regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
- regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
- regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
+ rtx *ptr = es->x_regno_reg_rtx;
+ ptr[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
+ ptr[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
+ ptr[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
+ ptr[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
+ ptr[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
+}
+
+void
+clear_emit_caches ()
+{
+ int i;
+
+ /* Clear the start_sequence/gen_sequence cache. */
+ sequence_element_free_list = 0;
+ for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
+ sequence_result[i] = 0;
+ free_insn = 0;
}
/* Initialize data structures and variables in this file
void
init_emit ()
{
- int i;
+ struct function *f = current_function;
+ f->emit = (struct emit_status *) xmalloc (sizeof (struct emit_status));
first_insn = NULL;
last_insn = NULL;
- sequence_rtl_expr = NULL;
+ seq_rtl_expr = NULL;
cur_insn_uid = 1;
reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
last_linenum = 0;
last_filename = 0;
first_label_num = label_num;
last_label_num = 0;
- sequence_stack = NULL;
+ seq_stack = NULL;
- /* Clear the start_sequence/gen_sequence cache. */
- sequence_element_free_list = 0;
- for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
- sequence_result[i] = 0;
- free_insn = 0;
+ clear_emit_caches ();
/* Init the tables that describe all the pseudo regs. */
- regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101;
+ f->emit->regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101;
- regno_pointer_flag
- = (char *) savealloc (regno_pointer_flag_length);
- bzero (regno_pointer_flag, regno_pointer_flag_length);
+ f->emit->regno_pointer_flag
+ = (char *) savealloc (f->emit->regno_pointer_flag_length);
+ bzero (f->emit->regno_pointer_flag, f->emit->regno_pointer_flag_length);
- regno_pointer_align
- = (char *) savealloc (regno_pointer_flag_length);
- bzero (regno_pointer_align, regno_pointer_flag_length);
+ f->emit->regno_pointer_align
+ = (char *) savealloc (f->emit->regno_pointer_flag_length);
+ bzero (f->emit->regno_pointer_align, f->emit->regno_pointer_flag_length);
regno_reg_rtx
- = (rtx *) savealloc (regno_pointer_flag_length * sizeof (rtx));
- bzero ((char *) regno_reg_rtx, regno_pointer_flag_length * sizeof (rtx));
+ = (rtx *) savealloc (f->emit->regno_pointer_flag_length * sizeof (rtx));
+ bzero ((char *) regno_reg_rtx,
+ f->emit->regno_pointer_flag_length * sizeof (rtx));
/* Put copies of all the virtual register rtx into regno_reg_rtx. */
- init_virtual_regs ();
+ init_virtual_regs (f->emit);
/* Indicate that the virtual registers and stack locations are
all pointers. */
no_line_numbers = ! line_numbers;
- sequence_stack = NULL;
-
/* Compute the word and byte modes. */
byte_mode = VOIDmode;
#include "rtl.h"
#include "tree.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "hard-reg-set.h"
#include "insn-config.h"
Nowadays this is never zero. */
int do_preexpand_calls = 1;
-/* Number of units that we should eventually pop off the stack.
- These are the arguments to function calls that have already returned. */
-int pending_stack_adjust;
-
-/* Under some ABIs, it is the caller's responsibility to pop arguments
- pushed for function calls. A naive implementation would simply pop
- the arguments immediately after each call. However, if several
- function calls are made in a row, it is typically cheaper to pop
- all the arguments after all of the calls are complete since a
- single pop instruction can be used. Therefore, GCC attempts to
- defer popping the arguments until absolutely necessary. (For
- example, at the end of a conditional, the arguments must be popped,
- since code outside the conditional won't know whether or not the
- arguments need to be popped.)
-
- When INHIBIT_DEFER_POP is non-zero, however, the compiler does not
- attempt to defer pops. Instead, the stack is popped immediately
- after each call. Rather then setting this variable directly, use
- NO_DEFER_POP and OK_DEFER_POP. */
-int inhibit_defer_pop;
-
/* Don't check memory usage, since code is being emitted to check a memory
usage. Used when current_function_check_memory_usage is true, to avoid
infinite recursion. */
static int in_check_memory_usage;
-/* Postincrements that still need to be expanded. */
-static rtx pending_chain;
-
/* This structure is used by move_by_pieces to describe the move to
be performed. */
struct move_by_pieces
};
extern struct obstack permanent_obstack;
-extern rtx arg_pointer_save_area;
static rtx get_push_address PROTO ((int));
static rtx enqueue_insn PROTO((rtx, rtx));
-static void init_queue PROTO((void));
static int move_by_pieces_ninsns PROTO((unsigned int, int));
static void move_by_pieces_1 PROTO((rtx (*) (rtx, ...), enum machine_mode,
struct move_by_pieces *));
void
init_expr ()
{
- init_queue ();
+ current_function->expr
+ = (struct expr_status *) xmalloc (sizeof (struct expr_status));
+ pending_chain = 0;
pending_stack_adjust = 0;
inhibit_defer_pop = 0;
saveregs_value = 0;
forced_labels = 0;
}
-/* Save all variables describing the current status into the structure *P.
- This is used before starting a nested function. */
-
+/* Small sanity check that the queue is empty at the end of a function. */
void
-save_expr_status (p)
- struct function *p;
+finish_expr_for_function ()
{
- p->pending_chain = pending_chain;
- p->pending_stack_adjust = pending_stack_adjust;
- p->inhibit_defer_pop = inhibit_defer_pop;
- p->saveregs_value = saveregs_value;
- p->apply_args_value = apply_args_value;
- p->forced_labels = forced_labels;
-
- pending_chain = NULL_RTX;
- pending_stack_adjust = 0;
- inhibit_defer_pop = 0;
- saveregs_value = 0;
- apply_args_value = 0;
- forced_labels = 0;
-}
-
-/* Restore all variables describing the current status from the structure *P.
- This is used after a nested function. */
-
-void
-restore_expr_status (p)
- struct function *p;
-{
- pending_chain = p->pending_chain;
- pending_stack_adjust = p->pending_stack_adjust;
- inhibit_defer_pop = p->inhibit_defer_pop;
- saveregs_value = p->saveregs_value;
- apply_args_value = p->apply_args_value;
- forced_labels = p->forced_labels;
+ if (pending_chain)
+ abort ();
}
\f
/* Manage the queue of increment instructions to be output
pending_chain = QUEUED_NEXT (p);
}
}
-
-static void
-init_queue ()
-{
- if (pending_chain)
- abort ();
-}
\f
/* Copy data from FROM to TO, where the machine modes are not the same.
Both modes may be integer, or both may be floating.
push_obstacks (p->function_obstack,
p->function_maybepermanent_obstack);
- p->forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
- label_rtx (exp),
- p->forced_labels);
+ p->expr->x_forced_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, label_rtx (exp),
+ p->expr->x_forced_labels);
pop_obstacks ();
}
else
memory protection).
Aggregates are not checked here; they're handled elsewhere. */
- if (current_function_check_memory_usage && code == VAR_DECL
+ if (current_function && current_function_check_memory_usage
+ && code == VAR_DECL
&& GET_CODE (DECL_RTL (exp)) == MEM
&& ! AGGREGATE_TYPE_P (TREE_TYPE (exp)))
{
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
- if (current_function_check_memory_usage && !AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ if (current_function && current_function_check_memory_usage
+ && ! AGGREGATE_TYPE_P (TREE_TYPE (exp)))
{
enum memory_use_mode memory_usage;
memory_usage = get_memory_usage_from_modifier (modifier);
}
/* Check the access. */
- if (current_function_check_memory_usage && GET_CODE (op0) == MEM)
+ if (current_function && current_function_check_memory_usage
+ && GET_CODE (op0) == MEM)
{
enum memory_use_mode memory_usage;
memory_usage = get_memory_usage_from_modifier (modifier);
MEMORY_USE_WO = 2, MEMORY_USE_RW = 3,
MEMORY_USE_TW = 6, MEMORY_USE_DONT = 99};
-/* List of labels that must never be deleted. */
-extern rtx forced_labels;
-
-/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
- So we can mark them all live at the end of the function, if stupid. */
-extern rtx save_expr_regs;
-
-/* Nonzero means __builtin_saveregs has already been done in this function.
- The value is the pseudoreg containing the value __builtin_saveregs
- returned. */
-extern rtx saveregs_value;
-
-/* Similarly for __builtin_apply_args. */
-extern rtx apply_args_value;
-
-extern int current_function_calls_alloca;
-extern int current_function_outgoing_args_size;
-
-/* This is the offset from the arg pointer to the place where the first
- anonymous arg can be found, if there is one. */
-extern rtx current_function_arg_offset_rtx;
-
-/* This is nonzero if the current function uses the constant pool. */
-extern int current_function_uses_const_pool;
-
-/* This is nonzero if the current function uses pic_offset_table_rtx. */
-extern int current_function_uses_pic_offset_table;
-
-/* The arg pointer hard register, or the pseudo into which it was copied. */
-extern rtx current_function_internal_arg_pointer;
-
-/* This is nonzero if memory access checking be enabled in the current
- function. */
-extern int current_function_check_memory_usage;
-
-/* Under some ABIs, it is the caller's responsibility to pop arguments
- pushed for function calls. A naive implementation would simply pop
- the arguments immediately after each call. However, if several
- function calls are made in a row, it is typically cheaper to pop
- all the arguments after all of the calls are complete since a
- single pop instruction can be used. Therefore, GCC attempts to
- defer popping the arguments until absolutely necessary. (For
- example, at the end of a conditional, the arguments must be popped,
- since code outside the conditional won't know whether or not the
- arguments need to be popped.)
-
- When INHIBIT_DEFER_POP is non-zero, however, the compiler does not
- attempt to defer pops. Instead, the stack is popped immediately
- after each call. Rather then setting this variable directly, use
- NO_DEFER_POP and OK_DEFER_POP. */
-extern int inhibit_defer_pop;
-
/* Prevent the compiler from deferring stack pops. See
inhibit_defer_pop for more information. */
#define NO_DEFER_POP (inhibit_defer_pop += 1)
/* Allow the compiler to defer stack pops. See inhibit_defer_pop for
more information. */
#define OK_DEFER_POP (inhibit_defer_pop -= 1)
-
-/* Number of function calls seen so far in current function. */
-
-extern int function_call_count;
-
-/* List (chain of EXPR_LIST) of stack slots that hold the current handlers
- for nonlocal gotos. There is one for every nonlocal label in the function;
- this list matches the one in nonlocal_labels.
- Zero when function does not have nonlocal labels. */
-
-extern rtx nonlocal_goto_handler_slots;
-
-/* RTX for stack slot that holds the stack pointer value to restore
- for a nonlocal goto.
- Zero when function does not have nonlocal labels. */
-
-extern rtx nonlocal_goto_stack_level;
-
-/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
- (labels to which there can be nonlocal gotos from nested functions)
- in this function. */
-
-#ifdef TREE_CODE /* Don't lose if tree.h not included. */
-extern tree nonlocal_labels;
-#endif
-
-/* Number of units that we should eventually pop off the stack.
- These are the arguments to function calls that have already returned. */
-extern int pending_stack_adjust;
-
-/* When temporaries are created by TARGET_EXPRs, they are created at
- this level of temp_slot_level, so that they can remain allocated
- until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
- of TARGET_EXPRs. */
-extern int target_temp_slot_level;
-
-/* Current level for normal temporaries. */
-
-extern int temp_slot_level;
\f
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
/* Structure to record the size of a sequence of arguments
/* This is run at the start of compiling a function. */
extern void init_expr PROTO((void));
+/* This is run at the end of compiling a function. */
+extern void finish_expr_for_function PROTO((void));
+
/* Use protect_from_queue to convert a QUEUED expression
into something that you can put immediately into an instruction. */
extern rtx protect_from_queue PROTO((rtx, int));
#include "defaults.h"
#include "output.h"
#include "except.h"
+#include "function.h"
#include "toplev.h"
#include "reload.h"
#include "intl.h"
extern int can_reach_end;
-/* Nonzero if function being compiled receives nonlocal gotos
- from nested functions. */
-
-extern int current_function_has_nonlocal_label;
-
-/* Nonzero if function being compiled has nonlocal gotos to parent
- function. */
-
-extern int current_function_has_nonlocal_goto;
-
-/* Nonzero if this function has a computed goto.
-
- It is computed during find_basic_blocks or during stupid life
- analysis. */
-
-extern int current_function_has_computed_jump;
-
/* Nonzero if GCC must add code to check memory access (used by Checker). */
extern int flag_check_memory_usage;
flag_check_memory_usage). */
extern int flag_prefix_function_name;
-/* Nonzero if the current function is a thunk, so we should try to cut
- corners where we can. */
-extern int current_function_is_thunk;
/* Value of the -G xx switch, and whether it was passed or not. */
extern int g_switch_value;
extern struct obstack *function_obstack;
-/* List of labels that must never be deleted. */
-extern rtx forced_labels;
-
/* Number of basic blocks in the current function. */
int n_basic_blocks;
#define NEED_SEPARATE_AP
#endif
-/* Number of bytes of args popped by function being compiled on its return.
- Zero if no bytes are to be popped.
- May affect compilation of return insn or of function epilogue. */
-
-int current_function_pops_args;
-
-/* Nonzero if function being compiled needs to be given an address
- where the value should be stored. */
-
-int current_function_returns_struct;
-
-/* Nonzero if function being compiled needs to
- return the address of where it has put a structure value. */
-
-int current_function_returns_pcc_struct;
-
-/* Nonzero if function being compiled needs to be passed a static chain. */
-
-int current_function_needs_context;
-
-/* Nonzero if function being compiled can call setjmp. */
-
-int current_function_calls_setjmp;
-
-/* Nonzero if function being compiled can call longjmp. */
-
-int current_function_calls_longjmp;
-
-/* Nonzero if function being compiled receives nonlocal gotos
- from nested functions. */
-
-int current_function_has_nonlocal_label;
-
-/* Nonzero if function being compiled has nonlocal gotos to parent
- function. */
-
-int current_function_has_nonlocal_goto;
-
-/* Nonzero if function being compiled contains nested functions. */
-
-int current_function_contains_functions;
-
/* Nonzero if function being compiled doesn't contain any calls
(ignoring the prologue and epilogue). This is set prior to
local register allocation and is valid for the remaining
compiler passes. */
-
int current_function_is_leaf;
/* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */
-
int current_function_sp_is_unchanging;
/* Nonzero if the function being compiled is a leaf function which only
uses leaf registers. This is valid after reload (specifically after
sched2) and is useful only if the port defines LEAF_REGISTERS. */
-
int current_function_uses_only_leaf_regs;
-/* Nonzero if the function being compiled issues a computed jump. */
-
-int current_function_has_computed_jump;
-
-/* Nonzero if the current function is a thunk (a lightweight function that
- just adjusts one of its arguments and forwards to another function), so
- we should try to cut corners where we can. */
-int current_function_is_thunk;
-
-/* Nonzero if function being compiled can call alloca,
- either as a subroutine or builtin. */
-
-int current_function_calls_alloca;
-
-/* Nonzero if the current function returns a pointer type */
-
-int current_function_returns_pointer;
-
-/* If some insns can be deferred to the delay slots of the epilogue, the
- delay list for them is recorded here. */
-
-rtx current_function_epilogue_delay_list;
-
-/* If function's args have a fixed size, this is that size, in bytes.
- Otherwise, it is -1.
- May affect compilation of return insn or of function epilogue. */
-
-int current_function_args_size;
-
-/* # bytes the prologue should push and pretend that the caller pushed them.
- The prologue must do this, but only if parms can be passed in registers. */
-
-int current_function_pretend_args_size;
-
-/* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
- defined, the needed space is pushed by the prologue. */
-
-int current_function_outgoing_args_size;
-
-/* This is the offset from the arg pointer to the place where the first
- anonymous arg can be found, if there is one. */
-
-rtx current_function_arg_offset_rtx;
-
-/* Nonzero if current function uses varargs.h or equivalent.
- Zero for functions that use stdarg.h. */
-
-int current_function_varargs;
-
-/* Nonzero if current function uses stdarg.h or equivalent.
- Zero for functions that use varargs.h. */
-
-int current_function_stdarg;
-
-/* Quantities of various kinds of registers
- used for the current function's args. */
-
-CUMULATIVE_ARGS current_function_args_info;
-
-/* Name of function now being compiled. */
-
-char *current_function_name;
-
-/* If non-zero, an RTL expression for the location at which the current
- function returns its result. If the current function returns its
- result in a register, current_function_return_rtx will always be
- the hard register containing the result. */
-
-rtx current_function_return_rtx;
-
-/* Nonzero if the current function uses the constant pool. */
-
-int current_function_uses_const_pool;
-
-/* Nonzero if the current function uses pic_offset_table_rtx. */
-int current_function_uses_pic_offset_table;
-
-/* The arg pointer hard register, or the pseudo into which it was copied. */
-rtx current_function_internal_arg_pointer;
-
-/* Language-specific reason why the current function cannot be made inline. */
-char *current_function_cannot_inline;
-
-/* Nonzero if instrumentation calls for function entry and exit should be
- generated. */
-int current_function_instrument_entry_exit;
-
-/* Nonzero if memory access checking be enabled in the current function. */
-int current_function_check_memory_usage;
-
-/* The FUNCTION_DECL for an inline function currently being expanded. */
-tree inline_function_decl;
-
-/* Number of function calls seen so far in current function. */
-
-int function_call_count;
-
-/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
- (labels to which there can be nonlocal gotos from nested functions)
- in this function. */
-
-tree nonlocal_labels;
-
-/* List (chain of EXPR_LIST) of stack slots that hold the current handlers
- for nonlocal gotos. There is one for every nonlocal label in the function;
- this list matches the one in nonlocal_labels.
- Zero when function does not have nonlocal labels. */
-
-rtx nonlocal_goto_handler_slots;
-
-/* List (chain of EXPR_LIST) of labels heading the current handlers for
- nonlocal gotos. */
-
-rtx nonlocal_goto_handler_labels;
-
-/* RTX for stack slot that holds the stack pointer value to restore
- for a nonlocal goto.
- Zero when function does not have nonlocal labels. */
-
-rtx nonlocal_goto_stack_level;
-
-/* Label that will go on parm cleanup code, if any.
- Jumping to this label runs cleanup code for parameters, if
- such code must be run. Following this code is the logical return label. */
-
-rtx cleanup_label;
-
-/* Label that will go on function epilogue.
- Jumping to this label serves as a "return" instruction
- on machines which require execution of the epilogue on all returns. */
-
-rtx return_label;
-
-/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
- So we can mark them all live at the end of the function, if nonopt. */
-rtx save_expr_regs;
-
-/* List (chain of EXPR_LISTs) of all stack slots in this function.
- Made for the sake of unshare_all_rtl. */
-rtx stack_slot_list;
-
-/* Chain of all RTL_EXPRs that have insns in them. */
-tree rtl_expr_chain;
-
-/* Label to jump back to for tail recursion, or 0 if we have
- not yet needed one for this function. */
-rtx tail_recursion_label;
-
-/* Place after which to insert the tail_recursion_label if we need one. */
-rtx tail_recursion_reentry;
-
-/* Location at which to save the argument pointer if it will need to be
- referenced. There are two cases where this is done: if nonlocal gotos
- exist, or if vars stored at an offset from the argument pointer will be
- needed by inner routines. */
-
-rtx arg_pointer_save_area;
-
-/* Offset to end of allocated area of stack frame.
- If stack grows down, this is the address of the last stack slot allocated.
- If stack grows up, this is the address for the next slot. */
-HOST_WIDE_INT frame_offset;
-
-/* List (chain of TREE_LISTs) of static chains for containing functions.
- Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
- in an RTL_EXPR in the TREE_VALUE. */
-static tree context_display;
-
-/* List (chain of TREE_LISTs) of trampolines for nested functions.
- The trampoline sets up the static chain and jumps to the function.
- We supply the trampoline's address when the function's address is requested.
-
- Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
- in an RTL_EXPR in the TREE_VALUE. */
-static tree trampoline_list;
-
-/* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
-static rtx parm_birth_insn;
-
-#if 0
-/* Nonzero if a stack slot has been generated whose address is not
- actually valid. It means that the generated rtl must all be scanned
- to detect and correct the invalid addresses where they occur. */
-static int invalid_stack_slot;
-#endif
-
-/* Last insn of those whose job was to put parms into their nominal homes. */
-static rtx last_parm_insn;
-
-/* 1 + last pseudo register number possibly used for loading a copy
- of a parameter of this function. */
-int max_parm_reg;
-
-/* Vector indexed by REGNO, containing location on stack in which
- to put the parm which is nominally in pseudo register REGNO,
- if we discover that that parm must go in the stack. The highest
- element in this vector is one less than MAX_PARM_REG, above. */
-rtx *parm_reg_stack_loc;
-
/* Nonzero once virtual register instantiation has been done.
assign_stack_local uses frame_pointer_rtx when this is nonzero. */
static int virtuals_instantiated;
integrate.c */
extern int rtx_equal_function_value_matters;
-extern tree sequence_rtl_expr;
+
+/* The FUNCTION_DECL for an inline function currently being expanded. */
+tree inline_function_decl;
/* The currently compiled function. */
struct function *current_function = 0;
info is for combine_temp_slots. */
HOST_WIDE_INT full_size;
};
-
-/* List of all temporaries allocated, both available and in use. */
-
-struct temp_slot *temp_slots;
-
-/* Current nesting level for temporaries. */
-
-int temp_slot_level;
-
-/* Current nesting level for variables in a block. */
-
-int var_temp_slot_level;
-
-/* When temporaries are created by TARGET_EXPRs, they are created at
- this level of temp_slot_level, so that they can remain allocated
- until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
- of TARGET_EXPRs. */
-int target_temp_slot_level;
\f
/* This structure is used to record MEMs or pseudos used to replace VAR, any
SUBREGs of VAR, and any MEMs containing VAR as an address. We need to
p->next = outer_function_chain;
outer_function_chain = p;
-
- p->name = current_function_name;
p->decl = current_function_decl;
- p->pops_args = current_function_pops_args;
- p->returns_struct = current_function_returns_struct;
- p->returns_pcc_struct = current_function_returns_pcc_struct;
- p->returns_pointer = current_function_returns_pointer;
- p->needs_context = current_function_needs_context;
- p->calls_setjmp = current_function_calls_setjmp;
- p->calls_longjmp = current_function_calls_longjmp;
- p->calls_alloca = current_function_calls_alloca;
- p->has_nonlocal_label = current_function_has_nonlocal_label;
- p->has_nonlocal_goto = current_function_has_nonlocal_goto;
- p->contains_functions = current_function_contains_functions;
- p->has_computed_jump = current_function_has_computed_jump;
- p->is_thunk = current_function_is_thunk;
- p->args_size = current_function_args_size;
- p->pretend_args_size = current_function_pretend_args_size;
- p->arg_offset_rtx = current_function_arg_offset_rtx;
- p->varargs = current_function_varargs;
- p->stdarg = current_function_stdarg;
- p->uses_const_pool = current_function_uses_const_pool;
- p->uses_pic_offset_table = current_function_uses_pic_offset_table;
- p->internal_arg_pointer = current_function_internal_arg_pointer;
- p->cannot_inline = current_function_cannot_inline;
- p->max_parm_reg = max_parm_reg;
- p->parm_reg_stack_loc = parm_reg_stack_loc;
- p->outgoing_args_size = current_function_outgoing_args_size;
- p->return_rtx = current_function_return_rtx;
- p->nonlocal_goto_handler_slots = nonlocal_goto_handler_slots;
- p->nonlocal_goto_handler_labels = nonlocal_goto_handler_labels;
- p->nonlocal_goto_stack_level = nonlocal_goto_stack_level;
- p->nonlocal_labels = nonlocal_labels;
- p->cleanup_label = cleanup_label;
- p->return_label = return_label;
- p->save_expr_regs = save_expr_regs;
- p->stack_slot_list = stack_slot_list;
- p->parm_birth_insn = parm_birth_insn;
- p->frame_offset = frame_offset;
- p->tail_recursion_label = tail_recursion_label;
- p->tail_recursion_reentry = tail_recursion_reentry;
- p->arg_pointer_save_area = arg_pointer_save_area;
- p->rtl_expr_chain = rtl_expr_chain;
- p->last_parm_insn = last_parm_insn;
- p->context_display = context_display;
- p->trampoline_list = trampoline_list;
- p->function_call_count = function_call_count;
- p->temp_slots = temp_slots;
- p->temp_slot_level = temp_slot_level;
- p->target_temp_slot_level = target_temp_slot_level;
- p->var_temp_slot_level = var_temp_slot_level;
p->fixup_var_refs_queue = 0;
- p->epilogue_delay_list = current_function_epilogue_delay_list;
- p->args_info = current_function_args_info;
- p->check_memory_usage = current_function_check_memory_usage;
- p->instrument_entry_exit = current_function_instrument_entry_exit;
save_tree_status (p, context);
- save_storage_status (p);
- save_emit_status (p);
- save_expr_status (p);
save_varasm_status (p, context);
if (save_machine_status)
(*save_machine_status) (p);
outer_function_chain = p->next;
current_function_contains_functions
- = p->contains_functions || p->inline_obstacks
- || context == current_function_decl;
- current_function_has_computed_jump = p->has_computed_jump;
- current_function_name = p->name;
+ |= p->inline_obstacks || context == current_function_decl;
current_function_decl = p->decl;
- current_function_pops_args = p->pops_args;
- current_function_returns_struct = p->returns_struct;
- current_function_returns_pcc_struct = p->returns_pcc_struct;
- current_function_returns_pointer = p->returns_pointer;
- current_function_needs_context = p->needs_context;
- current_function_calls_setjmp = p->calls_setjmp;
- current_function_calls_longjmp = p->calls_longjmp;
- current_function_calls_alloca = p->calls_alloca;
- current_function_has_nonlocal_label = p->has_nonlocal_label;
- current_function_has_nonlocal_goto = p->has_nonlocal_goto;
- current_function_is_thunk = p->is_thunk;
- current_function_args_size = p->args_size;
- current_function_pretend_args_size = p->pretend_args_size;
- current_function_arg_offset_rtx = p->arg_offset_rtx;
- current_function_varargs = p->varargs;
- current_function_stdarg = p->stdarg;
- current_function_uses_const_pool = p->uses_const_pool;
- current_function_uses_pic_offset_table = p->uses_pic_offset_table;
- current_function_internal_arg_pointer = p->internal_arg_pointer;
- current_function_cannot_inline = p->cannot_inline;
- max_parm_reg = p->max_parm_reg;
- parm_reg_stack_loc = p->parm_reg_stack_loc;
- current_function_outgoing_args_size = p->outgoing_args_size;
- current_function_return_rtx = p->return_rtx;
- nonlocal_goto_handler_slots = p->nonlocal_goto_handler_slots;
- nonlocal_goto_handler_labels = p->nonlocal_goto_handler_labels;
- nonlocal_goto_stack_level = p->nonlocal_goto_stack_level;
- nonlocal_labels = p->nonlocal_labels;
- cleanup_label = p->cleanup_label;
- return_label = p->return_label;
- save_expr_regs = p->save_expr_regs;
- stack_slot_list = p->stack_slot_list;
- parm_birth_insn = p->parm_birth_insn;
- frame_offset = p->frame_offset;
- tail_recursion_label = p->tail_recursion_label;
- tail_recursion_reentry = p->tail_recursion_reentry;
- arg_pointer_save_area = p->arg_pointer_save_area;
- rtl_expr_chain = p->rtl_expr_chain;
- last_parm_insn = p->last_parm_insn;
- context_display = p->context_display;
- trampoline_list = p->trampoline_list;
- function_call_count = p->function_call_count;
- temp_slots = p->temp_slots;
- temp_slot_level = p->temp_slot_level;
- target_temp_slot_level = p->target_temp_slot_level;
- var_temp_slot_level = p->var_temp_slot_level;
- current_function_epilogue_delay_list = p->epilogue_delay_list;
reg_renumber = 0;
- current_function_args_info = p->args_info;
- current_function_check_memory_usage = p->check_memory_usage;
- current_function_instrument_entry_exit = p->instrument_entry_exit;
restore_tree_status (p, context);
- restore_storage_status (p);
- restore_expr_status (p);
restore_emit_status (p);
restore_varasm_status (p);
\f
/* Allocate fixed slots in the stack frame of the current function. */
-/* Return size needed for stack frame based on slots so far allocated.
+/* Return size needed for stack frame based on slots so far allocated in
+ function F.
This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY;
the caller may have to do that. */
HOST_WIDE_INT
-get_frame_size ()
+get_func_frame_size (f)
+ struct function *f;
{
#ifdef FRAME_GROWS_DOWNWARD
- return -frame_offset;
+ return -f->x_frame_offset;
#else
- return frame_offset;
+ return f->x_frame_offset;
#endif
}
+/* Return size needed for stack frame based on slots so far allocated.
+ This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY;
+ the caller may have to do that. */
+HOST_WIDE_INT
+get_frame_size ()
+{
+ return get_func_frame_size (current_function);
+}
+
/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
with machine mode MODE.
alignment = align / BITS_PER_UNIT;
#ifdef FRAME_GROWS_DOWNWARD
- function->frame_offset -= size;
+ function->x_frame_offset -= size;
#endif
/* Round frame offset to that alignment. */
#ifdef FRAME_GROWS_DOWNWARD
- function->frame_offset = FLOOR_ROUND (function->frame_offset, alignment);
+ function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset, alignment);
#else
- function->frame_offset = CEIL_ROUND (function->frame_offset, alignment);
+ function->x_frame_offset = CEIL_ROUND (function->x_frame_offset, alignment);
#endif
/* On a big-endian machine, if we are allocating more space than we will use,
bigend_correction = size - GET_MODE_SIZE (mode);
addr = plus_constant (virtual_stack_vars_rtx,
- function->frame_offset + bigend_correction);
+ function->x_frame_offset + bigend_correction);
#ifndef FRAME_GROWS_DOWNWARD
- function->frame_offset += size;
+ function->x_frame_offset += size;
#endif
x = gen_rtx_MEM (mode, addr);
- function->stack_slot_list
- = gen_rtx_EXPR_LIST (VOIDmode, x, function->stack_slot_list);
+ function->x_stack_slot_list
+ = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
pop_obstacks ();
p->in_use = 1;
p->addr_taken = 0;
- p->rtl_expr = sequence_rtl_expr;
+ p->rtl_expr = seq_rtl_expr;
if (keep == 2)
{
if (function)
{
- if (regno < function->max_parm_reg)
- new = function->parm_reg_stack_loc[regno];
+ if (regno < function->x_max_parm_reg)
+ new = function->x_parm_reg_stack_loc[regno];
if (new == 0)
new = assign_outer_stack_local (decl_mode, GET_MODE_SIZE (decl_mode),
0, function);
{
tree pending;
rtx first_insn = get_insns ();
- struct sequence_stack *stack = sequence_stack;
+ struct sequence_stack *stack = seq_stack;
tree rtl_exps = rtl_expr_chain;
/* Must scan all insns for stack-refs that exceed the limit. */
#ifdef NEED_SEPARATE_AP
rtx addr;
- if (fp->arg_pointer_save_area == 0)
- fp->arg_pointer_save_area
+ if (fp->x_arg_pointer_save_area == 0)
+ fp->x_arg_pointer_save_area
= assign_outer_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0, fp);
- addr = fix_lexical_addr (XEXP (fp->arg_pointer_save_area, 0), var);
+ addr = fix_lexical_addr (XEXP (fp->x_arg_pointer_save_area, 0), var);
addr = memory_address (Pmode, addr);
base = copy_to_reg (gen_rtx_MEM (Pmode, addr));
round_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));
for (fp = outer_function_chain; fp; fp = fp->next)
- for (link = fp->trampoline_list; link; link = TREE_CHAIN (link))
+ for (link = fp->x_trampoline_list; link; link = TREE_CHAIN (link))
if (TREE_PURPOSE (link) == function)
{
tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
fp->function_maybepermanent_obstack);
rtlexp = make_node (RTL_EXPR);
RTL_EXPR_RTL (rtlexp) = tramp;
- fp->trampoline_list = tree_cons (function, rtlexp, fp->trampoline_list);
+ fp->x_trampoline_list = tree_cons (function, rtlexp,
+ fp->x_trampoline_list);
pop_obstacks ();
}
else
current_function_uses_pic_offset_table = 0;
current_function_cannot_inline = 0;
+ current_function->inlinable = 0;
+
/* We have not yet needed to make a label to jump to for tail-recursion. */
tail_recursion_label = 0;
current_function_returns_pointer
= POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
+}
+/* Make sure all values used by the optimization passes have sane
+ defaults. */
+void
+init_function_for_compilation ()
+{
+ reg_renumber = 0;
/* No prologue/epilogue insns yet. */
prologue = epilogue = 0;
}
force_next_line_note ();
}
\f
+/* Undo the effects of init_dummy_function_start. */
+void
+expand_dummy_function_end ()
+{
+ /* End any sequences that failed to be closed due to syntax errors. */
+ while (in_sequence_p ())
+ end_sequence ();
+
+ /* Outside function body, can't compute type's actual size
+ until next function's body starts. */
+ current_function = 0;
+}
+
/* Generate RTL for the end of the current function.
FILENAME and LINE are the current position in the source file.
static rtx initial_trampoline;
#endif
+ finish_expr_for_function ();
+
#ifdef NON_SAVING_SETJMP
/* Don't put any variables in registers if we call setjmp
on a machine that fails to restore the registers. */
struct simple_obstack_stack *next;
};
\f
+struct emit_status
+{
+ /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
+ After rtl generation, it is 1 plus the largest register number used. */
+ int x_reg_rtx_no;
+
+ /* Lowest label number in current function. */
+ int x_first_label_num;
+
+ /* The ends of the doubly-linked chain of rtl for the current function.
+ Both are reset to null at the start of rtl generation for the function.
+
+ start_sequence saves both of these on `sequence_stack' along with
+ `sequence_rtl_expr' and then starts a new, nested sequence of insns. */
+ rtx x_first_insn;
+ rtx x_last_insn;
+
+ /* RTL_EXPR within which the current sequence will be placed. Use to
+ prevent reuse of any temporaries within the sequence until after the
+ RTL_EXPR is emitted. */
+ tree sequence_rtl_expr;
+
+ /* Stack of pending (incomplete) sequences saved by `start_sequence'.
+ Each element describes one pending sequence.
+ The main insn-chain is saved in the last element of the chain,
+ unless the chain is empty. */
+ struct sequence_stack *sequence_stack;
+
+ /* INSN_UID for next insn emitted.
+ Reset to 1 for each function compiled. */
+ int x_cur_insn_uid;
+
+ /* Line number and source file of the last line-number NOTE emitted.
+ This is used to avoid generating duplicates. */
+ int x_last_linenum;
+ char *x_last_filename;
+
+ /* A vector indexed by pseudo reg number. The allocated length
+ of this vector is regno_pointer_flag_length. Since this
+ vector is needed during the expansion phase when the total
+ number of registers in the function is not yet known,
+ it is copied and made bigger when necessary. */
+ char *regno_pointer_flag;
+ int regno_pointer_flag_length;
+
+ /* Indexed by pseudo register number, if nonzero gives the known alignment
+ for that pseudo (if regno_pointer_flag is set).
+ Allocated in parallel with regno_pointer_flag. */
+ char *regno_pointer_align;
+
+ /* Indexed by pseudo register number, gives the rtx for that pseudo.
+ Allocated in parallel with regno_pointer_flag. */
+ rtx *x_regno_reg_rtx;
+};
+
+/* For backward compatibility... eventually these should all go away. */
+#define reg_rtx_no (current_function->emit->x_reg_rtx_no)
+#define seq_rtl_expr (current_function->emit->sequence_rtl_expr)
+#define regno_reg_rtx (current_function->emit->x_regno_reg_rtx)
+#define seq_stack (current_function->emit->sequence_stack)
+
+#define REGNO_POINTER_ALIGN(REGNO) \
+ (current_function->emit->regno_pointer_align[REGNO])
+#define REGNO_POINTER_FLAG(REGNO) \
+ (current_function->emit->regno_pointer_flag[REGNO])
+
+struct expr_status
+{
+ /* Number of units that we should eventually pop off the stack.
+ These are the arguments to function calls that have already returned. */
+ int x_pending_stack_adjust;
+
+ /* Under some ABIs, it is the caller's responsibility to pop arguments
+ pushed for function calls. A naive implementation would simply pop
+ the arguments immediately after each call. However, if several
+ function calls are made in a row, it is typically cheaper to pop
+ all the arguments after all of the calls are complete since a
+ single pop instruction can be used. Therefore, GCC attempts to
+ defer popping the arguments until absolutely necessary. (For
+ example, at the end of a conditional, the arguments must be popped,
+ since code outside the conditional won't know whether or not the
+ arguments need to be popped.)
+
+ When INHIBIT_DEFER_POP is non-zero, however, the compiler does not
+ attempt to defer pops. Instead, the stack is popped immediately
+ after each call. Rather then setting this variable directly, use
+ NO_DEFER_POP and OK_DEFER_POP. */
+ int x_inhibit_defer_pop;
+
+ /* Nonzero means __builtin_saveregs has already been done in this function.
+ The value is the pseudoreg containing the value __builtin_saveregs
+ returned. */
+ rtx x_saveregs_value;
+
+ /* Similarly for __builtin_apply_args. */
+ rtx x_apply_args_value;
+
+ /* List of labels that must never be deleted. */
+ rtx x_forced_labels;
+
+ /* Postincrements that still need to be expanded. */
+ rtx x_pending_chain;
+};
+
+#define pending_stack_adjust (current_function->expr->x_pending_stack_adjust)
+#define inhibit_defer_pop (current_function->expr->x_inhibit_defer_pop)
+#define saveregs_value (current_function->expr->x_saveregs_value)
+#define apply_args_value (current_function->expr->x_apply_args_value)
+#define forced_labels (current_function->expr->x_forced_labels)
+#define pending_chain (current_function->expr->x_pending_chain)
+
/* This structure can save all the important global and static variables
describing the status of the current function. */
struct eh_status *eh;
struct stmt_status *stmt;
+ struct expr_status *expr;
+ struct emit_status *emit;
/* For function.c. */
+
+ /* Name of this function. */
char *name;
+ /* Points to the FUNCTION_DECL of this function. */
tree decl;
+
+ /* Number of bytes of args popped by function being compiled on its return.
+ Zero if no bytes are to be popped.
+ May affect compilation of return insn or of function epilogue. */
int pops_args;
+
+ /* Nonzero if function being compiled needs to be given an address
+ where the value should be stored. */
int returns_struct;
+
+ /* Nonzero if function being compiled needs to
+ return the address of where it has put a structure value. */
int returns_pcc_struct;
+
+ /* Nonzero if the current function returns a pointer type. */
int returns_pointer;
+
+ /* Nonzero if function being compiled needs to be passed a static chain. */
int needs_context;
+
+ /* Nonzero if function being compiled can call setjmp. */
int calls_setjmp;
+
+ /* Nonzero if function being compiled can call longjmp. */
int calls_longjmp;
+
+ /* Nonzero if function being compiled can call alloca,
+ either as a subroutine or builtin. */
int calls_alloca;
+
+ /* Nonzero if function being compiled receives nonlocal gotos
+ from nested functions. */
+
int has_nonlocal_label;
+
+ /* Nonzero if function being compiled has nonlocal gotos to parent
+ function. */
int has_nonlocal_goto;
+
+ /* Nonzero if function being compiled contains nested functions. */
int contains_functions;
+
+ /* Nonzero if the function being compiled issues a computed jump. */
int has_computed_jump;
+
+ /* Nonzero if the current function is a thunk (a lightweight function that
+ just adjusts one of its arguments and forwards to another function), so
+ we should try to cut corners where we can. */
int is_thunk;
- rtx nonlocal_goto_handler_slots;
- rtx nonlocal_goto_handler_labels;
- rtx nonlocal_goto_stack_level;
- tree nonlocal_labels;
+
+ /* If function's args have a fixed size, this is that size, in bytes.
+ Otherwise, it is -1.
+ May affect compilation of return insn or of function epilogue. */
int args_size;
+
+ /* # bytes the prologue should push and pretend that the caller pushed them.
+ The prologue must do this, but only if parms can be passed in
+ registers. */
int pretend_args_size;
+
+ /* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
+ defined, the needed space is pushed by the prologue. */
+ int outgoing_args_size;
+
+ /* This is the offset from the arg pointer to the place where the first
+ anonymous arg can be found, if there is one. */
rtx arg_offset_rtx;
+
+ /* Nonzero if current function uses varargs.h or equivalent.
+ Zero for functions that use stdarg.h. */
int varargs;
+
+ /* Nonzero if current function uses stdarg.h or equivalent.
+ Zero for functions that use varargs.h. */
int stdarg;
- int max_parm_reg;
- rtx *parm_reg_stack_loc;
- int outgoing_args_size;
+
+ /* Quantities of various kinds of registers
+ used for the current function's args. */
+ CUMULATIVE_ARGS args_info;
+
+ /* If non-zero, an RTL expression for the location at which the current
+ function returns its result. If the current function returns its
+ result in a register, current_function_return_rtx will always be
+ the hard register containing the result. */
rtx return_rtx;
- rtx cleanup_label;
- rtx return_label;
- rtx save_expr_regs;
- rtx stack_slot_list;
- rtx parm_birth_insn;
- HOST_WIDE_INT frame_offset;
- rtx tail_recursion_label;
- rtx tail_recursion_reentry;
+
+ /* The arg pointer hard register, or the pseudo into which it was copied. */
rtx internal_arg_pointer;
+
+ /* Language-specific reason why the current function cannot be made
+ inline. */
char *cannot_inline;
- rtx arg_pointer_save_area;
- tree rtl_expr_chain;
- rtx last_parm_insn;
- tree context_display;
- tree trampoline_list;
- int function_call_count;
- struct temp_slot *temp_slots;
- int temp_slot_level;
- int target_temp_slot_level;
- int var_temp_slot_level;
+
+ /* Nonzero if instrumentation calls for function entry and exit should be
+ generated. */
int instrument_entry_exit;
- /* This slot is initialized as 0 and is added to
- during the nested function. */
- struct var_refs_queue *fixup_var_refs_queue;
- CUMULATIVE_ARGS args_info;
- /* For expr.c. */
- rtx pending_chain;
- int pending_stack_adjust;
- int inhibit_defer_pop;
- rtx saveregs_value;
- rtx apply_args_value;
- rtx forced_labels;
+ /* Nonzero if memory access checking be enabled in the current function. */
int check_memory_usage;
- /* For emit-rtl.c. */
- int reg_rtx_no;
- int first_label_num;
- rtx first_insn;
- rtx last_insn;
- tree sequence_rtl_expr;
- struct sequence_stack *sequence_stack;
- int cur_insn_uid;
- int last_linenum;
- char *last_filename;
- char *regno_pointer_flag;
- char *regno_pointer_align;
- int regno_pointer_flag_length;
- rtx *regno_reg_rtx;
-
- /* For stor-layout.c. */
- tree permanent_type_chain;
- tree temporary_type_chain;
- tree permanent_type_end;
- tree temporary_type_end;
- tree pending_sizes;
- int immediate_size_expand;
+ /* Number of function calls seen so far in current function. */
+ int x_function_call_count;
+
+ /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
+ (labels to which there can be nonlocal gotos from nested functions)
+ in this function. */
+ tree x_nonlocal_labels;
+
+ /* List (chain of EXPR_LIST) of stack slots that hold the current handlers
+ for nonlocal gotos. There is one for every nonlocal label in the
+ function; this list matches the one in nonlocal_labels.
+ Zero when function does not have nonlocal labels. */
+ rtx x_nonlocal_goto_handler_slots;
+
+ /* List (chain of EXPR_LIST) of labels heading the current handlers for
+ nonlocal gotos. */
+ rtx x_nonlocal_goto_handler_labels;
+
+ /* RTX for stack slot that holds the stack pointer value to restore
+ for a nonlocal goto.
+ Zero when function does not have nonlocal labels. */
+ rtx x_nonlocal_goto_stack_level;
+
+ /* Label that will go on parm cleanup code, if any.
+ Jumping to this label runs cleanup code for parameters, if
+ such code must be run. Following this code is the logical return
+ label. */
+ rtx x_cleanup_label;
+
+ /* Label that will go on function epilogue.
+ Jumping to this label serves as a "return" instruction
+ on machines which require execution of the epilogue on all returns. */
+ rtx x_return_label;
+
+ /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
+ So we can mark them all live at the end of the function, if nonopt. */
+ rtx x_save_expr_regs;
+
+ /* List (chain of EXPR_LISTs) of all stack slots in this function.
+ Made for the sake of unshare_all_rtl. */
+ rtx x_stack_slot_list;
+
+ /* Chain of all RTL_EXPRs that have insns in them. */
+ tree x_rtl_expr_chain;
+
+ /* Label to jump back to for tail recursion, or 0 if we have
+ not yet needed one for this function. */
+ rtx x_tail_recursion_label;
+
+ /* Place after which to insert the tail_recursion_label if we need one. */
+ rtx x_tail_recursion_reentry;
+
+ /* Location at which to save the argument pointer if it will need to be
+ referenced. There are two cases where this is done: if nonlocal gotos
+ exist, or if vars stored at an offset from the argument pointer will be
+ needed by inner routines. */
+ rtx x_arg_pointer_save_area;
+
+ /* Offset to end of allocated area of stack frame.
+ If stack grows down, this is the address of the last stack slot allocated.
+ If stack grows up, this is the address for the next slot. */
+ HOST_WIDE_INT x_frame_offset;
+
+ /* List (chain of TREE_LISTs) of static chains for containing functions.
+ Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
+ in an RTL_EXPR in the TREE_VALUE. */
+ tree x_context_display;
+
+ /* List (chain of TREE_LISTs) of trampolines for nested functions.
+ The trampoline sets up the static chain and jumps to the function.
+ We supply the trampoline's address when the function's address is
+ requested.
+
+ Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
+ in an RTL_EXPR in the TREE_VALUE. */
+ tree x_trampoline_list;
+
+ /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
+ rtx x_parm_birth_insn;
+
+ /* Last insn of those whose job was to put parms into their nominal
+ homes. */
+ rtx x_last_parm_insn;
+
+ /* 1 + last pseudo register number possibly used for loading a copy
+ of a parameter of this function. */
+ int x_max_parm_reg;
+
+ /* Vector indexed by REGNO, containing location on stack in which
+ to put the parm which is nominally in pseudo register REGNO,
+ if we discover that that parm must go in the stack. The highest
+ element in this vector is one less than MAX_PARM_REG, above. */
+ rtx *x_parm_reg_stack_loc;
+
+ /* List of all temporaries allocated, both available and in use. */
+ struct temp_slot *x_temp_slots;
+
+ /* Current nesting level for temporaries. */
+ int x_temp_slot_level;
+
+ /* Current nesting level for variables in a block. */
+ int x_var_temp_slot_level;
+
+ /* When temporaries are created by TARGET_EXPRs, they are created at
+ this level of temp_slot_level, so that they can remain allocated
+ until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
+ of TARGET_EXPRs. */
+ int x_target_temp_slot_level;
+
+ /* This slot is initialized as 0 and is added to
+ during the nested function. */
+ struct var_refs_queue *fixup_var_refs_queue;
/* For tree.c. */
int all_types_permanent;
struct obstack *rtl_obstack;
struct simple_obstack_stack *inline_obstacks;
- /* For integrate.c. */
+ /* For integrate.c. We duplicate some of the fields so that
+ save_for_inline_copying can keep two versions. */
+ int inlinable;
+ struct emit_status *inl_emit;
+ /* This is in fact an rtvec. */
+ void *original_arg_vector;
+ tree original_decl_initial;
+ /* Last insn of those whose job was to put parms into their nominal
+ homes. */
+ rtx inl_last_parm_insn;
+ /* Highest label number in current function. */
+ int inl_max_label_num;
+
+ /* Nonzero if the current function uses the constant pool. */
int uses_const_pool;
/* For md files. */
+
+ /* Nonzero if the current function uses pic_offset_table_rtx. */
int uses_pic_offset_table;
/* tm.h can use this to store whatever it likes. */
struct machine_function *machine;
/* For reorg. */
+
+ /* If some insns can be deferred to the delay slots of the epilogue, the
+ delay list for them is recorded here. */
rtx epilogue_delay_list;
/* For varasm. */
extern struct function *current_function;
extern struct function *all_functions;
+/* For backward compatibility... eventually these should all go away. */
+#define current_function_name (current_function->name)
+#define current_function_pops_args (current_function->pops_args)
+#define current_function_returns_struct (current_function->returns_struct)
+#define current_function_returns_pcc_struct (current_function->returns_pcc_struct)
+#define current_function_returns_pointer (current_function->returns_pointer)
+#define current_function_needs_context (current_function->needs_context)
+#define current_function_calls_setjmp (current_function->calls_setjmp)
+#define current_function_calls_alloca (current_function->calls_alloca)
+#define current_function_calls_longjmp (current_function->calls_longjmp)
+#define current_function_has_computed_jump (current_function->has_computed_jump)
+#define current_function_contains_functions (current_function->contains_functions)
+#define current_function_is_thunk (current_function->is_thunk)
+#define current_function_args_info (current_function->args_info)
+#define current_function_args_size (current_function->args_size)
+#define current_function_pretend_args_size (current_function->pretend_args_size)
+#define current_function_outgoing_args_size (current_function->outgoing_args_size)
+#define current_function_arg_offset_rtx (current_function->arg_offset_rtx)
+#define current_function_varargs (current_function->varargs)
+#define current_function_stdarg (current_function->stdarg)
+#define current_function_internal_arg_pointer (current_function->internal_arg_pointer)
+#define current_function_return_rtx (current_function->return_rtx)
+#define current_function_instrument_entry_exit (current_function->instrument_entry_exit)
+#define current_function_check_memory_usage (current_function->check_memory_usage)
+#define current_function_uses_pic_offset_table (current_function->uses_pic_offset_table)
+#define current_function_uses_const_pool (current_function->uses_const_pool)
+#define current_function_cannot_inline (current_function->cannot_inline)
+#define current_function_epilogue_delay_list (current_function->epilogue_delay_list)
+#define current_function_has_nonlocal_label (current_function->has_nonlocal_label)
+#define current_function_has_nonlocal_goto (current_function->has_nonlocal_goto)
+
+#define max_parm_reg (current_function->x_max_parm_reg)
+#define parm_reg_stack_loc (current_function->x_parm_reg_stack_loc)
+#define cleanup_label (current_function->x_cleanup_label)
+#define return_label (current_function->x_return_label)
+#define save_expr_regs (current_function->x_save_expr_regs)
+#define stack_slot_list (current_function->x_stack_slot_list)
+#define parm_birth_insn (current_function->x_parm_birth_insn)
+#define frame_offset (current_function->x_frame_offset)
+#define tail_recursion_label (current_function->x_tail_recursion_label)
+#define tail_recursion_reentry (current_function->x_tail_recursion_reentry)
+#define arg_pointer_save_area (current_function->x_arg_pointer_save_area)
+#define rtl_expr_chain (current_function->x_rtl_expr_chain)
+#define last_parm_insn (current_function->x_last_parm_insn)
+#define context_display (current_function->x_context_display)
+#define trampoline_list (current_function->x_trampoline_list)
+#define function_call_count (current_function->x_function_call_count)
+#define temp_slots (current_function->x_temp_slots)
+#define temp_slot_level (current_function->x_temp_slot_level)
+#define target_temp_slot_level (current_function->x_target_temp_slot_level)
+#define var_temp_slot_level (current_function->x_var_temp_slot_level)
+#define nonlocal_labels (current_function->x_nonlocal_labels)
+#define nonlocal_goto_handler_slots (current_function->x_nonlocal_goto_handler_slots)
+#define nonlocal_goto_handler_labels (current_function->x_nonlocal_goto_handler_labels)
+#define nonlocal_goto_stack_level (current_function->x_nonlocal_goto_stack_level)
+
/* The FUNCTION_DECL for an inline function currently being expanded. */
extern tree inline_function_decl;
-/* Label that will go on parm cleanup code, if any.
- Jumping to this label runs cleanup code for parameters, if
- such code must be run. Following this code is the logical return label. */
-
-extern rtx cleanup_label;
-
-/* Label that will go on function epilogue.
- Jumping to this label serves as a "return" instruction
- on machines which require execution of the epilogue on all returns. */
-
-extern rtx return_label;
-
-/* Offset to end of allocated area of stack frame.
- If stack grows down, this is the address of the last stack slot allocated.
- If stack grows up, this is the address for the next slot. */
-extern HOST_WIDE_INT frame_offset;
-
-/* Label to jump back to for tail recursion, or 0 if we have
- not yet needed one for this function. */
-extern rtx tail_recursion_label;
-
-/* Place after which to insert the tail_recursion_label if we need one. */
-extern rtx tail_recursion_reentry;
-
-/* Location at which to save the argument pointer if it will need to be
- referenced. There are two cases where this is done: if nonlocal gotos
- exist, or if vars whose is an offset from the argument pointer will be
- needed by inner routines. */
-
-extern rtx arg_pointer_save_area;
-
-/* Chain of all RTL_EXPRs that have insns in them. */
-extern tree rtl_expr_chain;
-
-/* List (chain of EXPR_LISTs) of all stack slots in this function.
- Made for the sake of unshare_all_rtl. */
-extern rtx stack_slot_list;
-
/* Given a function decl for a containing function,
return the `struct function' for it. */
struct function *find_function_data PROTO((tree));
This size counts from zero. It is not rounded to STACK_BOUNDARY;
the caller may have to do that. */
extern HOST_WIDE_INT get_frame_size PROTO((void));
+/* Likewise, but for a different than the current function. */
+extern HOST_WIDE_INT get_func_frame_size PROTO((struct function *));
/* These variables hold pointers to functions to
save and restore machine-specific data,
extern void restore_tree_status PROTO((struct function *, tree));
extern void save_varasm_status PROTO((struct function *, tree));
extern void restore_varasm_status PROTO((struct function *));
-extern void save_expr_status PROTO((struct function *));
-extern void restore_expr_status PROTO((struct function *));
-extern void save_emit_status PROTO((struct function *));
extern void restore_emit_status PROTO((struct function *));
-extern void save_storage_status PROTO((struct function *));
-extern void restore_storage_status PROTO((struct function *));
extern rtx get_first_block_beg PROTO((void));
+extern void init_virtual_regs PROTO((struct emit_status *));
+
#ifdef rtx
#undef rtx
#endif
#include "recog.h"
#include "basic-block.h"
#include "output.h"
+#include "function.h"
#include "expr.h"
#include "obstack.h"
static int const_prop_count;
/* Number of copys propagated. */
static int copy_prop_count;
-
-extern char *current_function_name;
-extern int current_function_calls_setjmp;
\f
/* These variables are used by classic GCSE.
Normally they'd be defined a bit later, but `rd_gen' needs to
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"rtl.h\"\n");
+ printf ("#include \"function.h\"\n");
printf ("#include \"expr.h\"\n");
printf ("#include \"real.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"rtl.h\"\n");
+ printf ("#include \"function.h\"\n");
printf ("#include \"regs.h\"\n");
printf ("#include \"hard-reg-set.h\"\n");
printf ("#include \"real.h\"\n");
#include "flags.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "insn-config.h"
#include "reload.h"
#include "output.h"
#include "rtl.h"
#include "flags.h"
#include "output.h"
+#include "function.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "toplev.h"
#include "rtl.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-config.h"
#define IN_EDGES(block) (in_edges[block])
#define OUT_EDGES(block) (out_edges[block])
-/* List of labels which cannot be deleted, needed for control
- flow graph construction. */
-extern rtx forced_labels;
static int is_cfg_nonregular PROTO ((void));
: (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
#endif
\f
-static rtx initialize_for_inline PROTO((tree, int, int, int, int));
-static void finish_inline PROTO((tree, rtx));
+static rtvec initialize_for_inline PROTO((tree, int));
static void adjust_copied_decl_tree PROTO((tree));
static tree copy_decl_list PROTO((tree));
static tree copy_decl_tree PROTO((tree));
Only reg numbers less than max_parm_reg are mapped here. */
static tree *parmdecl_map;
-/* Keep track of first pseudo-register beyond those that are parms. */
-extern int max_parm_reg;
-extern rtx *parm_reg_stack_loc;
-
/* When an insn is being copied by copy_for_inline,
this is nonzero if we have copied an ASM_OPERANDS.
In that case, it is the original input-operand vector. */
/* Subroutine for `save_for_inline{copying,nocopy}'. Performs initialization
needed to save FNDECL's insns and info for future inline expansion. */
-static rtx
-initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy)
+static rtvec
+initialize_for_inline (fndecl, copy)
tree fndecl;
- int min_labelno;
- int max_labelno;
- int max_reg;
int copy;
{
- int function_flags, i;
+ int i;
rtvec arg_vector;
tree parms;
- /* Compute the values of any flags we must restore when inlining this. */
-
- function_flags
- = (current_function_calls_alloca * FUNCTION_FLAGS_CALLS_ALLOCA
- + current_function_calls_setjmp * FUNCTION_FLAGS_CALLS_SETJMP
- + current_function_calls_longjmp * FUNCTION_FLAGS_CALLS_LONGJMP
- + current_function_returns_struct * FUNCTION_FLAGS_RETURNS_STRUCT
- + (current_function_returns_pcc_struct
- * FUNCTION_FLAGS_RETURNS_PCC_STRUCT)
- + current_function_needs_context * FUNCTION_FLAGS_NEEDS_CONTEXT
- + (current_function_has_nonlocal_label
- * FUNCTION_FLAGS_HAS_NONLOCAL_LABEL)
- + current_function_returns_pointer * FUNCTION_FLAGS_RETURNS_POINTER
- + current_function_uses_const_pool * FUNCTION_FLAGS_USES_CONST_POOL
- + (current_function_uses_pic_offset_table
- * FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
- + current_function_has_computed_jump * FUNCTION_FLAGS_HAS_COMPUTED_JUMP);
-
/* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */
bzero ((char *) parmdecl_map, max_parm_reg * sizeof (tree));
arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
}
}
- /* Assume we start out in the insns that set up the parameters. */
- in_nonparm_insns = 0;
-
- /* The list of DECL_SAVED_INSNS, starts off with a header which
- contains the following information:
-
- the first insn of the function (not including the insns that copy
- parameters into registers).
- the first parameter insn of the function,
- the first label used by that function,
- the last label used by that function,
- the highest register number used for parameters,
- the total number of registers used,
- the size of the incoming stack area for parameters,
- the number of bytes popped on return,
- the stack slot list,
- the labels that are forced to exist,
- some flags that are used to restore compiler globals,
- the value of current_function_outgoing_args_size,
- the original argument vector,
- the original DECL_INITIAL,
- and pointers to the table of pseudo regs, pointer flags, and alignment. */
-
- return gen_inline_header_rtx (NULL_RTX, NULL_RTX, min_labelno, max_labelno,
- max_parm_reg, max_reg,
- current_function_args_size,
- current_function_pops_args,
- stack_slot_list, forced_labels, function_flags,
- current_function_outgoing_args_size,
- arg_vector, (rtx) DECL_INITIAL (fndecl),
- (rtvec) regno_reg_rtx, regno_pointer_flag,
- regno_pointer_align,
- (rtvec) parm_reg_stack_loc);
-}
-
-/* Subroutine for `save_for_inline{copying,nocopy}'. Finishes up the
- things that must be done to make FNDECL expandable as an inline function.
- HEAD contains the chain of insns to which FNDECL will expand. */
-
-static void
-finish_inline (fndecl, head)
- tree fndecl;
- rtx head;
-{
- FIRST_FUNCTION_INSN (head) = get_first_nonparm_insn ();
- FIRST_PARM_INSN (head) = get_insns ();
- DECL_SAVED_INSNS (fndecl) = head;
- DECL_FRAME_SIZE (fndecl) = get_frame_size ();
+ return arg_vector;
}
/* Adjust the BLOCK_END_NOTE pointers in a given copied DECL tree so that
save_for_inline_copying (fndecl)
tree fndecl;
{
- rtx first_insn, last_insn, insn;
- rtx head, copy;
+ rtvec argvec;
+ rtx new_first_insn, new_last_insn, insn;
int max_labelno, min_labelno, i, len;
int max_reg;
int max_uid;
char *new, *new1;
rtx *new_parm_reg_stack_loc;
rtx *new2;
+ struct emit_status *es
+ = (struct emit_status *) xmalloc (sizeof (struct emit_status));
/* Make and emit a return-label if we have not already done so.
Do this before recording the bounds on label numbers. */
emit_label (return_label);
}
+ *es = *current_function->emit;
+
/* Get some bounds on the labels and registers used. */
max_labelno = max_label_num ();
parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree));
- head = initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, 1);
+ argvec = initialize_for_inline (fndecl, 1);
if (current_function_uses_const_pool)
{
clear_const_double_mem ();
}
- max_uid = INSN_UID (head);
+ max_uid = get_max_uid ();
/* We have now allocated all that needs to be allocated permanently
on the rtx obstack. Set our high-water mark, so that we
insn = get_insns ();
if (GET_CODE (insn) != NOTE)
abort ();
- first_insn = rtx_alloc (NOTE);
- NOTE_SOURCE_FILE (first_insn) = NOTE_SOURCE_FILE (insn);
- NOTE_LINE_NUMBER (first_insn) = NOTE_LINE_NUMBER (insn);
- INSN_UID (first_insn) = INSN_UID (insn);
- PREV_INSN (first_insn) = NULL;
- NEXT_INSN (first_insn) = NULL;
- last_insn = first_insn;
+ new_first_insn = rtx_alloc (NOTE);
+ NOTE_SOURCE_FILE (new_first_insn) = NOTE_SOURCE_FILE (insn);
+ NOTE_LINE_NUMBER (new_first_insn) = NOTE_LINE_NUMBER (insn);
+ INSN_UID (new_first_insn) = INSN_UID (insn);
+ PREV_INSN (new_first_insn) = NULL;
+ NEXT_INSN (new_first_insn) = NULL;
+ new_last_insn = new_first_insn;
/* Each pseudo-reg in the old insn chain must have a unique rtx in the copy.
Make these new rtx's now, and install them in regno_reg_rtx, so they
will be the official pseudo-reg rtx's for the rest of compilation. */
- reg_map = (rtx *) savealloc (regno_pointer_flag_length * sizeof (rtx));
+ reg_map = (rtx *) savealloc (es->regno_pointer_flag_length * sizeof (rtx));
len = sizeof (struct rtx_def) + (GET_RTX_LENGTH (REG) - 1) * sizeof (rtunion);
for (i = max_reg - 1; i > LAST_VIRTUAL_REGISTER; i--)
reg_map[i] = (rtx)obstack_copy (function_maybepermanent_obstack,
regno_reg_rtx[i], len);
- regno_reg_rtx = reg_map;
+ es->x_regno_reg_rtx = reg_map;
/* Put copies of all the virtual register rtx into the new regno_reg_rtx. */
- init_virtual_regs ();
+ init_virtual_regs (es);
/* Likewise each label rtx must have a unique rtx as its copy. */
for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
{
+ rtx copy;
orig_asm_operands_vector = 0;
if (insn == first_nonparm_insn)
}
INSN_UID (copy) = INSN_UID (insn);
insn_map[INSN_UID (insn)] = copy;
- NEXT_INSN (last_insn) = copy;
- PREV_INSN (copy) = last_insn;
- last_insn = copy;
+ NEXT_INSN (new_last_insn) = copy;
+ PREV_INSN (copy) = new_last_insn;
+ new_last_insn = copy;
}
adjust_copied_decl_tree (DECL_INITIAL (fndecl));
REG_NOTES (insn_map[INSN_UID (insn)])
= copy_for_inline (REG_NOTES (insn));
- NEXT_INSN (last_insn) = NULL;
-
- finish_inline (fndecl, head);
+ NEXT_INSN (new_last_insn) = NULL;
/* Make new versions of the register tables. */
- new = (char *) savealloc (regno_pointer_flag_length);
- bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
- new1 = (char *) savealloc (regno_pointer_flag_length);
- bcopy (regno_pointer_align, new1, regno_pointer_flag_length);
-
- regno_pointer_flag = new;
- regno_pointer_align = new1;
-
- set_new_first_and_last_insn (first_insn, last_insn);
-
- if (label_map)
- free (label_map);
+ new = (char *) savealloc (es->regno_pointer_flag_length);
+ memcpy (new, es->regno_pointer_flag, es->regno_pointer_flag_length);
+ new1 = (char *) savealloc (es->regno_pointer_flag_length);
+ memcpy (new1, es->regno_pointer_align, es->regno_pointer_flag_length);
+ es->regno_pointer_flag = new;
+ es->regno_pointer_align = new1;
+
+ free (label_map);
+
+ current_function->inl_max_label_num = max_label_num ();
+ current_function->inl_last_parm_insn = current_function->x_last_parm_insn;
+ current_function->original_arg_vector = argvec;
+ current_function->original_decl_initial = DECL_INITIAL (fndecl);
+ /* Use the copy we made for compiling the function now, and
+ use the original values for inlining. */
+ current_function->inl_emit = current_function->emit;
+ current_function->emit = es;
+ set_new_first_and_last_insn (new_first_insn, new_last_insn);
+ DECL_SAVED_INSNS (fndecl) = current_function;
}
/* Copy NODE (as with copy_node). NODE must be a DECL. Set the
tree fndecl;
{
rtx insn;
- rtx head;
+ rtvec argvec;
rtx first_nonparm_insn;
/* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
emit_label (return_label);
}
- head = initialize_for_inline (fndecl, get_first_label_num (),
- max_label_num (), max_reg_num (), 0);
+ argvec = initialize_for_inline (fndecl, 0);
/* If there are insns that copy parms from the stack into pseudo registers,
those insns are not copied. `expand_inline_function' must
preserve_data ();
- finish_inline (fndecl, head);
+ current_function->inl_emit = current_function->emit;
+ current_function->inl_max_label_num = max_label_num ();
+ current_function->inl_last_parm_insn = current_function->x_last_parm_insn;
+ current_function->original_arg_vector = argvec;
+ current_function->original_decl_initial = DECL_INITIAL (fndecl);
+ DECL_SAVED_INSNS (fndecl) = current_function;
}
\f
/* Given PX, a pointer into an insn, search for references to the constant
tree type;
rtx structure_value_addr;
{
+ struct function *inl_f = DECL_SAVED_INSNS (fndecl);
tree formal, actual, block;
- rtx header = DECL_SAVED_INSNS (fndecl);
- rtx insns = FIRST_FUNCTION_INSN (header);
- rtx parm_insns = FIRST_PARM_INSN (header);
+ rtx parm_insns = inl_f->inl_emit->x_first_insn;
+ rtx insns = (inl_f->inl_last_parm_insn
+ ? NEXT_INSN (inl_f->inl_last_parm_insn)
+ : parm_insns);
tree *arg_trees;
rtx *arg_vals;
rtx insn;
int max_regno;
register int i;
- int min_labelno = FIRST_LABELNO (header);
- int max_labelno = LAST_LABELNO (header);
+ int min_labelno = inl_f->inl_emit->x_first_label_num;
+ int max_labelno = inl_f->inl_max_label_num;
int nargs;
rtx local_return_label = 0;
rtx loc;
#ifdef HAVE_cc0
rtx cc0_insn = 0;
#endif
- rtvec arg_vector = ORIGINAL_ARG_VECTOR (header);
+ rtvec arg_vector = (rtvec) inl_f->original_arg_vector;
rtx static_chain_value = 0;
+ int inl_max_uid;
/* The pointer used to track the true location of the memory used
for MAP->LABEL_MAP. */
rtx *real_label_map = 0;
/* Allow for equivalences of the pseudos we make for virtual fp and ap. */
- max_regno = MAX_REGNUM (header) + 3;
+ max_regno = inl_f->inl_emit->x_reg_rtx_no + 3;
if (max_regno < FIRST_PSEUDO_REGISTER)
abort ();
= (rtx *) xmalloc ((max_labelno) * sizeof (rtx));
map->label_map = real_label_map;
- map->insn_map = (rtx *) alloca (INSN_UID (header) * sizeof (rtx));
- bzero ((char *) map->insn_map, INSN_UID (header) * sizeof (rtx));
+ inl_max_uid = (inl_f->inl_emit->x_cur_insn_uid + 1);
+ map->insn_map = (rtx *) alloca (inl_max_uid * sizeof (rtx));
+ bzero ((char *) map->insn_map, inl_max_uid * sizeof (rtx));
map->min_insnno = 0;
- map->max_insnno = INSN_UID (header);
+ map->max_insnno = inl_max_uid;
map->integrating = 1;
if (map->insns_at_start == 0)
map->insns_at_start = emit_note (NULL_PTR, NOTE_INSN_DELETED);
- map->regno_pointer_flag = INLINE_REGNO_POINTER_FLAG (header);
- map->regno_pointer_align = INLINE_REGNO_POINTER_ALIGN (header);
+ map->regno_pointer_flag = inl_f->inl_emit->regno_pointer_flag;
+ map->regno_pointer_align = inl_f->inl_emit->regno_pointer_align;
/* Update the outgoing argument size to allow for those in the inlined
function. */
- if (OUTGOING_ARGS_SIZE (header) > current_function_outgoing_args_size)
- current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (header);
+ if (inl_f->outgoing_args_size > current_function_outgoing_args_size)
+ current_function_outgoing_args_size = inl_f->outgoing_args_size;
/* If the inline function needs to make PIC references, that means
that this function's PIC offset table must be used. */
- if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
+ if (inl_f->uses_pic_offset_table)
current_function_uses_pic_offset_table = 1;
/* If this function needs a context, set it up. */
- if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_NEEDS_CONTEXT)
+ if (inl_f->needs_context)
static_chain_value = lookup_static_chain (fndecl);
if (GET_CODE (parm_insns) == NOTE
stack pointer around the call. This saves stack space, but
also is required if this inline is being done between two
pushes. */
- if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_CALLS_ALLOCA)
+ if (inl_f->calls_alloca)
emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX);
/* Now copy the insns one by one. Do this in two passes, first the insns and
emit_label (local_return_label);
/* Restore the stack pointer if we saved it above. */
- if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_CALLS_ALLOCA)
+ if (inl_f->calls_alloca)
emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
/* Make copies of the decls of the symbols in the inline function, so that
inline_function_decl = fndecl;
integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
- integrate_decl_tree ((tree) ORIGINAL_DECL_INITIAL (header), 0, map);
+ integrate_decl_tree (inl_f->original_decl_initial, 0, map);
inline_function_decl = 0;
/* End the scope containing the copied formal parameter variables
if (regno == VIRTUAL_STACK_VARS_REGNUM)
{
rtx loc, seq;
- int size = DECL_FRAME_SIZE (map->fndecl);
+ int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
#ifdef FRAME_GROWS_DOWNWARD
/* In this case, virtual_stack_vars_rtx points to one byte
/* Do the same for a block to contain any arguments referenced
in memory. */
rtx loc, seq;
- int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
+ int size = DECL_SAVED_INSNS (map->fndecl)->args_size;
start_sequence ();
loc = assign_stack_temp (BLKmode, size, 1);
output_inline_function (fndecl)
tree fndecl;
{
- rtx head;
+ struct function *f = DECL_SAVED_INSNS (fndecl);
rtx last;
/* Things we allocate from here on are part of this function, not
permanent. */
temporary_allocation ();
-
- head = DECL_SAVED_INSNS (fndecl);
+ current_function = f;
current_function_decl = fndecl;
-
- /* This call is only used to initialize global variables. */
- init_function_start (fndecl, "lossage", 1);
-
- /* Redo parameter determinations in case the FUNCTION_...
- macros took machine-specific actions that need to be redone. */
- assign_parms (fndecl, 1);
-
- /* Set stack frame size. */
- assign_stack_local (BLKmode, DECL_FRAME_SIZE (fndecl), 0);
-
- /* The first is a bit of a lie (the array may be larger), but doesn't
- matter too much and it isn't worth saving the actual bound. */
- reg_rtx_no = regno_pointer_flag_length = MAX_REGNUM (head);
- regno_reg_rtx = (rtx *) INLINE_REGNO_REG_RTX (head);
- regno_pointer_flag = INLINE_REGNO_POINTER_FLAG (head);
- regno_pointer_align = INLINE_REGNO_POINTER_ALIGN (head);
- max_parm_reg = MAX_PARMREG (head);
- parm_reg_stack_loc = (rtx *) PARMREG_STACK_LOC (head);
-
- stack_slot_list = STACK_SLOT_LIST (head);
- forced_labels = FORCED_LABELS (head);
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_HAS_COMPUTED_JUMP)
- current_function_has_computed_jump = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_ALLOCA)
- current_function_calls_alloca = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_SETJMP)
- current_function_calls_setjmp = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_LONGJMP)
- current_function_calls_longjmp = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_STRUCT)
- current_function_returns_struct = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_PCC_STRUCT)
- current_function_returns_pcc_struct = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_NEEDS_CONTEXT)
- current_function_needs_context = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_HAS_NONLOCAL_LABEL)
- current_function_has_nonlocal_label = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_POINTER)
- current_function_returns_pointer = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_CONST_POOL)
- current_function_uses_const_pool = 1;
-
- if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
- current_function_uses_pic_offset_table = 1;
-
- current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (head);
- current_function_pops_args = POPS_ARGS (head);
-
- /* This is the only thing the expand_function_end call that uses to be here
- actually does and that call can cause problems. */
- immediate_size_expand--;
+ clear_emit_caches ();
/* Find last insn and rebuild the constant pool. */
- for (last = FIRST_PARM_INSN (head);
- NEXT_INSN (last); last = NEXT_INSN (last))
+ init_const_rtx_hash_table ();
+ for (last = get_insns (); NEXT_INSN (last); last = NEXT_INSN (last))
{
if (GET_RTX_CLASS (GET_CODE (last)) == 'i')
{
}
}
- set_new_first_and_last_insn (FIRST_PARM_INSN (head), last);
- set_new_first_and_last_label_num (FIRST_LABELNO (head), LAST_LABELNO (head));
+ set_new_last_label_num (f->inl_max_label_num);
/* We must have already output DWARF debugging information for the
original (abstract) inline function declaration/definition, so
DECL_DEFER_OUTPUT (fndecl) = 0;
/* We can't inline this anymore. */
+ f->inlinable = 0;
DECL_INLINE (fndecl) = 0;
/* Compile this function all the way down to assembly code. */
rest_of_compilation (fndecl);
+ current_function = 0;
current_function_decl = 0;
}
#include "insn-flags.h"
#include "insn-attr.h"
#include "recog.h"
+#include "function.h"
#include "expr.h"
#include "real.h"
#include "except.h"
static rtx *jump_chain;
-/* List of labels referred to from initializers.
- These can never be deleted. */
-rtx forced_labels;
-
/* Maximum index in jump_chain. */
static int max_jump_chain;
#include "flags.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "hard-reg-set.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "system.h"
#include "rtl.h"
#include "obstack.h"
+#include "function.h"
#include "expr.h"
#include "insn-config.h"
#include "insn-flags.h"
#include "flags.h"
#include "insn-flags.h"
#include "insn-codes.h"
+#include "function.h"
#include "expr.h"
#include "recog.h"
#include "reload.h"
extern rtx final_sequence;
#endif
-/* Number of bytes of args popped by function being compiled on its return.
- Zero if no bytes are to be popped.
- May affect compilation of return insn or of function epilogue. */
-
-extern int current_function_pops_args;
-
-/* Nonzero if function being compiled needs to be given an address
- where the value should be stored. */
-
-extern int current_function_returns_struct;
-
-/* Nonzero if function being compiled needs to
- return the address of where it has put a structure value. */
-
-extern int current_function_returns_pcc_struct;
-
-/* Nonzero if function being compiled needs to be passed a static chain. */
-
-extern int current_function_needs_context;
-
-/* Nonzero if function being compiled can call setjmp. */
-
-extern int current_function_calls_setjmp;
-
-/* Nonzero if function being compiled can call longjmp. */
-
-extern int current_function_calls_longjmp;
-
-/* Nonzero if function being compiled can call alloca,
- either as a subroutine or builtin. */
-
-extern int current_function_calls_alloca;
+/* Nonzero means generate position-independent code.
+ This is not fully implemented yet. */
-/* Nonzero if function being compiled receives nonlocal gotos
- from nested functions. */
+extern int flag_pic;
-extern int current_function_has_nonlocal_label;
+/* The line number of the beginning of the current function.
+ sdbout.c needs this so that it can output relative linenumbers. */
-/* Nonzero if function being compiled contains nested functions. */
+#ifdef SDB_DEBUGGING_INFO /* Avoid undef sym in certain broken linkers. */
+extern int sdb_begin_function_line;
+#endif
-extern int current_function_contains_functions;
+/* File in which assembler code is being written. */
+#ifdef BUFSIZ
+extern FILE *asm_out_file;
+#endif
/* Nonzero if function being compiled doesn't contain any calls
(ignoring the prologue and epilogue). This is set prior to
local register allocation and is valid for the remaining
extern int current_function_uses_only_leaf_regs;
-/* Nonzero if the function being compiled issues a computed jump. */
-
-extern int current_function_has_computed_jump;
-
-/* Nonzero if the current function returns a pointer type */
-
-extern int current_function_returns_pointer;
-
-/* If function's args have a fixed size, this is that size, in bytes.
- Otherwise, it is -1.
- May affect compilation of return insn or of function epilogue. */
-
-extern int current_function_args_size;
-
-/* # bytes the prologue should push and pretend that the caller pushed them.
- The prologue must do this, but only if parms can be passed in registers. */
-
-extern int current_function_pretend_args_size;
-
-/* # of bytes of outgoing arguments required to be pushed by the prologue.
- If this is non-zero, it means that ACCUMULATE_OUTGOING_ARGS was defined
- and no stack adjusts will be done on function calls. */
-
-extern int current_function_outgoing_args_size;
-
-/* Nonzero if current function uses varargs.h or equivalent.
- Zero for functions that use stdarg.h. */
-
-extern int current_function_varargs;
-
-/* Nonzero if current function uses stdarg.h or equivalent.
- Zero for functions that use varargs.h. */
-
-extern int current_function_stdarg;
-
-/* Quantities of various kinds of registers
- used for the current function's args. */
-
-extern CUMULATIVE_ARGS current_function_args_info;
-
-/* Name of function now being compiled. */
-
-extern char *current_function_name;
-
-#ifdef RTX_CODE
-/* If non-zero, an RTL expression for that location at which the current
- function returns its result. Usually equal to
- DECL_RTL (DECL_RESULT (current_function_decl)). */
-
-extern rtx current_function_return_rtx;
-
-/* If some insns can be deferred to the delay slots of the epilogue, the
- delay list for them is recorded here. */
-
-extern rtx current_function_epilogue_delay_list;
-#endif
-
-/* Nonzero means generate position-independent code.
- This is not fully implemented yet. */
-
-extern int flag_pic;
-
-/* This is nonzero if the current function uses pic_offset_table_rtx. */
-extern int current_function_uses_pic_offset_table;
-
-/* This is nonzero if the current function uses the constant pool. */
-extern int current_function_uses_const_pool;
-
-/* Language-specific reason why the current function cannot be made inline. */
-extern char *current_function_cannot_inline;
-
-/* The line number of the beginning of the current function.
- sdbout.c needs this so that it can output relative linenumbers. */
-
-#ifdef SDB_DEBUGGING_INFO /* Avoid undef sym in certain broken linkers. */
-extern int sdb_begin_function_line;
-#endif
-
-/* File in which assembler code is being written. */
-
-#ifdef BUFSIZ
-extern FILE *asm_out_file;
-#endif
-
/* Default file in which to dump debug output. */
#ifdef BUFSIZ
#include "config.h"
#include "system.h"
#include "rtl.h"
+#include "tree.h"
#include "flags.h"
#include "insn-flags.h"
#include "insn-config.h"
#include "output.h"
#include "regs.h"
-#include "tree.h"
+#include "function.h"
#include "output.h"
#include "gcov-io.h"
#include "toplev.h"
#include "recog.h"
#include "regs.h"
#include "hard-reg-set.h"
+#include "function.h"
#include "flags.h"
#include "real.h"
#include "toplev.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
+#include "function.h"
#include "insn-config.h"
#include "regs.h"
#include "hard-reg-set.h"
return tmp;
}
-extern rtx forced_labels;
-
/* Forward declarations */
static void mark_regs_pat PROTO((rtx, HARD_REG_SET *));
#include "flags.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "insn-config.h"
#include "recog.h"
#include "reload.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "insn-flags.h"
#include "basic-block.h"
#define REGNO_LAST_NOTE_UID(N) (VARRAY_REG (reg_n_info, N)->last_note_uid)
-/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
- After rtl generation, it is 1 plus the largest register number used. */
-
-extern int reg_rtx_no;
-
-/* Vector indexed by regno; contains 1 for a register is considered a pointer.
- Reloading, etc. will use a pointer register rather than a non-pointer
- as the base register in an address, when there is a choice of two regs. */
-
-extern char *regno_pointer_flag;
-#define REGNO_POINTER_FLAG(REGNO) regno_pointer_flag[REGNO]
-extern int regno_pointer_flag_length;
-
/* List made of EXPR_LIST rtx's which gives pairs of pseudo registers
that have to go in the same hard reg. */
extern rtx regs_may_share;
-/* Vector mapping pseudo regno into the REG rtx for that register.
- This is computed by reg_scan. */
-
-extern rtx *regno_reg_rtx;
-
/* Flag set by local-alloc or global-alloc if they decide to allocate
something in a call-clobbered register. */
#include "flags.h"
#include "real.h"
#include "output.h"
+#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "insn-flags.h"
#include "insn-codes.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "regs.h"
#include "basic-block.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* List of labels that must never be deleted. */
-extern rtx forced_labels;
-
/* List of insn_chain instructions, one for every insn that reload needs to
examine. */
struct insn_chain *reload_insn_chain;
#include "toplev.h"
#include "rtl.h"
#include "expr.h"
+#include "function.h"
#include "insn-config.h"
#include "conditions.h"
#include "hard-reg-set.h"
#include "hard-reg-set.h"
#include "system.h"
#include "basic-block.h"
+#include "function.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
-3 means end of a contour; output N_RBRAC. */
DEF_RTL_EXPR(NOTE, "note", "iuusn", 'x')
-/* INLINE_HEADER is use by inline function machinery. The information
- it contains helps to build the mapping function between the rtx's of
- the function to be inlined and the current function being expanded. */
-
-DEF_RTL_EXPR(INLINE_HEADER, "inline_header", "iuuuiiiiiieeiiEeEssE", 'x')
-
/* ----------------------------------------------------------------------
Top level constituents of INSN, JUMP_INSN and CALL_INSN.
---------------------------------------------------------------------- */
/* 1 means a SYMBOL_REF has been the library function in emit_library_call. */
#define SYMBOL_REF_USED(RTX) ((RTX)->used)
-/* For an INLINE_HEADER rtx, FIRST_FUNCTION_INSN is the first insn
- of the function that is not involved in copying parameters to
- pseudo-registers. FIRST_PARM_INSN is the very first insn of
- the function, including the parameter copying.
- We keep this around in case we must splice
- this function into the assembly code at the end of the file.
- FIRST_LABELNO is the first label number used by the function (inclusive).
- LAST_LABELNO is the last label used by the function (exclusive).
- MAX_REGNUM is the largest pseudo-register used by that function.
- FUNCTION_ARGS_SIZE is the size of the argument block in the stack.
- POPS_ARGS is the number of bytes of input arguments popped by the function
- STACK_SLOT_LIST is the list of stack slots.
- FORCED_LABELS is the list of labels whose address was taken.
- FUNCTION_FLAGS are where single-bit flags are saved.
- OUTGOING_ARGS_SIZE is the size of the largest outgoing stack parameter list.
- ORIGINAL_ARG_VECTOR is a vector of the original DECL_RTX values
- for the function arguments.
- ORIGINAL_DECL_INITIAL is a pointer to the original DECL_INITIAL for the
- function.
- INLINE_REGNO_REG_RTX, INLINE_REGNO_POINTER_FLAG, and
- INLINE_REGNO_POINTER_ALIGN are pointers to the corresponding arrays.
-
- We want this to lay down like an INSN. The PREV_INSN field
- is always NULL. The NEXT_INSN field always points to the
- first function insn of the function being squirreled away. */
-
-#define FIRST_FUNCTION_INSN(RTX) ((RTX)->fld[2].rtx)
-#define FIRST_PARM_INSN(RTX) ((RTX)->fld[3].rtx)
-#define FIRST_LABELNO(RTX) ((RTX)->fld[4].rtint)
-#define LAST_LABELNO(RTX) ((RTX)->fld[5].rtint)
-#define MAX_PARMREG(RTX) ((RTX)->fld[6].rtint)
-#define MAX_REGNUM(RTX) ((RTX)->fld[7].rtint)
-#define FUNCTION_ARGS_SIZE(RTX) ((RTX)->fld[8].rtint)
-#define POPS_ARGS(RTX) ((RTX)->fld[9].rtint)
-#define STACK_SLOT_LIST(RTX) ((RTX)->fld[10].rtx)
-#define FORCED_LABELS(RTX) ((RTX)->fld[11].rtx)
-#define FUNCTION_FLAGS(RTX) ((RTX)->fld[12].rtint)
-#define OUTGOING_ARGS_SIZE(RTX) ((RTX)->fld[13].rtint)
-#define ORIGINAL_ARG_VECTOR(RTX) ((RTX)->fld[14].rtvec)
-#define ORIGINAL_DECL_INITIAL(RTX) ((RTX)->fld[15].rtx)
-#define INLINE_REGNO_REG_RTX(RTX) ((RTX)->fld[16].rtvec)
-#define INLINE_REGNO_POINTER_FLAG(RTX) ((RTX)->fld[17].rtstr)
-#define INLINE_REGNO_POINTER_ALIGN(RTX) ((RTX)->fld[18].rtstr)
-#define PARMREG_STACK_LOC(RTX) ((RTX)->fld[19].rtvec)
-
-/* In FUNCTION_FLAGS we save some variables computed when emitting the code
- for the function and which must be `or'ed into the current flag values when
- insns from that function are being inlined. */
-
-/* These ought to be an enum, but non-ANSI compilers don't like that. */
-#define FUNCTION_FLAGS_CALLS_ALLOCA 01
-#define FUNCTION_FLAGS_CALLS_SETJMP 02
-#define FUNCTION_FLAGS_RETURNS_STRUCT 04
-#define FUNCTION_FLAGS_RETURNS_PCC_STRUCT 010
-#define FUNCTION_FLAGS_NEEDS_CONTEXT 020
-#define FUNCTION_FLAGS_HAS_NONLOCAL_LABEL 040
-#define FUNCTION_FLAGS_RETURNS_POINTER 0100
-#define FUNCTION_FLAGS_USES_CONST_POOL 0200
-#define FUNCTION_FLAGS_CALLS_LONGJMP 0400
-#define FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE 01000
-#define FUNCTION_FLAGS_HAS_COMPUTED_JUMP 02000
-
/* Define a macro to look for REG_INC notes,
but save time on machines where they never exist. */
extern rtvec gen_rtvec_vv PROTO((int, rtunion *));
extern rtx gen_reg_rtx PROTO((enum machine_mode));
extern rtx gen_label_rtx PROTO((void));
-extern rtx gen_inline_header_rtx PROTO((rtx, rtx, int, int, int, int,
- int, int, rtx, rtx, int, int,
- rtvec, rtx,
- rtvec, char *, char *, rtvec));
extern rtx gen_lowpart_common PROTO((enum machine_mode, rtx));
extern rtx gen_lowpart PROTO((enum machine_mode, rtx));
extern rtx gen_lowpart_if_possible PROTO((enum machine_mode, rtx));
generate any new pseudo registers. */
extern int no_new_pseudos;
-/* Indexed by pseudo register number, gives the rtx for that pseudo.
- Allocated in parallel with regno_pointer_flag. */
-extern rtx *regno_reg_rtx;
-
-/* Vector indexed by regno; contain the alignment in bytes and type
- pointed to for a register that contains a pointer, if known. */
-extern char *regno_pointer_align;
-#define REGNO_POINTER_ALIGN(REGNO) regno_pointer_align[REGNO]
-
/* Translates rtx code to tree code, for those codes needed by
REAL_ARITHMETIC. The function returns an int because the caller may not
know what `enum tree_code' means. */
extern int get_max_uid PROTO ((void));
extern int in_sequence_p PROTO ((void));
extern void force_next_line_note PROTO ((void));
+extern void clear_emit_caches PROTO ((void));
extern void init_emit PROTO ((void));
extern void init_emit_once PROTO ((int));
extern void push_topmost_sequence PROTO ((void));
extern void reverse_comparison PROTO ((rtx));
extern void set_new_first_and_last_insn PROTO ((rtx, rtx));
extern void set_new_first_and_last_label_num PROTO ((int, int));
+extern void set_new_last_label_num PROTO ((int));
extern void unshare_all_rtl PROTO ((rtx));
extern void set_last_insn PROTO ((rtx));
extern void link_cc0_insns PROTO ((rtx));
extern void reorder_insns_with_line_notes PROTO ((rtx, rtx, rtx));
extern void emit_insn_after_with_line_notes PROTO ((rtx, rtx, rtx));
extern enum rtx_code classify_insn PROTO ((rtx));
-extern void init_virtual_regs PROTO ((void));
extern rtx emit PROTO ((rtx));
/* Query and clear/ restore no_line_numbers. This is used by the
switch / case handling in stmt.c to give proper line numbers in
extern void emit_jump PROTO ((rtx));
extern int preserve_subexpressions_p PROTO ((void));
-/* List (chain of EXPR_LIST) of labels heading the current handlers for
- nonlocal gotos. */
-extern rtx nonlocal_goto_handler_labels;
-
/* In expr.c */
extern void init_expr_once PROTO ((void));
extern void move_by_pieces PROTO ((rtx, rtx, int, int));
#include "rtl.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-config.h"
tree link;
/* Find the corresponding handler slot for this label. */
- handler_slot = p->nonlocal_goto_handler_slots;
- for (link = p->nonlocal_labels; TREE_VALUE (link) != label;
+ handler_slot = p->x_nonlocal_goto_handler_slots;
+ for (link = p->x_nonlocal_labels; TREE_VALUE (link) != label;
link = TREE_CHAIN (link))
handler_slot = XEXP (handler_slot, 1);
handler_slot = XEXP (handler_slot, 0);
if (HAVE_nonlocal_goto)
emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
copy_rtx (handler_slot),
- copy_rtx (p->nonlocal_goto_stack_level),
+ copy_rtx (p->x_nonlocal_goto_stack_level),
label_ref));
else
#endif
hard_frame_pointer_rtx));
/* Restore the stack pointer. Note this uses fp just restored. */
- addr = p->nonlocal_goto_stack_level;
+ addr = p->x_nonlocal_goto_stack_level;
if (addr)
addr = replace_rtx (copy_rtx (addr),
virtual_stack_vars_rtx,
return mode;
}
-\f
-/* Save all variables describing the current status into the structure *P.
- This is used before starting a nested function. */
-
-void
-save_storage_status (p)
- struct function *p ATTRIBUTE_UNUSED;
-{
-#if 0 /* Need not save, since always 0 and non0 (resp.) within a function. */
- p->pending_sizes = pending_sizes;
- p->immediate_size_expand = immediate_size_expand;
-#endif /* 0 */
-}
-
-/* Restore all variables describing the current status from the structure *P.
- This is used after a nested function. */
-
-void
-restore_storage_status (p)
- struct function *p ATTRIBUTE_UNUSED;
-{
-#if 0
- pending_sizes = p->pending_sizes;
- immediate_size_expand = p->immediate_size_expand;
-#endif /* 0 */
-}
#include "hard-reg-set.h"
#include "basic-block.h"
#include "regs.h"
+#include "function.h"
#include "insn-config.h"
#include "reload.h"
#include "flags.h"
#include "defaults.h"
#include "output.h"
#include "except.h"
+#include "function.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
/* Incremented on each change to input_file_stack. */
int input_file_stack_tick;
-/* FUNCTION_DECL for function now being parsed or compiled. */
-
-extern tree current_function_decl;
-
/* Name to use as base of names for dump output files. */
const char *dump_base_name;
init_decl_processing ();
init_optabs ();
init_stmt ();
- init_expmed ();
- init_expr_once ();
init_loop ();
init_reload ();
init_alias_once ();
+ /* The following initialization functions need to generate rtl, so
+ provide a dummy function context for them. */
+ init_dummy_function_start ();
+ init_expmed ();
+ init_expr_once ();
if (flag_caller_saves)
init_caller_save ();
+ expand_dummy_function_end ();
/* If auxiliary info generation is desired, open the output file.
This goes in the same directory as the source file--unlike
}
#endif
TIMEVAR (integration_time, save_for_inline_nocopy (decl));
- RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
+ DECL_SAVED_INSNS (decl)->inlinable = inlinable;
goto exit_rest_of_compilation;
}
saved_block_tree = DECL_INITIAL (decl);
saved_arguments = DECL_ARGUMENTS (decl);
TIMEVAR (integration_time, save_for_inline_copying (decl));
- RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
+ DECL_SAVED_INSNS (decl)->inlinable = inlinable;
}
/* If specified extern inline but we aren't inlining it, we are
goto exit_rest_of_compilation;
}
+ /* Initialize some variables used by the optimizers. */
+ init_function_for_compilation ();
+
if (! DECL_DEFER_OUTPUT (decl))
TREE_ASM_WRITTEN (decl) = 1;
goto exit_rest_of_compilation;
/* Dump rtl code after jump, if we are doing that. */
-
- if (jump_opt_dump)
- dump_rtl (".jump", decl, print_rtl, insns);
+ if (jump_opt_dump)
+ dump_rtl (".jump", decl, print_rtl, insns);
/* Perform common subexpression elimination.
Nonzero value from `cse_main' means that jumps were simplified
where the data was actually passed. */
#define DECL_INCOMING_RTL(NODE) (DECL_CHECK (NODE)->decl.saved_insns.r)
/* For FUNCTION_DECL, if it is inline, holds the saved insn chain. */
-#define DECL_SAVED_INSNS(NODE) (DECL_CHECK (NODE)->decl.saved_insns.r)
+#define DECL_SAVED_INSNS(NODE) (DECL_CHECK (NODE)->decl.saved_insns.f)
/* For FUNCTION_DECL, if it is inline,
holds the size of the stack frame, as an integer. */
#define DECL_FRAME_SIZE(NODE) (DECL_CHECK (NODE)->decl.frame_size.i)
/* For FUNCTION_DECLs: points to insn that constitutes its definition
on the permanent obstack. For FIELD_DECL, this is DECL_FIELD_SIZE. */
union {
+ struct function *f;
struct rtx_def *r;
HOST_WIDE_INT i;
} saved_insns;
extern void expand_main_function PROTO ((void));
extern void mark_varargs PROTO ((void));
extern void init_dummy_function_start PROTO ((void));
+extern void expand_dummy_function_end PROTO ((void));
+extern void init_function_for_compilation PROTO ((void));
extern void init_function_start PROTO ((tree, char *, int));
extern void assign_parms PROTO ((tree, int));
extern void put_var_into_stack PROTO ((tree));
#include "regs.h"
#include "recog.h"
#include "flags.h"
+#include "function.h"
#include "expr.h"
#include "loop.h"
#include "toplev.h"
}
/* Use our current register alignment and pointer flags. */
- map->regno_pointer_flag = regno_pointer_flag;
- map->regno_pointer_align = regno_pointer_align;
+ map->regno_pointer_flag = current_function->emit->regno_pointer_flag;
+ map->regno_pointer_align = current_function->emit->regno_pointer_align;
/* If the loop is being partially unrolled, and the iteration variables
are being split, and are being renamed for the split, then must fix up