@@ -6012,80 +6012,88 @@ void PhaseIdealLoop::dump_bad_graph(const char* msg, Node* n, Node* early, Node*
60126012 }
60136013 }
60146014 }
6015- tty->cr ();
6016- tty->print_cr (" idoms of early %d:" , early->_idx );
6017- dump_idom (early);
6018- tty->cr ();
6019- tty->print_cr (" idoms of (wrong) LCA %d:" , LCA->_idx );
6020- dump_idom (LCA);
6021- tty->cr ();
6022- dump_real_LCA (early, LCA);
6015+ dump_idoms (early, LCA);
60236016 tty->cr ();
60246017}
60256018
6026- // Find the real LCA of early and the wrongly assumed LCA.
6027- void PhaseIdealLoop::dump_real_LCA (Node* early, Node* wrong_lca) {
6028- assert (!is_dominator (early, wrong_lca) && !is_dominator (early, wrong_lca),
6029- " sanity check that one node does not dominate the other" );
6030- assert (!has_ctrl (early) && !has_ctrl (wrong_lca), " sanity check, no data nodes" );
6019+ // Class to compute the real LCA given an early node and a wrong LCA in a bad graph.
6020+ class RealLCA {
6021+ const PhaseIdealLoop* _phase;
6022+ Node* _early;
6023+ Node* _wrong_lca;
6024+ uint _early_index;
6025+ int _wrong_lca_index;
6026+
6027+ // Given idom chains of early and wrong LCA: Walk through idoms starting at StartNode and find the first node which
6028+ // is different: Return the previously visited node which must be the real LCA.
6029+ // The node lists also contain _early and _wrong_lca, respectively.
6030+ Node* find_real_lca (Unique_Node_List& early_with_idoms, Unique_Node_List& wrong_lca_with_idoms) {
6031+ int early_index = early_with_idoms.size () - 1 ;
6032+ int wrong_lca_index = wrong_lca_with_idoms.size () - 1 ;
6033+ bool found_difference = false ;
6034+ do {
6035+ if (early_with_idoms[early_index] != wrong_lca_with_idoms[wrong_lca_index]) {
6036+ // First time early and wrong LCA idoms differ. Real LCA must be at the previous index.
6037+ found_difference = true ;
6038+ break ;
6039+ }
6040+ early_index--;
6041+ wrong_lca_index--;
6042+ } while (wrong_lca_index >= 0 );
60316043
6032- ResourceMark rm;
6033- Node_List nodes_seen;
6034- Node* real_LCA = NULL ;
6035- Node* n1 = wrong_lca;
6036- Node* n2 = early;
6037- uint count_1 = 0 ;
6038- uint count_2 = 0 ;
6039- // Add early and wrong_lca to simplify calculation of idom indices
6040- nodes_seen.push (n1);
6041- nodes_seen.push (n2);
6042-
6043- // Walk the idom chain up from early and wrong_lca and stop when they intersect.
6044- while (!n1->is_Start () && !n2->is_Start ()) {
6045- n1 = idom (n1);
6046- n2 = idom (n2);
6047- if (n1 == n2) {
6048- // Both idom chains intersect at the same index
6049- real_LCA = n1;
6050- count_1 = nodes_seen.size () / 2 ;
6051- count_2 = count_1;
6052- break ;
6053- }
6054- if (check_idom_chains_intersection (n1, count_1, count_2, &nodes_seen)) {
6055- real_LCA = n1;
6056- break ;
6057- }
6058- if (check_idom_chains_intersection (n2, count_2, count_1, &nodes_seen)) {
6059- real_LCA = n2;
6060- break ;
6061- }
6062- nodes_seen.push (n1);
6063- nodes_seen.push (n2);
6044+ assert (early_index >= 0 , " must always find an LCA - cannot be early" );
6045+ _early_index = early_index;
6046+ _wrong_lca_index = wrong_lca_index;
6047+ Node* real_lca = early_with_idoms[_early_index + 1 ]; // Plus one to skip _early.
6048+ assert (found_difference || real_lca == _wrong_lca, " wrong LCA dominates early and is therefore the real LCA" );
6049+ return real_lca;
60646050 }
60656051
6066- assert (real_LCA != NULL , " must always find an LCA " );
6067- tty-> print_cr ( " Real LCA of early %d (idom[%d]) and (wrong) LCA %d (idom[%d]): " , early-> _idx , count_2, wrong_lca-> _idx , count_1 );
6068- real_LCA-> dump ( );
6069- }
6052+ void dump (Node* real_lca) {
6053+ tty-> cr ( );
6054+ tty-> print_cr ( " idoms of early \" %d %s \" : " , _early-> _idx , _early-> Name () );
6055+ _phase-> dump_idom (_early, _early_index + 1 );
60706056
6071- // Check if n is already on nodes_seen (i.e. idom chains of early and wrong_lca intersect at n). Determine the idom index of n
6072- // on both idom chains and return them in idom_idx_new and idom_idx_other, respectively.
6073- bool PhaseIdealLoop::check_idom_chains_intersection (const Node* n, uint& idom_idx_new, uint& idom_idx_other, const Node_List* nodes_seen) const {
6074- if (nodes_seen->contains (n)) {
6075- // The idom chain has just discovered n.
6076- // Divide by 2 because nodes_seen contains the same amount of nodes from both chains.
6077- idom_idx_new = nodes_seen->size () / 2 ;
6078-
6079- // The other chain already contained n. Search the index.
6080- for (uint i = 0 ; i < nodes_seen->size (); i++) {
6081- if (nodes_seen->at (i) == n) {
6082- // Divide by 2 because nodes_seen contains the same amount of nodes from both chains.
6083- idom_idx_other = i / 2 ;
6084- }
6057+ tty->cr ();
6058+ tty->print_cr (" idoms of (wrong) LCA \" %d %s\" :" , _wrong_lca->_idx , _wrong_lca->Name ());
6059+ _phase->dump_idom (_wrong_lca, _wrong_lca_index + 1 );
6060+
6061+ tty->cr ();
6062+ tty->print (" Real LCA of early \" %d %s\" (idom[%d]) and wrong LCA \" %d %s\" " ,
6063+ _early->_idx , _early->Name (), _early_index, _wrong_lca->_idx , _wrong_lca->Name ());
6064+ if (_wrong_lca_index >= 0 ) {
6065+ tty->print (" (idom[%d])" , _wrong_lca_index);
60856066 }
6086- return true ;
6067+ tty->print_cr (" :" );
6068+ real_lca->dump ();
60876069 }
6088- return false ;
6070+
6071+ public:
6072+ RealLCA (const PhaseIdealLoop* phase, Node* early, Node* wrong_lca)
6073+ : _phase(phase), _early(early), _wrong_lca(wrong_lca), _early_index(0 ), _wrong_lca_index(0 ) {
6074+ assert (!wrong_lca->is_Start (), " StartNode is always a common dominator" );
6075+ }
6076+
6077+ void compute_and_dump () {
6078+ ResourceMark rm;
6079+ Unique_Node_List early_with_idoms;
6080+ Unique_Node_List wrong_lca_with_idoms;
6081+ early_with_idoms.push (_early);
6082+ wrong_lca_with_idoms.push (_wrong_lca);
6083+ _phase->get_idoms (_early, 10000 , early_with_idoms);
6084+ _phase->get_idoms (_wrong_lca, 10000 , wrong_lca_with_idoms);
6085+ Node* real_lca = find_real_lca (early_with_idoms, wrong_lca_with_idoms);
6086+ dump (real_lca);
6087+ }
6088+ };
6089+
6090+ // Dump the idom chain of early, of the wrong LCA and dump the real LCA of early and wrong LCA.
6091+ void PhaseIdealLoop::dump_idoms (Node* early, Node* wrong_lca) {
6092+ assert (!is_dominator (early, wrong_lca), " sanity check that early does not dominate wrong lca" );
6093+ assert (!has_ctrl (early) && !has_ctrl (wrong_lca), " sanity check, no data nodes" );
6094+
6095+ RealLCA real_lca (this , early, wrong_lca);
6096+ real_lca.compute_and_dump ();
60896097}
60906098#endif // ASSERT
60916099
@@ -6158,16 +6166,38 @@ void PhaseIdealLoop::dump(IdealLoopTree* loop, uint idx, Node_List &rpo_list) co
61586166 }
61596167}
61606168
6161- void PhaseIdealLoop::dump_idom (Node* n) const {
6169+ void PhaseIdealLoop::dump_idom (Node* n, const uint count ) const {
61626170 if (has_ctrl (n)) {
61636171 tty->print_cr (" No idom for data nodes" );
61646172 } else {
6165- for (int i = 0 ; i < 100 && !n->is_Start (); i++) {
6166- tty->print (" idom[%d] " , i);
6167- n->dump ();
6168- n = idom (n);
6173+ ResourceMark rm;
6174+ Unique_Node_List idoms;
6175+ get_idoms (n, count, idoms);
6176+ dump_idoms_in_reverse (n, idoms);
6177+ }
6178+ }
6179+
6180+ void PhaseIdealLoop::get_idoms (Node* n, const uint count, Unique_Node_List& idoms) const {
6181+ Node* next = n;
6182+ for (uint i = 0 ; !next->is_Start () && i < count; i++) {
6183+ next = idom (next);
6184+ assert (!idoms.member (next), " duplicated idom is not possible" );
6185+ idoms.push (next);
6186+ }
6187+ }
6188+
6189+ void PhaseIdealLoop::dump_idoms_in_reverse (const Node* n, const Node_List& idom_list) const {
6190+ Node* next;
6191+ uint padding = 3 ;
6192+ uint node_index_padding_width = static_cast <int >(log10 (C->unique ())) + 1 ;
6193+ for (int i = idom_list.size () - 1 ; i >= 0 ; i--) {
6194+ if (i == 9 || i == 99 ) {
6195+ padding++;
61696196 }
6197+ next = idom_list[i];
6198+ tty->print_cr (" idom[%d]:%*c%*d %s" , i, padding, ' ' , node_index_padding_width, next->_idx , next->Name ());
61706199 }
6200+ tty->print_cr (" n: %*c%*d %s" , padding, ' ' , node_index_padding_width, n->_idx , n->Name ());
61716201}
61726202#endif // NOT PRODUCT
61736203
0 commit comments