< prev index next >

src/hotspot/share/opto/compile.cpp

Print this page




1563       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,Type::Offset(offset), ta->field_offset());
1564     }
1565     // During the 2nd round of IterGVN, NotNull castings are removed.
1566     // Make sure the Bottom and NotNull variants alias the same.
1567     // Also, make sure exact and non-exact variants alias the same.
1568     if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != NULL) {
1569       tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,Type::Offset(offset), ta->field_offset());
1570     }
1571   }
1572 
1573   // Oop pointers need some flattening
1574   const TypeInstPtr *to = tj->isa_instptr();
1575   if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) {
1576     ciInstanceKlass *k = to->klass()->as_instance_klass();
1577     if( ptr == TypePtr::Constant ) {
1578       if (to->klass() != ciEnv::current()->Class_klass() ||
1579           offset < k->size_helper() * wordSize) {
1580         // No constant oop pointers (such as Strings); they alias with
1581         // unknown strings.
1582         assert(!is_known_inst, "not scalarizable allocation");
1583         tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset));
1584       }
1585     } else if( is_known_inst ) {
1586       tj = to; // Keep NotNull and klass_is_exact for instance type
1587     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
1588       // During the 2nd round of IterGVN, NotNull castings are removed.
1589       // Make sure the Bottom and NotNull variants alias the same.
1590       // Also, make sure exact and non-exact variants alias the same.
1591       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset));
1592     }
1593     if (to->speculative() != NULL) {
1594       tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),Type::Offset(to->offset()), to->instance_id());
1595     }
1596     // Canonicalize the holder of this field
1597     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
1598       // First handle header references such as a LoadKlassNode, even if the
1599       // object's klass is unloaded at compile time (4965979).
1600       if (!is_known_inst) { // Do it only for non-instance types
1601         tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, Type::Offset(offset));
1602       }
1603     } else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
1604       to = tj->is_instptr();
1605     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1606       // Static fields are in the space above the normal instance
1607       // fields in the java.lang.Class instance.
1608       if (to->klass() != ciEnv::current()->Class_klass()) {
1609         to = NULL;
1610         tj = TypeOopPtr::BOTTOM;
1611         offset = tj->offset();
1612       }
1613     } else {
1614       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1615       if (!k->equals(canonical_holder) || tj->offset() != offset) {
1616         if( is_known_inst ) {
1617           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, Type::Offset(offset), to->instance_id());
1618         } else {
1619           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, Type::Offset(offset));
1620         }
1621       }
1622     }
1623   }
1624 
1625   // Klass pointers to object array klasses need some flattening
1626   const TypeKlassPtr *tk = tj->isa_klassptr();
1627   if( tk ) {
1628     // If we are referencing a field within a Klass, we need
1629     // to assume the worst case of an Object.  Both exact and
1630     // inexact types must flatten to the same alias class so
1631     // use NotNull as the PTR.
1632     if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
1633 
1634       tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
1635                                    TypeKlassPtr::OBJECT->klass(),
1636                                    Type::Offset(offset));

