Emit function locals in the place they appear in the tree

Do not sort and hoist function local variables to the top of the
function definition. The stack layout of automatic variables is not
defined by C so the compilers can lay these out optimally. Simplifies
internals for follow on work. Effect on model performance is neutral to
very slight improvement, so we do not seem to be loosing anything.
This commit is contained in:
Geza Lore 2021-07-02 16:55:57 +01:00
parent 766ad14ae0
commit 896b18e024
2 changed files with 24 additions and 16 deletions

View File

@ -544,7 +544,6 @@ void EmitCFunc::emitVarList(AstNode* firstp, EisWhich which, const string& prefi
doit = (varp->isParam() && !VN_IS(varp->valuep(), Const));
break;
case EVL_CLASS_ALL: doit = true; break;
case EVL_FUNC_ALL: doit = true; break;
default: v3fatalSrc("Bad Case");
}
if (varp->isStatic() ? !isstatic : isstatic) doit = false;
@ -574,8 +573,8 @@ void EmitCFunc::emitVarList(AstNode* firstp, EisWhich which, const string& prefi
&& !varp->isSc() // Aggregates can't be anon
&& (varp->basicp()
&& !varp->basicp()->isOpaque()) // Aggregates can't be anon
&& which != EVL_FUNC_ALL); // Anon not legal in funcs, and gcc
// bug free there anyhow
);
if (anonOk) {
varAnonMap[sortbytes].push_back(varp);
} else {

View File

@ -130,6 +130,7 @@ protected:
EmitCLazyDecls m_lazyDecls; // Visitor for emitting lazy declarations
bool m_useSelfForThis = false; // Replace "this" with "vlSelf"
AstNodeModule* m_modp = nullptr; // Current module being emitted
AstCFunc* m_cfuncp = nullptr; // Current function being emitted
public:
// METHODS
@ -159,8 +160,7 @@ public:
EVL_CLASS_SIG,
EVL_CLASS_TEMP,
EVL_CLASS_PAR,
EVL_CLASS_ALL,
EVL_FUNC_ALL
EVL_CLASS_ALL
};
void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp, string& sectionr);
static void emitVarSort(const VarSortMap& vmap, VarVec* sortedp);
@ -203,6 +203,8 @@ public:
// VISITORS
virtual void visit(AstCFunc* nodep) override {
VL_RESTORER(m_useSelfForThis);
VL_RESTORER(m_cfuncp);
m_cfuncp = nodep;
m_blkChangeDetVec.clear();
@ -238,25 +240,28 @@ public:
puts(nodep->isLoose() ? "__" : "::");
puts(nodep->nameProtect() + "\\n\"); );\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
for (AstNode* subnodep = nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* varp = VN_CAST(subnodep, Var)) {
if (varp->isFuncReturn()) emitVarDecl(varp, "");
}
}
string section;
emitVarList(nodep->initsp(), EVL_FUNC_ALL, "", section /*ref*/);
emitVarList(nodep->stmtsp(), EVL_FUNC_ALL, "", section /*ref*/);
iterateAndNextNull(nodep->initsp());
if (nodep->initsp()) {
putsDecoration("// Init\n");
iterateAndNextNull(nodep->initsp());
}
if (nodep->stmtsp()) {
putsDecoration("// Body\n");
iterateAndNextNull(nodep->stmtsp());
}
if (nodep->stmtsp()) putsDecoration("// Body\n");
iterateAndNextNull(nodep->stmtsp());
if (!m_blkChangeDetVec.empty()) emitChangeDet();
if (nodep->finalsp()) putsDecoration("// Final\n");
iterateAndNextNull(nodep->finalsp());
//
if (nodep->finalsp()) {
putsDecoration("// Final\n");
iterateAndNextNull(nodep->finalsp());
}
if (!m_blkChangeDetVec.empty()) puts("return __req;\n");
@ -264,6 +269,11 @@ public:
if (nodep->ifdef() != "") puts("#endif // " + nodep->ifdef() + "\n");
}
virtual void visit(AstVar* nodep) override {
UASSERT_OBJ(m_cfuncp, nodep, "Cannot emit non-local variable");
emitVarDecl(nodep, "");
}
virtual void visit(AstNodeAssign* nodep) override {
bool paren = true;
bool decind = false;
@ -1221,7 +1231,6 @@ public:
virtual void visit(AstTypedef*) override {}
virtual void visit(AstPragma*) override {}
virtual void visit(AstCell*) override {} // Handled outside the Visit class
virtual void visit(AstVar*) override {} // Handled outside the Visit class
virtual void visit(AstNodeText*) override {} // Handled outside the Visit class
virtual void visit(AstCFile*) override {} // Handled outside the Visit class
virtual void visit(AstCellInline*) override {} // Handled outside visit (in EmitCSyms)