changeset 2519: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 f8b038506985
children 08eb13460b3a
files src/share/vm/opto/graphKit.cpp src/share/vm/opto/graphKit.hpp src/share/vm/opto/idealKit.cpp src/share/vm/opto/idealKit.hpp src/share/vm/opto/library_call.cpp
diffstat 5 files changed, 129 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/graphKit.cpp	Fri Apr 01 21:45:33 2011 -0700
+++ b/src/share/vm/opto/graphKit.cpp	Sat Apr 02 09:49:27 2011 -0700
@@ -3385,10 +3385,15 @@
 #define __ ideal.
 
 void GraphKit::sync_kit(IdealKit& ideal) {
+  set_all_memory(__ merged_memory());
+  set_i_o(__ i_o());
+  set_control(__ ctrl());
+}
+
+void GraphKit::final_sync(IdealKit& ideal) {
   // Final sync IdealKit and graphKit.
   __ drain_delay_transform();
-  set_all_memory(__ merged_memory());
-  set_control(__ ctrl());
+  sync_kit(ideal);
 }
 
 // vanilla/CMS post barrier
@@ -3435,7 +3440,7 @@
   // (Else it's an array (or unknown), and we want more precise card marks.)
   assert(adr != NULL, "");
 
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   // Convert the pointer to an int prior to doing math on it
   Node* cast = __ CastPX(__ ctrl(), adr);
@@ -3461,7 +3466,7 @@
   }
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 
 // G1 pre/post barriers
@@ -3471,7 +3476,7 @@
                                     Node* val,
                                     const TypeOopPtr* val_type,
                                     BasicType bt) {
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   Node* tls = __ thread(); // ThreadLocalStorage
 
@@ -3548,7 +3553,7 @@
   } __ end_if();  // (!marking)
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 
 //
@@ -3614,7 +3619,7 @@
   // (Else it's an array (or unknown), and we want more precise card marks.)
   assert(adr != NULL, "");
 
-  IdealKit ideal(gvn(), control(), merged_memory(), true);
+  IdealKit ideal(this, true);
 
   Node* tls = __ thread(); // ThreadLocalStorage
 
@@ -3688,6 +3693,6 @@
   }
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(ideal);
+  final_sync(ideal);
 }
 #undef __
--- a/src/share/vm/opto/graphKit.hpp	Fri Apr 01 21:45:33 2011 -0700
+++ b/src/share/vm/opto/graphKit.hpp	Sat Apr 02 09:49:27 2011 -0700
@@ -662,7 +662,9 @@
             && Universe::heap()->can_elide_tlab_store_barriers());
   }
 
+  // Sync Ideal and Graph kits.
   void sync_kit(IdealKit& ideal);
+  void final_sync(IdealKit& ideal);
 
   // vanilla/CMS post barrier
   void write_barrier_post(Node *store, Node* obj,
--- a/src/share/vm/opto/idealKit.cpp	Fri Apr 01 21:45:33 2011 -0700
+++ b/src/share/vm/opto/idealKit.cpp	Sat Apr 02 09:49:27 2011 -0700
@@ -38,15 +38,16 @@
 const uint IdealKit::first_var = TypeFunc::Parms + 1;
 
 //----------------------------IdealKit-----------------------------------------
-IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms, bool has_declarations) :
-  _gvn(gvn), C(gvn.C) {
-  _initial_ctrl = control;
-  _initial_memory = mem;
+IdealKit::IdealKit(GraphKit* gkit, bool delay_all_transforms, bool has_declarations) :
+  _gvn(gkit->gvn()), C(gkit->C) {
+  _initial_ctrl = gkit->control();
+  _initial_memory = gkit->merged_memory();
+  _initial_i_o = gkit->i_o();
   _delay_all_transforms = delay_all_transforms;
   _var_ct = 0;
   _cvstate = NULL;
   // We can go memory state free or else we need the entire memory state
-  assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split");
+  assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split");
   int init_size = 5;
   _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
   _delay_transform  = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
@@ -56,6 +57,13 @@
   }
 }
 
+//----------------------------sync_kit-----------------------------------------
+void IdealKit::sync_kit(GraphKit* gkit) {
+  set_all_memory(gkit->merged_memory());
+  set_i_o(gkit->i_o());
+  set_ctrl(gkit->control());
+}
+
 //-------------------------------if_then-------------------------------------
 // Create:  if(left relop right)
 //          /  \
@@ -156,16 +164,14 @@
 // onto the stack.
 void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
   assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop");