1637     }
1638 
1639     ciKlass* klass = tk->klass();
1640     if (klass != NULL && klass->is_obj_array_klass()) {
1641       ciKlass* k = TypeAryPtr::OOPS->klass();
1642       if( !k || !k->is_loaded() )                  // Only fails for some -Xcomp runs
1643         k = TypeInstPtr::BOTTOM->klass();
1644       tj = tk = TypeKlassPtr::make(TypePtr::NotNull, k, Type::Offset(offset));
1645     }
1646 
1647     // Check for precise loads from the primary supertype array and force them
1648     // to the supertype cache alias index.  Check for generic array loads from
1649     // the primary supertype array and also force them to the supertype cache
1650     // alias index.  Since the same load can reach both, we need to merge
1651     // these 2 disparate memories into the same alias class.  Since the
1652     // primary supertype array is read-only, there's no chance of confusion
1653     // where we bypass an array load and an array store.
1654     int primary_supers_offset = in_bytes(Klass::primary_supers_offset());
1655     if (offset == Type::OffsetBot ||
1656         (offset >= primary_supers_offset &&
1657          offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) ||
1658         offset == (int)in_bytes(Klass::secondary_super_cache_offset())) {
1659       offset = in_bytes(Klass::secondary_super_cache_offset());
1660       tj = tk = TypeKlassPtr::make(TypePtr::NotNull, tk->klass(), Type::Offset(offset));
1661     }
1662   }
1663 
1664   // Flatten all Raw pointers together.
1665   if (tj->base() == Type::RawPtr)
1666     tj = TypeRawPtr::BOTTOM;
1667 
1668   if (tj->base() == Type::AnyPtr)
1669     tj = TypePtr::BOTTOM;      // An error, which the caller must check for.
1670 
1671   // Flatten all to bottom for now
1672   switch( _AliasLevel ) {
1673   case 0:
1674     tj = TypePtr::BOTTOM;
1675     break;
1676   case 1:                       // Flatten to: oop, static, field or array
1677     switch (tj->base()) {
1678     //case Type::AryPtr: tj = TypeAryPtr::RANGE;    break;
1679     case Type::RawPtr:   tj = TypeRawPtr::BOTTOM;   break;
1680     case Type::AryPtr:   // do not distinguish arrays at all


3420   case Op_LoadNKlass:
3421   case Op_LoadL:
3422   case Op_LoadL_unaligned:
3423   case Op_LoadPLocked:
3424   case Op_LoadP:
3425   case Op_LoadN:
3426   case Op_LoadRange:
3427   case Op_LoadS: {
3428   handle_mem:
3429 #ifdef ASSERT
3430     if( VerifyOptoOopOffsets ) {
3431       MemNode* mem  = n->as_Mem();
3432       // Check to see if address types have grounded out somehow.
3433       const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr();
3434       assert( !tp || oop_offset_is_sane(tp), "" );
3435     }
3436 #endif
3437     if (EnableValhalla && (nop == Op_LoadKlass || nop == Op_LoadNKlass)) {
3438       const TypeKlassPtr* tk = n->bottom_type()->make_ptr()->is_klassptr();
3439       assert(!tk->klass_is_exact(), "should have been folded");
3440       if (tk->klass()->can_be_value_array_klass()) {
3441         // Array load klass needs to filter out property bits (but not
3442         // GetNullFreePropertyNode which needs to extract the null free bits)

3443         uint last = unique();
3444         Node* pointer = NULL;
3445         if (nop == Op_LoadKlass) {
3446           Node* cast = new CastP2XNode(NULL, n);
3447           Node* masked = new LShiftXNode(cast, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
3448           masked = new RShiftXNode(masked, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
3449           pointer = new CastX2PNode(masked);
3450           pointer = new CheckCastPPNode(NULL, pointer, n->bottom_type());
3451         } else {
3452           Node* cast = new CastN2INode(n);
3453           Node* masked = new AndINode(cast, new ConINode(TypeInt::make(oopDesc::compressed_klass_mask())));
3454           pointer = new CastI2NNode(masked, n->bottom_type());
3455         }
3456         for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
3457           Node* u = n->fast_out(i);
3458           if (u->_idx < last && u->Opcode() != Op_GetNullFreeProperty) {
3459             // If user is a comparison with a klass that can't be a value type
3460             // array klass, we don't need to clear the storage property bits.
3461             Node* cmp = (u->is_DecodeNKlass() && u->outcnt() == 1) ? u->unique_out() : u;
3462             if (cmp->is_Cmp()) {
3463               const TypeKlassPtr* kp1 = cmp->in(1)->bottom_type()->make_ptr()->isa_klassptr();
3464               const TypeKlassPtr* kp2 = cmp->in(2)->bottom_type()->make_ptr()->isa_klassptr();
3465               if ((kp1 != NULL && !kp1->klass()->can_be_value_array_klass()) ||
3466                   (kp2 != NULL && !kp2->klass()->can_be_value_array_klass())) {
3467                 continue;
3468               }
3469             }
3470             int nb = u->replace_edge(n, pointer);
3471             --i, imax -= nb;
3472           }
3473         }
3474       }
3475     }
3476     break;
3477   }
3478 


3978     if (!Matcher::has_match_rule(Op_CmpUL)) {
3979       // No support for unsigned long comparisons
3980       ConINode* sign_pos = new ConINode(TypeInt::make(BitsPerLong - 1));
3981       Node* sign_bit_mask = new RShiftLNode(n->in(1), sign_pos);
3982       Node* orl = new OrLNode(n->in(1), sign_bit_mask);
3983       ConLNode* remove_sign_mask = new ConLNode(TypeLong::make(max_jlong));
3984       Node* andl = new AndLNode(orl, remove_sign_mask);
3985       Node* cmp = new CmpLNode(andl, n->in(2));
3986       n->subsume_by(cmp, this);
3987     }
3988     break;
3989   }
3990 #ifdef ASSERT
3991   case Op_ValueTypePtr:
3992   case Op_ValueType: {
3993     n->dump(-1);
3994     assert(false, "value type node was not removed");
3995     break;
3996   }
3997 #endif
3998   case Op_GetNullFreeProperty: {

3999     // Extract the null free bits
4000     uint last = unique();
4001     Node* null_free = NULL;

4002     if (n->in(1)->Opcode() == Op_LoadKlass) {
4003       Node* cast = new CastP2XNode(NULL, n->in(1));
4004       null_free = new AndLNode(cast, new ConLNode(TypeLong::make(((jlong)1)<<(oopDesc::wide_storage_props_shift + ArrayStorageProperties::null_free_bit))));
4005     } else {
4006       assert(n->in(1)->Opcode() == Op_LoadNKlass, "not a compressed klass?");
4007       Node* cast = new CastN2INode(n->in(1));
4008       null_free = new AndINode(cast, new ConINode(TypeInt::make(1<<(oopDesc::narrow_storage_props_shift + ArrayStorageProperties::null_free_bit))));
4009     }
4010     n->replace_by(null_free);
4011     break;
4012   }
4013   default:
4014     assert(!n->is_Call(), "");
4015     assert(!n->is_Mem(), "");
4016     assert(nop != Op_ProfileBoolean, "should be eliminated during IGVN");
4017     break;
4018   }
4019 }
4020 
4021 //------------------------------final_graph_reshaping_walk---------------------
4022 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
4023 // requires that the walk visits a node's inputs before visiting the node.
4024 void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) {
4025   ResourceArea *area = Thread::current()->resource_area();
4026   Unique_Node_List sfpt(area);
4027 
4028   frc._visited.set(root->_idx); // first, mark node as visited
4029   uint cnt = root->req();
4030   Node *n = root;




1563       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,Type::Offset(offset), ta->field_offset());
1564     }
1565     // During the 2nd round of IterGVN, NotNull castings are removed.
1566     // Make sure the Bottom and NotNull variants alias the same.
1567     // Also, make sure exact and non-exact variants alias the same.
1568     if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != NULL) {
1569       tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,Type::Offset(offset), ta->field_offset());
1570     }
1571   }
1572 
1573   // Oop pointers need some flattening
1574   const TypeInstPtr *to = tj->isa_instptr();
1575   if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) {
1576     ciInstanceKlass *k = to->klass()->as_instance_klass();
1577     if( ptr == TypePtr::Constant ) {
1578       if (to->klass() != ciEnv::current()->Class_klass() ||
1579           offset < k->size_helper() * wordSize) {
1580         // No constant oop pointers (such as Strings); they alias with
1581         // unknown strings.
1582         assert(!is_known_inst, "not scalarizable allocation");
1583         tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset), to->klass()->flatten_array());
1584       }
1585     } else if( is_known_inst ) {
1586       tj = to; // Keep NotNull and klass_is_exact for instance type
1587     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
1588       // During the 2nd round of IterGVN, NotNull castings are removed.
1589       // Make sure the Bottom and NotNull variants alias the same.
1590       // Also, make sure exact and non-exact variants alias the same.
1591       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset), to->klass()->flatten_array());
1592     }
1593     if (to->speculative() != NULL) {
1594       tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),Type::Offset(to->offset()), to->klass()->flatten_array(), to->instance_id());
1595     }
1596     // Canonicalize the holder of this field
1597     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
1598       // First handle header references such as a LoadKlassNode, even if the
1599       // object's klass is unloaded at compile time (4965979).
1600       if (!is_known_inst) { // Do it only for non-instance types
1601         tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, Type::Offset(offset), false);
1602       }
1603     } else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
1604       to = tj->is_instptr();
1605     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1606       // Static fields are in the space above the normal instance
1607       // fields in the java.lang.Class instance.
1608       if (to->klass() != ciEnv::current()->Class_klass()) {
1609         to = NULL;
1610         tj = TypeOopPtr::BOTTOM;
1611         offset = tj->offset();
1612       }
1613     } else {
1614       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1615       if (!k->equals(canonical_holder) || tj->offset() != offset) {
1616         if( is_known_inst ) {
1617           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, Type::Offset(offset), canonical_holder->flatten_array(), to->instance_id());
1618         } else {
1619           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, Type::Offset(offset), canonical_holder->flatten_array());
1620         }
1621       }
1622     }
1623   }
1624 
1625   // Klass pointers to object array klasses need some flattening
1626   const TypeKlassPtr *tk = tj->isa_klassptr();
1627   if( tk ) {
1628     // If we are referencing a field within a Klass, we need
1629     // to assume the worst case of an Object.  Both exact and
1630     // inexact types must flatten to the same alias class so
1631     // use NotNull as the PTR.
1632     if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
1633 
1634       tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
1635                                    TypeKlassPtr::OBJECT->klass(),
1636                                    Type::Offset(offset),
1637                                    false);
1638     }
1639 
1640     ciKlass* klass = tk->klass();
1641     if (klass != NULL && klass->is_obj_array_klass()) {
1642       ciKlass* k = TypeAryPtr::OOPS->klass();
1643       if( !k || !k->is_loaded() )                  // Only fails for some -Xcomp runs
1644         k = TypeInstPtr::BOTTOM->klass();
1645       tj = tk = TypeKlassPtr::make(TypePtr::NotNull, k, Type::Offset(offset), false);
1646     }
1647 
1648     // Check for precise loads from the primary supertype array and force them
1649     // to the supertype cache alias index.  Check for generic array loads from
1650     // the primary supertype array and also force them to the supertype cache
1651     // alias index.  Since the same load can reach both, we need to merge
1652     // these 2 disparate memories into the same alias class.  Since the
1653     // primary supertype array is read-only, there's no chance of confusion
1654     // where we bypass an array load and an array store.
1655     int primary_supers_offset = in_bytes(Klass::primary_supers_offset());
1656     if (offset == Type::OffsetBot ||
1657         (offset >= primary_supers_offset &&
1658          offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) ||
1659         offset == (int)in_bytes(Klass::secondary_super_cache_offset())) {
1660       offset = in_bytes(Klass::secondary_super_cache_offset());
1661       tj = tk = TypeKlassPtr::make(TypePtr::NotNull, tk->klass(), Type::Offset(offset), tk->flatten_array());
1662     }
1663   }
1664 
1665   // Flatten all Raw pointers together.
1666   if (tj->base() == Type::RawPtr)
1667     tj = TypeRawPtr::BOTTOM;
1668 
1669   if (tj->base() == Type::AnyPtr)
1670     tj = TypePtr::BOTTOM;      // An error, which the caller must check for.
1671 
1672   // Flatten all to bottom for now
1673   switch( _AliasLevel ) {
1674   case 0:
1675     tj = TypePtr::BOTTOM;
1676     break;
1677   case 1:                       // Flatten to: oop, static, field or array
1678     switch (tj->base()) {
1679     //case Type::AryPtr: tj = TypeAryPtr::RANGE;    break;
1680     case Type::RawPtr:   tj = TypeRawPtr::BOTTOM;   break;
1681     case Type::AryPtr:   // do not distinguish arrays at all


3421   case Op_LoadNKlass:
3422   case Op_LoadL:
3423   case Op_LoadL_unaligned:
3424   case Op_LoadPLocked:
3425   case Op_LoadP:
3426   case Op_LoadN:
3427   case Op_LoadRange:
3428   case Op_LoadS: {
3429   handle_mem:
3430 #ifdef ASSERT
3431     if( VerifyOptoOopOffsets ) {
3432       MemNode* mem  = n->as_Mem();
3433       // Check to see if address types have grounded out somehow.
3434       const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr();
3435       assert( !tp || oop_offset_is_sane(tp), "" );
3436     }
3437 #endif
3438     if (EnableValhalla && (nop == Op_LoadKlass || nop == Op_LoadNKlass)) {
3439       const TypeKlassPtr* tk = n->bottom_type()->make_ptr()->is_klassptr();
3440       assert(!tk->klass_is_exact(), "should have been folded");
3441       if (tk->klass()->can_be_value_array_klass() && n->as_Mem()->adr_type()->offset() == oopDesc::klass_offset_in_bytes()) {
3442         // Array load klass needs to filter out property bits (but not
3443         // GetNullFreePropertyNode or GetFlattenedPropertyNode which
3444         // needs to extract the storage property bits)
3445         uint last = unique();
3446         Node* pointer = NULL;
3447         if (nop == Op_LoadKlass) {
3448           Node* cast = new CastP2XNode(NULL, n);
3449           Node* masked = new LShiftXNode(cast, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
3450           masked = new RShiftXNode(masked, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
3451           pointer = new CastX2PNode(masked);
3452           pointer = new CheckCastPPNode(NULL, pointer, n->bottom_type());
3453         } else {
3454           Node* cast = new CastN2INode(n);
3455           Node* masked = new AndINode(cast, new ConINode(TypeInt::make(oopDesc::compressed_klass_mask())));
3456           pointer = new CastI2NNode(masked, n->bottom_type());
3457         }
3458         for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
3459           Node* u = n->fast_out(i);
3460           if (u->_idx < last && u->Opcode() != Op_GetNullFreeProperty && u->Opcode() != Op_GetFlattenedProperty) {
3461             // If user is a comparison with a klass that can't be a value type
3462             // array klass, we don't need to clear the storage property bits.
3463             Node* cmp = (u->is_DecodeNKlass() && u->outcnt() == 1) ? u->unique_out() : u;
3464             if (cmp->is_Cmp()) {
3465               const TypeKlassPtr* kp1 = cmp->in(1)->bottom_type()->make_ptr()->isa_klassptr();
3466               const TypeKlassPtr* kp2 = cmp->in(2)->bottom_type()->make_ptr()->isa_klassptr();
3467               if ((kp1 != NULL && !kp1->klass()->can_be_value_array_klass()) ||
3468                   (kp2 != NULL && !kp2->klass()->can_be_value_array_klass())) {
3469                 continue;
3470               }
3471             }
3472             int nb = u->replace_edge(n, pointer);
3473             --i, imax -= nb;
3474           }
3475         }
3476       }
3477     }
3478     break;
3479   }
3480 


3980     if (!Matcher::has_match_rule(Op_CmpUL)) {
3981       // No support for unsigned long comparisons
3982       ConINode* sign_pos = new ConINode(TypeInt::make(BitsPerLong - 1));
3983       Node* sign_bit_mask = new RShiftLNode(n->in(1), sign_pos);
3984       Node* orl = new OrLNode(n->in(1), sign_bit_mask);
3985       ConLNode* remove_sign_mask = new ConLNode(TypeLong::make(max_jlong));
3986       Node* andl = new AndLNode(orl, remove_sign_mask);
3987       Node* cmp = new CmpLNode(andl, n->in(2));
3988       n->subsume_by(cmp, this);
3989     }
3990     break;
3991   }
3992 #ifdef ASSERT
3993   case Op_ValueTypePtr:
3994   case Op_ValueType: {
3995     n->dump(-1);
3996     assert(false, "value type node was not removed");
3997     break;
3998   }
3999 #endif
4000   case Op_GetNullFreeProperty:
4001   case Op_GetFlattenedProperty: {
4002     // Extract the null free bits
4003     uint last = unique();
4004     Node* null_free = NULL;
4005     int bit = nop == Op_GetNullFreeProperty ? ArrayStorageProperties::null_free_bit : ArrayStorageProperties::flattened_bit;
4006     if (n->in(1)->Opcode() == Op_LoadKlass) {
4007       Node* cast = new CastP2XNode(NULL, n->in(1));
4008       null_free = new AndLNode(cast, new ConLNode(TypeLong::make(((jlong)1)<<(oopDesc::wide_storage_props_shift + bit))));
4009     } else {
4010       assert(n->in(1)->Opcode() == Op_LoadNKlass, "not a compressed klass?");
4011       Node* cast = new CastN2INode(n->in(1));
4012       null_free = new AndINode(cast, new ConINode(TypeInt::make(1<<(oopDesc::narrow_storage_props_shift + bit))));
4013     }
4014     n->subsume_by(null_free, this);
4015     break;
4016   }
4017   default:
4018     assert(!n->is_Call(), "");
4019     assert(!n->is_Mem(), "");
4020     assert(nop != Op_ProfileBoolean, "should be eliminated during IGVN");
4021     break;
4022   }
4023 }
4024 
4025 //------------------------------final_graph_reshaping_walk---------------------
4026 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
4027 // requires that the walk visits a node's inputs before visiting the node.
4028 void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) {
4029   ResourceArea *area = Thread::current()->resource_area();
4030   Unique_Node_List sfpt(area);
4031 
4032   frc._visited.set(root->_idx); // first, mark node as visited
4033   uint cnt = root->req();
4034   Node *n = root;


< prev index next >