761 ((InstructForm*)this)->dump();
762 // pretend it has multiple uses and no defs
763 return MANY_MEMORY_OPERANDS;
764 }
765 }
766
767 return NO_MEMORY_OPERAND;
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,"CastDD") ||
776 !strcmp(_matrule->_rChild->_opType,"CastFF") ||
777 !strcmp(_matrule->_rChild->_opType,"CastII") ||
778 !strcmp(_matrule->_rChild->_opType,"CastLL") ||
779 !strcmp(_matrule->_rChild->_opType,"CastVV") ||
780 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
781 !strcmp(_matrule->_rChild->_opType,"DecodeN") ||
782 !strcmp(_matrule->_rChild->_opType,"EncodeP") ||
783 !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
784 !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
785 !strcmp(_matrule->_rChild->_opType,"LoadN") ||
786 !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
787 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
788 !strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
789 !strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
790 !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
791 !strcmp(_matrule->_rChild->_opType,"RotateLeft") ||
792 !strcmp(_matrule->_rChild->_opType,"RotateRight") ||
793 #if INCLUDE_SHENANDOAHGC
794 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") ||
795 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") ||
796 #endif
797 !strcmp(_matrule->_rChild->_opType,"StrInflatedCopy") ||
798 !strcmp(_matrule->_rChild->_opType,"VectorCmpMasked")||
799 !strcmp(_matrule->_rChild->_opType,"VectorMaskGen")||
800 !strcmp(_matrule->_rChild->_opType,"VerifyVectorAlignment")||
801 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") ||
802 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true;
803 else if ( is_ideal_load() == Form::idealP ) return true;
804 else if ( is_ideal_store() != Form::none ) return true;
805
806 if (needs_base_oop_edge(globals)) return true;
807
808 if (is_vector()) return true;
809 if (is_mach_constant()) return true;
810
811 return false;
812 }
813
814
815 // Access instr_cost attribute or return null.
816 const char* InstructForm::cost() {
817 for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) {
818 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
819 return cur->_val;
820 }
821 }
822 return nullptr;
823 }
824
825 // Return count of top-level operands.
826 uint InstructForm::num_opnds() {
827 int num_opnds = _components.num_operands();
828
829 // Need special handling for matching some ideal nodes
830 // i.e. Matching a return node
831 /*
882 const char *InstructForm::out_reg_class(FormDict &globals) {
883 assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented");
884
885 return nullptr;
886 }
887
888
889
890 // Lookup the starting position of inputs we are interested in wrt. ideal nodes
891 uint InstructForm::oper_input_base(FormDict &globals) {
892 if( !_matrule ) return 1; // Skip control for most nodes
893
894 // Need special handling for matching some ideal nodes
895 // i.e. Matching a return node
896 if( strcmp(_matrule->_opType,"Return" )==0 ||
897 strcmp(_matrule->_opType,"Rethrow" )==0 ||
898 strcmp(_matrule->_opType,"TailCall" )==0 ||
899 strcmp(_matrule->_opType,"TailJump" )==0 ||
900 strcmp(_matrule->_opType,"ForwardException")==0 ||
901 strcmp(_matrule->_opType,"SafePoint" )==0 ||
902 strcmp(_matrule->_opType,"Halt" )==0 )
903 return AdlcVMDeps::Parms; // Skip the machine-state edges
904
905 if( _matrule->_rChild &&
906 ( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
907 strcmp(_matrule->_rChild->_opType,"VectorizedHashCode")==0 ||
908 strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
909 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
910 strcmp(_matrule->_rChild->_opType,"StrInflatedCopy" )==0 ||
911 strcmp(_matrule->_rChild->_opType,"StrCompressedCopy" )==0 ||
912 strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
913 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 ||
914 strcmp(_matrule->_rChild->_opType,"CountPositives")==0 ||
915 strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
916 // String.(compareTo/equals/indexOf/hashCode) and Arrays.equals
917 // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
918 // take 1 control and 1 memory edges.
919 // Also String.(compressedCopy/inflatedCopy).
920 return 2;
921 }
922
3624 void MatchNode::output(FILE *fp) {
3625 if (_lChild==0 && _rChild==0) {
3626 fprintf(fp," %s",_name); // operand
3627 }
3628 else {
3629 fprintf(fp," (%s ",_name); // " (opcodeName "
3630 if(_lChild) _lChild->output(fp); // left operand
3631 if(_rChild) _rChild->output(fp); // right operand
3632 fprintf(fp,")"); // ")"
3633 }
3634 }
3635
3636 void MatchNode::forms_do(FormClosure *f) {
3637 f->do_form_by_name(_name);
3638 if (_lChild) f->do_form(_lChild);
3639 if (_rChild) f->do_form(_rChild);
3640 }
3641
3642 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3643 static const char *needs_ideal_memory_list[] = {
3644 "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
3645 "StoreB","StoreC","Store" ,"StoreFP",
3646 "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
3647 "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
3648 "StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked",
3649 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
3650 "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3651 "CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3652 "WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN",
3653 "CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN",
3654 #if INCLUDE_SHENANDOAHGC
3655 "ShenandoahCompareAndSwapN", "ShenandoahCompareAndSwapP", "ShenandoahWeakCompareAndSwapP", "ShenandoahWeakCompareAndSwapN", "ShenandoahCompareAndExchangeP", "ShenandoahCompareAndExchangeN",
3656 #endif
3657 "GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
3658 "GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
3659 "ClearArray"
3660 };
3661 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3662 if( strcmp(_opType,"PrefetchAllocation")==0 )
3663 return 1;
3664 if( strcmp(_opType,"CacheWB")==0 )
|
761 ((InstructForm*)this)->dump();
762 // pretend it has multiple uses and no defs
763 return MANY_MEMORY_OPERANDS;
764 }
765 }
766
767 return NO_MEMORY_OPERAND;
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,"CastDD") ||
776 !strcmp(_matrule->_rChild->_opType,"CastFF") ||
777 !strcmp(_matrule->_rChild->_opType,"CastII") ||
778 !strcmp(_matrule->_rChild->_opType,"CastLL") ||
779 !strcmp(_matrule->_rChild->_opType,"CastVV") ||
780 !strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
781 !strcmp(_matrule->_rChild->_opType,"CastI2N") ||
782 !strcmp(_matrule->_rChild->_opType,"DecodeN") ||
783 !strcmp(_matrule->_rChild->_opType,"EncodeP") ||
784 !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
785 !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
786 !strcmp(_matrule->_rChild->_opType,"LoadN") ||
787 !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
788 !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
789 !strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
790 !strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
791 !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
792 !strcmp(_matrule->_rChild->_opType,"RotateLeft") ||
793 !strcmp(_matrule->_rChild->_opType,"RotateRight") ||
794 #if INCLUDE_SHENANDOAHGC
795 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") ||
796 !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") ||
797 #endif
798 !strcmp(_matrule->_rChild->_opType,"StrInflatedCopy") ||
799 !strcmp(_matrule->_rChild->_opType,"VectorCmpMasked")||
800 !strcmp(_matrule->_rChild->_opType,"VectorMaskGen")||
801 !strcmp(_matrule->_rChild->_opType,"VerifyVectorAlignment")||
802 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") ||
803 !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true;
804 else if ( is_ideal_load() == Form::idealP ) return true;
805 else if ( is_ideal_store() != Form::none ) return true;
806
807 if (needs_base_oop_edge(globals)) return true;
808
809 if (is_vector()) return true;
810 if (is_mach_constant()) return true;
811
812 return false;
813 }
814
815
816 // Access instr_cost attribute or return null.
817 const char* InstructForm::cost() {
818 for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) {
819 if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
820 return cur->_val;
821 }
822 }
823 return nullptr;
824 }
825
826 // Return count of top-level operands.
827 uint InstructForm::num_opnds() {
828 int num_opnds = _components.num_operands();
829
830 // Need special handling for matching some ideal nodes
831 // i.e. Matching a return node
832 /*
883 const char *InstructForm::out_reg_class(FormDict &globals) {
884 assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented");
885
886 return nullptr;
887 }
888
889
890
891 // Lookup the starting position of inputs we are interested in wrt. ideal nodes
892 uint InstructForm::oper_input_base(FormDict &globals) {
893 if( !_matrule ) return 1; // Skip control for most nodes
894
895 // Need special handling for matching some ideal nodes
896 // i.e. Matching a return node
897 if( strcmp(_matrule->_opType,"Return" )==0 ||
898 strcmp(_matrule->_opType,"Rethrow" )==0 ||
899 strcmp(_matrule->_opType,"TailCall" )==0 ||
900 strcmp(_matrule->_opType,"TailJump" )==0 ||
901 strcmp(_matrule->_opType,"ForwardException")==0 ||
902 strcmp(_matrule->_opType,"SafePoint" )==0 ||
903 strcmp(_matrule->_opType,"Halt" )==0 ||
904 strcmp(_matrule->_opType,"CallLeafNoFP")==0)
905 return AdlcVMDeps::Parms; // Skip the machine-state edges
906
907 if( _matrule->_rChild &&
908 ( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
909 strcmp(_matrule->_rChild->_opType,"VectorizedHashCode")==0 ||
910 strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
911 strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
912 strcmp(_matrule->_rChild->_opType,"StrInflatedCopy" )==0 ||
913 strcmp(_matrule->_rChild->_opType,"StrCompressedCopy" )==0 ||
914 strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
915 strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 ||
916 strcmp(_matrule->_rChild->_opType,"CountPositives")==0 ||
917 strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
918 // String.(compareTo/equals/indexOf/hashCode) and Arrays.equals
919 // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
920 // take 1 control and 1 memory edges.
921 // Also String.(compressedCopy/inflatedCopy).
922 return 2;
923 }
924
3626 void MatchNode::output(FILE *fp) {
3627 if (_lChild==0 && _rChild==0) {
3628 fprintf(fp," %s",_name); // operand
3629 }
3630 else {
3631 fprintf(fp," (%s ",_name); // " (opcodeName "
3632 if(_lChild) _lChild->output(fp); // left operand
3633 if(_rChild) _rChild->output(fp); // right operand
3634 fprintf(fp,")"); // ")"
3635 }
3636 }
3637
3638 void MatchNode::forms_do(FormClosure *f) {
3639 f->do_form_by_name(_name);
3640 if (_lChild) f->do_form(_lChild);
3641 if (_rChild) f->do_form(_rChild);
3642 }
3643
3644 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
3645 static const char *needs_ideal_memory_list[] = {
3646 "StoreI","StoreL","StoreLSpecial","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
3647 "StoreB","StoreC","Store" ,"StoreFP",
3648 "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,
3649 "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
3650 "StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked",
3651 "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
3652 "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
3653 "CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
3654 "WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN",
3655 "CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN",
3656 #if INCLUDE_SHENANDOAHGC
3657 "ShenandoahCompareAndSwapN", "ShenandoahCompareAndSwapP", "ShenandoahWeakCompareAndSwapP", "ShenandoahWeakCompareAndSwapN", "ShenandoahCompareAndExchangeP", "ShenandoahCompareAndExchangeN",
3658 #endif
3659 "GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
3660 "GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
3661 "ClearArray"
3662 };
3663 int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
3664 if( strcmp(_opType,"PrefetchAllocation")==0 )
3665 return 1;
3666 if( strcmp(_opType,"CacheWB")==0 )
|