From 277b7b35d0ecf072ecc407ef3ab8121f0f6e6afc Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 4 Jun 2020 12:20:14 +0200 Subject: [PATCH] cgen: write_fn_attr() --- vlib/v/gen/fn.v | 158 +++++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 5e894c475b..be4116bed3 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -34,86 +34,12 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { g.cur_generic_type = 0 return } - // if is_main && g.pref.is_liveshared { return } - // fn_start_pos := g.out.len - - mut msvc_attrs := '' - match g.attr { - 'inline' { - g.write('inline ') - } - // since these are supported by GCC, clang and MSVC, we can consider them officially supported. - 'no_inline' { - g.write('__NOINLINE ') - } - 'irq_handler' { - g.write('__IRQHANDLER ') - } - - // GCC/clang attributes - // prefixed by _ to indicate they're for advanced users only and not really supported by V. - // source for descriptions: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes - - // The cold attribute on functions is used to inform the compiler that the function is unlikely - // to be executed. The function is optimized for size rather than speed and on many targets it - // is placed into a special subsection of the text section so all cold functions appear close - // together, improving code locality of non-cold parts of program. - '_cold' { - g.write('__attribute__((cold)) ') - } - // The constructor attribute causes the function to be called automatically before execution - // enters main (). - '_constructor' { - g.write('__attribute__((constructor)) ') - } - // The destructor attribute causes the function to be called automatically after main () - // completes or exit () is called. - '_destructor' { - g.write('__attribute__((destructor)) ') - } - // Generally, inlining into a function is limited. For a function marked with this attribute, - // every call inside this function is inlined, if possible. - '_flatten' { - g.write('__attribute__((flatten)) ') - } - // The hot attribute on a function is used to inform the compiler that the function is a hot - // spot of the compiled program. - '_hot' { - g.write('__attribute__((hot)) ') - } - // This tells the compiler that a function is malloc-like, i.e., that the pointer P returned by - // the function cannot alias any other pointer valid when the function returns, and moreover no - // pointers to valid objects occur in any storage addressed by P. - '_malloc' { - g.write('__attribute__((malloc)) ') - } - - // Calls to functions whose return value is not affected by changes to the observable state - // of the program and that have no observable effects on such state other than to return a - // value may lend themselves to optimizations such as common subexpression elimination. - // Declaring such functions with the const attribute allows GCC to avoid emitting some calls in - // repeated invocations of the function with the same argument values. - '_pure' { - g.write('__attribute__((const)) ') - } - - // windows attributes (msvc/mingw) - // prefixed by windows to indicate they're for advanced users only and not really supported by V. - - 'windows_stdcall' { - msvc_attrs += '__stdcall ' - } - - else { - // nothing but keep V happy - } - } - - // + msvc_attrs := g.write_fn_attr() + // Live is_livefn := g.attr == 'live' is_livemain := g.pref.is_livemain && is_livefn is_liveshared := g.pref.is_liveshared && is_livefn @@ -309,6 +235,7 @@ fn (mut g Gen) write_defer_stmts_when_needed() { } } +// fn decl args fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string) { mut fargs := []string{} mut fargtypes := []string{} @@ -319,7 +246,7 @@ fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string) arg_type_sym := g.table.get_type_symbol(typ) mut arg_type_name := g.typ(typ) // arg_type_sym.name.replace('.', '__') // if arg.name == 'xxx' { - // println('! ' + arg_type_name) + // println('xxx arg type= ' + arg_type_name) // } is_varg := i == args.len - 1 && is_variadic if is_varg { @@ -774,3 +701,80 @@ fn (mut g Gen) is_gui_app() bool { fn (g &Gen) fileis(s string) bool { return g.file.path.contains(s) } + +fn (mut g Gen) write_fn_attr() string{ + mut msvc_attrs := '' + match g.attr { + 'inline' { + g.write('inline ') + } + // since these are supported by GCC, clang and MSVC, we can consider them officially supported. + 'no_inline' { + g.write('__NOINLINE ') + } + 'irq_handler' { + g.write('__IRQHANDLER ') + } + + // GCC/clang attributes + // prefixed by _ to indicate they're for advanced users only and not really supported by V. + // source for descriptions: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes + + // The cold attribute on functions is used to inform the compiler that the function is unlikely + // to be executed. The function is optimized for size rather than speed and on many targets it + // is placed into a special subsection of the text section so all cold functions appear close + // together, improving code locality of non-cold parts of program. + '_cold' { + g.write('__attribute__((cold)) ') + } + // The constructor attribute causes the function to be called automatically before execution + // enters main (). + '_constructor' { + g.write('__attribute__((constructor)) ') + } + // The destructor attribute causes the function to be called automatically after main () + // completes or exit () is called. + '_destructor' { + g.write('__attribute__((destructor)) ') + } + // Generally, inlining into a function is limited. For a function marked with this attribute, + // every call inside this function is inlined, if possible. + '_flatten' { + g.write('__attribute__((flatten)) ') + } + // The hot attribute on a function is used to inform the compiler that the function is a hot + // spot of the compiled program. + '_hot' { + g.write('__attribute__((hot)) ') + } + // This tells the compiler that a function is malloc-like, i.e., that the pointer P returned by + // the function cannot alias any other pointer valid when the function returns, and moreover no + // pointers to valid objects occur in any storage addressed by P. + '_malloc' { + g.write('__attribute__((malloc)) ') + } + + // Calls to functions whose return value is not affected by changes to the observable state + // of the program and that have no observable effects on such state other than to return a + // value may lend themselves to optimizations such as common subexpression elimination. + // Declaring such functions with the const attribute allows GCC to avoid emitting some calls in + // repeated invocations of the function with the same argument values. + '_pure' { + g.write('__attribute__((const)) ') + } + + // windows attributes (msvc/mingw) + // prefixed by windows to indicate they're for advanced users only and not really supported by V. + + 'windows_stdcall' { + msvc_attrs += '__stdcall ' + } + + else { + // nothing but keep V happy + } + } + return msvc_attrs + + } +