src/share/vm/opto/loopTransform.cpp

Print this page
rev 5186 : 8024342: PPC64 (part 111): Support for C calling conventions that require 64-bit ints.
Summary: Some platforms, as ppc and s390x/zArch require that 32-bit ints are passed as 64-bit values to C functions. This change adds support to adapt the signature and to issue proper casts to c2-compiled stubs. The functions are used in generate_native_wrapper(). Adapt signature in PhaseIdealLoop::intrinsify_fill().


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 &&