diff options
| author | Mattias EngdegÄrd | 2021-12-30 18:48:53 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2022-01-02 14:01:31 +0100 |
| commit | 5dd261282d28548609f9cfc9d63811fa02639549 (patch) | |
| tree | a506cd5bd35521f2a920b707059e27d477c831e3 /src/bytecode.c | |
| parent | 43932a0d90c2e416e4e315397dd7df503b2d1fd6 (diff) | |
| download | emacs-5dd261282d28548609f9cfc9d63811fa02639549.tar.gz emacs-5dd261282d28548609f9cfc9d63811fa02639549.zip | |
Inline fixnum operations in bytecode interpreter
Since numeric operations are mostly done on fixnums, this gives a
speed-up for common code.
* src/bytecode.c (exec_byte_code): Inline fixnum comparisons and
operations with fixnum results: =, >, <, <=, >=, -, +, -, *, /, %, max
and min.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 138 |
1 files changed, 108 insertions, 30 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index f8ffec0348a..5d8842f40cb 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -1032,43 +1032,72 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1032 | 1032 | ||
| 1033 | CASE (Beqlsign): | 1033 | CASE (Beqlsign): |
| 1034 | { | 1034 | { |
| 1035 | Lisp_Object v1 = POP; | 1035 | Lisp_Object v2 = POP; |
| 1036 | TOP = arithcompare (TOP, v1, ARITH_EQUAL); | 1036 | Lisp_Object v1 = TOP; |
| 1037 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1038 | TOP = EQ (v1, v2) ? Qt : Qnil; | ||
| 1039 | else | ||
| 1040 | TOP = arithcompare (v1, v2, ARITH_EQUAL); | ||
| 1037 | NEXT; | 1041 | NEXT; |
| 1038 | } | 1042 | } |
| 1039 | 1043 | ||
| 1040 | CASE (Bgtr): | 1044 | CASE (Bgtr): |
| 1041 | { | 1045 | { |
| 1042 | Lisp_Object v1 = POP; | 1046 | Lisp_Object v2 = POP; |
| 1043 | TOP = arithcompare (TOP, v1, ARITH_GRTR); | 1047 | Lisp_Object v1 = TOP; |
| 1048 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1049 | TOP = XFIXNUM (v1) > XFIXNUM (v2) ? Qt : Qnil; | ||
| 1050 | else | ||
| 1051 | TOP = arithcompare (v1, v2, ARITH_GRTR); | ||
| 1044 | NEXT; | 1052 | NEXT; |
| 1045 | } | 1053 | } |
| 1046 | 1054 | ||
| 1047 | CASE (Blss): | 1055 | CASE (Blss): |
| 1048 | { | 1056 | { |
| 1049 | Lisp_Object v1 = POP; | 1057 | Lisp_Object v2 = POP; |
| 1050 | TOP = arithcompare (TOP, v1, ARITH_LESS); | 1058 | Lisp_Object v1 = TOP; |
| 1059 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1060 | TOP = XFIXNUM (v1) < XFIXNUM (v2) ? Qt : Qnil; | ||
| 1061 | else | ||
| 1062 | TOP = arithcompare (v1, v2, ARITH_LESS); | ||
| 1051 | NEXT; | 1063 | NEXT; |
| 1052 | } | 1064 | } |
| 1053 | 1065 | ||
| 1054 | CASE (Bleq): | 1066 | CASE (Bleq): |
| 1055 | { | 1067 | { |
| 1056 | Lisp_Object v1 = POP; | 1068 | Lisp_Object v2 = POP; |
| 1057 | TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL); | 1069 | Lisp_Object v1 = TOP; |
| 1070 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1071 | TOP = XFIXNUM (v1) <= XFIXNUM (v2) ? Qt : Qnil; | ||
| 1072 | else | ||
| 1073 | TOP = arithcompare (v1, v2, ARITH_LESS_OR_EQUAL); | ||
| 1058 | NEXT; | 1074 | NEXT; |
| 1059 | } | 1075 | } |
| 1060 | 1076 | ||
| 1061 | CASE (Bgeq): | 1077 | CASE (Bgeq): |
| 1062 | { | 1078 | { |
| 1063 | Lisp_Object v1 = POP; | 1079 | Lisp_Object v2 = POP; |
| 1064 | TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL); | 1080 | Lisp_Object v1 = TOP; |
| 1081 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1082 | TOP = XFIXNUM (v1) >= XFIXNUM (v2) ? Qt : Qnil; | ||
| 1083 | else | ||
| 1084 | TOP = arithcompare (v1, v2, ARITH_GRTR_OR_EQUAL); | ||
| 1065 | NEXT; | 1085 | NEXT; |
| 1066 | } | 1086 | } |
| 1067 | 1087 | ||
| 1068 | CASE (Bdiff): | 1088 | CASE (Bdiff): |
| 1069 | DISCARD (1); | 1089 | { |
| 1070 | TOP = Fminus (2, &TOP); | 1090 | Lisp_Object v2 = POP; |
| 1071 | NEXT; | 1091 | Lisp_Object v1 = TOP; |
| 1092 | EMACS_INT res; | ||
| 1093 | if (FIXNUMP (v1) && FIXNUMP (v2) | ||
| 1094 | && (res = XFIXNUM (v1) - XFIXNUM (v2), | ||
| 1095 | !FIXNUM_OVERFLOW_P (res))) | ||
| 1096 | TOP = make_fixnum (res); | ||
| 1097 | else | ||
| 1098 | TOP = Fminus (2, &TOP); | ||
| 1099 | NEXT; | ||
| 1100 | } | ||
| 1072 | 1101 | ||
| 1073 | CASE (Bnegate): | 1102 | CASE (Bnegate): |
| 1074 | TOP = (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM | 1103 | TOP = (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM |
| @@ -1077,34 +1106,83 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1077 | NEXT; | 1106 | NEXT; |
| 1078 | 1107 | ||
| 1079 | CASE (Bplus): | 1108 | CASE (Bplus): |
| 1080 | DISCARD (1); | 1109 | { |
| 1081 | TOP = Fplus (2, &TOP); | 1110 | Lisp_Object v2 = POP; |
| 1082 | NEXT; | 1111 | Lisp_Object v1 = TOP; |
| 1112 | EMACS_INT res; | ||
| 1113 | if (FIXNUMP (v1) && FIXNUMP (v2) | ||
| 1114 | && (res = XFIXNUM (v1) + XFIXNUM (v2), | ||
| 1115 | !FIXNUM_OVERFLOW_P (res))) | ||
| 1116 | TOP = make_fixnum (res); | ||
| 1117 | else | ||
| 1118 | TOP = Fplus (2, &TOP); | ||
| 1119 | NEXT; | ||
| 1120 | } | ||
| 1083 | 1121 | ||
| 1084 | CASE (Bmax): | 1122 | CASE (Bmax): |
| 1085 | DISCARD (1); | 1123 | { |
| 1086 | TOP = Fmax (2, &TOP); | 1124 | Lisp_Object v2 = POP; |
| 1087 | NEXT; | 1125 | Lisp_Object v1 = TOP; |
| 1126 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1127 | { | ||
| 1128 | if (XFIXNUM (v2) > XFIXNUM (v1)) | ||
| 1129 | TOP = v2; | ||
| 1130 | } | ||
| 1131 | else | ||
| 1132 | TOP = Fmax (2, &TOP); | ||
| 1133 | NEXT; | ||
| 1134 | } | ||
| 1088 | 1135 | ||
| 1089 | CASE (Bmin): | 1136 | CASE (Bmin): |
| 1090 | DISCARD (1); | 1137 | { |
| 1091 | TOP = Fmin (2, &TOP); | 1138 | Lisp_Object v2 = POP; |
| 1092 | NEXT; | 1139 | Lisp_Object v1 = TOP; |
| 1140 | if (FIXNUMP (v1) && FIXNUMP (v2)) | ||
| 1141 | { | ||
| 1142 | if (XFIXNUM (v2) < XFIXNUM (v1)) | ||
| 1143 | TOP = v2; | ||
| 1144 | } | ||
| 1145 | else | ||
| 1146 | TOP = Fmin (2, &TOP); | ||
| 1147 | NEXT; | ||
| 1148 | } | ||
| 1093 | 1149 | ||
| 1094 | CASE (Bmult): | 1150 | CASE (Bmult): |
| 1095 | DISCARD (1); | 1151 | { |
| 1096 | TOP = Ftimes (2, &TOP); | 1152 | Lisp_Object v2 = POP; |
| 1097 | NEXT; | 1153 | Lisp_Object v1 = TOP; |
| 1154 | intmax_t res; | ||
| 1155 | if (FIXNUMP (v1) && FIXNUMP (v2) | ||
| 1156 | && !INT_MULTIPLY_WRAPV (XFIXNUM (v1), XFIXNUM (v2), &res) | ||
| 1157 | && !FIXNUM_OVERFLOW_P (res)) | ||
| 1158 | TOP = make_fixnum (res); | ||
| 1159 | else | ||
| 1160 | TOP = Ftimes (2, &TOP); | ||
| 1161 | NEXT; | ||
| 1162 | } | ||
| 1098 | 1163 | ||
| 1099 | CASE (Bquo): | 1164 | CASE (Bquo): |
| 1100 | DISCARD (1); | 1165 | { |
| 1101 | TOP = Fquo (2, &TOP); | 1166 | Lisp_Object v2 = POP; |
| 1102 | NEXT; | 1167 | Lisp_Object v1 = TOP; |
| 1168 | EMACS_INT res; | ||
| 1169 | if (FIXNUMP (v1) && FIXNUMP (v2) && XFIXNUM (v2) != 0 | ||
| 1170 | && (res = XFIXNUM (v1) / XFIXNUM (v2), | ||
| 1171 | !FIXNUM_OVERFLOW_P (res))) | ||
| 1172 | TOP = make_fixnum (res); | ||
| 1173 | else | ||
| 1174 | TOP = Fquo (2, &TOP); | ||
| 1175 | NEXT; | ||
| 1176 | } | ||
| 1103 | 1177 | ||
| 1104 | CASE (Brem): | 1178 | CASE (Brem): |
| 1105 | { | 1179 | { |
| 1106 | Lisp_Object v1 = POP; | 1180 | Lisp_Object v2 = POP; |
| 1107 | TOP = Frem (TOP, v1); | 1181 | Lisp_Object v1 = TOP; |
| 1182 | if (FIXNUMP (v1) && FIXNUMP (v2) && XFIXNUM (v2) != 0) | ||
| 1183 | TOP = make_fixnum (XFIXNUM (v1) % XFIXNUM (v2)); | ||
| 1184 | else | ||
| 1185 | TOP = Frem (v1, v2); | ||
| 1108 | NEXT; | 1186 | NEXT; |
| 1109 | } | 1187 | } |
| 1110 | 1188 | ||