Remove value_range_equiv.

With legacy VRP gone, value_range_equiv serves no purpose and any uses
of it can just be replaced with value_range.

gcc/ChangeLog:

	* Makefile.in: Remove value-range-equiv.o
	* gimple-array-bounds.cc
	(array_bounds_checker::array_bounds_checker): Remove comment.
	* tree-vrp.cc (supported_types_p): Remove use of value_range_equiv.
	* value-query.cc (class equiv_allocator): Same.
	(range_query::allocate_value_range_equiv): Remove.
	(range_query::free_value_range_equiv): Remove.
	(range_query::get_value_range): Remove.
	* value-query.h (class range_query): Remove get_value_range.
	Remove allocate_value_range_equiv.
	Remove free_value_range_equiv.
	* vr-values.cc (compare_ranges): Replace value_range_equiv with
	value_range.
	(simplify_using_ranges::get_vr_for_comparison): Same.
	(simplify_using_ranges::compare_names): Same.
	* vr-values.h: Remove value_range_equiv references.
	* value-range-equiv.cc: Removed.
	* value-range-equiv.h: Removed.
This commit is contained in:
Aldy Hernandez 2022-11-19 17:44:02 +01:00
parent ca0be1bbed
commit a3f7deefd4
9 changed files with 34 additions and 530 deletions

View File

@ -1717,7 +1717,6 @@ OBJS = \
value-pointer-equiv.o \
value-query.o \
value-range.o \
value-range-equiv.o \
value-range-pretty-print.o \
value-range-storage.o \
value-relation.o \

View File

