@@ -24,7 +24,6 @@ import {
2424 IdentifierId ,
2525 Instruction ,
2626 InstructionKind ,
27- InstructionValue ,
2827 isArrayType ,
2928 isJsxType ,
3029 isMapType ,
@@ -61,7 +60,6 @@ import {
6160 printAliasingSignature ,
6261 printIdentifier ,
6362 printInstruction ,
64- printInstructionValue ,
6563 printPlace ,
6664 printSourceLocation ,
6765} from '../HIR/PrintHIR' ;
@@ -107,11 +105,11 @@ export function inferMutationAliasingEffects(
107105 const statesByBlock : Map < BlockId , InferenceState > = new Map ( ) ;
108106
109107 for ( const ref of fn . context ) {
110- // TODO: using InstructionValue as a bit of a hack, but it's pragmatic
111- const value : InstructionValue = {
112- kind : 'ObjectExpression' ,
113- properties : [ ] ,
114- loc : ref . loc ,
108+ const value : AliasingEffect = {
109+ kind : 'Create' ,
110+ into : ref ,
111+ value : ValueKind . Context ,
112+ reason : ValueReason . Other ,
115113 } ;
116114 initialState . initialize ( value , {
117115 kind : ValueKind . Context ,
@@ -144,10 +142,11 @@ export function inferMutationAliasingEffects(
144142 }
145143 if ( ref != null ) {
146144 const place = ref . kind === 'Identifier' ? ref : ref . place ;
147- const value : InstructionValue = {
148- kind : 'ObjectExpression' ,
149- properties : [ ] ,
150- loc : place . loc ,
145+ const value : AliasingEffect = {
146+ kind : 'Create' ,
147+ into : place ,
148+ value : ValueKind . Mutable ,
149+ reason : ValueReason . Other ,
151150 } ;
152151 initialState . initialize ( value , {
153152 kind : ValueKind . Mutable ,
@@ -264,8 +263,6 @@ function findHoistedContextDeclarations(
264263class Context {
265264 internedEffects : Map < string , AliasingEffect > = new Map ( ) ;
266265 instructionSignatureCache : Map < Instruction , InstructionSignature > = new Map ( ) ;
267- effectInstructionValueCache : Map < AliasingEffect , InstructionValue > =
268- new Map ( ) ;
269266 applySignatureCache : Map <
270267 AliasingSignature ,
271268 Map < AliasingEffect , Array < AliasingEffect > | null >
@@ -317,10 +314,11 @@ function inferParam(
317314 paramKind : AbstractValue ,
318315) : void {
319316 const place = param . kind === 'Identifier' ? param : param . place ;
320- const value : InstructionValue = {
321- kind : 'Primitive' ,
322- loc : place . loc ,
323- value : undefined ,
317+ const value : AliasingEffect = {
318+ kind : 'Create' ,
319+ into : place ,
320+ value : paramKind . kind ,
321+ reason : ValueReason . Other ,
324322 } ;
325323 initialState . initialize ( value , paramKind ) ;
326324 initialState . define ( place , value ) ;
@@ -531,20 +529,11 @@ function applyEffect(
531529 } ) ;
532530 initialized . add ( effect . into . identifier . id ) ;
533531
534- let value = context . effectInstructionValueCache . get ( effect ) ;
535- if ( value == null ) {
536- value = {
537- kind : 'ObjectExpression' ,
538- properties : [ ] ,
539- loc : effect . into . loc ,
540- } ;
541- context . effectInstructionValueCache . set ( effect , value ) ;
542- }
543- state . initialize ( value , {
532+ state . initialize ( effect , {
544533 kind : effect . value ,
545534 reason : new Set ( [ effect . reason ] ) ,
546535 } ) ;
547- state . define ( effect . into , value ) ;
536+ state . define ( effect . into , effect ) ;
548537 effects . push ( effect ) ;
549538 break ;
550539 }
@@ -571,20 +560,11 @@ function applyEffect(
571560 initialized . add ( effect . into . identifier . id ) ;
572561
573562 const fromValue = state . kind ( effect . from ) ;
574- let value = context . effectInstructionValueCache . get ( effect ) ;
575- if ( value == null ) {
576- value = {
577- kind : 'ObjectExpression' ,
578- properties : [ ] ,
579- loc : effect . into . loc ,
580- } ;
581- context . effectInstructionValueCache . set ( effect , value ) ;
582- }
583- state . initialize ( value , {
563+ state . initialize ( effect , {
584564 kind : fromValue . kind ,
585565 reason : new Set ( fromValue . reason ) ,
586566 } ) ;
587- state . define ( effect . into , value ) ;
567+ state . define ( effect . into , effect ) ;
588568 switch ( fromValue . kind ) {
589569 case ValueKind . Primitive :
590570 case ValueKind . Global : {
@@ -672,11 +652,11 @@ function applyEffect(
672652 operand . effect = Effect . Read ;
673653 }
674654 }
675- state . initialize ( effect . function , {
655+ state . initialize ( effect , {
676656 kind : isMutable ? ValueKind . Mutable : ValueKind . Frozen ,
677657 reason : new Set ( [ ] ) ,
678658 } ) ;
679- state . define ( effect . into , effect . function ) ;
659+ state . define ( effect . into , effect ) ;
680660 for ( const capture of effect . captures ) {
681661 applyEffect (
682662 context ,
@@ -782,38 +762,20 @@ function applyEffect(
782762 initialized ,
783763 effects ,
784764 ) ;
785- let value = context . effectInstructionValueCache . get ( effect ) ;
786- if ( value == null ) {
787- value = {
788- kind : 'Primitive' ,
789- value : undefined ,
790- loc : effect . from . loc ,
791- } ;
792- context . effectInstructionValueCache . set ( effect , value ) ;
793- }
794- state . initialize ( value , {
765+ state . initialize ( effect , {
795766 kind : fromKind ,
796767 reason : new Set ( fromValue . reason ) ,
797768 } ) ;
798- state . define ( effect . into , value ) ;
769+ state . define ( effect . into , effect ) ;
799770 break ;
800771 }
801772 case ValueKind . Global :
802773 case ValueKind . Primitive : {
803- let value = context . effectInstructionValueCache . get ( effect ) ;
804- if ( value == null ) {
805- value = {
806- kind : 'Primitive' ,
807- value : undefined ,
808- loc : effect . from . loc ,
809- } ;
810- context . effectInstructionValueCache . set ( effect , value ) ;
811- }
812- state . initialize ( value , {
774+ state . initialize ( effect , {
813775 kind : fromKind ,
814776 reason : new Set ( fromValue . reason ) ,
815777 } ) ;
816- state . define ( effect . into , value ) ;
778+ state . define ( effect . into , effect ) ;
817779 break ;
818780 }
819781 default : {
@@ -828,14 +790,15 @@ function applyEffect(
828790 const functionValues = state . values ( effect . function ) ;
829791 if (
830792 functionValues . length === 1 &&
831- functionValues [ 0 ] . kind === 'FunctionExpression' &&
832- functionValues [ 0 ] . loweredFunc . func . aliasingEffects != null
793+ functionValues [ 0 ] . kind === 'CreateFunction' &&
794+ functionValues [ 0 ] . function . kind === 'FunctionExpression' &&
795+ functionValues [ 0 ] . function . loweredFunc . func . aliasingEffects != null
833796 ) {
834797 /*
835798 * We're calling a locally declared function, we already know it's effects!
836799 * We just have to substitute in the args for the params
837800 */
838- const functionExpr = functionValues [ 0 ] ;
801+ const functionExpr = functionValues [ 0 ] . function ;
839802 let signature = context . functionSignatureCache . get ( functionExpr ) ;
840803 if ( signature == null ) {
841804 signature = buildSignatureFromFunctionExpression (
@@ -1114,19 +1077,19 @@ class InferenceState {
11141077 #isFunctionExpression: boolean ;
11151078
11161079 // The kind of each value, based on its allocation site
1117- #values: Map < InstructionValue , AbstractValue > ;
1080+ #values: Map < AliasingEffect , AbstractValue > ;
11181081 /*
11191082 * The set of values pointed to by each identifier. This is a set
11201083 * to accomodate phi points (where a variable may have different
11211084 * values from different control flow paths).
11221085 */
1123- #variables: Map < IdentifierId , Set < InstructionValue > > ;
1086+ #variables: Map < IdentifierId , Set < AliasingEffect > > ;
11241087
11251088 constructor (
11261089 env : Environment ,
11271090 isFunctionExpression : boolean ,
1128- values : Map < InstructionValue , AbstractValue > ,
1129- variables : Map < IdentifierId , Set < InstructionValue > > ,
1091+ values : Map < AliasingEffect , AbstractValue > ,
1092+ variables : Map < IdentifierId , Set < AliasingEffect > > ,
11301093 ) {
11311094 this . env = env ;
11321095 this . #isFunctionExpression = isFunctionExpression ;
@@ -1146,18 +1109,11 @@ class InferenceState {
11461109 }
11471110
11481111 // (Re)initializes a @param value with its default @param kind.
1149- initialize ( value : InstructionValue , kind : AbstractValue ) : void {
1150- CompilerError . invariant ( value . kind !== 'LoadLocal' , {
1151- reason :
1152- '[InferMutationAliasingEffects] Expected all top-level identifiers to be defined as variables, not values' ,
1153- description : null ,
1154- loc : value . loc ,
1155- suggestions : null ,
1156- } ) ;
1112+ initialize ( value : AliasingEffect , kind : AbstractValue ) : void {
11571113 this . #values. set ( value , kind ) ;
11581114 }
11591115
1160- values ( place : Place ) : Array < InstructionValue > {
1116+ values ( place : Place ) : Array < AliasingEffect > {
11611117 const values = this . #variables. get ( place . identifier . id ) ;
11621118 CompilerError . invariant ( values != null , {
11631119 reason : `[InferMutationAliasingEffects] Expected value kind to be initialized` ,
@@ -1220,13 +1176,13 @@ class InferenceState {
12201176 }
12211177
12221178 // Defines (initializing or updating) a variable with a specific kind of value.
1223- define ( place : Place , value : InstructionValue ) : void {
1179+ define ( place : Place , value : AliasingEffect ) : void {
12241180 CompilerError . invariant ( this . #values. has ( value ) , {
12251181 reason : `[InferMutationAliasingEffects] Expected value to be initialized at '${ printSourceLocation (
1226- value . loc ,
1182+ place . loc ,
12271183 ) } '`,
1228- description : printInstructionValue ( value ) ,
1229- loc : value . loc ,
1184+ description : printAliasingEffect ( value ) ,
1185+ loc : place . loc ,
12301186 suggestions : null ,
12311187 } ) ;
12321188 this . #variables. set ( place . identifier . id , new Set ( [ value ] ) ) ;
@@ -1266,17 +1222,17 @@ class InferenceState {
12661222 }
12671223 }
12681224
1269- freezeValue ( value : InstructionValue , reason : ValueReason ) : void {
1225+ freezeValue ( value : AliasingEffect , reason : ValueReason ) : void {
12701226 this . #values. set ( value , {
12711227 kind : ValueKind . Frozen ,
12721228 reason : new Set ( [ reason ] ) ,
12731229 } ) ;
12741230 if (
1275- value . kind === 'FunctionExpression ' &&
1231+ value . kind === 'CreateFunction ' &&
12761232 ( this . env . config . enablePreserveExistingMemoizationGuarantees ||
12771233 this . env . config . enableTransitivelyFreezeFunctionExpressions )
12781234 ) {
1279- for ( const place of value . loweredFunc . func . context ) {
1235+ for ( const place of value . function . loweredFunc . func . context ) {
12801236 this . freeze ( place , reason ) ;
12811237 }
12821238 }
@@ -1351,8 +1307,8 @@ class InferenceState {
13511307 * termination.
13521308 */
13531309 merge ( other : InferenceState ) : InferenceState | null {
1354- let nextValues : Map < InstructionValue , AbstractValue > | null = null ;
1355- let nextVariables : Map < IdentifierId , Set < InstructionValue > > | null = null ;
1310+ let nextValues : Map < AliasingEffect , AbstractValue > | null = null ;
1311+ let nextVariables : Map < IdentifierId , Set < AliasingEffect > > | null = null ;
13561312
13571313 for ( const [ id , thisValue ] of this . #values) {
13581314 const otherValue = other . #values. get ( id ) ;
@@ -1376,7 +1332,7 @@ class InferenceState {
13761332 for ( const [ id , thisValues ] of this . #variables) {
13771333 const otherValues = other . #variables. get ( id ) ;
13781334 if ( otherValues !== undefined ) {
1379- let mergedValues : Set < InstructionValue > | null = null ;
1335+ let mergedValues : Set < AliasingEffect > | null = null ;
13801336 for ( const otherValue of otherValues ) {
13811337 if ( ! thisValues . has ( otherValue ) ) {
13821338 mergedValues = mergedValues ?? new Set ( thisValues ) ;
@@ -1429,8 +1385,8 @@ class InferenceState {
14291385 */
14301386 debug ( ) : any {
14311387 const result : any = { values : { } , variables : { } } ;
1432- const objects : Map < InstructionValue , number > = new Map ( ) ;
1433- function identify ( value : InstructionValue ) : number {
1388+ const objects : Map < AliasingEffect , number > = new Map ( ) ;
1389+ function identify ( value : AliasingEffect ) : number {
14341390 let id = objects . get ( value ) ;
14351391 if ( id == null ) {
14361392 id = objects . size ;
@@ -1442,7 +1398,7 @@ class InferenceState {
14421398 const id = identify ( value ) ;
14431399 result . values [ id ] = {
14441400 abstract : this . debugAbstractValue ( kind ) ,
1445- value : printInstructionValue ( value ) ,
1401+ value : printAliasingEffect ( value ) ,
14461402 } ;
14471403 }
14481404 for ( const [ variable , values ] of this . #variables) {
@@ -1459,7 +1415,7 @@ class InferenceState {
14591415 }
14601416
14611417 inferPhi ( phi : Phi ) : void {
1462- const values : Set < InstructionValue > = new Set ( ) ;
1418+ const values : Set < AliasingEffect > = new Set ( ) ;
14631419 for ( const [ _ , operand ] of phi . operands ) {
14641420 const operandValues = this . #variables. get ( operand . identifier . id ) ;
14651421 // This is a backedge that will be handled later by State.merge
@@ -2315,8 +2271,9 @@ function areArgumentsImmutableAndNonMutating(
23152271 const values = state . values ( place ) ;
23162272 for ( const value of values ) {
23172273 if (
2318- value . kind === 'FunctionExpression' &&
2319- value . loweredFunc . func . params . some ( param => {
2274+ value . kind === 'CreateFunction' &&
2275+ value . function . kind === 'FunctionExpression' &&
2276+ value . function . loweredFunc . func . params . some ( param => {
23202277 const place = param . kind === 'Identifier' ? param : param . place ;
23212278 const range = place . identifier . mutableRange ;
23222279 return range . end > range . start + 1 ;
0 commit comments