2675 bool aligned = false;
2676 if (offset != NULL && head->init_trip()->is_Con()) {
2677 int element_size = type2aelembytes(t);
2678 aligned = (offset->find_intptr_t_type()->get_con() + head->init_trip()->get_int() * element_size) % HeapWordSize == 0;
2679 }
2680
2681 // Build a call to the fill routine
2682 const char* fill_name;
2683 address fill = StubRoutines::select_fill_function(t, aligned, fill_name);
2684 assert(fill != NULL, "what?");
2685
2686 // Convert float/double to int/long for fill routines
2687 if (t == T_FLOAT) {
2688 store_value = new (C) MoveF2INode(store_value);
2689 _igvn.register_new_node_with_optimizer(store_value);
2690 } else if (t == T_DOUBLE) {
2691 store_value = new (C) MoveD2LNode(store_value);
2692 _igvn.register_new_node_with_optimizer(store_value);
2693 }
2694
2695 Node* mem_phi = store->in(MemNode::Memory);
2696 Node* result_ctrl;
2697 Node* result_mem;
2698 const TypeFunc* call_type = OptoRuntime::array_fill_Type();
2699 CallLeafNode *call = new (C) CallLeafNoFPNode(call_type, fill,
2700 fill_name, TypeAryPtr::get_array_body_type(t));
2701 call->init_req(TypeFunc::Parms+0, from);
2702 call->init_req(TypeFunc::Parms+1, store_value);
2703 #ifdef _LP64
2704 len = new (C) ConvI2LNode(len);
2705 _igvn.register_new_node_with_optimizer(len);
2706 #endif
2707 call->init_req(TypeFunc::Parms+2, len);
2708 #ifdef _LP64
2709 call->init_req(TypeFunc::Parms+3, C->top());
2710 #endif
2711 call->init_req( TypeFunc::Control, head->init_control());
2712 call->init_req( TypeFunc::I_O , C->top() ) ; // does no i/o
2713 call->init_req( TypeFunc::Memory , mem_phi->in(LoopNode::EntryControl) );
2714 call->init_req( TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr) );
2715 call->init_req( TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr) );
2716 _igvn.register_new_node_with_optimizer(call);
2717 result_ctrl = new (C) ProjNode(call,TypeFunc::Control);
2718 _igvn.register_new_node_with_optimizer(result_ctrl);
2719 result_mem = new (C) ProjNode(call,TypeFunc::Memory);
2720 _igvn.register_new_node_with_optimizer(result_mem);
2721
2722 /* Disable following optimization until proper fix (add missing checks).
2723
2724 // If this fill is tightly coupled to an allocation and overwrites
2725 // the whole body, allow it to take over the zeroing.
2726 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this);
2727 if (alloc != NULL && alloc->is_AllocateArray()) {
2728 Node* length = alloc->as_AllocateArray()->Ideal_length();
2729 if (head->limit() == length &&
|
2675 bool aligned = false;
2676 if (offset != NULL && head->init_trip()->is_Con()) {
2677 int element_size = type2aelembytes(t);
2678 aligned = (offset->find_intptr_t_type()->get_con() + head->init_trip()->get_int() * element_size) % HeapWordSize == 0;
2679 }
2680
2681 // Build a call to the fill routine
2682 const char* fill_name;
2683 address fill = StubRoutines::select_fill_function(t, aligned, fill_name);
2684 assert(fill != NULL, "what?");
2685
2686 // Convert float/double to int/long for fill routines
2687 if (t == T_FLOAT) {
2688 store_value = new (C) MoveF2INode(store_value);
2689 _igvn.register_new_node_with_optimizer(store_value);
2690 } else if (t == T_DOUBLE) {
2691 store_value = new (C) MoveD2LNode(store_value);
2692 _igvn.register_new_node_with_optimizer(store_value);
2693 }
2694
2695 if (SharedRuntime::c_calling_convention_requires_ints_as_longs() &&
2696 // see StubRoutines::select_fill_function for types. FLOAT has been converted to INT
2697 (t == T_FLOAT || t == T_INT || t == T_SHORT || t == T_CHAR || t == T_BOOLEAN || t == T_BYTE)) {
2698 store_value = new (C) ConvI2LNode(store_value);
2699 _igvn.register_new_node_with_optimizer(store_value);
2700 }
2701
2702 Node* mem_phi = store->in(MemNode::Memory);
2703 Node* result_ctrl;
2704 Node* result_mem;
2705 const TypeFunc* call_type = OptoRuntime::array_fill_Type();
2706 CallLeafNode *call = new (C) CallLeafNoFPNode(call_type, fill,
2707 fill_name, TypeAryPtr::get_array_body_type(t));
2708 uint cnt = 0;
2709 call->init_req(TypeFunc::Parms + cnt++, from);
2710 call->init_req(TypeFunc::Parms + cnt++, store_value);
2711 if (SharedRuntime::c_calling_convention_requires_ints_as_longs()) {
2712 call->init_req(TypeFunc::Parms + cnt++, C->top());
2713 }
2714 #ifdef _LP64
2715 len = new (C) ConvI2LNode(len);
2716 _igvn.register_new_node_with_optimizer(len);
2717 #endif
2718 call->init_req(TypeFunc::Parms + cnt++, len);
2719 #ifdef _LP64
2720 call->init_req(TypeFunc::Parms + cnt++, C->top());
2721 #endif
2722 call->init_req( TypeFunc::Control, head->init_control());
2723 call->init_req( TypeFunc::I_O , C->top() ) ; // does no i/o
2724 call->init_req( TypeFunc::Memory , mem_phi->in(LoopNode::EntryControl) );
2725 call->init_req( TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr) );
2726 call->init_req( TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr) );
2727 _igvn.register_new_node_with_optimizer(call);
2728 result_ctrl = new (C) ProjNode(call,TypeFunc::Control);
2729 _igvn.register_new_node_with_optimizer(result_ctrl);
2730 result_mem = new (C) ProjNode(call,TypeFunc::Memory);
2731 _igvn.register_new_node_with_optimizer(result_mem);
2732
2733 /* Disable following optimization until proper fix (add missing checks).
2734
2735 // If this fill is tightly coupled to an allocation and overwrites
2736 // the whole body, allow it to take over the zeroing.
2737 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this);
2738 if (alloc != NULL && alloc->is_AllocateArray()) {
2739 Node* length = alloc->as_AllocateArray()->Ideal_length();
2740 if (head->limit() == length &&
|