Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/idealKit.cpp @ 2444:07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
Summary: Added CallLeafNoFPNode generation to IdealKit. Added i_o synchronization.
Reviewed-by: never
author | kvn |
---|---|
date | Sat, 02 Apr 2011 09:49:27 -0700 |
parents | 9dc311b8473e |
children | 6c97c830fb6f |
comparison
equal
deleted
inserted
replaced
2443:f8b038506985 | 2444:07acc51c1d2a |
---|---|
36 // soak up spots in the inputs even though we only use early Control | 36 // soak up spots in the inputs even though we only use early Control |
37 // and Memory slots. (So far.) | 37 // and Memory slots. (So far.) |
38 const uint IdealKit::first_var = TypeFunc::Parms + 1; | 38 const uint IdealKit::first_var = TypeFunc::Parms + 1; |
39 | 39 |
40 //----------------------------IdealKit----------------------------------------- | 40 //----------------------------IdealKit----------------------------------------- |
41 IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms, bool has_declarations) : | 41 IdealKit::IdealKit(GraphKit* gkit, bool delay_all_transforms, bool has_declarations) : |
42 _gvn(gvn), C(gvn.C) { | 42 _gvn(gkit->gvn()), C(gkit->C) { |
43 _initial_ctrl = control; | 43 _initial_ctrl = gkit->control(); |
44 _initial_memory = mem; | 44 _initial_memory = gkit->merged_memory(); |
45 _initial_i_o = gkit->i_o(); | |
45 _delay_all_transforms = delay_all_transforms; | 46 _delay_all_transforms = delay_all_transforms; |
46 _var_ct = 0; | 47 _var_ct = 0; |
47 _cvstate = NULL; | 48 _cvstate = NULL; |
48 // We can go memory state free or else we need the entire memory state | 49 // We can go memory state free or else we need the entire memory state |
49 assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split"); | 50 assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split"); |
50 int init_size = 5; | 51 int init_size = 5; |
51 _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); | 52 _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); |
52 _delay_transform = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); | 53 _delay_transform = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); |
53 DEBUG_ONLY(_state = new (C->node_arena()) GrowableArray<int>(C->node_arena(), init_size, 0, 0)); | 54 DEBUG_ONLY(_state = new (C->node_arena()) GrowableArray<int>(C->node_arena(), init_size, 0, 0)); |
54 if (!has_declarations) { | 55 if (!has_declarations) { |
55 declarations_done(); | 56 declarations_done(); |
56 } | 57 } |
58 } | |
59 | |
60 //----------------------------sync_kit----------------------------------------- | |
61 void IdealKit::sync_kit(GraphKit* gkit) { | |
62 set_all_memory(gkit->merged_memory()); | |
63 set_i_o(gkit->i_o()); | |
64 set_ctrl(gkit->control()); | |
57 } | 65 } |
58 | 66 |
59 //-------------------------------if_then------------------------------------- | 67 //-------------------------------if_then------------------------------------- |
60 // Create: if(left relop right) | 68 // Create: if(left relop right) |
61 // / \ | 69 // / \ |
154 // | 162 // |
155 // Pushes the loop top cvstate first, then the else (loop exit) cvstate | 163 // Pushes the loop top cvstate first, then the else (loop exit) cvstate |
156 // onto the stack. | 164 // onto the stack. |
157 void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) { | 165 void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) { |
158 assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop"); | 166 assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop"); |
159 | 167 if (UseLoopPredicate) { |
160 // Sync IdealKit and graphKit. | 168 // Sync IdealKit and graphKit. |
161 gkit->set_all_memory(this->merged_memory()); | 169 gkit->sync_kit(*this); |
162 gkit->set_control(this->ctrl()); | 170 // Add loop predicate. |
163 // Add loop predicate. | 171 gkit->add_predicate(nargs); |
164 gkit->add_predicate(nargs); | 172 // Update IdealKit memory. |
165 // Update IdealKit memory. | 173 sync_kit(gkit); |
166 this->set_all_memory(gkit->merged_memory()); | 174 } |
167 this->set_ctrl(gkit->control()); | |
168 | |
169 set(iv, init); | 175 set(iv, init); |
170 Node* head = make_label(1); | 176 Node* head = make_label(1); |
171 bind(head); | 177 bind(head); |
172 _pending_cvstates->push(head); // push for use at end_loop | 178 _pending_cvstates->push(head); // push for use at end_loop |
173 _cvstate = copy_cvstate(); | 179 _cvstate = copy_cvstate(); |
278 //-----------------------------declarations_done------------------------------- | 284 //-----------------------------declarations_done------------------------------- |
279 void IdealKit::declarations_done() { | 285 void IdealKit::declarations_done() { |
280 _cvstate = new_cvstate(); // initialize current cvstate | 286 _cvstate = new_cvstate(); // initialize current cvstate |
281 set_ctrl(_initial_ctrl); // initialize control in current cvstate | 287 set_ctrl(_initial_ctrl); // initialize control in current cvstate |
282 set_all_memory(_initial_memory);// initialize memory in current cvstate | 288 set_all_memory(_initial_memory);// initialize memory in current cvstate |
289 set_i_o(_initial_i_o); // initialize i_o in current cvstate | |
283 DEBUG_ONLY(_state->push(BlockS)); | 290 DEBUG_ONLY(_state->push(BlockS)); |
284 } | 291 } |
285 | 292 |
286 //-----------------------------transform----------------------------------- | 293 //-----------------------------transform----------------------------------- |
287 Node* IdealKit::transform(Node* n) { | 294 Node* IdealKit::transform(Node* n) { |
419 void IdealKit::do_memory_merge(Node* merging, Node* join) { | 426 void IdealKit::do_memory_merge(Node* merging, Node* join) { |
420 | 427 |
421 // Get the region for the join state | 428 // Get the region for the join state |
422 Node* join_region = join->in(TypeFunc::Control); | 429 Node* join_region = join->in(TypeFunc::Control); |
423 assert(join_region != NULL, "join region must exist"); | 430 assert(join_region != NULL, "join region must exist"); |
431 if (join->in(TypeFunc::I_O) == NULL ) { | |
432 join->set_req(TypeFunc::I_O, merging->in(TypeFunc::I_O)); | |
433 } | |
424 if (join->in(TypeFunc::Memory) == NULL ) { | 434 if (join->in(TypeFunc::Memory) == NULL ) { |
425 join->set_req(TypeFunc::Memory, merging->in(TypeFunc::Memory)); | 435 join->set_req(TypeFunc::Memory, merging->in(TypeFunc::Memory)); |
426 return; | 436 return; |
427 } | 437 } |
428 | 438 |
465 phi->set_req(slot, merging_slice/* slow_path, slow_slice */); | 475 phi->set_req(slot, merging_slice/* slow_path, slow_slice */); |
466 // this updates join_m with the phi | 476 // this updates join_m with the phi |
467 mms.set_memory(phi); | 477 mms.set_memory(phi); |
468 } | 478 } |
469 } | 479 } |
480 | |
481 Node* join_io = join->in(TypeFunc::I_O); | |
482 Node* merging_io = merging->in(TypeFunc::I_O); | |
483 if (join_io != merging_io) { | |
484 PhiNode* phi; | |
485 if (join_io->is_Phi() && join_io->as_Phi()->region() == join_region) { | |
486 phi = join_io->as_Phi(); | |
487 } else { | |
488 phi = PhiNode::make(join_region, join_io, Type::ABIO); | |
489 phi = (PhiNode*) delay_transform(phi); | |
490 join->set_req(TypeFunc::I_O, phi); | |
491 } | |
492 phi->set_req(slot, merging_io); | |
493 } | |
470 } | 494 } |
471 | 495 |
472 | 496 |
473 //----------------------------- make_call ---------------------------- | 497 //----------------------------- make_call ---------------------------- |
474 // Trivial runtime call | 498 // Trivial runtime call |
475 void IdealKit::make_leaf_call(const TypeFunc *slow_call_type, | 499 void IdealKit::make_leaf_call(const TypeFunc *slow_call_type, |
476 address slow_call, | 500 address slow_call, |
477 const char *leaf_name, | 501 const char *leaf_name, |
478 Node* parm0, | 502 Node* parm0, |
479 Node* parm1, | 503 Node* parm1, |
480 Node* parm2) { | 504 Node* parm2, |
505 Node* parm3) { | |
481 | 506 |
482 // We only handle taking in RawMem and modifying RawMem | 507 // We only handle taking in RawMem and modifying RawMem |
483 const TypePtr* adr_type = TypeRawPtr::BOTTOM; | 508 const TypePtr* adr_type = TypeRawPtr::BOTTOM; |
484 uint adr_idx = C->get_alias_index(adr_type); | 509 uint adr_idx = C->get_alias_index(adr_type); |
485 | 510 |
496 call->init_req( TypeFunc::ReturnAdr, top() ); | 521 call->init_req( TypeFunc::ReturnAdr, top() ); |
497 | 522 |
498 if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); | 523 if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); |
499 if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); | 524 if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); |
500 if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); | 525 if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); |
526 if (parm3 != NULL) call->init_req(TypeFunc::Parms+3, parm3); | |
501 | 527 |
502 // Node *c = _gvn.transform(call); | 528 // Node *c = _gvn.transform(call); |
503 call = (CallNode *) _gvn.transform(call); | 529 call = (CallNode *) _gvn.transform(call); |
504 Node *c = call; // dbx gets confused with call call->dump() | 530 Node *c = call; // dbx gets confused with call call->dump() |
505 | 531 |
514 set_memory(mem, adr_idx); | 540 set_memory(mem, adr_idx); |
515 | 541 |
516 assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type), | 542 assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type), |
517 "call node must be constructed correctly"); | 543 "call node must be constructed correctly"); |
518 } | 544 } |
545 | |
546 | |
547 void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type, | |
548 address slow_call, | |
549 const char *leaf_name, | |
550 const TypePtr* adr_type, | |
551 Node* parm0, | |
552 Node* parm1, | |
553 Node* parm2, | |
554 Node* parm3) { | |
555 | |
556 // We only handle taking in RawMem and modifying RawMem | |
557 uint adr_idx = C->get_alias_index(adr_type); | |
558 | |
559 // Slow-path leaf call | |
560 int size = slow_call_type->domain()->cnt(); | |
561 CallNode *call = (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); | |
562 | |
563 // Set fixed predefined input arguments | |
564 call->init_req( TypeFunc::Control, ctrl() ); | |
565 call->init_req( TypeFunc::I_O , top() ) ; // does no i/o | |
566 // Narrow memory as only memory input | |
567 call->init_req( TypeFunc::Memory , memory(adr_idx)); | |
568 call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ ); | |
569 call->init_req( TypeFunc::ReturnAdr, top() ); | |
570 | |
571 if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); | |
572 if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); | |
573 if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); | |
574 if (parm3 != NULL) call->init_req(TypeFunc::Parms+3, parm3); | |
575 | |
576 // Node *c = _gvn.transform(call); | |
577 call = (CallNode *) _gvn.transform(call); | |
578 Node *c = call; // dbx gets confused with call call->dump() | |
579 | |
580 // Slow leaf call has no side-effects, sets few values | |
581 | |
582 set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); | |
583 | |
584 // Make memory for the call | |
585 Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); | |
586 | |
587 // Set the RawPtr memory state only. | |
588 set_memory(mem, adr_idx); | |
589 | |
590 assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type), | |
591 "call node must be constructed correctly"); | |
592 } |