Skip to content
This repository was archived by the owner on Jul 12, 2021. It is now read-only.

Commit bc68daa

Browse files
committed
Add: new vm instruction DVM_UNTAG for untagging a value of type "X|none" to a value of "X";
Remove: unnecessary generation of cast operations during inference and optimization.
1 parent 775da2b commit bc68daa

File tree

5 files changed

+26
-23
lines changed

5 files changed

+26
-23
lines changed

kernel/daoOptimizer.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ static void DaoOptimizer_ReduceRegister( DaoOptimizer *self, DaoRoutine *routine
15581558
intervals[2*id+1] = i + 1; /* plus one because it is alive at the exit; */
15591559
k += 1;
15601560
}
1561-
if( vmc->code == DVM_LOAD || vmc->code == DVM_CAST ){
1561+
if( vmc->code == DVM_LOAD || vmc->code == DVM_CAST || vmc->code == DVM_UNTAG ){
15621562
/* These opcodes may create a reference (alias) of ::a at the result register (::c),
15631563
// the liveness interval of ::a must be expanded to the point where ::c is used: */
15641564
for(j=i+1; j<N; ++j){
@@ -2708,10 +2708,9 @@ static DaoInode* DaoInferencer_InsertMove( DaoInferencer *self, DaoInode *inode,
27082708
*op = move->c;
27092709
return move;
27102710
}
2711-
static DaoInode* DaoInferencer_InsertCast( DaoInferencer *self, DaoInode *inode, unsigned short *op, DaoType *ct )
2711+
static DaoInode* DaoInferencer_InsertUntag( DaoInferencer *self, DaoInode *inode, unsigned short *op, DaoType *ct )
27122712
{
2713-
DaoInode *cast = DaoInferencer_InsertNode( self, inode, DVM_CAST, 1, ct );
2714-
cast->b = DaoRoutine_AddConstant( self->routine, (DaoValue*) ct );
2713+
DaoInode *cast = DaoInferencer_InsertNode( self, inode, DVM_UNTAG, 1, ct );
27152714
cast->a = *op;
27162715
*op = cast->c;
27172716
return cast;
@@ -5250,7 +5249,7 @@ int DaoInferencer_DoInference( DaoInferencer *self )
52505249
case DAO_CODE_MOVE :
52515250
if( code == DVM_LOAD ){
52525251
tt = DaoType_GetAutoCastType( at );
5253-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->a, tt );
5252+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->a, tt );
52545253
}
52555254
break;
52565255
case DAO_CODE_GETF :
@@ -5260,24 +5259,24 @@ int DaoInferencer_DoInference( DaoInferencer *self )
52605259
case DAO_CODE_ENUM2 :
52615260
case DAO_CODE_CALL :
52625261
tt = DaoType_GetAutoCastType( at );
5263-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->a, tt );
5262+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->a, tt );
52645263
break;
52655264
case DAO_CODE_UNARY2 :
52665265
tt = DaoType_GetAutoCastType( bt );
5267-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->b, tt );
5266+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->b, tt );
52685267
break;
52695268
case DAO_CODE_SETF :
52705269
case DAO_CODE_SETI :
52715270
case DAO_CODE_SETM :
52725271
tt = DaoType_GetAutoCastType( ct );
5273-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->c, tt );
5272+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->c, tt );
52745273
break;
52755274
case DAO_CODE_BINARY :
52765275
if( code == DVM_EQ || code == DVM_NE ) break;
52775276
tt = DaoType_GetAutoCastType( at );
5278-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->a, tt );
5277+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->a, tt );
52795278
tt = DaoType_GetAutoCastType( bt );
5280-
if( tt != NULL ) DaoInferencer_InsertCast( self, inode, & inode->b, tt );
5279+
if( tt != NULL ) DaoInferencer_InsertUntag( self, inode, & inode->b, tt );
52815280
break;
52825281
}
52835282
if( self->inodes->size != N ){
@@ -5418,9 +5417,6 @@ int DaoInferencer_DoInference( DaoInferencer *self )
54185417
}
54195418
vmc->code = DVM_SETVH_BB + type2[0]->tid - DAO_BOOLEAN;
54205419
vmc->code += K*(code - DVM_SETVH);
5421-
}else if( k == DAO_MT_SUB ){
5422-
/* global L = { 1.5, 2.5 }; L = { 1, 2 }; L[0] = 3.5 */
5423-
DaoInferencer_InsertCast( self, inode, & inode->a, *type2 );
54245420
}
54255421
break;
54265422
case DVM_GETI :
@@ -5572,8 +5568,6 @@ int DaoInferencer_DoInference( DaoInferencer *self )
55725568

