hotspot/src/share/vm/opto/memnode.cpp
changeset 2034 ca0ff0c51e3b
parent 2008 898493b2e3f1
parent 2022 28ce8115a91d
child 2109 f472b58223b5
child 2105 347008ce7984
equal deleted inserted replaced
2013:49e915da0905 2034:ca0ff0c51e3b
   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:
   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) LoadCNode(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()   );
   787   case T_FLOAT:   return new (C, 3) LoadFNode(ctl, mem, adr, adr_type, rt              );
   787   case T_FLOAT:   return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt              );
   788   case T_DOUBLE:  return new (C, 3) LoadDNode(ctl, mem, adr, adr_type, rt              );
   788   case T_DOUBLE:  return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt              );
   789   case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr()    );
   789   case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
   790   case T_OBJECT:
   790   case T_OBJECT:
   791 #ifdef _LP64
   791 #ifdef _LP64
   792     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
   792     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
   793       Node* load  = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
   793       Node* load  = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
   794       return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
   794       return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
  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);
       
  1079       Node* region = base->in(0);
  1079 
  1080 
  1080       Node* in1 = clone();
  1081       Node* in1 = clone();
  1081       Node* in1_addr = in1->in(Address)->clone();
  1082       Node* in1_addr = in1->in(Address)->clone();
  1082       in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
  1083       in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
  1083       in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
  1084       in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
  1084       in1_addr->set_req(AddPNode::Offset, offset);
  1085       in1_addr->set_req(AddPNode::Offset, offset);
  1085       in1->set_req(0, base->in(allocation_index));
  1086       in1->set_req(0, region->in(allocation_index));
  1086       in1->set_req(Address, in1_addr);
  1087       in1->set_req(Address, in1_addr);
  1087       in1->set_req(Memory, mem_phi->in(allocation_index));
  1088       in1->set_req(Memory, mem_phi->in(allocation_index));
  1088 
  1089 
  1089       Node* in2 = clone();
  1090       Node* in2 = clone();
  1090       Node* in2_addr = in2->in(Address)->clone();
  1091       Node* in2_addr = in2->in(Address)->clone();
  1091       in2_addr->set_req(AddPNode::Base, base->in(load_index));
  1092       in2_addr->set_req(AddPNode::Base, base->in(load_index));
  1092       in2_addr->set_req(AddPNode::Address, base->in(load_index));
  1093       in2_addr->set_req(AddPNode::Address, base->in(load_index));
  1093       in2_addr->set_req(AddPNode::Offset, offset);
  1094       in2_addr->set_req(AddPNode::Offset, offset);
  1094       in2->set_req(0, base->in(load_index));
  1095       in2->set_req(0, region->in(load_index));
  1095       in2->set_req(Address, in2_addr);
  1096       in2->set_req(Address, in2_addr);
  1096       in2->set_req(Memory, mem_phi->in(load_index));
  1097       in2->set_req(Memory, mem_phi->in(load_index));
  1097 
  1098 
  1098       in1_addr = phase->transform(in1_addr);
  1099       in1_addr = phase->transform(in1_addr);
  1099       in1 =      phase->transform(in1);
  1100       in1 =      phase->transform(in1);
  1100       in2_addr = phase->transform(in2_addr);
  1101       in2_addr = phase->transform(in2_addr);
  1101       in2 =      phase->transform(in2);
  1102       in2 =      phase->transform(in2);
  1102 
  1103 
  1103       PhiNode* result = PhiNode::make_blank(base->in(0), this);
  1104       PhiNode* result = PhiNode::make_blank(region, this);
  1104       result->set_req(allocation_index, in1);
  1105       result->set_req(allocation_index, in1);
  1105       result->set_req(load_index, in2);
  1106       result->set_req(load_index, in2);
  1106       return result;
  1107       return result;
  1107     }
  1108     }
  1108   } else if (base->is_Load()) {
  1109   } else if (base->is_Load()) {
  1355   // fold up, do so.
  1356   // fold up, do so.
  1356   Node* prev_mem = find_previous_store(phase);
  1357   Node* prev_mem = find_previous_store(phase);
  1357   // Steps (a), (b):  Walk past independent stores to find an exact match.
  1358   // Steps (a), (b):  Walk past independent stores to find an exact match.
  1358   if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
  1359   if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
  1359     // (c) See if we can fold up on the spot, but don't fold up here.
  1360     // (c) See if we can fold up on the spot, but don't fold up here.
  1360     // Fold-up might require truncation (for LoadB/LoadS/LoadC) or
  1361     // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or
  1361     // just return a prior value, which is done by Identity calls.
  1362     // just return a prior value, which is done by Identity calls.
  1362     if (can_see_stored_value(prev_mem, phase)) {
  1363     if (can_see_stored_value(prev_mem, phase)) {
  1363       // Make ready for step (d):
  1364       // Make ready for step (d):
  1364       set_req(MemNode::Memory, prev_mem);
  1365       set_req(MemNode::Memory, prev_mem);
  1365       return this;
  1366       return this;
  1604   }
  1605   }
  1605   // Identity call will handle the case where truncation is not needed.
  1606   // Identity call will handle the case where truncation is not needed.
  1606   return LoadNode::Ideal(phase, can_reshape);
  1607   return LoadNode::Ideal(phase, can_reshape);
  1607 }
  1608 }
  1608 
  1609 
  1609 //--------------------------LoadCNode::Ideal--------------------------------------
  1610 //--------------------------LoadUSNode::Ideal-------------------------------------
  1610 //
  1611 //
  1611 //  If the previous store is to the same address as this load,
  1612 //  If the previous store is to the same address as this load,
  1612 //  and the value stored was larger than a char, replace this load
  1613 //  and the value stored was larger than a char, replace this load
  1613 //  with the value stored truncated to a char.  If no truncation is
  1614 //  with the value stored truncated to a char.  If no truncation is
  1614 //  needed, the replacement is done in LoadNode::Identity().
  1615 //  needed, the replacement is done in LoadNode::Identity().
  1615 //
  1616 //
  1616 Node *LoadCNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1617 Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1617   Node* mem = in(MemNode::Memory);
  1618   Node* mem = in(MemNode::Memory);
  1618   Node* value = can_see_stored_value(mem,phase);
  1619   Node* value = can_see_stored_value(mem,phase);
  1619   if( value && !phase->type(value)->higher_equal( _type ) )
  1620   if( value && !phase->type(value)->higher_equal( _type ) )
  1620     return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF));
  1621     return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF));
  1621   // Identity call will handle the case where truncation is not needed.
  1622   // Identity call will handle the case where truncation is not needed.