-
-  // Sync IdealKit and graphKit.
-  gkit->set_all_memory(this->merged_memory());
-  gkit->set_control(this->ctrl());
-  // Add loop predicate.
-  gkit->add_predicate(nargs);
-  // Update IdealKit memory.
-  this->set_all_memory(gkit->merged_memory());
-  this->set_ctrl(gkit->control());
-
+  if (UseLoopPredicate) {
+    // Sync IdealKit and graphKit.
+    gkit->sync_kit(*this);
+    // Add loop predicate.
+    gkit->add_predicate(nargs);
+    // Update IdealKit memory.
+    sync_kit(gkit);
+  }
   set(iv, init);
   Node* head = make_label(1);
   bind(head);
@@ -280,6 +286,7 @@
   _cvstate = new_cvstate();   // initialize current cvstate
   set_ctrl(_initial_ctrl);    // initialize control in current cvstate
   set_all_memory(_initial_memory);// initialize memory in current cvstate
+  set_i_o(_initial_i_o);      // initialize i_o in current cvstate
   DEBUG_ONLY(_state->push(BlockS));
 }
 
@@ -421,6 +428,9 @@
   // Get the region for the join state
   Node* join_region = join->in(TypeFunc::Control);
   assert(join_region != NULL, "join region must exist");
+  if (join->in(TypeFunc::I_O) == NULL ) {
+    join->set_req(TypeFunc::I_O,  merging->in(TypeFunc::I_O));
+  }
   if (join->in(TypeFunc::Memory) == NULL ) {
     join->set_req(TypeFunc::Memory,  merging->in(TypeFunc::Memory));
     return;
@@ -467,6 +477,20 @@
       mms.set_memory(phi);
     }
   }
+
+  Node* join_io    = join->in(TypeFunc::I_O);
+  Node* merging_io = merging->in(TypeFunc::I_O);
+  if (join_io != merging_io) {
+    PhiNode* phi;
+    if (join_io->is_Phi() && join_io->as_Phi()->region() == join_region) {
+      phi = join_io->as_Phi();
+    } else {
+      phi = PhiNode::make(join_region, join_io, Type::ABIO);
+      phi = (PhiNode*) delay_transform(phi);
+      join->set_req(TypeFunc::I_O, phi);
+    }
+    phi->set_req(slot, merging_io);
+  }
 }
 
 
@@ -477,7 +501,8 @@
                               const char *leaf_name,
                               Node* parm0,
                               Node* parm1,
-                              Node* parm2) {
+                              Node* parm2,
+                              Node* parm3) {
 
   // We only handle taking in RawMem and modifying RawMem
   const TypePtr* adr_type = TypeRawPtr::BOTTOM;
@@ -498,6 +523,7 @@
   if (parm0 != NULL)  call->init_req(TypeFunc::Parms+0, parm0);
   if (parm1 != NULL)  call->init_req(TypeFunc::Parms+1, parm1);
   if (parm2 != NULL)  call->init_req(TypeFunc::Parms+2, parm2);
+  if (parm3 != NULL)  call->init_req(TypeFunc::Parms+3, parm3);
 
   // Node *c = _gvn.transform(call);
   call = (CallNode *) _gvn.transform(call);
@@ -516,3 +542,51 @@
   assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
          "call node must be constructed correctly");
 }
+
+
+void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
+                              address slow_call,
+                              const char *leaf_name,
+                              const TypePtr* adr_type,
+                              Node* parm0,
+                              Node* parm1,
+                              Node* parm2,
+                              Node* parm3) {
+
+  // We only handle taking in RawMem and modifying RawMem
+  uint adr_idx = C->get_alias_index(adr_type);
+
+  // Slow-path leaf call
+  int size = slow_call_type->domain()->cnt();
+  CallNode *call =  (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type);
+
+  // Set fixed predefined input arguments
+  call->init_req( TypeFunc::Control, ctrl() );
+  call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
+  // Narrow memory as only memory input
+  call->init_req( TypeFunc::Memory , memory(adr_idx));
+  call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ );
+  call->init_req( TypeFunc::ReturnAdr, top() );
+
+  if (parm0 != NULL)  call->init_req(TypeFunc::Parms+0, parm0);
+  if (parm1 != NULL)  call->init_req(TypeFunc::Parms+1, parm1);
+  if (parm2 != NULL)  call->init_req(TypeFunc::Parms+2, parm2);
+  if (parm3 != NULL)  call->init_req(TypeFunc::Parms+3, parm3);
+
+  // Node *c = _gvn.transform(call);
+  call = (CallNode *) _gvn.transform(call);
+  Node *c = call; // dbx gets confused with call call->dump()
+
+  // Slow leaf call has no side-effects, sets few values
+
+  set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
+
+  // Make memory for the call
+  Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+
+  // Set the RawPtr memory state only.
+  set_memory(mem, adr_idx);
+
+  assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
+         "call node must be constructed correctly");
+}
--- a/src/share/vm/opto/idealKit.hpp	Fri Apr 01 21:45:33 2011 -0700
+++ b/src/share/vm/opto/idealKit.hpp	Sat Apr 02 09:49:27 2011 -0700
@@ -108,6 +108,7 @@
   bool _delay_all_transforms;              // flag forcing all transforms to be delayed
   Node* _initial_ctrl;                     // saves initial control until variables declared
   Node* _initial_memory;                   // saves initial memory  until variables declared
