+ support for merging multiple tai_strings/tai_consts emitted as part of the

same string constant to be merged together into a single tai_string
    (required to efficiently represent string constants in llvm assembler
     --i.e., without splitting them into bytes--, while keeping the
     flexibility in the typed constant parser to mix individual elements
     and strings)

git-svn-id: branches/hlcgllvm@28135 -
This commit is contained in:
Jonas Maebe 2014-07-02 17:24:59 +00:00
parent 2d335baab8
commit e0c1c4d3bf
2 changed files with 92 additions and 1 deletions

View File

@ -79,10 +79,16 @@ type
protected
fvalues: tfplist;
fisstring: boolean;
{ converts the existing data to a single tai_string }
procedure convert_to_string;
procedure add_to_string(strtai: tai_string; othertai: tai);
public
constructor create(_adetyp: ttypedconstkind; _fdef: tdef);
function getenumerator: tadeenumerator;
procedure addvalue(val: tai_abstracttypedconst);
procedure finish;
destructor destroy; override;
end;
@ -241,9 +247,56 @@ implementation
tai_aggregatetypedconst
****************************************************************************}
procedure tai_aggregatetypedconst.convert_to_string;
var
ai: tai_abstracttypedconst;
newstr: tai_string;
begin
newstr:=tai_string.Create('');
for ai in self do
begin
if ai.adetyp<>tck_simple then
internalerror(2014070103);
add_to_string(newstr,tai_simpletypedconst(ai).val);
ai.free;
end;
fvalues.count:=0;
{ the "nil" def will be replaced with an array def of the appropriate
size once we're finished adding data, so we don't create intermediate
arraydefs all the time }
fvalues.add(tai_simpletypedconst.create(tck_simple,nil,newstr));
end;
procedure tai_aggregatetypedconst.add_to_string(strtai: tai_string; othertai: tai);
begin
case othertai.typ of
ait_string:
begin
strtai.str:=reallocmem(strtai.str,strtai.len+tai_string(othertai).len+1);
{ also copy null terminator }
move(tai_string(othertai).str[0],strtai.str[strtai.len],tai_string(othertai).len+1);
{ the null terminator is not part of the length }
strtai.len:=strtai.len+tai_string(othertai).len;
end;
ait_const:
begin
if tai_const(othertai).size<>1 then
internalerror(2014070101);
strtai.str:=reallocmem(strtai.str,strtai.len+1);
strtai.str[strtai.len]:=ansichar(tai_const(othertai).value);
strtai.str[strtai.len+1]:=#0;
inc(strtai.len);
end;
else
internalerror(2014070102);
end;
end;
constructor tai_aggregatetypedconst.create(_adetyp: ttypedconstkind; _fdef: tdef);
begin
inherited;
fisstring:=false;
fvalues:=tfplist.create;
end;
@ -256,7 +309,44 @@ implementation
procedure tai_aggregatetypedconst.addvalue(val: tai_abstracttypedconst);
begin
fvalues.add(val);
{ merge string constants and ordinal constants added in an array of
char, to unify the length and the string data }
if fisstring or
((val.adetyp=tck_simple) and
(tai_simpletypedconst(val).val.typ=ait_string)) then
begin
if not fisstring and
(fvalues.count>0) then
convert_to_string;
fisstring:=true;
case fvalues.count of
0: fvalues.add(val);
1:
begin
add_to_string(tai_string(tai_simpletypedconst(fvalues[0]).val),tai_simpletypedconst(val).val);
val.free
end
else
internalerror(2014070104);
end;
end
else
fvalues.add(val);
end;
procedure tai_aggregatetypedconst.finish;
begin
if fisstring then
begin
{ set the def: an array of char with the same length as the string
data }
if fvalues.count<>1 then
internalerror(2014070105);
tai_simpletypedconst(fvalues[0]).fdef:=
getarraydef(cansichartype,
tai_string(tai_simpletypedconst(fvalues[0]).val).len);
end;
end;

View File

@ -209,6 +209,7 @@ implementation
if not assigned(faggregates) or
(faggregates.count=0) then
internalerror(2014060101);
tai_aggregatetypedconst(faggregates[faggregates.count-1]).finish;
{ already added to the asmlist if necessary }
faggregates.count:=faggregates.count-1;
end;