Browse Source

* disable inlining across units when the inline procedure references
a variable or procedure in the static symtable

peter 20 years ago
parent
commit
29db12ecfa
3 changed files with 53 additions and 6 deletions
  1. 8 2
      compiler/globtype.pas
  2. 22 3
      compiler/ncal.pas
  3. 23 1
      compiler/psub.pas

+ 8 - 2
compiler/globtype.pas

@@ -236,7 +236,9 @@ than 255 characters. That's why using Ansi Strings}
          { procedure uses fpu}
          { procedure uses fpu}
          pi_uses_fpu,
          pi_uses_fpu,
          { procedure uses GOT for PIC code }
          { procedure uses GOT for PIC code }
-         pi_needs_got
+         pi_needs_got,
+         { references local var/proc }
+         pi_inline_local_only
        );
        );
        tprocinfoflags=set of tprocinfoflag;
        tprocinfoflags=set of tprocinfoflag;
 
 
@@ -313,7 +315,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.64  2004-10-31 21:45:03  peter
+  Revision 1.65  2004-12-15 21:08:15  peter
+    * disable inlining across units when the inline procedure references
+      a variable or procedure in the static symtable
+
+  Revision 1.64  2004/10/31 21:45:03  peter
     * generic tlocation
     * generic tlocation
     * move tlocation to cgutils
     * move tlocation to cgutils
 
 

+ 22 - 3
compiler/ncal.pas

@@ -2119,6 +2119,8 @@ type
 
 
 
 
     function tcallnode.pass_1 : tnode;
     function tcallnode.pass_1 : tnode;
+      var
+        st : tsymtable;
       begin
       begin
          result:=nil;
          result:=nil;
 
 
@@ -2126,8 +2128,21 @@ type
          if (procdefinition.proccalloption=pocall_inline) and
          if (procdefinition.proccalloption=pocall_inline) and
             (po_has_inlininginfo in procdefinition.procoptions) then
             (po_has_inlininginfo in procdefinition.procoptions) then
            begin
            begin
-             result:=pass1_inline;
-             exit;
+             { Check if we can inline the procedure when it references proc/var that
+               are not in the globally available }
+             st:=procdefinition.owner;
+             if (st.symtabletype=objectsymtable) then
+               st:=st.defowner.owner;
+             if (pi_inline_local_only in tprocdef(procdefinition).inlininginfo^.flags) and
+                (st.unitid<>0) then
+               begin
+                 Comment(V_lineinfo+V_Debug,'Not inlining "'+tprocdef(procdefinition).procsym.realname+'", references static symtable');
+               end
+             else
+               begin
+                 result:=pass1_inline;
+                 exit;
+               end;
            end;
            end;
 
 
          { calculate the parameter info for the procdef }
          { calculate the parameter info for the procdef }
@@ -2434,7 +2449,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.270  2004-12-15 19:30:16  peter
+  Revision 1.271  2004-12-15 21:08:15  peter
+    * disable inlining across units when the inline procedure references
+      a variable or procedure in the static symtable
+
+  Revision 1.270  2004/12/15 19:30:16  peter
     * give error when paraloc is not filled in order_parameter
     * give error when paraloc is not filled in order_parameter
 
 
   Revision 1.269  2004/12/07 16:11:52  peter
   Revision 1.269  2004/12/07 16:11:52  peter

+ 23 - 1
compiler/psub.pas

@@ -959,6 +959,20 @@ implementation
       end;
       end;
 
 
 
 
+    function checklocalinlining(var n: tnode; arg: pointer): foreachnoderesult;
+      begin
+        result:=fen_false;
+        case n.nodetype of
+          loadn :
+            if tloadnode(n).symtableentry.owner.symtabletype=staticsymtable then
+              result:=fen_norecurse_true;
+          calln :
+            if tcallnode(n).procdefinition.owner.symtabletype=staticsymtable then
+              result:=fen_norecurse_true;
+        end;
+      end;
+
+
     procedure tcgprocinfo.parse_body;
     procedure tcgprocinfo.parse_body;
       var
       var
          oldprocinfo : tprocinfo;
          oldprocinfo : tprocinfo;
@@ -1046,6 +1060,10 @@ implementation
                  include(procdef.procoptions,po_has_inlininginfo);
                  include(procdef.procoptions,po_has_inlininginfo);
                  procdef.inlininginfo^.code:=code.getcopy;
                  procdef.inlininginfo^.code:=code.getcopy;
                  procdef.inlininginfo^.flags:=current_procinfo.flags;
                  procdef.inlininginfo^.flags:=current_procinfo.flags;
+                 { References a local var or proc? }
+                 if foreachnodestatic(procdef.inlininginfo^.code,@checklocalinlining,nil) then
+                   include(procdef.inlininginfo^.flags,pi_inline_local_only);
+                 { The blocknode needs to set an exit label }
                  if procdef.inlininginfo^.code.nodetype=blockn then
                  if procdef.inlininginfo^.code.nodetype=blockn then
                    include(procdef.inlininginfo^.code.flags,nf_block_with_exit);
                    include(procdef.inlininginfo^.code.flags,nf_block_with_exit);
                end;
                end;
@@ -1446,7 +1464,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.224  2004-12-15 17:01:28  peter
+  Revision 1.225  2004-12-15 21:08:15  peter
+    * disable inlining across units when the inline procedure references
+      a variable or procedure in the static symtable
+
+  Revision 1.224  2004/12/15 17:01:28  peter
     * fixed crash with -vp
     * fixed crash with -vp
 
 
   Revision 1.223  2004/12/15 16:00:16  peter
   Revision 1.223  2004/12/15 16:00:16  peter