< prev index next >

src/share/vm/adlc/formssel.cpp

Print this page




 622     if( !form ) continue;
 623     OpClassForm *op   = form->is_opclass();
 624     if( !op ) continue;
 625     if( form->interface_type(globals) == Form::memory_interface ) {
 626       if( comp->isa(Component::USE) ) USE_of_memory = true;
 627       if( comp->isa(Component::DEF) ) {
 628         OperandForm *oper = form->is_operand();
 629         if( oper && oper->is_user_name_for_sReg() ) {
 630           // Stack slots are unaliased memory handled by allocator
 631           oper = oper;  // debug stopping point !!!!!
 632         } else {
 633           DEF_of_memory = true;
 634         }
 635       }
 636     }
 637   }
 638   return (USE_of_memory && !DEF_of_memory);
 639 }
 640 
 641 
 642 bool InstructForm::is_wide_memory_kill(FormDict &globals) const {
 643   if( _matrule == NULL ) return false;
 644   if( !_matrule->_opType ) return false;
 645 
 646   if( strcmp(_matrule->_opType,"MemBarRelease") == 0 ) return true;
 647   if( strcmp(_matrule->_opType,"MemBarAcquire") == 0 ) return true;
 648   if( strcmp(_matrule->_opType,"MemBarReleaseLock") == 0 ) return true;
 649   if( strcmp(_matrule->_opType,"MemBarAcquireLock") == 0 ) return true;
 650   if( strcmp(_matrule->_opType,"MemBarStoreStore") == 0 ) return true;
 651   if( strcmp(_matrule->_opType,"MemBarVolatile") == 0 ) return true;
 652   if( strcmp(_matrule->_opType,"StoreFence") == 0 ) return true;
 653   if( strcmp(_matrule->_opType,"LoadFence") == 0 ) return true;
 654 
 655   return false;
 656 }
 657 
 658 int InstructForm::memory_operand(FormDict &globals) const {
 659   // Machine independent loads must be checked for anti-dependences
 660   // Check if instruction has a USE of a memory operand class, or a def.
 661   int USE_of_memory  = 0;
 662   int DEF_of_memory  = 0;
 663   const char*    last_memory_DEF = NULL; // to test DEF/USE pairing in asserts
 664   const char*    last_memory_USE = NULL;
 665   Component     *unique          = NULL;
 666   Component     *comp            = NULL;
 667   ComponentList &components      = (ComponentList &)_components;
 668 
 669   components.reset();
 670   while( (comp = components.iter()) != NULL ) {
 671     const Form  *form = globals[comp->_type];
 672     if( !form ) continue;
 673     OpClassForm *op   = form->is_opclass();
 674     if( !op ) continue;
 675     if( op->stack_slots_only(globals) )  continue;
 676     if( form->interface_type(globals) == Form::memory_interface ) {
 677       if( comp->isa(Component::DEF) ) {


 765 
 766   return NO_MEMORY_OPERAND;
 767 }
 768 
 769 
 770 // This instruction captures the machine-independent bottom_type
 771 // Expected use is for pointer vs oop determination for LoadP
 772 bool InstructForm::captures_bottom_type(FormDict &globals) const {
 773   if( _matrule && _matrule->_rChild &&
 774        (!strcmp(_matrule->_rChild->_opType,"CastPP")       ||  // new result type
 775         !strcmp(_matrule->_rChild->_opType,"CastX2P")      ||  // new result type
 776         !strcmp(_matrule->_rChild->_opType,"DecodeN")      ||
 777         !strcmp(_matrule->_rChild->_opType,"EncodeP")      ||
 778         !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
 779         !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
 780         !strcmp(_matrule->_rChild->_opType,"LoadN")        ||
 781         !strcmp(_matrule->_rChild->_opType,"LoadNKlass")   ||
 782         !strcmp(_matrule->_rChild->_opType,"CreateEx")     ||  // type of exception
 783         !strcmp(_matrule->_rChild->_opType,"CheckCastPP")  ||
 784         !strcmp(_matrule->_rChild->_opType,"GetAndSetP")   ||
 785         !strcmp(_matrule->_rChild->_opType,"GetAndSetN")) )  return true;

 786   else if ( is_ideal_load() == Form::idealP )                return true;
 787   else if ( is_ideal_store() != Form::none  )                return true;
 788 
 789   if (needs_base_oop_edge(globals)) return true;
 790 
 791   if (is_vector()) return true;
 792   if (is_mach_constant()) return true;
 793 
 794   return  false;
 795 }
 796 
 797 
 798 // Access instr_cost attribute or return NULL.
 799 const char* InstructForm::cost() {
 800   for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
 801     if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
 802       return cur->_val;
 803     }
 804   }
 805   return NULL;


1142     return "MachReturnNode";
1143   }
1144   else if (is_ideal_halt()) {
1145     return "MachHaltNode";
1146   }
1147   else if (is_ideal_safepoint()) {
1148     return "MachSafePointNode";
1149   }
1150   else if (is_ideal_if()) {
1151     return "MachIfNode";
1152   }
1153   else if (is_ideal_goto()) {
1154     return "MachGotoNode";
1155   }
1156   else if (is_ideal_fastlock()) {
1157     return "MachFastLockNode";
1158   }
1159   else if (is_ideal_nop()) {
1160     return "MachNopNode";
1161   }



1162   else if (is_mach_constant()) {
1163     return "MachConstantNode";
1164   }
1165   else if (captures_bottom_type(globals)) {
1166     return "MachTypeNode";
1167   } else {
1168     return "MachNode";
1169   }
1170   assert( false, "ShouldNotReachHere()");
1171   return NULL;
1172 }
1173 
1174 // Compare the instruction predicates for textual equality
1175 bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
1176   const Predicate *pred1  = instr1->_predicate;
1177   const Predicate *pred2  = instr2->_predicate;
1178   if( pred1 == NULL && pred2 == NULL ) {
1179     // no predicates means they are identical
1180     return true;
1181   }


