This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Serious performance regression -- some tree optimizer questions
Zdenek Dvorak wrote:
> *************** add_to_evolution_1 (unsigned loop_nb,
> *** 704,709 ****
> --- 716,722 ----
> var = loop_nb;
> left = chrec_before;
> right = build_int_cst (type, 0);
> + chrec_before = NULL;
I would prefer
chrec_before = chrec_not_analyzed_yet;
but this is not very important.
> }
> else
> {
> *************** add_to_evolution_1 (unsigned loop_nb,
> *** 712,733 ****
> right = CHREC_RIGHT (chrec_before);
> }
>
> ! return build_polynomial_chrec
> ! (var, left, chrec_fold_plus (type, right, to_add));
> }
> else
> /* Search the evolution in LOOP_NB. */
> return build_polynomial_chrec
> (CHREC_VARIABLE (chrec_before),
> ! add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before), to_add),
> CHREC_RIGHT (chrec_before));
>
> default:
> /* These nodes do not depend on a loop. */
> if (chrec_before == chrec_dont_know)
> return chrec_dont_know;
> ! return build_polynomial_chrec (loop_nb, chrec_before, to_add);
> }
> }
>
> /* Add TO_ADD to the evolution part of CHREC_BEFORE in the dimension
> --- 725,762 ----
> right = CHREC_RIGHT (chrec_before);
> }
>
> ! chrec = build_polynomial_chrec (var, left,
> ! chrec_fold_plus (type,
> ! right, to_add));
> }
> else
> /* Search the evolution in LOOP_NB. */
> return build_polynomial_chrec
> (CHREC_VARIABLE (chrec_before),
> ! add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before), to_add,
> ! cannot_overflow),
> CHREC_RIGHT (chrec_before));
>
> default:
> /* These nodes do not depend on a loop. */
> if (chrec_before == chrec_dont_know)
> return chrec_dont_know;
> ! chrec = build_polynomial_chrec (loop_nb, chrec_before, to_add);
> ! chrec_before = NULL;
same here,
> ! break;
> }
> +
> + if (!cannot_overflow)
> + return chrec;
> +
> + /* If we know that the current operation cannot overflow, and that the chrec
> + either could not overflow in other operations, or there were no other
> + operations before, we know that the chrec cannot overflow now. */
> + if (!chrec_before
and here "if (chrec_before == chrec_not_analyzed_yet "
> + || CHREC_NO_OVERFLOW (chrec_before))
> + CHREC_NO_OVERFLOW (chrec) = true;
> +
> + return chrec;
> }
>
The changes to instantiate_parameters_1 are independent of the others,
and I think that these could be separately committed to mainline as
they are trivial compile time improvements.
> *************** instantiate_parameters_1 (struct loop *l
> *** 1955,1982 ****
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
> allow_superloop_chrecs);
> ! return build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
>
> case PLUS_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! return chrec_fold_plus (TREE_TYPE (chrec), op0, op1);
>
> case MINUS_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! return chrec_fold_minus (TREE_TYPE (chrec), op0, op1);
>
> case MULT_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! return chrec_fold_multiply (TREE_TYPE (chrec), op0, op1);
>
> case NOP_EXPR:
> case CONVERT_EXPR:
> --- 1992,2031 ----
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
> allow_superloop_chrecs);
> ! if (CHREC_LEFT (chrec) != op0
> ! || CHREC_RIGHT (chrec) != op1)
> ! chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
> ! return chrec;
>
> case PLUS_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! if (TREE_OPERAND (chrec, 0) != op0
> ! || TREE_OPERAND (chrec, 1) != op1)
> ! chrec = chrec_fold_plus (TREE_TYPE (chrec), op0, op1);
> ! return chrec;
>
> case MINUS_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! if (TREE_OPERAND (chrec, 0) != op0
> ! || TREE_OPERAND (chrec, 1) != op1)
> ! chrec = chrec_fold_minus (TREE_TYPE (chrec), op0, op1);
> ! return chrec;
>
> case MULT_EXPR:
> op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
> allow_superloop_chrecs);
> op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
> allow_superloop_chrecs);
> ! if (TREE_OPERAND (chrec, 0) != op0
> ! || TREE_OPERAND (chrec, 1) != op1)
> ! chrec = chrec_fold_multiply (TREE_TYPE (chrec), op0, op1);
> ! return chrec;
>
> case NOP_EXPR:
> case CONVERT_EXPR:
> *************** instantiate_parameters_1 (struct loop *l
> *** 1986,1991 ****
> --- 2035,2043 ----
> if (op0 == chrec_dont_know)
> return chrec_dont_know;
>
> + if (op0 == TREE_OPERAND (chrec, 0))
> + return chrec;
> +
> return chrec_convert (TREE_TYPE (chrec), op0);
>
> case SCEV_NOT_KNOWN:
> *************** instantiate_parameters_1 (struct loop *l
> *** 2011,2016 ****
> --- 2063,2074 ----
> || op1 == chrec_dont_know
> || op2 == chrec_dont_know)
> return chrec_dont_know;
> +
> + if (op0 == TREE_OPERAND (chrec, 0)
> + && op1 == TREE_OPERAND (chrec, 1)
> + && op2 == TREE_OPERAND (chrec, 2))
> + return chrec;
> +
> return fold (build (TREE_CODE (chrec),
> TREE_TYPE (chrec), op0, op1, op2));
>
> *************** instantiate_parameters_1 (struct loop *l
> *** 2022,2027 ****
> --- 2080,2089 ----
> if (op0 == chrec_dont_know
> || op1 == chrec_dont_know)
> return chrec_dont_know;
> +
> + if (op0 == TREE_OPERAND (chrec, 0)
> + && op1 == TREE_OPERAND (chrec, 1))
> + return chrec;
> return fold (build (TREE_CODE (chrec), TREE_TYPE (chrec), op0, op1));
>
> case 1:
> *************** instantiate_parameters_1 (struct loop *l
> *** 2029,2034 ****
> --- 2091,2098 ----
> allow_superloop_chrecs);
> if (op0 == chrec_dont_know)
> return chrec_dont_know;
> + if (op0 == TREE_OPERAND (chrec, 0))
> + return chrec;
> return fold (build1 (TREE_CODE (chrec), TREE_TYPE (chrec), op0));
>
> case 0:
Thanks,
Sebastian