Static specialization done
This commit is contained in:
@@ -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
@@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 :=
|
||||||
|
|||||||
Reference in New Issue
Block a user