#include "except.h"
#include "flags.h"
#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
#include "toplev.h"
#include "debug.h"
#include "params.h"
#include "value-prof.h"
#include "target.h"
#include "ssaexpand.h"
-
+#include "bitmap.h"
+#include "sbitmap.h"
+#include "insn-attr.h" /* For INSN_SCHEDULING. */
/* This variable holds information helping the rewriting of SSA trees
into RTL. */
grhs_class = get_gimple_rhs_class (gimple_expr_code (stmt));
- if (grhs_class == GIMPLE_BINARY_RHS)
+ if (grhs_class == GIMPLE_TERNARY_RHS)
+ t = build3 (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ gimple_assign_rhs3 (stmt));
+ else if (grhs_class == GIMPLE_BINARY_RHS)
t = build2 (gimple_assign_rhs_code (stmt),
TREE_TYPE (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt),
for (j = i; j != EOC; j = stack_vars[j].next)
{
tree decl = stack_vars[j].decl;
- unsigned int uid = DECL_UID (decl);
+ unsigned int uid = DECL_PT_UID (decl);
/* We should never end up partitioning SSA names (though they
may end up on the stack). Neither should we allocate stack
space to something that is unused and thus unreferenced. */
gcc_assert (DECL_P (decl)
- && referenced_var_lookup (uid));
+ && referenced_var_lookup (DECL_UID (decl)));
bitmap_set_bit (part, uid);
*((bitmap *) pointer_map_insert (decls_to_partitions,
(void *)(size_t) uid)) = part;
/* Make the SSA name point to all partition members. */
pi = get_ptr_info (name);
- pt_solution_set (&pi->pt, part);
+ pt_solution_set (&pi->pt, part, false, false);
}
/* Make all points-to sets that contain one member of a partition
add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped,
decls_to_partitions, visited, temp);
- add_partitioned_vars_to_ptset (&cfun->gimple_df->callused,
- decls_to_partitions, visited, temp);
pointer_set_destroy (visited);
pointer_map_destroy (decls_to_partitions);
ops.type = TREE_TYPE (lhs);
switch (get_gimple_rhs_class (gimple_expr_code (stmt)))
{
+ case GIMPLE_TERNARY_RHS:
+ ops.op2 = gimple_assign_rhs3 (stmt);
+ /* Fallthru */
case GIMPLE_BINARY_RHS:
ops.op1 = gimple_assign_rhs2 (stmt);
/* Fallthru */
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
addr_space_t as;
- enum machine_mode address_mode;
switch (TREE_CODE_CLASS (TREE_CODE (exp)))
{
{
case COND_EXPR:
case DOT_PROD_EXPR:
+ case WIDEN_MULT_PLUS_EXPR:
+ case WIDEN_MULT_MINUS_EXPR:
goto ternary;
case TRUTH_ANDIF_EXPR:
return op0;
}
+ case MEM_REF:
+ /* ??? FIXME. */
+ if (!integer_zerop (TREE_OPERAND (exp, 1)))
+ return NULL;
+ /* Fallthru. */
case INDIRECT_REF:
- case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
if (!op0)
return NULL;
if (POINTER_TYPE_P (TREE_TYPE (exp)))
- {
- as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
- address_mode = targetm.addr_space.address_mode (as);
- }
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
else
- {
- as = ADDR_SPACE_GENERIC;
- address_mode = Pmode;
- }
-
- if (TREE_CODE (exp) == ALIGN_INDIRECT_REF)
- {
- int align = TYPE_ALIGN_UNIT (TREE_TYPE (exp));
- op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
- }
+ as = ADDR_SPACE_GENERIC;
op0 = gen_rtx_MEM (mode, op0);
if (bitpos < 0)
return NULL;
+ if (GET_MODE (op0) == BLKmode)
+ return NULL;
+
if ((bitpos % BITS_PER_UNIT) == 0
&& bitsize == GET_MODE_BITSIZE (mode1))
{
enum machine_mode opmode = GET_MODE (op0);
- gcc_assert (opmode != BLKmode);
-
if (opmode == VOIDmode)
opmode = mode1;
return gen_rtx_FIX (mode, op0);
case POINTER_PLUS_EXPR:
+ /* For the rare target where pointers are not the same size as
+ size_t, we need to check for mis-matched modes and correct
+ the addend. */
+ if (op0 && op1
+ && GET_MODE (op0) != VOIDmode && GET_MODE (op1) != VOIDmode
+ && GET_MODE (op0) != GET_MODE (op1))
+ {
+ if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE (op1)))
+ op1 = gen_rtx_TRUNCATE (GET_MODE (op0), op1);
+ else
+ /* We always sign-extend, regardless of the signedness of
+ the operand, because the operand is always unsigned
+ here even if the original C expression is signed. */
+ op1 = gen_rtx_SIGN_EXTEND (GET_MODE (op0), op1);
+ }
+ /* Fall through. */
case PLUS_EXPR:
return gen_rtx_PLUS (mode, op0, op1);
return NULL;
case WIDEN_MULT_EXPR:
+ case WIDEN_MULT_PLUS_EXPR:
+ case WIDEN_MULT_MINUS_EXPR:
if (SCALAR_INT_MODE_P (GET_MODE (op0))
&& SCALAR_INT_MODE_P (mode))
{
+ enum machine_mode inner_mode = GET_MODE (op0);
if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))))
- op0 = gen_rtx_ZERO_EXTEND (mode, op0);
+ op0 = simplify_gen_unary (ZERO_EXTEND, mode, op0, inner_mode);
else
- op0 = gen_rtx_SIGN_EXTEND (mode, op0);
+ op0 = simplify_gen_unary (SIGN_EXTEND, mode, op0, inner_mode);
if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1))))
- op1 = gen_rtx_ZERO_EXTEND (mode, op1);
+ op1 = simplify_gen_unary (ZERO_EXTEND, mode, op1, inner_mode);
else
- op1 = gen_rtx_SIGN_EXTEND (mode, op1);
- return gen_rtx_MULT (mode, op0, op1);
+ op1 = simplify_gen_unary (SIGN_EXTEND, mode, op1, inner_mode);
+ op0 = gen_rtx_MULT (mode, op0, op1);
+ if (TREE_CODE (exp) == WIDEN_MULT_EXPR)
+ return op0;
+ else if (TREE_CODE (exp) == WIDEN_MULT_PLUS_EXPR)
+ return gen_rtx_PLUS (mode, op0, op2);
+ else
+ return gen_rtx_MINUS (mode, op2, op0);
}
return NULL;
stack. We check PREFERRED_STACK_BOUNDARY if there may be non-call
exceptions since callgraph doesn't collect incoming stack alignment
in this case. */
- if (flag_non_call_exceptions
+ if (cfun->can_throw_non_call_exceptions
&& PREFERRED_STACK_BOUNDARY > crtl->preferred_stack_boundary)
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
else
edge e;
unsigned i;
+ timevar_push (TV_OUT_OF_SSA);
rewrite_out_of_ssa (&SA);
+ timevar_pop (TV_OUT_OF_SSA);
SA.partition_to_pseudo = (rtx *)xcalloc (SA.map->num_partitions,
sizeof (rtx));
set_curr_insn_block (DECL_INITIAL (current_function_decl));
prologue_locator = curr_insn_locator ();
+#ifdef INSN_SCHEDULING
+ init_sched_attrs ();
+#endif
+
/* Make sure first insn is a note even if we don't want linenums.
This makes sure the first insn will never be deleted.
Also, final expects a note to appear there. */
/* Expand the variables recorded during gimple lowering. */
+ timevar_push (TV_VAR_EXPAND);
expand_used_vars ();
+ timevar_pop (TV_VAR_EXPAND);
/* Honor stack protection warnings. */
if (warn_stack_protect)
{
if (cfun->calls_alloca)
warning (OPT_Wstack_protector,
- "not protecting local variables: variable length buffer");
+ "stack protector not protecting local variables: "
+ "variable length buffer");
if (has_short_buffer && !crtl->stack_protect_guard)
warning (OPT_Wstack_protector,
- "not protecting function: no buffer at least %d bytes long",
+ "stack protector not protecting function: "
+ "all local arrays are less than %d bytes long",
(int) PARAM_VALUE (PARAM_SSP_BUFFER_SIZE));
}
expand_debug_locations ();
execute_free_datastructures ();
+ timevar_push (TV_OUT_OF_SSA);
finish_out_of_ssa (&SA);
+ timevar_pop (TV_OUT_OF_SSA);
+ timevar_push (TV_POST_EXPAND);
/* We are no longer in SSA form. */
cfun->gimple_df->in_ssa_p = false;
the common parent easily. */
set_block_levels (DECL_INITIAL (cfun->decl), 0);
default_rtl_profile ();
+ timevar_pop (TV_POST_EXPAND);
return 0;
}