@@ -23,7 +23,6 @@ import {
23
23
IdentifierId ,
24
24
Instruction ,
25
25
InstructionKind ,
26
- InstructionValue ,
27
26
isArrayType ,
28
27
isJsxType ,
29
28
isMapType ,
@@ -60,7 +59,6 @@ import {
60
59
printAliasingSignature ,
61
60
printIdentifier ,
62
61
printInstruction ,
63
- printInstructionValue ,
64
62
printPlace ,
65
63
printSourceLocation ,
66
64
} from '../HIR/PrintHIR' ;
@@ -106,11 +104,11 @@ export function inferMutationAliasingEffects(
106
104
const statesByBlock : Map < BlockId , InferenceState > = new Map ( ) ;
107
105
108
106
for ( const ref of fn . context ) {
109
- // TODO: using InstructionValue as a bit of a hack, but it's pragmatic
110
- const value : InstructionValue = {
111
- kind : 'ObjectExpression' ,
112
- properties : [ ] ,
113
- loc : ref . loc ,
107
+ const value : AliasingEffect = {
108
+ kind : 'Create' ,
109
+ into : ref ,
110
+ value : ValueKind . Context ,
111
+ reason : ValueReason . Other ,
114
112
} ;
115
113
initialState . initialize ( value , {
116
114
kind : ValueKind . Context ,
@@ -143,10 +141,11 @@ export function inferMutationAliasingEffects(
143
141
}
144
142
if ( ref != null ) {
145
143
const place = ref . kind === 'Identifier' ? ref : ref . place ;
146
- const value : InstructionValue = {
147
- kind : 'ObjectExpression' ,
148
- properties : [ ] ,
149
- loc : place . loc ,
144
+ const value : AliasingEffect = {
145
+ kind : 'Create' ,
146
+ into : place ,
147
+ value : ValueKind . Mutable ,
148
+ reason : ValueReason . Other ,
150
149
} ;
151
150
initialState . initialize ( value , {
152
151
kind : ValueKind . Mutable ,
@@ -263,8 +262,6 @@ function findHoistedContextDeclarations(
263
262
class Context {
264
263
internedEffects : Map < string , AliasingEffect > = new Map ( ) ;
265
264
instructionSignatureCache : Map < Instruction , InstructionSignature > = new Map ( ) ;
266
- effectInstructionValueCache : Map < AliasingEffect , InstructionValue > =
267
- new Map ( ) ;
268
265
applySignatureCache : Map <
269
266
AliasingSignature ,
270
267
Map < AliasingEffect , Array < AliasingEffect > | null >
@@ -316,10 +313,11 @@ function inferParam(
316
313
paramKind : AbstractValue ,
317
314
) : void {
318
315
const place = param . kind === 'Identifier' ? param : param . place ;
319
- const value : InstructionValue = {
320
- kind : 'Primitive' ,
321
- loc : place . loc ,
322
- value : undefined ,
316
+ const value : AliasingEffect = {
317
+ kind : 'Create' ,
318
+ into : place ,
319
+ value : paramKind . kind ,
320
+ reason : ValueReason . Other ,
323
321
} ;
324
322
initialState . initialize ( value , paramKind ) ;
325
323
initialState . define ( place , value ) ;
@@ -527,20 +525,11 @@ function applyEffect(
527
525
} ) ;
528
526
initialized . add ( effect . into . identifier . id ) ;
529
527
530
- let value = context . effectInstructionValueCache . get ( effect ) ;
531
- if ( value == null ) {
532
- value = {
533
- kind : 'ObjectExpression' ,
534
- properties : [ ] ,
535
- loc : effect . into . loc ,
536
- } ;
537
- context . effectInstructionValueCache . set ( effect , value ) ;
538
- }
539
- state . initialize ( value , {
528
+ state . initialize ( effect , {
540
529
kind : effect . value ,
541
530
reason : new Set ( [ effect . reason ] ) ,
542
531
} ) ;
543
- state . define ( effect . into , value ) ;
532
+ state . define ( effect . into , effect ) ;
544
533
effects . push ( effect ) ;
545
534
break ;
546
535
}
@@ -567,20 +556,11 @@ function applyEffect(
567
556
initialized . add ( effect . into . identifier . id ) ;
568
557
569
558
const fromValue = state . kind ( effect . from ) ;
570
- let value = context . effectInstructionValueCache . get ( effect ) ;
571
- if ( value == null ) {
572
- value = {
573
- kind : 'ObjectExpression' ,
574
- properties : [ ] ,
575
- loc : effect . into . loc ,
576
- } ;
577
- context . effectInstructionValueCache . set ( effect , value ) ;
578
- }
579
- state . initialize ( value , {
559
+ state . initialize ( effect , {
580
560
kind : fromValue . kind ,
581
561
reason : new Set ( fromValue . reason ) ,
582
562
} ) ;
583
- state . define ( effect . into , value ) ;
563
+ state . define ( effect . into , effect ) ;
584
564
switch ( fromValue . kind ) {
585
565
case ValueKind . Primitive :
586
566
case ValueKind . Global : {
@@ -668,11 +648,11 @@ function applyEffect(
668
648
operand . effect = Effect . Read ;
669
649
}
670
650
}
671
- state . initialize ( effect . function , {
651
+ state . initialize ( effect , {
672
652
kind : isMutable ? ValueKind . Mutable : ValueKind . Frozen ,
673
653
reason : new Set ( [ ] ) ,
674
654
} ) ;
675
- state . define ( effect . into , effect . function ) ;
655
+ state . define ( effect . into , effect ) ;
676
656
for ( const capture of effect . captures ) {
677
657
applyEffect (
678
658
context ,
@@ -777,38 +757,20 @@ function applyEffect(
777
757
initialized ,
778
758
effects ,
779
759
) ;
780
- let value = context . effectInstructionValueCache . get ( effect ) ;
781
- if ( value == null ) {
782
- value = {
783
- kind : 'Primitive' ,
784
- value : undefined ,
785
- loc : effect . from . loc ,
786
- } ;
787
- context . effectInstructionValueCache . set ( effect , value ) ;
788
- }
789
- state . initialize ( value , {
760
+ state . initialize ( effect , {
790
761
kind : fromKind ,
791
762
reason : new Set ( fromValue . reason ) ,
792
763
} ) ;
793
- state . define ( effect . into , value ) ;
764
+ state . define ( effect . into , effect ) ;
794
765
break ;
795
766
}
796
767
case ValueKind . Global :
797
768
case ValueKind . Primitive : {
798
- let value = context . effectInstructionValueCache . get ( effect ) ;
799
- if ( value == null ) {
800
- value = {
801
- kind : 'Primitive' ,
802
- value : undefined ,
803
- loc : effect . from . loc ,
804
- } ;
805
- context . effectInstructionValueCache . set ( effect , value ) ;
806
- }
807
- state . initialize ( value , {
769
+ state . initialize ( effect , {
808
770
kind : fromKind ,
809
771
reason : new Set ( fromValue . reason ) ,
810
772
} ) ;
811
- state . define ( effect . into , value ) ;
773
+ state . define ( effect . into , effect ) ;
812
774
break ;
813
775
}
814
776
default : {
@@ -823,14 +785,15 @@ function applyEffect(
823
785
const functionValues = state . values ( effect . function ) ;
824
786
if (
825
787
functionValues . length === 1 &&
826
- functionValues [ 0 ] . kind === 'FunctionExpression' &&
827
- functionValues [ 0 ] . loweredFunc . func . aliasingEffects != null
788
+ functionValues [ 0 ] . kind === 'CreateFunction' &&
789
+ functionValues [ 0 ] . function . kind === 'FunctionExpression' &&
790
+ functionValues [ 0 ] . function . loweredFunc . func . aliasingEffects != null
828
791
) {
829
792
/*
830
793
* We're calling a locally declared function, we already know it's effects!
831
794
* We just have to substitute in the args for the params
832
795
*/
833
- const functionExpr = functionValues [ 0 ] ;
796
+ const functionExpr = functionValues [ 0 ] . function ;
834
797
let signature = context . functionSignatureCache . get ( functionExpr ) ;
835
798
if ( signature == null ) {
836
799
signature = buildSignatureFromFunctionExpression (
@@ -1115,19 +1078,19 @@ class InferenceState {
1115
1078
#isFunctionExpression: boolean ;
1116
1079
1117
1080
// The kind of each value, based on its allocation site
1118
- #values: Map < InstructionValue , AbstractValue > ;
1081
+ #values: Map < AliasingEffect , AbstractValue > ;
1119
1082
/*
1120
1083
* The set of values pointed to by each identifier. This is a set
1121
1084
* to accomodate phi points (where a variable may have different
1122
1085
* values from different control flow paths).
1123
1086
*/
1124
- #variables: Map < IdentifierId , Set < InstructionValue > > ;
1087
+ #variables: Map < IdentifierId , Set < AliasingEffect > > ;
1125
1088
1126
1089
constructor (
1127
1090
env : Environment ,
1128
1091
isFunctionExpression : boolean ,
1129
- values : Map < InstructionValue , AbstractValue > ,
1130
- variables : Map < IdentifierId , Set < InstructionValue > > ,
1092
+ values : Map < AliasingEffect , AbstractValue > ,
1093
+ variables : Map < IdentifierId , Set < AliasingEffect > > ,
1131
1094
) {
1132
1095
this . env = env ;
1133
1096
this . #isFunctionExpression = isFunctionExpression ;
@@ -1147,18 +1110,11 @@ class InferenceState {
1147
1110
}
1148
1111
1149
1112
// (Re)initializes a @param value with its default @param kind.
1150
- initialize ( value : InstructionValue , kind : AbstractValue ) : void {
1151
- CompilerError . invariant ( value . kind !== 'LoadLocal' , {
1152
- reason :
1153
- '[InferMutationAliasingEffects] Expected all top-level identifiers to be defined as variables, not values' ,
1154
- description : null ,
1155
- loc : value . loc ,
1156
- suggestions : null ,
1157
- } ) ;
1113
+ initialize ( value : AliasingEffect , kind : AbstractValue ) : void {
1158
1114
this . #values. set ( value , kind ) ;
1159
1115
}
1160
1116
1161
- values ( place : Place ) : Array < InstructionValue > {
1117
+ values ( place : Place ) : Array < AliasingEffect > {
1162
1118
const values = this . #variables. get ( place . identifier . id ) ;
1163
1119
CompilerError . invariant ( values != null , {
1164
1120
reason : `[InferMutationAliasingEffects] Expected value kind to be initialized` ,
@@ -1221,13 +1177,13 @@ class InferenceState {
1221
1177
}
1222
1178
1223
1179
// Defines (initializing or updating) a variable with a specific kind of value.
1224
- define ( place : Place , value : InstructionValue ) : void {
1180
+ define ( place : Place , value : AliasingEffect ) : void {
1225
1181
CompilerError . invariant ( this . #values. has ( value ) , {
1226
1182
reason : `[InferMutationAliasingEffects] Expected value to be initialized at '${ printSourceLocation (
1227
- value . loc ,
1183
+ place . loc ,
1228
1184
) } '`,
1229
- description : printInstructionValue ( value ) ,
1230
- loc : value . loc ,
1185
+ description : printAliasingEffect ( value ) ,
1186
+ loc : place . loc ,
1231
1187
suggestions : null ,
1232
1188
} ) ;
1233
1189
this . #variables. set ( place . identifier . id , new Set ( [ value ] ) ) ;
@@ -1267,17 +1223,17 @@ class InferenceState {
1267
1223
}
1268
1224
}
1269
1225
1270
- freezeValue ( value : InstructionValue , reason : ValueReason ) : void {
1226
+ freezeValue ( value : AliasingEffect , reason : ValueReason ) : void {
1271
1227
this . #values. set ( value , {
1272
1228
kind : ValueKind . Frozen ,
1273
1229
reason : new Set ( [ reason ] ) ,
1274
1230
} ) ;
1275
1231
if (
1276
- value . kind === 'FunctionExpression ' &&
1232
+ value . kind === 'CreateFunction ' &&
1277
1233
( this . env . config . enablePreserveExistingMemoizationGuarantees ||
1278
1234
this . env . config . enableTransitivelyFreezeFunctionExpressions )
1279
1235
) {
1280
- for ( const place of value . loweredFunc . func . context ) {
1236
+ for ( const place of value . function . loweredFunc . func . context ) {
1281
1237
this . freeze ( place , reason ) ;
1282
1238
}
1283
1239
}
@@ -1352,8 +1308,8 @@ class InferenceState {
1352
1308
* termination.
1353
1309
*/
1354
1310
merge ( other : InferenceState ) : InferenceState | null {
1355
- let nextValues : Map < InstructionValue , AbstractValue > | null = null ;
1356
- let nextVariables : Map < IdentifierId , Set < InstructionValue > > | null = null ;
1311
+ let nextValues : Map < AliasingEffect , AbstractValue > | null = null ;
1312
+ let nextVariables : Map < IdentifierId , Set < AliasingEffect > > | null = null ;
1357
1313
1358
1314
for ( const [ id , thisValue ] of this . #values) {
1359
1315
const otherValue = other . #values. get ( id ) ;
@@ -1377,7 +1333,7 @@ class InferenceState {
1377
1333
for ( const [ id , thisValues ] of this . #variables) {
1378
1334
const otherValues = other . #variables. get ( id ) ;
1379
1335
if ( otherValues !== undefined ) {
1380
- let mergedValues : Set < InstructionValue > | null = null ;
1336
+ let mergedValues : Set < AliasingEffect > | null = null ;
1381
1337
for ( const otherValue of otherValues ) {
1382
1338
if ( ! thisValues . has ( otherValue ) ) {
1383
1339
mergedValues = mergedValues ?? new Set ( thisValues ) ;
@@ -1430,8 +1386,8 @@ class InferenceState {
1430
1386
*/
1431
1387
debug ( ) : any {
1432
1388
const result : any = { values : { } , variables : { } } ;
1433
- const objects : Map < InstructionValue , number > = new Map ( ) ;
1434
- function identify ( value : InstructionValue ) : number {
1389
+ const objects : Map < AliasingEffect , number > = new Map ( ) ;
1390
+ function identify ( value : AliasingEffect ) : number {
1435
1391
let id = objects . get ( value ) ;
1436
1392
if ( id == null ) {
1437
1393
id = objects . size ;
@@ -1443,7 +1399,7 @@ class InferenceState {
1443
1399
const id = identify ( value ) ;
1444
1400
result . values [ id ] = {
1445
1401
abstract : this . debugAbstractValue ( kind ) ,
1446
- value : printInstructionValue ( value ) ,
1402
+ value : printAliasingEffect ( value ) ,
1447
1403
} ;
1448
1404
}
1449
1405
for ( const [ variable , values ] of this . #variables) {
@@ -1460,7 +1416,7 @@ class InferenceState {
1460
1416
}
1461
1417
1462
1418
inferPhi ( phi : Phi ) : void {
1463
- const values : Set < InstructionValue > = new Set ( ) ;
1419
+ const values : Set < AliasingEffect > = new Set ( ) ;
1464
1420
for ( const [ _ , operand ] of phi . operands ) {
1465
1421
const operandValues = this . #variables. get ( operand . identifier . id ) ;
1466
1422
// This is a backedge that will be handled later by State.merge
@@ -2291,8 +2247,9 @@ function areArgumentsImmutableAndNonMutating(
2291
2247
const values = state . values ( place ) ;
2292
2248
for ( const value of values ) {
2293
2249
if (
2294
- value . kind === 'FunctionExpression' &&
2295
- value . loweredFunc . func . params . some ( param => {
2250
+ value . kind === 'CreateFunction' &&
2251
+ value . function . kind === 'FunctionExpression' &&
2252
+ value . function . loweredFunc . func . params . some ( param => {
2296
2253
const place = param . kind === 'Identifier' ? param : param . place ;
2297
2254
const range = place . identifier . mutableRange ;
2298
2255
return range . end > range . start + 1 ;
0 commit comments