Compute purity of AstCMethodHard (#4460)

This commit is contained in:
Ryszard Rozak 2023-09-11 13:06:15 +02:00 committed by GitHub
parent d72f1b89fc
commit b66c4153b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 6 deletions

View File

@ -600,6 +600,7 @@ public:
, m_name{name} { , m_name{name} {
this->fromp(fromp); this->fromp(fromp);
this->addPinsp(pinsp); this->addPinsp(pinsp);
setPurity();
} }
ASTGEN_MEMBERS_AstCMethodHard; ASTGEN_MEMBERS_AstCMethodHard;
string name() const override VL_MT_STABLE { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
@ -609,11 +610,13 @@ public:
return (m_name == asamep->m_name); return (m_name == asamep->m_name);
} }
bool isPure() const override { return m_pure; } bool isPure() const override { return m_pure; }
void pure(bool flag) { m_pure = flag; }
int instrCount() const override; int instrCount() const override;
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; } bool cleanOut() const override { return true; }
private:
void setPurity();
}; };
class AstCast final : public AstNodeExpr { class AstCast final : public AstNodeExpr {
// Cast to appropriate data type // Cast to appropriate data type

View File

@ -2326,6 +2326,74 @@ int AstCMethodHard::instrCount() const {
} }
return 0; return 0;
} }
void AstCMethodHard::setPurity() {
static const std::map<std::string, bool> isPureMethod{{"andNot", false},
{"any", true},
{"assign", false},
{"at", true},
{"atBack", true},
{"awaitingCurrentTime", true},
{"clear", false},
{"clearFired", false},
{"commit", false},
{"delay", false},
{"done", false},
{"erase", false},
{"evaluate", false},
{"evaluation", false},
{"exists", true},
{"find", true},
{"find_first", true},
{"find_first_index", true},
{"find_index", true},
{"find_last", true},
{"find_last_index", true},
{"fire", false},
{"first", false},
{"init", false},
{"insert", false},
{"isFired", true},
{"isTriggered", true},
{"join", false},
{"last", false},
{"max", true},
{"min", true},
{"neq", true},
{"next", false},
{"pop", false},
{"pop_back", false},
{"pop_front", false},
{"prev", false},
{"push", false},
{"push_back", false},
{"push_front", false},
{"r_and", true},
{"r_or", true},
{"r_product", true},
{"r_sum", true},
{"r_xor", true},
{"renew", false},
{"renew_copy", false},
{"resume", false},
{"reverse", false},
{"rsort", false},
{"set", false},
{"shuffle", false},
{"size", true},
{"slice", true},
{"sliceBackBack", true},
{"sliceFrontBack", true},
{"sort", false},
{"thisOr", false},
{"trigger", false},
{"unique", true},
{"unique_index", true},
{"word", true}};
auto isPureIt = isPureMethod.find(name());
UASSERT_OBJ(isPureIt != isPureMethod.end(), this, "Unknown purity of method " + name());
m_pure = isPureIt->second;
}
const char* AstCFunc::broken() const { const char* AstCFunc::broken() const {
BROKEN_RTN((m_scopep && !m_scopep->brokeExists())); BROKEN_RTN((m_scopep && !m_scopep->brokeExists()));
return nullptr; return nullptr;

View File

@ -393,7 +393,6 @@ AstSenTree* createTriggerSenTree(AstNetlist* netlistp, AstVarScope* const vscp,
AstCMethodHard* const callp AstCMethodHard* const callp
= new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}}; = new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}};
callp->dtypeSetUInt64(); callp->dtypeSetUInt64();
callp->pure(true);
AstNodeExpr* const termp AstNodeExpr* const termp
= new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp}; = new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp};
AstSenItem* const senItemp = new AstSenItem{flp, VEdgeType::ET_TRUE, termp}; AstSenItem* const senItemp = new AstSenItem{flp, VEdgeType::ET_TRUE, termp};
@ -479,7 +478,6 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
AstCMethodHard* const callp AstCMethodHard* const callp
= new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}}; = new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}};
callp->dtypeSetUInt64(); callp->dtypeSetUInt64();
callp->pure(true);
AstNodeExpr* const termp AstNodeExpr* const termp
= new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp}; = new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp};
return termp; return termp;

View File

@ -3107,7 +3107,6 @@ private:
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists",
index_exprp->unlinkFrBack()}; index_exprp->unlinkFrBack()};
newp->dtypeSetSigned32(); newp->dtypeSetSigned32();
newp->pure(true);
} else if (nodep->name() == "delete") { // function void delete([input integer index]) } else if (nodep->name() == "delete") { // function void delete([input integer index])
methodOkArguments(nodep, 0, 1); methodOkArguments(nodep, 0, 1);
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
@ -3192,7 +3191,6 @@ private:
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists",
index_exprp->unlinkFrBack()}; index_exprp->unlinkFrBack()};
newp->dtypeSetSigned32(); newp->dtypeSetSigned32();
newp->pure(true);
} else if (nodep->name() == "delete") { // function void delete([input integer index]) } else if (nodep->name() == "delete") { // function void delete([input integer index])
methodOkArguments(nodep, 0, 1); methodOkArguments(nodep, 0, 1);
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
@ -3657,7 +3655,6 @@ private:
AstCMethodHard* const callp = new AstCMethodHard{ AstCMethodHard* const callp = new AstCMethodHard{
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "isTriggered"}; nodep->fileline(), nodep->fromp()->unlinkFrBack(), "isTriggered"};
callp->dtypeSetBit(); callp->dtypeSetBit();
callp->pure(true);
nodep->replaceWith(callp); nodep->replaceWith(callp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else { } else {