From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 96542386FC3B for ; Tue, 27 Jul 2021 10:19:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 96542386FC3B Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-286-es4lyo4KO-K7Y1gdmOzDAA-1; Tue, 27 Jul 2021 06:19:41 -0400 X-MC-Unique: es4lyo4KO-K7Y1gdmOzDAA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 26A2F593AE; Tue, 27 Jul 2021 10:19:40 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.39.192.35]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7E86E179B3; Tue, 27 Jul 2021 10:19:39 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.16.1/8.15.2) with ESMTPS id 16RAJb8A2457165 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 27 Jul 2021 12:19:37 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.16.1/8.16.1/Submit) id 16RAJasc2457164; Tue, 27 Jul 2021 12:19:36 +0200 From: Aldy Hernandez To: GCC patches , Jeff Law Subject: [PATCH] Abstract out (forward) jump threader state handling. Date: Tue, 27 Jul 2021 12:19:15 +0200 Message-Id: <20210727101914.2457023-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2021 10:19:45 -0000 The *forward* jump threader has multiple places where it pushes and pops state, and where it sets context up for the jump threading simplifier callback. Not only are the idioms repetitive, but the only reason for passing const_and_copies, avail_exprs_stack, and the evrp engine around are so we can set up context. As part of my jump threading work, I will divorce the evrp engine from the DOM jump threader, replacing it with a subset of the path solver I have just contributed. Since this will entail passing even more context around, I've abstracted out the state handling so it can be passed around in one object. This cleans up the code, and also makes it trivial to set up context with another engine in the future. FWIW, I've used these cleanups with the path solver in a proof-of-concept to improve DOM's threaded edges by an additional 5%, and the overall threading opportunities in the compiler by 1%. This is in addition to the gains I have documented in the backwards threader rewrite. There are no functional changes with this patch. Tested on x86-64 Linux. OK? gcc/ChangeLog: * tree-ssa-dom.c (dom_jump_threader_simplifier): Put avail_exprs_stack in the class, instead of passing it to jump_threader_simplifier. (dom_jump_threader_simplifier::simplify): Add state argument. (dom_opt_dom_walker): Add state. (pass_dominator::execute): Pass state to threader. (dom_opt_dom_walker::before_dom_children): Use state. * tree-ssa-threadedge.c (jump_threader::jump_threader): Replace arguments by state. (jump_threader::record_temporary_equivalences_from_phis): Register equivalences through the state variable. (jump_threader::record_temporary_equivalences_from_stmts_at_dest): Record ranges in a statement through the state variable. (jump_threader::simplify_control_stmt_condition): Pass state to simplify. (jump_threader::simplify_control_stmt_condition_1): Same. (jump_threader::thread_around_empty_blocks): Remove obsolete comment. (jump_threader::thread_through_normal_block): Record equivalences on edge through the state variable. (jump_threader::thread_across_edge): Abstract state pushing. (jt_state::jt_state): New. (jt_state::push): New. (jt_state::pop): New. (jt_state::register_equiv): New. (jt_state::record_ranges_from_stmt): New. (jt_state::register_equivs_on_edge): New. (jump_threader_simplifier::jump_threader_simplifier): Move from header. (jump_threader_simplifier::simplify): Add state argument. * tree-ssa-threadedge.h (class jt_state): New. (class jump_threader): Add state to constructor. (class jump_threader_simplifier): Add state to simplify. Remove avail_exprs_stack from class. * tree-vrp.c (vrp_jump_threader_simplifier::simplify): Add state argument. (vrp_jump_threader::vrp_jump_threader): Add state. (vrp_jump_threader::~vrp_jump_threader): Cleanup state. --- gcc/tree-ssa-dom.c | 21 ++-- gcc/tree-ssa-threadedge.c | 219 +++++++++++++++++++++----------------- gcc/tree-ssa-threadedge.h | 39 ++++--- gcc/tree-vrp.c | 16 +-- 4 files changed, 172 insertions(+), 123 deletions(-) diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index c231e6c8467..a0df492df10 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -590,16 +590,18 @@ class dom_jump_threader_simplifier : public jump_threader_simplifier public: dom_jump_threader_simplifier (vr_values *v, avail_exprs_stack *avails) - : jump_threader_simplifier (v, avails) {} + : jump_threader_simplifier (v), m_avail_exprs_stack (avails) { } private: - tree simplify (gimple *, gimple *, basic_block); + tree simplify (gimple *, gimple *, basic_block, jt_state *) override; + avail_exprs_stack *m_avail_exprs_stack; }; tree dom_jump_threader_simplifier::simplify (gimple *stmt, gimple *within_stmt, - basic_block bb) + basic_block bb, + jt_state *state) { /* First see if the conditional is in the hash table. */ tree cached_lhs = m_avail_exprs_stack->lookup_avail_expr (stmt, @@ -607,7 +609,7 @@ dom_jump_threader_simplifier::simplify (gimple *stmt, if (cached_lhs) return cached_lhs; - return jump_threader_simplifier::simplify (stmt, within_stmt, bb); + return jump_threader_simplifier::simplify (stmt, within_stmt, bb, state); } class dom_opt_dom_walker : public dom_walker @@ -615,12 +617,14 @@ class dom_opt_dom_walker : public dom_walker public: dom_opt_dom_walker (cdi_direction direction, jump_threader *threader, + jt_state *state, evrp_range_analyzer *analyzer, const_and_copies *const_and_copies, avail_exprs_stack *avail_exprs_stack) : dom_walker (direction, REACHABLE_BLOCKS) { m_evrp_range_analyzer = analyzer; + m_state = state; m_dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node, integer_zero_node, NULL, NULL); m_const_and_copies = const_and_copies; @@ -651,6 +655,7 @@ private: jump_threader *m_threader; evrp_range_analyzer *m_evrp_range_analyzer; + jt_state *m_state; }; /* Jump threading, redundancy elimination and const/copy propagation. @@ -748,10 +753,11 @@ pass_dominator::execute (function *fun) /* Recursively walk the dominator tree optimizing statements. */ evrp_range_analyzer analyzer (true); dom_jump_threader_simplifier simplifier (&analyzer, avail_exprs_stack); - jump_threader threader (const_and_copies, avail_exprs_stack, - &simplifier, &analyzer); + jt_state state (const_and_copies, avail_exprs_stack, &analyzer); + jump_threader threader (&simplifier, &state); dom_opt_dom_walker walker (CDI_DOMINATORS, &threader, + &state, &analyzer, const_and_copies, avail_exprs_stack); @@ -1419,8 +1425,7 @@ dom_opt_dom_walker::before_dom_children (basic_block bb) continue; } - /* Compute range information and optimize the stmt. */ - m_evrp_range_analyzer->record_ranges_from_stmt (gsi_stmt (gsi), false); + m_state->record_ranges_from_stmt (gsi_stmt (gsi), false); bool removed_p = false; taken_edge = this->optimize_stmt (bb, &gsi, &removed_p); if (!removed_p) diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 6ce32644aa5..24ccf014416 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -61,10 +61,8 @@ set_ssa_name_value (tree name, tree value) ssa_name_values[SSA_NAME_VERSION (name)] = value; } -jump_threader::jump_threader (const_and_copies *copies, - avail_exprs_stack *avails, - jump_threader_simplifier *simplifier, - evrp_range_analyzer *analyzer) +jump_threader::jump_threader (jump_threader_simplifier *simplifier, + jt_state *state) { /* Initialize the per SSA_NAME value-handles array. */ gcc_assert (!ssa_name_values.exists ()); @@ -73,11 +71,9 @@ jump_threader::jump_threader (const_and_copies *copies, dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node, integer_zero_node, NULL, NULL); - m_const_and_copies = copies; - m_avail_exprs_stack = avails; m_registry = new jump_thread_path_registry (); m_simplifier = simplifier; - m_evrp_range_analyzer = analyzer; + m_state = state; } jump_threader::~jump_threader (void) @@ -168,41 +164,7 @@ jump_threader::record_temporary_equivalences_from_phis (edge e) if (!virtual_operand_p (dst)) stmt_count++; - m_const_and_copies->record_const_or_copy (dst, src); - - /* Also update the value range associated with DST, using - the range from SRC. - - Note that even if SRC is a constant we need to set a suitable - output range so that VR_UNDEFINED ranges do not leak through. */ - if (m_evrp_range_analyzer) - { - /* Get an empty new VR we can pass to update_value_range and save - away in the VR stack. */ - value_range_equiv *new_vr - = m_evrp_range_analyzer->allocate_value_range_equiv (); - new (new_vr) value_range_equiv (); - - /* There are three cases to consider: - - First if SRC is an SSA_NAME, then we can copy the value - range from SRC into NEW_VR. - - Second if SRC is an INTEGER_CST, then we can just wet - NEW_VR to a singleton range. - - Otherwise set NEW_VR to varying. This may be overly - conservative. */ - if (TREE_CODE (src) == SSA_NAME) - new_vr->deep_copy (m_evrp_range_analyzer->get_value_range (src)); - else if (TREE_CODE (src) == INTEGER_CST) - new_vr->set (src); - else - new_vr->set_varying (TREE_TYPE (src)); - - /* This is a temporary range for DST, so push it. */ - m_evrp_range_analyzer->push_value_range (dst, new_vr); - } + m_state->register_equiv (dst, src, /*update_range=*/true); } return true; } @@ -304,10 +266,7 @@ jump_threader::record_temporary_equivalences_from_stmts_at_dest (edge e) return NULL; } - /* These are temporary ranges, do nto reflect them back into - the global range data. */ - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->record_ranges_from_stmt (stmt, true); + m_state->record_ranges_from_stmt (stmt, true); /* If this is not a statement that sets an SSA_NAME to a new value, then do not try to simplify this statement as it will @@ -408,7 +367,7 @@ jump_threader::record_temporary_equivalences_from_stmts_at_dest (edge e) SET_USE (use_p, tmp); } - cached_lhs = m_simplifier->simplify (stmt, stmt, e->src); + cached_lhs = m_simplifier->simplify (stmt, stmt, e->src, m_state); /* Restore the statement's original uses/defs. */ i = 0; @@ -422,8 +381,7 @@ jump_threader::record_temporary_equivalences_from_stmts_at_dest (edge e) if (cached_lhs && (TREE_CODE (cached_lhs) == SSA_NAME || is_gimple_min_invariant (cached_lhs))) - m_const_and_copies->record_const_or_copy (gimple_get_lhs (stmt), - cached_lhs); + m_state->register_equiv (gimple_get_lhs (stmt), cached_lhs); } return stmt; } @@ -552,11 +510,12 @@ jump_threader::simplify_control_stmt_condition (edge e, gimple *stmt) the label that is proven to be taken. */ gswitch *dummy_switch = as_a (gimple_copy (stmt)); gimple_switch_set_index (dummy_switch, cached_lhs); - cached_lhs = m_simplifier->simplify (dummy_switch, stmt, e->src); + cached_lhs = m_simplifier->simplify (dummy_switch, stmt, e->src, + m_state); ggc_free (dummy_switch); } else - cached_lhs = m_simplifier->simplify (stmt, stmt, e->src); + cached_lhs = m_simplifier->simplify (stmt, stmt, e->src, m_state); } /* We couldn't find an invariant. But, callers of this @@ -733,7 +692,7 @@ jump_threader::simplify_control_stmt_condition_1 then use the pass specific callback to simplify the condition. */ if (!res || !is_gimple_min_invariant (res)) - res = m_simplifier->simplify (dummy_cond, stmt, e->src); + res = m_simplifier->simplify (dummy_cond, stmt, e->src, m_state); return res; } @@ -880,9 +839,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src) If it is threadable, add it to PATH and VISITED and recurse, ultimately returning TRUE from the toplevel call. Otherwise do nothing and - return false. - - The available expression table is referenced via AVAIL_EXPRS_STACK. */ + return false. */ bool jump_threader::thread_around_empty_blocks (vec *path, @@ -997,12 +954,6 @@ jump_threader::thread_around_empty_blocks (vec *path, limited in that case to avoid short-circuiting the loop incorrectly. - STACK is used to undo temporary equivalences created during the walk of - E->dest. - - Our caller is responsible for restoring the state of the expression - and const_and_copies stacks. - Positive return value is success. Zero return value is failure, but the block can still be duplicated as a joiner in a jump thread path, negative indicates the block should not be duplicated and thus is not @@ -1012,8 +963,7 @@ int jump_threader::thread_through_normal_block (vec *path, edge e, bitmap visited) { - /* We want to record any equivalences created by traversing E. */ - record_temporary_equivalences (e, m_const_and_copies, m_avail_exprs_stack); + m_state->register_equivs_on_edge (e); /* PHIs create temporary equivalences. Note that if we found a PHI that made the block non-threadable, then @@ -1186,10 +1136,7 @@ jump_threader::thread_across_edge (edge e) { bitmap visited = BITMAP_ALLOC (NULL); - m_const_and_copies->push_marker (); - m_avail_exprs_stack->push_marker (); - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->push_marker (); + m_state->push (e); stmt_count = 0; @@ -1208,10 +1155,7 @@ jump_threader::thread_across_edge (edge e) { propagate_threaded_block_debug_into (path->last ()->e->dest, e->dest); - m_const_and_copies->pop_to_marker (); - m_avail_exprs_stack->pop_to_marker (); - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->pop_to_marker (); + m_state->pop (); BITMAP_FREE (visited); m_registry->register_jump_thread (path); return; @@ -1234,10 +1178,7 @@ jump_threader::thread_across_edge (edge e) if (threaded < 0) { BITMAP_FREE (visited); - m_const_and_copies->pop_to_marker (); - m_avail_exprs_stack->pop_to_marker (); - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->pop_to_marker (); + m_state->pop (); return; } } @@ -1263,10 +1204,7 @@ jump_threader::thread_across_edge (edge e) FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) if (taken_edge->flags & EDGE_COMPLEX) { - m_const_and_copies->pop_to_marker (); - m_avail_exprs_stack->pop_to_marker (); - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->pop_to_marker (); + m_state->pop (); BITMAP_FREE (visited); return; } @@ -1278,12 +1216,7 @@ jump_threader::thread_across_edge (edge e) || (taken_edge->flags & EDGE_DFS_BACK) != 0) continue; - /* Push a fresh marker so we can unwind the equivalences created - for each of E->dest's successors. */ - m_const_and_copies->push_marker (); - m_avail_exprs_stack->push_marker (); - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->push_marker (); + m_state->push (taken_edge); /* Avoid threading to any block we have already visited. */ bitmap_clear (visited); @@ -1320,19 +1253,12 @@ jump_threader::thread_across_edge (edge e) else path->release (); - /* And unwind the equivalence table. */ - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->pop_to_marker (); - m_avail_exprs_stack->pop_to_marker (); - m_const_and_copies->pop_to_marker (); + m_state->pop (); } BITMAP_FREE (visited); } - if (m_evrp_range_analyzer) - m_evrp_range_analyzer->pop_to_marker (); - m_const_and_copies->pop_to_marker (); - m_avail_exprs_stack->pop_to_marker (); + m_state->pop (); } /* Examine the outgoing edges from BB and conditionally @@ -1375,10 +1301,113 @@ jump_threader::thread_outgoing_edges (basic_block bb) } } +jt_state::jt_state (const_and_copies *copies, + avail_exprs_stack *exprs, + evrp_range_analyzer *evrp) +{ + m_copies = copies; + m_exprs = exprs; + m_evrp = evrp; +} + +// Record that E is being crossed. + +void +jt_state::push (edge) +{ + m_copies->push_marker (); + m_exprs->push_marker (); + if (m_evrp) + m_evrp->push_marker (); +} + +// Pop to the last pushed state. + +void +jt_state::pop () +{ + m_copies->pop_to_marker (); + m_exprs->pop_to_marker (); + if (m_evrp) + m_evrp->pop_to_marker (); +} + +// Record an equivalence from DST to SRC. If UPDATE_RANGE is TRUE, +// update the value range associated with DST. + +void +jt_state::register_equiv (tree dst, tree src, bool update_range) +{ + m_copies->record_const_or_copy (dst, src); + + /* If requested, update the value range associated with DST, using + the range from SRC. */ + if (m_evrp && update_range) + { + /* Get new VR we can pass to push_value_range. */ + value_range_equiv *new_vr = m_evrp->allocate_value_range_equiv (); + new (new_vr) value_range_equiv (); + + /* There are three cases to consider: + + First if SRC is an SSA_NAME, then we can copy the value range + from SRC into NEW_VR. + + Second if SRC is an INTEGER_CST, then we can just set NEW_VR + to a singleton range. Note that even if SRC is a constant we + need to set a suitable output range so that VR_UNDEFINED + ranges do not leak through. + + Otherwise set NEW_VR to varying. This may be overly + conservative. */ + if (TREE_CODE (src) == SSA_NAME) + new_vr->deep_copy (m_evrp->get_value_range (src)); + else if (TREE_CODE (src) == INTEGER_CST) + new_vr->set (src); + else + new_vr->set_varying (TREE_TYPE (src)); + + /* This is a temporary range for DST, so push it. */ + m_evrp->push_value_range (dst, new_vr); + } +} + +// Record any ranges calculated in STMT. If TEMPORARY is TRUE, then +// this is a temporary equivalence and should be recorded into the +// unwind table, instead of the global table. + +void +jt_state::record_ranges_from_stmt (gimple *stmt, bool temporary) +{ + if (m_evrp) + m_evrp->record_ranges_from_stmt (stmt, temporary); +} + +// Record any equivalences created by traversing E. + +void +jt_state::register_equivs_on_edge (edge e) +{ + record_temporary_equivalences (e, m_copies, m_exprs); +} + +jump_threader_simplifier::jump_threader_simplifier (vr_values *v) +{ + m_vr_values = v; +} + +// Return the singleton that resolves STMT, if it is possible to +// simplify it. +// +// STMT may be a dummy statement, not necessarily in the CFG, in which +// case WITHIN_STMT can be used to determine the position in the CFG +// where STMT should be evaluated as being in. + tree jump_threader_simplifier::simplify (gimple *stmt, gimple *within_stmt, - basic_block) + basic_block, + jt_state *) { if (gcond *cond_stmt = dyn_cast (stmt)) { diff --git a/gcc/tree-ssa-threadedge.h b/gcc/tree-ssa-threadedge.h index 48735f2bc27..c0d3c921e0f 100644 --- a/gcc/tree-ssa-threadedge.h +++ b/gcc/tree-ssa-threadedge.h @@ -20,6 +20,27 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_TREE_SSA_THREADEDGE_H #define GCC_TREE_SSA_THREADEDGE_H +// Class used to maintain path state in the jump threader and pass it +// to the jump threader simplifier. + +class jt_state +{ +public: + jt_state (class const_and_copies *, + class avail_exprs_stack *, + class evrp_range_analyzer *); + void push (edge); + void pop (); + void register_equiv (tree dest, tree src, bool update_range = false); + void register_equivs_on_edge (edge e); + void record_ranges_from_stmt (gimple *stmt, bool temporary); + +private: + const_and_copies *m_copies; + avail_exprs_stack *m_exprs; + evrp_range_analyzer *m_evrp; +}; + // This is the high level threader. The entry point is // thread_outgoing_edges(), which calculates and registers paths to be // threaded. When all candidates have been registered, @@ -28,10 +49,7 @@ along with GCC; see the file COPYING3. If not see class jump_threader { public: - jump_threader (class const_and_copies *, - avail_exprs_stack *, - class jump_threader_simplifier *, - class evrp_range_analyzer * = NULL); + jump_threader (class jump_threader_simplifier *, class jt_state *); ~jump_threader (); void thread_outgoing_edges (basic_block); void remove_jump_threads_including (edge_def *); @@ -57,11 +75,9 @@ private: // Dummy condition to avoid creating lots of throw away statements. gcond *dummy_cond; - const_and_copies *m_const_and_copies; - avail_exprs_stack *m_avail_exprs_stack; class jump_thread_path_registry *m_registry; jump_threader_simplifier *m_simplifier; - evrp_range_analyzer *m_evrp_range_analyzer; + jt_state *m_state; }; // Statement simplifier callback for the jump threader. @@ -69,17 +85,12 @@ private: class jump_threader_simplifier { public: - jump_threader_simplifier (class vr_values *v, - avail_exprs_stack *avails) - : m_vr_values (v), - m_avail_exprs_stack (avails) - { } + jump_threader_simplifier (class vr_values *v); virtual ~jump_threader_simplifier () { } - virtual tree simplify (gimple *, gimple *, basic_block); + virtual tree simplify (gimple *, gimple *, basic_block, jt_state *); protected: vr_values *m_vr_values; - avail_exprs_stack *m_avail_exprs_stack; }; extern void propagate_threaded_block_debug_into (basic_block, basic_block); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 58111f83183..d1b6910fcbb 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4165,16 +4165,18 @@ class vrp_jump_threader_simplifier : public jump_threader_simplifier { public: vrp_jump_threader_simplifier (vr_values *v, avail_exprs_stack *avails) - : jump_threader_simplifier (v, avails) {} + : jump_threader_simplifier (v), m_avail_exprs_stack (avails) { } private: - tree simplify (gimple *, gimple *, basic_block) OVERRIDE; + tree simplify (gimple *, gimple *, basic_block, jt_state *) OVERRIDE; + avail_exprs_stack *m_avail_exprs_stack; }; tree vrp_jump_threader_simplifier::simplify (gimple *stmt, gimple *within_stmt, - basic_block bb) + basic_block bb, + jt_state *state) { /* First see if the conditional is in the hash table. */ tree cached_lhs = m_avail_exprs_stack->lookup_avail_expr (stmt, false, true); @@ -4206,7 +4208,7 @@ vrp_jump_threader_simplifier::simplify (gimple *stmt, return find_case_label_range (switch_stmt, vr); } - return jump_threader_simplifier::simplify (stmt, within_stmt, bb); + return jump_threader_simplifier::simplify (stmt, within_stmt, bb, state); } /* Blocks which have more than one predecessor and more than @@ -4257,6 +4259,7 @@ private: hash_table *m_avail_exprs; vrp_jump_threader_simplifier *m_simplifier; jump_threader *m_threader; + jt_state *m_state; }; vrp_jump_threader::vrp_jump_threader (struct function *fun, vr_values *v) @@ -4282,11 +4285,11 @@ vrp_jump_threader::vrp_jump_threader (struct function *fun, vr_values *v) m_vr_values = v; m_avail_exprs = new hash_table (1024); m_avail_exprs_stack = new avail_exprs_stack (m_avail_exprs); + m_state = new jt_state (m_const_and_copies, m_avail_exprs_stack, NULL); m_simplifier = new vrp_jump_threader_simplifier (m_vr_values, m_avail_exprs_stack); - m_threader = new jump_threader (m_const_and_copies, m_avail_exprs_stack, - m_simplifier); + m_threader = new jump_threader (m_simplifier, m_state); } vrp_jump_threader::~vrp_jump_threader () @@ -4299,6 +4302,7 @@ vrp_jump_threader::~vrp_jump_threader () delete m_avail_exprs_stack; delete m_simplifier; delete m_threader; + delete m_state; } /* Called before processing dominator children of BB. We want to look -- 2.31.1