diff --git a/Changes b/Changes index 9ec04f4ca..492257d01 100644 --- a/Changes +++ b/Changes @@ -10,6 +10,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix sign-compare warning in verilated.cpp, bug1437. [Sergey Kvachonok] +**** Mark infrequently called functions with GCC cold attribute. + * Verilator 4.014 2019-05-08 diff --git a/bin/verilator b/bin/verilator index 55204d202..47c77e49b 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1034,15 +1034,15 @@ developers. =item --output-split I -Enables splitting the output .cpp files into multiple outputs. When a -C++ file exceeds the specified number of operations, a new file will be -created at the next function boundary. In addition, any slow routines will -be placed into __Slow files. This accelerates compilation by as -optimization can be disabled on the slow routines, and the remaining files -can be compiled on parallel machines. Using --output-split should have -only a trivial impact on performance. With GCC 3.3 on a 2GHz Opteron, ---output-split 20000 will result in splitting into approximately -one-minute-compile chunks. +Enables splitting the output .cpp files into multiple outputs. When a C++ +file exceeds the specified number of operations, a new file will be created +at the next function boundary. In addition, any infrequently executed +"cold" routines will be placed into __Slow files. This accelerates +compilation by as optimization can be disabled on the routines in __Slow, +and the remaining files can be compiled on parallel machines. Using +--output-split should have only a trivial impact on performance. With GCC +3.3 on a 2GHz Opteron, --output-split 20000 will result in splitting into +approximately one-minute-compile chunks. =item --output-split-cfuncs I @@ -1871,7 +1871,7 @@ For -cc and -sc mode, it also creates: {prefix}.cpp // Top level C++ file {prefix}.h // Top level header - {prefix}__Slow{__n}.cpp // Constructors and infrequent routines + {prefix}__Slow{__n}.cpp // Constructors and infrequent cold routines {prefix}{__n}.cpp // Additional top C++ files (--output-split) {prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.h // Lower level internal header files diff --git a/include/verilatedos.h b/include/verilatedos.h index be7bce89e..951bb4660 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -36,6 +36,8 @@ #ifdef __GNUC__ # define VL_ATTR_ALIGNED(alignment) __attribute__ ((aligned (alignment))) # define VL_ATTR_ALWINLINE __attribute__ ((always_inline)) +# define VL_ATTR_COLD __attribute__ ((cold)) +# define VL_ATTR_HOT __attribute__ ((hot)) # define VL_ATTR_NORETURN __attribute__ ((noreturn)) # define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, (fmtArgNum), (fmtArgNum)+1))) # define VL_ATTR_PURE __attribute__ ((pure)) @@ -70,6 +72,12 @@ #ifndef VL_ATTR_ALWINLINE # define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing #endif +#ifndef VL_ATTR_COLD +# define VL_ATTR_COLD ///< Function is rarely executed +#endif +#ifndef VL_ATTR_HOT +# define VL_ATTR_HOT ///< Function is highly executed +#endif #ifndef VL_ATTR_NORETURN # define VL_ATTR_NORETURN ///< Function does not ever return #endif diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index c7ec3c129..e82a9bed7 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -2367,7 +2367,9 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) { if (funcp->ifdef()!="") puts("#ifdef "+funcp->ifdef()+"\n"); if (funcp->isStatic().trueU()) puts("static "); puts(funcp->rtnTypeVoid()); puts(" "); - puts(funcp->name()); puts("("+cFuncArgs(funcp)+");\n"); + puts(funcp->name()); puts("("+cFuncArgs(funcp)+")"); + if (funcp->slow()) puts(" VL_ATTR_COLD"); + puts(";\n"); if (funcp->ifdef()!="") puts("#endif // "+funcp->ifdef()+"\n"); } }