Browse Source

+ nolinline modifier to specify that a routine must never be inlined

git-svn-id: trunk@41198 -
Jonas Maebe 6 years ago
parent
commit
503ea604f3

+ 2 - 0
compiler/llvm/agllvm.pas

@@ -979,6 +979,8 @@ implementation
             writer.AsmWrite(' returns_twice');
             writer.AsmWrite(' returns_twice');
           if po_inline in pd.procoptions then
           if po_inline in pd.procoptions then
             writer.AsmWrite(' inlinehint');
             writer.AsmWrite(' inlinehint');
+          if po_noinline in pd.procoptions then
+            writer.AsmWrite(' noinline');
           { ensure that functions that happen to have the same name as a
           { ensure that functions that happen to have the same name as a
             standard C library function, but which are implemented in Pascal,
             standard C library function, but which are implemented in Pascal,
             are not considered to have the same semantics as the C function with
             are not considered to have the same semantics as the C function with

+ 11 - 2
compiler/pdecsub.pas

@@ -2369,7 +2369,7 @@ type
    end;
    end;
 const
 const
   {Should contain the number of procedure directives we support.}
   {Should contain the number of procedure directives we support.}
-  num_proc_directives=51;
+  num_proc_directives=52;
   proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
   proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
    (
    (
     (
     (
@@ -2516,7 +2516,16 @@ const
       pooption : [po_inline];
       pooption : [po_inline];
       mutexclpocall : [pocall_safecall];
       mutexclpocall : [pocall_safecall];
       mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
       mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
-      mutexclpo     : [po_exports,po_external,po_interrupt,po_virtualmethod,po_iocheck]
+      mutexclpo     : [po_noinline,po_exports,po_external,po_interrupt,po_virtualmethod,po_iocheck]
+    ),(
+      idtok:_NOINLINE;
+      pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
+      handler  : nil;
+      pocall   : pocall_none;
+      pooption : [po_noinline];
+      mutexclpocall : [];
+      mutexclpotype : [];
+      mutexclpo     : [po_inline,po_external]
     ),(
     ),(
       idtok:_INTERNCONST;
       idtok:_INTERNCONST;
       pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
       pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];

+ 1 - 0
compiler/psub.pas

@@ -1379,6 +1379,7 @@ implementation
         if (cs_opt_autoinline in current_settings.optimizerswitches) and
         if (cs_opt_autoinline in current_settings.optimizerswitches) and
            { inlining not turned off? }
            { inlining not turned off? }
            (cs_do_inline in current_settings.localswitches) and
            (cs_do_inline in current_settings.localswitches) and
+           not(po_noinline in procdef.procoptions) and
            { no inlining yet? }
            { no inlining yet? }
            not(procdef.has_inlininginfo) and not(has_nestedprocs) and
            not(procdef.has_inlininginfo) and not(has_nestedprocs) and
             not(procdef.proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,potype_constructor,
             not(procdef.proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,potype_constructor,

+ 5 - 2
compiler/symconst.pas

@@ -413,7 +413,9 @@ type
     { procedure is an automatically generated property getter }
     { procedure is an automatically generated property getter }
     po_is_auto_getter,
     po_is_auto_getter,
     { procedure is an automatically generated property setter }
     { procedure is an automatically generated property setter }
-    po_is_auto_setter
+    po_is_auto_setter,
+    { must never be inlined          by auto-inlining }
+    po_noinline
   );
   );
   tprocoptions=set of tprocoption;
   tprocoptions=set of tprocoption;
 
 
@@ -1024,7 +1026,8 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has
       'po_is_function_ref',{po_is_function_ref}
       'po_is_function_ref',{po_is_function_ref}
       'C-style blocks',{po_is_block}
       'C-style blocks',{po_is_block}
       'po_is_auto_getter',{po_is_auto_getter}
       'po_is_auto_getter',{po_is_auto_getter}
-      'po_is_auto_setter'{po_is_auto_setter}
+      'po_is_auto_setter',{po_is_auto_setter}
+      'po_noinline'{po_noinline}
     );
     );
 
 
 implementation
 implementation

+ 2 - 1
compiler/symsym.pas

@@ -1862,7 +1862,8 @@ implementation
             { globalasmsym is called normally before the body of a subroutine is parsed
             { globalasmsym is called normally before the body of a subroutine is parsed
               so we cannot know if it will be auto inlined, so make all symbols of it
               so we cannot know if it will be auto inlined, so make all symbols of it
               global if asked }
               global if asked }
-            (cs_opt_autoinline in current_settings.optimizerswitches))
+            (not(po_noinline in current_procinfo.procdef.procoptions) and
+             (cs_opt_autoinline in current_settings.optimizerswitches)))
           ) or
           ) or
           (vo_is_public in varoptions);
           (vo_is_public in varoptions);
       end;
       end;

+ 2 - 0
compiler/tokens.pas

@@ -236,6 +236,7 @@ type
     _MULTIPLY,
     _MULTIPLY,
     _MWPASCAL,
     _MWPASCAL,
     _NEGATIVE,
     _NEGATIVE,
+    _NOINLINE,
     _NORETURN,
     _NORETURN,
     _NOTEQUAL,
     _NOTEQUAL,
     _OPERATOR,
     _OPERATOR,
@@ -576,6 +577,7 @@ const
       (str:'MULTIPLY'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'MULTIPLY'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'MWPASCAL'      ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'MWPASCAL'      ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'NEGATIVE'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'NEGATIVE'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
+      (str:'NOINLINE'      ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'NORETURN'      ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'NORETURN'      ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'NOTEQUAL'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'NOTEQUAL'      ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'OPERATOR'      ;special:false;keyword:[m_fpc];op:NOTOKEN),
       (str:'OPERATOR'      ;special:false;keyword:[m_fpc];op:NOTOKEN),

+ 2 - 1
compiler/utils/ppuutils/ppudump.pp

@@ -2012,7 +2012,8 @@ const
      (mask:po_is_function_ref; str: 'Function reference'),
      (mask:po_is_function_ref; str: 'Function reference'),
      (mask:po_is_block;        str: 'C "Block"'),
      (mask:po_is_block;        str: 'C "Block"'),
      (mask:po_is_auto_getter;  str: 'Automatically generated getter'),
      (mask:po_is_auto_getter;  str: 'Automatically generated getter'),
-     (mask:po_is_auto_setter;  str: 'Automatically generated setter')
+     (mask:po_is_auto_setter;  str: 'Automatically generated setter'),
+     (mask:po_noinline;        str: 'Never inline')
   );
   );
 var
 var
   proctypeoption  : tproctypeoption;
   proctypeoption  : tproctypeoption;