#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
{
tree size = (*lang_hooks.expr_size) (exp);
- if (TREE_CODE (size) != INTEGER_CST
- && contains_placeholder_p (size))
+ if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
/* We can set RTX_UNCHANGING_P from TREE_READONLY for decls whose
initialization is only executed once, or whose initializer always
has the same value. Currently we simplify this to PARM_DECLs in the
- first case, and decls with TREE_CONSTANT initializers in the second. */
+ first case, and decls with TREE_CONSTANT initializers in the second.
+
+ We cannot do this for non-static aggregates, because of the double
+ writes that can be generated by store_constructor, depending on the
+ contents of the initializer. Yes, this does eliminate a good fraction
+ of the number of uses of RTX_UNCHANGING_P for a language like Ada.
+ It also eliminates a good quantity of bugs. Let this be incentive to
+ eliminate RTX_UNCHANGING_P entirely in favour of a more reliable
+ solution, perhaps based on alias sets. */
+
if ((TREE_READONLY (t) && DECL_P (t)
+ && (TREE_STATIC (t) || ! AGGREGATE_TYPE_P (TREE_TYPE (t)))
&& (TREE_CODE (t) == PARM_DECL
- || DECL_INITIAL (t) == NULL_TREE
- || TREE_CONSTANT (DECL_INITIAL (t))))
+ || (DECL_INITIAL (t) && TREE_CONSTANT (DECL_INITIAL (t)))))
|| TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
RTX_UNCHANGING_P (ref) = 1;
}
stabilize (x)
rtx x;
{
-
if (GET_CODE (x) != MEM
|| ! rtx_unstable_p (XEXP (x, 0)))
return x;
if INSN set something else (such as a SUBREG of TEMP). */
if (CONSTANT_P (x)
&& (set = single_set (insn)) != 0
- && SET_DEST (set) == temp)
+ && SET_DEST (set) == temp
+ && ! rtx_equal_p (x, SET_SRC (set)))
set_unique_reg_note (insn, REG_EQUAL, x);
return temp;
rtx size;
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
if (align == 1)
return size;
+
if (GET_CODE (size) == CONST_INT)
{
- int new = (INTVAL (size) + align - 1) / align * align;
+ HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align;
+
if (INTVAL (size) != new)
size = GEN_INT (new);
}
NULL_RTX, 1);
size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
}
+
return size;
}
\f
pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate;
if (pred && ! ((*pred) (size, mode)))
- size = copy_to_mode_reg (mode, size);
+ size = copy_to_mode_reg (mode, convert_to_mode (mode, size, 1));
emit_insn (gen_allocate_stack (target, size));
}
NULL_RTX, 1);
}
- /* Some systems require a particular insn to refer to the stack
- to make the pages exist. */
-#ifdef HAVE_probe
- if (HAVE_probe)
- emit_insn (gen_probe ());
-#endif
-
/* Record the new stack level for nonlocal gotos. */
if (nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);