/* Expands front end tree to back end RTL for GCC.
Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
static int all_blocks (tree, tree *);
static tree *get_block_vector (tree, int *);
extern tree debug_find_var_in_block_tree (tree, tree);
-/* We always define `record_insns' even if its not used so that we
+/* We always define `record_insns' even if it's not used so that we
can always export `prologue_epilogue_contains'. */
static void record_insns (rtx, varray_type *) ATTRIBUTE_UNUSED;
static int contains (rtx, varray_type);
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), reg, 0);
}
else if (rescan)
- fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);
+ {
+ /* This can only happen during reload. Clear the same flag bits as
+ reload. */
+ MEM_VOLATILE_P (reg) = 0;
+ RTX_UNCHANGING_P (reg) = 0;
+ MEM_IN_STRUCT_P (reg) = 0;
+ MEM_SCALAR_P (reg) = 0;
+ MEM_ATTRS (reg) = 0;
+
+ fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);
+ }
return reg;
}
return true;
}
purge_addressof_replacements
- = gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
- gen_rtx_EXPR_LIST (VOIDmode, sub,
- purge_addressof_replacements));
+ = gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0),
+ gen_rtx_EXPR_LIST (VOIDmode, sub,
+ purge_addressof_replacements));
return true;
}
goto restart;
return 0;
regno = REGNO (reg);
- nregs = HARD_REGNO_NREGS (regno, TYPE_MODE (type));
+ nregs = hard_regno_nregs[regno][TYPE_MODE (type)];
for (i = 0; i < nregs; i++)
if (! call_used_regs[regno + i])
return 1;
#ifdef INIT_CUMULATIVE_INCOMING_ARGS
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
#else
- INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, fndecl);
+ INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, fndecl, -1);
#endif
/* We haven't yet found an argument that we must push and pretend the
int in_regs;
int partial = 0;
int pretend_bytes = 0;
+ int loaded_in_reg = 0;
/* Set LAST_NAMED if this is last named arg before last
anonymous args. */
/* Set NAMED_ARG if this arg should be treated as a named arg. For
most machines, if this is a varargs/stdarg function, then we treat
the last named arg as if it were anonymous too. */
- named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
+ named_arg = (targetm.calls.strict_argument_naming (&args_so_far)
+ ? 1 : !last_named);
if (TREE_TYPE (parm) == error_mark_node
/* This can happen after weird syntax errors
if (REG_P (parmreg))
{
+ unsigned int regno = REGNO (parmreg);
+
emit_group_store (parmreg, entry_parm, TREE_TYPE (parm),
int_size_in_bytes (TREE_TYPE (parm)));
SET_DECL_RTL (parm, parmreg);
+ loaded_in_reg = 1;
+
+ if (regno >= max_parm_reg)
+ {
+ rtx *new;
+ int old_max_parm_reg = max_parm_reg;
+
+ /* It's slow to expand this one register at a time,
+ but it's also rare and we need max_parm_reg to be
+ precisely correct. */
+ max_parm_reg = regno + 1;
+ new = ggc_realloc (parm_reg_stack_loc,
+ max_parm_reg * sizeof (rtx));
+ memset (new + old_max_parm_reg, 0,
+ (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
+ parm_reg_stack_loc = new;
+ parm_reg_stack_loc[regno] = stack_parm;
+ }
}
}
Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == REG
- || GET_CODE (entry_parm) == PARALLEL)
+ || (GET_CODE (entry_parm) == PARALLEL
+ && (!loaded_in_reg || !optimize)))
{
int size = int_size_in_bytes (TREE_TYPE (parm));
int size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
size_stored / UNITS_PER_WORD);
}
/* If parm is already bound to register pair, don't change
- this binding. */
+ this binding. */
if (! DECL_RTL_SET_P (parm))
SET_DECL_RTL (parm, stack_parm);
}
init_stmt_for_function ();
init_eh_for_function ();
- init_emit ();
- init_expr ();
- init_varasm_status (cfun);
(*lang_hooks.function.init) (cfun);
if (init_machine_status)
DECL_SAVED_INSNS (fndecl) = cfun;
cfun->decl = fndecl;
- current_function_name = (*lang_hooks.decl_printable_name) (fndecl, 2);
-
result = DECL_RESULT (fndecl);
if (aggregate_value_p (result, fndecl))
{
cfun = DECL_SAVED_INSNS (fndecl);
else
allocate_struct_function (fndecl);
+ init_emit ();
+ init_varasm_status (cfun);
+ init_expr ();
cse_not_expected = ! optimize;
tem = decl_function_context (tem);
if (tem == 0)
break;
- /* Chain thru stack frames, assuming pointer to next lexical frame
+ /* Chain through stack frames, assuming pointer to next lexical frame
is found at the place we always store it. */
#ifdef FRAME_GROWS_DOWNWARD
last_ptr = plus_constant (last_ptr,
/* If we had calls to alloca, and this machine needs
an accurate stack pointer to exit the function,
insert some code to save and restore the stack pointer. */
-#ifdef EXIT_IGNORE_STACK
- if (! EXIT_IGNORE_STACK)
-#endif
- if (current_function_calls_alloca)
- {
- rtx tem = 0;
+ if (! EXIT_IGNORE_STACK
+ && current_function_calls_alloca)
+ {
+ rtx tem = 0;
- emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
- emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
- }
+ emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
+ emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
+ }
/* If scalar return value was computed in a pseudo-reg, or was a named
return value that got dumped to the stack, copy that to the hard
}
}
-/* Set the specified locator to the insn chain. */
+/* Set the locator of the insn chain starting at INSN to LOC. */
static void
set_insn_locators (rtx insn, int loc)
{
static void
emit_return_into_block (basic_block bb, rtx line_note)
{
- emit_jump_insn_after (gen_return (), bb->end);
+ emit_jump_insn_after (gen_return (), BB_END (bb));
if (line_note)
- emit_note_copy_after (line_note, PREV_INSN (bb->end));
+ emit_note_copy_after (line_note, PREV_INSN (BB_END (bb)));
}
#endif /* HAVE_return */
&& !REGNO_REG_SET_P (EXIT_BLOCK_PTR->global_live_at_start,
regno)
&& !refers_to_regno_p (regno,
- regno + HARD_REGNO_NREGS (regno,
- Pmode),
+ regno + hard_regno_nregs[regno]
+ [Pmode],
info.equiv_reg_src, NULL)
&& info.const_equiv[regno] == 0)
break;
last = e->src;
/* Verify that there are no active instructions in the last block. */
- label = last->end;
+ label = BB_END (last);
while (label && GET_CODE (label) != CODE_LABEL)
{
if (active_insn_p (label))
label = PREV_INSN (label);
}
- if (last->head == label && GET_CODE (label) == CODE_LABEL)
+ if (BB_HEAD (last) == label && GET_CODE (label) == CODE_LABEL)
{
rtx epilogue_line_note = NULL_RTX;
if (bb == ENTRY_BLOCK_PTR)
continue;
- jump = bb->end;
+ jump = BB_END (bb);
if ((GET_CODE (jump) != JUMP_INSN) || JUMP_LABEL (jump) != label)
continue;
/* Emit a return insn for the exit fallthru block. Whether
this is still reachable will be determined later. */
- emit_barrier_after (last->end);
+ emit_barrier_after (BB_END (last));
emit_return_into_block (last, epilogue_line_note);
- epilogue_end = last->end;
+ epilogue_end = BB_END (last);
last->succ->flags &= ~EDGE_FALLTHRU;
goto epilogue_done;
}
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
{
basic_block bb = e->src;
- rtx insn = bb->end;
+ rtx insn = BB_END (bb);
rtx i;
rtx newinsn;
#endif
#ifdef HAVE_prologue
+ /* This is probably all useless now that we use locators. */
if (prologue_end)
{
rtx insn, prev;
}
/* Find the last line number note in the first block. */
- for (insn = ENTRY_BLOCK_PTR->next_bb->end;
+ 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)
VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
}
+/* Returns the name of the current function. */
+const char *
+current_function_name (void)
+{
+ return (*lang_hooks.decl_printable_name) (cfun->decl, 2);
+}
+
#include "gt-function.h"