55735569
if( k == DAO_MT_SUB && at != ct ){
55745570
/* L = { 1.5, 2.5 }; L = { 1, 2 }; L[0] = 3.5 */
5575-
vmc->code = DVM_CAST;
5576-
vmc->b = DaoRoutine_AddConstant( self->routine, (DaoValue*) types[opc] );
55775571
if( at->tid && at->tid <= DAO_COMPLEX && types[opc]->tid == DAO_COMPLEX ){
55785572
if( at->tid < DAO_FLOAT ){
55795573
DaoInferencer_InsertMove( self, inode, & inode->a, at, dao_type_float );
@@ -5606,6 +5600,12 @@ int DaoInferencer_DoInference( DaoInferencer *self )
56065600
}
56075601
break;
56085602
}
5603+
case DVM_UNTAG :
5604+
tt = DaoType_GetAutoCastType( at );
5605+
if( tt == NULL ) goto ErrorTyping;
5606+
DaoInferencer_UpdateType( self, opc, tt );
5607+
AssertTypeMatching( tt, types[opc], defs );
5608+
break;
56095609
case DVM_ADD : case DVM_SUB : case DVM_MUL :
56105610
case DVM_DIV : case DVM_MOD : case DVM_POW :
56115611
if( DaoInferencer_HandleBinaryArith( self, inode, defs ) == 0 ) return 0;

kernel/daoProcess.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ int DaoProcess_Start( DaoProcess *self )
10061006
&& LAB_GETI , && LAB_GETDI , && LAB_GETMI , && LAB_GETF ,
10071007
&& LAB_SETVH , && LAB_SETVS , && LAB_SETVO , && LAB_SETVK , && LAB_SETVG ,
10081008
&& LAB_SETI , && LAB_SETDI , && LAB_SETMI , && LAB_SETF ,
1009-
&& LAB_LOAD , && LAB_CAST , && LAB_MOVE ,
1009+
&& LAB_LOAD , && LAB_MOVE , && LAB_UNTAG , && LAB_CAST ,
10101010
&& LAB_NOT , && LAB_MINUS , && LAB_TILDE , && LAB_SIZE ,
10111011
&& LAB_ADD , && LAB_SUB ,
10121012
&& LAB_MUL , && LAB_DIV ,
@@ -1399,13 +1399,13 @@ int DaoProcess_Start( DaoProcess *self )
13991399
DaoValue_Copy( vA, & locVars[vmc->c] );
14001400
}
14011401
}
1402-
}OPNEXT() OPCASE( CAST ){
1403-
DaoProcess_DoCast( self, vmc );
1404-
goto CheckException;
1405-
}OPNEXT() OPCASE( MOVE ){
1402+
}OPNEXT() OPCASE( MOVE ) OPCASE( UNTAG ) {
14061403
self->activeCode = vmc;
14071404
DaoProcess_Move( self, locVars[vmc->a], & locVars[vmc->c], locTypes[vmc->c] );
14081405
goto CheckException;
1406+
}OPNEXT() OPCASE( CAST ){
1407+
DaoProcess_DoCast( self, vmc );
1408+
goto CheckException;
14091409
}OPNEXT()
14101410
OPCASE( ADD )
14111411
OPCASE( SUB )

kernel/daoVmcode.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ static DaoVmCodeInfo dao_code_infolist[] =
6363
{ "SETMI", DVM_SETMI, DAO_CODE_SETM, 0 },
6464
{ "SETF", DVM_SETF, DAO_CODE_SETF, 0 },
6565
{ "LOAD", DVM_LOAD, DAO_CODE_MOVE, 1 },
66-
{ "CAST", DVM_CAST, DAO_CODE_MOVE, 0 },
6766
{ "MOVE", DVM_MOVE, DAO_CODE_MOVE, 0 },
67+
{ "UNTAG", DVM_UNTAG, DAO_CODE_MOVE, 0 },
68+
{ "CAST", DVM_CAST, DAO_CODE_MOVE, 0 },
6869
{ "NOT", DVM_NOT, DAO_CODE_UNARY, 0 },
6970
{ "MINUS", DVM_MINUS, DAO_CODE_UNARY, 0 },
7071
{ "TILDE", DVM_TILDE, DAO_CODE_UNARY, 0 },

kernel/daoVmcode.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ enum DaoOpcode
5757
DVM_SETMI , /* Set item(s): C[C+1, ..., C+B] = A; */
5858
DVM_SETF , /* Set field: C.B = A or C::B = A; */
5959
DVM_LOAD , /* Put local value A as reference at C; */
60-
DVM_CAST , /* Cast A to B and store at C: C = (B)A; B, local const index; */
6160
DVM_MOVE , /* Move A to C: C = A; B: B1, explicit; B2, decl; B3, invar; */
61+
DVM_UNTAG , /* Untag A of type X|none to X type at C; */
62+
DVM_CAST , /* Cast A to B and store at C: C = (B)A; B, local const index; */
6263
DVM_NOT , /* Not: C = ! A; */
6364
DVM_MINUS , /* Unary minus: C = - A; */
6465
DVM_TILDE , /* Bitwise not: C = ~ A */

modules/help/help_en/help_daovm_architecture.dao

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ DVM_SETDI # Set item(s): C[B] = A; B, direct index;
4646
DVM_SETMI # Set item(s): C[C+1, ..., C+B] = A;
4747
DVM_SETF # Set field: C.B = A or C::B = A;
4848
DVM_LOAD # Put local value A as reference at C;
49-
DVM_CAST # Cast A to B and store at C: C = (B)A; B, local const index;
5049
DVM_MOVE # Move A to C: C = A; C: Bit1, explicit; Bit2, decl; Bit3, invar;
50+
DVM_UNTAG # Untag A of type X|none to X type at C;
51+
DVM_CAST # Cast A to B and store at C: C = (B)A; B, local const index;
5152
DVM_NOT # Not: C = ! A;
5253
DVM_MINUS # Unary minus: C = - A;
5354
DVM_TILDE # Bitwise not: C = ~ A

0 commit comments

Comments
 (0)