summaryrefslogtreecommitdiff
path: root/gcc/tree-data-ref.c
diff options
context:
space:
mode:
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-11 11:13:34 +0000
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-11 11:13:34 +0000
commit7244316934ac6732ba27a33a8d9bc419523936fe (patch)
treea0d2e2a93834af978e8625b3a711d9c1a40ab9d8 /gcc/tree-data-ref.c
parentbe89a07ee09a22a68979ffbdc840dc6b467545b0 (diff)
downloadgcc-7244316934ac6732ba27a33a8d9bc419523936fe.tar.gz
* tree-data-ref.c (analyze_offset): Add a return value (bool) to
indicate success/failure of the analysis. Add negation to subtrahend in case of subtraction. Fail if both operands contain constants. (create_data_ref): Fail if analyze_offset fails. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122817 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-data-ref.c')
-rw-r--r--gcc/tree-data-ref.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 7eadde75bd5..d59278c89f5 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1835,7 +1835,7 @@ object_analysis (tree memref, tree stmt, bool is_read,
Extract INVARIANT and CONSTANT parts from OFFSET.
*/
-static void
+static bool
analyze_offset (tree offset, tree *invariant, tree *constant)
{
tree op0, op1, constant_0, constant_1, invariant_0, invariant_1;
@@ -1851,23 +1851,36 @@ analyze_offset (tree offset, tree *invariant, tree *constant)
*constant = offset;
else
*invariant = offset;
- return;
+ return true;
}
op0 = TREE_OPERAND (offset, 0);
op1 = TREE_OPERAND (offset, 1);
/* Recursive call with the operands. */
- analyze_offset (op0, &invariant_0, &constant_0);
- analyze_offset (op1, &invariant_1, &constant_1);
+ if (!analyze_offset (op0, &invariant_0, &constant_0)
+ || !analyze_offset (op1, &invariant_1, &constant_1))
+ return false;
- /* Combine the results. */
+ /* Combine the results. Add negation to the subtrahend in case of
+ subtraction. */
+ if (constant_0 && constant_1)
+ return false;
*constant = constant_0 ? constant_0 : constant_1;
+ if (code == MINUS_EXPR && constant_1)
+ *constant = fold_build1 (NEGATE_EXPR, TREE_TYPE (*constant), *constant);
+
if (invariant_0 && invariant_1)
*invariant =
fold_build2 (code, TREE_TYPE (invariant_0), invariant_0, invariant_1);
else
- *invariant = invariant_0 ? invariant_0 : invariant_1;
+ {
+ *invariant = invariant_0 ? invariant_0 : invariant_1;
+ if (code == MINUS_EXPR && invariant_1)
+ *invariant =
+ fold_build1 (NEGATE_EXPR, TREE_TYPE (*invariant), *invariant);
+ }
+ return true;
}
/* Free the memory used by the data reference DR. */
@@ -1941,7 +1954,17 @@ create_data_ref (tree memref, tree stmt, bool is_read)
STRIP_NOPS (offset);
if (offset != orig_offset)
type = TREE_TYPE (orig_offset);
- analyze_offset (offset, &invariant, &constant);
+ if (!analyze_offset (offset, &invariant, &constant))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\ncreate_data_ref: failed to analyze dr's");
+ fprintf (dump_file, " offset for ");
+ print_generic_expr (dump_file, memref, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ return NULL;
+ }
if (type && invariant)
invariant = fold_convert (type, invariant);