Mercurial > hg > truffle
comparison src/share/vm/opto/memnode.cpp @ 628:7bb995fbd3c0
Merge
author | trims |
---|---|
date | Thu, 12 Mar 2009 18:16:36 -0700 |
parents | 0fbdb4381b99 337400e7a5dd |
children | fbde8ec322d0 |
comparison
equal
deleted
inserted
replaced
580:ce2272390558 | 628:7bb995fbd3c0 |
---|---|
98 Node *prev = NULL; | 98 Node *prev = NULL; |
99 Node *result = mchain; | 99 Node *result = mchain; |
100 while (prev != result) { | 100 while (prev != result) { |
101 prev = result; | 101 prev = result; |
102 if (result == start_mem) | 102 if (result == start_mem) |
103 break; // hit one of our sentinals | 103 break; // hit one of our sentinels |
104 // skip over a call which does not affect this memory slice | 104 // skip over a call which does not affect this memory slice |
105 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { | 105 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { |
106 Node *proj_in = result->in(0); | 106 Node *proj_in = result->in(0); |
107 if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { | 107 if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { |
108 break; // hit one of our sentinals | 108 break; // hit one of our sentinels |
109 } else if (proj_in->is_Call()) { | 109 } else if (proj_in->is_Call()) { |
110 CallNode *call = proj_in->as_Call(); | 110 CallNode *call = proj_in->as_Call(); |
111 if (!call->may_modify(t_adr, phase)) { | 111 if (!call->may_modify(t_adr, phase)) { |
112 result = call->in(TypeFunc::Memory); | 112 result = call->in(TypeFunc::Memory); |
113 } | 113 } |
196 tinst->offset() == Type::OffsetBot) ) { | 196 tinst->offset() == Type::OffsetBot) ) { |
197 // compress paths and change unreachable cycles to TOP | 197 // compress paths and change unreachable cycles to TOP |
198 // If not, we can update the input infinitely along a MergeMem cycle | 198 // If not, we can update the input infinitely along a MergeMem cycle |
199 // Equivalent code in PhiNode::Ideal | 199 // Equivalent code in PhiNode::Ideal |
200 Node* m = phase->transform(mmem); | 200 Node* m = phase->transform(mmem); |
201 // If tranformed to a MergeMem, get the desired slice | 201 // If transformed to a MergeMem, get the desired slice |
202 // Otherwise the returned node represents memory for every slice | 202 // Otherwise the returned node represents memory for every slice |
203 mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; | 203 mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; |
204 // Update input if it is progress over what we have now | 204 // Update input if it is progress over what we have now |
205 } | 205 } |
206 return mem; | 206 return mem; |
776 "use LoadKlassNode instead"); | 776 "use LoadKlassNode instead"); |
777 assert(!(adr_type->isa_aryptr() && | 777 assert(!(adr_type->isa_aryptr() && |
778 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), | 778 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), |
779 "use LoadRangeNode instead"); | 779 "use LoadRangeNode instead"); |
780 switch (bt) { | 780 switch (bt) { |
781 case T_BOOLEAN: | 781 case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); |
782 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); | 782 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); |
783 case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); | 783 case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); |
784 case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); | 784 case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); |
785 case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); | 785 case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); |
786 case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); | 786 case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); |
968 // usually runs first, producing the singleton type of the Con.) | 968 // usually runs first, producing the singleton type of the Con.) |
969 return value; | 969 return value; |
970 } | 970 } |
971 | 971 |
972 // Search for an existing data phi which was generated before for the same | 972 // Search for an existing data phi which was generated before for the same |
973 // instance's field to avoid infinite genertion of phis in a loop. | 973 // instance's field to avoid infinite generation of phis in a loop. |
974 Node *region = mem->in(0); | 974 Node *region = mem->in(0); |
975 if (is_instance_field_load_with_local_phi(region)) { | 975 if (is_instance_field_load_with_local_phi(region)) { |
976 const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); | 976 const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); |
977 int this_index = phase->C->get_alias_index(addr_t); | 977 int this_index = phase->C->get_alias_index(addr_t); |
978 int this_offset = addr_t->offset(); | 978 int this_offset = addr_t->offset(); |
1064 allocation_index = i; | 1064 allocation_index = i; |
1065 load_index = 3 - allocation_index; | 1065 load_index = 3 - allocation_index; |
1066 break; | 1066 break; |
1067 } | 1067 } |
1068 } | 1068 } |
1069 LoadNode* load = NULL; | 1069 bool has_load = ( allocation != NULL && |
1070 if (allocation != NULL && base->in(load_index)->is_Load()) { | 1070 (base->in(load_index)->is_Load() || |
1071 load = base->in(load_index)->as_Load(); | 1071 base->in(load_index)->is_DecodeN() && |
1072 } | 1072 base->in(load_index)->in(1)->is_Load()) ); |
1073 if (load != NULL && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) { | 1073 if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) { |
1074 // Push the loads from the phi that comes from valueOf up | 1074 // Push the loads from the phi that comes from valueOf up |
1075 // through it to allow elimination of the loads and the recovery | 1075 // through it to allow elimination of the loads and the recovery |
1076 // of the original value. | 1076 // of the original value. |
1077 Node* mem_phi = in(Memory); | 1077 Node* mem_phi = in(Memory); |
1078 Node* offset = in(Address)->in(AddPNode::Offset); | 1078 Node* offset = in(Address)->in(AddPNode::Offset); |
1104 PhiNode* result = PhiNode::make_blank(region, this); | 1104 PhiNode* result = PhiNode::make_blank(region, this); |
1105 result->set_req(allocation_index, in1); | 1105 result->set_req(allocation_index, in1); |
1106 result->set_req(load_index, in2); | 1106 result->set_req(load_index, in2); |
1107 return result; | 1107 return result; |
1108 } | 1108 } |
1109 } else if (base->is_Load()) { | 1109 } else if (base->is_Load() || |
1110 base->is_DecodeN() && base->in(1)->is_Load()) { | |
1111 if (base->is_DecodeN()) { | |
1112 // Get LoadN node which loads cached Integer object | |
1113 base = base->in(1); | |
1114 } | |
1110 // Eliminate the load of Integer.value for integers from the cache | 1115 // Eliminate the load of Integer.value for integers from the cache |
1111 // array by deriving the value from the index into the array. | 1116 // array by deriving the value from the index into the array. |
1112 // Capture the offset of the load and then reverse the computation. | 1117 // Capture the offset of the load and then reverse the computation. |
1113 Node* load_base = base->in(Address)->in(AddPNode::Base); | 1118 Node* load_base = base->in(Address)->in(AddPNode::Base); |
1119 if (load_base->is_DecodeN()) { | |
1120 // Get LoadN node which loads IntegerCache.cache field | |
1121 load_base = load_base->in(1); | |
1122 } | |
1114 if (load_base != NULL) { | 1123 if (load_base != NULL) { |
1115 Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type()); | 1124 Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type()); |
1116 intptr_t cache_offset; | 1125 intptr_t cache_offset; |
1117 int shift = -1; | 1126 int shift = -1; |
1118 Node* cache = NULL; | 1127 Node* cache = NULL; |
1243 // Make sure that the type array is big enough for | 1252 // Make sure that the type array is big enough for |
1244 // our new node, even though we may throw the node away. | 1253 // our new node, even though we may throw the node away. |
1245 // (This tweaking with igvn only works because x is a new node.) | 1254 // (This tweaking with igvn only works because x is a new node.) |
1246 igvn->set_type(x, t); | 1255 igvn->set_type(x, t); |
1247 // If x is a TypeNode, capture any more-precise type permanently into Node | 1256 // If x is a TypeNode, capture any more-precise type permanently into Node |
1248 // othewise it will be not updated during igvn->transform since | 1257 // otherwise it will be not updated during igvn->transform since |
1249 // igvn->type(x) is set to x->Value() already. | 1258 // igvn->type(x) is set to x->Value() already. |
1250 x->raise_bottom_type(t); | 1259 x->raise_bottom_type(t); |
1251 Node *y = x->Identity(igvn); | 1260 Node *y = x->Identity(igvn); |
1252 if( y != x ) { | 1261 if( y != x ) { |
1253 wins++; | 1262 wins++; |
1605 } | 1614 } |
1606 // Identity call will handle the case where truncation is not needed. | 1615 // Identity call will handle the case where truncation is not needed. |
1607 return LoadNode::Ideal(phase, can_reshape); | 1616 return LoadNode::Ideal(phase, can_reshape); |
1608 } | 1617 } |
1609 | 1618 |
1619 //--------------------------LoadUBNode::Ideal------------------------------------- | |
1620 // | |
1621 // If the previous store is to the same address as this load, | |
1622 // and the value stored was larger than a byte, replace this load | |
1623 // with the value stored truncated to a byte. If no truncation is | |
1624 // needed, the replacement is done in LoadNode::Identity(). | |
1625 // | |
1626 Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) { | |
1627 Node* mem = in(MemNode::Memory); | |
1628 Node* value = can_see_stored_value(mem, phase); | |
1629 if (value && !phase->type(value)->higher_equal(_type)) | |
1630 return new (phase->C, 3) AndINode(value, phase->intcon(0xFF)); | |
1631 // Identity call will handle the case where truncation is not needed. | |
1632 return LoadNode::Ideal(phase, can_reshape); | |
1633 } | |
1634 | |
1610 //--------------------------LoadUSNode::Ideal------------------------------------- | 1635 //--------------------------LoadUSNode::Ideal------------------------------------- |
1611 // | 1636 // |
1612 // If the previous store is to the same address as this load, | 1637 // If the previous store is to the same address as this load, |
1613 // and the value stored was larger than a char, replace this load | 1638 // and the value stored was larger than a char, replace this load |
1614 // with the value stored truncated to a char. If no truncation is | 1639 // with the value stored truncated to a char. If no truncation is |
2580 // may also be created at that point to represent any required zeroing. | 2605 // may also be created at that point to represent any required zeroing. |
2581 // The InitializeNode is then marked 'complete', prohibiting further | 2606 // The InitializeNode is then marked 'complete', prohibiting further |
2582 // capturing of nearby memory operations. | 2607 // capturing of nearby memory operations. |
2583 // | 2608 // |
2584 // During macro-expansion, all captured initializations which store | 2609 // During macro-expansion, all captured initializations which store |
2585 // constant values of 32 bits or smaller are coalesced (if advantagous) | 2610 // constant values of 32 bits or smaller are coalesced (if advantageous) |
2586 // into larger 'tiles' 32 or 64 bits. This allows an object to be | 2611 // into larger 'tiles' 32 or 64 bits. This allows an object to be |
2587 // initialized in fewer memory operations. Memory words which are | 2612 // initialized in fewer memory operations. Memory words which are |
2588 // covered by neither tiles nor non-constant stores are pre-zeroed | 2613 // covered by neither tiles nor non-constant stores are pre-zeroed |
2589 // by explicit stores of zero. (The code shape happens to do all | 2614 // by explicit stores of zero. (The code shape happens to do all |
2590 // zeroing first, then all other stores, with both sequences occurring | 2615 // zeroing first, then all other stores, with both sequences occurring |
3667 new_mem = (new_base == this || new_base == empty_mem)? empty_mem : new_base; | 3692 new_mem = (new_base == this || new_base == empty_mem)? empty_mem : new_base; |
3668 } | 3693 } |
3669 else if (old_mmem != NULL) { | 3694 else if (old_mmem != NULL) { |
3670 new_mem = old_mmem->memory_at(i); | 3695 new_mem = old_mmem->memory_at(i); |
3671 } | 3696 } |
3672 // else preceeding memory was not a MergeMem | 3697 // else preceding memory was not a MergeMem |
3673 | 3698 |
3674 // replace equivalent phis (unfortunately, they do not GVN together) | 3699 // replace equivalent phis (unfortunately, they do not GVN together) |
3675 if (new_mem != NULL && new_mem != new_base && | 3700 if (new_mem != NULL && new_mem != new_base && |
3676 new_mem->req() == phi_len && new_mem->in(0) == phi_reg) { | 3701 new_mem->req() == phi_len && new_mem->in(0) == phi_reg) { |
3677 if (new_mem->is_Phi()) { | 3702 if (new_mem->is_Phi()) { |