From 758eec73c9d0adf42f2b8330b15bd09a89f5472c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 25 Nov 2024 14:51:05 +0100 Subject: [PATCH] Revert "Generalize BFS" This reverts commit fbde591803ada158cacc11bc553e1b5061e59ae7. --- src/hotspot/share/opto/node.cpp | 28 --------- src/hotspot/share/opto/node.hpp | 85 +++++++-------------------- src/hotspot/share/opto/predicates.cpp | 13 ++-- 3 files changed, 28 insertions(+), 98 deletions(-) diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index e4d0609bcf7bd..3f82c47216303 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -3029,31 +3029,3 @@ const Type* TypeNode::Value(PhaseGVN* phase) const { return _type; } uint TypeNode::ideal_reg() const { return _type->ideal_reg(); } - -// Run the BFS starting from 'start_node' and apply the actions provided to this class. -void CustomNodeInputsBFS::run(Node* start_node) { - assert(_bfs_visit_input_strategy.should_visit_input(start_node), "start node must pass the visiting strategy"); - ResourceMark rm; - Unique_Node_List nodes_to_visit; - nodes_to_visit.push(start_node); - for (uint i = 0; i < nodes_to_visit.size(); i++) { - Node* next = nodes_to_visit[i]; - visit_inputs_of(next, nodes_to_visit); - } -} - -void CustomNodeInputsBFS::visit_inputs_of(const Node* node, Unique_Node_List& nodes_to_visit) { - for (uint i = _bfs_visit_input_strategy.start_input_index(node); i < node->req(); i++) { - Node* input = node->in(i); - if (!_bfs_visit_input_strategy.should_visit_input(input)) { - // Different *NodeInputsBFS classes can define different strategies - continue; - } - if (_bfs_actions.is_target_node(input)) { - assert(_bfs_actions.should_visit(input), "must also pass node filter"); - _bfs_actions.target_node_action(input); - } else if (_bfs_actions.should_visit(input)) { - nodes_to_visit.push(input); - } - } -} diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index a6889aa0f6512..47d8711eafd82 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -2111,8 +2111,8 @@ inline int Op_DivModIL(BasicType bt, bool is_unsigned) { } } -// Interface to define actions that should be taken when running a *NodeInputsBFS. Each use can extend this class to -// specify a customized BFS. +// Interface to define actions that should be taken when running DataNodeBFS. Each use can extend this class to specify +// a customized BFS. class BFSActions : public StackObj { public: // Should a node's inputs further be visited in the BFS traversal? By default, we visit all data inputs. Override this @@ -2130,72 +2130,31 @@ class BFSActions : public StackObj { virtual void target_node_action(Node* target_node) = 0; }; -// Interface to define the node input visiting strategy. This interface is only used for CustomNodeInputsBFS and their -// users. -class BFSInputVisitStrategy : public StackObj { - public: - // Should this input be visited? This method can fundamentally restrict a BFS, for example, if only data nodes should - // be visited. - virtual bool should_visit_input(const Node* input) const = 0; - - // This method returns the starting input index that should be visited when processing 'node'. - // Example implementations: - // - Only visiting data nodes? Return the constant index 1. - // - Visiting CFG nodes? Return index 0 but if 'node' is a Region, we should start at index 1. - virtual uint start_input_index(const Node* node) const = 0; -}; - -// Generic and customizable class to perform a BFS traversal on input nodes, dictated by the given BFSInputVisitStrategy, -// from a given start node. The provided BFSActions guide which of a visited node's inputs should be further visited, -// which nodes are target nodes and what to do with the target nodes. -// -// A user to traverse the node inputs of a graph is encouraged to first have a look at the common use cases covered by -// the specialized *NodeInputsBFS classes found below that use this class internally. For example, DataNodeInputsBFS -// only traverses data node inputs. -class CustomNodeInputsBFS : public StackObj { - // Strategy defined by different *NodeInputsBFS classes. - const BFSInputVisitStrategy& _bfs_visit_input_strategy; - - // BFS actions defined by a user of a *NodeInputsBFS class. +// Class to perform a BFS traversal on the data nodes from a given start node. The provided BFSActions guide which +// data node's inputs should be further visited, which data nodes are target nodes and what to do with the target nodes. +class DataNodeBFS : public StackObj { BFSActions& _bfs_actions; - void visit_inputs_of(const Node* node, Unique_Node_List& nodes_to_visit); - - public: - CustomNodeInputsBFS(const BFSInputVisitStrategy& bfs_input_visit_strategy, BFSActions& bfs_actions) - : _bfs_visit_input_strategy(bfs_input_visit_strategy), - _bfs_actions(bfs_actions) {} - - void run(Node* start_node); -}; - -// This class defines a data node visiting strategy for CustomNodeInputsBFS. -class BFSDataNodeInputVisitStrategy : public BFSInputVisitStrategy { public: - // Only visit data nodes. - bool should_visit_input(const Node* input) const override { - return !input->is_CFG(); - } - - // Data node inputs start at index 1 for data nodes. - uint start_input_index(const Node* node) const override { - return 1; - } -}; - -// Class to perform a BFS traversal on the data input nodes from a given start data node. The provided BFSActions guide -// which of a data node's inputs should be further visited, which data nodes are target nodes and what to do with the -// target nodes. -class DataNodeInputsBFS : public StackObj { - const BFSDataNodeInputVisitStrategy _bfs_data_node_input_visit_strategy; - CustomNodeInputsBFS _custom_node_inputs_bfs; - - public: - explicit DataNodeInputsBFS(BFSActions& bfs_actions) - : _custom_node_inputs_bfs(_bfs_data_node_input_visit_strategy, bfs_actions) {} + explicit DataNodeBFS(BFSActions& bfs_action) : _bfs_actions(bfs_action) {} + // Run the BFS starting from 'start_node' and apply the actions provided to this class. void run(Node* start_node) { - _custom_node_inputs_bfs.run(start_node); + ResourceMark rm; + Unique_Node_List _nodes_to_visit; + _nodes_to_visit.push(start_node); + for (uint i = 0; i < _nodes_to_visit.size(); i++) { + Node* next = _nodes_to_visit[i]; + for (uint j = 1; j < next->req(); j++) { + Node* input = next->in(j); + if (_bfs_actions.is_target_node(input)) { + assert(_bfs_actions.should_visit(input), "must also pass node filter"); + _bfs_actions.target_node_action(input); + } else if (_bfs_actions.should_visit(input)) { + _nodes_to_visit.push(input); + } + } + } } }; diff --git a/src/hotspot/share/opto/predicates.cpp b/src/hotspot/share/opto/predicates.cpp index cb5d8afb561cb..9e742f41612f9 100644 --- a/src/hotspot/share/opto/predicates.cpp +++ b/src/hotspot/share/opto/predicates.cpp @@ -211,7 +211,7 @@ class OpaqueLoopNodesVerifier : public BFSActions { // - Always an OpaqueLoopInitNode // - Only an OpaqueLoopStrideNode for the last value. void verify(const TemplateAssertionPredicate& template_assertion_predicate) { - DataNodeInputsBFS bfs(*this); + DataNodeBFS bfs(*this); bfs.run(template_assertion_predicate.opaque_node()); if (template_assertion_predicate.is_last_value()) { assert(_found_init && _found_stride, @@ -224,7 +224,7 @@ class OpaqueLoopNodesVerifier : public BFSActions { // An Initialized Assertion Predicate never has any OpaqueLoop*Nodes. void verify(const InitializedAssertionPredicate& initialized_assertion_predicate) { - DataNodeInputsBFS bfs(*this); + DataNodeBFS bfs(*this); bfs.run(initialized_assertion_predicate.opaque_node()); assert(!_found_init && !_found_stride, "must neither find OpaqueLoopInit nor OpaqueLoopStride for Initialized Assertion Predicate"); @@ -491,7 +491,7 @@ class ReplaceOpaqueStrideInput : public BFSActions { NONCOPYABLE(ReplaceOpaqueStrideInput); void replace_for(OpaqueTemplateAssertionPredicateNode* opaque_node) { - DataNodeInputsBFS bfs(*this); + DataNodeBFS bfs(*this); bfs.run(opaque_node); } @@ -905,10 +905,9 @@ IfTrueNode* CreateAssertionPredicatesVisitor::initialize_from_template( const TemplateAssertionPredicate& template_assertion_predicate) const { DEBUG_ONLY(template_assertion_predicate.verify();) IfNode* template_head = template_assertion_predicate.head(); - InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(_phase); - IfTrueNode* initialized_predicate = initialized_assertion_predicate_creator.create_from_template(template_head, - _new_control, - _init, _stride); + InitializedAssertionPredicateCreator initialized_assertion_predicate(_phase); + IfTrueNode* initialized_predicate = initialized_assertion_predicate.create_from_template(template_head,_new_control, + _init, _stride); DEBUG_ONLY(InitializedAssertionPredicate::verify(initialized_predicate);) template_assertion_predicate.rewire_loop_data_dependencies(initialized_predicate, _node_in_loop_body, _phase); return initialized_predicate;