钟居哲 <juzhe.zh...@rivai.ai> writes: > I am sorry that I am still confused about that. > > Is this what you want ? > > bool use_minus_p = TREE_CODE (step) == INTEGER_CST && ((TYPE_UNSIGNED > (TREE_TYPE (step)) && tree_int_cst_lt (step1, step)) > || (!TYPE_UNSIGNED (TREE_TYPE (step)) && > !tree_expr_nonnegative_warnv_p (step, &ovf) && may_negate_without_overflow_p > (step))); > > /* For easier readability of the created code, produce MINUS_EXPRs > when suitable. */ > if (TREE_CODE (step) == INTEGER_CST) > { > if (TYPE_UNSIGNED (TREE_TYPE (step))) > { > step1 = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step); > if (tree_int_cst_lt (step1, step)) > { > incr_op = MINUS_EXPR; /* Remove it. */ > step = step1; > } > } > else > { > bool ovf; > > if (!tree_expr_nonnegative_warnv_p (step, &ovf) > && may_negate_without_overflow_p (step)) > { > incr_op = MINUS_EXPR; /* Remove it. */ > step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step); > } > } > } > if (POINTER_TYPE_P (TREE_TYPE (base))) > { > if (TREE_CODE (base) == ADDR_EXPR) > mark_addressable (TREE_OPERAND (base, 0)); > step = convert_to_ptrofftype (step); > if (incr_op == MINUS_EXPR) /* Change it into if (use_minus_p) */ > step = fold_build1 (NEGATE_EXPR, TREE_TYPE (step), step); > incr_op = POINTER_PLUS_EXPR; /* Remove it. */ > } > /* Gimplify the step if necessary. We put the computations in front of the > loop (i.e. the step should be loop invariant). */ > step = force_gimple_operand (step, &stmts, true, NULL_TREE); > if (stmts) > gsi_insert_seq_on_edge_immediate (pe, stmts); > > if (POINTER_TYPE_P (TREE_TYPE (base))) > stmt = gimple_build_assign (va, POINTER_PLUS_EXPR, vb, step); > else if (use_minus_p) > stmt = gimple_build_assign (va, MINUS_EXPR, vb, step); > else > stmt = gimple_build_assign (va, incr_op, vb, step); > ... > > Since I have no idea to make stmts flips between PLUS_EXPR and MINUS_EXPR.
No, I meant: - Rename the "code" argument to "incr_op". - Remove "tree_code incr_op = code;". - Replace both instances of: incr_op = MINUS_EXPR; with: incr_op = (incr_op == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); The point is that the current code (rightly) assumes that incr_op always starts out as PLUS_EXPR, i.e. that STEP starts out applying positively. Making STEP apply in the opposite direction is then as simple as changing incr_op to MINUS_EXPR. But the new interface allows STEP to start out applying positively or negatively, and so this code needs to cope with both cases. Thanks, Richard