diff options
author | Andrew Macleod <amacleod@gcc.gnu.org> | 2018-04-10 22:55:44 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@gcc.gnu.org> | 2018-04-10 22:55:44 +0000 |
commit | 57e7640ca39e7a63b5bca0bb890f127f5e3c058d (patch) | |
tree | e8023b358b6f28a479dbae239c6f176e39ca9ecf | |
parent | d739eb8b490b481c9b75a12274f08afd695c8041 (diff) | |
download | gcc-57e7640ca39e7a63b5bca0bb890f127f5e3c058d.tar.gz |
Reduce range_stmt to a single gimple stmt for efficiency
From-SVN: r259304
-rw-r--r-- | gcc/ssa-range-bb.c | 221 | ||||
-rw-r--r-- | gcc/ssa-range-bb.h | 11 | ||||
-rw-r--r-- | gcc/ssa-range-stmt.c | 281 | ||||
-rw-r--r-- | gcc/ssa-range-stmt.h | 66 | ||||
-rw-r--r-- | gcc/ssa-range.c | 14 |
5 files changed, 280 insertions, 313 deletions
diff --git a/gcc/ssa-range-bb.c b/gcc/ssa-range-bb.c index a288037b170..bafee0f817b 100644 --- a/gcc/ssa-range-bb.c +++ b/gcc/ssa-range-bb.c @@ -208,13 +208,14 @@ void gori_map::process_stmt (gimple *stmt, bitmap result, basic_block bb) { range_stmt rn (stmt); - tree ssa1 = rn.ssa_operand1 (); - tree ssa2 = rn.ssa_operand2 (); bitmap b; if (!rn.valid ()) return; + tree ssa1 = rn.ssa_operand1 (); + tree ssa2 = rn.ssa_operand2 (); + if (ssa1) { b = calc_def_chain (ssa1, bb); @@ -348,125 +349,36 @@ block_ranger::~block_ranger () delete gori; } -/* Return TRUE if CODE with operands of type TYPE is a boolean - evaluation. These are important to identify as both sides of a logical - binary expression must be evaluated in order to calculate a range. */ +/* This routine will return what is globally known about the range for an + operand of any kind. */ bool -block_ranger::logical_expr_p (tree_code code, tree type) const +block_ranger::get_operand_range (irange& r, tree op) { + /* This check allows unary operations to be handled without having to + make an explicit check for the existence of a second operand. */ + if (!op) + return false; - /* Look for boolean and/or condition. */ - switch (code) - { - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - return true; - - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - if (types_compatible_p (type, boolean_type_node)) - return true; - break; - - default: - break; - } - return false; -} - -/* Evaluate a binary logical expression given true and false ranges for each - of the operands. Base the result on the value in the LHS. */ -bool -block_ranger::eval_logical (irange& r, range_stmt &stmt, const irange& lhs, - const irange& op1_true, const irange& op1_false, - const irange& op2_true, - const irange& op2_false) const -{ - gcc_checking_assert (logical_expr_p (stmt.get_code (), - TREE_TYPE (stmt.operand1 ()))); - - /* If the LHS can be TRUE OR FALSE, then both need to be evalauted and - combined, otherwise any range restrictions that have been determined - leading up to this point would be lost. */ - if (!wi::eq_p (lhs.lower_bound(), lhs.upper_bound())) - { - irange r1; - if (eval_logical (r1, stmt, bool_zero, op1_true, op1_false, op2_true, - op2_false) && - eval_logical (r, stmt, bool_one, op1_true, op1_false, op2_true, - op2_false)) - { - r.union_ (r1); - return true; - } - return false; - - } - - /* Now combine based on whether the result is TRUE or FALSE. */ - switch (stmt.get_code ()) - { - - /* A logical operation on two ranges is executed with operand ranges that - have been determined for both a TRUE and FALSE result.. - Assuming x_8 is an unsigned char: - b_1 = x_8 < 20 - b_2 = x_8 > 5 - if we are looking for the range of x_8, the operand ranges will be: - will be: - b_1 TRUE x_8 = [0, 19] - b_1 FALSE x_8 = [20, 255] - b_2 TRUE x_8 = [6, 255] - b_2 FALSE x_8 = [0,5]. */ - - /* c_2 = b_1 && b_2 - The result of an AND operation with a TRUE result is the intersection - of the 2 TRUE ranges, [0,19] intersect [6,255] -> [6, 19]. */ - case TRUTH_AND_EXPR: - case BIT_AND_EXPR: - if (!lhs.zero_p ()) - r = irange_intersect (op1_true, op2_true); - else - { - /* The FALSE side is the union of the other 3 cases. */ - irange ff = irange_intersect (op1_false, op2_false); - irange tf = irange_intersect (op1_true, op2_false); - irange ft = irange_intersect (op1_false, op2_true); - r = irange_union (ff, tf); - r.union_ (ft); - } - break; - - /* c_2 = b_1 || b_2 - An OR operation will only take the FALSE path if both operands are - false, so [20, 255] intersect [0, 5] is the union: [0,5][20,255]. */ - case TRUTH_OR_EXPR: - case BIT_IOR_EXPR: - if (lhs.zero_p ()) - r = irange_intersect (op1_false, op2_false); - else - { - /* The TRUE side of the OR operation will be the union of the other - three combinations. */ - irange tt = irange_intersect (op1_true, op2_true); - irange tf = irange_intersect (op1_true, op2_false); - irange ft = irange_intersect (op1_false, op2_true); - r = irange_union (tt, tf); - r.union_ (ft); - } - break; - - default: - gcc_unreachable (); - } + if (TREE_CODE (op) == INTEGER_CST) + r.set_range (TREE_TYPE (op), op, op); + else + if (TREE_CODE (op) == SSA_NAME) + r = op; + else + if (TYPE_P (op)) + r.set_range_for_type (op); + else + /* Default to range for the type of the expression. */ + r.set_range_for_type (TREE_TYPE (op)); return true; } + /* Given a logical STMT, calculate true and false for each potential path using NAME and resolve the outcome based on the logical operator. */ bool -block_ranger::process_logical (range_stmt& stmt, irange& r, tree name, +block_ranger::process_logical (range_stmt stmt, irange& r, tree name, const irange& lhs) { range_stmt op_stmt; @@ -521,8 +433,8 @@ block_ranger::process_logical (range_stmt& stmt, irange& r, tree name, } } - if (!ret || !eval_logical (r, stmt, lhs, op1_true, op1_false, op2_true, - op2_false)) + if (!ret || !stmt.fold_logical (r, lhs, op1_true, op1_false, op2_true, + op2_false)) r.set_range_for_type (TREE_TYPE (name)); return true; } @@ -531,14 +443,22 @@ block_ranger::process_logical (range_stmt& stmt, irange& r, tree name, /* Given the expression in STMT, return an evaluation in R for NAME. Returning false means the name being looked for was NOT resolvable. */ bool -block_ranger::get_range (range_stmt& stmt, irange& r, tree name, - const irange& lhs) +block_ranger::get_range_from_stmt (range_stmt stmt, irange& r, tree name, + const irange& lhs) { - range_stmt op_stmt; irange op1_range, op2_range; tree op1, op2; bool op1_in_chain, op2_in_chain; + if (!stmt.valid ()) + return false; + + if (lhs.empty_p ()) + { + r.clear (TREE_TYPE (name)); + return true; + } + op1 = stmt.operand1 (); op2 = stmt.operand2 (); @@ -561,7 +481,7 @@ block_ranger::get_range (range_stmt& stmt, irange& r, tree name, } /* Check for boolean cases which require developing ranges and combining. */ - if (logical_expr_p (stmt.get_code (), TREE_TYPE (op1))) + if (stmt.logical_expr_p ()) return process_logical (stmt, r, name, lhs); /* Reaching this point means NAME is not in this stmt, but one of the @@ -621,29 +541,6 @@ block_ranger::get_range (range_stmt& stmt, irange& r, tree name, return get_range_from_stmt (SSA_NAME_DEF_STMT (op2), r, name, op2_range); } -/* Given the expression in STMT, return an evaluation in R for NAME. */ -bool -block_ranger::get_range_from_stmt (gimple *stmt, irange& r, tree name, - const irange& lhs) -{ - range_stmt rn; - rn = stmt; - - /* If it isnt an expression that is understood, we know nothing. */ - if (!rn.valid()) - return false; - - /* If the lhs has no range, ie , it cannot be executed, then the query - has no range either. */ - if (lhs.empty_p ()) - { - r.clear (TREE_TYPE (name)); - return true; - } - - return get_range (rn, r, name, lhs); -} - void block_ranger::dump (FILE *f) { @@ -812,28 +709,45 @@ block_ranger::range_on_stmt (irange& r, tree name, gimple *g) if (rn.operand1 () != name && rn.operand2 () != name) return false; - /* So far only understand LHS if its an assignment. */ - if (gimple_code (g) != GIMPLE_ASSIGN) + /* Only works if there is a LHS. */ + if (!gimple_get_lhs (g)) return false; if (get_operand_range (lhs, gimple_get_lhs (g))) - return get_range (rn, r, name, lhs); + return get_range_from_stmt (rn, r, name, lhs); return false; } + +/* Attempt to evaluate the epression using whatever is globally known about + the operands. If it can be evaluated, TRUE is returned + and the range is returned in R. */ + bool block_ranger::range_of_def (irange& r, gimple *g) { range_stmt rn (g); + irange r1, r2; /* If we don't understand the stmt... */ if (!rn.valid()) return false; - return rn.fold (r); + tree op1 = rn.operand1 (); + tree op2 = rn.operand2 (); + + get_operand_range (r1, op1); + if (op2) + return rn.fold (r, r1); + + get_operand_range (r2, op2); + return rn.fold (r, r1, r2); } +/* This method will attempt to evaluate the expression by replacing any + occurrence of ssa_name NAME with the range NAME_RANGE. If it can be + evaluated, TRUE is returned and the resulting range returned in R. */ bool block_ranger::range_of_def (irange& r, gimple *g, tree name, const irange& range_of_name) @@ -844,6 +758,23 @@ block_ranger::range_of_def (irange& r, gimple *g, tree name, if (!rn.valid()) return false; - return rn.fold (r, name, range_of_name); + irange r1, r2; + tree op1 = rn.operand1 (); + tree op2 = rn.operand2 (); + + if (op1 == name) + r1 = range_of_name; + else + get_operand_range (r1, op1); + + if (!op2) + return rn.fold (r, r1); + + if (op2 == name) + r2 = range_of_name; + else + get_operand_range (r2, op2); + + return rn.fold (r, r1, r2); } diff --git a/gcc/ssa-range-bb.h b/gcc/ssa-range-bb.h index ce42d432bb2..e4895566f78 100644 --- a/gcc/ssa-range-bb.h +++ b/gcc/ssa-range-bb.h @@ -34,15 +34,12 @@ class block_ranger class gori_map *gori; /* Generates Outgoing Range Info. */ irange bool_zero; irange bool_one; - bool logical_expr_p (tree_code code, tree type) const; - bool eval_logical (irange& r, range_stmt &stmt, const irange& lhs, - const irange& op1_true, const irange& op1_false, - const irange& op2_true, const irange& op2_false) const; - bool process_logical (range_stmt& stmt, irange& r, tree name, + bool process_logical (range_stmt stmt, irange& r, tree name, const irange& lhs); - bool get_range (range_stmt& stmt, irange& r, tree name, const irange& lhs); - bool get_range_from_stmt (gimple *stmt, irange& r, tree name, + bool get_range_from_stmt (range_stmt stmt, irange& r, tree name, const irange& lhs); +protected: + bool get_operand_range (irange& r, tree op); public: block_ranger (); ~block_ranger (); diff --git a/gcc/ssa-range-stmt.c b/gcc/ssa-range-stmt.c index 4cf6e0fcf8f..3e6eccf2947 100644 --- a/gcc/ssa-range-stmt.c +++ b/gcc/ssa-range-stmt.c @@ -46,94 +46,156 @@ along with GCC; see the file COPYING3. If not see #include "ssa-range-stmt.h" -/* This routine will return what is globally known about the range for an - operand of any kind. */ -bool -get_operand_range (irange& r, tree op) +/* Validate that the statement and all operands of this expression are + operable on iranges. If it is valid, set the stmt pointer. */ +void +range_stmt::validate_stmt (gimple *s) { - /* This check allows unary operations to be handled without having to - make an explicit check for the existence of a second operand. */ - if (!op) - return false; + // Check for supported statements + switch (gimple_code (s)) + { + case GIMPLE_COND: + case GIMPLE_ASSIGN: + g = s; + break; - if (TREE_CODE (op) == INTEGER_CST) - r.set_range (TREE_TYPE (op), op, op); - else - if (TREE_CODE (op) == SSA_NAME) - r = op; - else - if (TYPE_P (op)) - r.set_range_for_type (op); - else - /* Default to range for the type of the expression. */ - r.set_range_for_type (TREE_TYPE (op)); + default: + g = NULL; + } - return true; + // Must have a ranger operation handler as well. + if (g && handler ()) + { + // Now verify all the operanmds are compatible + tree op1 = operand1 (); + tree op2 = operand2 (); + tree ssa1 = valid_irange_ssa (op1); + tree ssa2 = valid_irange_ssa (op2); + + if (ssa1 || (TREE_CODE (op1) == INTEGER_CST && !TREE_OVERFLOW (op1))) + { + if (!op2) + return; + if (ssa2 || (TREE_CODE (op2) == INTEGER_CST && !TREE_OVERFLOW (op2))) + return; + } + } + g = NULL; } -/* Initialize the SSA operands and validate that all operands of this - expression are operable on iranges. - Return ERROR_MARK if they are not, otherwise the current tree code. */ -tree_code -range_stmt::validate_operands () +/* Return TRUE if CODE with operands of type TYPE is a boolean + evaluation. These are important to identify as both sides of a logical + binary expression must be evaluated in order to calculate a range. */ +bool +range_stmt::logical_expr_p () const { - ssa1 = valid_irange_ssa (op1); - ssa2 = valid_irange_ssa (op2); - - if (ssa1 || (TREE_CODE (op1) == INTEGER_CST && !TREE_OVERFLOW (op1))) - { - if (!op2) - return code; - if (ssa2 || (TREE_CODE (op2) == INTEGER_CST && !TREE_OVERFLOW (op2))) - return code; - } - return ERROR_MARK; + /* Look for boolean and/or condition. */ + switch (get_code ()) + { + case TRUTH_AND_EXPR: + case TRUTH_OR_EXPR: + return true; + + case BIT_AND_EXPR: + case BIT_IOR_EXPR: + if (types_compatible_p (TREE_TYPE (operand1 ()), boolean_type_node)) + return true; + break; + + default: + break; + } + return false; } -/* Build a range node from a stmt, if it possible. */ -void -range_stmt::from_stmt (gimple *s) + +/* Evaluate a binary logical expression given true and false ranges for each + of the operands. Base the result on the value in the LHS. */ +bool +range_stmt::fold_logical (irange& r, const irange& lhs, const irange& op1_true, + const irange& op1_false, const irange& op2_true, + const irange& op2_false) const { - switch (gimple_code (s)) + gcc_checking_assert (logical_expr_p ()); + + /* If the LHS can be TRUE OR FALSE, then both need to be evaluated and + combined, otherwise any range restrictions that have been determined + leading up to this point would be lost. */ + if (!wi::eq_p (lhs.lower_bound(), lhs.upper_bound())) { - case GIMPLE_COND: - { - gcond *gc = as_a <gcond *> (s); - code = gimple_cond_code (gc); - if (irange_op_handler (code)) - { - lhs = gimple_get_lhs (s); - op1 = gimple_cond_lhs (gc); - op2 = gimple_cond_rhs (gc); - code = validate_operands (); - return; - } - break; - } - case GIMPLE_ASSIGN: + irange r1; + irange bool_zero (boolean_type_node, 0, 0); + irange bool_one (boolean_type_node, 1, 1); + if (fold_logical (r1, bool_zero, op1_true, op1_false, op2_true, + op2_false) && + fold_logical (r, bool_one, op1_true, op1_false, op2_true, op2_false)) { - gassign *ga = as_a <gassign *> (s); - code = gimple_assign_rhs_code (ga); - if (irange_op_handler (code)) - { - lhs = gimple_get_lhs (s); - op1 = gimple_assign_rhs1 (ga); - if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) - op2 = gimple_assign_rhs2 (ga); - else - op2 = NULL; - code = validate_operands (); - return; - } - break; + r.union_ (r1); + return true; } + return false; - default: + } + + /* Now combine based on whether the result is TRUE or FALSE. */ + switch (get_code ()) + { + + /* A logical operation on two ranges is executed with operand ranges that + have been determined for both a TRUE and FALSE result.. + Assuming x_8 is an unsigned char: + b_1 = x_8 < 20 + b_2 = x_8 > 5 + if we are looking for the range of x_8, the operand ranges will be: + will be: + b_1 TRUE x_8 = [0, 19] + b_1 FALSE x_8 = [20, 255] + b_2 TRUE x_8 = [6, 255] + b_2 FALSE x_8 = [0,5]. */ + + /* c_2 = b_1 && b_2 + The result of an AND operation with a TRUE result is the intersection + of the 2 TRUE ranges, [0,19] intersect [6,255] -> [6, 19]. */ + case TRUTH_AND_EXPR: + case BIT_AND_EXPR: + if (!lhs.zero_p ()) + r = irange_intersect (op1_true, op2_true); + else + { + /* The FALSE side is the union of the other 3 cases. */ + irange ff = irange_intersect (op1_false, op2_false); + irange tf = irange_intersect (op1_true, op2_false); + irange ft = irange_intersect (op1_false, op2_true); + r = irange_union (ff, tf); + r.union_ (ft); + } break; + + /* c_2 = b_1 || b_2 + An OR operation will only take the FALSE path if both operands are + false, so [20, 255] intersect [0, 5] is the union: [0,5][20,255]. */ + case TRUTH_OR_EXPR: + case BIT_IOR_EXPR: + if (lhs.zero_p ()) + r = irange_intersect (op1_false, op2_false); + else + { + /* The TRUE side of the OR operation will be the union of the other + three combinations. */ + irange tt = irange_intersect (op1_true, op2_true); + irange tf = irange_intersect (op1_true, op2_false); + irange ft = irange_intersect (op1_false, op2_true); + r = irange_union (tt, tf); + r.union_ (ft); + } + break; + + default: + gcc_unreachable (); } - code = ERROR_MARK; - return; + + return true; } /* This method will attempt to resolve a unary expression with value R1 to @@ -144,16 +206,14 @@ bool range_stmt::fold (irange &res, const irange& r1) const { irange r2; - irange_operator *handler = irange_op_handler (code); - gcc_assert (handler != NULL); - + tree lhs = gimple_get_lhs (g); /* Single ssa operations require the LHS type as the second range. */ if (lhs) r2.set_range_for_type (TREE_TYPE (lhs)); else r2.clear (r1.get_type ()); - return handler->fold_range (res, r1, r2); + return handler()->fold_range (res, r1, r2); } /* This method will attempt to resolve a binary expression with operand @@ -163,62 +223,9 @@ range_stmt::fold (irange &res, const irange& r1) const bool range_stmt::fold (irange &res, const irange& r1, const irange& r2) const { - irange_operator *handler = irange_op_handler (code); - gcc_assert (handler != NULL); - // Make sure this isnt a unary operation being passed a second range. - gcc_assert (op2); - return handler->fold_range (res, r1, r2); -} - -/* This method will attempt to evaluate the epression using whatever is - globally known about the operands. If it can be evaluated, TRUE is returned - and the range is returned in RES. */ - -bool -range_stmt::fold (irange &res) const -{ - irange r1, r2; - - if (!op2) - { - get_operand_range (r1, op1); - return fold (res, r1); - } - - get_operand_range (r1, op1); - get_operand_range (r2, op2); - return fold (res, r1, r2); -} - -/* This method will attempt to evaluate the expression by replacing any - occurrence of ssa_name NAME with the range NAME_RANGE. If it can be - evaluated, TRUE is returned and the resulting range returned in RES. */ -bool -range_stmt::fold (irange& res, tree name, const irange& name_range) const -{ - irange r1, r2; - - if (!op2) - { - if (ssa1 == name) - r1 = name_range; - else - get_operand_range (r1, op1); - return fold (res, r1); - } - - if (ssa1 == name) - r1 = name_range; - else - get_operand_range (r1, op1); - - if (ssa2 == name) - r2 = name_range; - else - get_operand_range (r2, op2); - - return fold (res, r1, r2); + gcc_assert (operand2 ()); + return handler() ->fold_range (res, r1, r2); } /* This method will evaluate a range for the operand of a unary expression @@ -228,7 +235,7 @@ bool range_stmt::op1_irange (irange& r, const irange& lhs_range) const { irange type_range; - type_range.set_range_for_type (TREE_TYPE (op1)); + type_range.set_range_for_type (TREE_TYPE (operand1 ())); return handler ()->op1_irange (r, lhs_range, type_range); } @@ -240,7 +247,7 @@ bool range_stmt::op1_irange (irange& r, const irange& lhs_range, const irange& op2_range) const { - gcc_assert (op2 != NULL); + gcc_assert (operand2 () != NULL); return handler ()->op1_irange (r, lhs_range, op2_range); } @@ -259,6 +266,10 @@ range_stmt::op2_irange (irange& r, const irange& lhs_range, void range_stmt::dump (FILE *f) const { + tree lhs = gimple_get_lhs (g); + tree op1 = operand1 (); + tree op2 = operand2 (); + if (lhs) { print_generic_expr (f, lhs, TDF_SLIM); @@ -266,13 +277,13 @@ range_stmt::dump (FILE *f) const } if (!op2) - irange_op_handler (code)->dump (f); + handler ()->dump (f); print_generic_expr (f, op1, TDF_SLIM); if (op2) { - irange_op_handler (code)->dump (f); + handler ()->dump (f); print_generic_expr (f, op2, TDF_SLIM); } diff --git a/gcc/ssa-range-stmt.h b/gcc/ssa-range-stmt.h index fe685b010f5..e0d9bf78906 100644 --- a/gcc/ssa-range-stmt.h +++ b/gcc/ssa-range-stmt.h @@ -24,9 +24,6 @@ along with GCC; see the file COPYING3. If not see #include "range.h" #include "range-op.h" -/* Return a the range for a single tree object. */ -bool get_operand_range (irange& r, tree op); - /* This class is used summarize expressions that are supported by the irange_operator class, and provide an interface to the operators on the expression. @@ -43,12 +40,8 @@ bool get_operand_range (irange& r, tree op); class range_stmt { private: - tree_code code; - tree lhs; - tree op1, op2; - tree ssa1, ssa2; - tree_code validate_operands (); - void from_stmt (gimple *s); + gimple *g; + void validate_stmt (gimple *s); class irange_operator *handler() const; public: range_stmt (); @@ -64,8 +57,8 @@ public: tree ssa_operand1 () const; tree ssa_operand2 () const; - bool fold (irange& res) const; - bool fold (irange& res, tree name, const irange& name_range) const; + bool logical_expr_p () const; + bool fold (irange& res, const irange& r1) const; bool fold (irange& res, const irange& r1, const irange& r2) const; bool op1_irange (irange& r, const irange& lhs_range) const; @@ -74,6 +67,10 @@ public: bool op2_irange (irange& r, const irange& lhs_range, const irange& op1_range) const; + bool fold_logical (irange& r, const irange& lhs, const irange& op1_true, + const irange& op1_false, const irange& op2_true, + const irange& op2_false) const; + void dump (FILE *f) const; }; @@ -82,21 +79,21 @@ public: inline range_stmt::range_stmt () { - code = ERROR_MARK; + g = NULL; } /* Initialize a range statement from gimple statement S. */ inline range_stmt::range_stmt (gimple *s) { - from_stmt (s); + validate_stmt (s); } /* Initialize a range statement from gimple statement S. */ inline range_stmt& range_stmt::operator= (gimple *s) { - from_stmt (s); + validate_stmt (s); return *this; } @@ -104,43 +101,70 @@ range_stmt::operator= (gimple *s) inline bool range_stmt::valid () const { - return code != ERROR_MARK; + return g != NULL; } inline tree_code range_stmt::get_code () const { - return code; + return gimple_expr_code (g); } inline tree range_stmt::operand1 () const { - return op1; + switch (gimple_code (g)) + { + case GIMPLE_COND: + return gimple_cond_lhs (g); + case GIMPLE_ASSIGN: + return gimple_assign_rhs1 (g); + default: + break; + } + return NULL; } inline tree range_stmt::operand2 () const { - return op2; + switch (gimple_code (g)) + { + case GIMPLE_COND: + return gimple_cond_rhs (g); + case GIMPLE_ASSIGN: + if (gimple_num_ops (g) >= 3) + return gimple_assign_rhs2 (g); + else + return NULL; + default: + break; + } + return NULL; } inline tree range_stmt::ssa_operand1() const { - return ssa1; + tree op1 = operand1 (); + if (op1 && TREE_CODE (op1) == SSA_NAME) + return op1; + return NULL_TREE; } inline tree range_stmt::ssa_operand2 () const { - return ssa2; + tree op2 = operand2 (); + if (op2 && TREE_CODE (op2) == SSA_NAME) + return op2; + return NULL_TREE; } inline irange_operator * range_stmt::handler () const { - return irange_op_handler (code); + return irange_op_handler (get_code ()); } #endif /* GCC_SSA_RANGE_STMT_H */ diff --git a/gcc/ssa-range.c b/gcc/ssa-range.c index 58595e419bb..7a63089d0d3 100644 --- a/gcc/ssa-range.c +++ b/gcc/ssa-range.c @@ -430,6 +430,7 @@ path_ranger::path_range_stmt (irange& r, gimple *g) irange range_op1, range_op2; range_stmt rn; basic_block bb = gimple_bb (g); + bool res; if (is_a <gphi *> (g)) { @@ -458,13 +459,16 @@ path_ranger::path_range_stmt (irange& r, gimple *g) // If this is a unary operation, call fold now. if (!rn.operand2 ()) - return rn.fold (r, range_op1); + res = rn.fold (r, range_op1); + else + { - if (!path_get_operand (range_op2, rn.operand2 (), bb)) - return false; + if (!path_get_operand (range_op2, rn.operand2 (), bb)) + return false; - normalize_bool_type (range_op1, range_op2); - bool res = rn.fold (r, range_op1, range_op2); + normalize_bool_type (range_op1, range_op2); + res = rn.fold (r, range_op1, range_op2); + } if (name) { |