Static specialization done

This commit is contained in:
Michael Schimmel
2025-11-19 21:22:01 +01:00
parent d0d1053faf
commit ae10f4eee0
3 changed files with 99 additions and 235 deletions
+4 -3
View File
@@ -1158,10 +1158,9 @@ end;
procedure TForm1.FailingUpvalueButtonClick(Sender: TObject); procedure TForm1.FailingUpvalueButtonClick(Sender: TObject);
var var
mainBlock: IAstNode;
resultValue: TDataValue; resultValue: TDataValue;
begin begin
mainBlock := FCurrUnboundAst :=
TAst.Block( TAst.Block(
[ [
TAst.VarDecl(TAst.Identifier('a'), TAst.Constant(10)), TAst.VarDecl(TAst.Identifier('a'), TAst.Constant(10)),
@@ -1186,10 +1185,12 @@ begin
] ]
); );
UpdateScript;
Memo1.Lines.Clear; Memo1.Lines.Clear;
Memo1.Lines.Add('--- Executing Corrected Upvalue Test ---'); Memo1.Lines.Add('--- Executing Corrected Upvalue Test ---');
resultValue := ExecuteAst(mainBlock); resultValue := ExecuteAst(FCurrUnboundAst);
var res := resultValue.AsScalar.Value.AsInt64; var res := resultValue.AsScalar.Value.AsInt64;
if res = 15 then if res = 15 then
+76 -223
View File
@@ -16,24 +16,34 @@
} }
], ],
"Body": { "Body": {
"NodeType": "BinaryExpr", "NodeType": "FunctionCall",
"Operator": "+", "Callee": {
"Left": {
"NodeType": "BinaryExpr",
"Operator": "+",
"Left": {
"NodeType": "Identifier",
"Name": "a"
},
"Right": {
"NodeType": "Identifier",
"Name": "b"
}
},
"Right": {
"NodeType": "Identifier", "NodeType": "Identifier",
"Name": "c" "Name": "+"
} },
"Arguments": [
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "+"
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "a"
},
{
"NodeType": "Identifier",
"Name": "b"
}
]
},
{
"NodeType": "Identifier",
"Name": "c"
}
]
} }
}, },
"repeat": { "repeat": {
@@ -74,22 +84,27 @@
"Body": { "Body": {
"NodeType": "IfExpr", "NodeType": "IfExpr",
"Condition": { "Condition": {
"NodeType": "BinaryExpr", "NodeType": "FunctionCall",
"Operator": ">", "Callee": {
"Left": {
"NodeType": "Identifier", "NodeType": "Identifier",
"Name": "counter" "Name": ">"
}, },
"Right": { "Arguments": [
"NodeType": "Constant", {
"Value": { "NodeType": "Identifier",
"Kind": "Scalar", "Name": "counter"
},
{
"NodeType": "Constant",
"Value": { "Value": {
"Kind": "Ordinal", "Kind": "Scalar",
"Value": 0 "Value": {
"Kind": "Ordinal",
"Value": 0
}
} }
} }
} ]
}, },
"ThenBranch": { "ThenBranch": {
"NodeType": "Block", "NodeType": "Block",
@@ -105,22 +120,27 @@
"NodeType": "Recur", "NodeType": "Recur",
"Arguments": [ "Arguments": [
{ {
"NodeType": "BinaryExpr", "NodeType": "FunctionCall",
"Operator": "-", "Callee": {
"Left": {
"NodeType": "Identifier", "NodeType": "Identifier",
"Name": "counter" "Name": "-"
}, },
"Right": { "Arguments": [
"NodeType": "Constant", {
"Value": { "NodeType": "Identifier",
"Kind": "Scalar", "Name": "counter"
},
{
"NodeType": "Constant",
"Value": { "Value": {
"Kind": "Ordinal", "Kind": "Scalar",
"Value": 1 "Value": {
"Kind": "Ordinal",
"Value": 1
}
} }
} }
} ]
} }
] ]
} }
@@ -128,8 +148,7 @@
}, },
"ElseBranch": { "ElseBranch": {
"NodeType": "Block", "NodeType": "Block",
"Expressions": [ "Expressions": []
]
} }
} }
} }
@@ -483,8 +502,21 @@
"Name": "series" "Name": "series"
}, },
"Index": { "Index": {
"NodeType": "Identifier", "NodeType": "FunctionCall",
"Name": "len" "Callee": {
"NodeType": "Identifier",
"Name": "-"
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "count"
},
{
"NodeType": "Identifier",
"Name": "len"
}
]
} }
} }
] ]
@@ -632,185 +664,6 @@
} }
} }
}, },
{
"NodeType": "VarDecl",
"Identifier": {
"NodeType": "Identifier",
"Name": "sum-product"
},
"Initializer": {
"NodeType": "LambdaExpr",
"Parameters": [
{
"NodeType": "Identifier",
"Name": "xs"
},
{
"NodeType": "Identifier",
"Name": "ys"
}
],
"Body": {
"NodeType": "Block",
"Expressions": [
{
"NodeType": "VarDecl",
"Identifier": {
"NodeType": "Identifier",
"Name": "loop"
},
"Initializer": {
"NodeType": "LambdaExpr",
"Parameters": [
{
"NodeType": "Identifier",
"Name": "i"
},
{
"NodeType": "Identifier",
"Name": "acc"
}
],
"Body": {
"NodeType": "IfExpr",
"Condition": {
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "="
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "i"
},
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "series-count"
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "xs"
}
]
}
]
},
"ThenBranch": {
"NodeType": "Identifier",
"Name": "acc"
},
"ElseBranch": {
"NodeType": "Recur",
"Arguments": [
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "+"
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "i"
},
{
"NodeType": "Constant",
"Value": {
"Kind": "Scalar",
"Value": {
"Kind": "Ordinal",
"Value": 1
}
}
}
]
},
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "+"
},
"Arguments": [
{
"NodeType": "Identifier",
"Name": "acc"
},
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "*"
},
"Arguments": [
{
"NodeType": "Indexer",
"Base": {
"NodeType": "Identifier",
"Name": "xs"
},
"Index": {
"NodeType": "Identifier",
"Name": "i"
}
},
{
"NodeType": "Indexer",
"Base": {
"NodeType": "Identifier",
"Name": "ys"
},
"Index": {
"NodeType": "Identifier",
"Name": "i"
}
}
]
}
]
}
]
}
}
}
},
{
"NodeType": "FunctionCall",
"Callee": {
"NodeType": "Identifier",
"Name": "loop"
},
"Arguments": [
{
"NodeType": "Constant",
"Value": {
"Kind": "Scalar",
"Value": {
"Kind": "Ordinal",
"Value": 0
}
}
},
{
"NodeType": "Constant",
"Value": {
"Kind": "Scalar",
"Value": {
"Kind": "Ordinal",
"Value": 0
}
}
}
]
}
]
}
}
},
{ {
"NodeType": "VarDecl", "NodeType": "VarDecl",
"Identifier": { "Identifier": {
@@ -1035,7 +888,7 @@
}, },
{ {
"NodeType": "Identifier", "NodeType": "Identifier",
"Name": "sum-y" "Name": "sum-x"
} }
] ]
} }
+19 -9
View File
@@ -25,8 +25,6 @@ type
TStaticSpecializer = class(TAstTransformer, IAstSpecializer) TStaticSpecializer = class(TAstTransformer, IAstSpecializer)
private private
FEnvironment: IEnvironment; FEnvironment: IEnvironment;
FMonomorphCache: TMonomorphCache;
FFunctionRegistry: IFunctionDefinitionRegistry;
function GetStaticRtlFunction(const AName: string; const AArgTypes: TArray<IStaticType>): TSpecializedMethod; function GetStaticRtlFunction(const AName: string; const AArgTypes: TArray<IStaticType>): TSpecializedMethod;
@@ -53,9 +51,6 @@ begin
inherited Create; inherited Create;
Assert(Assigned(AEnvironment)); Assert(Assigned(AEnvironment));
FEnvironment := AEnvironment; FEnvironment := AEnvironment;
FMonomorphCache := AEnvironment.MonomorphCache;
FFunctionRegistry := AEnvironment.FunctionRegistry; // Get registry
Assert(Assigned(FFunctionRegistry));
end; end;
class function TStaticSpecializer.Specialize( class function TStaticSpecializer.Specialize(
@@ -139,7 +134,7 @@ begin
// 4. Check the Environment (Instance) Cache // 4. Check the Environment (Instance) Cache
key := TMonoCacheKey.Create(calleeIdent.Address, argTypes); key := TMonoCacheKey.Create(calleeIdent.Address, argTypes);
if FMonomorphCache.TryGetValue(key, specializedMethod) then if FEnvironment.MonomorphCache.TryGetValue(key, specializedMethod) then
begin begin
// 4a. Cache Hit (Environment): Found user-defined or previously specialized fn // 4a. Cache Hit (Environment): Found user-defined or previously specialized fn
Result := Result :=
@@ -158,7 +153,7 @@ begin
if Assigned(specializedMethod.Target) then if Assigned(specializedMethod.Target) then
begin begin
// 5a. Cache Hit (RTL): Found a native, static RTL function // 5a. Cache Hit (RTL): Found a native, static RTL function
FMonomorphCache.Add(key, specializedMethod); FEnvironment.MonomorphCache.Add(key, specializedMethod);
Result := Result :=
TAst.FunctionCall( TAst.FunctionCall(
@@ -172,10 +167,25 @@ begin
end; end;
// 6. Cache Miss (User Code) // 6. Cache Miss (User Code)
funcDef := FFunctionRegistry.Resolve(calleeIdent.Address); funcDef := FEnvironment.FunctionRegistry.Resolve(calleeIdent.Address);
if (funcDef <> nil) then if (funcDef <> nil) then
begin begin
// Cannot specialize closures or functions with nested closures
// that might depend on the local environment being detached.
// We check if it's a lambda expression node (which it usually is)
if funcDef.Kind = akLambdaExpression then
begin
var lambdaDef := funcDef.AsLambdaExpression;
if (Length(lambdaDef.Upvalues) > 0) or (lambdaDef.HasNestedLambdas) then
begin
// This function relies on local scope context. We cannot lift it
// to a static compilation unit safely. Fallback to dynamic dispatch.
Result := TAst.FunctionCall(newCallee, newArgs, Node.StaticType, Node.IsTailCall, nil);
exit;
end;
end;
// 6a. Compile func with KNOWN TYPES // 6a. Compile func with KNOWN TYPES
var compiled := FEnvironment.Compile(funcDef, argTypes); var compiled := FEnvironment.Compile(funcDef, argTypes);
@@ -183,7 +193,7 @@ begin
// Get the return type from the *full function type* returned by Compile // Get the return type from the *full function type* returned by Compile
var returnType := compiled.StaticType.Signatures[0].ReturnType; var returnType := compiled.StaticType.Signatures[0].ReturnType;
specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType); specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType);
FMonomorphCache.Add(key, specializedMethod); FEnvironment.MonomorphCache.Add(key, specializedMethod);
// 6e. Return the new node // 6e. Return the new node
Result := Result :=