+  Node* _initial_i_o;                      // saves initial i_o  until variables declared
 
   PhaseGVN& gvn() const { return _gvn; }
   // Create a new cvstate filled with nulls
@@ -142,17 +143,21 @@
   Node* memory(uint alias_idx);
 
  public:
-  IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false, bool has_declarations = false);
+  IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false);
   ~IdealKit() {
     stop();
     drain_delay_transform();
   }
+  void sync_kit(GraphKit* gkit);
+
   // Control
   Node* ctrl()                          { return _cvstate->in(TypeFunc::Control); }
   void set_ctrl(Node* ctrl)             { _cvstate->set_req(TypeFunc::Control, ctrl); }
   Node* top()                           { return C->top(); }
   MergeMemNode* merged_memory()         { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); }
   void set_all_memory(Node* mem)        { _cvstate->set_req(TypeFunc::Memory, mem); }
+  Node* i_o()                           { return _cvstate->in(TypeFunc::I_O); }
+  void set_i_o(Node* c)                 { _cvstate->set_req(TypeFunc::I_O, c); }
   void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); }
   Node* value(IdealVariable& v)         { return _cvstate->in(first_var + v.id()); }
   void dead(IdealVariable& v)           { set(v, (Node*)NULL); }
@@ -239,7 +244,18 @@
                       const char *leaf_name,
                       Node* parm0,
                       Node* parm1 = NULL,
-                      Node* parm2 = NULL);
+                      Node* parm2 = NULL,
+                      Node* parm3 = NULL);
+
+  void make_leaf_call_no_fp(const TypeFunc *slow_call_type,
+                            address slow_call,
+                            const char *leaf_name,
+                            const TypePtr* adr_type,
+                            Node* parm0,
+                            Node* parm1,
+                            Node* parm2,
+                            Node* parm3);
+
 };
 
 #endif // SHARE_VM_OPTO_IDEALKIT_HPP
--- a/src/share/vm/opto/library_call.cpp	Fri Apr 01 21:45:33 2011 -0700
+++ b/src/share/vm/opto/library_call.cpp	Sat Apr 02 09:49:27 2011 -0700
@@ -1120,7 +1120,7 @@
   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
 
-  IdealKit kit(gvn(), control(), merged_memory(), false, true);
+  IdealKit kit(this, false, true);
 #define __ kit.
   Node* zero             = __ ConI(0);
   Node* one              = __ ConI(1);
@@ -1171,7 +1171,7 @@
   __ bind(return_);
 
   // Final sync IdealKit and GraphKit.
-  sync_kit(kit);
+  final_sync(kit);
   Node* result = __ value(rtn);
 #undef __
   C->set_has_loops(true);
@@ -2318,22 +2318,20 @@
         // of it. So we need to emit code to conditionally do the proper type of
         // store.
 
-        IdealKit ideal(gvn(), control(),  merged_memory());
+        IdealKit ideal(this);
 #define __ ideal.
         // QQQ who knows what probability is here??
         __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
           // Sync IdealKit and graphKit.
-          set_all_memory( __ merged_memory());
-          set_control(__ ctrl());
+          sync_kit(ideal);
           Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
           // Update IdealKit memory.
-          __ set_all_memory(merged_memory());
-          __ set_ctrl(control());
+          __ sync_kit(this);
         } __ else_(); {
           __ store(__ ctrl(), adr, val, type, alias_type->index(), is_volatile);
         } __ end_if();
         // Final sync IdealKit and GraphKit.
-        sync_kit(ideal);
+        final_sync(ideal);
 #undef __
       }
     }