comparison src/share/vm/opto/compile.cpp @ 168:7793bd37a336

6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops Summary: Generate addresses and implicit null checks with narrow oops to avoid decoding. Reviewed-by: jrose, never
author kvn
date Thu, 29 May 2008 12:04:14 -0700
parents c436414a719e
children 44abbb0d4c18
comparison
equal deleted inserted replaced
167:feeb96a45707 168:7793bd37a336
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(), "" );