[tuples] Convert prefetching and related passes

Zdenek Dvorak rakdver@kam.mff.cuni.cz
Sun Mar 9 22:43:00 GMT 2008


Hi,

this patch converts loop prefetching and the related infrastructure
(dependency analysis, loop unrolling and versioning, and branch prediction).

Prefetching marks some assignment statements as nontemporal stores, I used one of
the unused flags in gimple_statement_base for it, as just now there does
not seem to be any other way how to add a flag to GIMPLE_ASSIGN
statements.

Additionally, number of smaller bugfixes is needed to fix the
regressions caused by the changes:

1) allocate_phi_node failed if the vector in free_phinodes was empty,
   but not NULL.
2) I have added two new functions (gimple_assign_rhs_code that returns
   the tree code of the rhs of an assignment -- it may differ from
   gimple_assign_subcode for SINGLE_RHS objects), and
   gimple_assign_rhs2_or_null (that returns NULL for non-binary
   right-hand sides), that simplify the code on a few places a bit.
3) I also went over all calls of gimple_assign_subcode and converted
   some of them to gimple_assign_rhs_code (there was one place where
   I am sure that it is necessary, and two or three where I was not
   sure, but it cannot harm).  The uses of gimple_assign_subcode
   in tree-ssa-coalesce.c were just wrong and are replaced with
   gimple_assign_copy_p calls.
4) gimplification forgets to set the ssa name in the lhs of newly created
   assignment.

I need a review for these changes outside of the loop optimizer, as well
as the branch prediction conversion.

