diff --git a/compiler/optcse.pas b/compiler/optcse.pas index ae59295b91..8e5821413d 100644 --- a/compiler/optcse.pas +++ b/compiler/optcse.pas @@ -51,7 +51,7 @@ unit optcse; nutils,compinnr, nbas,nld,ninl,ncal,nadd,nmem, pass_1, - symconst,symdef,symsym, + symconst,symdef,symsym,symtable,symtype, defutil, optbase; @@ -138,6 +138,7 @@ unit optcse; var i : longint; + tempdef : tdef; begin result:=fen_false; { don't add the tree below an untyped const parameter: there is @@ -160,14 +161,29 @@ unit optcse; if { node possible to add? } assigned(n.resultdef) and - ( + (( { regable expressions } (actualtargetnode(@n)^.flags*[nf_write,nf_modify,nf_address_taken]=[]) and - ((((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable or tstoreddef(n.resultdef).is_const_intregable) and + ( + tstoreddef(n.resultdef).is_intregable or + tstoreddef(n.resultdef).is_fpuregable or + tstoreddef(n.resultdef).is_const_intregable + ) and { is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this } - (not(n.resultdef.typ in [arraydef,recorddef]))) or - is_dynamic_array(n.resultdef) or - ((n.resultdef.typ in [arraydef,recorddef]) and not(is_special_array(tstoreddef(n.resultdef))) and not(tstoreddef(n.resultdef).is_intregable) and not(tstoreddef(n.resultdef).is_fpuregable)) + ( + not(n.resultdef.typ in [arraydef,recorddef]) or + ( + ( + (n.resultdef.typ = recorddef) and + tabstractrecordsymtable(tabstractrecorddef(n.resultdef).symtable).has_single_field(tempdef) + ) or + is_dynamic_array(n.resultdef) or + ( + not(is_special_array(tstoreddef(n.resultdef))) and + not(tstoreddef(n.resultdef).is_intregable) and + not(tstoreddef(n.resultdef).is_fpuregable) + ) + ) ) and { same for voiddef } not(is_void(n.resultdef)) and diff --git a/compiler/symsym.pas b/compiler/symsym.pas index f62a85b4f3..8e717e7a69 100644 --- a/compiler/symsym.pas +++ b/compiler/symsym.pas @@ -1728,6 +1728,8 @@ implementation function tabstractvarsym.is_regvar(refpara: boolean):boolean; + var + tempdef : tdef; begin { Register variables are not allowed in the following cases: - regvars are disabled @@ -1746,6 +1748,7 @@ implementation {$if not defined(powerpc) and not defined(powerpc64)} and ((vardef.typ <> recorddef) or (varregable = vr_addr) or + tabstractrecordsymtable(tabstractrecorddef(vardef).symtable).has_single_field(tempdef) or not(varstate in [vs_written,vs_readwritten])); {$endif} end;