* handle bitpacked booleans more efficiently

git-svn-id: trunk@38509 -
This commit is contained in:
florian 2018-03-12 22:05:34 +00:00
parent fe8f7a9876
commit a66016026b
4 changed files with 121 additions and 28 deletions

1
.gitattributes vendored
View File

@ -16055,6 +16055,7 @@ tests/webtbs/tw3328a.pp svneol=native#text/plain
tests/webtbs/tw3328b.pp svneol=native#text/plain
tests/webtbs/tw3334.pp svneol=native#text/plain
tests/webtbs/tw3340.pp svneol=native#text/plain
tests/webtbs/tw33417.pp svneol=native#text/pascal
tests/webtbs/tw3348.pp svneol=native#text/plain
tests/webtbs/tw3349.pp svneol=native#text/plain
tests/webtbs/tw3351.pp svneol=native#text/plain

View File

@ -59,37 +59,71 @@ implementation
var
tmpreg,lreg : tregister;
i : longint;
falselabel,truelabel,skiplabel: TAsmLabel;
begin
if not handle_locjump then
begin
secondpass(left);
case left.location.loc of
LOC_FLAGS :
begin
location_copy(location,left.location);
inverse_flags(location.resflags);
end;
LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE,
LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF :
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,0));
{ short code? }
if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG]) and
(left.location.sreg.bitlen=1) then
begin
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_SBRC,left.location.sreg.subsetreg,left.location.sreg.startbit));
current_asmdata.getjumplabel(truelabel);
current_asmdata.getjumplabel(falselabel);
{ sbrc does a jump without an explicit label,
if we do not insert skiplabel here and increase its reference count, the optimizer removes the whole true block altogether }
current_asmdata.getjumplabel(skiplabel);
skiplabel.increfs;
location_reset_jump(location,truelabel,falselabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,truelabel);
end
else if (left.location.loc in [LOC_SUBSETREF,LOC_CSUBSETREF]) and
(left.location.sref.bitlen=1) and (left.location.sref.bitindexreg=NR_NO) then
begin
tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,u8inttype,osuinttype,left.location.sref.ref,tmpreg);
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_SBRC,tmpreg,left.location.sref.startbit));
current_asmdata.getjumplabel(truelabel);
current_asmdata.getjumplabel(falselabel);
{ sbrc does a jump without an explicit label,
if we do not insert skiplabel here and increase its reference count, the optimizer removes the whole true block altogether }
current_asmdata.getjumplabel(skiplabel);
skiplabel.increfs;
location_reset_jump(location,truelabel,falselabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
cg.a_label(current_asmdata.CurrAsmList,skiplabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,truelabel);
end
else
case left.location.loc of
LOC_FLAGS :
begin
location_copy(location,left.location);
inverse_flags(location.resflags);
end;
LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF,
LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE :
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,0));
tmpreg:=left.location.register;
for i:=2 to tcgsize2size[left.location.size] do
begin
if i=5 then
tmpreg:=left.location.registerhi
else
tmpreg:=cg.GetNextReg(tmpreg);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,NR_R1,tmpreg));
end;
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags:=F_EQ;
tmpreg:=left.location.register;
for i:=2 to tcgsize2size[left.location.size] do
begin
if i=5 then
tmpreg:=left.location.registerhi
else
tmpreg:=cg.GetNextReg(tmpreg);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,NR_R1,tmpreg));
end;
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags:=F_EQ;
end;
else
internalerror(2003042401);
end;
else
internalerror(2003042401);
end;
end;
end;

View File

@ -253,11 +253,38 @@ implementation
begin
opsize:=def_cgsize(p.resultdef);
case p.location.loc of
LOC_SUBSETREG,LOC_CSUBSETREG,
LOC_SUBSETREG,LOC_CSUBSETREG:
begin
if p.location.sreg.bitlen=1 then
begin
tmpreg:=cg.getintregister(list,p.location.sreg.subsetregsize);
hlcg.a_op_const_reg_reg(list,OP_AND,cgsize_orddef(p.location.sreg.subsetregsize),1 shl p.location.sreg.startbit,p.location.sreg.subsetreg,tmpreg);
end
else
begin
tmpreg:=cg.getintregister(list,OS_INT);
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
end;
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,truelabel);
cg.a_jmp_always(list,falselabel);
end;
LOC_SUBSETREF,LOC_CSUBSETREF:
begin
tmpreg := cg.getintregister(list,OS_INT);
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
if (p.location.sref.bitindexreg=NR_NO) and (p.location.sref.bitlen=1) then
begin
tmpreg:=cg.getintregister(list,OS_INT);
hlcg.a_load_ref_reg(list,u8inttype,osuinttype,p.location.sref.ref,tmpreg);
if target_info.endian=endian_big then
hlcg.a_op_const_reg_reg(list,OP_AND,osuinttype,1 shl (8-(p.location.sref.startbit+1)),tmpreg,tmpreg)
else
hlcg.a_op_const_reg_reg(list,OP_AND,osuinttype,1 shl p.location.sref.startbit,tmpreg,tmpreg);
end
else
begin
tmpreg:=cg.getintregister(list,OS_INT);
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
end;
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,truelabel);
cg.a_jmp_always(list,falselabel);
end;

31
tests/webtbs/tw33417.pp Normal file
View File

@ -0,0 +1,31 @@
type
tflags = bitpacked record // Flags
bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7 : boolean;
end;
var
gflags : tflags;
procedure p;
var
flags : tflags;
begin
flags:=gflags;
if flags.bit5 then
halt(1);
if gflags.bit5 then
halt(1);
if not flags.bit6 then
halt(1);
if not gflags.bit6 then
halt(1);
end;
begin
gflags.bit4:=false;
gflags.bit5:=false;
gflags.bit6:=true;
p;
writeln('ok');
end.