diff options
author | Mike Pall <mike> | 2011-02-03 04:13:51 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-03 04:22:27 +0100 |
commit | df65b8b419c12327254dec0df116c62525aaabad (patch) | |
tree | b4ba6ea2841692123b49b3033420dbb7282cbcd6 /src/lj_opt_split.c | |
parent | 1027018b2135caf45057c3d3b3da03ffb0c6add3 (diff) | |
download | luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.gz luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.bz2 luajit-df65b8b419c12327254dec0df116c62525aaabad.zip |
FFI: Rename IR_CNEWP to IR_CNEWI and use it to box 64 bit integers.
Generates smaller IR and DCE eliminates many intermediate boxes.
Needs allocation sinking to eliminate the boxes kept alive by PHIs.
Diffstat (limited to '')
-rw-r--r-- | src/lj_opt_split.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index f53616b3..90b2b49c 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c | |||
@@ -159,7 +159,8 @@ static void split_ir(jit_State *J) | |||
159 | ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); | 159 | ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); |
160 | hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); | 160 | hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); |
161 | } else { | 161 | } else { |
162 | ir->prev = (IRRef1)ref; /* Identity substitution for loword. */ | 162 | ir->prev = ref; /* Identity substitution for loword. */ |
163 | hisubst[ref] = 0; | ||
163 | } | 164 | } |
164 | } | 165 | } |
165 | 166 | ||
@@ -168,6 +169,7 @@ static void split_ir(jit_State *J) | |||
168 | IRIns *ir = &oir[ref]; | 169 | IRIns *ir = &oir[ref]; |
169 | IRRef nref = lj_ir_nextins(J); | 170 | IRRef nref = lj_ir_nextins(J); |
170 | IRIns *nir = IR(nref); | 171 | IRIns *nir = IR(nref); |
172 | IRRef hi = 0; | ||
171 | 173 | ||
172 | /* Copy-substitute old instruction to new instruction. */ | 174 | /* Copy-substitute old instruction to new instruction. */ |
173 | nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev; | 175 | nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev; |
@@ -175,10 +177,11 @@ static void split_ir(jit_State *J) | |||
175 | ir->prev = nref; /* Loword substitution. */ | 177 | ir->prev = nref; /* Loword substitution. */ |
176 | nir->o = ir->o; | 178 | nir->o = ir->o; |
177 | nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI); | 179 | nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI); |
180 | hisubst[ref] = 0; | ||
178 | 181 | ||
179 | /* Split 64 bit instructions. */ | 182 | /* Split 64 bit instructions. */ |
180 | if (irt_isint64(ir->t)) { | 183 | if (irt_isint64(ir->t)) { |
181 | IRRef hi = hisubst[ir->op1]; | 184 | IRRef hiref = hisubst[ir->op1]; |
182 | nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ | 185 | nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ |
183 | switch (ir->o) { | 186 | switch (ir->o) { |
184 | case IR_ADD: | 187 | case IR_ADD: |
@@ -186,13 +189,13 @@ static void split_ir(jit_State *J) | |||
186 | /* Use plain op for hiword if loword cannot produce a carry/borrow. */ | 189 | /* Use plain op for hiword if loword cannot produce a carry/borrow. */ |
187 | if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) { | 190 | if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) { |
188 | ir->prev = nir->op1; /* Pass through loword. */ | 191 | ir->prev = nir->op1; /* Pass through loword. */ |
189 | nir->op1 = hi; nir->op2 = hisubst[ir->op2]; | 192 | nir->op1 = hiref; nir->op2 = hisubst[ir->op2]; |
190 | hi = nref; | 193 | hi = nref; |
191 | break; | 194 | break; |
192 | } | 195 | } |
193 | /* fallthrough */ | 196 | /* fallthrough */ |
194 | case IR_NEG: | 197 | case IR_NEG: |
195 | hi = split_emit(J, IRTI(IR_HIOP), hi, hisubst[ir->op2]); | 198 | hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]); |
196 | break; | 199 | break; |
197 | case IR_MUL: | 200 | case IR_MUL: |
198 | hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); | 201 | hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); |
@@ -212,6 +215,13 @@ static void split_ir(jit_State *J) | |||
212 | irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : | 215 | irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : |
213 | IRCALL_lj_carith_powu64); | 216 | IRCALL_lj_carith_powu64); |
214 | break; | 217 | break; |
218 | case IR_FLOAD: | ||
219 | lua_assert(ir->op2 == IRFL_CDATA_INT64); | ||
220 | hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64HI); | ||
221 | #if LJ_BE | ||
222 | ir->prev = hi; hi = nref; | ||
223 | #endif | ||
224 | break; | ||
215 | case IR_XLOAD: | 225 | case IR_XLOAD: |
216 | hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2); | 226 | hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2); |
217 | #if LJ_BE | 227 | #if LJ_BE |
@@ -220,19 +230,18 @@ static void split_ir(jit_State *J) | |||
220 | break; | 230 | break; |
221 | case IR_XSTORE: | 231 | case IR_XSTORE: |
222 | #if LJ_LE | 232 | #if LJ_LE |
223 | hi = hisubst[ir->op2]; | 233 | hiref = hisubst[ir->op2]; |
224 | #else | 234 | #else |
225 | hi = nir->op2; nir->op2 = hisubst[ir->op2]; | 235 | hiref = nir->op2; nir->op2 = hisubst[ir->op2]; |
226 | #endif | 236 | #endif |
227 | split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hi); | 237 | split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hiref); |
228 | continue; | 238 | break; |
229 | case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ | 239 | case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ |
230 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | 240 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); |
231 | if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ | 241 | if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ |
232 | hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); | 242 | hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); |
233 | } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ | 243 | } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ |
234 | /* Drop cast, since assembler doesn't care. */ | 244 | /* Drop cast, since assembler doesn't care. */ |
235 | hisubst[ref] = hi; | ||
236 | goto fwdlo; | 245 | goto fwdlo; |
237 | } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ | 246 | } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ |
238 | IRRef k31 = lj_ir_kint(J, 31); | 247 | IRRef k31 = lj_ir_kint(J, 31); |
@@ -242,27 +251,26 @@ static void split_ir(jit_State *J) | |||
242 | nir->op2 = k31; | 251 | nir->op2 = k31; |
243 | hi = nref; | 252 | hi = nref; |
244 | } else { /* Zero-extend to 64 bit. */ | 253 | } else { /* Zero-extend to 64 bit. */ |
245 | hisubst[ref] = lj_ir_kint(J, 0); | 254 | hi = lj_ir_kint(J, 0); |
246 | goto fwdlo; | 255 | goto fwdlo; |
247 | } | 256 | } |
248 | break; | 257 | break; |
249 | } | 258 | } |
250 | case IR_PHI: { | 259 | case IR_PHI: { |
251 | IRRef hi2; | 260 | IRRef hiref2; |
252 | if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || | 261 | if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || |
253 | nir->op1 == nir->op2) | 262 | nir->op1 == nir->op2) |
254 | J->cur.nins--; /* Drop useless PHIs. */ | 263 | J->cur.nins--; /* Drop useless PHIs. */ |
255 | hi2 = hisubst[ir->op2]; | 264 | hiref2 = hisubst[ir->op2]; |
256 | if (!((irref_isk(hi) && irref_isk(hi2)) || hi == hi2)) | 265 | if (!((irref_isk(hiref) && irref_isk(hiref2)) || hiref == hiref2)) |
257 | split_emit(J, IRTI(IR_PHI), hi, hi2); | 266 | split_emit(J, IRTI(IR_PHI), hiref, hiref2); |
258 | continue; | 267 | break; |
259 | } | 268 | } |
260 | default: | 269 | default: |
261 | lua_assert(ir->o <= IR_NE); | 270 | lua_assert(ir->o <= IR_NE); /* Comparisons. */ |
262 | split_emit(J, IRTGI(IR_HIOP), hi, hisubst[ir->op2]); /* Comparisons. */ | 271 | split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]); |
263 | continue; | 272 | break; |
264 | } | 273 | } |
265 | hisubst[ref] = hi; /* Store hiword substitution. */ | ||
266 | } else if (ir->o == IR_CONV) { /* See above, too. */ | 274 | } else if (ir->o == IR_CONV) { /* See above, too. */ |
267 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | 275 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); |
268 | if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ | 276 | if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ |
@@ -277,9 +285,13 @@ static void split_ir(jit_State *J) | |||
277 | nir->op1 = nir->op2 = 0; | 285 | nir->op1 = nir->op2 = 0; |
278 | } | 286 | } |
279 | } | 287 | } |
288 | } else if (ir->o == IR_CNEWI) { | ||
289 | if (hisubst[ir->op2]) | ||
290 | split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]); | ||
280 | } else if (ir->o == IR_LOOP) { | 291 | } else if (ir->o == IR_LOOP) { |
281 | J->loopref = nref; /* Needed by assembler. */ | 292 | J->loopref = nref; /* Needed by assembler. */ |
282 | } | 293 | } |
294 | hisubst[ref] = hi; /* Store hiword substitution. */ | ||
283 | } | 295 | } |
284 | 296 | ||
285 | /* Add PHI marks. */ | 297 | /* Add PHI marks. */ |