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 11 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]);