Explorar el Código

* do not set the addr taken flag for nodes to passed to const/var/out parameters, if
the code of the callee is known and within the callee no address of the parameters
is taken

florian hace 11 meses
padre
commit
b2892adebf
Se han modificado 1 ficheros con 27 adiciones y 9 borrados
  1. 27 9
      compiler/ncal.pas

+ 27 - 9
compiler/ncal.pas

@@ -1385,10 +1385,16 @@ implementation
                    begin
                      { compilerprocs never capture the address of their
                        parameters }
-                     if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
-                       make_not_regable(left,[ra_addr_regable,ra_addr_taken])
-                     else
+                     if (po_compilerproc in aktcallnode.procdefinition.procoptions) or
+                     { if we handled already the proc. body and it is not inlined,
+                       we can propagate the information if the address of a parameter is taken or not }
+                     ((aktcallnode.procdefinition.typ=procdef) and
+                      not(po_inline in tprocdef(aktcallnode.procdefinition).procoptions) and
+                      (tprocdef(aktcallnode.procdefinition).is_implemented) and
+                      not(parasym.addr_taken)) then
                        make_not_regable(left,[ra_addr_regable])
+                     else
+                       make_not_regable(left,[ra_addr_regable,ra_addr_taken]);
                    end
                  else
                   case parasym.varspez of
@@ -1400,10 +1406,16 @@ implementation
                         set_varstate(left,vs_readwritten,[]);
                         { compilerprocs never capture the address of their
                           parameters }
-                        if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
-                          make_not_regable(left,[ra_addr_regable,ra_addr_taken])
-                        else
+                        if (po_compilerproc in aktcallnode.procdefinition.procoptions) or
+                        { if we handled already the proc. body and it is not inlined,
+                          we can propagate the information if the address of a parameter is taken or not }
+                        ((aktcallnode.procdefinition.typ=procdef) and
+                         not(po_inline in tprocdef(aktcallnode.procdefinition).procoptions) and
+                         (tprocdef(aktcallnode.procdefinition).is_implemented) and
+                         not(parasym.addr_taken)) then
                           make_not_regable(left,[ra_addr_regable])
+                        else
+                          make_not_regable(left,[ra_addr_regable,ra_addr_taken]);
                       end;
                     vs_var,
                     vs_constref:
@@ -1411,10 +1423,16 @@ implementation
                         set_varstate(left,vs_readwritten,[vsf_must_be_valid,vsf_use_hints]);
                         { compilerprocs never capture the address of their
                           parameters }
-                        if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
-                          make_not_regable(left,[ra_addr_regable,ra_addr_taken])
-                        else
+                        if (po_compilerproc in aktcallnode.procdefinition.procoptions) or
+                        { if we handled already the proc. body and it is not inlined,
+                          we can propagate the information if the address of a parameter is taken or not }
+                        ((aktcallnode.procdefinition.typ=procdef) and
+                         not(po_inline in tprocdef(aktcallnode.procdefinition).procoptions) and
+                         (tprocdef(aktcallnode.procdefinition).is_implemented) and
+                         not(parasym.addr_taken)) then
                           make_not_regable(left,[ra_addr_regable])
+                        else
+                          make_not_regable(left,[ra_addr_regable,ra_addr_taken]);
                       end;
                     else
                       set_varstate(left,vs_read,[vsf_must_be_valid]);