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_crecord.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 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index cd5c7d49..1ba98ae8 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -137,7 +137,7 @@ static int crec_isnonzero(CType *s, void *p) | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | 140 | static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, |
141 | void *svisnz) | 141 | void *svisnz) |
142 | { | 142 | { |
143 | CTSize dsize = d->size, ssize = s->size; | 143 | CTSize dsize = d->size, ssize = s->size; |
@@ -190,6 +190,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | |||
190 | #endif | 190 | #endif |
191 | xstore: | 191 | xstore: |
192 | if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J); | 192 | if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J); |
193 | if (dp == 0) return sp; | ||
193 | emitir(IRT(IR_XSTORE, dt), dp, sp); | 194 | emitir(IRT(IR_XSTORE, dt), dp, sp); |
194 | break; | 195 | break; |
195 | case CCX(I, C): | 196 | case CCX(I, C): |
@@ -290,6 +291,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | |||
290 | lj_trace_err(J, LJ_TRERR_NYICONV); | 291 | lj_trace_err(J, LJ_TRERR_NYICONV); |
291 | break; | 292 | break; |
292 | } | 293 | } |
294 | return 0; | ||
293 | } | 295 | } |
294 | 296 | ||
295 | /* -- Convert C type to TValue (load) ------------------------------------- */ | 297 | /* -- Convert C type to TValue (load) ------------------------------------- */ |
@@ -306,21 +308,18 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
306 | goto err_nyi; /* NYI: copyval of >64 bit integers. */ | 308 | goto err_nyi; /* NYI: copyval of >64 bit integers. */ |
307 | tr = emitir(IRT(IR_XLOAD, t), sp, 0); | 309 | tr = emitir(IRT(IR_XLOAD, t), sp, 0); |
308 | if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */ | 310 | if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */ |
309 | tr = emitconv(tr, IRT_NUM, t, 0); | 311 | return emitconv(tr, IRT_NUM, t, 0); |
310 | } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */ | 312 | } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */ |
311 | TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); | 313 | sp = tr; |
312 | TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, | ||
313 | lj_ir_kintp(J, sizeof(GCcdata))); | ||
314 | emitir(IRT(IR_XSTORE, t), ptr, tr); | ||
315 | lj_needsplit(J); | 314 | lj_needsplit(J); |
316 | return dp; | ||
317 | } else if ((sinfo & CTF_BOOL)) { | 315 | } else if ((sinfo & CTF_BOOL)) { |
318 | /* Assume not equal to zero. Fixup and emit pending guard later. */ | 316 | /* Assume not equal to zero. Fixup and emit pending guard later. */ |
319 | lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0)); | 317 | lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0)); |
320 | J->postproc = LJ_POST_FIXGUARD; | 318 | J->postproc = LJ_POST_FIXGUARD; |
321 | tr = TREF_TRUE; | 319 | return TREF_TRUE; |
320 | } else { | ||
321 | return tr; | ||
322 | } | 322 | } |
323 | return tr; | ||
324 | } else if (ctype_isptr(sinfo)) { | 323 | } else if (ctype_isptr(sinfo)) { |
325 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; | 324 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; |
326 | sp = emitir(IRT(IR_XLOAD, t), sp, 0); | 325 | sp = emitir(IRT(IR_XLOAD, t), sp, 0); |
@@ -345,13 +344,13 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
345 | err_nyi: | 344 | err_nyi: |
346 | lj_trace_err(J, LJ_TRERR_NYICONV); | 345 | lj_trace_err(J, LJ_TRERR_NYICONV); |
347 | } | 346 | } |
348 | /* Box pointer or ref. */ | 347 | /* Box pointer, ref or 64 bit integer. */ |
349 | return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, sid), sp); | 348 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp); |
350 | } | 349 | } |
351 | 350 | ||
352 | /* -- Convert TValue to C type (store) ------------------------------------ */ | 351 | /* -- Convert TValue to C type (store) ------------------------------------ */ |
353 | 352 | ||
354 | static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | 353 | static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) |
355 | { | 354 | { |
356 | CTState *cts = ctype_ctsG(J2G(J)); | 355 | CTState *cts = ctype_ctsG(J2G(J)); |
357 | CTypeID sid = CTID_P_VOID; | 356 | CTypeID sid = CTID_P_VOID; |
@@ -402,6 +401,12 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
402 | } else { | 401 | } else { |
403 | goto doconv; /* The pointer value was loaded, don't load number. */ | 402 | goto doconv; /* The pointer value was loaded, don't load number. */ |
404 | } | 403 | } |
404 | |||
405 | } else if (ctype_isnum(s->info) && s->size == 8) { | ||
406 | IRType t = (s->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64; | ||
407 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT64); | ||
408 | lj_needsplit(J); | ||
409 | goto doconv; | ||
405 | } else { | 410 | } else { |
406 | sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); | 411 | sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); |
407 | } | 412 | } |
@@ -418,7 +423,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
418 | s = ctype_get(cts, sid); | 423 | s = ctype_get(cts, sid); |
419 | doconv: | 424 | doconv: |
420 | if (ctype_isenum(d->info)) d = ctype_child(cts, d); | 425 | if (ctype_isenum(d->info)) d = ctype_child(cts, d); |
421 | crec_ct_ct(J, d, s, dp, sp, svisnz); | 426 | return crec_ct_ct(J, d, s, dp, sp, svisnz); |
422 | } | 427 | } |
423 | 428 | ||
424 | /* -- C data metamethods -------------------------------------------------- */ | 429 | /* -- C data metamethods -------------------------------------------------- */ |
@@ -578,15 +583,18 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
578 | CTState *cts = ctype_ctsG(J2G(J)); | 583 | CTState *cts = ctype_ctsG(J2G(J)); |
579 | CTSize sz; | 584 | CTSize sz; |
580 | CTInfo info = lj_ctype_info(cts, id, &sz); | 585 | CTInfo info = lj_ctype_info(cts, id, &sz); |
586 | CType *d = ctype_raw(cts, id); | ||
581 | TRef trid; | 587 | TRef trid; |
582 | if (sz == 0 || sz > 64 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) | 588 | if (sz == 0 || sz > 64 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) |
583 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */ | 589 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */ |
584 | trid = lj_ir_kint(J, id); | 590 | trid = lj_ir_kint(J, id); |
585 | if (ctype_isptr(info)) { | 591 | /* Use special instruction to box pointer or 64 bit integer. */ |
586 | TRef sp = J->base[1] ? J->base[1] : lj_ir_kptr(J, NULL); | 592 | if (ctype_isptr(info) || (ctype_isnum(info) && sz == 8)) { |
587 | J->base[0] = emitir(IRTG(IR_CNEWP, IRT_CDATA), trid, sp); | 593 | TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) : |
594 | ctype_isptr(info) ? lj_ir_kptr(J, NULL) : | ||
595 | (lj_needsplit(J), lj_ir_kint64(J, 0)); | ||
596 | J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp); | ||
588 | } else { | 597 | } else { |
589 | CType *d = ctype_raw(cts, id); | ||
590 | TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); | 598 | TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); |
591 | J->base[0] = trcd; | 599 | J->base[0] = trcd; |
592 | if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) { | 600 | if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) { |
@@ -598,7 +606,7 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
598 | TValue tv; | 606 | TValue tv; |
599 | TValue *sval = &tv; | 607 | TValue *sval = &tv; |
600 | MSize i; | 608 | MSize i; |
601 | setnumV(&tv, 0); | 609 | tv.u64 = 0; |
602 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) | 610 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) |
603 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ | 611 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ |
604 | for (i = 1, ofs = 0; ofs < sz; ofs += esize) { | 612 | for (i = 1, ofs = 0; ofs < sz; ofs += esize) { |
@@ -645,11 +653,16 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
645 | } | 653 | } |
646 | } | 654 | } |
647 | } else { | 655 | } else { |
648 | TRef sp, dp; | 656 | TRef dp; |
649 | single_init: | 657 | single_init: |
650 | sp = J->base[1] ? J->base[1] : lj_ir_kint(J, 0); | ||
651 | dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata))); | 658 | dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata))); |
652 | crec_ct_tv(J, d, dp, sp, &rd->argv[1]); | 659 | if (J->base[1]) { |
660 | crec_ct_tv(J, d, dp, J->base[1], &rd->argv[1]); | ||
661 | } else { | ||
662 | TValue tv; | ||
663 | tv.u64 = 0; | ||
664 | crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv); | ||
665 | } | ||
653 | } | 666 | } |
654 | } | 667 | } |
655 | } | 668 | } |
@@ -669,7 +682,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
669 | if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { | 682 | if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { |
670 | IRType dt; | 683 | IRType dt; |
671 | CTypeID id; | 684 | CTypeID id; |
672 | TRef tr, dp, ptr; | 685 | TRef tr; |
673 | MSize i; | 686 | MSize i; |
674 | lj_needsplit(J); | 687 | lj_needsplit(J); |
675 | if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || | 688 | if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || |
@@ -702,10 +715,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
702 | } else { | 715 | } else { |
703 | tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]); | 716 | tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]); |
704 | } | 717 | } |
705 | dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, id), TREF_NIL); | 718 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); |
706 | ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata))); | ||
707 | emitir(IRT(IR_XSTORE, dt), ptr, tr); | ||
708 | return dp; | ||
709 | } | 719 | } |
710 | return 0; | 720 | return 0; |
711 | } | 721 | } |
@@ -767,7 +777,7 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
767 | tr = emitir(IRT(IR_ADD, IRT_PTR), sp[0], tr); | 777 | tr = emitir(IRT(IR_ADD, IRT_PTR), sp[0], tr); |
768 | id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)), | 778 | id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)), |
769 | CTSIZE_PTR); | 779 | CTSIZE_PTR); |
770 | return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, id), tr); | 780 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); |
771 | } | 781 | } |
772 | } | 782 | } |
773 | 783 | ||
@@ -787,6 +797,11 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
787 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; | 797 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; |
788 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); | 798 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); |
789 | tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR); | 799 | tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR); |
800 | } else if (ctype_isnum(ct->info) && ct->size == 8) { | ||
801 | IRType t = (ct->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64; | ||
802 | tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64); | ||
803 | lj_needsplit(J); | ||
804 | goto ok; | ||
790 | } else { | 805 | } else { |
791 | tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); | 806 | tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); |
792 | } | 807 | } |
@@ -807,6 +822,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
807 | } else if (!tref_isnum(tr)) { | 822 | } else if (!tref_isnum(tr)) { |
808 | goto err_type; | 823 | goto err_type; |
809 | } | 824 | } |
825 | ok: | ||
810 | s[i] = ct; | 826 | s[i] = ct; |
811 | sp[i] = tr; | 827 | sp[i] = tr; |
812 | } | 828 | } |