Inline C functions that are used only once, msg1525.
This commit is contained in:
parent
5078152292
commit
68c6f0ff07
2
Changes
2
Changes
|
|
@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
** SystemPerl mode is deprecated and now untested.
|
** SystemPerl mode is deprecated and now untested.
|
||||||
|
|
||||||
|
*** Inline C functions that are used only once, msg1525. [Jie Xu]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.866 2014-11-15
|
* Verilator 3.866 2014-11-15
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1399,6 +1399,10 @@ especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
|
||||||
both compilation and link. Note LTO may cause excessive compile times on
|
both compilation and link. Note LTO may cause excessive compile times on
|
||||||
large designs.
|
large designs.
|
||||||
|
|
||||||
|
If you are using your own makefiles, you may want to compile the Verilated
|
||||||
|
code with -DVL_INLINE_OPT=inline. This will inline functions, however this
|
||||||
|
requires that all cpp files be compiled in a single compiler run.
|
||||||
|
|
||||||
You may uncover further tuning possibilities by profiling the Verilog code.
|
You may uncover further tuning possibilities by profiling the Verilog code.
|
||||||
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
|
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
|
||||||
either oprofile or gprof to see where in the C++ code the time is spent.
|
either oprofile or gprof to see where in the C++ code the time is spent.
|
||||||
|
|
|
||||||
|
|
@ -12,5 +12,9 @@ require 5.005;
|
||||||
use warnings;
|
use warnings;
|
||||||
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
|
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
|
||||||
foreach my $param (@ARGV) {
|
foreach my $param (@ARGV) {
|
||||||
|
if ($param =~ /^-D([^=]+)=(.*)/) {
|
||||||
|
print "#define $1 $2\n"
|
||||||
|
} else {
|
||||||
print "#include \"$param\"\n"
|
print "#include \"$param\"\n"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
|
||||||
# Programs
|
# Programs
|
||||||
|
|
||||||
SP_PREPROC = sp_preproc
|
SP_PREPROC = sp_preproc
|
||||||
SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
SP_INCLUDER = $(VERILATOR_INCLUDER)
|
||||||
|
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Make checks
|
# Make checks
|
||||||
|
|
@ -151,15 +153,15 @@ VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||||
|
|
||||||
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
||||||
|
|
||||||
ifneq ($(VM_PARALLEL_BUILDS),1)
|
ifneq ($(VM_PARALLEL_BUILDS),0)
|
||||||
# Fast building, all .cpp's in one fell swoop
|
# Fast building, all .cpp's in one fell swoop
|
||||||
# This saves about 5 sec per module, but can be slower if only a little changes
|
# This saves about 5 sec per module, but can be slower if only a little changes
|
||||||
VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o
|
VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o
|
||||||
all_cpp: $(VM_PREFIX)__ALLcls.cpp $(VM_PREFIX)__ALLsup.cpp
|
all_cpp: $(VM_PREFIX)__ALLcls.cpp $(VM_PREFIX)__ALLsup.cpp
|
||||||
$(VM_PREFIX)__ALLcls.cpp: $(VK_CLASSES_CPP)
|
$(VM_PREFIX)__ALLcls.cpp: $(VK_CLASSES_CPP)
|
||||||
$(SP_INCLUDER) $^ > $@
|
$(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
|
||||||
$(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP)
|
$(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP)
|
||||||
$(SP_INCLUDER) $^ > $@
|
$(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
|
||||||
else
|
else
|
||||||
#Slow way of building... Each .cpp file by itself
|
#Slow way of building... Each .cpp file by itself
|
||||||
VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT))
|
VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT))
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,13 @@
|
||||||
# define VL_UNIQUE_PTR auto_ptr
|
# define VL_UNIQUE_PTR auto_ptr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Optimization
|
||||||
|
|
||||||
|
#ifndef VL_INLINE_OPT
|
||||||
|
# define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run
|
||||||
|
#endif
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Warning disabled
|
// Warning disabled
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4699,6 +4699,7 @@ private:
|
||||||
bool m_formCallTree:1; // Make a global function to call entire tree of functions
|
bool m_formCallTree:1; // Make a global function to call entire tree of functions
|
||||||
bool m_slow:1; // Slow routine, called once or just at init time
|
bool m_slow:1; // Slow routine, called once or just at init time
|
||||||
bool m_funcPublic:1; // From user public task/function
|
bool m_funcPublic:1; // From user public task/function
|
||||||
|
bool m_isInline:1; // Inline function
|
||||||
bool m_isStatic:1; // Function is declared static (no this)
|
bool m_isStatic:1; // Function is declared static (no this)
|
||||||
bool m_symProlog:1; // Setup symbol table for later instructions
|
bool m_symProlog:1; // Setup symbol table for later instructions
|
||||||
bool m_entryPoint:1; // User may call into this top level function
|
bool m_entryPoint:1; // User may call into this top level function
|
||||||
|
|
@ -4719,6 +4720,7 @@ public:
|
||||||
m_formCallTree = false;
|
m_formCallTree = false;
|
||||||
m_slow = false;
|
m_slow = false;
|
||||||
m_funcPublic = false;
|
m_funcPublic = false;
|
||||||
|
m_isInline = false;
|
||||||
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
|
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
|
||||||
m_symProlog = false;
|
m_symProlog = false;
|
||||||
m_entryPoint = false;
|
m_entryPoint = false;
|
||||||
|
|
@ -4748,6 +4750,7 @@ public:
|
||||||
string rtnTypeVoid() const { return ((m_rtnType=="") ? "void" : m_rtnType); }
|
string rtnTypeVoid() const { return ((m_rtnType=="") ? "void" : m_rtnType); }
|
||||||
bool dontCombine() const { return m_dontCombine || funcType()!=AstCFuncType::FT_NORMAL; }
|
bool dontCombine() const { return m_dontCombine || funcType()!=AstCFuncType::FT_NORMAL; }
|
||||||
void dontCombine(bool flag) { m_dontCombine = flag; }
|
void dontCombine(bool flag) { m_dontCombine = flag; }
|
||||||
|
bool dontInline() const { return !dontCombine() && !slow() && !skipDecl() && !funcPublic(); }
|
||||||
bool skipDecl() const { return m_skipDecl; }
|
bool skipDecl() const { return m_skipDecl; }
|
||||||
void skipDecl(bool flag) { m_skipDecl = flag; }
|
void skipDecl(bool flag) { m_skipDecl = flag; }
|
||||||
bool declPrivate() const { return m_declPrivate; }
|
bool declPrivate() const { return m_declPrivate; }
|
||||||
|
|
@ -4762,6 +4765,8 @@ public:
|
||||||
string argTypes() const { return m_argTypes; }
|
string argTypes() const { return m_argTypes; }
|
||||||
void funcType(AstCFuncType flag) { m_funcType = flag; }
|
void funcType(AstCFuncType flag) { m_funcType = flag; }
|
||||||
AstCFuncType funcType() const { return m_funcType; }
|
AstCFuncType funcType() const { return m_funcType; }
|
||||||
|
bool isInline() const { return m_isInline; }
|
||||||
|
void isInline(bool flag) { m_isInline = flag; }
|
||||||
bool isStatic() const { return m_isStatic; }
|
bool isStatic() const { return m_isStatic; }
|
||||||
void isStatic(bool flag) { m_isStatic = flag; }
|
void isStatic(bool flag) { m_isStatic = flag; }
|
||||||
bool symProlog() const { return m_symProlog; }
|
bool symProlog() const { return m_symProlog; }
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
// At each IF/(IF else).
|
// At each IF/(IF else).
|
||||||
// Count underneath $display/$stop statements.
|
// Count underneath $display/$stop statements.
|
||||||
// If more on if than else, this branch is unlikely, or vice-versa.
|
// If more on if than else, this branch is unlikely, or vice-versa.
|
||||||
|
// At each FTASKREF,
|
||||||
|
// Count calls into the function
|
||||||
|
// Then, if FTASK is called only once, add inline attribute
|
||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
@ -40,9 +43,18 @@
|
||||||
|
|
||||||
class BranchVisitor : public AstNVisitor {
|
class BranchVisitor : public AstNVisitor {
|
||||||
private:
|
private:
|
||||||
|
// NODE STATE
|
||||||
|
// Entire netlist:
|
||||||
|
// AstFTask::user1() -> int. Number of references
|
||||||
|
AstUser1InUse m_inuser1;
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
typedef vector<AstCFunc*> CFuncVec;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
int m_likely; // Excuses for branch likely taken
|
int m_likely; // Excuses for branch likely taken
|
||||||
int m_unlikely; // Excuses for branch likely not taken
|
int m_unlikely; // Excuses for branch likely not taken
|
||||||
|
CFuncVec m_cfuncsp; // List of all tasks
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
|
|
@ -55,6 +67,12 @@ private:
|
||||||
m_likely = false;
|
m_likely = false;
|
||||||
m_unlikely = false;
|
m_unlikely = false;
|
||||||
}
|
}
|
||||||
|
void checkUnlikely(AstNode* nodep) {
|
||||||
|
if (nodep->isUnlikely()) {
|
||||||
|
UINFO(4," UNLIKELY: "<<nodep<<endl);
|
||||||
|
m_unlikely++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||||
|
|
@ -83,20 +101,37 @@ private:
|
||||||
m_likely = lastLikely;
|
m_likely = lastLikely;
|
||||||
m_unlikely = lastUnlikely;
|
m_unlikely = lastUnlikely;
|
||||||
}
|
}
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||||
// Default: Just iterate
|
checkUnlikely(nodep);
|
||||||
if (nodep->isUnlikely()) {
|
nodep->funcp()->user1Inc();
|
||||||
UINFO(4," UNLIKELY: "<<nodep<<endl);
|
|
||||||
m_unlikely++;
|
|
||||||
}
|
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||||
|
checkUnlikely(nodep);
|
||||||
|
m_cfuncsp.push_back(nodep);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
|
checkUnlikely(nodep);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHODS
|
||||||
|
void calc_tasks() {
|
||||||
|
for (CFuncVec::iterator it=m_cfuncsp.begin(); it!=m_cfuncsp.end(); ++it) {
|
||||||
|
AstCFunc* nodep = *it;
|
||||||
|
if (!nodep->dontInline()) {
|
||||||
|
nodep->isInline(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
BranchVisitor(AstNetlist* nodep) {
|
BranchVisitor(AstNetlist* nodep) {
|
||||||
reset();
|
reset();
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
|
calc_tasks();
|
||||||
}
|
}
|
||||||
virtual ~BranchVisitor() {}
|
virtual ~BranchVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -829,6 +829,7 @@ class EmitCImp : EmitCStmts {
|
||||||
splitSizeInc(nodep);
|
splitSizeInc(nodep);
|
||||||
|
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
if (nodep->isInline()) puts("VL_INLINE_OPT ");
|
||||||
puts(nodep->rtnTypeVoid()); puts(" ");
|
puts(nodep->rtnTypeVoid()); puts(" ");
|
||||||
puts(modClassName(m_modp)+"::"+nodep->name()
|
puts(modClassName(m_modp)+"::"+nodep->name()
|
||||||
+"("+cFuncArgs(nodep)+") {\n");
|
+"("+cFuncArgs(nodep)+") {\n");
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ endif
|
||||||
|
|
||||||
#Our own compile rules; Faster compile, all in one file
|
#Our own compile rules; Faster compile, all in one file
|
||||||
$(VM_PREFIX)__ALLboth.cpp: $(VK_CLASSES_CPP) $(VK_SUPPORT_CPP)
|
$(VM_PREFIX)__ALLboth.cpp: $(VK_CLASSES_CPP) $(VK_SUPPORT_CPP)
|
||||||
$(SP_INCLUDER) $^ > $@
|
$(VERILATOR_INCLUDER) -DVL_INLINE_OPT=inline $^ > $@
|
||||||
|
|
||||||
$(VM_PREFIX)__ALLboth.o: $(VM_PREFIX)__ALLboth.cpp
|
$(VM_PREFIX)__ALLboth.o: $(VM_PREFIX)__ALLboth.cpp
|
||||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue