3187 }
3188
3189 // Must have constant stride
3190 CountedLoopNode* head = lpt->_head->as_CountedLoop();
3191 if (!head->is_valid_counted_loop() || !head->is_normal_loop()) {
3192 return false;
3193 }
3194
3195 head->verify_strip_mined(1);
3196
3197 // Check that the body only contains a store of a loop invariant
3198 // value that is indexed by the loop phi.
3199 Node* store = NULL;
3200 Node* store_value = NULL;
3201 Node* shift = NULL;
3202 Node* offset = NULL;
3203 if (!match_fill_loop(lpt, store, store_value, shift, offset)) {
3204 return false;
3205 }
3206
3207 Node* exit = head->loopexit()->proj_out(0);
3208 if (exit == NULL) {
3209 return false;
3210 }
3211
3212 #ifndef PRODUCT
3213 if (TraceLoopOpts) {
3214 tty->print("ArrayFill ");
3215 lpt->dump_head();
3216 }
3217 #endif
3218
3219 // Now replace the whole loop body by a call to a fill routine that
3220 // covers the same region as the loop.
3221 Node* base = store->in(MemNode::Address)->as_AddP()->in(AddPNode::Base);
3222
3223 // Build an expression for the beginning of the copy region
3224 Node* index = head->init_trip();
3225 #ifdef _LP64
3226 index = new ConvI2LNode(index);
3227 _igvn.register_new_node_with_optimizer(index);
3263 Node* mem_phi = store->in(MemNode::Memory);
3264 Node* result_ctrl;
3265 Node* result_mem;
3266 const TypeFunc* call_type = OptoRuntime::array_fill_Type();
3267 CallLeafNode *call = new CallLeafNoFPNode(call_type, fill,
3268 fill_name, TypeAryPtr::get_array_body_type(t));
3269 uint cnt = 0;
3270 call->init_req(TypeFunc::Parms + cnt++, from);
3271 call->init_req(TypeFunc::Parms + cnt++, store_value);
3272 #ifdef _LP64
3273 len = new ConvI2LNode(len);
3274 _igvn.register_new_node_with_optimizer(len);
3275 #endif
3276 call->init_req(TypeFunc::Parms + cnt++, len);
3277 #ifdef _LP64
3278 call->init_req(TypeFunc::Parms + cnt++, C->top());
3279 #endif
3280 call->init_req(TypeFunc::Control, head->init_control());
3281 call->init_req(TypeFunc::I_O, C->top()); // Does no I/O.
3282 call->init_req(TypeFunc::Memory, mem_phi->in(LoopNode::EntryControl));
3283 call->init_req(TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr));
3284 call->init_req(TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr));
3285 _igvn.register_new_node_with_optimizer(call);
3286 result_ctrl = new ProjNode(call,TypeFunc::Control);
3287 _igvn.register_new_node_with_optimizer(result_ctrl);
3288 result_mem = new ProjNode(call,TypeFunc::Memory);
3289 _igvn.register_new_node_with_optimizer(result_mem);
3290
3291 /* Disable following optimization until proper fix (add missing checks).
3292
3293 // If this fill is tightly coupled to an allocation and overwrites
3294 // the whole body, allow it to take over the zeroing.
3295 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this);
3296 if (alloc != NULL && alloc->is_AllocateArray()) {
3297 Node* length = alloc->as_AllocateArray()->Ideal_length();
3298 if (head->limit() == length &&
3299 head->init_trip() == _igvn.intcon(0)) {
3300 if (TraceOptimizeFill) {
3301 tty->print_cr("Eliminated zeroing in allocation");
3302 }
3303 alloc->maybe_set_complete(&_igvn);
3304 } else {
|
3187 }
3188
3189 // Must have constant stride
3190 CountedLoopNode* head = lpt->_head->as_CountedLoop();
3191 if (!head->is_valid_counted_loop() || !head->is_normal_loop()) {
3192 return false;
3193 }
3194
3195 head->verify_strip_mined(1);
3196
3197 // Check that the body only contains a store of a loop invariant
3198 // value that is indexed by the loop phi.
3199 Node* store = NULL;
3200 Node* store_value = NULL;
3201 Node* shift = NULL;
3202 Node* offset = NULL;
3203 if (!match_fill_loop(lpt, store, store_value, shift, offset)) {
3204 return false;
3205 }
3206
3207 Node* exit = head->loopexit()->proj_out_or_null(0);
3208 if (exit == NULL) {
3209 return false;
3210 }
3211
3212 #ifndef PRODUCT
3213 if (TraceLoopOpts) {
3214 tty->print("ArrayFill ");
3215 lpt->dump_head();
3216 }
3217 #endif
3218
3219 // Now replace the whole loop body by a call to a fill routine that
3220 // covers the same region as the loop.
3221 Node* base = store->in(MemNode::Address)->as_AddP()->in(AddPNode::Base);
3222
3223 // Build an expression for the beginning of the copy region
3224 Node* index = head->init_trip();
3225 #ifdef _LP64
3226 index = new ConvI2LNode(index);
3227 _igvn.register_new_node_with_optimizer(index);
3263 Node* mem_phi = store->in(MemNode::Memory);
3264 Node* result_ctrl;
3265 Node* result_mem;
3266 const TypeFunc* call_type = OptoRuntime::array_fill_Type();
3267 CallLeafNode *call = new CallLeafNoFPNode(call_type, fill,
3268 fill_name, TypeAryPtr::get_array_body_type(t));
3269 uint cnt = 0;
3270 call->init_req(TypeFunc::Parms + cnt++, from);
3271 call->init_req(TypeFunc::Parms + cnt++, store_value);
3272 #ifdef _LP64
3273 len = new ConvI2LNode(len);
3274 _igvn.register_new_node_with_optimizer(len);
3275 #endif
3276 call->init_req(TypeFunc::Parms + cnt++, len);
3277 #ifdef _LP64
3278 call->init_req(TypeFunc::Parms + cnt++, C->top());
3279 #endif
3280 call->init_req(TypeFunc::Control, head->init_control());
3281 call->init_req(TypeFunc::I_O, C->top()); // Does no I/O.
3282 call->init_req(TypeFunc::Memory, mem_phi->in(LoopNode::EntryControl));
3283 call->init_req(TypeFunc::ReturnAdr, C->start()->proj_out_or_null(TypeFunc::ReturnAdr));
3284 call->init_req(TypeFunc::FramePtr, C->start()->proj_out_or_null(TypeFunc::FramePtr));
3285 _igvn.register_new_node_with_optimizer(call);
3286 result_ctrl = new ProjNode(call,TypeFunc::Control);
3287 _igvn.register_new_node_with_optimizer(result_ctrl);
3288 result_mem = new ProjNode(call,TypeFunc::Memory);
3289 _igvn.register_new_node_with_optimizer(result_mem);
3290
3291 /* Disable following optimization until proper fix (add missing checks).
3292
3293 // If this fill is tightly coupled to an allocation and overwrites
3294 // the whole body, allow it to take over the zeroing.
3295 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this);
3296 if (alloc != NULL && alloc->is_AllocateArray()) {
3297 Node* length = alloc->as_AllocateArray()->Ideal_length();
3298 if (head->limit() == length &&
3299 head->init_trip() == _igvn.intcon(0)) {
3300 if (TraceOptimizeFill) {
3301 tty->print_cr("Eliminated zeroing in allocation");
3302 }
3303 alloc->maybe_set_complete(&_igvn);
3304 } else {
|