diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2017-02-24 10:00:04 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2017-02-24 10:00:04 +0000 |
commit | bf6b72928e7a8d1734e14ef075dc9c985a4902fe (patch) | |
tree | e5293e4d0a31ed5753df85e0cae454a18c38ed30 /gcc/ada/gcc-interface/utils.c | |
parent | 4af362a9571170538b66411d9cf7b6dc87745854 (diff) | |
download | gcc-bf6b72928e7a8d1734e14ef075dc9c985a4902fe.zip gcc-bf6b72928e7a8d1734e14ef075dc9c985a4902fe.tar.gz gcc-bf6b72928e7a8d1734e14ef075dc9c985a4902fe.tar.bz2 |
misc.c (gnat_type_max_size): Try to return a meaningful value for array types with TYPE_INDEX_TYPE set on...
* gcc-interface/misc.c (gnat_type_max_size): Try to return a meaningful
value for array types with TYPE_INDEX_TYPE set on their domain type.
* gcc-interface/utils.c (max_size): For operations and expressions, do
not build a new node if the operands have not changed or are missing.
From-SVN: r245698
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 33a37ce..0f4d8a4 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -3534,6 +3534,7 @@ max_size (tree exp, bool max_p) { enum tree_code code = TREE_CODE (exp); tree type = TREE_TYPE (exp); + tree op0, op1, op2; switch (TREE_CODE_CLASS (code)) { @@ -3575,15 +3576,19 @@ max_size (tree exp, bool max_p) return exp; case tcc_comparison: - return max_p ? size_one_node : size_zero_node; + return build_int_cst (type, max_p ? 1 : 0); case tcc_unary: if (code == NON_LVALUE_EXPR) return max_size (TREE_OPERAND (exp, 0), max_p); - return fold_build1 (code, type, - max_size (TREE_OPERAND (exp, 0), - code == NEGATE_EXPR ? !max_p : max_p)); + op0 = max_size (TREE_OPERAND (exp, 0), + code == NEGATE_EXPR ? !max_p : max_p); + + if (op0 == TREE_OPERAND (exp, 0)) + return exp; + + return fold_build1 (code, type, op0); case tcc_binary: { @@ -3623,6 +3628,9 @@ max_size (tree exp, bool max_p) code = PLUS_EXPR; } + if (lhs == TREE_OPERAND (exp, 0) && rhs == TREE_OPERAND (exp, 1)) + return exp; + /* We need to detect overflows so we call size_binop here. */ return size_binop (code, lhs, rhs); } @@ -3634,23 +3642,40 @@ max_size (tree exp, bool max_p) if (code == SAVE_EXPR) return exp; - return fold_build1 (code, type, - max_size (TREE_OPERAND (exp, 0), - code == TRUTH_NOT_EXPR ? !max_p : max_p)); + op0 = max_size (TREE_OPERAND (exp, 0), + code == TRUTH_NOT_EXPR ? !max_p : max_p); + + if (op0 == TREE_OPERAND (exp, 0)) + return exp; + + return fold_build1 (code, type, op0); case 2: if (code == COMPOUND_EXPR) return max_size (TREE_OPERAND (exp, 1), max_p); - return fold_build2 (code, type, - max_size (TREE_OPERAND (exp, 0), max_p), - max_size (TREE_OPERAND (exp, 1), max_p)); + op0 = max_size (TREE_OPERAND (exp, 0), max_p); + op1 = max_size (TREE_OPERAND (exp, 1), max_p); + + if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)) + return exp; + + return fold_build2 (code, type, op0, op1); case 3: if (code == COND_EXPR) - return fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type, - max_size (TREE_OPERAND (exp, 1), max_p), - max_size (TREE_OPERAND (exp, 2), max_p)); + { + op1 = TREE_OPERAND (exp, 1); + op2 = TREE_OPERAND (exp, 2); + + if (!op1 || !op2) + return exp; + + return + fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type, + max_size (op1, max_p), max_size (op2, max_p)); + } + break; default: break; |