src/share/vm/opto/memnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8034812 Cdiff src/share/vm/opto/memnode.cpp

src/share/vm/opto/memnode.cpp

Print this page

        

*** 906,948 **** assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw || // oop will be recorded in oop map if load crosses safepoint rt->isa_oopptr() || is_immutable_value(adr), "raw memory operations should have control edge"); switch (bt) { ! case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_BYTE: return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_INT: return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_CHAR: return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_SHORT: return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_LONG: return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo); ! case T_FLOAT: return new (C) LoadFNode (ctl, mem, adr, adr_type, rt, mo); ! case T_DOUBLE: return new (C) LoadDNode (ctl, mem, adr, adr_type, rt, mo); ! case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo); case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { ! Node* load = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo)); ! return new (C) DecodeNNode(load, load->bottom_type()->make_ptr()); } else #endif { assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop"); ! return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo); } } ShouldNotReachHere(); return (LoadNode*)NULL; } LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; ! return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic); } LoadDNode* LoadDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; ! return new (C) LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic); } //------------------------------hash------------------------------------------- --- 906,948 ---- assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw || // oop will be recorded in oop map if load crosses safepoint rt->isa_oopptr() || is_immutable_value(adr), "raw memory operations should have control edge"); switch (bt) { ! case T_BOOLEAN: return new LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_BYTE: return new LoadBNode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_INT: return new LoadINode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_CHAR: return new LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_SHORT: return new LoadSNode (ctl, mem, adr, adr_type, rt->is_int(), mo); ! case T_LONG: return new LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo); ! case T_FLOAT: return new LoadFNode (ctl, mem, adr, adr_type, rt, mo); ! case T_DOUBLE: return new LoadDNode (ctl, mem, adr, adr_type, rt, mo); ! case T_ADDRESS: return new LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(), mo); case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { ! Node* load = gvn.transform(new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo)); ! return new DecodeNNode(load, load->bottom_type()->make_ptr()); } else #endif { assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop"); ! return new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo); } } ShouldNotReachHere(); return (LoadNode*)NULL; } LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; ! return new LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic); } LoadDNode* LoadDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) { bool require_atomic = true; ! return new LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic); } //------------------------------hash-------------------------------------------
*** 1226,1262 **** return NULL; // should not happen since cache is array indexed by value } // Add up all the offsets making of the address of the load Node* result = elements[0]; for (int i = 1; i < count; i++) { ! result = phase->transform(new (phase->C) AddXNode(result, elements[i])); } // Remove the constant offset from the address and then ! result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-(int)offset))); // remove the scaling of the offset to recover the original index. if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { // Peel the shift off directly but wrap it in a dummy node // since Ideal can't return existing nodes ! result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0)); } else if (result->is_Add() && result->in(2)->is_Con() && result->in(1)->Opcode() == Op_LShiftX && result->in(1)->in(2) == phase->intcon(shift)) { // We can't do general optimization: ((X<<Z) + Y) >> Z ==> X + (Y>>Z) // but for boxing cache access we know that X<<Z will not overflow // (there is range check) so we do this optimizatrion by hand here. ! Node* add_con = new (phase->C) RShiftXNode(result->in(2), phase->intcon(shift)); ! result = new (phase->C) AddXNode(result->in(1)->in(1), phase->transform(add_con)); } else { ! result = new (phase->C) RShiftXNode(result, phase->intcon(shift)); } #ifdef _LP64 if (bt != T_LONG) { ! result = new (phase->C) ConvL2INode(phase->transform(result)); } #else if (bt == T_LONG) { ! result = new (phase->C) ConvI2LNode(phase->transform(result)); } #endif return result; } } --- 1226,1262 ---- return NULL; // should not happen since cache is array indexed by value } // Add up all the offsets making of the address of the load Node* result = elements[0]; for (int i = 1; i < count; i++) { ! result = phase->transform(new AddXNode(result, elements[i])); } // Remove the constant offset from the address and then ! result = phase->transform(new AddXNode(result, phase->MakeConX(-(int)offset))); // remove the scaling of the offset to recover the original index. if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { // Peel the shift off directly but wrap it in a dummy node // since Ideal can't return existing nodes ! result = new RShiftXNode(result->in(1), phase->intcon(0)); } else if (result->is_Add() && result->in(2)->is_Con() && result->in(1)->Opcode() == Op_LShiftX && result->in(1)->in(2) == phase->intcon(shift)) { // We can't do general optimization: ((X<<Z) + Y) >> Z ==> X + (Y>>Z) // but for boxing cache access we know that X<<Z will not overflow // (there is range check) so we do this optimizatrion by hand here. ! Node* add_con = new RShiftXNode(result->in(2), phase->intcon(shift)); ! result = new AddXNode(result->in(1)->in(1), phase->transform(add_con)); } else { ! result = new RShiftXNode(result, phase->intcon(shift)); } #ifdef _LP64 if (bt != T_LONG) { ! result = new ConvL2INode(phase->transform(result)); } #else if (bt == T_LONG) { ! result = new ConvI2LNode(phase->transform(result)); } #endif return result; } }
*** 1383,1393 **** if (!t_oop->is_known_instance() && load_boxed_values) { // Use _idx of address base for boxed values. this_iid = base->_idx; } PhaseIterGVN* igvn = phase->is_IterGVN(); ! Node* phi = new (C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); for (uint i = 1; i < region->req(); i++) { Node* x; Node* the_clone = NULL; if (region->in(i) == C->top()) { x = C->top(); // Dead path? Use a dead data op --- 1383,1393 ---- if (!t_oop->is_known_instance() && load_boxed_values) { // Use _idx of address base for boxed values. this_iid = base->_idx; } PhaseIterGVN* igvn = phase->is_IterGVN(); ! Node* phi = new PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); for (uint i = 1; i < region->req(); i++) { Node* x; Node* the_clone = NULL; if (region->in(i) == C->top()) { x = C->top(); // Dead path? Use a dead data op
*** 1406,1416 **** if (address->is_Phi() && address->in(0) == region) { x->set_req(Address, address->in(i)); // Use pre-Phi input for the clone } if (base_is_phi && (base->in(0) == region)) { Node* base_x = base->in(i); // Clone address for loads from boxed objects. ! Node* adr_x = phase->transform(new (C) AddPNode(base_x,base_x,address->in(AddPNode::Offset))); x->set_req(Address, adr_x); } } // Check for a 'win' on some paths const Type *t = x->Value(igvn); --- 1406,1416 ---- if (address->is_Phi() && address->in(0) == region) { x->set_req(Address, address->in(i)); // Use pre-Phi input for the clone } if (base_is_phi && (base->in(0) == region)) { Node* base_x = base->in(i); // Clone address for loads from boxed objects. ! Node* adr_x = phase->transform(new AddPNode(base_x,base_x,address->in(AddPNode::Offset))); x->set_req(Address, adr_x); } } // Check for a 'win' on some paths const Type *t = x->Value(igvn);
*** 1895,1906 **** // Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { ! Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(24)) ); ! return new (phase->C) RShiftINode(result, phase->intcon(24)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } --- 1895,1906 ---- // Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { ! Node *result = phase->transform( new LShiftINode(value, phase->intcon(24)) ); ! return new RShiftINode(result, phase->intcon(24)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); }
*** 1927,1937 **** // Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem, phase); if (value && !phase->type(value)->higher_equal(_type)) ! return new (phase->C) AndINode(value, phase->intcon(0xFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } const Type* LoadUBNode::Value(PhaseTransform *phase) const { --- 1927,1937 ---- // Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem, phase); if (value && !phase->type(value)->higher_equal(_type)) ! return new AndINode(value, phase->intcon(0xFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } const Type* LoadUBNode::Value(PhaseTransform *phase) const {
*** 1957,1967 **** // Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) ! return new (phase->C) AndINode(value,phase->intcon(0xFFFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } const Type* LoadUSNode::Value(PhaseTransform *phase) const { --- 1957,1967 ---- // Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) ! return new AndINode(value,phase->intcon(0xFFFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } const Type* LoadUSNode::Value(PhaseTransform *phase) const {
*** 1987,1998 **** // Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { ! Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(16)) ); ! return new (phase->C) RShiftINode(result, phase->intcon(16)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } --- 1987,1998 ---- // Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { ! Node *result = phase->transform( new LShiftINode(value, phase->intcon(16)) ); ! return new RShiftINode(result, phase->intcon(16)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); }
*** 2020,2035 **** const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { assert(UseCompressedClassPointers, "no compressed klasses"); ! Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); ! return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } #endif assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); ! return new (C) LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered); } //------------------------------Value------------------------------------------ const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { return klass_value_common(phase); --- 2020,2035 ---- const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { assert(UseCompressedClassPointers, "no compressed klasses"); ! Node* load_klass = gvn.transform(new LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); ! return new DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } #endif assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); ! return new LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered); } //------------------------------Value------------------------------------------ const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { return klass_value_common(phase);
*** 2253,2263 **** const Type *t = phase->type( x ); if( t == Type::TOP ) return x; if( t->isa_narrowklass()) return x; assert (!t->isa_narrowoop(), "no narrow oop here"); ! return phase->transform(new (phase->C) EncodePKlassNode(x, t->make_narrowklass())); } //------------------------------Value----------------------------------------- const Type *LoadRangeNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP --- 2253,2263 ---- const Type *t = phase->type( x ); if( t == Type::TOP ) return x; if( t->isa_narrowklass()) return x; assert (!t->isa_narrowoop(), "no narrow oop here"); ! return phase->transform(new EncodePKlassNode(x, t->make_narrowklass())); } //------------------------------Value----------------------------------------- const Type *LoadRangeNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP
*** 2348,2394 **** assert(C->get_alias_index(adr_type) != Compile::AliasIdxRaw || ctl != NULL, "raw memory operations should have control edge"); switch (bt) { case T_BOOLEAN: ! case T_BYTE: return new (C) StoreBNode(ctl, mem, adr, adr_type, val, mo); ! case T_INT: return new (C) StoreINode(ctl, mem, adr, adr_type, val, mo); case T_CHAR: ! case T_SHORT: return new (C) StoreCNode(ctl, mem, adr, adr_type, val, mo); ! case T_LONG: return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo); ! case T_FLOAT: return new (C) StoreFNode(ctl, mem, adr, adr_type, val, mo); ! case T_DOUBLE: return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo); case T_METADATA: case T_ADDRESS: case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { ! val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop())); ! return new (C) StoreNNode(ctl, mem, adr, adr_type, val, mo); } else if (adr->bottom_type()->is_ptr_to_narrowklass() || (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { ! val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); ! return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val, mo); } #endif { ! return new (C) StorePNode(ctl, mem, adr, adr_type, val, mo); } } ShouldNotReachHere(); return (StoreNode*)NULL; } StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; ! return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } StoreDNode* StoreDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; ! return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } //--------------------------bottom_type---------------------------------------- const Type *StoreNode::bottom_type() const { --- 2348,2394 ---- assert(C->get_alias_index(adr_type) != Compile::AliasIdxRaw || ctl != NULL, "raw memory operations should have control edge"); switch (bt) { case T_BOOLEAN: ! case T_BYTE: return new StoreBNode(ctl, mem, adr, adr_type, val, mo); ! case T_INT: return new StoreINode(ctl, mem, adr, adr_type, val, mo); case T_CHAR: ! case T_SHORT: return new StoreCNode(ctl, mem, adr, adr_type, val, mo); ! case T_LONG: return new StoreLNode(ctl, mem, adr, adr_type, val, mo); ! case T_FLOAT: return new StoreFNode(ctl, mem, adr, adr_type, val, mo); ! case T_DOUBLE: return new StoreDNode(ctl, mem, adr, adr_type, val, mo); case T_METADATA: case T_ADDRESS: case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { ! val = gvn.transform(new EncodePNode(val, val->bottom_type()->make_narrowoop())); ! return new StoreNNode(ctl, mem, adr, adr_type, val, mo); } else if (adr->bottom_type()->is_ptr_to_narrowklass() || (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { ! val = gvn.transform(new EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); ! return new StoreNKlassNode(ctl, mem, adr, adr_type, val, mo); } #endif { ! return new StorePNode(ctl, mem, adr, adr_type, val, mo); } } ShouldNotReachHere(); return (StoreNode*)NULL; } StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; ! return new StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } StoreDNode* StoreDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) { bool require_atomic = true; ! return new StoreDNode(ctl, mem, adr, adr_type, val, mo, require_atomic); } //--------------------------bottom_type---------------------------------------- const Type *StoreNode::bottom_type() const {
*** 2777,2792 **** if( adr->Opcode() != Op_AddP ) Unimplemented(); Node *base = adr->in(1); Node *zero = phase->makecon(TypeLong::ZERO); Node *off = phase->MakeConX(BytesPerLong); ! mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); count--; while( count-- ) { mem = phase->transform(mem); ! adr = phase->transform(new (phase->C) AddPNode(base,adr,off)); ! mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); } return mem; } //----------------------------step_through---------------------------------- --- 2777,2792 ---- if( adr->Opcode() != Op_AddP ) Unimplemented(); Node *base = adr->in(1); Node *zero = phase->makecon(TypeLong::ZERO); Node *off = phase->MakeConX(BytesPerLong); ! mem = new StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); count--; while( count-- ) { mem = phase->transform(mem); ! adr = phase->transform(new AddPNode(base,adr,off)); ! mem = new StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false); } return mem; } //----------------------------step_through----------------------------------
*** 2823,2833 **** Compile* C = phase->C; intptr_t offset = start_offset; int unit = BytesPerLong; if ((offset % unit) != 0) { ! Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); mem = phase->transform(mem); offset += BytesPerInt; --- 2823,2833 ---- Compile* C = phase->C; intptr_t offset = start_offset; int unit = BytesPerLong; if ((offset % unit) != 0) { ! Node* adr = new AddPNode(dest, dest, phase->MakeConX(offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); mem = phase->transform(mem); offset += BytesPerInt;
*** 2853,2870 **** Node* zend = end_offset; // Scale to the unit required by the CPU: if (!Matcher::init_array_count_is_in_bytes) { Node* shift = phase->intcon(exact_log2(unit)); ! zbase = phase->transform( new(C) URShiftXNode(zbase, shift) ); ! zend = phase->transform( new(C) URShiftXNode(zend, shift) ); } // Bulk clear double-words ! Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); ! Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) ); ! mem = new (C) ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); } Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, intptr_t start_offset, --- 2853,2870 ---- Node* zend = end_offset; // Scale to the unit required by the CPU: if (!Matcher::init_array_count_is_in_bytes) { Node* shift = phase->intcon(exact_log2(unit)); ! zbase = phase->transform(new URShiftXNode(zbase, shift) ); ! zend = phase->transform(new URShiftXNode(zend, shift) ); } // Bulk clear double-words ! Node* zsize = phase->transform(new SubXNode(zend, zbase) ); ! Node* adr = phase->transform(new AddPNode(dest, dest, start_offset) ); ! mem = new ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); } Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, intptr_t start_offset,
*** 2884,2894 **** if (done_offset > start_offset) { mem = clear_memory(ctl, mem, dest, start_offset, phase->MakeConX(done_offset), phase); } if (done_offset < end_offset) { // emit the final 32-bit store ! Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(done_offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); mem = phase->transform(mem); done_offset += BytesPerInt; --- 2884,2894 ---- if (done_offset > start_offset) { mem = clear_memory(ctl, mem, dest, start_offset, phase->MakeConX(done_offset), phase); } if (done_offset < end_offset) { // emit the final 32-bit store ! Node* adr = new AddPNode(dest, dest, phase->MakeConX(done_offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered); mem = phase->transform(mem); done_offset += BytesPerInt;
*** 2918,2937 **** } //------------------------------make------------------------------------------- MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { switch (opcode) { ! case Op_MemBarAcquire: return new(C) MemBarAcquireNode(C, atp, pn); ! case Op_LoadFence: return new(C) LoadFenceNode(C, atp, pn); ! case Op_MemBarRelease: return new(C) MemBarReleaseNode(C, atp, pn); ! case Op_StoreFence: return new(C) StoreFenceNode(C, atp, pn); ! case Op_MemBarAcquireLock: return new(C) MemBarAcquireLockNode(C, atp, pn); ! case Op_MemBarReleaseLock: return new(C) MemBarReleaseLockNode(C, atp, pn); ! case Op_MemBarVolatile: return new(C) MemBarVolatileNode(C, atp, pn); ! case Op_MemBarCPUOrder: return new(C) MemBarCPUOrderNode(C, atp, pn); ! case Op_Initialize: return new(C) InitializeNode(C, atp, pn); ! case Op_MemBarStoreStore: return new(C) MemBarStoreStoreNode(C, atp, pn); default: ShouldNotReachHere(); return NULL; } } //------------------------------Ideal------------------------------------------ --- 2918,2937 ---- } //------------------------------make------------------------------------------- MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { switch (opcode) { ! case Op_MemBarAcquire: return new MemBarAcquireNode(C, atp, pn); ! case Op_LoadFence: return new LoadFenceNode(C, atp, pn); ! case Op_MemBarRelease: return new MemBarReleaseNode(C, atp, pn); ! case Op_StoreFence: return new StoreFenceNode(C, atp, pn); ! case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn); ! case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn); ! case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn); ! case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn); ! case Op_Initialize: return new InitializeNode(C, atp, pn); ! case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); default: ShouldNotReachHere(); return NULL; } } //------------------------------Ideal------------------------------------------
*** 2990,3000 **** PhaseIterGVN* igvn = phase->is_IterGVN(); igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) ! return new (phase->C) ConINode(TypeInt::ZERO); } } return NULL; } --- 2990,3000 ---- PhaseIterGVN* igvn = phase->is_IterGVN(); igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) ! return new ConINode(TypeInt::ZERO); } } return NULL; }
*** 3010,3020 **** // Construct projections for memory. Node *MemBarNode::match( const ProjNode *proj, const Matcher *m ) { switch (proj->_con) { case TypeFunc::Control: case TypeFunc::Memory: ! return new (m->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); } ShouldNotReachHere(); return NULL; } --- 3010,3020 ---- // Construct projections for memory. Node *MemBarNode::match( const ProjNode *proj, const Matcher *m ) { switch (proj->_con) { case TypeFunc::Control: case TypeFunc::Memory: ! return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); } ShouldNotReachHere(); return NULL; }
*** 3436,3446 **** Node* InitializeNode::make_raw_address(intptr_t offset, PhaseTransform* phase) { Node* addr = in(RawAddress); if (offset != 0) { Compile* C = phase->C; ! addr = phase->transform( new (C) AddPNode(C->top(), addr, phase->MakeConX(offset)) ); } return addr; } --- 3436,3446 ---- Node* InitializeNode::make_raw_address(intptr_t offset, PhaseTransform* phase) { Node* addr = in(RawAddress); if (offset != 0) { Compile* C = phase->C; ! addr = phase->transform( new AddPNode(C->top(), addr, phase->MakeConX(offset)) ); } return addr; }
*** 4125,4135 **** } // Make a new, untransformed MergeMem with the same base as 'mem'. // If mem is itself a MergeMem, populate the result with the same edges. MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { ! return new(C) MergeMemNode(mem); } //------------------------------cmp-------------------------------------------- uint MergeMemNode::hash() const { return NO_HASH; } uint MergeMemNode::cmp( const Node &n ) const { --- 4125,4135 ---- } // Make a new, untransformed MergeMem with the same base as 'mem'. // If mem is itself a MergeMem, populate the result with the same edges. MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { ! return new MergeMemNode(mem); } //------------------------------cmp-------------------------------------------- uint MergeMemNode::hash() const { return NO_HASH; } uint MergeMemNode::cmp( const Node &n ) const {
src/share/vm/opto/memnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File