/* Floating point range operators. Copyright (C) 2022 Free Software Foundation, Inc. Contributed by Aldy Hernandez . This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "backend.h" #include "insn-codes.h" #include "rtl.h" #include "tree.h" #include "gimple.h" #include "cfghooks.h" #include "tree-pass.h" #include "ssa.h" #include "optabs-tree.h" #include "gimple-pretty-print.h" #include "diagnostic-core.h" #include "flags.h" #include "fold-const.h" #include "stor-layout.h" #include "calls.h" #include "cfganal.h" #include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-walk.h" #include "tree-cfg.h" #include "wide-int.h" #include "value-relation.h" #include "range-op.h" // Default definitions for floating point operators. bool range_operator_float::fold_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lh ATTRIBUTE_UNUSED, const frange &rh ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } bool range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lh ATTRIBUTE_UNUSED, const frange &rh ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } bool range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lhs ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } bool range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const irange &lhs ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } bool range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } bool range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { return false; } relation_kind range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const { return VREL_VARYING; } relation_kind range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const { return VREL_VARYING; } relation_kind range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const { return VREL_VARYING; } relation_kind range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const { return VREL_VARYING; } relation_kind range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const { return VREL_VARYING; } class foperator_identity : public range_operator_float { using range_operator_float::fold_range; using range_operator_float::op1_range; bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED, const frange &op1, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const final override { r = op1; return true; } bool op1_range (frange &r, tree type ATTRIBUTE_UNUSED, const frange &lhs, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const final override { r = lhs; return true; } public: } fop_identity; // Instantiate a range_op_table for floating point operations. static floating_op_table global_floating_table; // Pointer to the float table so the dispatch code can access it. floating_op_table *floating_tree_table = &global_floating_table; floating_op_table::floating_op_table () { set (SSA_NAME, fop_identity); set (PAREN_EXPR, fop_identity); set (OBJ_TYPE_REF, fop_identity); set (REAL_CST, fop_identity); } // Return a pointer to the range_operator_float instance, if there is // one associated with tree_code CODE. range_operator_float * floating_op_table::operator[] (enum tree_code code) { return m_range_tree[code]; } // Add OP to the handler table for CODE. void floating_op_table::set (enum tree_code code, range_operator_float &op) { gcc_checking_assert (m_range_tree[code] == NULL); m_range_tree[code] = &op; }