Use VIsCached for checking purity of arguments in AstCMethodHard (#8350)

This commit is contained in:
Pawel Kojma
2026-09-16 11:23:34 -04:00
committed by GitHub
parent 195d0db009
commit 282b898b21
2 changed files with 18 additions and 21 deletions
+6 -4
View File
@@ -750,7 +750,7 @@ class AstCMethodHard final : public AstNodeExpr {
// @astgen op2 := pinsp : List[AstNodeExpr] // Arguments
// @astgen op3 := withp : Optional[AstWith] // With clause
VCMethod m_method; // Which method to call
bool m_pure = false; // Pure optimizable
VIsCached m_purity; // Pure optimizable
bool m_usePtr = false; // Use '->' not '.'
public:
AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, VCMethod method, AstNodeExpr* pinsp = nullptr)
@@ -758,7 +758,6 @@ public:
, m_method{method} {
this->fromp(fromp);
addPinsp(pinsp);
setPurity();
}
ASTGEN_MEMBERS_AstCMethodHard;
void dump(std::ostream& str) const override;
@@ -768,7 +767,10 @@ public:
const AstCMethodHard* const asamep = VN_DBG_AS(samep, CMethodHard);
return (m_method == asamep->m_method);
}
bool isPure() override { return m_pure; }
bool isPure() override {
if (!m_purity.isCached()) m_purity.set(getPurity());
return m_purity.get();
}
int instrCount() const override;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
@@ -779,7 +781,7 @@ public:
void method(VCMethod value) { m_method = value; }
private:
void setPurity();
bool getPurity();
};
class AstCReset final : public AstNodeExpr {
// Reset variable at startup
+12 -17
View File
@@ -588,39 +588,34 @@ void AstCFunc::dumpJson(std::ostream& str) const {
}
void AstCMethodHard::dump(std::ostream& str) const {
Super::dump(str);
if (m_pure) str << " [PURE]";
if (m_purity.get()) str << " [PURE]";
if (usePtr()) str << " [USEPTR]";
}
void AstCMethodHard::dumpJson(std::ostream& str) const {
dumpJsonBoolIf(str, "pure", m_pure);
dumpJsonBoolIf(str, "pure", m_purity.get());
dumpJsonBoolIf(str, "usePtr", usePtr());
dumpJsonGen(str);
}
int AstCMethodHard::instrCount() const {
return 0; // TODO
}
void AstCMethodHard::setPurity() {
bool AstCMethodHard::getPurity() {
if (method() == VCMethod::DYN_AT_WRITE_APPEND
|| method() == VCMethod::DYN_AT_WRITE_APPEND_BACK) {
m_pure = false;
// Treat atWriteAppend as pure if the argument is a loop iterator
if (const AstNodeExpr* const argp = pinsp()) {
if (const AstVarRef* const varrefp = VN_CAST(argp, VarRef)) {
if (varrefp->varp()->isUsedLoopIdx()) m_pure = true;
if (varrefp->varp()->isUsedLoopIdx()) return true;
}
}
return;
return false;
}
m_pure = method().isPure();
if (!m_pure) return;
if (!fromp()->isPure()) m_pure = false;
if (!m_pure) return;
if (!method().isPure()) return false;
if (!fromp()->isPure()) return false;
for (AstNodeExpr* argp = pinsp(); argp; argp = VN_AS(argp->nextp(), NodeExpr)) {
if (!argp->isPure()) {
m_pure = false;
return;
}
if (!argp->isPure()) return false;
}
return true;
}
int AstCMethodHard::instrCount() const {
return 0; // TODO
}
void AstCReset::dump(std::ostream& str) const {
Super::dump(str);