1840 |
1840 |
1841 //------------------------------final_graph_reshaping_impl---------------------- |
1841 //------------------------------final_graph_reshaping_impl---------------------- |
1842 // Implement items 1-5 from final_graph_reshaping below. |
1842 // Implement items 1-5 from final_graph_reshaping below. |
1843 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { |
1843 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { |
1844 |
1844 |
|
1845 if ( n->outcnt() == 0 ) return; // dead node |
1845 uint nop = n->Opcode(); |
1846 uint nop = n->Opcode(); |
1846 |
1847 |
1847 // Check for 2-input instruction with "last use" on right input. |
1848 // Check for 2-input instruction with "last use" on right input. |
1848 // Swap to left input. Implements item (2). |
1849 // Swap to left input. Implements item (2). |
1849 if( n->req() == 3 && // two-input instruction |
1850 if( n->req() == 3 && // two-input instruction |
1906 case Op_CmpD3: |
1907 case Op_CmpD3: |
1907 fpu.inc_double_count(); |
1908 fpu.inc_double_count(); |
1908 break; |
1909 break; |
1909 case Op_Opaque1: // Remove Opaque Nodes before matching |
1910 case Op_Opaque1: // Remove Opaque Nodes before matching |
1910 case Op_Opaque2: // Remove Opaque Nodes before matching |
1911 case Op_Opaque2: // Remove Opaque Nodes before matching |
1911 n->replace_by(n->in(1)); |
1912 n->subsume_by(n->in(1)); |
1912 break; |
1913 break; |
1913 case Op_CallStaticJava: |
1914 case Op_CallStaticJava: |
1914 case Op_CallJava: |
1915 case Op_CallJava: |
1915 case Op_CallDynamicJava: |
1916 case Op_CallDynamicJava: |
1916 fpu.inc_java_call_count(); // Count java call site; |
1917 fpu.inc_java_call_count(); // Count java call site; |
1999 break; |
2000 break; |
2000 } |
2001 } |
2001 |
2002 |
2002 #ifdef _LP64 |
2003 #ifdef _LP64 |
2003 case Op_CmpP: |
2004 case Op_CmpP: |
2004 if( n->in(1)->Opcode() == Op_DecodeN ) { |
2005 // Do this transformation here to preserve CmpPNode::sub() and |
|
2006 // other TypePtr related Ideal optimizations (for example, ptr nullness). |
|
2007 if( n->in(1)->is_DecodeN() ) { |
2005 Compile* C = Compile::current(); |
2008 Compile* C = Compile::current(); |
2006 Node* in2 = NULL; |
2009 Node* in2 = NULL; |
2007 if( n->in(2)->Opcode() == Op_DecodeN ) { |
2010 if( n->in(2)->is_DecodeN() ) { |
2008 in2 = n->in(2)->in(1); |
2011 in2 = n->in(2)->in(1); |
2009 } else if ( n->in(2)->Opcode() == Op_ConP ) { |
2012 } else if ( n->in(2)->Opcode() == Op_ConP ) { |
2010 const Type* t = n->in(2)->bottom_type(); |
2013 const Type* t = n->in(2)->bottom_type(); |
2011 if (t == TypePtr::NULL_PTR) { |
2014 if (t == TypePtr::NULL_PTR) { |
2012 Node *in1 = n->in(1); |
2015 Node *in1 = n->in(1); |
2013 uint i = 0; |
2016 if (Matcher::clone_shift_expressions) { |
2014 for (; i < in1->outcnt(); i++) { |
2017 // x86, ARM and friends can handle 2 adds in addressing mode. |
2015 if (in1->raw_out(i)->is_AddP()) |
2018 // Decode a narrow oop and do implicit NULL check in address |
2016 break; |
2019 // [R12 + narrow_oop_reg<<3 + offset] |
2017 } |
2020 in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
2018 if (i >= in1->outcnt()) { |
2021 } else { |
2019 // Don't replace CmpP(o ,null) if 'o' is used in AddP |
2022 // Don't replace CmpP(o ,null) if 'o' is used in AddP |
2020 // to generate implicit NULL check. |
2023 // to generate implicit NULL check on Sparc where |
2021 in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
2024 // narrow oops can't be used in address. |
|
2025 uint i = 0; |
|
2026 for (; i < in1->outcnt(); i++) { |
|
2027 if (in1->raw_out(i)->is_AddP()) |
|
2028 break; |
|
2029 } |
|
2030 if (i >= in1->outcnt()) { |
|
2031 in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
|
2032 } |
2022 } |
2033 } |
2023 } else if (t->isa_oopptr()) { |
2034 } else if (t->isa_oopptr()) { |
2024 in2 = ConNode::make(C, t->is_oopptr()->make_narrowoop()); |
2035 in2 = ConNode::make(C, t->is_oopptr()->make_narrowoop()); |
2025 } |
2036 } |
2026 } |
2037 } |
2027 if( in2 != NULL ) { |
2038 if( in2 != NULL ) { |
2028 Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2); |
2039 Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2); |
2029 n->replace_by( cmpN ); |
2040 n->subsume_by( cmpN ); |
2030 } |
2041 } |
2031 } |
2042 } |
2032 #endif |
2043 #endif |
2033 |
2044 |
2034 case Op_ModI: |
2045 case Op_ModI: |
2038 if (d) { |
2049 if (d) { |
2039 // Replace them with a fused divmod if supported |
2050 // Replace them with a fused divmod if supported |
2040 Compile* C = Compile::current(); |
2051 Compile* C = Compile::current(); |
2041 if (Matcher::has_match_rule(Op_DivModI)) { |
2052 if (Matcher::has_match_rule(Op_DivModI)) { |
2042 DivModINode* divmod = DivModINode::make(C, n); |
2053 DivModINode* divmod = DivModINode::make(C, n); |
2043 d->replace_by(divmod->div_proj()); |
2054 d->subsume_by(divmod->div_proj()); |
2044 n->replace_by(divmod->mod_proj()); |
2055 n->subsume_by(divmod->mod_proj()); |
2045 } else { |
2056 } else { |
2046 // replace a%b with a-((a/b)*b) |
2057 // replace a%b with a-((a/b)*b) |
2047 Node* mult = new (C, 3) MulINode(d, d->in(2)); |
2058 Node* mult = new (C, 3) MulINode(d, d->in(2)); |
2048 Node* sub = new (C, 3) SubINode(d->in(1), mult); |
2059 Node* sub = new (C, 3) SubINode(d->in(1), mult); |
2049 n->replace_by( sub ); |
2060 n->subsume_by( sub ); |
2050 } |
2061 } |
2051 } |
2062 } |
2052 } |
2063 } |
2053 break; |
2064 break; |
2054 |
2065 |
2059 if (d) { |
2070 if (d) { |
2060 // Replace them with a fused divmod if supported |
2071 // Replace them with a fused divmod if supported |
2061 Compile* C = Compile::current(); |
2072 Compile* C = Compile::current(); |
2062 if (Matcher::has_match_rule(Op_DivModL)) { |
2073 if (Matcher::has_match_rule(Op_DivModL)) { |
2063 DivModLNode* divmod = DivModLNode::make(C, n); |
2074 DivModLNode* divmod = DivModLNode::make(C, n); |
2064 d->replace_by(divmod->div_proj()); |
2075 d->subsume_by(divmod->div_proj()); |
2065 n->replace_by(divmod->mod_proj()); |
2076 n->subsume_by(divmod->mod_proj()); |
2066 } else { |
2077 } else { |
2067 // replace a%b with a-((a/b)*b) |
2078 // replace a%b with a-((a/b)*b) |
2068 Node* mult = new (C, 3) MulLNode(d, d->in(2)); |
2079 Node* mult = new (C, 3) MulLNode(d, d->in(2)); |
2069 Node* sub = new (C, 3) SubLNode(d->in(1), mult); |
2080 Node* sub = new (C, 3) SubLNode(d->in(1), mult); |
2070 n->replace_by( sub ); |
2081 n->subsume_by( sub ); |
2071 } |
2082 } |
2072 } |
2083 } |
2073 } |
2084 } |
2074 break; |
2085 break; |
2075 |
2086 |
2111 case Op_PackD: |
2122 case Op_PackD: |
2112 if (n->req()-1 > 2) { |
2123 if (n->req()-1 > 2) { |
2113 // Replace many operand PackNodes with a binary tree for matching |
2124 // Replace many operand PackNodes with a binary tree for matching |
2114 PackNode* p = (PackNode*) n; |
2125 PackNode* p = (PackNode*) n; |
2115 Node* btp = p->binaryTreePack(Compile::current(), 1, n->req()); |
2126 Node* btp = p->binaryTreePack(Compile::current(), 1, n->req()); |
2116 n->replace_by(btp); |
2127 n->subsume_by(btp); |
2117 } |
2128 } |
2118 break; |
2129 break; |
2119 default: |
2130 default: |
2120 assert( !n->is_Call(), "" ); |
2131 assert( !n->is_Call(), "" ); |
2121 assert( !n->is_Mem(), "" ); |
2132 assert( !n->is_Mem(), "" ); |