@ -46,9 +46,6 @@ array_bounds_checker::array_bounds_checker (struct function *func,
/* No-op. */
}
// This purposely returns a value_range, not a value_range_equiv, to
// break the dependency on equivalences for this pass.
const value_range *
array_bounds_checker::get_value_range (const_tree op, gimple *stmt)
{

View File

@ -582,10 +582,9 @@ compare_values (tree val1, tree val2)
static bool
supported_types_p (value_range *vr,
tree type0,
tree type1 = NULL)
tree = NULL)
{
if (!value_range_equiv::supports_p (type0)
|| (type1 && !value_range_equiv::supports_p (type1)))
if (!value_range::supports_p (type0))
{
vr->set_varying (type0);
return false;

View File

@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see
#include "ssa.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
#include "value-range-equiv.h"
#include "value-query.h"
#include "alloc-pool.h"
#include "gimple-range.h"
@ -143,34 +142,22 @@ range_query::dump (FILE *)
{
}
// valuation_query support routines for value_range_equiv's.
// valuation_query support routines for value_range's.
class equiv_allocator : public object_allocator<value_range_equiv>
class equiv_allocator : public object_allocator<value_range>
{
public:
equiv_allocator ()
: object_allocator<value_range_equiv> ("equiv_allocator pool") { }
: object_allocator<value_range> ("equiv_allocator pool") { }
};
value_range_equiv *
range_query::allocate_value_range_equiv ()
{
return new (equiv_alloc->allocate ()) value_range_equiv;
}
void
range_query::free_value_range_equiv (value_range_equiv *v)
{
equiv_alloc->remove (v);
}
const class value_range_equiv *
const value_range *
range_query::get_value_range (const_tree expr, gimple *stmt)
{
int_range_max r;
if (range_of_expr (r, const_cast<tree> (expr), stmt))
return new (equiv_alloc->allocate ()) value_range_equiv (r);
return new (equiv_alloc->allocate ()) value_range_equiv (TREE_TYPE (expr));
return new (equiv_alloc->allocate ()) value_range (r);
return new (equiv_alloc->allocate ()) value_range (TREE_TYPE (expr));
}
range_query::range_query ()

View File

@ -106,13 +106,10 @@ public:
// DEPRECATED: This method is used from vr-values. The plan is to
// rewrite all uses of it to the above API.
virtual const class value_range_equiv *get_value_range (const_tree,
gimple * = NULL);
virtual const value_range *get_value_range (const_tree, gimple * = NULL);
virtual void dump (FILE *);
protected:
class value_range_equiv *allocate_value_range_equiv ();
void free_value_range_equiv (class value_range_equiv *);
bool get_tree_range (vrange &v, tree expr, gimple *stmt);
bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
relation_oracle *m_oracle;

View File

@ -1,330 +0,0 @@
/* Support routines for value ranges with equivalences.
Copyright (C) 2020-2022 Free Software Foundation, Inc.
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
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "value-range-equiv.h"
value_range_equiv::value_range_equiv (tree min, tree max, bitmap equiv,
value_range_kind kind)
{
m_equiv = NULL;
set (min, max, equiv, kind);
}
value_range_equiv::value_range_equiv (const value_range &other)
{
m_equiv = NULL;
set (other.min(), other.max (), NULL, other.kind ());
}
void
value_range_equiv::set (tree min, tree max, bitmap equiv,
value_range_kind kind)
{
value_range::set (min, max, kind);
set_equiv (equiv);
if (flag_checking)
check ();
}
void
value_range_equiv::set (tree min, tree max, value_range_kind kind)
{
set (min, max, m_equiv, kind);
}
void
value_range_equiv::set (tree val)
{
gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
if (TREE_OVERFLOW_P (val))
val = drop_tree_overflow (val);
set (val, val);
}
void
value_range_equiv::set_undefined ()
{
set (NULL, NULL, NULL, VR_UNDEFINED);
}
void
value_range_equiv::set_varying (tree type)
{
value_range::set_varying (type);
equiv_clear ();
}
/* Like set, but keep the equivalences in place. */
void
value_range_equiv::update (tree min, tree max, value_range_kind kind)
{
set (min, max,
(kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL, kind);
}
/* Copy value_range in FROM into THIS while avoiding bitmap sharing.
Note: The code that avoids the bitmap sharing looks at the existing
this->m_equiv, so this function cannot be used to initalize an
object. Use the constructors for initialization. */
void
value_range_equiv::deep_copy (const value_range_equiv *from)
{
set (from->min (), from->max (), from->m_equiv, from->kind ());
}
void
value_range_equiv::move (value_range_equiv *from)
{
set (from->min (), from->max (), NULL, from->kind ());
m_equiv = from->m_equiv;
from->m_equiv = NULL;
}
void
value_range_equiv::set_equiv (bitmap equiv)
{
if (undefined_p () || varying_p ())
equiv = NULL;
/* Since updating the equivalence set involves deep copying the
bitmaps, only do it if absolutely necessary.
All equivalence bitmaps are allocated from the same obstack. So
we can use the obstack associated with EQUIV to allocate vr->equiv. */
if (m_equiv == NULL
&& equiv != NULL)
m_equiv = BITMAP_ALLOC (equiv->obstack);
if (equiv != m_equiv)
{
if (equiv && !bitmap_empty_p (equiv))
bitmap_copy (m_equiv, equiv);
else
bitmap_clear (m_equiv);
}
}
void
value_range_equiv::check ()
{
value_range::verify_range ();
switch (kind ())
{
case VR_UNDEFINED:
case VR_VARYING:
gcc_assert (!m_equiv || bitmap_empty_p (m_equiv));
default:;
}
}
/* Return true if the bitmaps B1 and B2 are equal. */
static bool
vr_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
{
return (b1 == b2
|| ((!b1 || bitmap_empty_p (b1))
&& (!b2 || bitmap_empty_p (b2)))
|| (b1 && b2
&& bitmap_equal_p (b1, b2)));
}
/* Returns TRUE if THIS == OTHER. Ignores the equivalence bitmap if
IGNORE_EQUIVS is TRUE. */
bool
value_range_equiv::equal_p (const value_range_equiv &other,
bool ignore_equivs) const
{
return (value_range::operator== (other)
&& (ignore_equivs || vr_bitmap_equal_p (m_equiv, other.m_equiv)));
}
void
value_range_equiv::equiv_clear ()
{
if (m_equiv)
bitmap_clear (m_equiv);
}
/* Add VAR and VAR's equivalence set (VAR_VR) to the equivalence
bitmap. If no equivalence table has been created, OBSTACK is the
obstack to use (NULL for the default obstack).
This is the central point where equivalence processing can be
turned on/off. */
void
value_range_equiv::equiv_add (const_tree var,
const value_range_equiv *var_vr,
bitmap_obstack *obstack)
{
if (!m_equiv)
m_equiv = BITMAP_ALLOC (obstack);
unsigned ver = SSA_NAME_VERSION (var);
bitmap_set_bit (m_equiv, ver);
if (var_vr && var_vr->m_equiv)
bitmap_ior_into (m_equiv, var_vr->m_equiv);
}
void
value_range_equiv::legacy_verbose_intersect (const value_range_equiv *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Intersecting\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
/* If THIS is varying we want to pick up equivalences from OTHER.
Just special-case this here rather than trying to fixup after the
fact. */
if (this->varying_p ())
this->deep_copy (other);
else
{
legacy_intersect (this, other);
if (varying_p () || undefined_p ())
equiv_clear ();
/* If the result is VR_UNDEFINED there is no need to mess with
equivalencies. */
if (!undefined_p ())
{
/* The resulting set of equivalences for range intersection
is the union of the two sets. */
if (m_equiv && other->m_equiv && m_equiv != other->m_equiv)
bitmap_ior_into (m_equiv, other->m_equiv);
else if (other->m_equiv && !m_equiv)
{
/* All equivalence bitmaps are allocated from the same
obstack. So we can use the obstack associated with
VR to allocate this->m_equiv. */
m_equiv = BITMAP_ALLOC (other->m_equiv->obstack);
bitmap_copy (m_equiv, other->m_equiv);
}
}
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\n");
}
}
void
value_range_equiv::legacy_verbose_union_ (const value_range_equiv *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Meeting\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
/* If THIS is undefined we want to pick up equivalences from OTHER.
Just special-case this here rather than trying to fixup after the fact. */
if (this->undefined_p ())
this->deep_copy (other);
else
{
legacy_union (this, other);
if (varying_p () || undefined_p ())
equiv_clear ();
/* The resulting set of equivalences is always the intersection of
the two sets. */
if (this->m_equiv && other->m_equiv && this->m_equiv != other->m_equiv)
bitmap_and_into (this->m_equiv, other->m_equiv);
else if (this->m_equiv && !other->m_equiv)
bitmap_clear (this->m_equiv);
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\n");
}
}
void
value_range_equiv::dump (FILE *file) const
{
value_range::dump (file);
if ((kind () == VR_RANGE || kind () == VR_ANTI_RANGE)
&& m_equiv)
{
bitmap_iterator bi;
unsigned i, c = 0;
fprintf (file, " EQUIVALENCES: { ");
EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
{
print_generic_expr (file, ssa_name (i));
fprintf (file, " ");
c++;
}
fprintf (file, "} (%u elements)", c);
}
}
void
value_range_equiv::dump () const
{
dump (stderr);
}
void
dump_value_range (FILE *file, const value_range_equiv *vr)
{
if (!vr)
fprintf (file, "[]");
else
vr->dump (file);
}
DEBUG_FUNCTION void
debug (const value_range_equiv *vr)
{
dump_value_range (stderr, vr);
}
DEBUG_FUNCTION void
debug (const value_range_equiv &vr)
{
dump_value_range (stderr, &vr);
}

View File

@ -1,90 +0,0 @@
/* Support routines for value ranges with equivalences.
Copyright (C) 2020-2022 Free Software Foundation, Inc.
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
<http://www.gnu.org/licenses/>. */
#ifndef GCC_VALUE_RANGE_EQUIV_H
#define GCC_VALUE_RANGE_EQUIV_H
#include "value-range.h"
/* Note value_range_equiv cannot currently be used with GC memory,
only value_range is fully set up for this. */
class GTY((user)) value_range_equiv : public value_range
{
public:
value_range_equiv () : value_range () { m_equiv = NULL; }
value_range_equiv (const value_range &);
/* Deep-copies equiv bitmap argument. */
value_range_equiv (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
/* Shallow-copies equiv bitmap. */
value_range_equiv (const value_range_equiv &) /* = delete */;
/* Shallow-copies equiv bitmap. */
value_range_equiv& operator=(const value_range_equiv &) /* = delete */;
/* Virtual destructor. */
virtual ~value_range_equiv () = default;
/* Move equiv bitmap from source range. */
void move (value_range_equiv *);
/* Leaves equiv bitmap alone. */
virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
void update (tree, tree, value_range_kind = VR_RANGE);
/* Deep-copies equiv bitmap argument. */
void set (tree, tree, bitmap, value_range_kind = VR_RANGE);
void set (tree);
bool operator== (const value_range_equiv &) const /* = delete */;
bool operator!= (const value_range_equiv &) const /* = delete */;
void legacy_verbose_intersect (const value_range_equiv *);
void legacy_verbose_union_ (const value_range_equiv *);
bool equal_p (const value_range_equiv &, bool ignore_equivs) const;
/* Types of value ranges. */
void set_undefined () override;
void set_varying (tree) override;
/* Equivalence bitmap methods. */
bitmap equiv () const { return m_equiv; }
void equiv_clear ();
void equiv_add (const_tree, const value_range_equiv *,
bitmap_obstack * = NULL);
/* Misc methods. */
void deep_copy (const value_range_equiv *);
void dump (FILE *) const;
void dump () const;
static bool supports_p (tree type)
{
return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
}
private:
/* Deep-copies bitmap argument. */
void set_equiv (bitmap);
void check ();
/* Set of SSA names whose value ranges are equivalent to this one.
This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
bitmap m_equiv;
};
extern void dump_value_range (FILE *, const value_range_equiv *);
#endif // GCC_VALUE_RANGE_EQUIV_H

View File

@ -215,8 +215,8 @@ check_for_binary_op_overflow (range_query *query,
static tree
compare_ranges (enum tree_code comp, const value_range_equiv *vr0,
const value_range_equiv *vr1, bool *strict_overflow_p)
compare_ranges (enum tree_code comp, const value_range *vr0,
const value_range *vr1, bool *strict_overflow_p)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
if (vr0->varying_p ()
@ -619,19 +619,20 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
or a symbolic range containing the SSA_NAME only if the value range
is varying or undefined. Uses TEM as storage for the alternate range. */
const value_range_equiv *
simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem,
const value_range *
simplify_using_ranges::get_vr_for_comparison (int i, value_range *tem,
gimple *s)
{
/* Shallow-copy equiv bitmap. */
const value_range_equiv *vr = query->get_value_range (ssa_name (i), s);
const value_range *vr = query->get_value_range (ssa_name (i), s);
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
have N_i in their ranges. */
if (vr->varying_p () || vr->undefined_p ())
{
tem->set (ssa_name (i));
tree ssa = ssa_name (i);
tem->set (ssa, ssa);
return tem;
}
@ -646,77 +647,26 @@ simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem,
tree
simplify_using_ranges::compare_name_with_value
(enum tree_code comp, tree var, tree val,
bool *strict_overflow_p, bool use_equiv_p,
gimple *s)
bool *strict_overflow_p, gimple *s)
{
/* Get the set of equivalences for VAR. */
bitmap e = query->get_value_range (var, s)->equiv ();
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
int used_strict_overflow = -1;
/* Compare vars' value range with val. */
value_range_equiv tem_vr;
const value_range_equiv *equiv_vr
value_range tem_vr;
const value_range *equiv_vr
= get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr, s);
bool sop = false;
tree retval = compare_range_with_value (comp, equiv_vr, val, &sop);
if (retval)
used_strict_overflow = sop ? 1 : 0;
/* If the equiv set is empty we have done all work we need to do. */
if (e == NULL)
{
if (retval && used_strict_overflow > 0)
*strict_overflow_p = true;
return retval;
}
unsigned i;
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
{
tree name = ssa_name (i);
if (!name)
continue;
if (!use_equiv_p
&& !SSA_NAME_IS_DEFAULT_DEF (name)
&& prop_simulate_again_p (SSA_NAME_DEF_STMT (name)))
continue;
equiv_vr = get_vr_for_comparison (i, &tem_vr, s);
sop = false;
tree t = compare_range_with_value (comp, equiv_vr, val, &sop);
if (t)
{
/* If we get different answers from different members
of the equivalence set this check must be in a dead
code region. Folding it to a trap representation
would be correct here. For now just return don't-know. */
if (retval != NULL
&& t != retval)
{
retval = NULL_TREE;
break;
}
retval = t;
if (!sop)
used_strict_overflow = 0;
else if (used_strict_overflow < 0)
used_strict_overflow = 1;
}
}
if (retval && used_strict_overflow > 0)
*strict_overflow_p = true;
return retval;
}
/* Given a comparison code COMP and names N1 and N2, compare all the
ranges equivalent to N1 against all the ranges equivalent to N2
to determine the value of N1 COMP N2. Return the same value
@ -728,10 +678,10 @@ tree
simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
bool *strict_overflow_p, gimple *s)
{
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
bitmap e1 = query->get_value_range (n1, s)->equiv ();
bitmap e2 = query->get_value_range (n2, s)->equiv ();
/* ?? These bitmaps are NULL as there are no longer any equivalences
available in the value_range*. */
bitmap e1 = NULL;
bitmap e2 = NULL;
/* Use the fake bitmaps if e1 or e2 are not available. */
static bitmap s_e1 = NULL, s_e2 = NULL;
@ -780,8 +730,8 @@ simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
if (!ssa_name (i1))
continue;
value_range_equiv tem_vr1;
const value_range_equiv *vr1 = get_vr_for_comparison (i1, &tem_vr1, s);
value_range tem_vr1;
const value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1, s);
tree t = NULL_TREE, retval = NULL_TREE;
bitmap_iterator bi2;
@ -793,9 +743,8 @@ simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
bool sop = false;
value_range_equiv tem_vr2;
const value_range_equiv *vr2 = get_vr_for_comparison (i2, &tem_vr2,
s);
value_range tem_vr2;
const value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2, s);
t = compare_ranges (comp, vr1, vr2, &sop);
if (t)
@ -844,7 +793,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p,
gimple *s)
{
const value_range_equiv *vr0, *vr1;
const value_range *vr0, *vr1;
vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0, s) : NULL;
vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1, s) : NULL;
@ -925,7 +874,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
}
else
gcc_unreachable ();
const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
const value_range *vr0 = query->get_value_range (op0, stmt);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
@ -955,11 +904,10 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
&& use_equiv_p)
return compare_names (code, op0, op1, strict_overflow_p, stmt);
else if (TREE_CODE (op0) == SSA_NAME)
return compare_name_with_value (code, op0, op1,
strict_overflow_p, use_equiv_p, stmt);
return compare_name_with_value (code, op0, op1, strict_overflow_p, stmt);
else if (TREE_CODE (op1) == SSA_NAME)
return compare_name_with_value (swap_tree_comparison (code), op1, op0,
strict_overflow_p, use_equiv_p, stmt);
strict_overflow_p, stmt);
return NULL_TREE;
}
@ -1250,7 +1198,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
const value_range_equiv *vr1 = query->get_value_range (op1, stmt);
const value_range *vr1 = query->get_value_range (op1, stmt);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}

View File

@ -20,7 +20,6 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_VR_VALUES_H
#define GCC_VR_VALUES_H
#include "value-range-equiv.h"
#include "value-query.h"
// Abstract class to return a range for a given SSA.
@ -54,11 +53,9 @@ private:
bool two_valued_val_range_p (tree, tree *, tree *, gimple *);
bool op_with_boolean_value_range_p (tree, gimple *);
tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool,
gimple *);
tree compare_name_with_value (enum tree_code, tree, tree, bool *, gimple *);
tree compare_names (enum tree_code, tree, tree, bool *, gimple *s);
const value_range_equiv *get_vr_for_comparison (int, value_range_equiv *,
gimple *s);
const value_range *get_vr_for_comparison (int, value_range *, gimple *s);
tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
tree, tree,
bool *, gimple *s);