* The "Val" intrinsic is now simplified for string constants akin to a

pure function.
This commit is contained in:
J. Gareth "Curious Kit" Moreton 2023-12-27 18:56:42 +00:00 committed by FPK
parent a9316b1953
commit 6597f02ebc
2 changed files with 68 additions and 2 deletions

View File

@ -2734,6 +2734,9 @@ implementation
maxlennode, outnode, valnode: TNode;
MaxStrLen: Int64;
StringLiteral: string;
ValOutput: TConstExprInt;
ValCode: TCGInt;
NewStatements: TStatementNode;
begin
result := nil;
case intrinsiccode of
@ -2802,6 +2805,69 @@ implementation
end;
end;
end;
in_val_x:
begin
{ rare optimization opportunity which takes some extra time,
so check only at level 3+ }
if not(cs_opt_level3 in current_settings.optimizerswitches) then
exit;
{ If the input is a constant, attempt to convert, for example:
"Val('5', Output, Code);" to "Output := 5; Code := 0;" }
{ Format of the internal function fpc_val_sint_*str) is:
fpc_val_sint_*str(SizeInt; *String; out ValSInt): ValSInt; }
{ Remember the parameters are in reverse order - the leftmost one
is the integer data size can usually be ignored.
For fpc_val_uint_*str variants, the data size is not present as
of FPC 3.2.0
Para indices:
* 0 = Code output (present even if omitted in original code)
* 1 = String input
* 2 = Data size
}
para := GetParaFromIndex(0);
if Assigned(para) then
begin
outnode := para.left;
para := GetParaFromIndex(1);
if Assigned(para) then
begin
valnode := para.left;
if is_conststringnode(valnode) then
begin
ValOutput.signed := is_signed(ResultDef);
if ValOutput.signed then
Val(TStringConstNode(valnode).value_str, ValOutput.svalue, ValCode)
else
Val(TStringConstNode(valnode).value_str, ValOutput.uvalue, ValCode);
{ Due to the way the node tree works, we have to insert
the assignment to the Code output within the
assignment to the value output (function result),
so use a block node for that}
Result := internalstatements(NewStatements);
{ Create a node for writing the Code output }
addstatement(
NewStatements,
CAssignmentNode.Create_Internal(
outnode.getcopy(), { The original will get destroyed }
COrdConstNode.Create(ValCode, outnode.ResultDef, False)
)
);
{ Now actually create the function result }
valnode := COrdConstNode.Create(ValOutput, ResultDef, False);
addstatement(NewStatements, valnode);
{ Result will now undergo firstpass }
end;
end;
end;
end;
else
;
end;

View File

@ -1765,9 +1765,9 @@ implementation
if (destpara.resultdef.typ=enumdef) or
((destpara.resultdef.typ=floatdef) and (tfloatdef(destpara.resultdef).floattype=s64comp))
then
tc:=ccallnode.createintern(procname,newparas)
tc:=ccallnode.createfromintrinsic(in_val_x,procname,newparas)
else
tc:=ctypeconvnode.create(ccallnode.createintern(procname,newparas),destpara.left.resultdef);
tc:=ctypeconvnode.create(ccallnode.createfromintrinsic(in_val_x,procname,newparas),destpara.left.resultdef);
addstatement(newstatement,cassignmentnode.create(
destpara.left,ctypeconvnode.create_internal(tc,destpara.left.resultdef)));