diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index 28a7d50629..80864da1bc 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -979,6 +979,8 @@ implementation writer.AsmWrite(' returns_twice'); if po_inline in pd.procoptions then 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 standard C library function, but which are implemented in Pascal, are not considered to have the same semantics as the C function with diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 1348f5c3c5..9b623b22ea 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -2369,7 +2369,7 @@ type end; const {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= ( ( @@ -2516,7 +2516,16 @@ const pooption : [po_inline]; mutexclpocall : [pocall_safecall]; 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; pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper]; diff --git a/compiler/psub.pas b/compiler/psub.pas index 88880662a9..f92dad5631 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -1379,6 +1379,7 @@ implementation if (cs_opt_autoinline in current_settings.optimizerswitches) and { inlining not turned off? } (cs_do_inline in current_settings.localswitches) and + not(po_noinline in procdef.procoptions) and { no inlining yet? } not(procdef.has_inlininginfo) and not(has_nestedprocs) and not(procdef.proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,potype_constructor, diff --git a/compiler/symconst.pas b/compiler/symconst.pas index 039b376679..1edf225e40 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -413,7 +413,9 @@ type { procedure is an automatically generated property getter } po_is_auto_getter, { 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; @@ -1024,7 +1026,8 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has 'po_is_function_ref',{po_is_function_ref} 'C-style blocks',{po_is_block} '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 diff --git a/compiler/symsym.pas b/compiler/symsym.pas index 5e9aff405d..1025931323 100644 --- a/compiler/symsym.pas +++ b/compiler/symsym.pas @@ -1862,7 +1862,8 @@ implementation { 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 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 (vo_is_public in varoptions); end; diff --git a/compiler/tokens.pas b/compiler/tokens.pas index 0565e1dcb8..e208e6bbd8 100644 --- a/compiler/tokens.pas +++ b/compiler/tokens.pas @@ -236,6 +236,7 @@ type _MULTIPLY, _MWPASCAL, _NEGATIVE, + _NOINLINE, _NORETURN, _NOTEQUAL, _OPERATOR, @@ -576,6 +577,7 @@ const (str:'MULTIPLY' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name } (str:'MWPASCAL' ;special:false;keyword:[m_none];op:NOTOKEN), (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:'NOTEQUAL' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name } (str:'OPERATOR' ;special:false;keyword:[m_fpc];op:NOTOKEN), diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index ccf019fad1..9ba8628506 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/compiler/utils/ppuutils/ppudump.pp @@ -2012,7 +2012,8 @@ const (mask:po_is_function_ref; str: 'Function reference'), (mask:po_is_block; str: 'C "Block"'), (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 proctypeoption : tproctypeoption;