/* Procedure integration for GNU CC.
Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
#include "config.h"
#include "system.h"
: (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
#endif
-/* Decide whether a function with a target specific attribute
+/* Decide whether a function with a target specific attribute
attached can be inlined. By default we disallow this. */
#ifndef FUNCTION_ATTRIBUTE_INLINABLE_P
#define FUNCTION_ATTRIBUTE_INLINABLE_P(FNDECL) 0
rtx x = map->label_map[i];
if (x == NULL_RTX)
- x = map->label_map[i] = gen_label_rtx();
+ x = map->label_map[i] = gen_label_rtx ();
return x;
}
{
if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
return N_("function with varying-size parameter cannot be inline");
- else if (TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
+ else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
+ && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
return N_("function with transparent unit parameter cannot be inline");
}
for (ninsns = 0, insn = get_first_nonparm_insn ();
insn && ninsns < max_insns;
insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
ninsns++;
if (ninsns >= max_insns)
/* In save_for_inline, nonzero if past the parm-initialization insns. */
static int in_nonparm_insns;
\f
-/* Subroutine for `save_for_inline_nocopy'. Performs initialization
+/* Subroutine for `save_for_inline'. Performs initialization
needed to save FNDECL's insns and info for future inline expansion. */
static rtvec
tree parms;
/* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */
- bzero ((char *) parmdecl_map, max_parm_reg * sizeof (tree));
+ memset ((char *) parmdecl_map, 0, max_parm_reg * sizeof (tree));
arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
for (parms = DECL_ARGUMENTS (fndecl), i = 0;
}
/* Copy NODE (which must be a DECL, but not a PARM_DECL). The DECL
- originally was in the FROM_FN, but now it will be in the
+ originally was in the FROM_FN, but now it will be in the
TO_FN. */
tree
/* Set the context for the new declaration. */
if (!DECL_CONTEXT (decl))
/* Globals stay global. */
- ;
+ ;
else if (DECL_CONTEXT (decl) != from_fn)
/* Things that weren't in the scope of the function we're inlining
from aren't in the scope we're inlining too, either. */
functions at the end of compilation. */
void
-save_for_inline_nocopy (fndecl)
+save_for_inline (fndecl)
tree fndecl;
{
rtx insn;
in_nonparm_insns = 0;
save_parm_insns (insn, first_nonparm_insn);
- /* We have now allocated all that needs to be allocated permanently
- on the rtx obstack. Set our high-water mark, so that we
- can free the rest of this when the time comes. */
-
- preserve_data ();
-
cfun->inl_max_label_num = max_label_num ();
cfun->inl_last_parm_insn = cfun->x_last_parm_insn;
cfun->original_arg_vector = argvec;
cfun->original_decl_initial = DECL_INITIAL (fndecl);
+ cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
DECL_SAVED_INSNS (fndecl) = cfun;
/* Clean up. */
static void
save_parm_insns (insn, first_nonparm_insn)
- rtx insn;
- rtx first_nonparm_insn;
+ rtx insn;
+ rtx first_nonparm_insn;
{
if (insn == NULL_RTX)
return;
if (insn == first_nonparm_insn)
in_nonparm_insns = 1;
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
{
/* Record what interesting things happen to our parameters. */
note_stores (PATTERN (insn), note_modified_parmregs, NULL);
/* If this is a CALL_PLACEHOLDER insn then we need to look into the
three attached sequences: normal call, sibling call and tail
- recursion. */
+ recursion. */
if (GET_CODE (insn) == CALL_INSN
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
{
/* Used by duplicate_eh_handlers to map labels for the exception table */
static struct inline_remap *eif_eh_map;
-static rtx
+static rtx
expand_inline_function_eh_labelmap (label)
- rtx label;
+ rtx label;
{
int index = CODE_LABEL_NUMBER (label);
return get_label_from_map (eif_eh_map, index);
tree b1 = *((const tree *) v1);
tree b2 = *((const tree *) v2);
- return ((char *) BLOCK_ABSTRACT_ORIGIN (b1)
+ return ((char *) BLOCK_ABSTRACT_ORIGIN (b1)
- (char *) BLOCK_ABSTRACT_ORIGIN (b2));
}
if (max_regno < FIRST_PSEUDO_REGISTER)
abort ();
+ /* Pull out the decl for the function definition; fndecl may be a
+ local declaration, which would break DECL_ABSTRACT_ORIGIN. */
+ fndecl = inl_f->decl;
+
nargs = list_length (DECL_ARGUMENTS (fndecl));
if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
&& REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
{
- rtx stack_slot
- = assign_stack_temp (TYPE_MODE (TREE_TYPE (arg)),
- int_size_in_bytes (TREE_TYPE (arg)), 1);
- MEM_SET_IN_STRUCT_P (stack_slot,
- AGGREGATE_TYPE_P (TREE_TYPE (arg)));
+ rtx stack_slot = assign_temp (TREE_TYPE (arg), 1, 1, 1);
store_expr (arg, stack_slot, 0);
-
arg_vals[i] = XEXP (stack_slot, 0);
invisiref = 1;
}
mark_reg_pointer (arg_vals[i],
TYPE_ALIGN (TREE_TYPE (TREE_TYPE (formal))));
}
-
+
/* Allocate the structures we use to remap things. */
map = (struct inline_remap *) xmalloc (sizeof (struct inline_remap));
if (map->insns_at_start == 0)
map->insns_at_start = emit_note (NULL_PTR, NOTE_INSN_DELETED);
- map->regno_pointer_flag = inl_f->emit->regno_pointer_flag;
map->regno_pointer_align = inl_f->emit->regno_pointer_align;
+ map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
/* Update the outgoing argument size to allow for those in the inlined
function. */
if (! structure_value_addr
|| ! aggregate_value_p (DECL_RESULT (fndecl)))
abort ();
-
+
/* Pass the function the address in which to return a structure
value. Note that a constructor can cause someone to call us
with STRUCTURE_VALUE_ADDR, but the initialization takes place
{
temp = force_operand (structure_value_addr, NULL_RTX);
temp = force_reg (Pmode, temp);
+ /* A virtual register might be invalid in an insn, because
+ it can cause trouble in reload. Since we don't have access
+ to the expanders at map translation time, make sure we have
+ a proper register now.
+ If a virtual register is actually valid, cse or combine
+ can put it into the mapped insns. */
+ if (REGNO (temp) >= FIRST_VIRTUAL_REGISTER
+ && REGNO (temp) <= LAST_VIRTUAL_REGISTER)
+ temp = copy_to_mode_reg (Pmode, temp);
map->reg_map[REGNO (XEXP (loc, 0))] = temp;
if (CONSTANT_P (structure_value_addr)
{
/* Don't make BLKmode registers. If this looks like
a BLKmode object being returned in a register, get
- the mode from that, otherwise abort. */
+ the mode from that, otherwise abort. */
if (departing_mode == BLKmode)
{
if (REG == GET_CODE (DECL_RTL (DECL_RESULT (fndecl))))
arriving_mode = departing_mode;
}
else
- abort();
+ abort ();
}
-
- target = gen_reg_rtx (departing_mode);
+
+ target = gen_reg_rtx (departing_mode);
}
/* If function's value was promoted before return,
/* Initialize label_map. get_label_from_map will actually make
the labels. */
- bzero ((char *) &map->label_map [min_labelno],
+ memset ((char *) &map->label_map[min_labelno], 0,
(max_labelno - min_labelno) * sizeof (rtx));
/* Make copies of the decls of the symbols in the inline function, so that
/* Sort the block-map so that it will be easy to find remapped
blocks later. */
- qsort (&VARRAY_TREE (map->block_map, 0),
+ qsort (&VARRAY_TREE (map->block_map, 0),
map->block_map->elements_used,
sizeof (tree),
compare_blocks);
insert_block (block);
else
{
- BLOCK_CHAIN (block)
+ BLOCK_CHAIN (block)
= BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
}
emit_line_note (input_filename, lineno);
/* If the function returns a BLKmode object in a register, copy it
- out of the temp register into a BLKmode memory object. */
- if (target
+ out of the temp register into a BLKmode memory object. */
+ if (target
&& TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
&& ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
-
+
if (structure_value_addr)
{
target = gen_rtx_MEM (TYPE_MODE (type),
memory_address (TYPE_MODE (type),
structure_value_addr));
- MEM_SET_IN_STRUCT_P (target, 1);
+ set_mem_attributes (target, type, 1);
}
/* Make sure we free the things we explicitly allocated with xmalloc. */
/* Make copies of each insn in the given list using the mapping
computed in expand_inline_function. This function may call itself for
insns containing sequences.
-
- Copying is done in two passes, first the insns and then their REG_NOTES,
- just like save_for_inline.
+
+ Copying is done in two passes, first the insns and then their REG_NOTES.
If static_chain_value is non-zero, it represents the context-pointer
- register for the function. */
+ register for the function. */
static void
copy_insn_list (insns, map, static_chain_value)
- rtx insns;
- struct inline_remap *map;
- rtx static_chain_value;
+ rtx insns;
+ struct inline_remap *map;
+ rtx static_chain_value;
{
register int i;
rtx insn;
#endif
/* Copy the insns one by one. Do this in two passes, first the insns and
- then their REG_NOTES, just like save_for_inline. */
+ then their REG_NOTES. */
/* This loop is very similar to the loop in copy_loop_body in unroll.c. */
break;
/* If the inline fn needs eh context, make sure that
- the current fn has one. */
+ the current fn has one. */
if (GET_CODE (pattern) == USE
&& find_reg_note (insn, REG_EH_CONTEXT, 0) != 0)
get_eh_context ();
break;
}
+ /* Similarly if an ignored return value is clobbered. */
+ else if (map->inline_target == 0
+ && GET_CODE (pattern) == CLOBBER
+ && GET_CODE (XEXP (pattern, 0)) == REG
+ && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
+ break;
+
/* If this is setting the static chain rtx, omit it. */
else if (static_chain_value != 0
&& set != 0
/* If this used to be a conditional jump insn but whose branch
direction is now know, we must do something special. */
- if (condjump_p (insn) && ! simplejump_p (insn) && map->last_pc_value)
+ if (any_condjump_p (insn) && onlyjump_p (insn) && map->last_pc_value)
{
#ifdef HAVE_cc0
/* If the previous insn set cc0 for us, delete it. */
case CALL_INSN:
/* If this is a CALL_PLACEHOLDER insn then we need to copy the
three attached sequences: normal call, sibling call and tail
- recursion. */
+ recursion. */
if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
{
rtx sequence[3];
for (i = 0; i < 3; i++)
{
rtx seq;
-
+
sequence[i] = NULL_RTX;
seq = XEXP (PATTERN (insn), i);
if (seq)
}
}
- /* Find the new tail recursion label.
+ /* Find the new tail recursion label.
It will already be substituted into sequence[2]. */
tail_label = copy_rtx_and_substitute (XEXP (PATTERN (insn), 3),
map, 0);
- copy = emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode,
- sequence[0],
- sequence[1],
- sequence[2],
- tail_label));
+ copy = emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode,
+ sequence[0],
+ sequence[1],
+ sequence[2],
+ tail_label));
break;
}
copy = emit_call_insn (pattern);
SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
+ CONST_CALL_P (copy) = CONST_CALL_P (insn);
/* Because the USAGE information potentially contains objects other
than hard registers, we need to copy it. */
#endif
try_constants (copy, map);
- /* Be lazy and assume CALL_INSNs clobber all hard registers. */
+ /* Be lazy and assume CALL_INSNs clobber all hard registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
break;
break;
case NOTE:
- /* NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG are
- discarded because it is important to have only one of
+ /* NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG are
+ discarded because it is important to have only one of
each in the current function.
- NOTE_INSN_DELETED notes aren't useful (save_for_inline
- deleted these in the copy used for continuing compilation,
- not the copy used for inlining).
+ NOTE_INSN_DELETED notes aren't useful.
NOTE_INSN_BASIC_BLOCK is discarded because the saved bb
pointer (which will soon be dangling) confuses flow's
rtx label
= get_label_from_map (map, NOTE_EH_HANDLER (copy));
- /* we have to duplicate the handlers for the original */
- if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG)
- {
- /* We need to duplicate the handlers for the EH region
- and we need to indicate where the label map is */
- eif_eh_map = map;
- duplicate_eh_handlers (NOTE_EH_HANDLER (copy),
- CODE_LABEL_NUMBER (label),
- expand_inline_function_eh_labelmap);
- }
+ /* We have to duplicate the handlers for the original. */
+ if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG)
+ {
+ /* We need to duplicate the handlers for the EH region
+ and we need to indicate where the label map is */
+ eif_eh_map = map;
+ duplicate_eh_handlers (NOTE_EH_HANDLER (copy),
+ CODE_LABEL_NUMBER (label),
+ expand_inline_function_eh_labelmap);
+ }
/* We have to forward these both to match the new exception
region. */
tree *mapped_block_p;
mapped_block_p
- = (tree *) bsearch (NOTE_BLOCK (insn),
+ = (tree *) bsearch (NOTE_BLOCK (insn),
&VARRAY_TREE (map->block_map, 0),
map->block_map->elements_used,
sizeof (tree),
find_block);
-
+
if (!mapped_block_p)
abort ();
else
are valid across the entire function. */
map->const_age++;
for (insn = insns; insn; insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ if (INSN_P (insn)
&& map->insn_map[INSN_UID (insn)]
&& REG_NOTES (insn))
{
- rtx tem = copy_rtx_and_substitute (REG_NOTES (insn), map, 0);
+ rtx next, note = copy_rtx_and_substitute (REG_NOTES (insn), map, 0);
/* We must also do subst_constants, in case one of our parameters
has const type and constant value. */
- subst_constants (&tem, NULL_RTX, map, 0);
+ subst_constants (¬e, NULL_RTX, map, 0);
apply_change_group ();
- REG_NOTES (map->insn_map[INSN_UID (insn)]) = tem;
+ REG_NOTES (map->insn_map[INSN_UID (insn)]) = note;
+
+ /* Finally, delete any REG_LABEL notes from the chain. */
+ for (; note; note = next)
+ {
+ next = XEXP (note, 1);
+ if (REG_NOTE_KIND (note) == REG_LABEL)
+ remove_note (map->insn_map[INSN_UID (insn)], note);
+ }
}
if (local_return_label)
{
tree d;
- push_obstacks_nochange ();
- saveable_allocation ();
d = copy_decl_for_inlining (t, map->fndecl, current_function_decl);
- pop_obstacks ();
if (DECL_RTL (t) != 0)
{
TREE_USED (new_block) = TREE_USED (let);
BLOCK_ABSTRACT_ORIGIN (new_block) = let;
-
+
return new_block;
}
\f
{
/* Some hard registers are also mapped,
but others are not translated. */
- if (map->reg_map[regno] != 0)
+ if (map->reg_map[regno] != 0
+ /* We shouldn't usually have reg_map set for return
+ register, but it may happen if we have leaf-register
+ remapping and the return register is used in one of
+ the calling sequences of a call_placeholer. In this
+ case, we'll end up with a reg_map set for this
+ register, but we don't want to use for registers
+ marked as return values. */
+ && ! REG_FUNCTION_VALUE_P (orig))
return map->reg_map[regno];
/* If this is the virtual frame pointer, make space in current
equivalence for it to be the address. This will substitute the
address into insns where it can be substituted and use the new
pseudo where it can't. */
- if (regno == VIRTUAL_STACK_VARS_REGNUM)
+ else if (regno == VIRTUAL_STACK_VARS_REGNUM)
{
rtx loc, seq;
int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
start_sequence ();
loc = assign_stack_temp (BLKmode, size, 1);
loc = XEXP (loc, 0);
- /* When arguments grow downward, the virtual incoming
+ /* When arguments grow downward, the virtual incoming
args pointer points to the top of the argument block,
so the remapped location better do the same. */
#ifdef ARGS_GROW_DOWNWARD
else
return map->inline_target;
}
- return orig;
+#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
+ /* If leaf_renumber_regs_insn() might remap this register to
+ some other number, make sure we don't share it with the
+ inlined function, otherwise delayed optimization of the
+ inlined function may change it in place, breaking our
+ reference to it. We may still shared it within the
+ function, so create an entry for this register in the
+ reg_map. */
+ if (map->integrating && regno < FIRST_PSEUDO_REGISTER
+ && LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
+ {
+ temp = gen_rtx_REG (mode, regno);
+ map->reg_map[regno] = temp;
+ return temp;
+ }
+#endif
+ else
+ return orig;
+
+ abort ();
}
if (map->reg_map[regno] == NULL)
{
RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (orig);
/* A reg with REG_FUNCTION_VALUE_P true will never reach here. */
- if (map->regno_pointer_flag[regno])
+ if (REG_POINTER (map->x_regno_reg_rtx[regno]))
mark_reg_pointer (map->reg_map[regno],
map->regno_pointer_align[regno]);
}
copy = gen_rtx_ADDRESSOF (mode,
copy_rtx_and_substitute (XEXP (orig, 0),
map, for_lhs),
- 0, ADDRESSOF_DECL(orig));
+ 0, ADDRESSOF_DECL (orig));
regno = ADDRESSOF_REGNO (orig);
if (map->reg_map[regno])
regno = REGNO (map->reg_map[regno]);
RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (temp);
/* A reg with REG_FUNCTION_VALUE_P true will never reach here. */
- if (map->regno_pointer_flag[regno])
+ if (REG_POINTER (map->x_regno_reg_rtx[regno]))
mark_reg_pointer (map->reg_map[regno],
map->regno_pointer_align[regno]);
regno = REGNO (map->reg_map[regno]);
copy_rtx_and_substitute (constant, map, for_lhs)),
0);
}
- else
- if (SYMBOL_REF_NEED_ADJUST (orig))
- {
- eif_eh_map = map;
- return rethrow_symbol_map (orig,
- expand_inline_function_eh_labelmap);
- }
+ else if (SYMBOL_REF_NEED_ADJUST (orig))
+ {
+ eif_eh_map = map;
+ return rethrow_symbol_map (orig,
+ expand_inline_function_eh_labelmap);
+ }
return orig;
break;
case ASM_OPERANDS:
- /* If a single asm insn contains multiple output operands
- then it contains multiple ASM_OPERANDS rtx's that share operand 3.
- We must make sure that the copied insn continues to share it. */
- if (map->orig_asm_operands_vector == XVEC (orig, 3))
+ /* If a single asm insn contains multiple output operands then
+ it contains multiple ASM_OPERANDS rtx's that share the input
+ and constraint vecs. We must make sure that the copied insn
+ continues to share it. */
+ if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
{
copy = rtx_alloc (ASM_OPERANDS);
copy->volatil = orig->volatil;
- XSTR (copy, 0) = XSTR (orig, 0);
- XSTR (copy, 1) = XSTR (orig, 1);
- XINT (copy, 2) = XINT (orig, 2);
- XVEC (copy, 3) = map->copy_asm_operands_vector;
- XVEC (copy, 4) = map->copy_asm_constraints_vector;
- XSTR (copy, 5) = XSTR (orig, 5);
- XINT (copy, 6) = XINT (orig, 6);
+ PUT_MODE (copy, GET_MODE (orig));
+ ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
+ ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
+ = ASM_OPERANDS_OUTPUT_CONSTRAINT (orig);
+ ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig);
+ ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
+ ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
+ = map->copy_asm_constraints_vector;
+ ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
+ ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
return copy;
}
break;
if (SET_DEST (orig) == virtual_stack_vars_rtx
|| SET_DEST (orig) == virtual_incoming_args_rtx)
{
- /* In case a translation hasn't occurred already, make one now. */
+ /* In case a translation hasn't occurred already, make one now. */
rtx equiv_reg;
rtx equiv_loc;
HOST_WIDE_INT loc_offset;
REGNO (equiv_reg)).rtx;
loc_offset
= GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1));
-
+
return gen_rtx_SET (VOIDmode, SET_DEST (orig),
force_operand
(plus_constant
XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map, 0);
MEM_COPY_ATTRIBUTES (copy, orig);
return copy;
-
+
default:
break;
}
if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
{
- map->orig_asm_operands_vector = XVEC (orig, 3);
- map->copy_asm_operands_vector = XVEC (copy, 3);
- map->copy_asm_constraints_vector = XVEC (copy, 4);
+ map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
+ map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
+ map->copy_asm_constraints_vector
+ = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
}
return copy;
into insns; cse will do the latter task better.
This function is also used to adjust address of items previously addressed
- via the virtual stack variable or virtual incoming arguments registers.
+ via the virtual stack variable or virtual incoming arguments registers.
If MEMONLY is nonzero, only make changes inside a MEM. */
/* We can't call subst_constants on &SUBREG_REG (x) because any
constant or SUBREG wouldn't be valid inside our SUBEG. Instead,
see what is inside, try to form the new SUBREG and see if that is
- valid. We handle two cases: extracting a full word in an
+ valid. We handle two cases: extracting a full word in an
integral mode and extracting the low part. */
subst_constants (&inner, NULL_RTX, map, 0);
}
format_ptr = GET_RTX_FORMAT (code);
-
+
/* If the first operand is an expression, save its mode for later. */
if (*format_ptr == 'e')
op0_mode = GET_MODE (XEXP (x, 0));
case 'i':
case 's':
case 'w':
- case 'n':
+ case 'n':
case 't':
break;
}
#endif
break;
- }
+ }
case '2':
case 'c':
{
unsigned int uregno = regno;
unsigned int last_reg = (uregno >= FIRST_PSEUDO_REGISTER ? uregno
- : uregno + HARD_REGNO_NREGS (uregno, mode) - 1);
+ : uregno + HARD_REGNO_NREGS (uregno, mode) - 1);
unsigned int i;
/* Ignore virtual stack var or virtual arg register since those
BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;
{
- register tree local_decl;
+ register tree local_decl;
- for (local_decl = BLOCK_VARS (stmt);
+ for (local_decl = BLOCK_VARS (stmt);
local_decl != NULL_TREE;
local_decl = TREE_CHAIN (local_decl))
- set_decl_origin_self (local_decl); /* Potential recursion. */
+ set_decl_origin_self (local_decl); /* Potential recursion. */
}
{
- register tree subblock;
+ register tree subblock;
- for (subblock = BLOCK_SUBBLOCKS (stmt);
+ for (subblock = BLOCK_SUBBLOCKS (stmt);
subblock != NULL_TREE;
subblock = BLOCK_CHAIN (subblock))
- set_block_origin_self (subblock); /* Recurse. */
+ set_block_origin_self (subblock); /* Recurse. */
}
}
}
tree fndecl;
{
struct function *old_cfun = cfun;
+ enum debug_info_type old_write_symbols = write_symbols;
struct function *f = DECL_SAVED_INSNS (fndecl);
cfun = f;
current_function_decl = fndecl;
clear_emit_caches ();
- /* Things we allocate from here on are part of this function, not
- permanent. */
- temporary_allocation ();
-
set_new_last_label_num (f->inl_max_label_num);
/* We're not deferring this any longer. */
DECL_DEFER_OUTPUT (fndecl) = 0;
+ /* If requested, suppress debugging information. */
+ if (f->no_debugging_symbols)
+ write_symbols = NO_DEBUG;
+
/* Compile this function all the way down to assembly code. */
rest_of_compilation (fndecl);
cfun = old_cfun;
current_function_decl = old_cfun ? old_cfun->decl : 0;
+ write_symbols = old_write_symbols;
}