Pass constant data to backend as pointers into buffer.

This avoids needing to generate many intermediate code records representing the data at most 8 bytes at a time, which should reduce memory use and probably improve performance for large initialized arrays or structs.
This commit is contained in:
Stephen Heumann 2022-12-03 00:14:15 -06:00
parent 28e119afb1
commit d56cf7e666
4 changed files with 60 additions and 27 deletions

40
CGI.pas
View File

@ -279,7 +279,11 @@ type
cgDouble,
cgComp,
cgExtended : (rval: extended);
cgString : (str: longStringPtr);
cgString : (
case isByteSeq: boolean of
false : (str: longStringPtr);
true : (data: ptr; len: longint);
);
cgVoid,
ccPointer : (pval: longint; pstr: longStringPtr);
end;
@ -574,6 +578,16 @@ procedure GenS (fop: pcodes; str: longstringPtr);
{ str - pointer to string }
procedure GenBS (fop: pcodes; data: ptr; len: longint);
{ generate an instruction that uses a byte sequence operand }
{ }
{ parameters: }
{ fop - operation code }
{ data - pointer to data }
{ data - length of data }
procedure GenL1 (fop: pcodes; lval: longint; fp1: integer);
{ generate an instruction that uses a longint and an int }
@ -1230,6 +1244,30 @@ if codeGeneration then begin
end; {GenS}
procedure GenBS {fop: pcodes; data: ptr; len: longint};
{ generate an instruction that uses a byte sequence operand }
{ }
{ parameters: }
{ fop - operation code }
{ data - pointer to data }
{ len - length of data }
var
lcode: icptr; {local copy of code}
begin {GenBS}
if codeGeneration then begin
lcode := code;
lcode^.optype := cgString;
lcode^.isByteSeq := true;
lcode^.data := data;
lcode^.len := len;
Gen0(fop);
end; {if}
end; {GenBS}
procedure GenL1 {fop: pcodes; lval: longint; fp1: integer};
{ generate an instruction that uses a longint and an int }

View File

@ -202,6 +202,7 @@ else if (op1 <> nil) and (op2 <> nil) then
or fastMath then
CodesMatch := true;
cgString:
if not (op1^.isByteSeq or op1^.isByteSeq) then
CodesMatch := LongStrCmp(op1^.str, op2^.str);
cgVoid, ccPointer:
if op1^.pval = op2^.pval then

View File

@ -361,6 +361,7 @@ type
rkind = (k1,k2,k3,k4); {cnv record types}
var
bp: ^byte; {byte pointer}
ch: char; {temp storage for string constants}
cns: realRec; {for converting reals to bytes}
cnv: record {for converting double, real to bytes}
@ -672,9 +673,20 @@ case mode of
CnOut(cns.inSANE[j]);
end;
cgString : begin
if not icptr(name)^.isByteSeq then begin
sptr := icptr(name)^.str;
for j := 1 to sptr^.length do
CnOut(ord(sPtr^.str[j]));
end {if}
else begin
lval := 0;
while lval < icptr(name)^.len do begin
bp := pointer(
ord4(icptr(name)^.data) + lval);
CnOut(bp^);
lval := lval + 1;
end;
end; {else}
end;
ccPointer : begin
if icptr(name)^.lab <> nil then begin

View File

@ -801,7 +801,7 @@ procedure DoGlobals;
begin {StaticInit}
{allocate buffer}
{(+3 for possible bitfield overhang)}
buffHandle := NewHandle(variable^.itype^.size+3, UserID, $8000, nil);
buffHandle := NewHandle(variable^.itype^.size+3, globalID, $8000, nil);
if ToolError <> 0 then TermError(5);
buffPtr := buffHandle^;
@ -892,25 +892,9 @@ procedure DoGlobals;
endDisp := variable^.itype^.size
else
endDisp := relocs^.disp;
while endDisp - disp >= 8 do begin
qp := pointer(ord4(buffPtr) + disp);
GenQ1(dc_cns, qp^, 1);
disp := disp + 8;
end; {while}
if endDisp - disp >= 4 then begin
lp := pointer(ord4(buffPtr) + disp);
GenL1(dc_cns, lp^, 1);
disp := disp + 4;
end; {if}
if endDisp - disp >= 2 then begin
wp := pointer(ord4(buffPtr) + disp);
Gen2t(dc_cns, wp^, 1, cgUWord);
disp := disp + 2;
end; {if}
if endDisp - disp >= 1 then begin
bp := pointer(ord4(buffPtr) + disp);
Gen2t(dc_cns, bp^, 1, cgUByte);
disp := disp + 1;
if disp <> endDisp then begin
GenBS(dc_cns, pointer(ord4(buffPtr) + disp), endDisp - disp);
disp := endDisp;
end; {if}
if relocs <> nil then begin
code^.optype := ccPointer;
@ -930,8 +914,6 @@ procedure DoGlobals;
disp := disp + cgPointerSize;
end; {if}
end; {while}
DisposeHandle(buffHandle);
end; {StaticInit}