1225       const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper);
1226     } else {
1227       cisc_spill_operand = Not_cisc_spillable;
1228     }
1229   } else {
1230     cisc_spill_operand = Not_cisc_spillable;
1231   }
1232 
1233   set_cisc_spill_operand(cisc_spill_operand);
1234   return (cisc_spill_operand != Not_cisc_spillable);
1235 }
1236 
1237 // Check to see if this instruction can be replaced with the short branch
1238 // instruction `short-branch'
1239 bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) {
1240   if (_matrule != NULL &&
1241       this != short_branch &&   // Don't match myself
1242       !is_short_branch() &&     // Don't match another short branch variant
1243       reduce_result() != NULL &&
1244       strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&
1245       _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) {

1246     // The instructions are equivalent.
1247 
1248     // Now verify that both instructions have the same parameters and
1249     // the same effects. Both branch forms should have the same inputs
1250     // and resulting projections to correctly replace a long branch node
1251     // with corresponding short branch node during code generation.
1252 
1253     bool different = false;
1254     if (short_branch->_components.count() != _components.count()) {
1255        different = true;
1256     } else if (_components.count() > 0) {
1257       short_branch->_components.reset();
1258       _components.reset();
1259       Component *comp;
1260       while ((comp = _components.iter()) != NULL) {
1261         Component *short_comp = short_branch->_components.iter();
1262         if (short_comp == NULL ||
1263             short_comp->_type != comp->_type ||
1264             short_comp->_usedef != comp->_usedef) {
1265           different = true;


3472     if(_rChild) _rChild->output(fp); //                    right operand
3473     fprintf(fp,")");                 //                                 ")"
3474   }
3475 }
3476 
3477 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3478   static const char *needs_ideal_memory_list[] = {
3479     "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
3480     "StoreB","StoreC","Store" ,"StoreFP",
3481     "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
3482     "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
3483     "StoreVector", "LoadVector",
3484     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3485     "LoadPLocked",
3486     "StorePConditional", "StoreIConditional", "StoreLConditional",
3487     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3488     "StoreCM",
3489     "ClearArray",
3490     "GetAndAddI", "GetAndSetI", "GetAndSetP",
3491     "GetAndAddL", "GetAndSetL", "GetAndSetN",

3492   };
3493   int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3494   if( strcmp(_opType,"PrefetchRead")==0 ||
3495       strcmp(_opType,"PrefetchWrite")==0 ||
3496       strcmp(_opType,"PrefetchAllocation")==0 )
3497     return 1;
3498   if( _lChild ) {
3499     const char *opType = _lChild->_opType;
3500     for( int i=0; i<cnt; i++ )
3501       if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3502         return 1;
3503     if( _lChild->needs_ideal_memory_edge(globals) )
3504       return 1;
3505   }
3506   if( _rChild ) {
3507     const char *opType = _rChild->_opType;
3508     for( int i=0; i<cnt; i++ )
3509       if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3510         return 1;
3511     if( _rChild->needs_ideal_memory_edge(globals) )




 622     if( !form ) continue;
 623     OpClassForm *op   = form->is_opclass();
 624     if( !op ) continue;
 625     if( form->interface_type(globals) == Form::memory_interface ) {
 626       if( comp->isa(Component::USE) ) USE_of_memory = true;
 627       if( comp->isa(Component::DEF) ) {
 628         OperandForm *oper = form->is_operand();
 629         if( oper && oper->is_user_name_for_sReg() ) {
 630           // Stack slots are unaliased memory handled by allocator
 631           oper = oper;  // debug stopping point !!!!!
 632         } else {
 633           DEF_of_memory = true;
 634         }
 635       }
 636     }
 637   }
 638   return (USE_of_memory && !DEF_of_memory);
 639 }
 640 
 641 
















 642 int InstructForm::memory_operand(FormDict &globals) const {
 643   // Machine independent loads must be checked for anti-dependences
 644   // Check if instruction has a USE of a memory operand class, or a def.
 645   int USE_of_memory  = 0;
 646   int DEF_of_memory  = 0;
 647   const char*    last_memory_DEF = NULL; // to test DEF/USE pairing in asserts
 648   const char*    last_memory_USE = NULL;
 649   Component     *unique          = NULL;
 650   Component     *comp            = NULL;
 651   ComponentList &components      = (ComponentList &)_components;
 652 
 653   components.reset();
 654   while( (comp = components.iter()) != NULL ) {
 655     const Form  *form = globals[comp->_type];
 656     if( !form ) continue;
 657     OpClassForm *op   = form->is_opclass();
 658     if( !op ) continue;
 659     if( op->stack_slots_only(globals) )  continue;
 660     if( form->interface_type(globals) == Form::memory_interface ) {
 661       if( comp->isa(Component::DEF) ) {


 749 
 750   return NO_MEMORY_OPERAND;
 751 }
 752 
 753 
 754 // This instruction captures the machine-independent bottom_type
 755 // Expected use is for pointer vs oop determination for LoadP
 756 bool InstructForm::captures_bottom_type(FormDict &globals) const {
 757   if( _matrule && _matrule->_rChild &&
 758        (!strcmp(_matrule->_rChild->_opType,"CastPP")       ||  // new result type
 759         !strcmp(_matrule->_rChild->_opType,"CastX2P")      ||  // new result type
 760         !strcmp(_matrule->_rChild->_opType,"DecodeN")      ||
 761         !strcmp(_matrule->_rChild->_opType,"EncodeP")      ||
 762         !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
 763         !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
 764         !strcmp(_matrule->_rChild->_opType,"LoadN")        ||
 765         !strcmp(_matrule->_rChild->_opType,"LoadNKlass")   ||
 766         !strcmp(_matrule->_rChild->_opType,"CreateEx")     ||  // type of exception
 767         !strcmp(_matrule->_rChild->_opType,"CheckCastPP")  ||
 768         !strcmp(_matrule->_rChild->_opType,"GetAndSetP")   ||
 769         !strcmp(_matrule->_rChild->_opType,"GetAndSetN")   ||
 770         !strcmp(_matrule->_rChild->_opType,"ShenandoahReadBarrier"))) return true;
 771   else if ( is_ideal_load() == Form::idealP )                return true;
 772   else if ( is_ideal_store() != Form::none  )                return true;
 773 
 774   if (needs_base_oop_edge(globals)) return true;
 775 
 776   if (is_vector()) return true;
 777   if (is_mach_constant()) return true;
 778 
 779   return  false;
 780 }
 781 
 782 
 783 // Access instr_cost attribute or return NULL.
 784 const char* InstructForm::cost() {
 785   for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
 786     if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
 787       return cur->_val;
 788     }
 789   }
 790   return NULL;


1127     return "MachReturnNode";
1128   }
1129   else if (is_ideal_halt()) {
1130     return "MachHaltNode";
1131   }
1132   else if (is_ideal_safepoint()) {
1133     return "MachSafePointNode";
1134   }
1135   else if (is_ideal_if()) {
1136     return "MachIfNode";
1137   }
1138   else if (is_ideal_goto()) {
1139     return "MachGotoNode";
1140   }
1141   else if (is_ideal_fastlock()) {
1142     return "MachFastLockNode";
1143   }
1144   else if (is_ideal_nop()) {
1145     return "MachNopNode";
1146   }
1147   else if (is_ideal_membar()) {
1148     return "MachMemBarNode";
1149   }
1150   else if (is_mach_constant()) {
1151     return "MachConstantNode";
1152   }
1153   else if (captures_bottom_type(globals)) {
1154     return "MachTypeNode";
1155   } else {
1156     return "MachNode";
1157   }
1158   assert( false, "ShouldNotReachHere()");
1159   return NULL;
1160 }
1161 
1162 // Compare the instruction predicates for textual equality
1163 bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
1164   const Predicate *pred1  = instr1->_predicate;
1165   const Predicate *pred2  = instr2->_predicate;
1166   if( pred1 == NULL && pred2 == NULL ) {
1167     // no predicates means they are identical
1168     return true;
1169   }


1213       const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper);
1214     } else {
1215       cisc_spill_operand = Not_cisc_spillable;
1216     }
1217   } else {
1218     cisc_spill_operand = Not_cisc_spillable;
1219   }
1220 
1221   set_cisc_spill_operand(cisc_spill_operand);
1222   return (cisc_spill_operand != Not_cisc_spillable);
1223 }
1224 
1225 // Check to see if this instruction can be replaced with the short branch
1226 // instruction `short-branch'
1227 bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) {
1228   if (_matrule != NULL &&
1229       this != short_branch &&   // Don't match myself
1230       !is_short_branch() &&     // Don't match another short branch variant
1231       reduce_result() != NULL &&
1232       strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&
1233       _matrule->equivalent(AD.globalNames(), short_branch->_matrule) &&
1234       equivalent_predicates(this, short_branch)) {
1235     // The instructions are equivalent.
1236 
1237     // Now verify that both instructions have the same parameters and
1238     // the same effects. Both branch forms should have the same inputs
1239     // and resulting projections to correctly replace a long branch node
1240     // with corresponding short branch node during code generation.
1241 
1242     bool different = false;
1243     if (short_branch->_components.count() != _components.count()) {
1244        different = true;
1245     } else if (_components.count() > 0) {
1246       short_branch->_components.reset();
1247       _components.reset();
1248       Component *comp;
1249       while ((comp = _components.iter()) != NULL) {
1250         Component *short_comp = short_branch->_components.iter();
1251         if (short_comp == NULL ||
1252             short_comp->_type != comp->_type ||
1253             short_comp->_usedef != comp->_usedef) {
1254           different = true;


3461     if(_rChild) _rChild->output(fp); //                    right operand
3462     fprintf(fp,")");                 //                                 ")"
3463   }
3464 }
3465 
3466 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3467   static const char *needs_ideal_memory_list[] = {
3468     "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
3469     "StoreB","StoreC","Store" ,"StoreFP",
3470     "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
3471     "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
3472     "StoreVector", "LoadVector",
3473     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3474     "LoadPLocked",
3475     "StorePConditional", "StoreIConditional", "StoreLConditional",
3476     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3477     "StoreCM",
3478     "ClearArray",
3479     "GetAndAddI", "GetAndSetI", "GetAndSetP",
3480     "GetAndAddL", "GetAndSetL", "GetAndSetN",
3481     "ShenandoahReadBarrier",
3482   };
3483   int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3484   if( strcmp(_opType,"PrefetchRead")==0 ||
3485       strcmp(_opType,"PrefetchWrite")==0 ||
3486       strcmp(_opType,"PrefetchAllocation")==0 )
3487     return 1;
3488   if( _lChild ) {
3489     const char *opType = _lChild->_opType;
3490     for( int i=0; i<cnt; i++ )
3491       if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3492         return 1;
3493     if( _lChild->needs_ideal_memory_edge(globals) )
3494       return 1;
3495   }
3496   if( _rChild ) {
3497     const char *opType = _rChild->_opType;
3498     for( int i=0; i<cnt; i++ )
3499       if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
3500         return 1;
3501     if( _rChild->needs_ideal_memory_edge(globals) )


< prev index next >