@@ -23,7 +23,6 @@ import {
2323 IdentifierId ,
2424 Instruction ,
2525 InstructionKind ,
26- InstructionValue ,
2726 isArrayType ,
2827 isJsxType ,
2928 isMapType ,
@@ -60,7 +59,6 @@ import {
6059 printAliasingSignature ,
6160 printIdentifier ,
6261 printInstruction ,
63- printInstructionValue ,
6462 printPlace ,
6563 printSourceLocation ,
6664} from '../HIR/PrintHIR' ;
@@ -106,11 +104,11 @@ export function inferMutationAliasingEffects(
106104 const statesByBlock : Map < BlockId , InferenceState > = new Map ( ) ;
107105
108106 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 ,
114112 } ;
115113 initialState . initialize ( value , {
116114 kind : ValueKind . Context ,
@@ -143,10 +141,11 @@ export function inferMutationAliasingEffects(
143141 }
144142 if ( ref != null ) {
145143 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 ,
150149 } ;
151150 initialState . initialize ( value , {
152151 kind : ValueKind . Mutable ,
@@ -263,8 +262,6 @@ function findHoistedContextDeclarations(
263262class Context {
264263 internedEffects : Map < string , AliasingEffect > = new Map ( ) ;
265264 instructionSignatureCache : Map < Instruction , InstructionSignature > = new Map ( ) ;
266- effectInstructionValueCache : Map < AliasingEffect , InstructionValue > =
267- new Map ( ) ;
268265 applySignatureCache : Map <
269266 AliasingSignature ,
270267 Map < AliasingEffect , Array < AliasingEffect > | null >
@@ -316,10 +313,11 @@ function inferParam(
316313 paramKind : AbstractValue ,
317314) : void {
318315 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 ,
323321 } ;
324322 initialState . initialize ( value , paramKind ) ;
325323 initialState . define ( place , value ) ;
@@ -527,20 +525,11 @@ function applyEffect(
527525 } ) ;
528526 initialized . add ( effect . into . identifier . id ) ;
529527
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 , {
540529 kind : effect . value ,
541530 reason : new Set ( [ effect . reason ] ) ,
542531 } ) ;
543- state . define ( effect . into , value ) ;
532+ state . define ( effect . into , effect ) ;
544533 effects . push ( effect ) ;
545534 break ;
546535 }
@@ -567,20 +556,11 @@ function applyEffect(
567556 initialized . add ( effect . into . identifier . id ) ;
568557
569558 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 , {
580560 kind : fromValue . kind ,
581561 reason : new Set ( fromValue . reason ) ,
582562 } ) ;
583- state . define ( effect . into , value ) ;
563+ state . define ( effect . into , effect ) ;
584564 switch ( fromValue . kind ) {
585565 case ValueKind . Primitive :
586566 case ValueKind . Global : {
@@ -668,11 +648,11 @@ function applyEffect(
668648 operand . effect = Effect . Read ;
669649 }
670650 }
671- state . initialize ( effect . function , {
651+ state . initialize ( effect , {
672652 kind : isMutable ? ValueKind . Mutable : ValueKind . Frozen ,
673653 reason : new Set ( [ ] ) ,
674654 } ) ;
675- state . define ( effect . into , effect . function ) ;
655+ state . define ( effect . into , effect ) ;
676656 for ( const capture of effect . captures ) {
677657 applyEffect (
678658 context ,
@@ -777,38 +757,20 @@ function applyEffect(
777757 initialized ,
778758 effects ,
779759 ) ;
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 , {
790761 kind : fromKind ,
791762 reason : new Set ( fromValue . reason ) ,
792763 } ) ;
793- state . define ( effect . into , value ) ;
764+ state . define ( effect . into , effect ) ;
794765 break ;
795766 }
796767 case ValueKind . Global :
797768 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 , {
808770 kind : fromKind ,
809771 reason : new Set ( fromValue . reason ) ,
810772 } ) ;
811- state . define ( effect . into , value ) ;
773+ state . define ( effect . into , effect ) ;
812774 break ;
813775 }
814776 default : {
@@ -823,14 +785,15 @@ function applyEffect(
823785 const functionValues = state . values ( effect . function ) ;
824786 if (
825787 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
828791 ) {
829792 /*
830793 * We're calling a locally declared function, we already know it's effects!
831794 * We just have to substitute in the args for the params
832795 */
833- const functionExpr = functionValues [ 0 ] ;
796+ const functionExpr = functionValues [ 0 ] . function ;
834797 let signature = context . functionSignatureCache . get ( functionExpr ) ;
835798 if ( signature == null ) {
836799 signature = buildSignatureFromFunctionExpression (
@@ -1115,19 +1078,19 @@ class InferenceState {
11151078 #isFunctionExpression: boolean ;
11161079
11171080 // The kind of each value, based on its allocation site
1118- #values: Map < InstructionValue , AbstractValue > ;
1081+ #values: Map < AliasingEffect , AbstractValue > ;
11191082 /*
11201083 * The set of values pointed to by each identifier. This is a set
11211084 * to accomodate phi points (where a variable may have different
11221085 * values from different control flow paths).
11231086 */
1124- #variables: Map < IdentifierId , Set < InstructionValue > > ;
1087+ #variables: Map < IdentifierId , Set < AliasingEffect > > ;
11251088
11261089 constructor (
11271090 env : Environment ,
11281091 isFunctionExpression : boolean ,
1129- values : Map < InstructionValue , AbstractValue > ,
1130- variables : Map < IdentifierId , Set < InstructionValue > > ,
1092+ values : Map < AliasingEffect , AbstractValue > ,
1093+ variables : Map < IdentifierId , Set < AliasingEffect > > ,
11311094 ) {
11321095 this . env = env ;
11331096 this . #isFunctionExpression = isFunctionExpression ;
@@ -1147,18 +1110,11 @@ class InferenceState {
11471110 }
11481111
11491112 // (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 {
11581114 this . #values. set ( value , kind ) ;
11591115 }
11601116
1161- values ( place : Place ) : Array < InstructionValue > {
1117+ values ( place : Place ) : Array < AliasingEffect > {
11621118 const values = this . #variables. get ( place . identifier . id ) ;
11631119 CompilerError . invariant ( values != null , {
11641120 reason : `[InferMutationAliasingEffects] Expected value kind to be initialized` ,
@@ -1221,13 +1177,13 @@ class InferenceState {
12211177 }
12221178
12231179 // 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 {
12251181 CompilerError . invariant ( this . #values. has ( value ) , {
12261182 reason : `[InferMutationAliasingEffects] Expected value to be initialized at '${ printSourceLocation (
1227- value . loc ,
1183+ place . loc ,
12281184 ) } '`,
1229- description : printInstructionValue ( value ) ,
1230- loc : value . loc ,
1185+ description : printAliasingEffect ( value ) ,
1186+ loc : place . loc ,
12311187 suggestions : null ,
12321188 } ) ;
12331189 this . #variables. set ( place . identifier . id , new Set ( [ value ] ) ) ;
@@ -1267,17 +1223,17 @@ class InferenceState {
12671223 }
12681224 }
12691225
1270- freezeValue ( value : InstructionValue , reason : ValueReason ) : void {
1226+ freezeValue ( value : AliasingEffect , reason : ValueReason ) : void {
12711227 this . #values. set ( value , {
12721228 kind : ValueKind . Frozen ,
12731229 reason : new Set ( [ reason ] ) ,
12741230 } ) ;
12751231 if (
1276- value . kind === 'FunctionExpression ' &&
1232+ value . kind === 'CreateFunction ' &&
12771233 ( this . env . config . enablePreserveExistingMemoizationGuarantees ||
12781234 this . env . config . enableTransitivelyFreezeFunctionExpressions )
12791235 ) {
1280- for ( const place of value . loweredFunc . func . context ) {
1236+ for ( const place of value . function . loweredFunc . func . context ) {
12811237 this . freeze ( place , reason ) ;
12821238 }
12831239 }
@@ -1352,8 +1308,8 @@ class InferenceState {
13521308 * termination.
13531309 */
13541310 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 ;
13571313
13581314 for ( const [ id , thisValue ] of this . #values) {
13591315 const otherValue = other . #values. get ( id ) ;
@@ -1377,7 +1333,7 @@ class InferenceState {
13771333 for ( const [ id , thisValues ] of this . #variables) {
13781334 const otherValues = other . #variables. get ( id ) ;
13791335 if ( otherValues !== undefined ) {
1380- let mergedValues : Set < InstructionValue > | null = null ;
1336+ let mergedValues : Set < AliasingEffect > | null = null ;
13811337 for ( const otherValue of otherValues ) {
13821338 if ( ! thisValues . has ( otherValue ) ) {
13831339 mergedValues = mergedValues ?? new Set ( thisValues ) ;
@@ -1430,8 +1386,8 @@ class InferenceState {
14301386 */
14311387 debug ( ) : any {
14321388 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 {
14351391 let id = objects . get ( value ) ;
14361392 if ( id == null ) {
14371393 id = objects . size ;
@@ -1443,7 +1399,7 @@ class InferenceState {
14431399 const id = identify ( value ) ;
14441400 result . values [ id ] = {
14451401 abstract : this . debugAbstractValue ( kind ) ,
1446- value : printInstructionValue ( value ) ,
1402+ value : printAliasingEffect ( value ) ,
14471403 } ;
14481404 }
14491405 for ( const [ variable , values ] of this . #variables) {
@@ -1460,7 +1416,7 @@ class InferenceState {
14601416 }
14611417
14621418 inferPhi ( phi : Phi ) : void {
1463- const values : Set < InstructionValue > = new Set ( ) ;
1419+ const values : Set < AliasingEffect > = new Set ( ) ;
14641420 for ( const [ _ , operand ] of phi . operands ) {
14651421 const operandValues = this . #variables. get ( operand . identifier . id ) ;
14661422 // This is a backedge that will be handled later by State.merge
@@ -2291,8 +2247,9 @@ function areArgumentsImmutableAndNonMutating(
22912247 const values = state . values ( place ) ;
22922248 for ( const value of values ) {
22932249 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 => {
22962253 const place = param . kind === 'Identifier' ? param : param . place ;
22972254 const range = place . identifier . mutableRange ;
22982255 return range . end > range . start + 1 ;
0 commit comments