* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer)
Initialize vr_values. (evrp_range_analyzer::try_find_new_range): Call methods attached to vr_values via vr_values class instance rather than delegators. (evrp_range_analyzer::record_ranges_from_phis): Likewise. (evrp_range_analyzer::record_ranges_from_stmt): Likewise. (evrp_range_analyzer::push_value_range): Likewise. (evrp_range_analyzer::pop_value_range): Likewise. * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove most delegators. Those remaining are exposed as public interfaces. Make vr_values a pointer and private. (evrp_range_analyzer::~evrp_range_analyzer): Delete the attached vr_values. (evrp_range_analyzer::get_vr_value): New method. * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN. (evrp_folder::evrp_folder): New ctor to initialize vr_values. (class evrp_dom_walker): Attach evrp_folder class, initialize it in the ctor. Remove temporary delegators. (evrp_dom_walker::before_dom_children): Call methods in attached evrp_range_analyzer class via class instance pointer. Use free value_range_constant_singleton to remove need for op_with_constant_singleton_value delegator method. Do not create a vrp_prop class instance for every call! Narrow scope of a couple variables. (evrp_dom_walker::cleanup): Call methods in attached evrp_range_analyzer class via class instance pointer. * vr-values.h (class vr_values): Privatize many methods and data members. From-SVN: r255074
This commit is contained in:
parent
16d24520af
commit
a5de02e9e3
@ -1,3 +1,34 @@
|
||||
2017-11-22 Jeff Law <law@redhat.com>
|
||||
|
||||
* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer)
|
||||
Initialize vr_values.
|
||||
(evrp_range_analyzer::try_find_new_range): Call methods attached to
|
||||
vr_values via vr_values class instance rather than delegators.
|
||||
(evrp_range_analyzer::record_ranges_from_phis): Likewise.
|
||||
(evrp_range_analyzer::record_ranges_from_stmt): Likewise.
|
||||
(evrp_range_analyzer::push_value_range): Likewise.
|
||||
(evrp_range_analyzer::pop_value_range): Likewise.
|
||||
* gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove
|
||||
most delegators. Those remaining are exposed as public interfaces.
|
||||
Make vr_values a pointer and private.
|
||||
(evrp_range_analyzer::~evrp_range_analyzer): Delete the attached
|
||||
vr_values.
|
||||
(evrp_range_analyzer::get_vr_value): New method.
|
||||
* gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN.
|
||||
(evrp_folder::evrp_folder): New ctor to initialize vr_values.
|
||||
(class evrp_dom_walker): Attach evrp_folder class, initialize
|
||||
it in the ctor. Remove temporary delegators.
|
||||
(evrp_dom_walker::before_dom_children): Call methods in attached
|
||||
evrp_range_analyzer class via class instance pointer. Use
|
||||
free value_range_constant_singleton to remove need for
|
||||
op_with_constant_singleton_value delegator method. Do not
|
||||
create a vrp_prop class instance for every call! Narrow
|
||||
scope of a couple variables.
|
||||
(evrp_dom_walker::cleanup): Call methods in attached
|
||||
evrp_range_analyzer class via class instance pointer.
|
||||
* vr-values.h (class vr_values): Privatize many methods and
|
||||
data members.
|
||||
|
||||
2017-11-22 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* tree.def (REDUC_MAX_EXPR, REDUC_MIN_EXPR, REDUC_PLUS_EXPR): Delete.
|
||||
|
@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10)
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
e->flags |= EDGE_EXECUTABLE;
|
||||
}
|
||||
vr_values = new class vr_values;
|
||||
}
|
||||
|
||||
void
|
||||
@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name,
|
||||
value_range *old_vr = get_value_range (name);
|
||||
|
||||
/* Discover VR when condition is true. */
|
||||
extract_range_for_var_from_comparison_expr (name, code, op,
|
||||
limit, &vr);
|
||||
vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
|
||||
limit, &vr);
|
||||
/* If we found any usable VR, set the VR to ssa_name and create a
|
||||
PUSH old value in the stack with the old VR. */
|
||||
if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
|
||||
@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name,
|
||||
&& vrp_operand_equal_p (old_vr->min, vr.min)
|
||||
&& vrp_operand_equal_p (old_vr->max, vr.max))
|
||||
return NULL;
|
||||
value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
|
||||
value_range *new_vr = vr_values->vrp_value_range_pool.allocate ();
|
||||
*new_vr = vr;
|
||||
return new_vr;
|
||||
}
|
||||
@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
|
||||
value_range vr_result = VR_INITIALIZER;
|
||||
bool interesting = stmt_interesting_for_vrp (phi);
|
||||
if (!has_unvisited_preds && interesting)
|
||||
extract_range_from_phi_node (phi, &vr_result);
|
||||
vr_values->extract_range_from_phi_node (phi, &vr_result);
|
||||
else
|
||||
{
|
||||
set_value_range_to_varying (&vr_result);
|
||||
@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
|
||||
if (interesting
|
||||
&& (l = loop_containing_stmt (phi))
|
||||
&& l->header == gimple_bb (phi))
|
||||
adjust_range_with_scev (&vr_result, l, phi, lhs);
|
||||
vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
|
||||
}
|
||||
update_value_range (lhs, &vr_result);
|
||||
vr_values->update_value_range (lhs, &vr_result);
|
||||
|
||||
/* Set the SSA with the value range. */
|
||||
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
|
||||
@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
|
||||
{
|
||||
edge taken_edge;
|
||||
value_range vr = VR_INITIALIZER;
|
||||
extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
|
||||
vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
|
||||
if (output
|
||||
&& (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
|
||||
{
|
||||
update_value_range (output, &vr);
|
||||
vr_values->update_value_range (output, &vr);
|
||||
|
||||
/* Set the SSA with the value range. */
|
||||
if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
|
||||
@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
|
||||
set_ptr_nonnull (output);
|
||||
}
|
||||
else
|
||||
set_defs_to_varying (stmt);
|
||||
vr_values->set_defs_to_varying (stmt);
|
||||
}
|
||||
else
|
||||
set_defs_to_varying (stmt);
|
||||
vr_values->set_defs_to_varying (stmt);
|
||||
|
||||
/* See if we can derive a range for any of STMT's operands. */
|
||||
tree op;
|
||||
@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr)
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
stack.safe_push (std::make_pair (var, get_value_range (var)));
|
||||
set_vr_value (var, vr);
|
||||
vr_values->set_vr_value (var, vr);
|
||||
}
|
||||
|
||||
/* Pop the Value Range from the vrp_stack and update VAR with it. */
|
||||
@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var)
|
||||
dump_value_range (dump_file, vr);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
set_vr_value (var, vr);
|
||||
vr_values->set_vr_value (var, vr);
|
||||
stack.pop ();
|
||||
return vr;
|
||||
}
|
||||
|
@ -24,16 +24,45 @@ class evrp_range_analyzer
|
||||
{
|
||||
public:
|
||||
evrp_range_analyzer (void);
|
||||
~evrp_range_analyzer (void) { stack.release (); }
|
||||
~evrp_range_analyzer (void)
|
||||
{
|
||||
delete vr_values;
|
||||
stack.release ();
|
||||
}
|
||||
|
||||
void enter (basic_block);
|
||||
void leave (basic_block);
|
||||
void record_ranges_from_stmt (gimple *);
|
||||
|
||||
class vr_values vr_values;
|
||||
/* Main interface to retrieve range information. */
|
||||
value_range *get_value_range (const_tree op)
|
||||
{ return vr_values->get_value_range (op); }
|
||||
|
||||
/* Dump all the current value ranges. This is primarily
|
||||
a debugging interface. */
|
||||
void dump_all_value_ranges (FILE *fp)
|
||||
{ vr_values->dump_all_value_ranges (fp); }
|
||||
|
||||
/* A bit of a wart. This should ideally go away. */
|
||||
void vrp_visit_cond_stmt (gcond *cond, edge *e)
|
||||
{ return vr_values->vrp_visit_cond_stmt (cond, e); }
|
||||
|
||||
/* Get the underlying vr_values class instance. If TRANSFER is
|
||||
true, then we are transferring ownership. Else we keep ownership.
|
||||
|
||||
This should be converted to a unique_ptr. */
|
||||
class vr_values *get_vr_values (bool transfer)
|
||||
{
|
||||
class vr_values *x = vr_values;
|
||||
if (transfer)
|
||||
vr_values = NULL;
|
||||
return x;
|
||||
}
|
||||
|
||||
private:
|
||||
DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
|
||||
class vr_values *vr_values;
|
||||
|
||||
void push_value_range (tree var, value_range *vr);
|
||||
value_range *pop_value_range (tree var);
|
||||
value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
|
||||
@ -42,30 +71,6 @@ class evrp_range_analyzer
|
||||
|
||||
/* STACK holds the old VR. */
|
||||
auto_vec<std::pair <tree, value_range*> > stack;
|
||||
|
||||
/* Temporary delegators. */
|
||||
value_range *get_value_range (const_tree op)
|
||||
{ return vr_values.get_value_range (op); }
|
||||
bool update_value_range (const_tree op, value_range *vr)
|
||||
{ return vr_values.update_value_range (op, vr); }
|
||||
void extract_range_from_phi_node (gphi *phi, value_range *vr)
|
||||
{ vr_values.extract_range_from_phi_node (phi, vr); }
|
||||
void adjust_range_with_scev (value_range *vr, struct loop *loop,
|
||||
gimple *stmt, tree var)
|
||||
{ vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
|
||||
void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
|
||||
tree *output_p, value_range *vr)
|
||||
{ vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
|
||||
void set_defs_to_varying (gimple *stmt)
|
||||
{ return vr_values.set_defs_to_varying (stmt); }
|
||||
void set_vr_value (tree name, value_range *vr)
|
||||
{ vr_values.set_vr_value (name, vr); }
|
||||
void extract_range_for_var_from_comparison_expr (tree var,
|
||||
enum tree_code cond_code,
|
||||
tree op, tree limit,
|
||||
value_range *vr_p)
|
||||
{ vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
|
||||
op, limit, vr_p); }
|
||||
};
|
||||
|
||||
#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
|
||||
|
@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine
|
||||
{
|
||||
public:
|
||||
tree get_value (tree) FINAL OVERRIDE;
|
||||
|
||||
evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
|
||||
class vr_values *vr_values;
|
||||
|
||||
private:
|
||||
DISABLE_COPY_AND_ASSIGN (evrp_folder);
|
||||
};
|
||||
|
||||
tree
|
||||
@ -63,7 +66,9 @@ evrp_folder::get_value (tree op)
|
||||
class evrp_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
evrp_dom_walker () : dom_walker (CDI_DOMINATORS)
|
||||
evrp_dom_walker ()
|
||||
: dom_walker (CDI_DOMINATORS),
|
||||
evrp_folder (evrp_range_analyzer.get_vr_values (false))
|
||||
{
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
}
|
||||
@ -82,14 +87,7 @@ public:
|
||||
auto_vec<gimple *> stmts_to_remove;
|
||||
|
||||
class evrp_range_analyzer evrp_range_analyzer;
|
||||
|
||||
/* Temporary delegators. */
|
||||
value_range *get_value_range (const_tree op)
|
||||
{ return evrp_range_analyzer.vr_values.get_value_range (op); }
|
||||
tree op_with_constant_singleton_value_range (tree op)
|
||||
{ return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); }
|
||||
void vrp_visit_cond_stmt (gcond *cond, edge *e)
|
||||
{ evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
|
||||
class evrp_folder evrp_folder;
|
||||
};
|
||||
|
||||
edge
|
||||
@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb)
|
||||
if (virtual_operand_p (lhs))
|
||||
continue;
|
||||
|
||||
value_range *vr = evrp_range_analyzer.get_value_range (lhs);
|
||||
/* Mark PHIs whose lhs we fully propagate for removal. */
|
||||
tree val = op_with_constant_singleton_value_range (lhs);
|
||||
tree val = value_range_constant_singleton (vr);
|
||||
if (val && may_propagate_copy (lhs, val))
|
||||
{
|
||||
stmts_to_remove.safe_push (phi);
|
||||
@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
|
||||
|
||||
if (gcond *cond = dyn_cast <gcond *> (stmt))
|
||||
{
|
||||
vrp_visit_cond_stmt (cond, &taken_edge);
|
||||
evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge);
|
||||
if (taken_edge)
|
||||
{
|
||||
if (taken_edge->flags & EDGE_TRUE_VALUE)
|
||||
@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb)
|
||||
}
|
||||
else if (stmt_interesting_for_vrp (stmt))
|
||||
{
|
||||
value_range vr = VR_INITIALIZER;
|
||||
output = get_output_for_vrp (stmt);
|
||||
if (output)
|
||||
{
|
||||
tree val;
|
||||
vr = *get_value_range (output);
|
||||
value_range *vr = evrp_range_analyzer.get_value_range (output);
|
||||
|
||||
/* Mark stmts whose output we fully propagate for removal. */
|
||||
if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
|
||||
&& (val = op_with_constant_singleton_value_range (output))
|
||||
if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
|
||||
&& (val = value_range_constant_singleton (vr))
|
||||
&& may_propagate_copy (output, val)
|
||||
&& !stmt_could_throw_p (stmt)
|
||||
&& !gimple_has_side_effects (stmt))
|
||||
@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb)
|
||||
}
|
||||
|
||||
/* Try folding stmts with the VR discovered. */
|
||||
class evrp_folder evrp_folder;
|
||||
evrp_folder.vr_values = &evrp_range_analyzer.vr_values;
|
||||
bool did_replace = evrp_folder.replace_uses_in (stmt);
|
||||
if (fold_stmt (&gsi, follow_single_use_edges)
|
||||
|| did_replace)
|
||||
@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
|
||||
if (TREE_CODE (arg) != SSA_NAME
|
||||
|| virtual_operand_p (arg))
|
||||
continue;
|
||||
tree val = op_with_constant_singleton_value_range (arg);
|
||||
value_range *vr = evrp_range_analyzer.get_value_range (arg);
|
||||
tree val = value_range_constant_singleton (vr);
|
||||
if (val && may_propagate_copy (arg, val))
|
||||
propagate_value (use_p, val);
|
||||
}
|
||||
@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void)
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
|
||||
evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file);
|
||||
evrp_range_analyzer.dump_all_value_ranges (dump_file);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
|
@ -40,80 +40,81 @@ class vr_values
|
||||
vr_values (void);
|
||||
~vr_values (void);
|
||||
|
||||
/* Value range array. After propagation, VR_VALUE[I] holds the range
|
||||
of values that SSA name N_I may take. */
|
||||
unsigned int num_vr_values;
|
||||
value_range **vr_value;
|
||||
bool values_propagated;
|
||||
value_range *get_value_range (const_tree);
|
||||
|
||||
/* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
|
||||
number of executable edges we saw the last time we visited the
|
||||
node. */
|
||||
int *vr_phi_edge_counts;
|
||||
void set_vr_value (tree, value_range *);
|
||||
void set_defs_to_varying (gimple *);
|
||||
bool update_value_range (const_tree, value_range *);
|
||||
tree op_with_constant_singleton_value_range (tree);
|
||||
void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
|
||||
tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
|
||||
void dump_all_value_ranges (FILE *);
|
||||
|
||||
void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
|
||||
tree, tree, value_range *);
|
||||
void extract_range_from_phi_node (gphi *, value_range *);
|
||||
void extract_range_basic (value_range *, gimple *);
|
||||
void extract_range_from_assignment (value_range *, gassign *);
|
||||
void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
|
||||
|
||||
void vrp_visit_cond_stmt (gcond *, edge *);
|
||||
|
||||
void simplify_cond_using_ranges_2 (gcond *);
|
||||
bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
|
||||
|
||||
/* This probably belongs in the lattice rather than in here. */
|
||||
bool values_propagated;
|
||||
|
||||
/* Allocation pools for tree-vrp allocations. */
|
||||
object_allocator<value_range> vrp_value_range_pool;
|
||||
|
||||
private:
|
||||
bitmap_obstack vrp_equiv_obstack;
|
||||
|
||||
value_range *get_value_range (const_tree);
|
||||
void set_vr_value (tree, value_range *);
|
||||
|
||||
void set_defs_to_varying (gimple *);
|
||||
bool update_value_range (const_tree, value_range *);
|
||||
void add_equivalence (bitmap *, const_tree);
|
||||
bool vrp_stmt_computes_nonzero (gimple *);
|
||||
tree op_with_constant_singleton_value_range (tree);
|
||||
bool op_with_boolean_value_range_p (tree);
|
||||
bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
|
||||
void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
|
||||
value_range get_vr_for_comparison (int);
|
||||
tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
|
||||
tree compare_names (enum tree_code, tree, tree, bool *);
|
||||
bool two_valued_val_range_p (tree, tree *, tree *);
|
||||
|
||||
tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
|
||||
tree, tree,
|
||||
bool *);
|
||||
tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
|
||||
tree, tree, bool,
|
||||
bool *, bool *);
|
||||
tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
|
||||
|
||||
|
||||
void dump_all_value_ranges (FILE *);
|
||||
|
||||
void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
|
||||
tree, tree, value_range *);
|
||||
void extract_range_from_assert (value_range *, tree);
|
||||
void extract_range_from_ssa_name (value_range *, tree);
|
||||
void extract_range_from_binary_expr (value_range *, enum tree_code,
|
||||
tree, tree, tree);
|
||||
void extract_range_from_unary_expr (value_range *, enum tree_code,
|
||||
tree, tree);
|
||||
void extract_range_from_phi_node (gphi *, value_range *);
|
||||
void extract_range_from_cond_expr (value_range *, gassign *);
|
||||
void extract_range_basic (value_range *, gimple *);
|
||||
void extract_range_from_assignment (value_range *, gassign *);
|
||||
void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
|
||||
void extract_range_from_comparison (value_range *, enum tree_code,
|
||||
tree, tree, tree);
|
||||
|
||||
void vrp_visit_assignment_or_call (gimple*, tree *, value_range *);
|
||||
void vrp_visit_switch_stmt (gswitch *, edge *);
|
||||
void vrp_visit_cond_stmt (gcond *, edge *);
|
||||
|
||||
bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_cond_using_ranges_1 (gcond *);
|
||||
void simplify_cond_using_ranges_2 (gcond *);
|
||||
bool simplify_switch_using_ranges (gswitch *);
|
||||
bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *,
|
||||
gimple *);
|
||||
bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *);
|
||||
bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
|
||||
|
||||
/* Value range array. After propagation, VR_VALUE[I] holds the range
|
||||
of values that SSA name N_I may take. */
|
||||
unsigned int num_vr_values;
|
||||
value_range **vr_value;
|
||||
|
||||
/* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
|
||||
number of executable edges we saw the last time we visited the
|
||||
node. */
|
||||
int *vr_phi_edge_counts;
|
||||
};
|
||||
|
||||
#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
|
||||
|
Loading…
Reference in New Issue
Block a user