static bool idx_analyze_ref (tree base, tree *index, void *data) { struct ar_data *ar_data = data; tree ibase, step, stepsize; HOST_WIDE_INT istep, idelta = 0, imult = 1; affine_iv iv; if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF || TREE_CODE (base) == ALIGN_INDIRECT_REF) return false; if (!simple_iv (ar_data->loop, ar_data->stmt, *index, &iv, false)) return false; ibase = iv.base; step = iv.step; if (zero_p (step)) istep = 0; else { if (!cst_and_fits_in_hwi (step)) return false; istep = int_cst_value (step); } if (TREE_CODE (ibase) == PLUS_EXPR && cst_and_fits_in_hwi (TREE_OPERAND (ibase, 1))) { idelta = int_cst_value (TREE_OPERAND (ibase, 1)); ibase = TREE_OPERAND (ibase, 0); } if (cst_and_fits_in_hwi (ibase)) { idelta += int_cst_value (ibase); ibase = build_int_cst (TREE_TYPE (ibase), 0); } if (TREE_CODE (base) == ARRAY_REF) { stepsize = array_ref_element_size (base); if (!cst_and_fits_in_hwi (stepsize)) return false; imult = int_cst_value (stepsize); istep *= imult; idelta *= imult; } *ar_data->step += istep; *ar_data->delta += idelta; *index = ibase; return true; }
static bool constant_after_peeling (tree op, gimple *stmt, struct loop *loop) { affine_iv iv; if (is_gimple_min_invariant (op)) return true; /* We can still fold accesses to constant arrays when index is known. */ if (TREE_CODE (op) != SSA_NAME) { tree base = op; /* First make fast look if we see constant array inside. */ while (handled_component_p (base)) base = TREE_OPERAND (base, 0); if ((DECL_P (base) && ctor_for_folding (base) != error_mark_node) || CONSTANT_CLASS_P (base)) { /* If so, see if we understand all the indices. */ base = op; while (handled_component_p (base)) { if (TREE_CODE (base) == ARRAY_REF && !constant_after_peeling (TREE_OPERAND (base, 1), stmt, loop)) return false; base = TREE_OPERAND (base, 0); } return true; } return false; } /* Induction variables are constants. */ if (!simple_iv (loop, loop_containing_stmt (stmt), op, &iv, false)) return false; if (!is_gimple_min_invariant (iv.base)) return false; if (!is_gimple_min_invariant (iv.step)) return false; return true; }