From 6a11476684547180634a11896c3b91a9970ea133 Mon Sep 17 00:00:00 2001 From: Jan Sjodin Date: Wed, 7 Jan 2009 15:53:03 +0000 Subject: re PR middle-end/38492 ([graphite] segfaulting code when compiled with -fgraphite -fgraphite-identity) 2009-01-07 Jan Sjodin PR tree-optimization/38492 PR tree-optimization/38498 * tree-check.c (operator_is_linear, scev_is_linear_expression): New. * tree-chrec.h (scev_is_linear_expression): Declared. * graphite.c (graphite_cannot_represent_loop_niter): New. (scopdet_basic_block_info): Call graphite_cannot_represent_loop_niter. (graphite_loop_normal_form): Use gcc_assert. (scan_tree_for_params): Use CASE_CONVERT. (phi_node_is_iv, bb_contains_non_iv_scalar_phi_nodes): New. (build_scop_conditions_1): Call bb_contains_non_iv_scalar_phi_nodes. Use gcc_assert. Discard scops that contain unhandled cases. (build_scop_conditions): Return a boolean status for unhandled cases. (strip_mine_profitable_p): Print the loop number, not its depth. (is_interchange_valid): Pass the depth of the loop nest, don't recompute it wrongly. (graphite_trans_bb_block): Same. (graphite_trans_bb_block): Print tentative of loop blocking. (graphite_trans_scop_block): Do not print that the loop has been blocked. (graphite_transform_loops): Do not handle scops that contain condition scalar phi nodes. * testsuite/gcc.dg/graphite/pr38500.c: Fixed warning as committed in trunk. * testsuite/gcc.dg/graphite/block-0.c: Update test. * testsuite/gcc.dg/graphite/block-1.c: Same. * testsuite/gcc.dg/graphite/block-2.c: Remove xfail and test for blocking. * testsuite/gcc.dg/graphite/block-4.c: Remove test for strip mine. * testsuite/gcc.dg/graphite/block-3.c: New. * testsuite/gcc.dg/graphite/pr38498.c: New. From-SVN: r143159 --- gcc/tree-chrec.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'gcc/tree-chrec.c') diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 26ae9b4..7a065b6 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -1430,3 +1430,64 @@ for_each_scev_op (tree *scev, bool (*cbck) (tree *, void *), void *data) } } +/* Returns true when the operation can be part of a linear + expression. */ + +static inline bool +operator_is_linear (tree scev) +{ + switch (TREE_CODE (scev)) + { + case INTEGER_CST: + case POLYNOMIAL_CHREC: + case PLUS_EXPR: + case POINTER_PLUS_EXPR: + case MULT_EXPR: + case MINUS_EXPR: + case NEGATE_EXPR: + case SSA_NAME: + case NON_LVALUE_EXPR: + CASE_CONVERT: + return true; + + default: + return false; + } +} + +/* Return true when SCEV is a linear expression. Linear expressions + can contain additions, substractions and multiplications. + Multiplications are restricted to constant scaling: "cst * x". */ + +bool +scev_is_linear_expression (tree scev) +{ + if (scev == NULL + || !operator_is_linear (scev)) + return false; + + if (TREE_CODE (scev) == MULT_EXPR) + return !(tree_contains_chrecs (TREE_OPERAND (scev, 0), NULL) + && tree_contains_chrecs (TREE_OPERAND (scev, 1), NULL)); + + switch (TREE_CODE_LENGTH (TREE_CODE (scev))) + { + case 3: + return scev_is_linear_expression (TREE_OPERAND (scev, 0)) + && scev_is_linear_expression (TREE_OPERAND (scev, 1)) + && scev_is_linear_expression (TREE_OPERAND (scev, 2)); + + case 2: + return scev_is_linear_expression (TREE_OPERAND (scev, 0)) + && scev_is_linear_expression (TREE_OPERAND (scev, 1)); + + case 1: + return scev_is_linear_expression (TREE_OPERAND (scev, 0)); + + case 0: + return true; + + default: + return false; + } +} -- cgit v1.1