Exclude SystemC variables from DFG (#6208)
SystemC variables are fairly special (they can only be assigned to/from, but not otherwise participate in expressions), which complicates some DFG code. These variables only ever appear as port on the top level wrapper, so excluding them from DFG does not make us loose any optimizations, but simplifies internals.
This commit is contained in:
parent
a8dca71ed0
commit
7646e7d89c
|
@ -639,9 +639,6 @@ DfgVertexVar* DfgVertex::getResultVar() {
|
|||
this->forEachSink([&resp](DfgVertex& sink) {
|
||||
DfgVertexVar* const varp = sink.cast<DfgVertexVar>();
|
||||
if (!varp) return;
|
||||
// Ignore SystemC variables, they cannot participate in expressions or
|
||||
// be assigned rvalue expressions.
|
||||
if (varp->varp()->isSc()) return;
|
||||
// First variable found
|
||||
if (!resp) {
|
||||
resp = varp;
|
||||
|
|
|
@ -918,12 +918,14 @@ DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVar* varp)
|
|||
, m_varp{varp}
|
||||
, m_varScopep{nullptr} {
|
||||
UASSERT_OBJ(dfg.modulep(), varp, "Un-scoped DfgVertexVar created in scoped DfgGraph");
|
||||
UASSERT_OBJ(!m_varp->isSc(), varp, "SystemC variable is not representable by DfgVertexVar");
|
||||
}
|
||||
DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp)
|
||||
: DfgVertexUnary{dfg, type, vscp->fileline(), dtypeFor(vscp)}
|
||||
, m_varp{vscp->varp()}
|
||||
, m_varScopep{vscp} {
|
||||
UASSERT_OBJ(!dfg.modulep(), vscp, "Scoped DfgVertexVar created in un-scoped DfgGraph");
|
||||
UASSERT_OBJ(!m_varp->isSc(), vscp, "SystemC variable is not representable by DfgVertexVar");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -125,8 +125,9 @@ class AstToDfgVisitor final : public VNVisitor {
|
|||
|
||||
void markReferenced(AstNode* nodep) {
|
||||
nodep->foreach([this](const AstVarRef* refp) {
|
||||
// No need to (and in fact cannot) mark variables with unsupported dtypes
|
||||
if (!DfgVertex::isSupportedDType(refp->varp()->dtypep())) return;
|
||||
// No need to (and in fact cannot) mark variables if:
|
||||
if (!DfgVertex::isSupportedDType(refp->varp()->dtypep())) return; // unsupported type
|
||||
if (refp->varp()->isSc()) return; // SystemC
|
||||
VariableType* const tgtp = getTarget(refp);
|
||||
// Mark vertex as having a module reference outside current DFG
|
||||
getNet(tgtp)->setHasModRefs();
|
||||
|
@ -809,6 +810,7 @@ class AstToDfgVisitor final : public VNVisitor {
|
|||
|| nodep->varp()->isIfaceRef() // Cannot handle interface references
|
||||
|| nodep->varp()->delayp() // Cannot handle delayed variables
|
||||
|| nodep->classOrPackagep() // Cannot represent cross module references
|
||||
|| nodep->varp()->isSc() // SystemC variables are special and rare, we can ignore
|
||||
) {
|
||||
markReferenced(nodep);
|
||||
m_foundUnhandled = true;
|
||||
|
|
|
@ -169,18 +169,8 @@ void V3DfgPasses::cse(DfgGraph& dfg, V3DfgCseContext& ctx) {
|
|||
void V3DfgPasses::inlineVars(DfgGraph& dfg) {
|
||||
for (DfgVertexVar& vtx : dfg.varVertices()) {
|
||||
if (DfgVarPacked* const varp = vtx.cast<DfgVarPacked>()) {
|
||||
// Don't inline SystemC variables, as SystemC types are not interchangeable with
|
||||
// internal types, and hence the variables are not interchangeable either.
|
||||
if (varp->hasSinks() && varp->isDrivenFullyByDfg() && !varp->varp()->isSc()) {
|
||||
if (varp->hasSinks() && varp->isDrivenFullyByDfg()) {
|
||||
DfgVertex* const driverp = varp->srcp();
|
||||
|
||||
// We must keep the original driver in certain cases, when swapping them would
|
||||
// not be functionally or technically (implementation reasons) equivalent:
|
||||
// 1. If driven from a SystemC variable (assignment is non-trivial)
|
||||
if (DfgVertexVar* const driverVarp = driverp->cast<DfgVarPacked>()) {
|
||||
if (driverVarp->varp()->isSc()) continue;
|
||||
}
|
||||
|
||||
varp->forEachSinkEdge([=](DfgEdge& edge) { edge.relinkSource(driverp); });
|
||||
}
|
||||
}
|
||||
|
@ -559,9 +549,7 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) {
|
|||
varp->replaceWith(varp->srcp());
|
||||
varp->nodep()->unlinkFrBack()->deleteTree();
|
||||
} else if (DfgVarPacked* const driverp = varp->srcp()->cast<DfgVarPacked>()) {
|
||||
// If it's driven from another variable, it can be replaced by that. However, we do not
|
||||
// want to propagate SystemC variables into the design.
|
||||
if (driverp->varp()->isSc()) continue;
|
||||
// If it's driven from another variable, it can be replaced by that.
|
||||
// Mark it for replacement
|
||||
++ctx.m_varsReplaced;
|
||||
UASSERT_OBJ(!varp->hasSinks(), varp, "Variable inlining should make this impossible");
|
||||
|
|
|
@ -1202,7 +1202,7 @@ class V3DfgPeephole final : public DfgVisitor {
|
|||
void visit(DfgArraySel* vtxp) override {
|
||||
if (DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>()) {
|
||||
if (DfgVarArray* const varp = vtxp->fromp()->cast<DfgVarArray>()) {
|
||||
if (varp->srcp() && !varp->varp()->isForced() && !varp->varp()->isSc()) {
|
||||
if (varp->srcp() && !varp->varp()->isForced()) {
|
||||
if (DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>()) {
|
||||
if (DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT())) {
|
||||
if (!driverp->is<DfgVertexSplice>()) {
|
||||
|
|
|
@ -54,14 +54,6 @@ class DfgRegularize final {
|
|||
});
|
||||
return hasNonVarSink;
|
||||
}
|
||||
// Anything that drives an SC variable needs an intermediate,
|
||||
// as we can only assign simple variables to SC variables at runtime.
|
||||
const bool hasScSink = vtx.findSink<DfgVertexVar>([](const DfgVertexVar& var) { //
|
||||
return var.varp()->isSc();
|
||||
});
|
||||
if (hasScSink) return true;
|
||||
// // Splice vertices always need a variable as they represent partial updates
|
||||
// if (vtx.is<DfgVertexSplice>()) return true;
|
||||
// Operations without multiple sinks need no variables
|
||||
if (!vtx.hasMultipleSinks()) return false;
|
||||
// Array selects need no variables, they are just memory references
|
||||
|
|
Loading…
Reference in New Issue