diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index 04679edd8..9d498a02b 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -639,9 +639,6 @@ DfgVertexVar* DfgVertex::getResultVar() { this->forEachSink([&resp](DfgVertex& sink) { DfgVertexVar* const varp = sink.cast(); 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; diff --git a/src/V3Dfg.h b/src/V3Dfg.h index be198cf47..a725e1a60 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -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"); } //------------------------------------------------------------------------------ diff --git a/src/V3DfgAstToDfg.cpp b/src/V3DfgAstToDfg.cpp index 8691b1a53..f5f4f03ed 100644 --- a/src/V3DfgAstToDfg.cpp +++ b/src/V3DfgAstToDfg.cpp @@ -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; diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index 717012a10..0168ba629 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -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()) { - // 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()) { - 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()) { - // 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"); diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index b91e34071..f308a0c7c 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -1202,7 +1202,7 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgArraySel* vtxp) override { if (DfgConst* const idxp = vtxp->bitp()->cast()) { if (DfgVarArray* const varp = vtxp->fromp()->cast()) { - if (varp->srcp() && !varp->varp()->isForced() && !varp->varp()->isSc()) { + if (varp->srcp() && !varp->varp()->isForced()) { if (DfgSpliceArray* const splicep = varp->srcp()->cast()) { if (DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT())) { if (!driverp->is()) { diff --git a/src/V3DfgRegularize.cpp b/src/V3DfgRegularize.cpp index d8de75898..64eef883a 100644 --- a/src/V3DfgRegularize.cpp +++ b/src/V3DfgRegularize.cpp @@ -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([](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()) return true; // Operations without multiple sinks need no variables if (!vtx.hasMultipleSinks()) return false; // Array selects need no variables, they are just memory references