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. */
&& 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;
/* 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;
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,
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
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
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)
{
/* 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
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 ();
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 ();
{
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)
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,
{
int i, j;
- if (GET_CODE (insn) == INSN
+ if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
{
int count = 0;
/* 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;
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;
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
rtx i;
rtx newinsn;
- if (GET_CODE (insn) != CALL_INSN
+ if (!CALL_P (insn)
|| ! SIBLING_CALL_P (insn))
continue;
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
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
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;
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))
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;
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);
}
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;
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;
}