/* Convert a program in SSA form into Normal form.
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Andrew Macleod <amacleod@redhat.com>
#include "ggc.h"
#include "basic-block.h"
#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "tree-flow.h"
#include "timevar.h"
}
}
-/* Emit insns to copy SRC into DEST converting SRC if necessary. */
+/* Emit insns to copy SRC into DEST converting SRC if necessary. As
+ SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
+ which we deduce the size to copy in that case. */
static inline rtx
-emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
+emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
{
rtx seq;
if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp);
- emit_move_insn (dest, src);
+ if (GET_MODE (src) == BLKmode)
+ {
+ gcc_assert (GET_MODE (dest) == BLKmode);
+ emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL);
+ }
+ else
+ emit_move_insn (dest, src);
seq = get_insns ();
end_sequence ();
static void
insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
{
+ tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (locus)
set_curr_insn_source_location (locus);
+ var = partition_to_var (SA.map, src);
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (
- partition_to_var (SA.map, src))));
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}
x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
x = convert_modes (dest_mode, src_mode, x, unsignedp);
}
+ else if (src_mode == BLKmode)
+ {
+ x = SA.partition_to_pseudo[dest];
+ store_expr (src, x, 0, false);
+ }
else
x = expand_expr (src, SA.partition_to_pseudo[dest],
dest_mode, EXPAND_NORMAL);
if (locus)
set_curr_insn_source_location (locus);
+ /* We give the destination as sizeexp in case src/dest are BLKmode
+ mems. Usually we give the source. As we result from SSA names
+ the left and right size should be the same (and no WITH_SIZE_EXPR
+ involved), so it doesn't matter. */
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
- src,
- unsignedsrcp);
+ src, unsignedsrcp,
+ partition_to_var (SA.map, dest));
insert_insn_on_edge (seq, e);
}
static void
insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
{
+ tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (locus)
set_curr_insn_source_location (locus);
+ var = partition_to_var (SA.map, src);
seq = emit_partition_copy (dest,
SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (
- partition_to_var (SA.map, src))));
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}
y_ = VEC_index (int, (GRAPH)->edge_list, x_); \
if (y_ != (NODE)) \
continue; \
- (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \
- (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
+ (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1)); \
+ (void) ((LOCUS) = VEC_index (source_location, \
+ (GRAPH)->edge_locus, x_ / 2)); \
CODE; \
} \
} while (0)
y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \
if (y_ != (NODE)) \
continue; \
- (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \
- (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
+ (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_)); \
+ (void) ((LOCUS) = VEC_index (source_location, \
+ (GRAPH)->edge_locus, x_ / 2)); \
CODE; \
} \
} while (0)
FOR_EACH_IMM_USE_FAST (use, imm_iter, result)
{
gimple use_stmt = USE_STMT (use);
+ if (is_gimple_debug (use_stmt))
+ continue;
/* Now, if there's a use of RESULT that lies outside this basic block,
then there surely is a conflict with ARG. */
if (gimple_bb (use_stmt) != bb)