X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;ds=sidebyside;f=gcc%2Ffunction.c;h=23fb74cf6761380da260542fc266fafa68a45f69;hb=a38904360a9b5e258d5011e686ebf58e89399379;hp=57d52eee2659a3fe149017c17324c0731e61e262;hpb=6388f9f700c2179281798c832fa45aa1914706f8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/function.c b/gcc/function.c index 57d52eee265..23fb74cf676 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2026,6 +2026,27 @@ use_register_for_decl (tree decl) return (optimize || DECL_REGISTER (decl)); } +/* Return true if TYPE should be passed by invisible reference. */ + +bool +pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode, + tree type, bool named_arg) +{ + if (type) + { + /* If this type contains non-trivial constructors, then it is + forbidden for the middle-end to create any new copies. */ + if (TREE_ADDRESSABLE (type)) + return true; + + /* GCC post 3.4 passes *all* variable sized types by reference. */ + if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + return true; + } + + return targetm.calls.pass_by_reference (ca, mode, type, named_arg); +} + /* Structures to communicate between the subroutines of assign_parms. The first holds data persistent across all parameters, the second is cleared out for each parameter. */ @@ -2236,16 +2257,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, && TYPE_TRANSPARENT_UNION (passed_type))) passed_type = TREE_TYPE (TYPE_FIELDS (passed_type)); - /* See if this arg was passed by invisible reference. It is if it is an - object whose size depends on the contents of the object itself or if - the machine requires these objects be passed that way. */ - if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type)) - || TREE_ADDRESSABLE (passed_type) -#ifdef FUNCTION_ARG_PASS_BY_REFERENCE - || FUNCTION_ARG_PASS_BY_REFERENCE (all->args_so_far, passed_mode, - passed_type, data->named_arg) -#endif - ) + /* See if this arg was passed by invisible reference. */ + if (pass_by_reference (&all->args_so_far, passed_mode, + passed_type, data->named_arg)) { passed_type = nominal_type = build_pointer_type (passed_type); data->passed_pointer = true; @@ -2358,10 +2372,10 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, /* If this parameter was passed both in registers and in the stack, use the copy on the stack. */ - if (MUST_PASS_IN_STACK (data->promoted_mode, data->passed_type)) + if (targetm.calls.must_pass_in_stack (data->promoted_mode, + data->passed_type)) entry_parm = 0; -#ifdef FUNCTION_ARG_PARTIAL_NREGS if (entry_parm) { int partial; @@ -2404,7 +2418,6 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, all->extra_pretend_bytes = all->pretend_args_size; } } -#endif locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs, entry_parm ? data->partial : 0, current_function_decl, @@ -2849,7 +2862,6 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, data->stack_parm = NULL; } -#ifdef FUNCTION_ARG_CALLEE_COPIES /* If we are passed an arg by reference and it is our responsibility to make a copy, do it now. PASSED_TYPE and PASSED mode now refer to the pointer, not the @@ -2894,7 +2906,6 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, did_conversion = true; } } -#endif /* FUNCTION_ARG_CALLEE_COPIES */ /* Mark the register as eliminable if we did no conversion and it was copied from memory at a fixed offset, and the arg pointer was not @@ -3647,7 +3658,7 @@ reorder_blocks_1 (rtx insns, tree current_block, varray_type *p_block_stack) for (insn = insns; insn; insn = NEXT_INSN (insn)) { - if (GET_CODE (insn) == NOTE) + if (NOTE_P (insn)) { if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG) { @@ -4066,12 +4077,7 @@ expand_pending_sizes (tree pending_sizes) /* Evaluate now the sizes of any types declared among the arguments. */ for (tem = pending_sizes; tem; tem = TREE_CHAIN (tem)) - { - expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode, 0); - /* Flush the queue in case this parameter declaration has - side-effects. */ - emit_queue (); - } + expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode, 0); } /* Start the RTL for a new function, and set variables used for @@ -4196,6 +4202,7 @@ expand_function_start (tree subr) t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area, integer_zero_node, NULL_TREE, NULL_TREE); r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE); + r_save = convert_memory_address (Pmode, r_save); emit_move_insn (r_save, virtual_stack_vars_rtx); update_nonlocal_goto_save_area (); @@ -4207,7 +4214,7 @@ expand_function_start (tree subr) as opposed to parm setup. */ emit_note (NOTE_INSN_FUNCTION_BEG); - if (GET_CODE (get_last_insn ()) != NOTE) + if (!NOTE_P (get_last_insn ())) emit_note (NOTE_INSN_DELETED); parm_birth_insn = get_last_insn (); @@ -4330,8 +4337,6 @@ expand_function_end (void) { rtx clobber_after; - finish_expr_for_function (); - /* If arg_pointer_save_area was referenced only from a nested function, we will not have initialized it yet. Do that now. */ if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init) @@ -4345,7 +4350,7 @@ expand_function_end (void) rtx insn, seq; for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == CALL_INSN) + if (CALL_P (insn)) { start_sequence (); probe_stack_range (STACK_CHECK_PROTECT, @@ -4630,7 +4635,7 @@ contains (rtx insn, varray_type vec) { int i, j; - if (GET_CODE (insn) == INSN + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) { int count = 0; @@ -5125,14 +5130,14 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) /* Verify that there are no active instructions in the last block. */ label = BB_END (last); - while (label && GET_CODE (label) != CODE_LABEL) + while (label && !LABEL_P (label)) { if (active_insn_p (label)) break; label = PREV_INSN (label); } - if (BB_HEAD (last) == label && GET_CODE (label) == CODE_LABEL) + if (BB_HEAD (last) == label && LABEL_P (label)) { rtx epilogue_line_note = NULL_RTX; @@ -5141,7 +5146,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) for (seq = get_last_insn (); seq && ! active_insn_p (seq); seq = PREV_INSN (seq)) - if (GET_CODE (seq) == NOTE && NOTE_LINE_NUMBER (seq) > 0) + if (NOTE_P (seq) && NOTE_LINE_NUMBER (seq) > 0) { epilogue_line_note = seq; break; @@ -5157,7 +5162,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) continue; jump = BB_END (bb); - if ((GET_CODE (jump) != JUMP_INSN) || JUMP_LABEL (jump) != label) + if (!JUMP_P (jump) || JUMP_LABEL (jump) != label) continue; /* If we have an unconditional jump, we can replace that @@ -5272,7 +5277,7 @@ epilogue_done: rtx i; rtx newinsn; - if (GET_CODE (insn) != CALL_INSN + if (!CALL_P (insn) || ! SIBLING_CALL_P (insn)) continue; @@ -5314,7 +5319,7 @@ epilogue_done: for (insn = prologue_end; insn; insn = prev) { prev = PREV_INSN (insn); - if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) + if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) { /* Note that we cannot reorder the first insn in the chain, since rest_of_compilation relies on that @@ -5329,7 +5334,7 @@ epilogue_done: for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb); insn != prologue_end && insn; insn = PREV_INSN (insn)) - if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) + if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) break; /* If we didn't find one, make a copy of the first line number @@ -5339,7 +5344,7 @@ epilogue_done: for (insn = next_active_insn (prologue_end); insn; insn = PREV_INSN (insn)) - if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0) + if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) { emit_note_copy_after (insn, prologue_end); break; @@ -5360,7 +5365,7 @@ epilogue_done: for (insn = epilogue_end; insn; insn = next) { next = NEXT_INSN (insn); - if (GET_CODE (insn) == NOTE + if (NOTE_P (insn) && (NOTE_LINE_NUMBER (insn) > 0 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)) @@ -5389,7 +5394,7 @@ reposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED) reorg has run. */ for (insn = f; insn; insn = NEXT_INSN (insn)) { - if (GET_CODE (insn) == NOTE) + if (NOTE_P (insn)) { if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END) note = insn; @@ -5409,13 +5414,13 @@ reposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED) if (note == 0) { for (note = last; (note = NEXT_INSN (note));) - if (GET_CODE (note) == NOTE + if (NOTE_P (note) && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END) break; } /* Avoid placing note between CODE_LABEL and BASIC_BLOCK note. */ - if (GET_CODE (last) == CODE_LABEL) + if (LABEL_P (last)) last = NEXT_INSN (last); reorder_insns (note, note, last); } @@ -5430,7 +5435,7 @@ reposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED) reorg has run. */ for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) { - if (GET_CODE (insn) == NOTE) + if (NOTE_P (insn)) { if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG) note = insn; @@ -5450,7 +5455,7 @@ reposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED) if (note == 0) { for (note = insn; (note = PREV_INSN (note));) - if (GET_CODE (note) == NOTE + if (NOTE_P (note) && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG) break; }