#ifdef HAVE_return
static void emit_return_into_block (basic_block, rtx);
#endif
-static void purge_single_hard_subreg_set (rtx);
#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
static rtx keep_stack_depressed (rtx);
#endif
lang_hooks.function.leave_nested (p);
/* Reset variables that have known state during rtx generation. */
- rtx_equal_function_value_matters = 1;
virtuals_instantiated = 0;
generating_concat_p = 1;
}
/* f->eh->eh_return_stub_label is used by code generation. */
lang_hooks.function.final (f);
- f->stmt = NULL;
}
/* Clear out all parts of the state in F that can safely be discarded
{
rtx x, addr;
int bigend_correction = 0;
- int alignment;
+ unsigned int alignment;
int frame_off, frame_alignment, frame_phase;
if (align == 0)
use logical operations which are unambiguous. */
#ifdef FRAME_GROWS_DOWNWARD
function->x_frame_offset
- = (FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment)
+ = (FLOOR_ROUND (function->x_frame_offset - frame_phase,
+ (unsigned HOST_WIDE_INT) alignment)
+ frame_phase);
#else
function->x_frame_offset
- = (CEIL_ROUND (function->x_frame_offset - frame_phase, alignment)
+ = (CEIL_ROUND (function->x_frame_offset - frame_phase,
+ (unsigned HOST_WIDE_INT) alignment)
+ frame_phase);
#endif
}
KEEP is 1 if this slot is to be retained after a call to
free_temp_slots. Automatic variables for a block are allocated
- with this flag. KEEP is 2 if we allocate a longer term temporary,
- whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3
- if we are to allocate something at an inner level to be treated as
- a variable in the block (e.g., a SAVE_EXPR).
+ with this flag. KEEP values of 2 or 3 were needed respectively
+ for variables whose lifetime is controlled by CLEANUP_POINT_EXPRs
+ or for SAVE_EXPRs, but they are now unused and will abort.
TYPE is the type that will be used for the stack slot. */
if (size == -1)
abort ();
+ /* These are now unused. */
+ if (keep > 1)
+ abort ();
+
if (mode == BLKmode)
align = BIGGEST_ALIGNMENT;
else
p->in_use = 1;
p->addr_taken = 0;
p->type = type;
-
- if (keep == 2)
- {
- p->level = target_temp_slot_level;
- p->keep = 1;
- }
- else if (keep == 3)
- {
- p->level = var_temp_slot_level;
- p->keep = 0;
- }
- else
- {
- p->level = temp_slot_level;
- p->keep = keep;
- }
+ p->level = temp_slot_level;
+ p->keep = keep;
pp = temp_slots_at_level (p->level);
insert_slot_to_list (p, pp);
avail_temp_slots = 0;
used_temp_slots = 0;
temp_slot_level = 0;
- var_temp_slot_level = 0;
- target_temp_slot_level = 0;
}
\f
/* These routines are responsible for converting virtual register references
#endif
\f
-/* Convert a SET of a hard subreg to a set of the appropriate hard
- register. A subroutine of purge_hard_subreg_sets. */
-
-static void
-purge_single_hard_subreg_set (rtx pattern)
-{
- rtx reg = SET_DEST (pattern);
- enum machine_mode mode = GET_MODE (SET_DEST (pattern));
- int offset = 0;
-
- if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg))
- && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
- {
- offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
- GET_MODE (SUBREG_REG (reg)),
- SUBREG_BYTE (reg),
- GET_MODE (reg));
- reg = SUBREG_REG (reg);
- }
-
-
- if (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER)
- {
- reg = gen_rtx_REG (mode, REGNO (reg) + offset);
- SET_DEST (pattern) = reg;
- }
-}
-
-/* Eliminate all occurrences of SETs of hard subregs from INSNS. The
- only such SETs that we expect to see are those left in because
- integrate can't handle sets of parts of a return value register.
-
- We don't use alter_subreg because we only want to eliminate subregs
- of hard registers. */
-
-void
-purge_hard_subreg_sets (rtx insn)
-{
- for (; insn; insn = NEXT_INSN (insn))
- {
- if (INSN_P (insn))
- {
- rtx pattern = PATTERN (insn);
- switch (GET_CODE (pattern))
- {
- case SET:
- if (GET_CODE (SET_DEST (pattern)) == SUBREG)
- purge_single_hard_subreg_set (pattern);
- break;
- case PARALLEL:
- {
- int j;
- for (j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
- {
- rtx inner_pattern = XVECEXP (pattern, 0, j);
- if (GET_CODE (inner_pattern) == SET
- && GET_CODE (SET_DEST (inner_pattern)) == SUBREG)
- purge_single_hard_subreg_set (inner_pattern);
- }
- }
- break;
- default:
- break;
- }
- }
- }
-}
-\f
/* Pass through the INSNS of function FNDECL and convert virtual register
references to hard register references. */
if (TREE_CODE (type) == VOID_TYPE)
return 0;
+ /* If the front end has decided that this needs to be passed by
+ reference, do so. */
+ if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
+ && DECL_BY_REFERENCE (exp))
+ return 1;
if (targetm.calls.return_in_memory (type, fntype))
return 1;
/* Types that are TREE_ADDRESSABLE must be constructed in memory,
data->passed_pointer = true;
passed_mode = nominal_mode = Pmode;
}
- /* See if the frontend wants to pass this by invisible reference. */
- else if (passed_type != nominal_type
- && POINTER_TYPE_P (passed_type)
- && TREE_TYPE (passed_type) == nominal_type)
- {
- nominal_type = passed_type;
- data->passed_pointer = 1;
- passed_mode = nominal_mode = Pmode;
- }
/* Find mode as it is passed by the ABI. */
promoted_mode = passed_mode;
rtx addr = DECL_RTL (all.function_result_decl);
rtx x;
- addr = convert_memory_address (Pmode, addr);
- x = gen_rtx_MEM (DECL_MODE (result), addr);
- set_mem_attributes (x, result, 1);
+ if (DECL_BY_REFERENCE (result))
+ x = addr;
+ else
+ {
+ addr = convert_memory_address (Pmode, addr);
+ x = gen_rtx_MEM (DECL_MODE (result), addr);
+ set_mem_attributes (x, result, 1);
+ }
SET_DECL_RTL (result, x);
}
cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
- init_stmt_for_function ();
init_eh_for_function ();
lang_hooks.function.init (cfun);
/* We haven't done register allocation yet. */
reg_renumber = 0;
- /* Indicate that we need to distinguish between the return value of the
- present function and the return value of a function being called. */
- rtx_equal_function_value_matters = 1;
-
/* Indicate that we have not instantiated virtual registers yet. */
virtuals_instantiated = 0;
}
if (value_address)
{
- rtx x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
- set_mem_attributes (x, DECL_RESULT (subr), 1);
+ rtx x = value_address;
+ if (!DECL_BY_REFERENCE (DECL_RESULT (subr)))
+ {
+ x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), x);
+ set_mem_attributes (x, DECL_RESULT (subr), 1);
+ }
SET_DECL_RTL (DECL_RESULT (subr), x);
}
}
if (current_function_returns_struct
|| current_function_returns_pcc_struct)
{
- rtx value_address
- = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
+ rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl));
tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ rtx outgoing;
+
+ if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
+ type = TREE_TYPE (type);
+ else
+ value_address = XEXP (value_address, 0);
+
#ifdef FUNCTION_OUTGOING_VALUE
- rtx outgoing
- = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
- current_function_decl);
+ outgoing = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
+ current_function_decl);
#else
- rtx outgoing
- = FUNCTION_VALUE (build_pointer_type (type), current_function_decl);
-#endif
+ outgoing = FUNCTION_VALUE (build_pointer_type (type),
+ current_function_decl);
+#endif
/* Mark this as a function return value so integrate will delete the
assignment and USE below when inlining this function. */
use return. Inserting a jump 'by hand' is extremely messy, so
we take advantage of cfg_layout_finalize using
fixup_fallthru_exit_predecessor. */
- cfg_layout_initialize ();
+ cfg_layout_initialize (0);
FOR_EACH_BB (cur_bb)
if (cur_bb->index >= 0 && cur_bb->next_bb->index >= 0)
cur_bb->rbi->next = cur_bb->next_bb;