This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lno] Generic create_iv function
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: Daniel Berlin <dberlin at dberlin dot org>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Feb 2004 15:16:57 +0100
- Subject: [lno] Generic create_iv function
- References: <BFF21737-625E-11D8-8006-000A95DA505C@dberlin.org>
Hello,
> Is there any way you could generalize create_iv so that it takes a
> loop argument, the position to place, and the increment, and creates
> an iv for that loop?
>
> I would much appreciate it, since this is what i have to do for
> recreating loop nests based on the loop nests lambda hands us.
>
> Otherwise, i'm going to have to build high level loop manipulators
> like create_iv on my own, which seems a waste of time since you've
> more or less already done it.
here it is.
Zdenek
Index: ChangeLog.lno
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/ChangeLog.lno,v
retrieving revision 1.1.2.56
diff -c -3 -p -r1.1.2.56 ChangeLog.lno
*** ChangeLog.lno 19 Feb 2004 13:19:19 -0000 1.1.2.56
--- ChangeLog.lno 19 Feb 2004 14:14:32 -0000
***************
*** 1,5 ****
--- 1,11 ----
2004-02-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ * tree-flow.h (create_iv): Declare.
+ * tree-ssa-loop-ivopts.c (create_iv): New function.
+ (create_new_iv): Use create_iv.
+
+ 2004-02-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
* tree-ssa-loop.c (do_while_loop_p): New function.
(copy_loop_headers): Do not peel do-while loops.
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.177.2.9
diff -c -3 -p -r1.1.4.177.2.9 tree-flow.h
*** tree-flow.h 16 Feb 2004 21:59:28 -0000 1.1.4.177.2.9
--- tree-flow.h 19 Feb 2004 14:14:33 -0000
*************** bool tree_duplicate_loop_to_header_edge
*** 556,561 ****
--- 556,563 ----
unsigned int, sbitmap,
edge, edge *,
unsigned int *, int);
+ void create_iv (tree, tree, tree, struct loop *, block_stmt_iterator *, bool,
+ tree *, tree *);
void test_loop_versioning (struct loops *loops);
bool tree_ssa_loop_version (struct loops *, struct loop *, tree);
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-loop-ivopts.c,v
retrieving revision 1.1.2.7
diff -c -3 -p -r1.1.2.7 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c 19 Feb 2004 07:14:43 -0000 1.1.2.7
--- tree-ssa-loop-ivopts.c 19 Feb 2004 14:14:33 -0000
*************** find_optimal_iv_set (void)
*** 3867,3879 ****
return best;
}
/* Creates a new induction variable corresponding to CAND. */
static void
create_new_iv (struct iv_cand *cand)
{
block_stmt_iterator incr_pos;
! tree initial, stmt, base, stmts;
bool after = false;
switch (cand->pos)
--- 3867,3934 ----
return best;
}
+ /* 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
+ (if NULL, a new temporary will be created). The increment will occur at
+ INCR_POS (after it if AFTER is true, before it otherwise). The ssa versions
+ of the variable before and after increment will be stored in VAR_BEFORE and
+ VAR_AFTER (unless they are NULL). */
+
+ 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, stmts, initial;
+ tree vb, va;
+
+ if (!var)
+ {
+ var = create_tmp_var (TREE_TYPE (base), "ivtmp");
+ add_referenced_tmp_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;
+
+ stmt = build (MODIFY_EXPR, void_type_node, va,
+ build (PLUS_EXPR, 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, var, false);
+ if (stmts)
+ {
+ basic_block new_bb;
+ edge pe = loop_preheader_edge (loop);
+
+ new_bb = bsi_insert_on_edge_immediate (pe, stmts);
+ if (new_bb)
+ add_bb_to_loop (new_bb, new_bb->pred->src->loop_father);
+ }
+
+ 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));
+ }
+
/* Creates a new induction variable corresponding to CAND. */
static void
create_new_iv (struct iv_cand *cand)
{
block_stmt_iterator incr_pos;
! tree base;
bool after = false;
switch (cand->pos)
*************** create_new_iv (struct iv_cand *cand)
*** 3902,3920 ****
gimple_add_tmp_var (cand->var_before);
add_referenced_tmp_var (cand->var_before);
- cand->var_before = make_ssa_name (cand->var_before, NULL_TREE);
- cand->var_after = make_ssa_name (cand->var_after, NULL_TREE);
-
- stmt = build (MODIFY_EXPR, void_type_node,
- cand->var_after,
- build (PLUS_EXPR, TREE_TYPE (cand->var_after),
- cand->var_before,
- cand->iv->step));
- SSA_NAME_DEF_STMT (cand->var_after) = stmt;
- if (after)
- bsi_insert_after (&incr_pos, stmt, BSI_NEW_STMT);
- else
- bsi_insert_before (&incr_pos, stmt, BSI_NEW_STMT);
base = unshare_expr (cand->iv->base);
if (cand->pos == IP_START)
--- 3957,3962 ----
*************** create_new_iv (struct iv_cand *cand)
*** 3924,3945 ****
base = fold (build (MINUS_EXPR, TREE_TYPE (base), base, cand->iv->step));
}
! initial = force_gimple_operand (base, &stmts,
! SSA_NAME_VAR (cand->var_before), false);
! if (stmts)
! {
! basic_block new_bb;
! edge pe = loop_preheader_edge (current_loop);
!
! new_bb = bsi_insert_on_edge_immediate (pe, stmts);
! if (new_bb)
! add_bb_to_loop (new_bb, new_bb->pred->src->loop_father);
! }
!
! stmt = create_phi_node (cand->var_before, current_loop->header);
! SSA_NAME_DEF_STMT (cand->var_before) = stmt;
! add_phi_arg (&stmt, initial, loop_preheader_edge (current_loop));
! add_phi_arg (&stmt, cand->var_after, loop_latch_edge (current_loop));
}
/* Creates new induction variables described in SET. */
--- 3966,3973 ----
base = fold (build (MINUS_EXPR, TREE_TYPE (base), base, cand->iv->step));
}
! create_iv (base, cand->iv->step, cand->var_before, current_loop,
! &incr_pos, after, &cand->var_before, &cand->var_after);
}
/* Creates new induction variables described in SET. */