Limit the number of relations registered per basic block.

In pathological cases, the number of transitive relations being added is
potentially quadratic.  Lookups for relations in a block is linear in
nature, so simply limit the number of relations to some reasonable number.

	PR tree-optimization/104038
	* doc/invoke.texi (relation-block-limit): New.
	* params.opt (relation-block-limit): New.
	* value-relation.cc (dom_oracle::register_relation): Check for NULL
	record before invoking transitive registery.
	(dom_oracle::set_one_relation): Check limit before creating record.
	(dom_oracle::register_transitives): Stop when no record created.
	* value-relation.h (relation_chain_head::m_num_relations): New.
This commit is contained in:
Andrew MacLeod 2022-01-17 12:03:18 -05:00
parent c952126870
commit 254ada46ae
4 changed files with 20 additions and 3 deletions

View File

@ -15088,6 +15088,9 @@ per supernode, before terminating analysis.
Maximum depth of logical expression evaluation ranger will look through
when evaluating outgoing edge ranges.
@item relation-block-limit
Maximum number of relations the oracle will register in a basic block.
@item openacc-kernels
Specify mode of OpenACC `kernels' constructs handling.
With @option{--param=openacc-kernels=decompose}, OpenACC `kernels'

View File

@ -915,6 +915,10 @@ Common Joined UInteger Var(param_ranger_logical_depth) Init(6) IntegerRange(1, 9
Maximum depth of logical expression evaluation ranger will look through when
evaluating outgoing edge ranges.
-param=relation-block-limit=
Common Joined UInteger Var(param_relation_block_limit) Init(200) IntegerRange(0, 9999) Param Optimization
Maximum number of relations the oracle will register in a basic block.
-param=rpo-vn-max-loop-depth=
Common Joined UInteger Var(param_rpo_vn_max_loop_depth) Init(7) IntegerRange(2, 65536) Param Optimization
Maximum depth of a loop nest to fully value-number optimistically.

View File

@ -889,13 +889,14 @@ dom_oracle::register_relation (basic_block bb, relation_kind k, tree op1,
else
{
relation_chain *ptr = set_one_relation (bb, k, op1, op2);
register_transitives (bb, *ptr);
if (ptr)
register_transitives (bb, *ptr);
}
}
// Register relation K between OP! and OP2 in block BB.
// This creates the record and searches for existing records in the dominator
// tree to merge with.
// tree to merge with. Return the record, or NULL if no record was created.
relation_chain *
dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1,
@ -940,6 +941,13 @@ dom_oracle::set_one_relation (basic_block bb, relation_kind k, tree op1,
}
else
{
if (m_relations[bbi].m_num_relations >= param_relation_block_limit)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Not registered due to bb being full\n");
return NULL;
}
m_relations[bbi].m_num_relations++;
// Check for an existing relation further up the DOM chain.
// By including dominating relations, The first one found in any search
// will be the aggregate of all the previous ones.
@ -1040,7 +1048,8 @@ dom_oracle::register_transitives (basic_block root_bb,
value_relation nr (relation.kind (), r1, r2);
if (nr.apply_transitive (*ptr))
{
set_one_relation (root_bb, nr.kind (), nr.op1 (), nr.op2 ());
if (!set_one_relation (root_bb, nr.kind (), nr.op1 (), nr.op2 ()))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Registering transitive relation ");

View File

@ -157,6 +157,7 @@ class relation_chain_head
public:
bitmap m_names; // ssa_names with relations in this block.
class relation_chain *m_head; // List of relations in block.
int m_num_relations; // Number of relations in block.
relation_kind find_relation (const_bitmap b1, const_bitmap b2) const;
};