Mercurial > hg > graal-compiler
comparison src/share/vm/opto/matcher.cpp @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | eac007780a58 |
children | 885ed790ecf0 |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
28 OptoReg::Name OptoReg::c_frame_pointer; | 28 OptoReg::Name OptoReg::c_frame_pointer; |
29 | 29 |
30 | 30 |
31 | 31 |
32 const int Matcher::base2reg[Type::lastype] = { | 32 const int Matcher::base2reg[Type::lastype] = { |
33 Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, | 33 Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN, |
34 Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */ | 34 Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */ |
35 Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */ | 35 Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */ |
36 0, 0/*abio*/, | 36 0, 0/*abio*/, |
37 Op_RegP /* Return address */, 0, /* the memories */ | 37 Op_RegP /* Return address */, 0, /* the memories */ |
38 Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD, | 38 Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD, |
68 _shared(&_states_arena), | 68 _shared(&_states_arena), |
69 _dontcare(&_states_arena) { | 69 _dontcare(&_states_arena) { |
70 C->set_matcher(this); | 70 C->set_matcher(this); |
71 | 71 |
72 idealreg2spillmask[Op_RegI] = NULL; | 72 idealreg2spillmask[Op_RegI] = NULL; |
73 idealreg2spillmask[Op_RegN] = NULL; | |
73 idealreg2spillmask[Op_RegL] = NULL; | 74 idealreg2spillmask[Op_RegL] = NULL; |
74 idealreg2spillmask[Op_RegF] = NULL; | 75 idealreg2spillmask[Op_RegF] = NULL; |
75 idealreg2spillmask[Op_RegD] = NULL; | 76 idealreg2spillmask[Op_RegD] = NULL; |
76 idealreg2spillmask[Op_RegP] = NULL; | 77 idealreg2spillmask[Op_RegP] = NULL; |
77 | 78 |
78 idealreg2debugmask[Op_RegI] = NULL; | 79 idealreg2debugmask[Op_RegI] = NULL; |
80 idealreg2debugmask[Op_RegN] = NULL; | |
79 idealreg2debugmask[Op_RegL] = NULL; | 81 idealreg2debugmask[Op_RegL] = NULL; |
80 idealreg2debugmask[Op_RegF] = NULL; | 82 idealreg2debugmask[Op_RegF] = NULL; |
81 idealreg2debugmask[Op_RegD] = NULL; | 83 idealreg2debugmask[Op_RegD] = NULL; |
82 idealreg2debugmask[Op_RegP] = NULL; | 84 idealreg2debugmask[Op_RegP] = NULL; |
83 } | 85 } |
364 // Disallow any debug info in outgoing argument areas by setting the | 366 // Disallow any debug info in outgoing argument areas by setting the |
365 // initial mask accordingly. | 367 // initial mask accordingly. |
366 void Matcher::init_first_stack_mask() { | 368 void Matcher::init_first_stack_mask() { |
367 | 369 |
368 // Allocate storage for spill masks as masks for the appropriate load type. | 370 // Allocate storage for spill masks as masks for the appropriate load type. |
369 RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask)*10); | 371 RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask)*12); |
370 idealreg2spillmask[Op_RegI] = &rms[0]; | 372 idealreg2spillmask[Op_RegN] = &rms[0]; |
371 idealreg2spillmask[Op_RegL] = &rms[1]; | 373 idealreg2spillmask[Op_RegI] = &rms[1]; |
372 idealreg2spillmask[Op_RegF] = &rms[2]; | 374 idealreg2spillmask[Op_RegL] = &rms[2]; |
373 idealreg2spillmask[Op_RegD] = &rms[3]; | 375 idealreg2spillmask[Op_RegF] = &rms[3]; |
374 idealreg2spillmask[Op_RegP] = &rms[4]; | 376 idealreg2spillmask[Op_RegD] = &rms[4]; |
375 idealreg2debugmask[Op_RegI] = &rms[5]; | 377 idealreg2spillmask[Op_RegP] = &rms[5]; |
376 idealreg2debugmask[Op_RegL] = &rms[6]; | 378 idealreg2debugmask[Op_RegN] = &rms[6]; |
377 idealreg2debugmask[Op_RegF] = &rms[7]; | 379 idealreg2debugmask[Op_RegI] = &rms[7]; |
378 idealreg2debugmask[Op_RegD] = &rms[8]; | 380 idealreg2debugmask[Op_RegL] = &rms[8]; |
379 idealreg2debugmask[Op_RegP] = &rms[9]; | 381 idealreg2debugmask[Op_RegF] = &rms[9]; |
382 idealreg2debugmask[Op_RegD] = &rms[10]; | |
383 idealreg2debugmask[Op_RegP] = &rms[11]; | |
380 | 384 |
381 OptoReg::Name i; | 385 OptoReg::Name i; |
382 | 386 |
383 // At first, start with the empty mask | 387 // At first, start with the empty mask |
384 C->FIRST_STACK_mask().Clear(); | 388 C->FIRST_STACK_mask().Clear(); |
397 | 401 |
398 // Finally, set the "infinite stack" bit. | 402 // Finally, set the "infinite stack" bit. |
399 C->FIRST_STACK_mask().set_AllStack(); | 403 C->FIRST_STACK_mask().set_AllStack(); |
400 | 404 |
401 // Make spill masks. Registers for their class, plus FIRST_STACK_mask. | 405 // Make spill masks. Registers for their class, plus FIRST_STACK_mask. |
406 #ifdef _LP64 | |
407 *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN]; | |
408 idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask()); | |
409 #endif | |
402 *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI]; | 410 *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI]; |
403 idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask()); | 411 idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask()); |
404 *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL]; | 412 *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL]; |
405 idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask()); | 413 idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask()); |
406 *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF]; | 414 *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF]; |
411 idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask()); | 419 idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask()); |
412 | 420 |
413 // Make up debug masks. Any spill slot plus callee-save registers. | 421 // Make up debug masks. Any spill slot plus callee-save registers. |
414 // Caller-save registers are assumed to be trashable by the various | 422 // Caller-save registers are assumed to be trashable by the various |
415 // inline-cache fixup routines. | 423 // inline-cache fixup routines. |
424 *idealreg2debugmask[Op_RegN]= *idealreg2spillmask[Op_RegN]; | |
416 *idealreg2debugmask[Op_RegI]= *idealreg2spillmask[Op_RegI]; | 425 *idealreg2debugmask[Op_RegI]= *idealreg2spillmask[Op_RegI]; |
417 *idealreg2debugmask[Op_RegL]= *idealreg2spillmask[Op_RegL]; | 426 *idealreg2debugmask[Op_RegL]= *idealreg2spillmask[Op_RegL]; |
418 *idealreg2debugmask[Op_RegF]= *idealreg2spillmask[Op_RegF]; | 427 *idealreg2debugmask[Op_RegF]= *idealreg2spillmask[Op_RegF]; |
419 *idealreg2debugmask[Op_RegD]= *idealreg2spillmask[Op_RegD]; | 428 *idealreg2debugmask[Op_RegD]= *idealreg2spillmask[Op_RegD]; |
420 *idealreg2debugmask[Op_RegP]= *idealreg2spillmask[Op_RegP]; | 429 *idealreg2debugmask[Op_RegP]= *idealreg2spillmask[Op_RegP]; |
426 for( i=OptoReg::Name(0); i<OptoReg::Name(_last_Mach_Reg); i = OptoReg::add(i,1) ) { | 435 for( i=OptoReg::Name(0); i<OptoReg::Name(_last_Mach_Reg); i = OptoReg::add(i,1) ) { |
427 // registers the caller has to save do not work | 436 // registers the caller has to save do not work |
428 if( _register_save_policy[i] == 'C' || | 437 if( _register_save_policy[i] == 'C' || |
429 _register_save_policy[i] == 'A' || | 438 _register_save_policy[i] == 'A' || |
430 (_register_save_policy[i] == 'E' && exclude_soe) ) { | 439 (_register_save_policy[i] == 'E' && exclude_soe) ) { |
440 idealreg2debugmask[Op_RegN]->Remove(i); | |
431 idealreg2debugmask[Op_RegI]->Remove(i); // Exclude save-on-call | 441 idealreg2debugmask[Op_RegI]->Remove(i); // Exclude save-on-call |
432 idealreg2debugmask[Op_RegL]->Remove(i); // registers from debug | 442 idealreg2debugmask[Op_RegL]->Remove(i); // registers from debug |
433 idealreg2debugmask[Op_RegF]->Remove(i); // masks | 443 idealreg2debugmask[Op_RegF]->Remove(i); // masks |
434 idealreg2debugmask[Op_RegD]->Remove(i); | 444 idealreg2debugmask[Op_RegD]->Remove(i); |
435 idealreg2debugmask[Op_RegP]->Remove(i); | 445 idealreg2debugmask[Op_RegP]->Remove(i); |
659 const TypePtr* atp = TypePtr::BOTTOM; | 669 const TypePtr* atp = TypePtr::BOTTOM; |
660 // Share frame pointer while making spill ops | 670 // Share frame pointer while making spill ops |
661 set_shared(fp); | 671 set_shared(fp); |
662 | 672 |
663 // Compute generic short-offset Loads | 673 // Compute generic short-offset Loads |
674 #ifdef _LP64 | |
675 MachNode *spillCP = match_tree(new (C, 3) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); | |
676 #endif | |
664 MachNode *spillI = match_tree(new (C, 3) LoadINode(NULL,mem,fp,atp)); | 677 MachNode *spillI = match_tree(new (C, 3) LoadINode(NULL,mem,fp,atp)); |
665 MachNode *spillL = match_tree(new (C, 3) LoadLNode(NULL,mem,fp,atp)); | 678 MachNode *spillL = match_tree(new (C, 3) LoadLNode(NULL,mem,fp,atp)); |
666 MachNode *spillF = match_tree(new (C, 3) LoadFNode(NULL,mem,fp,atp)); | 679 MachNode *spillF = match_tree(new (C, 3) LoadFNode(NULL,mem,fp,atp)); |
667 MachNode *spillD = match_tree(new (C, 3) LoadDNode(NULL,mem,fp,atp)); | 680 MachNode *spillD = match_tree(new (C, 3) LoadDNode(NULL,mem,fp,atp)); |
668 MachNode *spillP = match_tree(new (C, 3) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); | 681 MachNode *spillP = match_tree(new (C, 3) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); |
669 assert(spillI != NULL && spillL != NULL && spillF != NULL && | 682 assert(spillI != NULL && spillL != NULL && spillF != NULL && |
670 spillD != NULL && spillP != NULL, ""); | 683 spillD != NULL && spillP != NULL, ""); |
671 | 684 |
672 // Get the ADLC notion of the right regmask, for each basic type. | 685 // Get the ADLC notion of the right regmask, for each basic type. |
686 #ifdef _LP64 | |
687 idealreg2regmask[Op_RegN] = &spillCP->out_RegMask(); | |
688 #endif | |
673 idealreg2regmask[Op_RegI] = &spillI->out_RegMask(); | 689 idealreg2regmask[Op_RegI] = &spillI->out_RegMask(); |
674 idealreg2regmask[Op_RegL] = &spillL->out_RegMask(); | 690 idealreg2regmask[Op_RegL] = &spillL->out_RegMask(); |
675 idealreg2regmask[Op_RegF] = &spillF->out_RegMask(); | 691 idealreg2regmask[Op_RegF] = &spillF->out_RegMask(); |
676 idealreg2regmask[Op_RegD] = &spillD->out_RegMask(); | 692 idealreg2regmask[Op_RegD] = &spillD->out_RegMask(); |
677 idealreg2regmask[Op_RegP] = &spillP->out_RegMask(); | 693 idealreg2regmask[Op_RegP] = &spillP->out_RegMask(); |
1224 if( x == m->in(0) ) // Does 'control' post-dominate | 1240 if( x == m->in(0) ) // Does 'control' post-dominate |
1225 break; // m->in(0)? If so, we can use it | 1241 break; // m->in(0)? If so, we can use it |
1226 } | 1242 } |
1227 if( j == max_scan ) // No post-domination before scan end? | 1243 if( j == max_scan ) // No post-domination before scan end? |
1228 return true; // Then break the match tree up | 1244 return true; // Then break the match tree up |
1245 } | |
1246 | |
1247 if (m->Opcode() == Op_DecodeN && m->outcnt() == 2) { | |
1248 // These are commonly used in address expressions and can | |
1249 // efficiently fold into them in some cases but because they are | |
1250 // consumed by AddP they commonly have two users. | |
1251 if (m->raw_out(0) == m->raw_out(1) && m->raw_out(0)->Opcode() == Op_AddP) return false; | |
1229 } | 1252 } |
1230 } | 1253 } |
1231 | 1254 |
1232 // Not forceably cloning. If shared, put it into a register. | 1255 // Not forceably cloning. If shared, put it into a register. |
1233 return shared; | 1256 return shared; |
1712 case Op_StoreD: | 1735 case Op_StoreD: |
1713 case Op_StoreF: | 1736 case Op_StoreF: |
1714 case Op_StoreI: | 1737 case Op_StoreI: |
1715 case Op_StoreL: | 1738 case Op_StoreL: |
1716 case Op_StoreP: | 1739 case Op_StoreP: |
1740 case Op_StoreN: | |
1717 case Op_Store16B: | 1741 case Op_Store16B: |
1718 case Op_Store8B: | 1742 case Op_Store8B: |
1719 case Op_Store4B: | 1743 case Op_Store4B: |
1720 case Op_Store8C: | 1744 case Op_Store8C: |
1721 case Op_Store4C: | 1745 case Op_Store4C: |
1737 case Op_LoadI: | 1761 case Op_LoadI: |
1738 case Op_LoadKlass: | 1762 case Op_LoadKlass: |
1739 case Op_LoadL: | 1763 case Op_LoadL: |
1740 case Op_LoadS: | 1764 case Op_LoadS: |
1741 case Op_LoadP: | 1765 case Op_LoadP: |
1766 case Op_LoadN: | |
1742 case Op_LoadRange: | 1767 case Op_LoadRange: |
1743 case Op_LoadD_unaligned: | 1768 case Op_LoadD_unaligned: |
1744 case Op_LoadL_unaligned: | 1769 case Op_LoadL_unaligned: |
1745 case Op_Load16B: | 1770 case Op_Load16B: |
1746 case Op_Load8B: | 1771 case Op_Load8B: |
1851 switch( n->Opcode() ) { // Handle some opcodes special | 1876 switch( n->Opcode() ) { // Handle some opcodes special |
1852 case Op_StorePConditional: | 1877 case Op_StorePConditional: |
1853 case Op_StoreLConditional: | 1878 case Op_StoreLConditional: |
1854 case Op_CompareAndSwapI: | 1879 case Op_CompareAndSwapI: |
1855 case Op_CompareAndSwapL: | 1880 case Op_CompareAndSwapL: |
1856 case Op_CompareAndSwapP: { // Convert trinary to binary-tree | 1881 case Op_CompareAndSwapP: |
1882 case Op_CompareAndSwapN: { // Convert trinary to binary-tree | |
1857 Node *newval = n->in(MemNode::ValueIn ); | 1883 Node *newval = n->in(MemNode::ValueIn ); |
1858 Node *oldval = n->in(LoadStoreNode::ExpectedIn); | 1884 Node *oldval = n->in(LoadStoreNode::ExpectedIn); |
1859 Node *pair = new (C, 3) BinaryNode( oldval, newval ); | 1885 Node *pair = new (C, 3) BinaryNode( oldval, newval ); |
1860 n->set_req(MemNode::ValueIn,pair); | 1886 n->set_req(MemNode::ValueIn,pair); |
1861 n->del_req(LoadStoreNode::ExpectedIn); | 1887 n->del_req(LoadStoreNode::ExpectedIn); |
1903 Node *iff = proj->in(0); | 1929 Node *iff = proj->in(0); |
1904 if( iff->Opcode() == Op_If ) { | 1930 if( iff->Opcode() == Op_If ) { |
1905 // During matching If's have Bool & Cmp side-by-side | 1931 // During matching If's have Bool & Cmp side-by-side |
1906 BoolNode *b = iff->in(1)->as_Bool(); | 1932 BoolNode *b = iff->in(1)->as_Bool(); |
1907 Node *cmp = iff->in(2); | 1933 Node *cmp = iff->in(2); |
1908 if( cmp->Opcode() == Op_CmpP ) { | 1934 int opc = cmp->Opcode(); |
1909 if( cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { | 1935 if (opc != Op_CmpP && opc != Op_CmpN) return; |
1910 | 1936 |
1911 if( proj->Opcode() == Op_IfTrue ) { | 1937 const Type* ct = cmp->in(2)->bottom_type(); |
1912 extern int all_null_checks_found; | 1938 if (ct == TypePtr::NULL_PTR || |
1913 all_null_checks_found++; | 1939 (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) { |
1914 if( b->_test._test == BoolTest::ne ) { | 1940 |
1915 _null_check_tests.push(proj); | 1941 if( proj->Opcode() == Op_IfTrue ) { |
1916 _null_check_tests.push(cmp->in(1)); | 1942 extern int all_null_checks_found; |
1917 } | 1943 all_null_checks_found++; |
1918 } else { | 1944 if( b->_test._test == BoolTest::ne ) { |
1919 assert( proj->Opcode() == Op_IfFalse, "" ); | 1945 _null_check_tests.push(proj); |
1920 if( b->_test._test == BoolTest::eq ) { | 1946 _null_check_tests.push(cmp->in(1)); |
1921 _null_check_tests.push(proj); | 1947 } |
1922 _null_check_tests.push(cmp->in(1)); | 1948 } else { |
1923 } | 1949 assert( proj->Opcode() == Op_IfFalse, "" ); |
1950 if( b->_test._test == BoolTest::eq ) { | |
1951 _null_check_tests.push(proj); | |
1952 _null_check_tests.push(cmp->in(1)); | |
1924 } | 1953 } |
1925 } | 1954 } |
1926 } | 1955 } |
1927 } | 1956 } |
1928 } | 1957 } |
2036 | 2065 |
2037 if (xop == Op_MemBarVolatile || | 2066 if (xop == Op_MemBarVolatile || |
2038 xop == Op_FastLock || | 2067 xop == Op_FastLock || |
2039 xop == Op_CompareAndSwapL || | 2068 xop == Op_CompareAndSwapL || |
2040 xop == Op_CompareAndSwapP || | 2069 xop == Op_CompareAndSwapP || |
2070 xop == Op_CompareAndSwapN || | |
2041 xop == Op_CompareAndSwapI) | 2071 xop == Op_CompareAndSwapI) |
2042 return true; | 2072 return true; |
2043 | 2073 |
2044 if (x->is_MemBar()) { | 2074 if (x->is_MemBar()) { |
2045 // We must retain this membar if there is an upcoming volatile | 2075 // We must retain this membar if there is an upcoming volatile |