Zdenek

	* tree-ssa-loop-niter.c (chain_of_csts_start): Exclude memory loads.
	(get_val_for): Assert that the statement is an assignment.
	(derive_constant_upper_bound_assign): Use gimple_assign_rhs_code
	and gimple_assign_rhs2_or_null.
	* tree-ssa-loop-manip.c (create_iv, ip_normal_pos,
	standard_iv_increment_position, determine_exit_conditions,
	tree_transform_and_unroll_loop): Tuplify.
	* tree-scalar-evolution.c (interpret_expr): Fail for chrecs.
	(interpret_gimple_assign): Use gimple_assign_rhs_code and
	gimple_assign_rhs2_or_null.
	* tree-phinodes.c (allocate_phi_node): Test whether the queue
	is free using VEC_empty.
	* tree-gimple.c (gimple_assign_rhs_code): New function.
	* tree-gimple.h (gimple_assign_rhs_code): Declare.
	* tree-ssa-loop-ivopts.c (single_dom_exit): Enable.
	* gimple-dummy.c (compute_data_dependences_for_loop, dump_ddrs,
	free_data_refs, free_dependence_relations,
	gimple_duplicate_loop_to_header_edge, tree_ssa_prefetch_arrays,
	estimated_loop_iterations_int): Removed.
	* tree-ssa-loop-ivcanon.c (tree_num_loop_insns): Tuplify.
	* predict.c, tree-data-ref.c, tree-ssa-loop-prefetch.c: Tuplify.
	* tree-data-ref.h (struct data_reference, struct rdg_vertex): Change
	the type of stmt to gimple.
	(get_references_in_stmt, create_data_ref, rdg_vertex_for_stmt,
	stores_from_loop, remove_similar_memory_refs,
	have_similar_memory_accesses): Declaration changed.
	* gimple-iterator.c (gsi_insert_seq_on_edge_immediate): New.
	* gimple-pretty-print.c (dump_gimple_assign): Dump nontemporal
	move.
	* gimplify.c (gimplify_modify_expr): Set lhs of the assignment to
	the new SSA name.
	* tree-ssa-coalesce.c (build_ssa_conflict_graph,
	create_outofssa_var_map): Use gimple_assign_copy_p.
	* tree-predcom.c (mark_virtual_ops_for_renaming): Enable.
	* tree-inline.c (estimate_num_insns): Use gimple_assign_rhs_code.
	* tree-flow.h (mark_virtual_ops_for_renaming): Declaration changed.
	* gimple.h (struct gimple_statement_base): Change unused_4 flag
	to nontemporal_move flag.
	(gimple_assign_rhs2_or_null, gimple_assign_nontemporal_move_p,
	gimple_assign_set_nontemporal_move): New functions.
	(gsi_insert_seq_on_edge_immediate): Declare.
	* tree-cfg.c (verify_types_in_gimple_assign): Use
	gimple_assign_rhs_code.
	(gimple_lv_adjust_loop_header_phi, gimple_lv_add_condition_to_bb):
	Tuplify.
	(gimple_cfg_hooks): Enable lv_add_condition_to_bb and
	lv_adjust_loop_header_phi hooks.
	* passes.c (init_optimization_passes): Enable pass_profile,
	pass_check_data_deps and pass_loop_prefetch.

Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 133063)
--- tree-ssa-loop-niter.c	(working copy)
*************** chain_of_csts_start (struct loop *loop, 
*** 1953,1958 ****
--- 1953,1959 ----
    gimple stmt = SSA_NAME_DEF_STMT (x);
    tree use;
    basic_block bb = gimple_bb (stmt);
+   enum tree_code code;
  
    if (!bb
        || !flow_bb_inside_loop_p (loop, bb))
*************** chain_of_csts_start (struct loop *loop, 
*** 1969,1977 ****
    if (gimple_code (stmt) != GIMPLE_ASSIGN)
      return NULL;
  
!   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
!     return NULL;
!   if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
      return NULL;
  
    use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
--- 1970,1984 ----
    if (gimple_code (stmt) != GIMPLE_ASSIGN)
      return NULL;
  
!   code = gimple_assign_rhs_code (stmt);
!   if (stmt_references_memory_p (stmt)
!       /* Before alias information is computed, operand scanning marks
! 	 statements that write memory volatile.  However, the statements
! 	 that only read memory are not marked, thus stmt_references_memory_p
! 	 returns false for them.  */
!       || TREE_CODE_CLASS (code) == tcc_reference
!       || TREE_CODE_CLASS (code) == tcc_declaration
!       || SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
      return NULL;
  
    use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
*************** get_val_for (tree x, tree base)
*** 2044,2049 ****
--- 2051,2058 ----
    if (gimple_code (stmt) == GIMPLE_PHI)
      return base;
  
+   gcc_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
+ 
    FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
      {
        /* FIXME -- rewriting the statement this way in order to fold its rhs
*************** static double_int derive_constant_upper_
*** 2206,2215 ****
  static double_int
  derive_constant_upper_bound_assign (gimple stmt)
  {
!   enum tree_code code = gimple_assign_subcode (stmt);
    tree op0 = gimple_assign_rhs1 (stmt);
!   tree op1 = (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
! 	      ? gimple_assign_rhs2 (stmt) : NULL_TREE);
  
    return derive_constant_upper_bound_ops (TREE_TYPE (gimple_assign_lhs (stmt)),
  					  op0, code, op1);
--- 2215,2223 ----
  static double_int
  derive_constant_upper_bound_assign (gimple stmt)
  {
!   enum tree_code code = gimple_assign_rhs_code (stmt);
    tree op0 = gimple_assign_rhs1 (stmt);
!   tree op1 = gimple_assign_rhs2_or_null (stmt);
  
    return derive_constant_upper_bound_ops (TREE_TYPE (gimple_assign_lhs (stmt)),
  					  op0, code, op1);
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 133063)
--- tree-ssa-loop-manip.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 38,45 ****
  #include "params.h"
  #include "tree-inline.h"
  
- /* FIXME tuples.  */
- #if 0
  /* Creates an induction variable with value BASE + STEP * iteration in LOOP.
     It is expected that neither BASE nor STEP are shared with other expressions
     (unless the sharing rules allow this).  Use VAR as a base var_decl for it
--- 38,43 ----
*************** along with GCC; see the file COPYING3.  
*** 51,60 ****
  
  void
  create_iv (tree base, tree step, tree var, struct loop *loop,
! 	   block_stmt_iterator *incr_pos, bool after,
  	   tree *var_before, tree *var_after)
  {
!   tree stmt, initial, step1, stmts;
    tree vb, va;
    enum tree_code incr_op = PLUS_EXPR;
    edge pe = loop_preheader_edge (loop);
--- 49,60 ----
  
  void
  create_iv (tree base, tree step, tree var, struct loop *loop,
! 	   gimple_stmt_iterator *incr_pos, bool after,
  	   tree *var_before, tree *var_after)
  {
!   gimple stmt;
!   tree initial, step1;
!   gimple_seq stmts;
    tree vb, va;
    enum tree_code incr_op = PLUS_EXPR;
    edge pe = loop_preheader_edge (loop);
*************** create_iv (tree base, tree step, tree va
*** 65,74 ****
        add_referenced_var (var);
      }
  
!   vb = make_ssa_name (var, NULL_TREE);
    if (var_before)
      *var_before = vb;
!   va = make_ssa_name (var, NULL_TREE);
    if (var_after)
      *var_after = va;
  
--- 65,74 ----
        add_referenced_var (var);
      }
  
!   vb = make_ssa_name (var, NULL);
    if (var_before)
      *var_before = vb;
!   va = make_ssa_name (var, NULL);
    if (var_after)
      *var_after = va;
  
*************** create_iv (tree base, tree step, tree va
*** 108,134 ****
       loop (i.e. the step should be loop invariant).  */
    step = force_gimple_operand (step, &stmts, true, var);
    if (stmts)
!     bsi_insert_on_edge_immediate (pe, stmts);
  
!   stmt = build_gimple_modify_stmt (va,
! 				   build2 (incr_op, TREE_TYPE (base),
! 					   vb, step));
    SSA_NAME_DEF_STMT (va) = stmt;
    if (after)
!     bsi_insert_after (incr_pos, stmt, BSI_NEW_STMT);
    else
!     bsi_insert_before (incr_pos, stmt, BSI_NEW_STMT);
  
    initial = force_gimple_operand (base, &stmts, true, var);
    if (stmts)
!     bsi_insert_on_edge_immediate (pe, stmts);
  
    stmt = create_phi_node (vb, loop->header);
    SSA_NAME_DEF_STMT (vb) = stmt;
    add_phi_arg (stmt, initial, loop_preheader_edge (loop));
    add_phi_arg (stmt, va, loop_latch_edge (loop));
  }
- #endif
  
  /* Add exit phis for the USE on EXIT.  */
  
--- 108,131 ----
       loop (i.e. the step should be loop invariant).  */
    step = force_gimple_operand (step, &stmts, true, var);
    if (stmts)
!     gsi_insert_seq_on_edge_immediate (pe, stmts);
  
!   stmt = gimple_build_assign_with_ops (incr_op, va, vb, step);
    SSA_NAME_DEF_STMT (va) = stmt;
    if (after)
!     gsi_insert_after (incr_pos, stmt, GSI_NEW_STMT);
    else
!     gsi_insert_before (incr_pos, stmt, GSI_NEW_STMT);
  
    initial = force_gimple_operand (base, &stmts, true, var);
    if (stmts)
!     gsi_insert_seq_on_edge_immediate (pe, stmts);
  
    stmt = create_phi_node (vb, loop->header);
    SSA_NAME_DEF_STMT (vb) = stmt;
    add_phi_arg (stmt, initial, loop_preheader_edge (loop));
    add_phi_arg (stmt, va, loop_latch_edge (loop));
  }
  
  /* Add exit phis for the USE on EXIT.  */
  
*************** split_loop_exit_edge (edge exit)
*** 499,506 ****
    return bb;
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Returns the basic block in that statements should be emitted for induction
     variables incremented at the end of the LOOP.  */
  
--- 496,501 ----
*************** ip_end_pos (struct loop *loop)
*** 516,522 ****
  basic_block
  ip_normal_pos (struct loop *loop)
  {
!   tree last;
    basic_block bb;
    edge exit;
  
--- 511,517 ----
  basic_block
  ip_normal_pos (struct loop *loop)
  {
!   gimple last;
    basic_block bb;
    edge exit;
  
*************** ip_normal_pos (struct loop *loop)
*** 526,532 ****
    bb = single_pred (loop->latch);
    last = last_stmt (bb);
    if (!last
!       || TREE_CODE (last) != COND_EXPR)
      return NULL;
  
    exit = EDGE_SUCC (bb, 0);
--- 521,527 ----
    bb = single_pred (loop->latch);
    last = last_stmt (bb);
    if (!last
!       || gimple_code (last) != GIMPLE_COND)
      return NULL;
  
    exit = EDGE_SUCC (bb, 0);
*************** ip_normal_pos (struct loop *loop)
*** 545,565 ****
     the increment should be inserted after *BSI.  */
  
  void
! standard_iv_increment_position (struct loop *loop, block_stmt_iterator *bsi,
  				bool *insert_after)
  {
    basic_block bb = ip_normal_pos (loop), latch = ip_end_pos (loop);
!   tree last = last_stmt (latch);
  
    if (!bb
!       || (last && TREE_CODE (last) != LABEL_EXPR))
      {
!       *bsi = bsi_last (latch);
        *insert_after = true;
      }
    else
      {
!       *bsi = bsi_last (bb);
        *insert_after = false;
      }
  }
--- 540,560 ----
     the increment should be inserted after *BSI.  */
  
  void
! standard_iv_increment_position (struct loop *loop, gimple_stmt_iterator *bsi,
  				bool *insert_after)
  {
    basic_block bb = ip_normal_pos (loop), latch = ip_end_pos (loop);
!   gimple last = last_stmt (latch);
  
    if (!bb
!       || (last && gimple_code (last) != GIMPLE_LABEL))
      {
!       *bsi = gsi_last_bb (latch);
        *insert_after = true;
      }
    else
      {
!       *bsi = gsi_last_bb (bb);
        *insert_after = false;
      }
  }
*************** determine_exit_conditions (struct loop *
*** 681,687 ****
  			   tree *exit_base, tree *exit_step,
  			   enum tree_code *exit_cmp, tree *exit_bound)
  {
!   tree stmts;
    tree base = desc->control.base;
    tree step = desc->control.step;
    tree bound = desc->bound;
--- 676,682 ----
  			   tree *exit_base, tree *exit_step,
  			   enum tree_code *exit_cmp, tree *exit_bound)
  {
!   gimple_seq stmts;
    tree base = desc->control.base;
    tree step = desc->control.step;
    tree bound = desc->bound;
*************** determine_exit_conditions (struct loop *
*** 756,762 ****
  
    cond = force_gimple_operand (unshare_expr (cond), &stmts, false, NULL_TREE);
    if (stmts)
!     bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
    /* cond now may be a gimple comparison, which would be OK, but also any
       other gimple rhs (say a && b).  In this case we need to force it to
       operand.  */
--- 751,757 ----
  
    cond = force_gimple_operand (unshare_expr (cond), &stmts, false, NULL_TREE);
    if (stmts)
!     gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
    /* cond now may be a gimple comparison, which would be OK, but also any
       other gimple rhs (say a && b).  In this case we need to force it to
       operand.  */
*************** determine_exit_conditions (struct loop *
*** 764,779 ****
      {
        cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
        if (stmts)
! 	bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
      }
    *enter_cond = cond;
  
    base = force_gimple_operand (unshare_expr (base), &stmts, true, NULL_TREE);
    if (stmts)
!     bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
    bound = force_gimple_operand (unshare_expr (bound), &stmts, true, NULL_TREE);
    if (stmts)
!     bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
  
    *exit_base = base;
    *exit_step = bigstep;
--- 759,774 ----
      {
        cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
        if (stmts)
! 	gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
      }
    *enter_cond = cond;
  
    base = force_gimple_operand (unshare_expr (base), &stmts, true, NULL_TREE);
    if (stmts)
!     gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
    bound = force_gimple_operand (unshare_expr (bound), &stmts, true, NULL_TREE);
    if (stmts)
!     gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
  
    *exit_base = base;
    *exit_step = bigstep;
*************** tree_transform_and_unroll_loop (struct l
*** 867,881 ****
  				transform_callback transform,
  				void *data)
  {
!   tree  exit_if, ctr_before, ctr_after;
    tree enter_main_cond, exit_base, exit_step, exit_bound;
    enum tree_code exit_cmp;
!   tree phi_old_loop, phi_new_loop, phi_rest, init, next, new_init, var;
    struct loop *new_loop;
    basic_block rest, exit_bb;
    edge old_entry, new_entry, old_latch, precond_edge, new_exit;
    edge new_nonexit, e;
!   block_stmt_iterator bsi;
    use_operand_p op;
    bool ok;
    unsigned est_niter, prob_entry, scale_unrolled, scale_rest, freq_e, freq_h;
--- 862,879 ----
  				transform_callback transform,
  				void *data)
  {
!   gimple exit_if;
!   tree ctr_before, ctr_after;
    tree enter_main_cond, exit_base, exit_step, exit_bound;
    enum tree_code exit_cmp;
!   gimple phi_old_loop, phi_new_loop, phi_rest;
!   gimple_stmt_iterator psi_old_loop, psi_new_loop;
!   tree init, next, new_init, var;
    struct loop *new_loop;
    basic_block rest, exit_bb;
    edge old_entry, new_entry, old_latch, precond_edge, new_exit;
    edge new_nonexit, e;
!   gimple_stmt_iterator bsi;
    use_operand_p op;
    bool ok;
    unsigned est_niter, prob_entry, scale_unrolled, scale_rest, freq_e, freq_h;
*************** tree_transform_and_unroll_loop (struct l
*** 945,955 ****
  				  REG_BR_PROB_BASE,
  				  REG_BR_PROB_BASE - exit->probability);
  
!   bsi = bsi_last (exit_bb);
!   exit_if = build3 (COND_EXPR, void_type_node, boolean_true_node,
! 		    NULL_TREE, NULL_TREE);
  
!   bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT);
    new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
    rescan_loop_exit (new_exit, true, false);
  
--- 943,954 ----
  				  REG_BR_PROB_BASE,
  				  REG_BR_PROB_BASE - exit->probability);
  
!   bsi = gsi_last_bb (exit_bb);
!   exit_if = gimple_build_cond (EQ_EXPR, integer_zero_node,
! 			       integer_zero_node,
! 			       NULL_TREE, NULL_TREE);
  
!   gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
    new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
    rescan_loop_exit (new_exit, true, false);
  
*************** tree_transform_and_unroll_loop (struct l
*** 970,981 ****
    old_entry = loop_preheader_edge (loop);
    new_entry = loop_preheader_edge (new_loop);
    old_latch = loop_latch_edge (loop);
!   for (phi_old_loop = phi_nodes (loop->header),
!        phi_new_loop = phi_nodes (new_loop->header);
!        phi_old_loop;
!        phi_old_loop = PHI_CHAIN (phi_old_loop),
!        phi_new_loop = PHI_CHAIN (phi_new_loop))
      {
        init = PHI_ARG_DEF_FROM_EDGE (phi_old_loop, old_entry);
        op = PHI_ARG_DEF_PTR_FROM_EDGE (phi_new_loop, new_entry);
        gcc_assert (operand_equal_for_phi_arg_p (init, USE_FROM_PTR (op)));
--- 969,982 ----
    old_entry = loop_preheader_edge (loop);
    new_entry = loop_preheader_edge (new_loop);
    old_latch = loop_latch_edge (loop);
!   for (psi_old_loop = gsi_start (phi_nodes (loop->header)),
!        psi_new_loop = gsi_start (phi_nodes (new_loop->header));
!        !gsi_end_p (psi_old_loop);
!        gsi_next (&psi_old_loop), gsi_next (&psi_new_loop))
      {
+       phi_old_loop = gsi_stmt (psi_old_loop);
+       phi_new_loop = gsi_stmt (psi_new_loop);
+ 
        init = PHI_ARG_DEF_FROM_EDGE (phi_old_loop, old_entry);
        op = PHI_ARG_DEF_PTR_FROM_EDGE (phi_new_loop, new_entry);
        gcc_assert (operand_equal_for_phi_arg_p (init, USE_FROM_PTR (op)));
*************** tree_transform_and_unroll_loop (struct l
*** 994,1000 ****
  	  add_referenced_var (var);
  	}
  
!       new_init = make_ssa_name (var, NULL_TREE);
        phi_rest = create_phi_node (new_init, rest);
        SSA_NAME_DEF_STMT (new_init) = phi_rest;
  
--- 995,1001 ----
  	  add_referenced_var (var);
  	}
  
!       new_init = make_ssa_name (var, NULL);
        phi_rest = create_phi_node (new_init, rest);
        SSA_NAME_DEF_STMT (new_init) = phi_rest;
  
*************** tree_transform_and_unroll_loop (struct l
*** 1015,1021 ****
    sbitmap_ones (wont_exit);
    RESET_BIT (wont_exit, factor - 1);
  
!   ok = tree_duplicate_loop_to_header_edge
  	  (loop, loop_latch_edge (loop), factor - 1,
  	   wont_exit, new_exit, &to_remove, DLTHE_FLAG_UPDATE_FREQ);
    free (wont_exit);
--- 1016,1022 ----
    sbitmap_ones (wont_exit);
    RESET_BIT (wont_exit, factor - 1);
  
!   ok = gimple_duplicate_loop_to_header_edge
  	  (loop, loop_latch_edge (loop), factor - 1,
  	   wont_exit, new_exit, &to_remove, DLTHE_FLAG_UPDATE_FREQ);
    free (wont_exit);
*************** tree_transform_and_unroll_loop (struct l
*** 1057,1068 ****
  
    /* Finally create the new counter for number of iterations and add the new
       exit instruction.  */
!   bsi = bsi_last (exit_bb);
!   exit_if = bsi_stmt (bsi);
    create_iv (exit_base, exit_step, NULL_TREE, loop,
  	     &bsi, false, &ctr_before, &ctr_after);
!   COND_EXPR_COND (exit_if) = build2 (exit_cmp, boolean_type_node, ctr_after,
! 				     exit_bound);
    update_stmt (exit_if);
  
  #ifdef ENABLE_CHECKING
--- 1058,1070 ----
  
    /* Finally create the new counter for number of iterations and add the new
       exit instruction.  */
!   bsi = gsi_last_bb (exit_bb);
!   exit_if = gsi_stmt (bsi);
    create_iv (exit_base, exit_step, NULL_TREE, loop,
  	     &bsi, false, &ctr_before, &ctr_after);
!   gimple_cond_set_code (exit_if, exit_cmp);
!   gimple_cond_set_lhs (exit_if, ctr_after);
!   gimple_cond_set_rhs (exit_if, exit_bound);
    update_stmt (exit_if);
  
  #ifdef ENABLE_CHECKING
*************** tree_unroll_loop (struct loop *loop, uns
*** 1084,1087 ****
    tree_transform_and_unroll_loop (loop, factor, exit, desc,
  				  NULL, NULL);
  }
- #endif
--- 1086,1088 ----
Index: tree-scalar-evolution.c
===================================================================
*** tree-scalar-evolution.c	(revision 133063)
--- tree-scalar-evolution.c	(working copy)
*************** interpret_expr (struct loop *loop, gimpl
*** 1704,1709 ****
--- 1704,1712 ----
    if (automatically_generated_chrec_p (expr))
      return expr;
  
+   if (TREE_CODE (expr) == POLYNOMIAL_CHREC)
+     return chrec_dont_know;
+ 
    extract_ops_from_tree (expr, &code, &op0, &op1);
  
    return interpret_rhs_expr (loop, at_stmt, type,
*************** static tree
*** 1716,1737 ****
  interpret_gimple_assign (struct loop *loop, gimple stmt)
  {
    tree type = TREE_TYPE (gimple_assign_lhs (stmt));
!   enum tree_code code = gimple_assign_subcode (stmt);
! 
!   switch (get_gimple_rhs_class (code))
!     {
!     case GIMPLE_BINARY_RHS:
!       return interpret_rhs_expr (loop, stmt, type,
! 				 gimple_assign_rhs1 (stmt), code,
! 				 gimple_assign_rhs2 (stmt));
!     case GIMPLE_UNARY_RHS:
!     case GIMPLE_SINGLE_RHS:
!       return interpret_rhs_expr (loop, stmt, type,
! 				 gimple_assign_rhs1 (stmt), code, NULL_TREE);
  
!     default:
!       return chrec_dont_know;
!     }
  }
  
  
--- 1719,1729 ----
  interpret_gimple_assign (struct loop *loop, gimple stmt)
  {
    tree type = TREE_TYPE (gimple_assign_lhs (stmt));
!   enum tree_code code = gimple_assign_rhs_code (stmt);
  
!   return interpret_rhs_expr (loop, stmt, type,
! 			     gimple_assign_rhs1 (stmt), code,
! 			     gimple_assign_rhs2_or_null (stmt));
  }
  
  
Index: tree-phinodes.c
===================================================================
*** tree-phinodes.c	(revision 133063)
--- tree-phinodes.c	(working copy)
*************** allocate_phi_node (size_t len)
*** 136,142 ****
  
    if (free_phinode_count)
      for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
!       if (free_phinodes[bucket])
  	break;
  
    /* If our free list has an element, then use it.  */
--- 136,142 ----
  
    if (free_phinode_count)
      for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
!       if (!VEC_empty (gimple, free_phinodes[bucket]))
  	break;
  
    /* If our free list has an element, then use it.  */
Index: tree-gimple.c
===================================================================
*** tree-gimple.c	(revision 133063)
--- tree-gimple.c	(working copy)
*************** get_gimple_rhs_class (enum tree_code cod
*** 99,104 ****
--- 99,121 ----
    return GIMPLE_INVALID_RHS;
  }
  
+ /* Return the code of the expression computed on the rhs of assignment
+    statement GS.  In case that the rhs is a single object, returns the
+    tree code of the object.  */
+ 
+ enum tree_code
+ gimple_assign_rhs_code (const_gimple gs)
+ {
+   enum tree_code code;
+   GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ 
+   code = gimple_subcode (gs);
+   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+     code = TREE_CODE (gimple_assign_rhs1 (gs));
+ 
+   return code;
+ }
+ 
  
  /* Return the number of operands needed on the RHS of a GIMPLE
     assignment for an expression with tree code CODE.  */
Index: tree-gimple.h
===================================================================
*** tree-gimple.h	(revision 133063)
--- tree-gimple.h	(working copy)
*************** extern tree get_call_expr_in (tree t);
*** 108,113 ****
--- 108,114 ----
  extern void recalculate_side_effects (tree);
  extern enum gimple_rhs_class get_gimple_rhs_class (enum tree_code);
  extern size_t get_gimple_rhs_num_ops (enum tree_code);
+ extern enum tree_code gimple_assign_rhs_code (const_gimple);
  
  /* FIXME we should deduce this from the predicate.  */
  typedef enum fallback_t {
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 133063)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** iv_cand (struct ivopts_data *data, unsig
*** 360,365 ****
--- 360,366 ----
  {
    return VEC_index (iv_cand_p, data->iv_candidates, i);
  }
+ #endif
  
  /* The single loop exit if it dominates the latch, NULL otherwise.  */
  
*************** single_dom_exit (struct loop *loop)
*** 377,382 ****
--- 378,385 ----
    return exit;
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /* Dumps information about the induction variable IV to FILE.  */
  
  extern void dump_iv (FILE *, struct iv *);
Index: gimple-dummy.c
===================================================================
*** gimple-dummy.c	(revision 133063)
--- gimple-dummy.c	(working copy)
*************** DUMMY_VAR (memory_identifier_string);
*** 19,28 ****
  
  DUMMY_FN (canonicalize_induction_variables)
  DUMMY_FN (compute_builtin_object_size)
- DUMMY_FN (compute_data_dependences_for_loop)
- DUMMY_FN (dump_ddrs)
- DUMMY_FN (free_data_refs)
- DUMMY_FN (free_dependence_relations)
  DUMMY_FN (get_type)
  DUMMY_FN (ipa_add_method)
  DUMMY_FN (ipa_callsite_callee)
--- 19,24 ----
*************** DUMMY_FN (multiplier_allowed_in_address_
*** 53,69 ****
  DUMMY_FN (multiply_by_cost)
  DUMMY_FN (optimize_inline_calls)
  DUMMY_FN (remove_empty_loops)
- DUMMY_FN (gimple_duplicate_loop_to_header_edge)
  DUMMY_FN (tree_function_versioning)
  DUMMY_FN (tree_ssa_iv_optimize)
- DUMMY_FN (tree_ssa_prefetch_arrays)
  DUMMY_FN (tree_ssa_unswitch_loops)
  DUMMY_FN (tree_unroll_loops_completely)
  DUMMY_FN (tree_versionable_function_p)
  DUMMY_FN (vec_set_verbosity_level)
  DUMMY_FN (vect_set_verbosity_level)
  DUMMY_FN (vectorize_loops)
- DUMMY_FN (estimated_loop_iterations_int)
  DUMMY_FN (remove_iv)
  DUMMY_FN (omp_reduction_init)
  DUMMY_FN (diagnose_omp_structured_block_errors)
--- 49,62 ----
Index: tree-ssa-loop-ivcanon.c
===================================================================
*** tree-ssa-loop-ivcanon.c	(revision 133063)
--- tree-ssa-loop-ivcanon.c	(working copy)
*************** create_canonical_iv (struct loop *loop, 
*** 112,134 ****
    update_stmt (cond);
  }
  
  /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
  
  unsigned
  tree_num_loop_insns (struct loop *loop, eni_weights *weights)
  {
    basic_block *body = get_loop_body (loop);
!   block_stmt_iterator bsi;
    unsigned size = 1, i;
  
    for (i = 0; i < loop->num_nodes; i++)
!     for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
!       size += estimate_num_insns (bsi_stmt (bsi), weights);
    free (body);
  
    return size;
  }
  
  /* Estimate number of insns of completely unrolled loop.  We assume
     that the size of the unrolled loop is decreased in the
     following way (the numbers of insns are based on what
--- 112,138 ----
    update_stmt (cond);
  }
  
+ #endif
+ 
  /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
  
  unsigned
  tree_num_loop_insns (struct loop *loop, eni_weights *weights)
  {
    basic_block *body = get_loop_body (loop);
!   gimple_stmt_iterator bsi;
    unsigned size = 1, i;
  
    for (i = 0; i < loop->num_nodes; i++)
!     for (bsi = gsi_start_bb (body[i]); !gsi_end_p (bsi); gsi_next (&bsi))
!       size += estimate_num_insns (gsi_stmt (bsi), weights);
    free (body);
  
    return size;
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /* Estimate number of insns of completely unrolled loop.  We assume
     that the size of the unrolled loop is decreased in the
     following way (the numbers of insns are based on what
Index: predict.c
===================================================================
*** predict.c	(revision 133063)
--- predict.c	(working copy)
*************** static sreal real_zero, real_one, real_a
*** 74,83 ****
  
  static void combine_predictions_for_insn (rtx, basic_block);
  static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
- /* FIXME tuples  */
- #if 0
  static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
- #endif
  static void compute_function_frequency (void);
  static void choose_function_section (void);
  static bool can_predict_insn_p (const_rtx);
--- 74,80 ----
*************** remove_predictions_associated_with_edge 
*** 338,345 ****
      }
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Clears the list of predictions stored for BB.  */
  
  static void
--- 335,340 ----
*************** clear_bb_predictions (basic_block bb)
*** 358,364 ****
      }
    *preds = NULL;
  }
- #endif
  
  /* Return true when we can store prediction on insn INSN.
     At the moment we represent predictions only on conditional
--- 353,358 ----
*************** combine_predictions_for_insn (rtx insn, 
*** 571,578 ****
      single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Combine predictions into single probability and store them into CFG.
     Remove now useless prediction entries.  */
  
--- 565,570 ----
*************** combine_predictions_for_bb (basic_block 
*** 695,704 ****
        second->probability = REG_BR_PROB_BASE - combined_probability;
      }
  }
- #endif
  
- /* FIXME tuples.  */
- #if 0
  /* Predict edge probabilities by exploiting loop structure.  */
  
  static void
--- 687,693 ----
*************** predict_loops (void)
*** 834,840 ****
  
    scev_finalize ();
  }
- #endif
  
  /* Attempt to predict probabilities of BB outgoing edges using local
     properties.  */
--- 823,828 ----
*************** guess_outgoing_edge_probabilities (basic
*** 943,980 ****
    combine_predictions_for_insn (BB_END (bb), bb);
  }
  
! /* Return constant EXPR will likely have at execution time, NULL if unknown. 
!    The function is used by builtin_expect branch predictor so the evidence
!    must come from this construct and additional possible constant folding.
!   
!    We may want to implement more involved value guess (such as value range
!    propagation based prediction), but such tricks shall go to new
!    implementation.  */
  
-   /* FIXME tuples.  */
- #if 0
  static tree
! expr_expected_value (tree expr ATTRIBUTE_UNUSED, bitmap visited ATTRIBUTE_UNUSED)
  {
!   if (TREE_CONSTANT (expr))
!     return expr;
!   else if (TREE_CODE (expr) == SSA_NAME)
      {
!       tree def = SSA_NAME_DEF_STMT (expr);
  
        /* If we were already here, break the infinite cycle.  */
!       if (bitmap_bit_p (visited, SSA_NAME_VERSION (expr)))
  	return NULL;
!       bitmap_set_bit (visited, SSA_NAME_VERSION (expr));
  
!       if (TREE_CODE (def) == PHI_NODE)
  	{
  	  /* All the arguments of the PHI node must have the same constant
  	     length.  */
! 	  int i;
  	  tree val = NULL, new_val;
  
! 	  for (i = 0; i < PHI_NUM_ARGS (def); i++)
  	    {
  	      tree arg = PHI_ARG_DEF (def, i);
  
--- 931,968 ----
    combine_predictions_for_insn (BB_END (bb), bb);
  }
  
! static tree expr_expected_value (tree, bitmap);
! 
! /* Helper function for expr_expected_value.  */
  
  static tree
! expr_expected_value_1 (tree type, tree op0, enum tree_code code, tree op1, bitmap visited)
  {
!   gimple def;
! 
!   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
      {
!       if (TREE_CONSTANT (op0))
! 	return op0;
! 
!       if (code != SSA_NAME)
! 	return NULL_TREE;
! 
!       def = SSA_NAME_DEF_STMT (op0);
  
        /* If we were already here, break the infinite cycle.  */
!       if (bitmap_bit_p (visited, SSA_NAME_VERSION (op0)))
  	return NULL;
!       bitmap_set_bit (visited, SSA_NAME_VERSION (op0));
  
!       if (gimple_code (def) == GIMPLE_PHI)
  	{
  	  /* All the arguments of the PHI node must have the same constant
  	     length.  */
! 	  int i, n = gimple_phi_num_args (def);
  	  tree val = NULL, new_val;
  
! 	  for (i = 0; i < n; i++)
  	    {
  	      tree arg = PHI_ARG_DEF (def, i);
  
*************** expr_expected_value (tree expr ATTRIBUTE
*** 997,1077 ****
  	    }
  	  return val;
  	}
!       if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
! 	  || GIMPLE_STMT_OPERAND (def, 0) != expr)
! 	return NULL;
!       return expr_expected_value (GIMPLE_STMT_OPERAND (def, 1), visited);
!     }
!   else if (TREE_CODE (expr) == CALL_EXPR)
!     {
!       tree decl = get_callee_fndecl (expr);
!       if (!decl)
! 	return NULL;
!       if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
! 	  && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT)
  	{
! 	  tree val;
  
! 	  if (call_expr_nargs (expr) != 2)
  	    return NULL;
! 	  val = CALL_EXPR_ARG (expr, 0);
! 	  if (TREE_CONSTANT (val))
! 	    return val;
! 	  return CALL_EXPR_ARG (expr, 1);
  	}
      }
!   if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
      {
!       tree op0, op1, res;
!       op0 = expr_expected_value (TREE_OPERAND (expr, 0), visited);
        if (!op0)
  	return NULL;
!       op1 = expr_expected_value (TREE_OPERAND (expr, 1), visited);
        if (!op1)
  	return NULL;
!       res = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), op0, op1);
        if (TREE_CONSTANT (res))
  	return res;
        return NULL;
      }
!   if (UNARY_CLASS_P (expr))
      {
!       tree op0, res;
!       op0 = expr_expected_value (TREE_OPERAND (expr, 0), visited);
        if (!op0)
  	return NULL;
!       res = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr), op0);
        if (TREE_CONSTANT (res))
  	return res;
        return NULL;
      }
    return NULL;
  }
  
  /* Get rid of all builtin_expect calls we no longer need.  */
  static void
  strip_builtin_expect (void)
  {
    basic_block bb;
    FOR_EACH_BB (bb)
      {
!       block_stmt_iterator bi;
!       for (bi = bsi_start (bb); !bsi_end_p (bi); bsi_next (&bi))
  	{
! 	  tree stmt = bsi_stmt (bi);
  	  tree fndecl;
- 	  tree call;
  
! 	  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
! 	      && (call = GIMPLE_STMT_OPERAND (stmt, 1))
! 	      && TREE_CODE (call) == CALL_EXPR
! 	      && (fndecl = get_callee_fndecl (call))
  	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
  	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
! 	      && call_expr_nargs (call) == 2)
  	    {
! 	      GIMPLE_STMT_OPERAND (stmt, 1) = CALL_EXPR_ARG (call, 0);
! 	      update_stmt (stmt);
  	    }
  	}
      }
--- 985,1108 ----
  	    }
  	  return val;
  	}
!       if (gimple_code (def) == GIMPLE_ASSIGN)
  	{
! 	  if (gimple_assign_lhs (def) != op0)
! 	    return NULL;
! 
! 	  return expr_expected_value_1 (TREE_TYPE (gimple_assign_lhs (def)),
! 					gimple_assign_rhs1 (def),
! 					gimple_subcode (def),
! 					gimple_assign_rhs2_or_null (def),
! 					visited);
! 	}
  
!       if (gimple_code (def) == GIMPLE_CALL)
! 	{
! 	  tree decl = gimple_call_fndecl (def);
! 	  if (!decl)
  	    return NULL;
! 	  if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
! 	      && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT)
! 	    {
! 	      tree val;
! 
! 	      if (gimple_call_num_args (def) != 2)
! 		return NULL;
! 	      val = gimple_call_arg (def, 0);
! 	      if (TREE_CONSTANT (val))
! 		return val;
! 	      return gimple_call_arg (def, 1);
! 	    }
  	}
+ 
+       return NULL;
      }
! 
!   if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
      {
!       tree res;
!       op0 = expr_expected_value (op0, visited);
        if (!op0)
  	return NULL;
!       op1 = expr_expected_value (op1, visited);
        if (!op1)
  	return NULL;
!       res = fold_build2 (code, type, op0, op1);
        if (TREE_CONSTANT (res))
  	return res;
        return NULL;
      }
!   if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
      {
!       tree res;
!       op0 = expr_expected_value (op0, visited);
        if (!op0)
  	return NULL;
!       res = fold_build1 (code, type, op0);
        if (TREE_CONSTANT (res))
  	return res;
        return NULL;
      }
    return NULL;
  }
+ 
+ /* Return constant EXPR will likely have at execution time, NULL if unknown. 
+    The function is used by builtin_expect branch predictor so the evidence
+    must come from this construct and additional possible constant folding.
+   
+    We may want to implement more involved value guess (such as value range
+    propagation based prediction), but such tricks shall go to new
+    implementation.  */
+ 
+ static tree
+ expr_expected_value (tree expr, bitmap visited)
+ {
+   enum tree_code code;
+   tree op0, op1;
+ 
+   if (TREE_CONSTANT (expr))
+     return expr;
+ 
+   extract_ops_from_tree (expr, &code, &op0, &op1);
+   return expr_expected_value_1 (TREE_TYPE (expr),
+ 				op0, code, op1, visited);
+ }
+ 
  
  /* Get rid of all builtin_expect calls we no longer need.  */
  static void
  strip_builtin_expect (void)
  {
    basic_block bb;
+   gimple ass_stmt;
+   tree var;
+ 
    FOR_EACH_BB (bb)
      {
!       gimple_stmt_iterator bi;
!       for (bi = gsi_start_bb (bb); !gsi_end_p (bi); gsi_next (&bi))
  	{
! 	  gimple stmt = gsi_stmt (bi);
  	  tree fndecl;
  
! 	  if (gimple_code (stmt) != GIMPLE_CALL)
! 	    continue;
! 
! 	  fndecl = gimple_call_fndecl (stmt);
! 
! 	  if (fndecl
  	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
  	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
! 	      && gimple_call_num_args (stmt) == 2)
  	    {
! 	      var = gimple_call_lhs (stmt);
! 	      ass_stmt = gimple_build_assign (var, gimple_call_arg (stmt, 0));
! 
! 	      if (TREE_CODE (var) == SSA_NAME)
! 		SSA_NAME_DEF_STMT (var) = ass_stmt;
! 
! 	      gsi_replace (&bi, ass_stmt, true);
  	    }
  	}
      }
*************** strip_builtin_expect (void)
*** 1079,1107 ****
  
  /* Predict using opcode of the last statement in basic block.  */
  static void
! tree_predict_by_opcode (basic_block bb ATTRIBUTE_UNUSED)
  {
!   tree stmt = last_stmt (bb);
    edge then_edge;
!   tree cond;
!   tree op0;
    tree type;
    tree val;
    bitmap visited;
    edge_iterator ei;
  
!   if (!stmt || TREE_CODE (stmt) != COND_EXPR)
      return;
    FOR_EACH_EDGE (then_edge, ei, bb->succs)
      if (then_edge->flags & EDGE_TRUE_VALUE)
        break;
!   cond = TREE_OPERAND (stmt, 0);
!   if (!COMPARISON_CLASS_P (cond))
!     return;
!   op0 = TREE_OPERAND (cond, 0);
    type = TREE_TYPE (op0);
    visited = BITMAP_ALLOC (NULL);
!   val = expr_expected_value (cond, visited);
    BITMAP_FREE (visited);
    if (val)
      {
--- 1110,1137 ----
  
  /* Predict using opcode of the last statement in basic block.  */
  static void
! tree_predict_by_opcode (basic_block bb)
  {
!   gimple stmt = last_stmt (bb);
    edge then_edge;
!   tree op0, op1;
    tree type;
    tree val;
+   enum tree_code cmp;
    bitmap visited;
    edge_iterator ei;
  
!   if (!stmt || gimple_code (stmt) != GIMPLE_COND)
      return;
    FOR_EACH_EDGE (then_edge, ei, bb->succs)
      if (then_edge->flags & EDGE_TRUE_VALUE)
        break;
!   op0 = gimple_cond_lhs (stmt);
!   op1 = gimple_cond_rhs (stmt);
!   cmp = gimple_cond_code (stmt);
    type = TREE_TYPE (op0);
    visited = BITMAP_ALLOC (NULL);
!   val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
    BITMAP_FREE (visited);
    if (val)
      {
*************** tree_predict_by_opcode (basic_block bb A
*** 1116,1124 ****
       Similarly, a comparison ptr1 == ptr2 is predicted as false.  */
    if (POINTER_TYPE_P (type))
      {
!       if (TREE_CODE (cond) == EQ_EXPR)
  	predict_edge_def (then_edge, PRED_TREE_POINTER, NOT_TAKEN);
!       else if (TREE_CODE (cond) == NE_EXPR)
  	predict_edge_def (then_edge, PRED_TREE_POINTER, TAKEN);
      }
    else
--- 1146,1154 ----
       Similarly, a comparison ptr1 == ptr2 is predicted as false.  */
    if (POINTER_TYPE_P (type))
      {
!       if (cmp == EQ_EXPR)
  	predict_edge_def (then_edge, PRED_TREE_POINTER, NOT_TAKEN);
!       else if (cmp == NE_EXPR)
  	predict_edge_def (then_edge, PRED_TREE_POINTER, TAKEN);
      }
    else
*************** tree_predict_by_opcode (basic_block bb A
*** 1127,1133 ****
       EQ tests are usually false and NE tests are usually true. Also,
       most quantities are positive, so we can make the appropriate guesses
       about signed comparisons against zero.  */
!     switch (TREE_CODE (cond))
        {
        case EQ_EXPR:
        case UNEQ_EXPR:
--- 1157,1163 ----
       EQ tests are usually false and NE tests are usually true. Also,
       most quantities are positive, so we can make the appropriate guesses
       about signed comparisons against zero.  */
!     switch (cmp)
        {
        case EQ_EXPR:
        case UNEQ_EXPR:
*************** tree_predict_by_opcode (basic_block bb A
*** 1138,1145 ****
  	  ;
  	/* Comparisons with 0 are often used for booleans and there is
  	   nothing useful to predict about them.  */
! 	else if (integer_zerop (op0)
! 		 || integer_zerop (TREE_OPERAND (cond, 1)))
  	  ;
  	else
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, NOT_TAKEN);
--- 1168,1174 ----
  	  ;
  	/* Comparisons with 0 are often used for booleans and there is
  	   nothing useful to predict about them.  */
! 	else if (integer_zerop (op0) || integer_zerop (op1))
  	  ;
  	else
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, NOT_TAKEN);
*************** tree_predict_by_opcode (basic_block bb A
*** 1155,1161 ****
  	/* Comparisons with 0 are often used for booleans and there is
  	   nothing useful to predict about them.  */
  	else if (integer_zerop (op0)
! 		 || integer_zerop (TREE_OPERAND (cond, 1)))
  	  ;
  	else
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, TAKEN);
--- 1184,1190 ----
  	/* Comparisons with 0 are often used for booleans and there is
  	   nothing useful to predict about them.  */
  	else if (integer_zerop (op0)
! 		 || integer_zerop (op1))
  	  ;
  	else
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, TAKEN);
*************** tree_predict_by_opcode (basic_block bb A
*** 1171,1193 ****
  
        case LE_EXPR:
        case LT_EXPR:
! 	if (integer_zerop (TREE_OPERAND (cond, 1))
! 	    || integer_onep (TREE_OPERAND (cond, 1))
! 	    || integer_all_onesp (TREE_OPERAND (cond, 1))
! 	    || real_zerop (TREE_OPERAND (cond, 1))
! 	    || real_onep (TREE_OPERAND (cond, 1))
! 	    || real_minus_onep (TREE_OPERAND (cond, 1)))
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN);
  	break;
  
        case GE_EXPR:
        case GT_EXPR:
! 	if (integer_zerop (TREE_OPERAND (cond, 1))
! 	    || integer_onep (TREE_OPERAND (cond, 1))
! 	    || integer_all_onesp (TREE_OPERAND (cond, 1))
! 	    || real_zerop (TREE_OPERAND (cond, 1))
! 	    || real_onep (TREE_OPERAND (cond, 1))
! 	    || real_minus_onep (TREE_OPERAND (cond, 1)))
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN);
  	break;
  
--- 1200,1222 ----
  
        case LE_EXPR:
        case LT_EXPR:
! 	if (integer_zerop (op1)
! 	    || integer_onep (op1)
! 	    || integer_all_onesp (op1)
! 	    || real_zerop (op1)
! 	    || real_onep (op1)
! 	    || real_minus_onep (op1))
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN);
  	break;
  
        case GE_EXPR:
        case GT_EXPR:
! 	if (integer_zerop (op1)
! 	    || integer_onep (op1)
! 	    || integer_all_onesp (op1)
! 	    || real_zerop (op1)
! 	    || real_onep (op1)
! 	    || real_minus_onep (op1))
  	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN);
  	break;
  
*************** return_prediction (tree val, enum predic
*** 1236,1254 ****
      }
    return PRED_NO_PREDICTION;
  }
- #endif
  
  /* Find the basic block with return expression and look up for possible
     return value trying to apply RETURN_PREDICTION heuristics.  */
- /* FIXME tuples.  */
- #if 0
  static void
  apply_return_prediction (void)
  {
!   tree return_stmt = NULL;
    tree return_val;
    edge e;
!   tree phi;
    int phi_num_args, i;
    enum br_predictor pred;
    enum prediction direction;
--- 1265,1280 ----
      }
    return PRED_NO_PREDICTION;
  }
  
  /* Find the basic block with return expression and look up for possible
     return value trying to apply RETURN_PREDICTION heuristics.  */
  static void
  apply_return_prediction (void)
  {
!   gimple return_stmt = NULL;
    tree return_val;
    edge e;
!   gimple phi;
    int phi_num_args, i;
    enum br_predictor pred;
    enum prediction direction;
*************** apply_return_prediction (void)
*** 1258,1283 ****
      {
        return_stmt = last_stmt (e->src);
        if (return_stmt
! 	  && TREE_CODE (return_stmt) == RETURN_EXPR)
  	break;
      }
    if (!e)
      return;
!   return_val = TREE_OPERAND (return_stmt, 0);
    if (!return_val)
      return;
-   if (TREE_CODE (return_val) == GIMPLE_MODIFY_STMT)
-     return_val = GIMPLE_STMT_OPERAND (return_val, 1);
    if (TREE_CODE (return_val) != SSA_NAME
        || !SSA_NAME_DEF_STMT (return_val)
!       || TREE_CODE (SSA_NAME_DEF_STMT (return_val)) != PHI_NODE)
!     return;
!   for (phi = SSA_NAME_DEF_STMT (return_val); phi; phi = PHI_CHAIN (phi))
!     if (PHI_RESULT (phi) == return_val)
!       break;
!   if (!phi)
      return;
!   phi_num_args = PHI_NUM_ARGS (phi);
    pred = return_prediction (PHI_ARG_DEF (phi, 0), &direction);
  
    /* Avoid the degenerate case where all return values form the function
--- 1284,1303 ----
      {
        return_stmt = last_stmt (e->src);
        if (return_stmt
! 	  && gimple_code (return_stmt) == GIMPLE_RETURN)
  	break;
      }
    if (!e)
      return;
!   return_val = gimple_return_retval (return_stmt);
    if (!return_val)
      return;
    if (TREE_CODE (return_val) != SSA_NAME
        || !SSA_NAME_DEF_STMT (return_val)
!       || gimple_code (SSA_NAME_DEF_STMT (return_val)) != GIMPLE_PHI)
      return;
!   phi = SSA_NAME_DEF_STMT (return_val);
!   phi_num_args = gimple_phi_num_args (phi);
    pred = return_prediction (PHI_ARG_DEF (phi, 0), &direction);
  
    /* Avoid the degenerate case where all return values form the function
*************** apply_return_prediction (void)
*** 1291,1297 ****
        {
  	pred = return_prediction (PHI_ARG_DEF (phi, i), &direction);
  	if (pred != PRED_NO_PREDICTION)
! 	  predict_paths_leading_to (PHI_ARG_EDGE (phi, i)->src, pred,
  				    direction);
        }
  }
--- 1311,1317 ----
        {
  	pred = return_prediction (PHI_ARG_DEF (phi, i), &direction);
  	if (pred != PRED_NO_PREDICTION)
! 	  predict_paths_leading_to (gimple_phi_arg_edge (phi, i)->src, pred,
  				    direction);
        }
  }
*************** tree_bb_level_predictions (void)
*** 1309,1354 ****
  
    FOR_EACH_BB (bb)
      {
!       block_stmt_iterator bsi = bsi_last (bb);
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
  	{
! 	  tree stmt = bsi_stmt (bsi);
  	  tree decl;
  
! 	  switch (TREE_CODE (stmt))
  	    {
! 	      case GIMPLE_MODIFY_STMT:
! 		if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR)
! 		  {
! 		    stmt = GIMPLE_STMT_OPERAND (stmt, 1);
! 		    goto call_expr;
! 		  }
! 		break;
! 	      case CALL_EXPR:
! call_expr:;
! 		if (call_expr_flags (stmt) & ECF_NORETURN)
! 		  predict_paths_leading_to (bb, PRED_NORETURN,
! 		      			    NOT_TAKEN);
! 		decl = get_callee_fndecl (stmt);
! 		if (decl
! 		    && lookup_attribute ("cold",
! 					 DECL_ATTRIBUTES (decl)))
! 		  predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
! 		      			    NOT_TAKEN);
! 		break;
! 	      default:
! 		break;
  	    }
  	}
      }
  }
- #endif
  
  #ifdef ENABLE_CHECKING
  
- /* FIXME tuples.  */
- #if 0
  /* Callback for pointer_map_traverse, asserts that the pointer map is
     empty.  */
  
--- 1329,1359 ----
  
    FOR_EACH_BB (bb)
      {
!       gimple_stmt_iterator bsi;
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
  	{
! 	  gimple stmt = gsi_stmt (bsi);
  	  tree decl;
  
! 	  if (gimple_code (stmt) == GIMPLE_CALL)
  	    {
! 	      if (gimple_call_flags (stmt) & ECF_NORETURN)
! 		predict_paths_leading_to (bb, PRED_NORETURN,
! 					  NOT_TAKEN);
! 	      decl = gimple_call_fndecl (stmt);
! 	      if (decl
! 		  && lookup_attribute ("cold",
! 				       DECL_ATTRIBUTES (decl)))
! 		predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
! 					  NOT_TAKEN);
  	    }
  	}
      }
  }
  
  #ifdef ENABLE_CHECKING
  
  /* Callback for pointer_map_traverse, asserts that the pointer map is
     empty.  */
  
*************** assert_is_empty (const void *key ATTRIBU
*** 1360,1373 ****
    return false;
  }
  #endif
- #endif
  
  /* Predict branch probabilities and estimate profile of the tree CFG.  */
  static unsigned int
  tree_estimate_probability (void)
  {
-   /* FIXME tuples.  */
- #if 0
    basic_block bb;
  
    loop_optimizer_init (0);
--- 1365,1375 ----
*************** tree_estimate_probability (void)
*** 1415,1421 ****
  	      && e->dest != EXIT_BLOCK_PTR
  	      && single_succ_p (e->dest)
  	      && single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
! 	      && TREE_CODE (last_stmt (e->dest)) == RETURN_EXPR)
  	    {
  	      edge e1;
  	      edge_iterator ei1;
--- 1417,1423 ----
  	      && e->dest != EXIT_BLOCK_PTR
  	      && single_succ_p (e->dest)
  	      && single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
! 	      && gimple_code (last_stmt (e->dest)) == GIMPLE_RETURN)
  	    {
  	      edge e1;
  	      edge_iterator ei1;
*************** tree_estimate_probability (void)
*** 1441,1463 ****
  	      && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
  	      && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
  	    {
! 	      block_stmt_iterator bi;
  
  	      /* The call heuristic claims that a guarded function call
  		 is improbable.  This is because such calls are often used
  		 to signal exceptional situations such as printing error
  		 messages.  */
! 	      for (bi = bsi_start (e->dest); !bsi_end_p (bi);
! 		   bsi_next (&bi))
  		{
! 		  tree stmt = bsi_stmt (bi);
! 		  if ((TREE_CODE (stmt) == CALL_EXPR
! 		       || (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
! 			   && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1))
! 			      == CALL_EXPR))
  		      /* Constant and pure calls are hardly used to signalize
  			 something exceptional.  */
! 		      && TREE_SIDE_EFFECTS (stmt))
  		    {
  		      predict_edge_def (e, PRED_CALL, NOT_TAKEN);
  		      break;
--- 1443,1462 ----
  	      && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
  	      && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
  	    {
! 	      gimple_stmt_iterator bi;
  
  	      /* The call heuristic claims that a guarded function call
  		 is improbable.  This is because such calls are often used
  		 to signal exceptional situations such as printing error
  		 messages.  */
! 	      for (bi = gsi_start_bb (e->dest); !gsi_end_p (bi);
! 		   gsi_next (&bi))
  		{
! 		  gimple stmt = gsi_stmt (bi);
! 		  if (gimple_code (stmt) == GIMPLE_CALL
  		      /* Constant and pure calls are hardly used to signalize
  			 something exceptional.  */
! 		      && gimple_has_side_effects (stmt))
  		    {
  		      predict_edge_def (e, PRED_CALL, NOT_TAKEN);
  		      break;
*************** tree_estimate_probability (void)
*** 1482,1502 ****
    remove_fake_exit_edges ();
    loop_optimizer_finalize ();
    if (dump_file && (dump_flags & TDF_DETAILS))
!     dump_tree_cfg (dump_file, dump_flags);
    if (profile_status == PROFILE_ABSENT)
      profile_status = PROFILE_GUESSED;
    return 0;
- #else
-   gimple_unreachable ();
-   return 0;
- #endif
  }
  
  /* Predict edges to succestors of CUR whose sources are not postdominated by
     BB by PRED and recurse to all postdominators.  */
  
- /* FIXME tuples */
- #if 0
  static void
  predict_paths_for_bb (basic_block cur, basic_block bb,
  		      enum br_predictor pred,
--- 1481,1495 ----
    remove_fake_exit_edges ();
    loop_optimizer_finalize ();
    if (dump_file && (dump_flags & TDF_DETAILS))
!     gimple_dump_cfg (dump_file, dump_flags);
    if (profile_status == PROFILE_ABSENT)
      profile_status = PROFILE_GUESSED;
    return 0;
  }
  
  /* Predict edges to succestors of CUR whose sources are not postdominated by
     BB by PRED and recurse to all postdominators.  */
  
  static void
  predict_paths_for_bb (basic_block cur, basic_block bb,
  		      enum br_predictor pred,
*************** predict_paths_leading_to (basic_block bb
*** 1530,1536 ****
  {
    predict_paths_for_bb (bb, bb, pred, taken);
  }
- #endif
  
  /* This is used to carry information about basic blocks.  It is
     attached to the AUX field of the standard CFG block.  */
--- 1523,1528 ----
Index: gimple-iterator.c
===================================================================
*** gimple-iterator.c	(revision 133063)
--- gimple-iterator.c	(working copy)
*************** gsi_insert_on_edge_immediate (edge e, gi
*** 613,618 ****
--- 613,636 ----
    return new_bb;
  }
  
+ /* Insert STMTS on edge E.  If a new block has to be created, it
+    is returned.  */
+ 
+ basic_block
+ gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts)
+ {
+   gimple_stmt_iterator gsi;
+   basic_block new_bb = NULL;
+ 
+   gcc_assert (!PENDING_STMT (e));
+ 
+   if (gimple_find_edge_insert_loc (e, &gsi, &new_bb))
+     gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
+   else
+     gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
+ 
+   return new_bb;
+ }
  
  /* This routine will commit all pending edge insertions, creating any new
     basic blocks which are necessary.  */
Index: gimple-pretty-print.c
===================================================================
*** gimple-pretty-print.c	(revision 133063)
--- gimple-pretty-print.c	(working copy)
*************** dump_gimple_assign (pretty_printer *buff
*** 329,334 ****
--- 329,336 ----
        dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
        pp_space (buffer);
        pp_character (buffer, '=');
+       if (gimple_assign_nontemporal_move_p (gs))
+ 	pp_string (buffer, "{nt}");
        pp_space (buffer);
  
        if (gimple_num_ops (gs) == 2)
Index: tree-data-ref.c
===================================================================
*** tree-data-ref.c	(revision 133063)
--- tree-data-ref.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 93,101 ****
  #include "tree-pass.h"
  #include "langhooks.h"
  
- /* FIXME tuples.  */
- #if 0
- 
  static struct datadep_stats
  {
    int num_dependence_tests;
--- 93,98 ----
*************** dump_data_reference (FILE *outf, 
*** 189,195 ****
    unsigned int i;
    
    fprintf (outf, "(Data Ref: \n  stmt: ");
!   print_generic_stmt (outf, DR_STMT (dr), 0);
    fprintf (outf, "  ref: ");
    print_generic_stmt (outf, DR_REF (dr), 0);
    fprintf (outf, "  base_object: ");
--- 186,192 ----
    unsigned int i;
    
    fprintf (outf, "(Data Ref: \n  stmt: ");
!   print_gimple_stmt (outf, DR_STMT (dr), 0, 0);
    fprintf (outf, "  ref: ");
    print_generic_stmt (outf, DR_REF (dr), 0);
    fprintf (outf, "  base_object: ");
*************** dump_ddrs (FILE *file, VEC (ddr_p, heap)
*** 500,567 ****
    fprintf (file, "\n\n");
  }
  
! /* Expresses EXP as VAR + OFF, where off is a constant.  The type of OFF
!    will be ssizetype.  */
  
! void
! split_constant_offset (tree exp, tree *var, tree *off)
  {
-   tree type = TREE_TYPE (exp), otype;
    tree var0, var1;
    tree off0, off1;
-   enum tree_code code;
  
!   *var = exp;
!   STRIP_NOPS (exp);
!   otype = TREE_TYPE (exp);
!   code = TREE_CODE (exp);
  
    switch (code)
      {
      case INTEGER_CST:
        *var = build_int_cst (type, 0);
!       *off = fold_convert (ssizetype, exp);
!       return;
  
      case POINTER_PLUS_EXPR:
        code = PLUS_EXPR;
        /* FALLTHROUGH */
      case PLUS_EXPR:
      case MINUS_EXPR:
!       split_constant_offset (TREE_OPERAND (exp, 0), &var0, &off0);
!       split_constant_offset (TREE_OPERAND (exp, 1), &var1, &off1);
!       *var = fold_convert (type, fold_build2 (TREE_CODE (exp), otype, 
! 					      var0, var1));
        *off = size_binop (code, off0, off1);
!       return;
  
      case MULT_EXPR:
!       off1 = TREE_OPERAND (exp, 1);
!       if (TREE_CODE (off1) != INTEGER_CST)
! 	break;
  
!       split_constant_offset (TREE_OPERAND (exp, 0), &var0, &off0);
!       *var = fold_convert (type, fold_build2 (MULT_EXPR, otype,
! 					      var0, off1));
!       *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, off1));
!       return;
  
      case ADDR_EXPR:
        {
! 	tree op, base, poffset;
  	HOST_WIDE_INT pbitsize, pbitpos;
  	enum machine_mode pmode;
  	int punsignedp, pvolatilep;
  
! 	op = TREE_OPERAND (exp, 0);
! 	if (!handled_component_p (op))
! 	  break;
  
! 	base = get_inner_reference (op, &pbitsize, &pbitpos, &poffset,
  				    &pmode, &punsignedp, &pvolatilep, false);
  
  	if (pbitpos % BITS_PER_UNIT != 0)
! 	  break;
  	base = build_fold_addr_expr (base);
  	off0 = ssize_int (pbitpos / BITS_PER_UNIT);
  
--- 497,560 ----
    fprintf (file, "\n\n");
  }
  
! /* Helper function for split_constant_offset.  Expresses OP0 CODE OP1
!    (the type of the result is TYPE) as VAR + OFF, where OFF is a nonzero
!    constant of type ssizetype, and returns true.  If we cannot do this
!    with OFF nonzero, OFF and VAR are set to NULL_TREE instead and false
!    is returned.  */
  
! static bool
! split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
! 			 tree *var, tree *off)
  {
    tree var0, var1;
    tree off0, off1;
  
!   *var = NULL_TREE;
!   *off = NULL_TREE;
  
    switch (code)
      {
      case INTEGER_CST:
        *var = build_int_cst (type, 0);
!       *off = fold_convert (ssizetype, op0);
!       return true;
  
      case POINTER_PLUS_EXPR:
        code = PLUS_EXPR;
        /* FALLTHROUGH */
      case PLUS_EXPR:
      case MINUS_EXPR:
!       split_constant_offset (op0, &var0, &off0);
!       split_constant_offset (op1, &var1, &off1);
!       *var = fold_build2 (code, type, var0, var1);
        *off = size_binop (code, off0, off1);
!       return true;
  
      case MULT_EXPR:
!       if (TREE_CODE (op1) != INTEGER_CST)
! 	return false;
  
!       split_constant_offset (op0, &var0, &off0);
!       *var = fold_build2 (MULT_EXPR, type, var0, op1);
!       *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1));
!       return true;
  
      case ADDR_EXPR:
        {
! 	tree base, poffset;
  	HOST_WIDE_INT pbitsize, pbitpos;
  	enum machine_mode pmode;
  	int punsignedp, pvolatilep;
  
! 	if (!handled_component_p (op0))
! 	  return false;
  
! 	base = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset,
  				    &pmode, &punsignedp, &pvolatilep, false);
  
  	if (pbitpos % BITS_PER_UNIT != 0)
! 	  return false;
  	base = build_fold_addr_expr (base);
  	off0 = ssize_int (pbitpos / BITS_PER_UNIT);
  
*************** split_constant_offset (tree exp, tree *v
*** 595,634 ****
  	while (POINTER_TYPE_P (type))
  	  type = TREE_TYPE (type);
  	if (int_size_in_bytes (type) < 0)
! 	  break;
  
  	*var = var0;
  	*off = off0;
! 	return;
        }
  
      case SSA_NAME:
        {
! 	tree def_stmt = SSA_NAME_DEF_STMT (exp);
! 	if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT)
! 	  {
! 	    tree def_stmt_rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
  
! 	    if (!TREE_SIDE_EFFECTS (def_stmt_rhs) 
! 		&& EXPR_P (def_stmt_rhs)
! 		&& !REFERENCE_CLASS_P (def_stmt_rhs)
! 		&& !get_call_expr_in (def_stmt_rhs))
! 	      {
! 		split_constant_offset (def_stmt_rhs, &var0, &off0);
! 		var0 = fold_convert (type, var0);
! 		*var = var0;
! 		*off = off0;
! 		return;
! 	      }
! 	  }
! 	break;
        }
  
      default:
!       break;
      }
  
!   *off = ssize_int (0);
  }
  
  /* Returns the address ADDR of an object in a canonical shape (without nop
--- 588,640 ----
  	while (POINTER_TYPE_P (type))
  	  type = TREE_TYPE (type);
  	if (int_size_in_bytes (type) < 0)
! 	  return false;
  
  	*var = var0;
  	*off = off0;
! 	return true;
        }
  
      case SSA_NAME:
        {
! 	gimple def_stmt = SSA_NAME_DEF_STMT (op0);
! 	enum tree_code subcode;
  
! 	if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
! 	  return false;
! 
! 	var0 = gimple_assign_rhs1 (def_stmt);
! 	subcode = gimple_assign_rhs_code (def_stmt);
! 	var1 = gimple_assign_rhs2_or_null (def_stmt);
! 
! 	return split_constant_offset_1 (type, var0, subcode, var1, var, off);
        }
  
      default:
!       return false;
      }
+ }
+ 
+ /* Expresses EXP as VAR + OFF, where off is a constant.  The type of OFF
+    will be ssizetype.  */
+ 
+ void
+ split_constant_offset (tree exp, tree *var, tree *off)
+ {
+   tree type = TREE_TYPE (exp), otype, op0, op1;
+   enum tree_code code;
  
!   STRIP_NOPS (exp);
!   otype = TREE_TYPE (exp);
!   code = TREE_CODE (exp);
!   extract_ops_from_tree (exp, &code, &op0, &op1);
!   if (split_constant_offset_1 (otype, op0, code, op1, var, off))
!     *var = fold_convert (type, *var);
!   else
!     {
!       *var = exp;
!       *off = ssize_int (0);
!     }
  }
  
  /* Returns the address ADDR of an object in a canonical shape (without nop
*************** canonicalize_base_object_address (tree a
*** 658,664 ****
  void
  dr_analyze_innermost (struct data_reference *dr)
  {
!   tree stmt = DR_STMT (dr);
    struct loop *loop = loop_containing_stmt (stmt);
    tree ref = DR_REF (dr);
    HOST_WIDE_INT pbitsize, pbitpos;
--- 664,670 ----
  void
  dr_analyze_innermost (struct data_reference *dr)
  {
!   gimple stmt = DR_STMT (dr);
    struct loop *loop = loop_containing_stmt (stmt);
    tree ref = DR_REF (dr);
    HOST_WIDE_INT pbitsize, pbitpos;
*************** dr_analyze_innermost (struct data_refere
*** 729,735 ****
  static void
  dr_analyze_indices (struct data_reference *dr, struct loop *nest)
  {
!   tree stmt = DR_STMT (dr);
    struct loop *loop = loop_containing_stmt (stmt);
    VEC (tree, heap) *access_fns = NULL;
    tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
--- 735,741 ----
  static void
  dr_analyze_indices (struct data_reference *dr, struct loop *nest)
  {
!   gimple stmt = DR_STMT (dr);
    struct loop *loop = loop_containing_stmt (stmt);
    VEC (tree, heap) *access_fns = NULL;
    tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
*************** dr_analyze_indices (struct data_referenc
*** 773,779 ****
  static void
  dr_analyze_alias (struct data_reference *dr)
  {
!   tree stmt = DR_STMT (dr);
    tree ref = DR_REF (dr);
    tree base = get_base_address (ref), addr, smt = NULL_TREE;
    ssa_op_iter it;
--- 779,785 ----
  static void
  dr_analyze_alias (struct data_reference *dr)
  {
!   gimple stmt = DR_STMT (dr);
    tree ref = DR_REF (dr);
    tree base = get_base_address (ref), addr, smt = NULL_TREE;
    ssa_op_iter it;
*************** free_data_ref (data_reference_p dr)
*** 836,842 ****
     loop nest in that the reference should be analyzed.  */
  
  struct data_reference *
! create_data_ref (struct loop *nest, tree memref, tree stmt, bool is_read)
  {
    struct data_reference *dr;
  
--- 842,848 ----
     loop nest in that the reference should be analyzed.  */
  
  struct data_reference *
! create_data_ref (struct loop *nest, tree memref, gimple stmt, bool is_read)
  {
    struct data_reference *dr;
  
*************** analyze_ziv_subscript (tree chrec_a, 
*** 1522,1529 ****
      fprintf (dump_file, "(analyze_ziv_subscript \n");
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
!   chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
    difference = chrec_fold_minus (type, chrec_a, chrec_b);
    
    switch (TREE_CODE (difference))
--- 1528,1535 ----
      fprintf (dump_file, "(analyze_ziv_subscript \n");
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL);
!   chrec_b = chrec_convert (type, chrec_b, NULL);
    difference = chrec_fold_minus (type, chrec_a, chrec_b);
    
    switch (TREE_CODE (difference))
*************** analyze_siv_subscript_cst_affine (tree c
*** 1653,1660 ****
    tree type, difference, tmp;
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
!   chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
    difference = chrec_fold_minus (type, initial_condition (chrec_b), chrec_a);
    
    if (!chrec_is_positive (initial_condition (difference), &value0))
--- 1659,1666 ----
    tree type, difference, tmp;
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL);
!   chrec_b = chrec_convert (type, chrec_b, NULL);
    difference = chrec_fold_minus (type, initial_condition (chrec_b), chrec_a);
    
    if (!chrec_is_positive (initial_condition (difference), &value0))
*************** can_use_analyze_subscript_affine_affine 
*** 2324,2330 ****
  
    type = chrec_type (*chrec_a);
    left_a = CHREC_LEFT (*chrec_a);
!   left_b = chrec_convert (type, CHREC_LEFT (*chrec_b), NULL_TREE);
    diff = chrec_fold_minus (type, left_a, left_b);
  
    if (!evolution_function_is_constant_p (diff))
--- 2330,2336 ----
  
    type = chrec_type (*chrec_a);
    left_a = CHREC_LEFT (*chrec_a);
!   left_b = chrec_convert (type, CHREC_LEFT (*chrec_b), NULL);
    diff = chrec_fold_minus (type, left_a, left_b);
  
    if (!evolution_function_is_constant_p (diff))
*************** can_use_analyze_subscript_affine_affine 
*** 2335,2341 ****
  
    *chrec_a = build_polynomial_chrec (CHREC_VARIABLE (*chrec_a), 
  				     diff, CHREC_RIGHT (*chrec_a));
!   right_b = chrec_convert (type, CHREC_RIGHT (*chrec_b), NULL_TREE);
    *chrec_b = build_polynomial_chrec (CHREC_VARIABLE (*chrec_b),
  				     build_int_cst (type, 0),
  				     right_b);
--- 2341,2347 ----
  
    *chrec_a = build_polynomial_chrec (CHREC_VARIABLE (*chrec_a), 
  				     diff, CHREC_RIGHT (*chrec_a));
!   right_b = chrec_convert (type, CHREC_RIGHT (*chrec_b), NULL);
    *chrec_b = build_polynomial_chrec (CHREC_VARIABLE (*chrec_b),
  				     build_int_cst (type, 0),
  				     right_b);
*************** analyze_miv_subscript (tree chrec_a, 
*** 2481,2488 ****
      fprintf (dump_file, "(analyze_miv_subscript \n");
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
!   chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
    difference = chrec_fold_minus (type, chrec_a, chrec_b);
    
    if (eq_evolutions_p (chrec_a, chrec_b))
--- 2487,2494 ----
      fprintf (dump_file, "(analyze_miv_subscript \n");
  
    type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
!   chrec_a = chrec_convert (type, chrec_a, NULL);
!   chrec_b = chrec_convert (type, chrec_b, NULL);
    difference = chrec_fold_minus (type, chrec_a, chrec_b);
    
    if (eq_evolutions_p (chrec_a, chrec_b))
*************** omega_setup_subscript (tree access_fun_a
*** 3432,3439 ****
    int eq;
    tree type = signed_type_for_types (TREE_TYPE (access_fun_a),
  				     TREE_TYPE (access_fun_b));
!   tree fun_a = chrec_convert (type, access_fun_a, NULL_TREE);
!   tree fun_b = chrec_convert (type, access_fun_b, NULL_TREE);
    tree difference = chrec_fold_minus (type, fun_a, fun_b);
  
    /* When the fun_a - fun_b is not constant, the dependence is not
--- 3438,3445 ----
    int eq;
    tree type = signed_type_for_types (TREE_TYPE (access_fun_a),
  				     TREE_TYPE (access_fun_b));
!   tree fun_a = chrec_convert (type, access_fun_a, NULL);
!   tree fun_b = chrec_convert (type, access_fun_b, NULL);
    tree difference = chrec_fold_minus (type, fun_a, fun_b);
  
    /* When the fun_a - fun_b is not constant, the dependence is not
*************** compute_affine_dependence (struct data_d
*** 3793,3801 ****
      {
        fprintf (dump_file, "(compute_affine_dependence\n");
        fprintf (dump_file, "  (stmt_a = \n");
!       print_generic_expr (dump_file, DR_STMT (dra), 0);
        fprintf (dump_file, ")\n  (stmt_b = \n");
!       print_generic_expr (dump_file, DR_STMT (drb), 0);
        fprintf (dump_file, ")\n");
      }
  
--- 3799,3807 ----
      {
        fprintf (dump_file, "(compute_affine_dependence\n");
        fprintf (dump_file, "  (stmt_a = \n");
!       print_gimple_stmt (dump_file, DR_STMT (dra), 0, 0);
        fprintf (dump_file, ")\n  (stmt_b = \n");
!       print_gimple_stmt (dump_file, DR_STMT (drb), 0, 0);
        fprintf (dump_file, ")\n");
      }
  
*************** compute_all_dependences (VEC (data_refer
*** 3945,3975 ****
     true if STMT clobbers memory, false otherwise.  */
  
  bool
! get_references_in_stmt (tree stmt, VEC (data_ref_loc, heap) **references)
  {
    bool clobbers_memory = false;
    data_ref_loc *ref;
!   tree *op0, *op1, call;
  
    *references = NULL;
  
    /* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
       Calls have side-effects, except those to const or pure
       functions.  */
!   call = get_call_expr_in (stmt);
!   if ((call
!        && !(call_expr_flags (call) & (ECF_CONST | ECF_PURE)))
!       || (TREE_CODE (stmt) == ASM_EXPR
! 	  && ASM_VOLATILE_P (stmt)))
      clobbers_memory = true;
  
    if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
      return clobbers_memory;
  
!   if (TREE_CODE (stmt) ==  GIMPLE_MODIFY_STMT)
      {
!       op0 = &GIMPLE_STMT_OPERAND (stmt, 0);
!       op1 = &GIMPLE_STMT_OPERAND (stmt, 1);
  		
        if (DECL_P (*op1)
  	  || (REFERENCE_CLASS_P (*op1) && get_base_address (*op1)))
--- 3951,3981 ----
     true if STMT clobbers memory, false otherwise.  */
  
  bool
! get_references_in_stmt (gimple stmt, VEC (data_ref_loc, heap) **references)
  {
    bool clobbers_memory = false;
    data_ref_loc *ref;
!   tree *op0, *op1;
!   enum gimple_code stmt_code = gimple_code (stmt);
  
    *references = NULL;
  
    /* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
       Calls have side-effects, except those to const or pure
       functions.  */
!   if ((stmt_code == GIMPLE_CALL
!        && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
!       || (stmt_code == GIMPLE_ASM
! 	  && gimple_asm_volatile_p (stmt)))
      clobbers_memory = true;
  
    if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
      return clobbers_memory;
  
!   if (stmt_code == GIMPLE_ASSIGN)
      {
!       op0 = gimple_assign_lhs_ptr (stmt);
!       op1 = gimple_assign_rhs1_ptr (stmt);
  		
        if (DECL_P (*op1)
  	  || (REFERENCE_CLASS_P (*op1) && get_base_address (*op1)))
*************** get_references_in_stmt (tree stmt, VEC (
*** 3987,4000 ****
  	  ref->is_read = false;
  	}
      }
! 
!   if (call)
      {
!       unsigned i, n = call_expr_nargs (call);
  
        for (i = 0; i < n; i++)
  	{
! 	  op0 = &CALL_EXPR_ARG (call, i);
  
  	  if (DECL_P (*op0)
  	      || (REFERENCE_CLASS_P (*op0) && get_base_address (*op0)))
--- 3993,4005 ----
  	  ref->is_read = false;
  	}
      }
!   else if (stmt_code == GIMPLE_CALL)
      {
!       unsigned i, n = gimple_call_num_args (stmt);
  
        for (i = 0; i < n; i++)
  	{
! 	  op0 = gimple_call_arg_ptr (stmt, i);
  
  	  if (DECL_P (*op0)
  	      || (REFERENCE_CLASS_P (*op0) && get_base_address (*op0)))
*************** get_references_in_stmt (tree stmt, VEC (
*** 4014,4020 ****
     loop of the loop nest in that the references should be analyzed.  */
  
  static bool
! find_data_references_in_stmt (struct loop *nest, tree stmt,
  			      VEC (data_reference_p, heap) **datarefs)
  {
    unsigned i;
--- 4019,4025 ----
     loop of the loop nest in that the references should be analyzed.  */
  
  static bool
! find_data_references_in_stmt (struct loop *nest, gimple stmt,
  			      VEC (data_reference_p, heap) **datarefs)
  {
    unsigned i;
*************** find_data_references_in_loop (struct loo
*** 4064,4070 ****
  {
    basic_block bb, *bbs;
    unsigned int i;
!   block_stmt_iterator bsi;
  
    bbs = get_loop_body_in_dom_order (loop);
  
--- 4069,4075 ----
  {
    basic_block bb, *bbs;
    unsigned int i;
!   gimple_stmt_iterator bsi;
  
    bbs = get_loop_body_in_dom_order (loop);
  
*************** find_data_references_in_loop (struct loo
*** 4072,4080 ****
      {
        bb = bbs[i];
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
  	{
! 	  tree stmt = bsi_stmt (bsi);
  
  	  if (!find_data_references_in_stmt (loop, stmt, datarefs))
  	    {
--- 4077,4085 ----
      {
        bb = bbs[i];
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
  	{
! 	  gimple stmt = gsi_stmt (bsi);
  
  	  if (!find_data_references_in_stmt (loop, stmt, datarefs))
  	    {
*************** analyze_all_data_dependences (struct loo
*** 4295,4301 ****
    free_dependence_relations (dependence_relations);
    free_data_refs (datarefs);
  }
- #endif
  
  /* Computes all the data dependences and check that the results of
     several analyzers are the same.  */
--- 4300,4305 ----
*************** analyze_all_data_dependences (struct loo
*** 4303,4322 ****
  void
  tree_check_data_deps (void)
  {
-   /* FIXME tuples.  */
- #if 0
    loop_iterator li;
    struct loop *loop_nest;
  
    FOR_EACH_LOOP (li, loop_nest, 0)
      analyze_all_data_dependences (loop_nest);
- #else
-   gimple_unreachable ();
- #endif
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Free the memory used by a data dependence relation DDR.  */
  
  void
--- 4307,4319 ----
*************** dump_rdg_vertex (FILE *file, struct grap
*** 4400,4406 ****
        fprintf (file, " %d", e->dest);
  
    fprintf (file, ") \n");
!   print_generic_stmt (file, RDGV_STMT (v), TDF_VOPS|TDF_MEMSYMS);
    fprintf (file, ")\n");
  }
  
--- 4397,4403 ----
        fprintf (file, " %d", e->dest);
  
    fprintf (file, ") \n");
!   print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS);
    fprintf (file, ")\n");
  }
  
*************** dot_rdg (struct graph *rdg)
*** 4536,4549 ****
  
  struct rdg_vertex_info GTY(())
  {
!   tree stmt;
    int index;
  };
  
  /* Returns the index of STMT in RDG.  */
  
  int
! rdg_vertex_for_stmt (struct graph *rdg, tree stmt)
  {
    struct rdg_vertex_info rvi, *slot;
  
--- 4533,4546 ----
  
  struct rdg_vertex_info GTY(())
  {
!   gimple stmt;
    int index;
  };
  
  /* Returns the index of STMT in RDG.  */
  
  int
! rdg_vertex_for_stmt (struct graph *rdg, gimple stmt)
  {
    struct rdg_vertex_info rvi, *slot;
  
*************** create_rdg_edges (struct graph *rdg, VEC
*** 4647,4658 ****
  /* Build the vertices of the reduced dependence graph RDG.  */
  
  static void
! create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
  {
    int i, j;
!   tree stmt;
  
!   for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++)
      {
        VEC (data_ref_loc, heap) *references;
        data_ref_loc *ref;
--- 4644,4655 ----
  /* Build the vertices of the reduced dependence graph RDG.  */
  
  static void
! create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts)
  {
    int i, j;
!   gimple stmt;
  
!   for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++)
      {
        VEC (data_ref_loc, heap) *references;
        data_ref_loc *ref;
*************** create_rdg_vertices (struct graph *rdg, 
*** 4674,4680 ****
  
        RDG_MEM_WRITE_STMT (rdg, i) = false;
        RDG_MEM_READS_STMT (rdg, i) = false;
!       if (TREE_CODE (stmt) == PHI_NODE)
  	continue;
  
        get_references_in_stmt (stmt, &references);
--- 4671,4677 ----
  
        RDG_MEM_WRITE_STMT (rdg, i) = false;
        RDG_MEM_READS_STMT (rdg, i) = false;
!       if (gimple_code (stmt) == GIMPLE_PHI)
  	continue;
  
        get_references_in_stmt (stmt, &references);
*************** create_rdg_vertices (struct graph *rdg, 
*** 4695,4717 ****
     identifying statements. */
  
  static void
! stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
  {
    unsigned int i;
    basic_block *bbs = get_loop_body_in_dom_order (loop);
  
    for (i = 0; i < loop->num_nodes; i++)
      {
-       tree phi, stmt;
        basic_block bb = bbs[i];
!       block_stmt_iterator bsi;
  
!       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
! 	VEC_safe_push (tree, heap, *stmts, phi);
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
! 	if (TREE_CODE (stmt = bsi_stmt (bsi)) != LABEL_EXPR)
! 	  VEC_safe_push (tree, heap, *stmts, stmt);
      }
  
    free (bbs);
--- 4692,4717 ----
     identifying statements. */
  
  static void
! stmts_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
  {
    unsigned int i;
    basic_block *bbs = get_loop_body_in_dom_order (loop);
  
    for (i = 0; i < loop->num_nodes; i++)
      {
        basic_block bb = bbs[i];
!       gimple_stmt_iterator bsi;
!       gimple stmt;
  
!       for (bsi = gsi_start (phi_nodes (bb)); !gsi_end_p (bsi); gsi_next (&bsi))
! 	VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi));
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
! 	{
! 	  stmt = gsi_stmt (bsi);
! 	  if (gimple_code (stmt) != GIMPLE_LABEL)
! 	    VEC_safe_push (gimple, heap, *stmts, stmt);
! 	}
      }
  
    free (bbs);
*************** static hashval_t
*** 4738,4744 ****
  hash_stmt_vertex_info (const void *elt)
  {
    struct rdg_vertex_info *rvi = (struct rdg_vertex_info *) elt;
!   tree stmt = rvi->stmt;
  
    return htab_hash_pointer (stmt);
  }
--- 4738,4744 ----
  hash_stmt_vertex_info (const void *elt)
  {
    struct rdg_vertex_info *rvi = (struct rdg_vertex_info *) elt;
!   gimple stmt = rvi->stmt;
  
    return htab_hash_pointer (stmt);
  }
*************** build_rdg (struct loop *loop)
*** 4773,4779 ****
    struct graph *rdg = NULL;
    VEC (ddr_p, heap) *dependence_relations;
    VEC (data_reference_p, heap) *datarefs;
!   VEC (tree, heap) *stmts = VEC_alloc (tree, heap, nb_data_refs);
    
    dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
    datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
--- 4773,4779 ----
    struct graph *rdg = NULL;
    VEC (ddr_p, heap) *dependence_relations;
    VEC (data_reference_p, heap) *datarefs;
!   VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, nb_data_refs);
    
    dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
    datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
*************** build_rdg (struct loop *loop)
*** 4786,4792 ****
      goto end_rdg;
  
    stmts_from_loop (loop, &stmts);
!   rdg = new_graph (VEC_length (tree, stmts));
  
    rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
  			      eq_stmt_vertex_info, hash_stmt_vertex_del);
--- 4786,4792 ----
      goto end_rdg;
  
    stmts_from_loop (loop, &stmts);
!   rdg = new_graph (VEC_length (gimple, stmts));
  
    rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
  			      eq_stmt_vertex_info, hash_stmt_vertex_del);
*************** build_rdg (struct loop *loop)
*** 4796,4802 ****
   end_rdg:
    free_dependence_relations (dependence_relations);
    free_data_refs (datarefs);
!   VEC_free (tree, heap, stmts);
  
    return rdg;
  }
--- 4796,4802 ----
   end_rdg:
    free_dependence_relations (dependence_relations);
    free_data_refs (datarefs);
!   VEC_free (gimple, heap, stmts);
  
    return rdg;
  }
*************** free_rdg (struct graph *rdg)
*** 4819,4825 ****
     store to memory.  */
  
  void
! stores_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
  {
    unsigned int i;
    basic_block *bbs = get_loop_body_in_dom_order (loop);
--- 4819,4825 ----
     store to memory.  */
  
  void
! stores_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
  {
    unsigned int i;
    basic_block *bbs = get_loop_body_in_dom_order (loop);
*************** stores_from_loop (struct loop *loop, VEC
*** 4827,4837 ****
    for (i = 0; i < loop->num_nodes; i++)
      {
        basic_block bb = bbs[i];
!       block_stmt_iterator bsi;
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
! 	if (!ZERO_SSA_OPERANDS (bsi_stmt (bsi), SSA_OP_VDEF))
! 	  VEC_safe_push (tree, heap, *stmts, bsi_stmt (bsi));
      }
  
    free (bbs);
--- 4827,4837 ----
    for (i = 0; i < loop->num_nodes; i++)
      {
        basic_block bb = bbs[i];
!       gimple_stmt_iterator bsi;
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
! 	if (!ZERO_SSA_OPERANDS (gsi_stmt (bsi), SSA_OP_VDEF))
! 	  VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi));
      }
  
    free (bbs);
*************** stores_from_loop (struct loop *loop, VEC
*** 4841,4847 ****
     address or NULL_TREE if the base is not determined.  */
  
  static inline tree
! ref_base_address (tree stmt, data_ref_loc *ref)
  {
    tree base = NULL_TREE;
    tree base_address;
--- 4841,4847 ----
     address or NULL_TREE if the base is not determined.  */
  
  static inline tree
! ref_base_address (gimple stmt, data_ref_loc *ref)
  {
    tree base = NULL_TREE;
    tree base_address;
*************** ref_base_address (tree stmt, data_ref_lo
*** 4877,4883 ****
  bool
  rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
  {
!   tree stmt = RDG_STMT (rdg, v);
    struct loop *loop = loop_containing_stmt (stmt);
    use_operand_p imm_use_p;
    imm_use_iterator iterator;
--- 4877,4883 ----
  bool
  rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
  {
!   gimple stmt = RDG_STMT (rdg, v);
    struct loop *loop = loop_containing_stmt (stmt);
    use_operand_p imm_use_p;
    imm_use_iterator iterator;
*************** rdg_defs_used_in_other_loops_p (struct g
*** 4905,4911 ****
     ref_base_address is the same.  */
  
  bool
! have_similar_memory_accesses (tree s1, tree s2)
  {
    bool res = false;
    unsigned i, j;
--- 4905,4911 ----
     ref_base_address is the same.  */
  
  bool
! have_similar_memory_accesses (gimple s1, gimple s2)
  {
    bool res = false;
    unsigned i, j;
*************** have_similar_memory_accesses (tree s1, t
*** 4939,4945 ****
  static int
  have_similar_memory_accesses_1 (const void *s1, const void *s2)
  {
!   return have_similar_memory_accesses ((tree) s1, (tree) s2);
  }
  
  /* Helper function for the hashtab.  */
--- 4939,4945 ----
  static int
  have_similar_memory_accesses_1 (const void *s1, const void *s2)
  {
!   return have_similar_memory_accesses ((gimple) s1, (gimple) s2);
  }
  
  /* Helper function for the hashtab.  */
*************** have_similar_memory_accesses_1 (const vo
*** 4947,4953 ****
  static hashval_t
  ref_base_address_1 (const void *s)
  {
!   tree stmt = (tree) s;
    unsigned i;
    VEC (data_ref_loc, heap) *refs;
    data_ref_loc *ref;
--- 4947,4953 ----
  static hashval_t
  ref_base_address_1 (const void *s)
  {
!   gimple stmt = (gimple) s;
    unsigned i;
    VEC (data_ref_loc, heap) *refs;
    data_ref_loc *ref;
*************** ref_base_address_1 (const void *s)
*** 4969,4989 ****
  /* Try to remove duplicated write data references from STMTS.  */
  
  void
! remove_similar_memory_refs (VEC (tree, heap) **stmts)
  {
    unsigned i;
!   tree stmt;
!   htab_t seen = htab_create (VEC_length (tree, *stmts), ref_base_address_1,
  			     have_similar_memory_accesses_1, NULL);
  
!   for (i = 0; VEC_iterate (tree, *stmts, i, stmt); )
      {
        void **slot;
  
        slot = htab_find_slot (seen, stmt, INSERT);
  
        if (*slot)
! 	VEC_ordered_remove (tree, *stmts, i);
        else
  	{
  	  *slot = (void *) stmt;
--- 4969,4989 ----
  /* Try to remove duplicated write data references from STMTS.  */
  
  void
! remove_similar_memory_refs (VEC (gimple, heap) **stmts)
  {
    unsigned i;
!   gimple stmt;
!   htab_t seen = htab_create (VEC_length (gimple, *stmts), ref_base_address_1,
  			     have_similar_memory_accesses_1, NULL);
  
!   for (i = 0; VEC_iterate (gimple, *stmts, i, stmt); )
      {
        void **slot;
  
        slot = htab_find_slot (seen, stmt, INSERT);
  
        if (*slot)
! 	VEC_ordered_remove (gimple, *stmts, i);
        else
  	{
  	  *slot = (void *) stmt;
*************** remove_similar_memory_refs (VEC (tree, h
*** 4993,4996 ****
  
    htab_delete (seen);
  }
- #endif
--- 4993,4995 ----
Index: tree-data-ref.h
===================================================================
*** tree-data-ref.h	(revision 133063)
--- tree-data-ref.h	(working copy)
*************** struct dr_alias
*** 100,106 ****
  struct data_reference
  {
    /* A pointer to the statement that contains this DR.  */
!   tree stmt;
    
    /* A pointer to the memory reference.  */
    tree ref;
--- 100,106 ----
  struct data_reference
  {
    /* A pointer to the statement that contains this DR.  */
!   gimple stmt;
    
    /* A pointer to the memory reference.  */
    tree ref;
*************** typedef struct data_ref_loc_d
*** 304,310 ****
  DEF_VEC_O (data_ref_loc);
  DEF_VEC_ALLOC_O (data_ref_loc, heap);
  
! bool get_references_in_stmt (tree, VEC (data_ref_loc, heap) **);
  void dr_analyze_innermost (struct data_reference *);
  extern void compute_data_dependences_for_loop (struct loop *, bool,
  					       VEC (data_reference_p, heap) **,
--- 304,310 ----
  DEF_VEC_O (data_ref_loc);
  DEF_VEC_ALLOC_O (data_ref_loc, heap);
  
! bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
  void dr_analyze_innermost (struct data_reference *);
  extern void compute_data_dependences_for_loop (struct loop *, bool,
  					       VEC (data_reference_p, heap) **,
*************** extern void free_dependence_relation (st
*** 328,334 ****
  extern void free_dependence_relations (VEC (ddr_p, heap) *);
  extern void free_data_ref (data_reference_p);
  extern void free_data_refs (VEC (data_reference_p, heap) *);
! struct data_reference *create_data_ref (struct loop *, tree, tree, bool);
  bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
  void compute_all_dependences (VEC (data_reference_p, heap) *,
  			      VEC (ddr_p, heap) **, VEC (loop_p, heap) *, bool);
--- 328,334 ----
  extern void free_dependence_relations (VEC (ddr_p, heap) *);
  extern void free_data_ref (data_reference_p);
  extern void free_data_refs (VEC (data_reference_p, heap) *);
! struct data_reference *create_data_ref (struct loop *, tree, gimple, bool);
  bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
  void compute_all_dependences (VEC (data_reference_p, heap) *,
  			      VEC (ddr_p, heap) **, VEC (loop_p, heap) *, bool);
*************** ddr_dependence_level (ddr_p ddr)
*** 398,404 ****
  typedef struct rdg_vertex
  {
    /* The statement represented by this vertex.  */
!   tree stmt;
  
    /* True when the statement contains a write to memory.  */
    bool has_mem_write;
--- 398,404 ----
  typedef struct rdg_vertex
  {
    /* The statement represented by this vertex.  */
!   gimple stmt;
  
    /* True when the statement contains a write to memory.  */
    bool has_mem_write;
*************** void debug_rdg_component (struct graph *
*** 421,427 ****
  void dump_rdg (FILE *, struct graph *);
  void debug_rdg (struct graph *);
  void dot_rdg (struct graph *);
! int rdg_vertex_for_stmt (struct graph *, tree);
  
  /* Data dependence type.  */
  
--- 421,427 ----
  void dump_rdg (FILE *, struct graph *);
  void debug_rdg (struct graph *);
  void dot_rdg (struct graph *);
! int rdg_vertex_for_stmt (struct graph *, gimple);
  
  /* Data dependence type.  */
  
*************** index_in_loop_nest (int var, VEC (loop_p
*** 474,483 ****
    return var_index;
  }
  
! void stores_from_loop (struct loop *, VEC (tree, heap) **);
! void remove_similar_memory_refs (VEC (tree, heap) **);
  bool rdg_defs_used_in_other_loops_p (struct graph *, int);
! bool have_similar_memory_accesses (tree, tree);
  
  /* Determines whether RDG vertices V1 and V2 access to similar memory
     locations, in which case they have to be in the same partition.  */
--- 474,483 ----
    return var_index;
  }
  
! void stores_from_loop (struct loop *, VEC (gimple, heap) **);
! void remove_similar_memory_refs (VEC (gimple, heap) **);
  bool rdg_defs_used_in_other_loops_p (struct graph *, int);
! bool have_similar_memory_accesses (gimple, gimple);
  
  /* Determines whether RDG vertices V1 and V2 access to similar memory
     locations, in which case they have to be in the same partition.  */
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 133063)
--- gimplify.c	(working copy)
*************** gimplify_modify_expr (tree *expr_p, gimp
*** 4023,4028 ****
--- 4023,4029 ----
  	 we're probably modified it twice.  Not good.  */
        gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
        *to_p = make_ssa_name (*to_p, assign);
+       gimple_assign_set_lhs (assign, *to_p);
      }
  
    if (want_value)
Index: tree-ssa-coalesce.c
===================================================================
*** tree-ssa-coalesce.c	(revision 133063)
--- tree-ssa-coalesce.c	(working copy)
*************** build_ssa_conflict_graph (tree_live_info
*** 861,867 ****
  	    {
  	      tree lhs = gimple_assign_lhs (stmt);
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (get_gimple_rhs_num_ops (gimple_assign_subcode (stmt)) == 1
                    && TREE_CODE (lhs) == SSA_NAME
                    && TREE_CODE (rhs1) == SSA_NAME)
  		live_track_clear_var (live, rhs1);
--- 861,867 ----
  	    {
  	      tree lhs = gimple_assign_lhs (stmt);
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (gimple_assign_copy_p (stmt)
                    && TREE_CODE (lhs) == SSA_NAME
                    && TREE_CODE (rhs1) == SSA_NAME)
  		live_track_clear_var (live, rhs1);
*************** create_outofssa_var_map (coalesce_list_p
*** 1042,1048 ****
  		tree lhs = gimple_assign_lhs (stmt);
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  
! 		if (get_gimple_rhs_num_ops (gimple_assign_subcode (stmt)) == 1
                      && TREE_CODE (lhs) == SSA_NAME
  		    && TREE_CODE (rhs1) == SSA_NAME
  		    && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1))
--- 1042,1048 ----
  		tree lhs = gimple_assign_lhs (stmt);
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  
! 		if (gimple_assign_copy_p (stmt)
                      && TREE_CODE (lhs) == SSA_NAME
  		    && TREE_CODE (rhs1) == SSA_NAME
  		    && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1))
Index: tree-predcom.c
===================================================================
*** tree-predcom.c	(revision 133063)
--- tree-predcom.c	(working copy)
*************** get_init_expr (chain_p chain, unsigned i
*** 1386,1391 ****
--- 1386,1393 ----
      return VEC_index (tree, chain->inits, index);
  }
  
+ #endif
+ 
  /* Marks all virtual operands of statement STMT for renaming.  */
  
  void
*************** mark_virtual_ops_for_renaming (gimple st
*** 1394,1400 ****
    ssa_op_iter iter;
    tree var;
  
!   if (gimple_code (stmt) == GIMPLE_PI)
      {
        var = PHI_RESULT (stmt);
        if (is_gimple_reg (var))
--- 1396,1402 ----
    ssa_op_iter iter;
    tree var;
  
!   if (gimple_code (stmt) == GIMPLE_PHI)
      {
        var = PHI_RESULT (stmt);
        if (is_gimple_reg (var))
*************** mark_virtual_ops_for_renaming (gimple st
*** 1416,1421 ****
--- 1418,1425 ----
      }
  }
  
+    /* FIXME tuples.  */
+ #if 0
  /* Calls mark_virtual_ops_for_renaming for all members of LIST.  */
  
  static void
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 133063)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 48,55 ****
  #include "tree-data-ref.h"
  #include "optabs.h"
  
- /* FIXME tuples.  */
- #if 0
  /* This pass inserts prefetch instructions to optimize cache usage during
     accesses to arrays in loops.  It processes loops sequentially and:
  
--- 48,53 ----
*************** struct mem_ref_group
*** 203,209 ****
  
  struct mem_ref
  {
!   tree stmt;			/* Statement in that the reference appears.  */
    tree mem;			/* The reference.  */
    HOST_WIDE_INT delta;		/* Constant offset of the reference.  */
    struct mem_ref_group *group;	/* The group of references it belongs to.  */
--- 201,207 ----
  
  struct mem_ref
  {
!   gimple stmt;			/* Statement in that the reference appears.  */
    tree mem;			/* The reference.  */
    HOST_WIDE_INT delta;		/* Constant offset of the reference.  */
    struct mem_ref_group *group;	/* The group of references it belongs to.  */
*************** find_or_create_group (struct mem_ref_gro
*** 280,286 ****
     WRITE_P.  The reference occurs in statement STMT.  */
  
  static void
! record_ref (struct mem_ref_group *group, tree stmt, tree mem,
  	    HOST_WIDE_INT delta, bool write_p)
  {
    struct mem_ref **aref;
--- 278,284 ----
     WRITE_P.  The reference occurs in statement STMT.  */
  
  static void
! record_ref (struct mem_ref_group *group, gimple stmt, tree mem,
  	    HOST_WIDE_INT delta, bool write_p)
  {
    struct mem_ref **aref;
*************** release_mem_refs (struct mem_ref_group *
*** 346,352 ****
  struct ar_data
  {
    struct loop *loop;			/* Loop of the reference.  */
!   tree stmt;				/* Statement of the reference.  */
    HOST_WIDE_INT *step;			/* Step of the memory reference.  */
    HOST_WIDE_INT *delta;			/* Offset of the memory reference.  */
  };
--- 344,350 ----
  struct ar_data
  {
    struct loop *loop;			/* Loop of the reference.  */
!   gimple stmt;				/* Statement of the reference.  */
    HOST_WIDE_INT *step;			/* Step of the memory reference.  */
    HOST_WIDE_INT *delta;			/* Offset of the memory reference.  */
  };
*************** idx_analyze_ref (tree base, tree *index,
*** 413,419 ****
  static bool
  analyze_ref (struct loop *loop, tree *ref_p, tree *base,
  	     HOST_WIDE_INT *step, HOST_WIDE_INT *delta,
! 	     tree stmt)
  {
    struct ar_data ar_data;
    tree off;
--- 411,417 ----
  static bool
  analyze_ref (struct loop *loop, tree *ref_p, tree *base,
  	     HOST_WIDE_INT *step, HOST_WIDE_INT *delta,
! 	     gimple stmt)
  {
    struct ar_data ar_data;
    tree off;
*************** analyze_ref (struct loop *loop, tree *re
*** 453,459 ****
  
  static bool
  gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
! 			      tree ref, bool write_p, tree stmt)
  {
    tree base;
    HOST_WIDE_INT step, delta;
--- 451,457 ----
  
  static bool
  gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
! 			      tree ref, bool write_p, gimple stmt)
  {
    tree base;
    HOST_WIDE_INT step, delta;
*************** gather_memory_references (struct loop *l
*** 479,486 ****
    basic_block *body = get_loop_body_in_dom_order (loop);
    basic_block bb;
    unsigned i;
!   block_stmt_iterator bsi;
!   tree stmt, lhs, rhs, call;
    struct mem_ref_group *refs = NULL;
  
    *no_other_refs = true;
--- 477,485 ----
    basic_block *body = get_loop_body_in_dom_order (loop);
    basic_block bb;
    unsigned i;
!   gimple_stmt_iterator bsi;
!   gimple stmt;
!   tree lhs, rhs;
    struct mem_ref_group *refs = NULL;
  
    *no_other_refs = true;
*************** gather_memory_references (struct loop *l
*** 493,514 ****
        if (bb->loop_father != loop)
  	continue;
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
  	{
! 	  stmt = bsi_stmt (bsi);
! 	  call = get_call_expr_in (stmt);
! 	  if (call && !(call_expr_flags (call) & ECF_CONST))
! 	    *no_other_refs = false;
  
! 	  if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
  	    {
! 	      if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
  		*no_other_refs = false;
  	      continue;
  	    }
  
! 	  lhs = GIMPLE_STMT_OPERAND (stmt, 0);
! 	  rhs = GIMPLE_STMT_OPERAND (stmt, 1);
  
  	  if (REFERENCE_CLASS_P (rhs))
  	    *no_other_refs &= gather_memory_references_ref (loop, &refs,
--- 492,512 ----
        if (bb->loop_father != loop)
  	continue;
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
  	{
! 	  stmt = gsi_stmt (bsi);
  
! 	  if (gimple_code (stmt) != GIMPLE_ASSIGN)
  	    {
! 	      if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)
! 		  || (gimple_code (stmt) == GIMPLE_CALL
! 		      && !(gimple_call_flags (stmt) & ECF_CONST)))
  		*no_other_refs = false;
  	      continue;
  	    }
  
! 	  lhs = gimple_assign_lhs (stmt);
! 	  rhs = gimple_assign_rhs1 (stmt);
  
  	  if (REFERENCE_CLASS_P (rhs))
  	    *no_other_refs &= gather_memory_references_ref (loop, &refs,
*************** static void
*** 868,875 ****
  issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
  {
    HOST_WIDE_INT delta;
!   tree addr, addr_base, prefetch, write_p, local;
!   block_stmt_iterator bsi;
    unsigned n_prefetches, ap;
    bool nontemporal = ref->reuse_distance >= L2_CACHE_SIZE_BYTES;
  
--- 866,874 ----
  issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
  {
    HOST_WIDE_INT delta;
!   tree addr, addr_base, write_p, local;
!   gimple prefetch;
!   gimple_stmt_iterator bsi;
    unsigned n_prefetches, ap;
    bool nontemporal = ref->reuse_distance >= L2_CACHE_SIZE_BYTES;
  
*************** issue_prefetch_ref (struct mem_ref *ref,
*** 878,890 ****
  	     nontemporal ? " nontemporal" : "",
  	     (void *) ref);
  
!   bsi = bsi_for_stmt (ref->stmt);
  
    n_prefetches = ((unroll_factor + ref->prefetch_mod - 1)
  		  / ref->prefetch_mod);
    addr_base = build_fold_addr_expr_with_type (ref->mem, ptr_type_node);
!   addr_base = force_gimple_operand_bsi (&bsi, unshare_expr (addr_base),
! 					true, NULL, true, BSI_SAME_STMT);
    write_p = ref->write_p ? integer_one_node : integer_zero_node;
    local = build_int_cst (integer_type_node, nontemporal ? 0 : 3);
  
--- 877,889 ----
  	     nontemporal ? " nontemporal" : "",
  	     (void *) ref);
  
!   bsi = gsi_for_stmt (ref->stmt);
  
    n_prefetches = ((unroll_factor + ref->prefetch_mod - 1)
  		  / ref->prefetch_mod);
    addr_base = build_fold_addr_expr_with_type (ref->mem, ptr_type_node);
!   addr_base = force_gimple_operand_gsi (&bsi, unshare_expr (addr_base),
! 					true, NULL, true, GSI_SAME_STMT);
    write_p = ref->write_p ? integer_one_node : integer_zero_node;
    local = build_int_cst (integer_type_node, nontemporal ? 0 : 3);
  
*************** issue_prefetch_ref (struct mem_ref *ref,
*** 894,906 ****
        delta = (ahead + ap * ref->prefetch_mod) * ref->group->step;
        addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
  			  addr_base, size_int (delta));
!       addr = force_gimple_operand_bsi (&bsi, unshare_expr (addr), true, NULL,
! 				       true, BSI_SAME_STMT);
  
        /* Create the prefetch instruction.  */
!       prefetch = build_call_expr (built_in_decls[BUILT_IN_PREFETCH],
! 				  3, addr, write_p, local);
!       bsi_insert_before (&bsi, prefetch, BSI_SAME_STMT);
      }
  }
  
--- 893,905 ----
        delta = (ahead + ap * ref->prefetch_mod) * ref->group->step;
        addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
  			  addr_base, size_int (delta));
!       addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, NULL,
! 				       true, GSI_SAME_STMT);
  
        /* Create the prefetch instruction.  */
!       prefetch = gimple_build_call (built_in_decls[BUILT_IN_PREFETCH],
! 				    3, addr, write_p, local);
!       gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT);
      }
  }
  
*************** mark_nontemporal_store (struct mem_ref *
*** 959,965 ****
      fprintf (dump_file, "Marked reference %p as a nontemporal store.\n",
  	     (void *) ref);
  
!   MOVE_NONTEMPORAL (ref->stmt) = true;
    ref->storent_p = true;
  
    return true;
--- 958,964 ----
      fprintf (dump_file, "Marked reference %p as a nontemporal store.\n",
  	     (void *) ref);
  
!   gimple_assign_set_nontemporal_move (ref->stmt, true);
    ref->storent_p = true;
  
    return true;
*************** emit_mfence_after_loop (struct loop *loo
*** 972,993 ****
  {
    VEC (edge, heap) *exits = get_loop_exit_edges (loop);
    edge exit;
!   tree call;
!   block_stmt_iterator bsi;
    unsigned i;
  
    for (i = 0; VEC_iterate (edge, exits, i, exit); i++)
      {
!       call = build_function_call_expr (FENCE_FOLLOWING_MOVNT, NULL_TREE);
  
        if (!single_pred_p (exit->dest)
  	  /* If possible, we prefer not to insert the fence on other paths
  	     in cfg.  */
  	  && !(exit->flags & EDGE_ABNORMAL))
  	split_loop_exit_edge (exit);
!       bsi = bsi_after_labels (exit->dest);
  
!       bsi_insert_before (&bsi, call, BSI_NEW_STMT);
        mark_virtual_ops_for_renaming (call);
      }
  
--- 971,992 ----
  {
    VEC (edge, heap) *exits = get_loop_exit_edges (loop);
    edge exit;
!   gimple call;
!   gimple_stmt_iterator bsi;
    unsigned i;
  
    for (i = 0; VEC_iterate (edge, exits, i, exit); i++)
      {
!       call = gimple_build_call (FENCE_FOLLOWING_MOVNT, 0);
  
        if (!single_pred_p (exit->dest)
  	  /* If possible, we prefer not to insert the fence on other paths
  	     in cfg.  */
  	  && !(exit->flags & EDGE_ABNORMAL))
  	split_loop_exit_edge (exit);
!       bsi = gsi_after_labels (exit->dest);
  
!       gsi_insert_before (&bsi, call, GSI_NEW_STMT);
        mark_virtual_ops_for_renaming (call);
      }
  
*************** tree_ssa_prefetch_arrays (void)
*** 1596,1599 ****
    free_original_copy_tables ();
    return todo_flags;
  }
- #endif
--- 1595,1597 ----
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 133063)
--- tree-inline.c	(working copy)
*************** estimate_num_insns (gimple stmt, eni_wei
*** 2412,2418 ****
        else
  	cost = estimate_move_cost (TREE_TYPE (lhs));
  
!       cost += estimate_operator_cost (gimple_assign_subcode (stmt), weights);
        break;
  
      case GIMPLE_COND:
--- 2412,2418 ----
        else
  	cost = estimate_move_cost (TREE_TYPE (lhs));
  
!       cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights);
        break;
  
      case GIMPLE_COND:
Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 133063)
--- tree-flow.h	(working copy)
*************** void tree_transform_and_unroll_loop (str
*** 1020,1026 ****
  				     transform_callback, void *);
  bool contains_abnormal_ssa_name_p (tree);
  bool stmt_dominates_stmt_p (gimple, gimple);
! void mark_virtual_ops_for_renaming (tree);
  
  /* In tree-ssa-threadedge.c */
  extern bool potentially_threadable_block (basic_block);
--- 1020,1026 ----
  				     transform_callback, void *);
  bool contains_abnormal_ssa_name_p (tree);
  bool stmt_dominates_stmt_p (gimple, gimple);
! void mark_virtual_ops_for_renaming (gimple);
  
  /* In tree-ssa-threadedge.c */
  extern bool potentially_threadable_block (basic_block);
Index: gimple.h
===================================================================
*** gimple.h	(revision 133063)
--- gimple.h	(working copy)
*************** struct gimple_statement_base GTY(())
*** 208,217 ****
       structure grow an additional word on 32bit hosts.  */
    unsigned int no_warning	: 1;
    unsigned int visited		: 1;
    unsigned int unused_1		: 1;
    unsigned int unused_2		: 1;
    unsigned int unused_3		: 1;
-   unsigned int unused_4		: 1;
  
    /* Pass local flags.  These flags are free for any pass to use as
       they see fit.  Passes should not assume that these flags contain
--- 208,217 ----
       structure grow an additional word on 32bit hosts.  */
    unsigned int no_warning	: 1;
    unsigned int visited		: 1;
+   unsigned int nontemporal_move	: 1;
    unsigned int unused_1		: 1;
    unsigned int unused_2		: 1;
    unsigned int unused_3		: 1;
  
    /* Pass local flags.  These flags are free for any pass to use as
       they see fit.  Passes should not assume that these flags contain
*************** gimple_assign_rhs2 (const_gimple gs)
*** 1121,1126 ****
--- 1120,1139 ----
    return gimple_op (gs, 2);
  }
  
+ /* Return the second operand on the RHS of assignment statement GS
+    if it has one, NULL_TREE otherwise.  */
+ 
+ static inline tree
+ gimple_assign_rhs2_or_null (const_gimple gs)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ 
+   if (gimple_num_ops (gs) >= 3)
+     return gimple_op (gs, 2);
+   else
+     return NULL_TREE;
+ }
+ 
  /* Return a pointer to the second operand on the RHS of assignment
     statement GS.  */
  
*************** gimple_assign_set_rhs2 (gimple gs, tree 
*** 1142,1147 ****
--- 1155,1177 ----
    gimple_set_op (gs, 2, rhs);
  }
  
+ /* Returns true if GS is a nontemporal move.  */
+ 
+ static inline bool
+ gimple_assign_nontemporal_move_p (const_gimple gs)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+   return gs->gsbase.nontemporal_move;
+ }
+ 
+ /* Sets nontemporal move flag of GS to NONTEMPORAL.  */
+ 
+ static inline void
+ gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+   gs->gsbase.nontemporal_move = nontemporal;
+ }
  
  /* Return true if S is an type-cast assignment.  */
  
*************** void gsi_move_to_bb_end (gimple_stmt_ite
*** 3015,3020 ****
--- 3045,3051 ----
  void gsi_insert_on_edge (edge, gimple);
  void gsi_insert_seq_on_edge (edge, gimple_seq);
  basic_block gsi_insert_on_edge_immediate (edge, gimple);
+ basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
  void gsi_commit_one_edge_insert (edge, basic_block *);
  void gsi_commit_edge_inserts (void);
  
Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 133063)
--- tree-cfg.c	(working copy)
*************** verify_types_in_gimple_cond (gimple stmt
*** 3278,3284 ****
  static bool
  verify_types_in_gimple_assign (gimple stmt)
  {
!   enum tree_code rhs_code = gimple_assign_subcode (stmt);
    tree lhs = gimple_assign_lhs (stmt);
    tree rhs1 = gimple_assign_rhs1 (stmt);
    tree rhs2 = (gimple_num_ops (stmt) == 3) ? gimple_assign_rhs2 (stmt) : NULL;
--- 3278,3284 ----
  static bool
  verify_types_in_gimple_assign (gimple stmt)
  {
!   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    tree lhs = gimple_assign_lhs (stmt);
    tree rhs1 = gimple_assign_rhs1 (stmt);
    tree rhs2 = (gimple_num_ops (stmt) == 3) ? gimple_assign_rhs2 (stmt) : NULL;
*************** gimple_execute_on_shrinking_pred (edge e
*** 6482,6494 ****
     additional edge 'e' that new_head to second edge received as part of edge
     splitting.  */
  
- /* FIXME tuples.  */
- #if 0
  static void
  gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
! 				basic_block new_head, edge e)
  {
!   tree phi1, phi2;
    edge e2 = find_edge (new_head, second);
  
    /* Because NEW_HEAD has been created by splitting SECOND's incoming
--- 6482,6494 ----
     additional edge 'e' that new_head to second edge received as part of edge
     splitting.  */
  
  static void
  gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
! 				  basic_block new_head, edge e)
  {
!   gimple phi1, phi2;
!   gimple_stmt_iterator psi1, psi2;
!   tree def;
    edge e2 = find_edge (new_head, second);
  
    /* Because NEW_HEAD has been created by splitting SECOND's incoming
*************** gimple_lv_adjust_loop_header_phi (basic_
*** 6498,6508 ****
    /* Browse all 'second' basic block phi nodes and add phi args to
       edge 'e' for 'first' head. PHI args are always in correct order.  */
  
!   for (phi2 = phi_nodes (second), phi1 = phi_nodes (first);
!        phi2 && phi1;
!        phi2 = PHI_CHAIN (phi2),  phi1 = PHI_CHAIN (phi1))
!     {
!       tree def = PHI_ARG_DEF (phi2, e2->dest_idx);
        add_phi_arg (phi1, def, e);
      }
  }
--- 6498,6511 ----
    /* Browse all 'second' basic block phi nodes and add phi args to
       edge 'e' for 'first' head. PHI args are always in correct order.  */
  
!   for (psi2 = gsi_start (phi_nodes (second)),
!        psi1 = gsi_start (phi_nodes (first));
!        !gsi_end_p (psi2) && !gsi_end_p (psi1);
!        gsi_next (&psi2),  gsi_next (&psi1))
!     {
!       phi1 = gsi_stmt (psi1);
!       phi2 = gsi_stmt (psi2);
!       def = PHI_ARG_DEF (phi2, e2->dest_idx);
        add_phi_arg (phi1, def, e);
      }
  }
*************** gimple_lv_adjust_loop_header_phi (basic_
*** 6513,6540 ****
  
  static void
  gimple_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
! 			     basic_block second_head ATTRIBUTE_UNUSED,
! 			     basic_block cond_bb, void *cond_e)
  {
    gimple_stmt_iterator gsi;
!   tree new_cond_expr = NULL_TREE;
    tree cond_expr = (tree) cond_e;
    edge e0;
  
    /* Build new conditional expr */
!   new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr,
! 			  NULL_TREE, NULL_TREE);
  
    /* Add new cond in cond_bb.  */
!   gsi = gsi_start (cond_bb);
    gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
    /* Adjust edges appropriately to connect new head with first head
       as well as second head.  */
    e0 = single_succ_edge (cond_bb);
    e0->flags &= ~EDGE_FALLTHRU;
    e0->flags |= EDGE_FALSE_VALUE;
  }
- #endif
  
  struct cfg_hooks gimple_cfg_hooks = {
    "gimple",
--- 6516,6543 ----
  
  static void
  gimple_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
! 			       basic_block second_head ATTRIBUTE_UNUSED,
! 			       basic_block cond_bb, void *cond_e)
  {
    gimple_stmt_iterator gsi;
!   gimple new_cond_expr;
    tree cond_expr = (tree) cond_e;
    edge e0;
  
    /* Build new conditional expr */
!   new_cond_expr = gimple_build_cond_from_tree (cond_expr,
! 					       NULL_TREE, NULL_TREE);
  
    /* Add new cond in cond_bb.  */
!   gsi = gsi_last_bb (cond_bb);
    gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
+ 
    /* Adjust edges appropriately to connect new head with first head
       as well as second head.  */
    e0 = single_succ_edge (cond_bb);
    e0->flags &= ~EDGE_FALLTHRU;
    e0->flags |= EDGE_FALSE_VALUE;
  }
  
  struct cfg_hooks gimple_cfg_hooks = {
    "gimple",
*************** struct cfg_hooks gimple_cfg_hooks = {
*** 6562,6569 ****
    gimple_execute_on_growing_pred,	/* execute_on_growing_pred */
    gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
    gimple_duplicate_loop_to_header_edge, /* duplicate loop for trees */
!   0 /* FIXME tuples gimple_lv_add_condition_to_bb */, /* lv_add_condition_to_bb */
!   0 /* FIXME tuples gimple_lv_adjust_loop_header_phi */, /* lv_adjust_loop_header_phi*/
    extract_true_false_edges_from_block, /* extract_cond_bb_edges */
    flush_pending_stmts		/* flush_pending_stmts */
  };
--- 6565,6572 ----
    gimple_execute_on_growing_pred,	/* execute_on_growing_pred */
    gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
    gimple_duplicate_loop_to_header_edge, /* duplicate loop for trees */
!   gimple_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
!   gimple_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
    extract_true_false_edges_from_block, /* extract_cond_bb_edges */
    flush_pending_stmts		/* flush_pending_stmts */
  };
Index: passes.c
===================================================================
*** passes.c	(revision 133063)
--- passes.c	(working copy)
*************** init_optimization_passes (void)
*** 552,558 ****
--- 552,561 ----
  #if 0
  	  NEXT_PASS (pass_simple_dse);
  	  NEXT_PASS (pass_tail_recursion);
+ #endif
            NEXT_PASS (pass_profile);
+ /* FIXME tuples.  */
+ #if 0
  	  NEXT_PASS (pass_release_ssa_names);
  #endif
  	}
*************** init_optimization_passes (void)
*** 672,678 ****
--- 675,683 ----
  #if 0
  	  NEXT_PASS (pass_empty_loop);
  	  NEXT_PASS (pass_record_bounds);
+ #endif
  	  NEXT_PASS (pass_check_data_deps);
+ #if 0
  	  NEXT_PASS (pass_loop_distribution);
  	  NEXT_PASS (pass_linear_transform);
  	  NEXT_PASS (pass_iv_canon);
*************** init_optimization_passes (void)
*** 685,691 ****
--- 690,698 ----
  	    }
  	  NEXT_PASS (pass_complete_unroll);
  	  NEXT_PASS (pass_parallelize_loops);
+ #endif
  	  NEXT_PASS (pass_loop_prefetch);
+ #if 0
  	  NEXT_PASS (pass_iv_optimize);
  #endif
  	  NEXT_PASS (pass_tree_loop_done);



More information about the Gcc-patches mailing list