static bool stmt_has_simple_data_refs_p (loop_p outermost_loop ATTRIBUTE_UNUSED, gimple stmt) { data_reference_p dr; unsigned i; int j; bool res = true; vec<data_reference_p> drs = vNULL; loop_p outer; for (outer = loop_containing_stmt (stmt); outer; outer = loop_outer (outer)) { graphite_find_data_references_in_stmt (outer, loop_containing_stmt (stmt), stmt, &drs); FOR_EACH_VEC_ELT (drs, j, dr) for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++) if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i))) { res = false; goto done; } free_data_refs (drs); drs.create (0); } done: free_data_refs (drs); return res; }
static bool graphite_can_represent_expr (basic_block scop_entry, loop_p loop, tree expr) { tree scev = analyze_scalar_evolution (loop, expr); scev = instantiate_scev (scop_entry, loop, scev); return graphite_can_represent_scev (scev); }
static bool graphite_can_represent_scev (tree scev) { if (chrec_contains_undetermined (scev)) return false; switch (TREE_CODE (scev)) { case PLUS_EXPR: case MINUS_EXPR: return graphite_can_represent_scev (TREE_OPERAND (scev, 0)) && graphite_can_represent_scev (TREE_OPERAND (scev, 1)); case MULT_EXPR: return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0))) && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1))) && !(chrec_contains_symbols (TREE_OPERAND (scev, 0)) && chrec_contains_symbols (TREE_OPERAND (scev, 1))) && graphite_can_represent_init (scev) && graphite_can_represent_scev (TREE_OPERAND (scev, 0)) && graphite_can_represent_scev (TREE_OPERAND (scev, 1)); case POLYNOMIAL_CHREC: /* Check for constant strides. With a non constant stride of 'n' we would have a value of 'iv * n'. Also check that the initial value can represented: for example 'n * m' cannot be represented. */ if (!evolution_function_right_is_integer_cst (scev) || !graphite_can_represent_init (scev)) return false; default: break; } /* Only affine functions can be represented. */ if (!scev_is_linear_expression (scev)) return false; return true; }
static bool graphite_can_represent_scev (tree scev) { if (chrec_contains_undetermined (scev)) return false; /* We disable the handling of pointer types, because it’s currently not supported by Graphite with the ISL AST generator. SSA_NAME nodes are the only nodes, which are disabled in case they are pointers to object types, but this can be changed. */ if (POINTER_TYPE_P (TREE_TYPE (scev)) && TREE_CODE (scev) == SSA_NAME) return false; switch (TREE_CODE (scev)) { case NEGATE_EXPR: case BIT_NOT_EXPR: CASE_CONVERT: case NON_LVALUE_EXPR: return graphite_can_represent_scev (TREE_OPERAND (scev, 0)); case PLUS_EXPR: case POINTER_PLUS_EXPR: case MINUS_EXPR: return graphite_can_represent_scev (TREE_OPERAND (scev, 0)) && graphite_can_represent_scev (TREE_OPERAND (scev, 1)); case MULT_EXPR: return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0))) && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1))) && !(chrec_contains_symbols (TREE_OPERAND (scev, 0)) && chrec_contains_symbols (TREE_OPERAND (scev, 1))) && graphite_can_represent_init (scev) && graphite_can_represent_scev (TREE_OPERAND (scev, 0)) && graphite_can_represent_scev (TREE_OPERAND (scev, 1)); case POLYNOMIAL_CHREC: /* Check for constant strides. With a non constant stride of 'n' we would have a value of 'iv * n'. Also check that the initial value can represented: for example 'n * m' cannot be represented. */ if (!evolution_function_right_is_integer_cst (scev) || !graphite_can_represent_init (scev)) return false; return graphite_can_represent_scev (CHREC_LEFT (scev)); default: break; } /* Only affine functions can be represented. */ if (tree_contains_chrecs (scev, NULL) || !scev_is_linear_expression (scev)) return false; return true; }
static bool stmt_has_simple_data_refs_p (loop_p outermost_loop ATTRIBUTE_UNUSED, gimple *stmt) { data_reference_p dr; int j; bool res = true; vec<data_reference_p> drs = vNULL; loop_p outer; for (outer = loop_containing_stmt (stmt); outer; outer = loop_outer (outer)) { graphite_find_data_references_in_stmt (outer, loop_containing_stmt (stmt), stmt, &drs); FOR_EACH_VEC_ELT (drs, j, dr) { int nb_subscripts = DR_NUM_DIMENSIONS (dr); tree ref = DR_REF (dr); for (int i = nb_subscripts - 1; i >= 0; i--) { if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i)) || (TREE_CODE (ref) != ARRAY_REF && TREE_CODE (ref) != MEM_REF && TREE_CODE (ref) != COMPONENT_REF)) { free_data_refs (drs); return false; } ref = TREE_OPERAND (ref, 0); } } free_data_refs (drs); drs.create (0); }