diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2022-01-17 12:03:18 -0500 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2022-01-18 10:02:02 -0500 |
commit | 254ada46ae0f21bd6f40314214f969f368328e22 (patch) | |
tree | 45c2a9fd29aa47dda63f86debfd557c811ebe108 | |
parent | c952126870c92cf293d59ffb1497e402eb8fc269 (diff) | |
download | gcc-254ada46ae0f21bd6f40314214f969f368328e22.zip gcc-254ada46ae0f21bd6f40314214f969f368328e22.tar.gz gcc-254ada46ae0f21bd6f40314214f969f368328e22.tar.bz2 |
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.
-rw-r--r-- | gcc/doc/invoke.texi | 3 | ||||
-rw-r--r-- | gcc/params.opt | 4 | ||||
-rw-r--r-- | gcc/value-relation.cc | 15 | ||||
-rw-r--r-- | gcc/value-relation.h | 1 |
4 files changed, 20 insertions, 3 deletions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 96a64f3..58751c4 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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' diff --git a/gcc/params.opt b/gcc/params.opt index 665071f..b07663d 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -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. diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 1e495bd..32ca693 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -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 "); diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 207defa..44d0796 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -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; }; |