Add relational support to range-op.

This patch integrates relations with range-op functionality so that any
known relations can be used to help reduce or resolve ranges.
Initially handle  EQ_EXPR, NE_EXPR, LE_EXPR, LT_EXPR, GT_EXPR and GE_EXPR.

	* range-op.cc (range_operator::wi_fold): Apply relation effect.
	(range_operator::fold_range): Adjust and apply relation effect.
	(*::fold_range): Add relation parameters.
	(*::op1_range): Ditto.
	(*::op2_range): Ditto.
	(range_operator::lhs_op1_relation): New.
	(range_operator::lhs_op2_relation): New.
	(range_operator::op1_op2_relation): New.
	(range_operator::op1_op2_relation_effect): New.
	(relop_early_resolve): New.
	(operator_equal::op1_op2_relation): New.
	(operator_equal::fold_range): Call relop_early_resolve.
	(operator_not_equal::op1_op2_relation): New.
	(operator_not_equal::fold_range): Call relop_early_resolve.
	(operator_lt::op1_op2_relation): New.
	(operator_lt::fold_range): Call relop_early_resolve.
	(operator_le::op1_op2_relation): New.
	(operator_le::fold_range): Call relop_early_resolve.
	(operator_gt::op1_op2_relation): New.
	(operator_gt::fold_range): Call relop_early_resolve.
	(operator_ge::op1_op2_relation): New.
	(operator_ge::fold_range): Call relop_early_resolve.
	* range-op.h (class range_operator): Adjust parameters and methods.
This commit is contained in:
Andrew MacLeod 2021-06-17 11:49:21 -04:00
parent 3aaa69e5f3
commit 80dd13f5c3
2 changed files with 469 additions and 139 deletions

File diff suppressed because it is too large Load Diff

View File

@ -52,7 +52,8 @@ public:
// Perform an operation between 2 ranges and return it.
virtual bool fold_range (irange &r, tree type,
const irange &lh,
const irange &rh) const;
const irange &rh,
relation_kind rel = VREL_NONE) const;
// Return the range for op[12] in the general case. LHS is the range for
// the LHS of the expression, OP[12]is the range for the other
@ -67,11 +68,23 @@ public:
// is re-formed as R = [LHS] - OP2.
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2) const;
const irange &op2,
relation_kind rel = VREL_NONE) const;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1) const;
const irange &op1,
relation_kind rel = VREL_NONE) const;
// The following routines are used to represent relations between the
// various operations. If the caller knows where the symbolics are,
// it can query for relationships between them given known ranges.
virtual enum tree_code lhs_op1_relation (const irange &lhs,
const irange &op1,
const irange &op2) const;
virtual enum tree_code lhs_op2_relation (const irange &lhs,
const irange &op1,
const irange &op2) const;
virtual enum tree_code op1_op2_relation (const irange &lhs) const;
protected:
// Perform an integral operation between 2 sub-ranges and return it.
virtual void wi_fold (irange &r, tree type,
@ -79,6 +92,11 @@ protected:
const wide_int &lh_ub,
const wide_int &rh_lb,
const wide_int &rh_ub) const;
// Side effect of relation for generic fold_range clients.
virtual bool op1_op2_relation_effect (irange &lhs_range, tree type,
const irange &op1_range,
const irange &op2_range,
relation_kind rel) const;
};
extern range_operator *range_op_handler (enum tree_code code, tree type);