aboutsummaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-03 04:13:51 +0100
committerMike Pall <mike>2011-02-03 04:22:27 +0100
commitdf65b8b419c12327254dec0df116c62525aaabad (patch)
treeb4ba6ea2841692123b49b3033420dbb7282cbcd6 /src/lj_crecord.c
parent1027018b2135caf45057c3d3b3da03ffb0c6add3 (diff)
downloadluajit-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.c70
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
140static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, 140static 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
354static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) 353static 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);
419doconv: 424doconv:
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 }