Browse Source

* 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 9 tháng trước cách đây
mục cha
commit
b2892adebf
1 tập tin đã thay đổi với 27 bổ sung9 xóa
  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]);