@@ -69,7 +69,7 @@ const char *ir_op_name[IR_LAST_OP] = {
6969
7070void ir_print_const (const ir_ctx * ctx , const ir_insn * insn , FILE * f , bool quoted )
7171{
72- if (insn -> op == IR_FUNC ) {
72+ if (insn -> op == IR_FUNC || insn -> op == IR_SYM ) {
7373 fprintf (f , "%s" , ir_get_str (ctx , insn -> val .i32 ));
7474 return ;
7575 } else if (insn -> op == IR_STR ) {
@@ -462,7 +462,7 @@ ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t addr)
462462 return ref ;
463463}
464464
465- IR_NEVER_INLINE ir_ref ir_const (ir_ctx * ctx , ir_val val , uint8_t type )
465+ static IR_NEVER_INLINE ir_ref ir_const_ex (ir_ctx * ctx , ir_val val , uint8_t type , uint32_t optx )
466466{
467467 ir_insn * insn , * prev_insn ;
468468 ir_ref ref , prev ;
@@ -477,7 +477,7 @@ IR_NEVER_INLINE ir_ref ir_const(ir_ctx *ctx, ir_val val, uint8_t type)
477477 while (ref ) {
478478 insn = & ctx -> ir_base [ref ];
479479 if (UNEXPECTED (insn -> val .u64 >= val .u64 )) {
480- if (insn -> val .u64 == val .u64 ) {
480+ if (insn -> val .u64 == val .u64 && insn -> optx == optx ) {
481481 return ref ;
482482 } else {
483483 break ;
@@ -499,12 +499,17 @@ IR_NEVER_INLINE ir_ref ir_const(ir_ctx *ctx, ir_val val, uint8_t type)
499499 insn = & ctx -> ir_base [ref ];
500500 insn -> prev_const = prev ;
501501
502- insn -> optx = IR_OPT ( type , type ) ;
502+ insn -> optx = optx ;
503503 insn -> val .u64 = val .u64 ;
504504
505505 return ref ;
506506}
507507
508+ ir_ref ir_const (ir_ctx * ctx , ir_val val , uint8_t type )
509+ {
510+ return ir_const_ex (ctx , val , type , IR_OPT (type , type ));
511+ }
512+
508513ir_ref ir_const_i8 (ir_ctx * ctx , int8_t c )
509514{
510515 ir_val val ;
@@ -600,47 +605,33 @@ ir_ref ir_const_addr(ir_ctx *ctx, uintptr_t c)
600605
601606ir_ref ir_const_func_addr (ir_ctx * ctx , uintptr_t c , uint16_t flags )
602607{
603- ir_ref top = - ctx -> consts_count ;
604- ir_ref ref ;
605- ir_insn * insn ;
606-
607608 if (c == 0 ) {
608609 return IR_NULL ;
609610 }
610611 ir_val val ;
611612 val .u64 = c ;
612- ref = ir_const (ctx , val , IR_ADDR );
613- if (ref == top ) {
614- insn = & ctx -> ir_base [ref ];
615- insn -> optx = IR_OPT (IR_FUNC_ADDR , IR_ADDR );
616- insn -> const_flags = flags ;
617- } else {
618- IR_ASSERT (ctx -> ir_base [ref ].opt == IR_OPT (IR_FUNC_ADDR , IR_ADDR ) && ctx -> ir_base [ref ].const_flags == flags );
619- }
620- return ref ;
613+ return ir_const_ex (ctx , val , IR_ADDR , IR_OPTX (IR_FUNC_ADDR , IR_ADDR , flags ));
621614}
622615
623616ir_ref ir_const_func (ir_ctx * ctx , ir_ref str , uint16_t flags )
624617{
625- ir_ref ref = ir_next_const (ctx );
626- ir_insn * insn = & ctx -> ir_base [ref ];
627-
628- insn -> optx = IR_OPT (IR_FUNC , IR_ADDR );
629- insn -> const_flags = flags ;
630- insn -> val .addr = str ;
618+ ir_val val ;
619+ val .addr = str ;
620+ return ir_const_ex (ctx , val , IR_ADDR , IR_OPTX (IR_FUNC , IR_ADDR , flags ));
621+ }
631622
632- return ref ;
623+ ir_ref ir_const_sym (ir_ctx * ctx , ir_ref str )
624+ {
625+ ir_val val ;
626+ val .addr = str ;
627+ return ir_const_ex (ctx , val , IR_ADDR , IR_OPTX (IR_SYM , IR_ADDR , 0 ));
633628}
634629
635630ir_ref ir_const_str (ir_ctx * ctx , ir_ref str )
636631{
637- ir_ref ref = ir_next_const (ctx );
638- ir_insn * insn = & ctx -> ir_base [ref ];
639-
640- insn -> optx = IR_OPT (IR_STR , IR_ADDR );
641- insn -> val .addr = str ;
642-
643- return ref ;
632+ ir_val val ;
633+ val .addr = str ;
634+ return ir_const_ex (ctx , val , IR_ADDR , IR_OPTX (IR_STR , IR_ADDR , 0 ));
644635}
645636
646637ir_ref ir_str (ir_ctx * ctx , const char * s )
@@ -1997,26 +1988,26 @@ void _ir_UNREACHABLE(ir_ctx *ctx)
19971988 ctx -> control = IR_UNUSED ;
19981989}
19991990
2000- void _ir_TAILCALL (ir_ctx * ctx , ir_ref func )
1991+ void _ir_TAILCALL (ir_ctx * ctx , ir_type type , ir_ref func )
20011992{
20021993 IR_ASSERT (ctx -> control );
2003- ctx -> control = ir_emit2 (ctx , IR_OPTX (IR_TAILCALL , IR_VOID , 2 ), ctx -> control , func );
1994+ ctx -> control = ir_emit2 (ctx , IR_OPTX (IR_TAILCALL , type , 2 ), ctx -> control , func );
20041995 _ir_UNREACHABLE (ctx );
20051996}
20061997
2007- void _ir_TAILCALL_1 (ir_ctx * ctx , ir_ref func , ir_ref arg1 )
1998+ void _ir_TAILCALL_1 (ir_ctx * ctx , ir_type type , ir_ref func , ir_ref arg1 )
20081999{
20092000 IR_ASSERT (ctx -> control );
2010- ctx -> control = ir_emit3 (ctx , IR_OPTX (IR_TAILCALL , IR_VOID , 3 ), ctx -> control , func , arg1 );
2001+ ctx -> control = ir_emit3 (ctx , IR_OPTX (IR_TAILCALL , type , 3 ), ctx -> control , func , arg1 );
20112002 _ir_UNREACHABLE (ctx );
20122003}
20132004
2014- void _ir_TAILCALL_2 (ir_ctx * ctx , ir_ref func , ir_ref arg1 , ir_ref arg2 )
2005+ void _ir_TAILCALL_2 (ir_ctx * ctx , ir_type type , ir_ref func , ir_ref arg1 , ir_ref arg2 )
20152006{
20162007 ir_ref call ;
20172008
20182009 IR_ASSERT (ctx -> control );
2019- call = ir_emit_N (ctx , IR_TAILCALL , 4 );
2010+ call = ir_emit_N (ctx , IR_OPT ( IR_TAILCALL , type ) , 4 );
20202011 ir_set_op (ctx , call , 1 , ctx -> control );
20212012 ir_set_op (ctx , call , 2 , func );
20222013 ir_set_op (ctx , call , 3 , arg1 );
@@ -2025,12 +2016,12 @@ void _ir_TAILCALL_2(ir_ctx *ctx, ir_ref func, ir_ref arg1, ir_ref arg2)
20252016 _ir_UNREACHABLE (ctx );
20262017}
20272018
2028- void _ir_TAILCALL_3 (ir_ctx * ctx , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 )
2019+ void _ir_TAILCALL_3 (ir_ctx * ctx , ir_type type , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 )
20292020{
20302021 ir_ref call ;
20312022
20322023 IR_ASSERT (ctx -> control );
2033- call = ir_emit_N (ctx , IR_TAILCALL , 5 );
2024+ call = ir_emit_N (ctx , IR_OPT ( IR_TAILCALL , type ) , 5 );
20342025 ir_set_op (ctx , call , 1 , ctx -> control );
20352026 ir_set_op (ctx , call , 2 , func );
20362027 ir_set_op (ctx , call , 3 , arg1 );
@@ -2040,12 +2031,12 @@ void _ir_TAILCALL_3(ir_ctx *ctx, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref a
20402031 _ir_UNREACHABLE (ctx );
20412032}
20422033
2043- void _ir_TAILCALL_4 (ir_ctx * ctx , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 , ir_ref arg4 )
2034+ void _ir_TAILCALL_4 (ir_ctx * ctx , ir_type type , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 , ir_ref arg4 )
20442035{
20452036 ir_ref call ;
20462037
20472038 IR_ASSERT (ctx -> control );
2048- call = ir_emit_N (ctx , IR_TAILCALL , 6 );
2039+ call = ir_emit_N (ctx , IR_OPT ( IR_TAILCALL , type ) , 6 );
20492040 ir_set_op (ctx , call , 1 , ctx -> control );
20502041 ir_set_op (ctx , call , 2 , func );
20512042 ir_set_op (ctx , call , 3 , arg1 );
@@ -2056,12 +2047,12 @@ void _ir_TAILCALL_4(ir_ctx *ctx, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref a
20562047 _ir_UNREACHABLE (ctx );
20572048}
20582049
2059- void _ir_TAILCALL_5 (ir_ctx * ctx , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 , ir_ref arg4 , ir_ref arg5 )
2050+ void _ir_TAILCALL_5 (ir_ctx * ctx , ir_type type , ir_ref func , ir_ref arg1 , ir_ref arg2 , ir_ref arg3 , ir_ref arg4 , ir_ref arg5 )
20602051{
20612052 ir_ref call ;
20622053
20632054 IR_ASSERT (ctx -> control );
2064- call = ir_emit_N (ctx , IR_TAILCALL , 7 );
2055+ call = ir_emit_N (ctx , IR_OPT ( IR_TAILCALL , type ) , 7 );
20652056 ir_set_op (ctx , call , 1 , ctx -> control );
20662057 ir_set_op (ctx , call , 2 , func );
20672058 ir_set_op (ctx , call , 3 , arg1 );
@@ -2073,13 +2064,13 @@ void _ir_TAILCALL_5(ir_ctx *ctx, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref a
20732064 _ir_UNREACHABLE (ctx );
20742065}
20752066
2076- void _ir_TAILCALL_N (ir_ctx * ctx , ir_ref func , uint32_t count , ir_ref * args )
2067+ void _ir_TAILCALL_N (ir_ctx * ctx , ir_type type , ir_ref func , uint32_t count , ir_ref * args )
20772068{
20782069 ir_ref call ;
20792070 uint32_t i ;
20802071
20812072 IR_ASSERT (ctx -> control );
2082- call = ir_emit_N (ctx , IR_TAILCALL , count + 2 );
2073+ call = ir_emit_N (ctx , IR_OPT ( IR_TAILCALL , type ) , count + 2 );
20832074 ir_set_op (ctx , call , 1 , ctx -> control );
20842075 ir_set_op (ctx , call , 2 , func );
20852076 for (i = 0 ; i < count ; i ++ ) {
@@ -2375,7 +2366,9 @@ ir_type ir_get_return_type(ir_ctx *ctx)
23752366 insn = & ctx -> ir_base [insn -> op1 ];
23762367 if (insn -> op == IR_TAILCALL ) {
23772368 type = insn -> type ;
2378- goto check_type ;
2369+ if (type != IR_VOID ) {
2370+ goto check_type ;
2371+ }
23792372 }
23802373 }
23812374 ref = ctx -> ir_base [ref ].op3 ;
0 commit comments