refactor(ast): replace TIdentExpr.IsVarParam with TParamMode enum
Introduce TParamMode (pmNone, pmVar, pmRecordValue, pmStaticArrayValue) on TIdentExpr so the semantic pass records the precise param-slot classification once instead of merging three cases into a Boolean. The QBE backend treats all three modes identically (ParamMode <> pmNone), preserving existing semantics. The native x86-64 and LLVM backends can now dispatch on the enum directly instead of re-deriving the distinction from Sym.Kind and TypeDesc.Kind at every reader site. Other IsVarParam fields (TFieldAccessExpr, TMethodCallExpr, TAssignment, TMethodParam, TMethodCallStmt) are unchanged. Based on Andrew Haines' proposal and patch (blaise_llvm d16f877).
This commit is contained in:
parent
d00323e0b2
commit
40755b987a
|
|
@ -2846,7 +2846,7 @@ begin
|
|||
if TIdentExpr(AExpr).IsConstant then
|
||||
Self.Emit(Format(#9'movabsq $%s, %%rax',
|
||||
[IntToStr(TIdentExpr(AExpr).ConstValue)]))
|
||||
else if TIdentExpr(AExpr).IsVarParam then
|
||||
else if TIdentExpr(AExpr).ParamMode <> pmNone then
|
||||
begin
|
||||
Self.Emit(Format(#9'movq %s, %%rcx',
|
||||
[Self.VarOperand(TIdentExpr(AExpr).Name)]));
|
||||
|
|
@ -4327,7 +4327,7 @@ begin
|
|||
|
||||
{ @VarParam — the variable's slot holds a pointer to the caller's data;
|
||||
load that pointer value (not the slot address). }
|
||||
if (AOE.Expr is TIdentExpr) and TIdentExpr(AOE.Expr).IsVarParam then
|
||||
if (AOE.Expr is TIdentExpr) and (TIdentExpr(AOE.Expr).ParamMode <> pmNone) then
|
||||
begin
|
||||
Self.Emit(Format(#9'movq %s, %%rax',
|
||||
[Self.VarOperand(TIdentExpr(AOE.Expr).Name)]));
|
||||
|
|
@ -4770,7 +4770,7 @@ begin
|
|||
begin
|
||||
{ Pass the argument's address. If the arg is itself a var param the slot
|
||||
already holds a pointer; otherwise take the address of the local/global. }
|
||||
if (AArg is TIdentExpr) and TIdentExpr(AArg).IsVarParam then
|
||||
if (AArg is TIdentExpr) and (TIdentExpr(AArg).ParamMode <> pmNone) then
|
||||
Self.Emit(Format(#9'movq %s, %%rax',
|
||||
[Self.VarOperand(TIdentExpr(AArg).Name)]))
|
||||
else if (AArg is TIdentExpr) and Self.IsLocal(TIdentExpr(AArg).Name) then
|
||||
|
|
@ -7589,7 +7589,7 @@ begin
|
|||
end
|
||||
else if IsVar then
|
||||
begin
|
||||
if (Arg is TIdentExpr) and TIdentExpr(Arg).IsVarParam then
|
||||
if (Arg is TIdentExpr) and (TIdentExpr(Arg).ParamMode <> pmNone) then
|
||||
Self.Emit(Format(#9'movq %s, %%rax',
|
||||
[Self.VarOperand(TIdentExpr(Arg).Name)]))
|
||||
else if (Arg is TIdentExpr) and Self.IsLocal(TIdentExpr(Arg).Name) then
|
||||
|
|
@ -7692,7 +7692,7 @@ begin
|
|||
end
|
||||
else if IsVar then
|
||||
begin
|
||||
if (Arg is TIdentExpr) and TIdentExpr(Arg).IsVarParam then
|
||||
if (Arg is TIdentExpr) and (TIdentExpr(Arg).ParamMode <> pmNone) then
|
||||
Self.Emit(Format(#9'movq %s, %%rax',
|
||||
[Self.VarOperand(TIdentExpr(Arg).Name)]))
|
||||
else if (Arg is TIdentExpr) and Self.IsLocal(TIdentExpr(Arg).Name) then
|
||||
|
|
@ -7798,7 +7798,7 @@ begin
|
|||
TProcParamInfo(AProcType.Params.Items[I]).IsVarParam;
|
||||
if IsVar then
|
||||
begin
|
||||
if (Arg is TIdentExpr) and TIdentExpr(Arg).IsVarParam then
|
||||
if (Arg is TIdentExpr) and (TIdentExpr(Arg).ParamMode <> pmNone) then
|
||||
Self.Emit(Format(#9'movq %s, %%rax',
|
||||
[Self.VarOperand(TIdentExpr(Arg).Name)]))
|
||||
else if (Arg is TIdentExpr) and Self.IsLocal(TIdentExpr(Arg).Name) then
|
||||
|
|
|
|||
|
|
@ -69,10 +69,17 @@ type
|
|||
|
||||
TNilLiteral = class(TASTExpr); { nil keyword — type is tyNil }
|
||||
|
||||
TParamMode = (
|
||||
pmNone,
|
||||
pmVar,
|
||||
pmRecordValue,
|
||||
pmStaticArrayValue
|
||||
);
|
||||
|
||||
TIdentExpr = class(TASTExpr)
|
||||
public
|
||||
Name: string;
|
||||
IsVarParam: Boolean; { set by uSemantic — True if this ident is a var parameter }
|
||||
ParamMode: TParamMode; { set by uSemantic — how the param slot is laid out }
|
||||
IsConstant: Boolean; { set by uSemantic — True if this ident is a skConstant symbol }
|
||||
ConstValue: Int64; { valid when IsConstant = True; integer/bool/enum value }
|
||||
ConstString: string; { valid when IsConstant = True and type is tyString }
|
||||
|
|
@ -1690,7 +1697,7 @@ begin
|
|||
begin
|
||||
IE := TIdentExpr.Create();
|
||||
IE.Name := TIdentExpr(AExpr).Name;
|
||||
{ Note: leave IsConstant/IsVarParam/IsImplicitSelf/etc. nil/false —
|
||||
{ Note: leave IsConstant/ParamMode/IsImplicitSelf/etc. nil/false —
|
||||
semantic analyser must re-resolve in the new instance's scope. }
|
||||
Result := IE;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ begin
|
|||
end;
|
||||
if TIdentExpr(AExpr).IsImplicitSelfMethod then
|
||||
Flags := Flags + ' ImplicitSelfMethod';
|
||||
if TIdentExpr(AExpr).IsVarParam then
|
||||
if TIdentExpr(AExpr).ParamMode <> pmNone then
|
||||
Flags := Flags + ' VarParam';
|
||||
if TIdentExpr(AExpr).IsGlobal then
|
||||
Flags := Flags + ' Global';
|
||||
|
|
|
|||
|
|
@ -4322,7 +4322,7 @@ begin
|
|||
EmitLine(Format(' %s =l loadl %s', [Loaded, VarRef(Id.Name, Id.IsGlobal)]));
|
||||
Result := Loaded;
|
||||
end
|
||||
else if Id.IsVarParam then
|
||||
else if Id.ParamMode <> pmNone then
|
||||
begin
|
||||
{ Var-record param: dereference the param slot to get the actual record
|
||||
address. }
|
||||
|
|
@ -4449,7 +4449,7 @@ var
|
|||
SelfT: string;
|
||||
ImplFld: TFieldInfo;
|
||||
begin
|
||||
if AIdent.IsVarParam then
|
||||
if AIdent.ParamMode <> pmNone then
|
||||
begin
|
||||
// The local slot holds the caller's pointer — load it so we pass the
|
||||
// original address, not the address of the local slot.
|
||||
|
|
@ -10216,7 +10216,7 @@ begin
|
|||
EmitLine(Format(' %s =w loadw %%_cap_%s', [T, TIdentExpr(AExpr).Name]));
|
||||
end;
|
||||
end
|
||||
else if TIdentExpr(AExpr).IsVarParam and
|
||||
else if (TIdentExpr(AExpr).ParamMode <> pmNone) and
|
||||
(AExpr.ResolvedType <> nil) and
|
||||
(AExpr.ResolvedType.Kind in [tyRecord, tyStaticArray]) then
|
||||
begin
|
||||
|
|
@ -10225,7 +10225,7 @@ begin
|
|||
EmitLine(Format(' %s =l loadl %%_var_%s', [T, TIdentExpr(AExpr).Name]));
|
||||
Exit(T);
|
||||
end
|
||||
else if TIdentExpr(AExpr).IsVarParam then
|
||||
else if TIdentExpr(AExpr).ParamMode <> pmNone then
|
||||
begin
|
||||
{ Var param of scalar type: load pointer, then dereference to get value }
|
||||
Ptr := AllocTemp();
|
||||
|
|
|
|||
|
|
@ -7938,10 +7938,16 @@ begin
|
|||
the QBE ABI level: the local slot holds a pointer, not the aggregate
|
||||
bytes. Codegen must dereference the slot before reading fields. }
|
||||
TIdentExpr(AExpr).Name := Sym.Name; { normalise to declared casing }
|
||||
TIdentExpr(AExpr).IsVarParam :=
|
||||
(Sym.Kind = skVarParameter) or
|
||||
((Sym.Kind = skParameter) and (Sym.TypeDesc <> nil) and
|
||||
(Sym.TypeDesc.Kind in [tyRecord, tyStaticArray]));
|
||||
if Sym.Kind = skVarParameter then
|
||||
TIdentExpr(AExpr).ParamMode := pmVar
|
||||
else if (Sym.Kind = skParameter) and (Sym.TypeDesc <> nil) and
|
||||
(Sym.TypeDesc.Kind = tyRecord) then
|
||||
TIdentExpr(AExpr).ParamMode := pmRecordValue
|
||||
else if (Sym.Kind = skParameter) and (Sym.TypeDesc <> nil) and
|
||||
(Sym.TypeDesc.Kind = tyStaticArray) then
|
||||
TIdentExpr(AExpr).ParamMode := pmStaticArrayValue
|
||||
else
|
||||
TIdentExpr(AExpr).ParamMode := pmNone;
|
||||
TIdentExpr(AExpr).IsGlobal := Sym.IsGlobal;
|
||||
TIdentExpr(AExpr).IsThreadVar := Sym.IsThreadVar;
|
||||
if Sym.Kind = skConstant then
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ TArrayLiteralExpr.Elements serialise
|
|||
|
||||
# TNilLiteral (uAST.pas:70)
|
||||
|
||||
# TIdentExpr (uAST.pas:72)
|
||||
# TIdentExpr (uAST.pas:79)
|
||||
TIdentExpr.Name serialise
|
||||
TIdentExpr.IsVarParam safe
|
||||
TIdentExpr.ParamMode safe
|
||||
TIdentExpr.IsConstant safe
|
||||
TIdentExpr.ConstValue safe
|
||||
TIdentExpr.ConstString safe
|
||||
|
|
@ -38,7 +38,7 @@ TIdentExpr.IsImplicitSelfMethod safe
|
|||
TIdentExpr.IsMetaclassRef safe
|
||||
TIdentExpr.ConstArraySymbol safe
|
||||
|
||||
# TFieldAccessExpr (uAST.pas:93)
|
||||
# TFieldAccessExpr (uAST.pas:100)
|
||||
TFieldAccessExpr.RecordName serialise
|
||||
TFieldAccessExpr.FieldName serialise
|
||||
TFieldAccessExpr.Base serialise
|
||||
|
|
@ -63,29 +63,29 @@ TFieldAccessExpr.PropIndexExpr serialise
|
|||
TFieldAccessExpr.IsCharAccess safe
|
||||
TFieldAccessExpr.IsArrayAccess safe
|
||||
|
||||
# TIsExpr (uAST.pas:125)
|
||||
# TIsExpr (uAST.pas:132)
|
||||
TIsExpr.Obj serialise
|
||||
TIsExpr.TypeName serialise
|
||||
|
||||
# TAsExpr (uAST.pas:133)
|
||||
# TAsExpr (uAST.pas:140)
|
||||
TAsExpr.Obj serialise
|
||||
TAsExpr.TypeName serialise
|
||||
|
||||
# TSupportsExpr (uAST.pas:142)
|
||||
# TSupportsExpr (uAST.pas:149)
|
||||
TSupportsExpr.Obj serialise
|
||||
TSupportsExpr.IntfTypeName serialise
|
||||
TSupportsExpr.OutVarName serialise
|
||||
TSupportsExpr.OutVarIsGlobal safe
|
||||
|
||||
# TBinaryExpr (uAST.pas:158)
|
||||
# TBinaryExpr (uAST.pas:165)
|
||||
TBinaryExpr.Op serialise
|
||||
TBinaryExpr.Left serialise
|
||||
TBinaryExpr.Right serialise
|
||||
|
||||
# TNotExpr (uAST.pas:166)
|
||||
# TNotExpr (uAST.pas:173)
|
||||
TNotExpr.Expr serialise
|
||||
|
||||
# TAssignment (uAST.pas:178)
|
||||
# TAssignment (uAST.pas:185)
|
||||
TAssignment.Name serialise
|
||||
TAssignment.Expr serialise
|
||||
TAssignment.IsVarParam safe
|
||||
|
|
@ -94,23 +94,23 @@ TAssignment.IsThreadVar safe
|
|||
TAssignment.IsWeakLhs safe
|
||||
TAssignment.ImplicitSelfField safe
|
||||
|
||||
# TIfStmt (uAST.pas:194)
|
||||
# TIfStmt (uAST.pas:201)
|
||||
TIfStmt.Condition serialise
|
||||
TIfStmt.ThenStmt serialise
|
||||
TIfStmt.ElseStmt serialise
|
||||
|
||||
# TCompoundStmt (uAST.pas:202)
|
||||
# TCompoundStmt (uAST.pas:209)
|
||||
TCompoundStmt.Stmts serialise
|
||||
|
||||
# TWhileStmt (uAST.pas:209)
|
||||
# TWhileStmt (uAST.pas:216)
|
||||
TWhileStmt.Condition serialise
|
||||
TWhileStmt.Body serialise
|
||||
|
||||
# TRepeatStmt (uAST.pas:216)
|
||||
# TRepeatStmt (uAST.pas:223)
|
||||
TRepeatStmt.Body serialise
|
||||
TRepeatStmt.Condition serialise
|
||||
|
||||
# TForStmt (uAST.pas:223)
|
||||
# TForStmt (uAST.pas:230)
|
||||
TForStmt.VarName serialise
|
||||
TForStmt.IsGlobal safe
|
||||
TForStmt.StartExpr serialise
|
||||
|
|
@ -118,7 +118,7 @@ TForStmt.EndExpr serialise
|
|||
TForStmt.IsDownTo serialise
|
||||
TForStmt.Body serialise
|
||||
|
||||
# TForInStmt (uAST.pas:234)
|
||||
# TForInStmt (uAST.pas:241)
|
||||
TForInStmt.VarName serialise
|
||||
TForInStmt.VarIsGlobal safe
|
||||
TForInStmt.CollExpr serialise
|
||||
|
|
@ -137,34 +137,34 @@ TForInStmt.IsSetIter safe
|
|||
TForInStmt.SetBitCount safe
|
||||
TForInStmt.SetMaskVarName safe
|
||||
|
||||
# TTryFinallyStmt (uAST.pas:267)
|
||||
# TTryFinallyStmt (uAST.pas:274)
|
||||
TTryFinallyStmt.TryBody serialise
|
||||
TTryFinallyStmt.FinallyBody serialise
|
||||
|
||||
# TTryExceptStmt (uAST.pas:284)
|
||||
# TTryExceptStmt (uAST.pas:291)
|
||||
TTryExceptStmt.TryBody serialise
|
||||
TTryExceptStmt.Handlers serialise
|
||||
TTryExceptStmt.ElseBody serialise
|
||||
TTryExceptStmt.ExceptBody serialise
|
||||
|
||||
# TRaiseStmt (uAST.pas:297)
|
||||
# TRaiseStmt (uAST.pas:304)
|
||||
TRaiseStmt.Expr serialise
|
||||
|
||||
# TExitStmt (uAST.pas:308)
|
||||
# TExitStmt (uAST.pas:315)
|
||||
TExitStmt.Value safe
|
||||
TExitStmt.ResultAssign safe
|
||||
|
||||
# TBreakStmt (uAST.pas:316)
|
||||
# TBreakStmt (uAST.pas:323)
|
||||
|
||||
# TContinueStmt (uAST.pas:319)
|
||||
# TContinueStmt (uAST.pas:326)
|
||||
|
||||
# TCaseStmt (uAST.pas:330)
|
||||
# TCaseStmt (uAST.pas:337)
|
||||
TCaseStmt.Selector serialise
|
||||
TCaseStmt.Branches serialise
|
||||
TCaseStmt.ElseStmt serialise
|
||||
TCaseStmt.IsStringCase safe
|
||||
|
||||
# TFieldAssignment (uAST.pas:341)
|
||||
# TFieldAssignment (uAST.pas:348)
|
||||
TFieldAssignment.RecordName serialise
|
||||
TFieldAssignment.FieldName serialise
|
||||
TFieldAssignment.Expr serialise
|
||||
|
|
@ -177,24 +177,24 @@ TFieldAssignment.IsVarParam safe
|
|||
TFieldAssignment.PropIndexExpr serialise
|
||||
TFieldAssignment.PropOwnerType safe
|
||||
|
||||
# TStaticSubscriptAssign (uAST.pas:360)
|
||||
# TStaticSubscriptAssign (uAST.pas:367)
|
||||
TStaticSubscriptAssign.ArrayName serialise
|
||||
TStaticSubscriptAssign.IndexExpr serialise
|
||||
TStaticSubscriptAssign.ValueExpr serialise
|
||||
TStaticSubscriptAssign.IsGlobal safe
|
||||
|
||||
# TPointerWriteStmt (uAST.pas:371)
|
||||
# TPointerWriteStmt (uAST.pas:378)
|
||||
TPointerWriteStmt.PtrExpr serialise
|
||||
TPointerWriteStmt.ValExpr serialise
|
||||
|
||||
# TProcCall (uAST.pas:379)
|
||||
# TProcCall (uAST.pas:386)
|
||||
TProcCall.Name serialise
|
||||
TProcCall.Args serialise
|
||||
TProcCall.IsImplicitSelfMethod safe
|
||||
TProcCall.IsIndirectCall safe
|
||||
TProcCall.IndirectCallIsGlobal safe
|
||||
|
||||
# TFuncCallExpr (uAST.pas:392)
|
||||
# TFuncCallExpr (uAST.pas:399)
|
||||
TFuncCallExpr.Name serialise
|
||||
TFuncCallExpr.Args serialise
|
||||
TFuncCallExpr.IsImplicitSelfMethod safe
|
||||
|
|
@ -204,18 +204,18 @@ TFuncCallExpr.IsBuiltinHasClassAttr safe
|
|||
TFuncCallExpr.HasClassAttrClass safe
|
||||
TFuncCallExpr.HasClassAttrAttr safe
|
||||
|
||||
# TIndirectFuncCallExpr (uAST.pas:418)
|
||||
# TIndirectFuncCallExpr (uAST.pas:425)
|
||||
TIndirectFuncCallExpr.CalleeExpr serialise
|
||||
TIndirectFuncCallExpr.Args serialise
|
||||
|
||||
# TDerefExpr (uAST.pas:428)
|
||||
# TDerefExpr (uAST.pas:435)
|
||||
TDerefExpr.Expr serialise
|
||||
|
||||
# TAddrOfExpr (uAST.pas:435)
|
||||
# TAddrOfExpr (uAST.pas:442)
|
||||
TAddrOfExpr.Expr serialise
|
||||
TAddrOfExpr.ResolvedFreeRoutine safe
|
||||
|
||||
# TMethodCallStmt (uAST.pas:447)
|
||||
# TMethodCallStmt (uAST.pas:454)
|
||||
TMethodCallStmt.ObjectName serialise
|
||||
TMethodCallStmt.Name serialise
|
||||
TMethodCallStmt.Args serialise
|
||||
|
|
@ -226,11 +226,11 @@ TMethodCallStmt.IsVarParam safe
|
|||
TMethodCallStmt.IsBuiltinToString safe
|
||||
TMethodCallStmt.IsProcFieldCall safe
|
||||
|
||||
# TInheritedCallStmt (uAST.pas:474)
|
||||
# TInheritedCallStmt (uAST.pas:481)
|
||||
TInheritedCallStmt.Name serialise
|
||||
TInheritedCallStmt.Args serialise
|
||||
|
||||
# TMethodCallExpr (uAST.pas:664)
|
||||
# TMethodCallExpr (uAST.pas:671)
|
||||
TMethodCallExpr.ObjectName serialise
|
||||
TMethodCallExpr.Name serialise
|
||||
TMethodCallExpr.Args serialise
|
||||
|
|
|
|||
Loading…
Reference in a new issue