< prev index next >

src/hotspot/share/opto/castnode.cpp

Print this page




 401   //   // ELSE return same old type as before
 402   //   return _type;
 403   // }
 404   // // Not joining two pointers
 405   // return join;
 406 }
 407 
 408 Node* CheckCastPPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
 409   // This is a value type. Its input is the return of a call: the call
 410   // returns a value type and we now know its exact type: build a
 411   // ValueTypePtrNode from the call.
 412   if (can_reshape &&
 413       in(0) == NULL &&
 414       phase->C->can_add_value_type() &&
 415       type()->isa_valuetypeptr() &&
 416       in(1) != NULL && in(1)->is_Proj() &&
 417       in(1)->in(0) != NULL && in(1)->in(0)->is_CallStaticJava() &&
 418       in(1)->in(0)->as_CallStaticJava()->method() != NULL &&
 419       in(1)->as_Proj()->_con == TypeFunc::Parms) {
 420     const TypeValueTypePtr* cast_type = type()->is_valuetypeptr();
 421     ciValueKlass* vk = cast_type->value_type()->value_klass();
 422     assert(!vk->is__Value(), "why cast to __Value?");
 423     PhaseIterGVN* igvn = phase->is_IterGVN();
 424 
 425     if (ValueTypeReturnedAsFields && vk->can_be_returned_as_fields()) {
 426       igvn->set_delay_transform(true);
 427       CallNode* call = in(1)->in(0)->as_Call();
 428       igvn->C->remove_macro_node(call);
 429       // We now know the return type of the call
 430       const TypeTuple* range_sig = TypeTuple::make_range(vk, false);
 431       const TypeTuple* range_cc = TypeTuple::make_range(vk, true);
 432       assert(range_sig != call->_tf->range_sig() && range_cc != call->_tf->range_cc(), "type should change");
 433       call->_tf = TypeFunc::make(call->_tf->domain_sig(), call->_tf->domain_cc(),
 434                                  range_sig, range_cc);
 435       igvn->set_type(call, call->Value(igvn));
 436       igvn->set_type(in(1), in(1)->Value(igvn));
 437 
 438       Node* ctl_hook = new Node(1);
 439       Node* mem_hook = new Node(1);
 440       Node* io_hook = new Node(1);
 441       Node* res_hook = new Node(1);


 477       // or we get a tagged klass pointer and we need to allocate a value.
 478       Node* cast = igvn->transform(new CastP2XNode(kit.control(), projs.resproj));
 479       Node* masked = igvn->transform(new AndXNode(cast, igvn->MakeConX(0x1)));
 480       Node* cmp = igvn->transform(new CmpXNode(masked, igvn->MakeConX(0x1)));
 481       Node* bol = kit.Bool(cmp, BoolTest::eq);
 482       IfNode* iff = kit.create_and_map_if(kit.control(), bol, PROB_MAX, COUNT_UNKNOWN);
 483       Node* iftrue = kit.IfTrue(iff);
 484       Node* iffalse = kit.IfFalse(iff);
 485 
 486       Node* region = new RegionNode(3);
 487       Node* mem_phi = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
 488       Node* io_phi = new PhiNode(region, Type::ABIO);
 489       Node* res_phi = new PhiNode(region, cast_type);
 490       Node* ex_region = new RegionNode(3);
 491       Node* ex_mem_phi = new PhiNode(ex_region, Type::MEMORY, TypePtr::BOTTOM);
 492       Node* ex_io_phi = new PhiNode(ex_region, Type::ABIO);
 493 
 494       // True branch: result is a tagged klass pointer
 495       // Allocate a value type (will add extra projections to the call)
 496       kit.set_control(iftrue);
 497       Node* res = igvn->transform(ValueTypePtrNode::make(&kit, vk, call));
 498       res = res->isa_ValueTypePtr()->allocate(&kit);
 499 
 500       // Get exception state
 501       GraphKit ekit(kit.transfer_exceptions_into_jvms(), igvn);
 502       SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
 503       Node* ex_oop = ekit.use_exception_state(ex_map);
 504 
 505       region->init_req(1, kit.control());
 506       mem_phi->init_req(1, kit.reset_memory());
 507       io_phi->init_req(1, kit.i_o());
 508       res_phi->init_req(1, res);
 509       ex_region->init_req(1, ekit.control());
 510       ex_mem_phi->init_req(1, ekit.reset_memory());
 511       ex_io_phi->init_req(1, ekit.i_o());
 512 
 513       // False branch: result is not tagged
 514       // Load buffered value type from returned oop
 515       kit.set_control(iffalse);
 516       kit.set_all_memory(projs.fallthrough_memproj);
 517       kit.set_i_o(projs.fallthrough_ioproj);
 518       // Cast oop to NotNull
 519       ConstraintCastNode* res_cast = clone()->as_ConstraintCast();
 520       res_cast->set_req(0, kit.control());
 521       res_cast->set_req(1, projs.resproj);
 522       res_cast->set_type(cast_type->cast_to_ptr_type(TypePtr::NotNull));
 523       Node* ctl = kit.control(); // Control may get updated below
 524       res = ValueTypePtrNode::make(*igvn, ctl, kit.merged_memory(), igvn->transform(res_cast));
 525 
 526       region->init_req(2, ctl);
 527       mem_phi->init_req(2, kit.reset_memory());
 528       io_phi->init_req(2, kit.i_o());
 529       res_phi->init_req(2, igvn->transform(res));
 530       ex_region->init_req(2, projs.catchall_catchproj);
 531       ex_mem_phi->init_req(2, projs.catchall_memproj);
 532       ex_io_phi->init_req(2, projs.catchall_ioproj);
 533 
 534       igvn->set_delay_transform(false);
 535 
 536       // Re-attach users to newly created PhiNodes
 537       igvn->replace_node(ctl_hook, igvn->transform(region));
 538       igvn->replace_node(mem_hook, igvn->transform(mem_phi));
 539       igvn->replace_node(io_hook, igvn->transform(io_phi));
 540       igvn->replace_node(res_hook, igvn->transform(res_phi));
 541       igvn->replace_node(ex_ctl_hook, igvn->transform(ex_region));
 542       igvn->replace_node(ex_mem_hook, igvn->transform(ex_mem_phi));
 543       igvn->replace_node(ex_io_hook, igvn->transform(ex_io_phi));
 544       return this;
 545     } else {
 546       CallNode* call = in(1)->in(0)->as_Call();
 547       // We now know the return type of the call
 548       const TypeTuple* range = TypeTuple::make_range(vk, false);
 549       if (range != call->_tf->range_sig()) {
 550         // Build the ValueTypePtrNode by loading the fields
 551         call->_tf = TypeFunc::make(call->_tf->domain_sig(), call->_tf->domain_cc(),
 552                                    range, range);
 553         phase->set_type(call, call->Value(phase));
 554         phase->set_type(in(1), in(1)->Value(phase));
 555         uint last = phase->C->unique();
 556         CallNode* call = in(1)->in(0)->as_Call();
 557         // Extract projections from the call and hook control users to temporary node
 558         CallProjections projs;
 559         call->extract_projections(&projs, true, true);
 560         Node* ctl = projs.fallthrough_catchproj;
 561         Node* mem = projs.fallthrough_memproj;
 562         Node* ctl_hook = new Node(1);
 563         igvn->replace_in_uses(ctl, ctl_hook);
 564         Node* vtptr = ValueTypePtrNode::make(*phase, ctl, mem, in(1));
 565         // Attach users to updated control
 566         igvn->replace_node(ctl_hook, ctl);
 567         return vtptr;
 568       }
 569     }
 570   }
 571   return NULL;
 572 }
 573 
 574 //=============================================================================
 575 //------------------------------Value------------------------------------------
 576 const Type* CastX2PNode::Value(PhaseGVN* phase) const {
 577   const Type* t = phase->type(in(1));
 578   if (t == Type::TOP) return Type::TOP;
 579   if (t->base() == Type_X && t->singleton()) {
 580     uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con();
 581     if (bits == 0)   return TypePtr::NULL_PTR;
 582     return TypeRawPtr::make((address) bits);
 583   }
 584   return CastX2PNode::bottom_type();




 401   //   // ELSE return same old type as before
 402   //   return _type;
 403   // }
 404   // // Not joining two pointers
 405   // return join;
 406 }
 407 
 408 Node* CheckCastPPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
 409   // This is a value type. Its input is the return of a call: the call
 410   // returns a value type and we now know its exact type: build a
 411   // ValueTypePtrNode from the call.
 412   if (can_reshape &&
 413       in(0) == NULL &&
 414       phase->C->can_add_value_type() &&
 415       type()->isa_valuetypeptr() &&
 416       in(1) != NULL && in(1)->is_Proj() &&
 417       in(1)->in(0) != NULL && in(1)->in(0)->is_CallStaticJava() &&
 418       in(1)->in(0)->as_CallStaticJava()->method() != NULL &&
 419       in(1)->as_Proj()->_con == TypeFunc::Parms) {
 420     const TypeValueTypePtr* cast_type = type()->is_valuetypeptr();
 421     ciValueKlass* vk = cast_type->value_klass();
 422     assert(!vk->is__Value(), "why cast to __Value?");
 423     PhaseIterGVN* igvn = phase->is_IterGVN();
 424 
 425     if (ValueTypeReturnedAsFields && vk->can_be_returned_as_fields()) {
 426       igvn->set_delay_transform(true);
 427       CallNode* call = in(1)->in(0)->as_Call();
 428       igvn->C->remove_macro_node(call);
 429       // We now know the return type of the call
 430       const TypeTuple* range_sig = TypeTuple::make_range(vk, false);
 431       const TypeTuple* range_cc = TypeTuple::make_range(vk, true);
 432       assert(range_sig != call->_tf->range_sig() && range_cc != call->_tf->range_cc(), "type should change");
 433       call->_tf = TypeFunc::make(call->_tf->domain_sig(), call->_tf->domain_cc(),
 434                                  range_sig, range_cc);
 435       igvn->set_type(call, call->Value(igvn));
 436       igvn->set_type(in(1), in(1)->Value(igvn));
 437 
 438       Node* ctl_hook = new Node(1);
 439       Node* mem_hook = new Node(1);
 440       Node* io_hook = new Node(1);
 441       Node* res_hook = new Node(1);


 477       // or we get a tagged klass pointer and we need to allocate a value.
 478       Node* cast = igvn->transform(new CastP2XNode(kit.control(), projs.resproj));
 479       Node* masked = igvn->transform(new AndXNode(cast, igvn->MakeConX(0x1)));
 480       Node* cmp = igvn->transform(new CmpXNode(masked, igvn->MakeConX(0x1)));
 481       Node* bol = kit.Bool(cmp, BoolTest::eq);
 482       IfNode* iff = kit.create_and_map_if(kit.control(), bol, PROB_MAX, COUNT_UNKNOWN);
 483       Node* iftrue = kit.IfTrue(iff);
 484       Node* iffalse = kit.IfFalse(iff);
 485 
 486       Node* region = new RegionNode(3);
 487       Node* mem_phi = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
 488       Node* io_phi = new PhiNode(region, Type::ABIO);
 489       Node* res_phi = new PhiNode(region, cast_type);
 490       Node* ex_region = new RegionNode(3);
 491       Node* ex_mem_phi = new PhiNode(ex_region, Type::MEMORY, TypePtr::BOTTOM);
 492       Node* ex_io_phi = new PhiNode(ex_region, Type::ABIO);
 493 
 494       // True branch: result is a tagged klass pointer
 495       // Allocate a value type (will add extra projections to the call)
 496       kit.set_control(iftrue);
 497       Node* res = igvn->transform(ValueTypePtrNode::make_from_call(&kit, vk, call));
 498       res = res->isa_ValueTypePtr()->allocate(&kit);
 499 
 500       // Get exception state
 501       GraphKit ekit(kit.transfer_exceptions_into_jvms(), igvn);
 502       SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
 503       Node* ex_oop = ekit.use_exception_state(ex_map);
 504 
 505       region->init_req(1, kit.control());
 506       mem_phi->init_req(1, kit.reset_memory());
 507       io_phi->init_req(1, kit.i_o());
 508       res_phi->init_req(1, res);
 509       ex_region->init_req(1, ekit.control());
 510       ex_mem_phi->init_req(1, ekit.reset_memory());
 511       ex_io_phi->init_req(1, ekit.i_o());
 512 
 513       // False branch: result is not tagged
 514       // Load buffered value type from returned oop
 515       kit.set_control(iffalse);
 516       kit.set_all_memory(projs.fallthrough_memproj);
 517       kit.set_i_o(projs.fallthrough_ioproj);
 518       // Cast oop to NotNull
 519       ConstraintCastNode* res_cast = clone()->as_ConstraintCast();
 520       res_cast->set_req(0, kit.control());
 521       res_cast->set_req(1, projs.resproj);
 522       res_cast->set_type(cast_type->cast_to_ptr_type(TypePtr::NotNull));
 523       Node* ctl = kit.control(); // Control may get updated below
 524       res = ValueTypePtrNode::make_from_oop(*igvn, ctl, kit.merged_memory(), igvn->transform(res_cast));
 525 
 526       region->init_req(2, ctl);
 527       mem_phi->init_req(2, kit.reset_memory());
 528       io_phi->init_req(2, kit.i_o());
 529       res_phi->init_req(2, igvn->transform(res));
 530       ex_region->init_req(2, projs.catchall_catchproj);
 531       ex_mem_phi->init_req(2, projs.catchall_memproj);
 532       ex_io_phi->init_req(2, projs.catchall_ioproj);
 533 
 534       igvn->set_delay_transform(false);
 535 
 536       // Re-attach users to newly created PhiNodes
 537       igvn->replace_node(ctl_hook, igvn->transform(region));
 538       igvn->replace_node(mem_hook, igvn->transform(mem_phi));
 539       igvn->replace_node(io_hook, igvn->transform(io_phi));
 540       igvn->replace_node(res_hook, igvn->transform(res_phi));
 541       igvn->replace_node(ex_ctl_hook, igvn->transform(ex_region));
 542       igvn->replace_node(ex_mem_hook, igvn->transform(ex_mem_phi));
 543       igvn->replace_node(ex_io_hook, igvn->transform(ex_io_phi));
 544       return this;
 545     } else {
 546       CallNode* call = in(1)->in(0)->as_Call();
 547       // We now know the return type of the call
 548       const TypeTuple* range = TypeTuple::make_range(vk, false);
 549       if (range != call->_tf->range_sig()) {
 550         // Build the ValueTypePtrNode by loading the fields
 551         call->_tf = TypeFunc::make(call->_tf->domain_sig(), call->_tf->domain_cc(),
 552                                    range, range);
 553         phase->set_type(call, call->Value(phase));
 554         phase->set_type(in(1), in(1)->Value(phase));
 555         uint last = phase->C->unique();
 556         CallNode* call = in(1)->in(0)->as_Call();
 557         // Extract projections from the call and hook control users to temporary node
 558         CallProjections projs;
 559         call->extract_projections(&projs, true, true);
 560         Node* ctl = projs.fallthrough_catchproj;
 561         Node* mem = projs.fallthrough_memproj;
 562         Node* ctl_hook = new Node(1);
 563         igvn->replace_in_uses(ctl, ctl_hook);
 564         Node* vtptr = ValueTypePtrNode::make_from_oop(*phase, ctl, mem, in(1));
 565         // Attach users to updated control
 566         igvn->replace_node(ctl_hook, ctl);
 567         return vtptr;
 568       }
 569     }
 570   }
 571   return NULL;
 572 }
 573 
 574 //=============================================================================
 575 //------------------------------Value------------------------------------------
 576 const Type* CastX2PNode::Value(PhaseGVN* phase) const {
 577   const Type* t = phase->type(in(1));
 578   if (t == Type::TOP) return Type::TOP;
 579   if (t->base() == Type_X && t->singleton()) {
 580     uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con();
 581     if (bits == 0)   return TypePtr::NULL_PTR;
 582     return TypeRawPtr::make((address) bits);
 583   }
 584   return CastX2PNode::bottom_type();


< prev index next >