Internals: Change user1-4 storage to uint64 (#8317)

This commit is contained in:
Wilson Snyder
2026-09-10 06:45:54 -04:00
committed by GitHub
parent 3c8630744d
commit 24692ad3ef
14 changed files with 93 additions and 95 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ VCMethod VCMethod::arrayMethod(const string& name) {
std::string VNUser::dumpStr(std::string (*fmtAddrp)(const void*)) const {
#ifdef VL_USER_TYPE_CHECKS
if (const int* const uip = std::get_if<int>(&m_u)) return "#"s + cvtToStr(*uip);
if (const uint64_t* const uip = std::get_if<uint64_t>(&m_u)) return "#"s + cvtToStr(*uip);
if (void* const* const upp = std::get_if<void*>(&m_u)) return fmtAddrp(*upp);
return "";
#else
+38 -38
View File
@@ -151,11 +151,11 @@ class VNUser final {
#ifdef VL_USER_TYPE_CHECKS
// monostate is an unwritten / cleared slot. It can be read as either form
// and yields nullptr/0.
std::variant<std::monostate, int, void*> m_u;
std::variant<std::monostate, uint64_t, void*> m_u;
#else
union {
void* up;
int ui;
uint64_t uq;
} m_u;
#endif
@@ -164,7 +164,7 @@ public:
VNUser() = default;
// non-explicit:
// cppcheck-suppress noExplicitConstructor
VNUser(int i) {
VNUser(uint64_t i) {
// VNUser{0} represents the monostate
if (i) m_u = i;
}
@@ -178,22 +178,22 @@ public:
typename std::enable_if<std::is_pointer<T>::value, T>::type to() const VL_MT_SAFE {
if (std::holds_alternative<std::monostate>(m_u)) return nullptr;
void* const* const upp = std::get_if<void*>(&m_u);
UASSERT_STATIC(upp, "AstNode user() slot written as int, read as pointer");
UASSERT_STATIC(upp, "AstNode user() slot written as uint64_t, read as pointer");
return reinterpret_cast<T>(*upp);
}
int toInt() const {
uint64_t toUQuad() const {
if (std::holds_alternative<std::monostate>(m_u)) return 0;
const int* const uip = std::get_if<int>(&m_u);
UASSERT_STATIC(uip, "AstNode user() slot written as pointer, read as int");
const uint64_t* const uip = std::get_if<uint64_t>(&m_u);
UASSERT_STATIC(uip, "AstNode user() slot written as pointer, read as uint64_t");
return *uip;
}
#else
VNUser() = default;
// non-explicit:
// cppcheck-suppress noExplicitConstructor
VNUser(int i) {
VNUser(uint64_t i) {
m_u.up = nullptr;
m_u.ui = i;
m_u.uq = i;
}
explicit VNUser(void* p) { m_u.up = p; }
~VNUser() = default;
@@ -202,7 +202,7 @@ public:
typename std::enable_if<std::is_pointer<T>::value, T>::type to() const VL_MT_SAFE {
return reinterpret_cast<T>(m_u.up);
}
int toInt() const { return m_u.ui; }
uint64_t toUQuad() const { return m_u.uq; }
#endif
VSymEnt* toSymEnt() const { return to<VSymEnt*>(); }
AstNode* toNodep() const VL_MT_SAFE { return to<AstNode*>(); }
@@ -492,14 +492,14 @@ class AstNode VL_NOT_FINAL {
// This member ordering both allows 64 bit alignment and puts associated data together
// (under VL_USER_TYPE_CHECKS a VNUser is larger than 64 bits, so this packing no
// longer holds; that build trades node size for catching int/pointer confusion)
VNUser m_user1u{0}; // Contains any information the user iteration routine wants
VNUser m_user1u{nullptr}; // Contains any information the user iteration routine wants
uint32_t m_user1Cnt = 0; // Mark of when userp was set
uint32_t m_user2Cnt = 0; // Mark of when userp was set
VNUser m_user2u{0}; // Contains any information the user iteration routine wants
VNUser m_user3u{0}; // Contains any information the user iteration routine wants
VNUser m_user2u{nullptr}; // Contains any information the user iteration routine wants
VNUser m_user3u{nullptr}; // Contains any information the user iteration routine wants
uint32_t m_user3Cnt = 0; // Mark of when userp was set
uint32_t m_user4Cnt = 0; // Mark of when userp was set
VNUser m_user4u{0}; // Contains any information the user iteration routine wants
VNUser m_user4u{nullptr}; // Contains any information the user iteration routine wants
// METHODS
void op1p(AstNode* nodep) {
@@ -708,61 +708,61 @@ public:
VNUser user1u() const VL_MT_STABLE {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(VNUser1InUse::s_userBusy, "user1p used without AstUserInUse");
return ((m_user1Cnt == VNUser1InUse::s_userCntGbl) ? m_user1u : VNUser{0});
return ((m_user1Cnt == VNUser1InUse::s_userCntGbl) ? m_user1u : VNUser{nullptr});
}
AstNode* user1p() const VL_MT_STABLE { return user1u().toNodep(); }
void user1u(const VNUser& user) { m_user1u = user; m_user1Cnt = VNUser1InUse::s_userCntGbl; }
void user1p(void* userp) { user1u(VNUser{userp}); }
void user1(int val) { user1u(VNUser{val}); }
int user1() const { return user1u().toInt(); }
int user1Inc(int val = 1) { const int v = user1(); user1(v + val); return v; }
int user1Or(int val) { const int v = user1(); user1(v | val); return v; }
int user1SetOnce() { const int v = user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
void user1(uint64_t val) { user1u(VNUser{val}); }
uint64_t user1() const { return user1u().toUQuad(); }
uint64_t user1Inc(uint64_t val = 1) { const uint64_t v = user1(); user1(v + val); return v; }
uint64_t user1Or(uint64_t val) { const uint64_t v = user1(); user1(v | val); return v; }
uint64_t user1SetOnce() { const uint64_t v = user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
static void user1ClearTree() { VNUser1InUse::clear(); } // Clear userp()'s across the entire tree
VNUser user2u() const VL_MT_STABLE {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(VNUser2InUse::s_userBusy, "user2p used without AstUserInUse");
return ((m_user2Cnt == VNUser2InUse::s_userCntGbl) ? m_user2u : VNUser{0});
return ((m_user2Cnt == VNUser2InUse::s_userCntGbl) ? m_user2u : VNUser{nullptr});
}
AstNode* user2p() const VL_MT_STABLE { return user2u().toNodep(); }
void user2u(const VNUser& user) { m_user2u = user; m_user2Cnt = VNUser2InUse::s_userCntGbl; }
void user2p(void* userp) { user2u(VNUser{userp}); }
void user2(int val) { user2u(VNUser{val}); }
int user2() const { return user2u().toInt(); }
int user2Inc(int val = 1) { const int v = user2(); user2(v + val); return v; }
int user2Or(int val) { const int v = user2(); user2(v | val); return v; }
int user2SetOnce() { const int v = user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
void user2(uint64_t val) { user2u(VNUser{val}); }
uint64_t user2() const { return user2u().toUQuad(); }
uint64_t user2Inc(uint64_t val = 1) { const uint64_t v = user2(); user2(v + val); return v; }
uint64_t user2Or(uint64_t val) { const uint64_t v = user2(); user2(v | val); return v; }
uint64_t user2SetOnce() { const uint64_t v = user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
static void user2ClearTree() { VNUser2InUse::clear(); } // Clear userp()'s across the entire tree
VNUser user3u() const VL_MT_STABLE {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(VNUser3InUse::s_userBusy, "user3p used without AstUserInUse");
return ((m_user3Cnt == VNUser3InUse::s_userCntGbl) ? m_user3u : VNUser{0});
return ((m_user3Cnt == VNUser3InUse::s_userCntGbl) ? m_user3u : VNUser{nullptr});
}
AstNode* user3p() const VL_MT_STABLE { return user3u().toNodep(); }
void user3u(const VNUser& user) { m_user3u = user; m_user3Cnt = VNUser3InUse::s_userCntGbl; }
void user3p(void* userp) { user3u(VNUser{userp}); }
void user3(int val) { user3u(VNUser{val}); }
int user3() const { return user3u().toInt(); }
int user3Inc(int val = 1) { const int v = user3(); user3(v + val); return v; }
int user3Or(int val) { const int v = user3(); user3(v | val); return v; }
int user3SetOnce() { const int v = user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
void user3(uint64_t val) { user3u(VNUser{val}); }
uint64_t user3() const { return user3u().toUQuad(); }
uint64_t user3Inc(uint64_t val = 1) { const uint64_t v = user3(); user3(v + val); return v; }
uint64_t user3Or(uint64_t val) { const uint64_t v = user3(); user3(v | val); return v; }
uint64_t user3SetOnce() { const uint64_t v = user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
static void user3ClearTree() { VNUser3InUse::clear(); } // Clear userp()'s across the entire tree
VNUser user4u() const VL_MT_STABLE {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(VNUser4InUse::s_userBusy, "user4p used without AstUserInUse");
return ((m_user4Cnt == VNUser4InUse::s_userCntGbl) ? m_user4u : VNUser{0});
return ((m_user4Cnt == VNUser4InUse::s_userCntGbl) ? m_user4u : VNUser{nullptr});
}
AstNode* user4p() const VL_MT_STABLE { return user4u().toNodep(); }
void user4u(const VNUser& user) { m_user4u = user; m_user4Cnt = VNUser4InUse::s_userCntGbl; }
void user4p(void* userp) { user4u(VNUser{userp}); }
void user4(int val) { user4u(VNUser{val}); }
int user4() const { return user4u().toInt(); }
int user4Or(int val) { const int v = user4(); user4(v | val); return v; }
int user4Inc(int val = 1) { const int v = user4(); user4(v + val); return v; }
int user4SetOnce() { const int v = user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
void user4(uint64_t val) { user4u(VNUser{val}); }
uint64_t user4() const { return user4u().toUQuad(); }
uint64_t user4Or(uint64_t val) { const uint64_t v = user4(); user4(v | val); return v; }
uint64_t user4Inc(uint64_t val = 1) { const uint64_t v = user4(); user4(v + val); return v; }
uint64_t user4SetOnce() { const uint64_t v = user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
static void user4ClearTree() { VNUser4InUse::clear(); } // Clear userp()'s across the entire tree
// clang-format on
+5 -5
View File
@@ -50,11 +50,11 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class DeadVisitor final : public VNVisitor {
// NODE STATE
// Entire Netlist:
// AstNodeModule::user1() -> int. Count of number of cells referencing this module.
// AstVar::user1() -> int. Count of number of references
// AstVarScope::user1() -> int. Count of number of references
// AstNodeDType::user1() -> int. Count of number of references
// AstNodeFTask::user1() -> int. Count of number of references (via AstNodeFTaskRefs)
// AstNodeModule::user1() -> uint64_t. Count of number of cells referencing this module.
// AstVar::user1() -> uint64_t. Count of number of references
// AstVarScope::user1() -> uint64_t. Count of number of references
// AstNodeDType::user1() -> uint64_t. Count of number of references
// AstNodeFTask::user1() -> uint64_t. Count of number of references (via AstNodeFTaskRefs)
const VNUser1InUse m_inuser1;
// TYPES
+1 -1
View File
@@ -72,8 +72,8 @@ protected:
public:
~DfgVertexVar() {
// Decrement reference count
UASSERT_OBJ(m_vscp->user1() >= 0x40, m_vscp, "Reference count underflow");
m_vscp->user1(m_vscp->user1() - 0x40);
UASSERT_OBJ((m_vscp->user1() >> 6) >= 0, m_vscp, "Reference count underflow");
}
ASTGEN_MEMBERS_DfgVertexVar;
+2 -2
View File
@@ -267,7 +267,7 @@ private:
class DynScopeVisitor final : public VNVisitor {
// NODE STATE
// AstVar::user1() -> int. timing-control fork nesting level of that variable
// AstVar::user1() -> uint64_t. timing-control fork nesting level of that variable
// AstVarRef::user2() -> bool. Node is a class handle reference. The handle gets
// modified in the context of this reference.
// AstAssignDly::user2() -> bool. Already visited
@@ -281,7 +281,7 @@ class DynScopeVisitor final : public VNVisitor {
std::deque<AstNode*> m_frameOrder; // Ordered list of frames (for determinism)
std::map<AstNode*, ForkDynScopeFrame*> m_frames; // Map nodes to related DynScopeFrames
VMemberMap m_memberMap; // Class member look-up
int m_forkDepth = 0; // Number of asynchronous forks we are currently under
uint64_t m_forkDepth = 0; // Number of asynchronous forks we are currently under
bool m_afterTimingControl = false; // A timing control might've be executed in the current
// process
size_t m_id = 0; // Unique ID for a frame
+3 -3
View File
@@ -55,7 +55,7 @@ class HasherVisitor final : public VNVisitorConst {
std::function<void()>&& f) {
// See comments in visit(AstCFunc) about this breaking recursion
if (m_cacheInUser4 && nodep->user4()) {
return V3Hash{nodep->user4()};
return V3Hash{static_cast<uint32_t>(nodep->user4())};
} else {
VL_RESTORER(m_hash);
// Reset accumulator
@@ -585,13 +585,13 @@ public:
V3Hash V3Hasher::operator()(AstNode* nodep) const {
if (!nodep->user4()) HasherVisitor{nodep};
return V3Hash{nodep->user4()};
return V3Hash{static_cast<uint32_t>(nodep->user4())};
}
V3Hash V3Hasher::rehash(AstNode* nodep) const {
nodep->user4(0);
{ HasherVisitor{nodep}; }
return V3Hash{nodep->user4()};
return V3Hash{static_cast<uint32_t>(nodep->user4())};
}
V3Hash V3Hasher::uncachedHash(const AstNode* nodep) {
+1 -1
View File
@@ -32,7 +32,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class InstrCountVisitor final : public VNVisitorConst {
// NODE STATE
// AstNode::user1() -> bool. Processed if assertNoDups
// AstNode::user2() -> int. Path cost + 1, 0 means don't dump
// AstNode::user2() -> uint64_t. Path cost + 1, 0 means don't dump
const VNUser2InUse m_inuser2;
// MEMBERS
+1 -1
View File
@@ -124,7 +124,7 @@ public:
class LifeBlock final {
// NODE STATE
// Cleared each AstIf:
// AstVarScope::user1() -> int. Used in combining to detect duplicates
// AstVarScope::user1() -> uint64_t. Used in combining to detect duplicates
// LIFE MAP
// For each basic block, we'll make a new map of what variables that if/else is changing
+24 -24
View File
@@ -138,7 +138,7 @@ union RandomizeMode final {
bool usesMode : 1; // Variable/constraint uses rand_mode/constraint_mode
uint32_t index : 31; // Index of var/constraint in rand_mode/constraint_mode vector
};
int asInt; // Representation as int to be stored in nodep->user*
uint64_t asUQuad; // Representation as int to be stored in nodep->user*
};
// Look through unpacked array dimensions to the element type
@@ -246,7 +246,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
if (nodep->user1() == IS_RANDOMIZED_INLINE) {
RandomizeMode randMode = {};
randMode.usesMode = true;
varp->user1(randMode.asInt);
varp->user1(randMode.asUQuad);
}
}
}
@@ -411,7 +411,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
"No class found for inline randomized variable");
RandomizeMode randMode = {};
randMode.usesMode = true;
randVarp->user1(randMode.asInt);
randVarp->user1(randMode.asUQuad);
backp->user1(IS_RANDOMIZED_INLINE);
}
}
@@ -488,14 +488,14 @@ class RandomizeMarkVisitor final : public VNVisitor {
// Called on a rand member variable
RandomizeMode randMode = {};
randMode.usesMode = true;
randModeTarget.receiverp->user1(randMode.asInt);
randModeTarget.receiverp->user1(randMode.asUQuad);
} else {
// Called on 'this' or a non-rand class instance
randModeTarget.classp->foreachMember([&](AstClass*, AstVar* varp) {
if (!varp->isRand()) return;
RandomizeMode randMode = {};
randMode.usesMode = true;
varp->user1(randMode.asInt);
varp->user1(randMode.asUQuad);
});
}
}
@@ -546,10 +546,10 @@ class RandomizeMarkVisitor final : public VNVisitor {
RandomizeMode constraintMode = {};
constraintMode.usesMode = true;
if (constrp) {
constrp->user1(constraintMode.asInt);
constrp->user1(constraintMode.asUQuad);
} else {
classp->foreachMember([=](AstClass*, AstConstraint* constrp) {
constrp->user1(constraintMode.asInt);
constrp->user1(constraintMode.asUQuad);
});
}
} else {
@@ -1638,7 +1638,7 @@ class ConstraintExprVisitor final : public VNVisitor {
if (memberselp) varp = memberselp->varp();
AstNodeModule* const classOrPackagep = nodep->classOrPackagep();
const RandomizeMode randMode = {.asInt = varp->user1()};
const RandomizeMode randMode = {.asUQuad = varp->user1()};
if (!randMode.usesMode && editFormat(nodep)) return;
VNRelinker relinker;
@@ -2566,7 +2566,7 @@ class ConstraintExprVisitor final : public VNVisitor {
writeVarCallp->addPinsp(new AstConst{fl, AstConst::Unsized64{}, elemWidth});
writeVarCallp->addPinsp(varnamep);
writeVarCallp->addPinsp(new AstConst{fl, 1}); // Dimension
const RandomizeMode randMode = {.asInt = varp->user1()};
const RandomizeMode randMode = {.asUQuad = varp->user1()};
if (randMode.usesMode) {
writeVarCallp->addPinsp(
new AstConst{fl, AstConst::Unsized64{}, randMode.index});
@@ -2951,7 +2951,7 @@ class ConstraintExprVisitor final : public VNVisitor {
UASSERT_OBJ(unpackedDims == 1, arrVarp, "Array isn't 1-D");
writeVarCallp->addPinsp(new AstConst{fl, 1}); // Dimension
const RandomizeMode randMode = {.asInt = arrVarp->user1()};
const RandomizeMode randMode = {.asUQuad = arrVarp->user1()};
if (randMode.usesMode) {
writeVarCallp->addPinsp(
new AstConst{fl, AstConst::Unsized64{}, randMode.index});
@@ -3790,7 +3790,7 @@ class RandomizeVisitor final : public VNVisitor {
// index overlap. If the index > 0, it's already been set.
if (AstConstraint* const constrp = VN_CAST(memberp, Constraint)) {
hasConstraints = true;
RandomizeMode constraintMode = {.asInt = memberp->user1()};
RandomizeMode constraintMode = {.asUQuad = memberp->user1()};
if (!constraintMode.usesMode) return;
if (constraintMode.index == 0) {
// Use separate index counters for static vs non-static constraints
@@ -3799,7 +3799,7 @@ class RandomizeVisitor final : public VNVisitor {
} else {
constraintMode.index = constraintModeCount++;
}
memberp->user1(constraintMode.asInt);
memberp->user1(constraintMode.asUQuad);
} else {
if (constrp->isStatic()) {
staticConstraintModeCount = constraintMode.index + 1;
@@ -3808,7 +3808,7 @@ class RandomizeVisitor final : public VNVisitor {
}
}
} else if (AstVar* const varp = VN_CAST(memberp, Var)) {
RandomizeMode randMode = {.asInt = memberp->user1()};
RandomizeMode randMode = {.asUQuad = memberp->user1()};
if (!randMode.usesMode) return;
const bool isStaticVar = varp->lifetime().isStatic();
if (randMode.index == 0) {
@@ -3817,7 +3817,7 @@ class RandomizeVisitor final : public VNVisitor {
} else {
randMode.index = randModeCount++;
}
memberp->user1(randMode.asInt);
memberp->user1(randMode.asUQuad);
} else {
if (isStaticVar) {
staticRandModeCount = randMode.index + 1;
@@ -3835,7 +3835,7 @@ class RandomizeVisitor final : public VNVisitor {
std::function<void(AstClass*)> findSubObjRandModes = [&](AstClass* subClassp) {
subClassp->foreachMember([&](AstClass*, AstNode* subMemberp) {
if (AstVar* const subVarp = VN_CAST(subMemberp, Var)) {
const RandomizeMode rm = {.asInt = subVarp->user1()};
const RandomizeMode rm = {.asUQuad = subVarp->user1()};
if (!rm.usesMode) return;
// Static rand vars index into their own class's static
// rand mode array, not into the outer __Vrandmode.
@@ -3968,13 +3968,13 @@ class RandomizeVisitor final : public VNVisitor {
return new AstBegin{fl, "", stmtsp, true};
}
AstNodeStmt* wrapIfRandMode(AstClass* classp, AstVar* const varp, AstNodeStmt* stmtp) {
const RandomizeMode rmode = {.asInt = varp->user1()};
const RandomizeMode rmode = {.asUQuad = varp->user1()};
AstVar* const modeVarp = varp->lifetime().isStatic() ? getStaticRandModeVar(classp)
: getRandModeVarFromClass(classp);
return VN_AS(wrapIfMode(rmode, modeVarp, stmtp), NodeStmt);
}
AstNode* wrapIfConstraintMode(AstClass* classp, AstConstraint* const constrp, AstNode* stmtp) {
const RandomizeMode rmode = {.asInt = constrp->user1()};
const RandomizeMode rmode = {.asUQuad = constrp->user1()};
AstVar* const modeVarp = constrp->isStatic() ? getStaticConstraintModeVar(classp)
: getConstraintModeVar(classp);
return wrapIfMode(rmode, modeVarp, stmtp);
@@ -4576,7 +4576,7 @@ class RandomizeVisitor final : public VNVisitor {
UASSERT_OBJ(newp, nodep, "No new() in class");
nodep->foreachMember([&](AstClass* classp, AstVar* memberVarp) {
if (!memberVarp->rand().isRandomizable()) return;
const RandomizeMode randMode = {.asInt = memberVarp->user1()};
const RandomizeMode randMode = {.asUQuad = memberVarp->user1()};
if (randMode.usesMode
&& !memberVarp->rand().isRand()) { // Not randomizable by default
AstCMethodHard* setp = new AstCMethodHard{
@@ -4670,7 +4670,7 @@ class RandomizeVisitor final : public VNVisitor {
if (receiverp) {
// Called on a rand member variable/constraint. Set the variable/constraint's
// mode
const RandomizeMode rmode = {.asInt = receiverp->user1()};
const RandomizeMode rmode = {.asUQuad = receiverp->user1()};
UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode");
AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE,
new AstConst{fl, rmode.index}};
@@ -4688,7 +4688,7 @@ class RandomizeVisitor final : public VNVisitor {
} else {
UASSERT_OBJ(receiverp, ftaskRefp, "Should have receiver");
UASSERT_OBJ(!appendStmtp, ftaskRefp, "Append path requires arg-form rand_mode");
const RandomizeMode rmode = {.asInt = receiverp->user1()};
const RandomizeMode rmode = {.asUQuad = receiverp->user1()};
UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode");
AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE,
new AstConst{fl, rmode.index}};
@@ -4786,7 +4786,7 @@ class RandomizeVisitor final : public VNVisitor {
savedRandModeVarps.insert(randModeVarp);
tmpVarps = AstNode::addNext(tmpVarps, randModeTmpVarp);
}
const RandomizeMode randMode = {.asInt = randVarp->user1()};
const RandomizeMode randMode = {.asUQuad = randVarp->user1()};
AstCMethodHard* setp = new AstCMethodHard{
fl, makeModeVarRef(exprp, randModeVarp, VAccess::WRITE),
VCMethod::ARRAY_AT_WRITE, new AstConst{fl, randMode.index}};
@@ -4905,7 +4905,7 @@ class RandomizeVisitor final : public VNVisitor {
static bool distBoundRefsModeVar(const AstNode* boundp) {
return boundp->exists([](const AstVarRef* vrefp) {
if (!vrefp->varp()->rand().isRandomizable()) return false;
const RandomizeMode rmode = {.asInt = vrefp->varp()->user1()};
const RandomizeMode rmode = {.asUQuad = vrefp->varp()->user1()};
return rmode.usesMode;
});
}
@@ -5049,7 +5049,7 @@ class RandomizeVisitor final : public VNVisitor {
arrayp = new AstVarRef{fl, VN_AS(randModeVarp->user2p(), NodeModule), randModeVarp,
VAccess::READ};
}
const RandomizeMode rmode = {.asInt = varp->user1()};
const RandomizeMode rmode = {.asUQuad = varp->user1()};
AstCMethodHard* const atp
= new AstCMethodHard{fl, arrayp, VCMethod::ARRAY_AT, new AstConst{fl, rmode.index}};
atp->dtypeSetUInt32();
@@ -5063,7 +5063,7 @@ class RandomizeVisitor final : public VNVisitor {
if (!varp->rand().isRandomizable()) {
return new AstConst{fl, AstConst::BitTrue{}, ownerLevel};
}
const RandomizeMode rmode = {.asInt = varp->user1()};
const RandomizeMode rmode = {.asUQuad = varp->user1()};
if (!rmode.usesMode) return new AstConst{fl, AstConst::BitTrue{}};
return newModeBitRead(varp, mselp, randModeVarp, fl);
}
+1 -1
View File
@@ -320,7 +320,7 @@ class ReorderVisitor final : public VNVisitor {
// Is the current ordering OK?
bool leaveAlone = true;
int newOrder = 0; // New sequence number of assignment
uint64_t newOrder = 0; // New sequence number of assignment
for (const auto& item : rankMap) {
const AstNode* const nextp = item.second;
if (++newOrder != nextp->user4()) leaveAlone = false;
+8 -8
View File
@@ -52,8 +52,8 @@ class SliceVisitor final : public VNVisitor {
// AstNodeUniop::user1() -> bool. True if find is complete
// AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to
const VNUser1InUse m_inuser1;
// AstInitArray::user2() -> int. Previously accessed itemIdx
// AstInitItem::user2() -> int. Corresponding first elemIdx
// AstInitArray::user2() -> uint64_t. Previously accessed itemIdx
// AstInitItem::user2() -> uint64_t. Corresponding first elemIdx
const VNUser2InUse m_inuser2;
// STATE - across all visitors
@@ -66,7 +66,7 @@ class SliceVisitor final : public VNVisitor {
bool m_okInitArray = false; // Allow InitArray children
// METHODS
AstNodeExpr* cloneAndSel(AstNodeExpr* const nodep, int elements, int elemIdx,
AstNodeExpr* cloneAndSel(AstNodeExpr* const nodep, uint64_t elements, uint64_t elemIdx,
const bool needPure) {
// Insert an ArraySel, except for a few special cases
const AstUnpackArrayDType* const arrayp
@@ -83,7 +83,7 @@ class SliceVisitor final : public VNVisitor {
// Likely will cause downstream errors
return nodep->cloneTree(false, needPure);
}
if (arrayp->rangep()->elementsConst() != elements) {
if (static_cast<uint64_t>(arrayp->rangep()->elementsConst()) != elements) {
if (!m_assignError) {
nodep->v3error(
"Slices of arrays in assignments have different unpacked dimensions, "
@@ -103,10 +103,10 @@ class SliceVisitor final : public VNVisitor {
: idxFromLeft;
};
newp = nullptr;
int itemIdx = 0;
int i = 0;
uint64_t itemIdx = 0;
uint64_t i = 0;
const AstInitArray::KeyItemMap& itemMap = initp->map();
if (const int prevItemIdx = initp->user2()) {
if (const uint64_t prevItemIdx = initp->user2()) {
const auto it = itemMap.find(considerOrder(arrayp, prevItemIdx));
if (it != itemMap.end()) {
const AstInitItem* itemp = it->second;
@@ -284,7 +284,7 @@ class SliceVisitor final : public VNVisitor {
// Assign of an ascending range slice to a descending range one must reverse
// the elements
AstNodeAssign* newlistp = nullptr;
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
for (uint64_t elemIdx = 0; elemIdx < static_cast<uint64_t>(elements); ++elemIdx) {
// Original node is replaced, so it is safe to copy it one time even if it is impure.
AstNodeAssign* const newp
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx, elemIdx != 0),
+1 -1
View File
@@ -26,7 +26,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class StackCountVisitor final : public VNVisitorConst {
// NODE STATE
// AstNode::user2() -> int. Path cost + 1,
// AstNode::user2() -> uint64_t. Path cost + 1,
const VNUser2InUse m_inuser2;
// MEMBERS
+5 -7
View File
@@ -173,13 +173,11 @@ class TimingSuspendableVisitor final : public VNVisitor {
};
// NODE STATE
// AstClass::user1() -> bool. Set true if the class
// member cache has been
// refreshed.
// Ast{NodeProcedure,CFunc,Begin}::user2() -> int. Set to >= T_SUSP if
// process/task suspendable
// and to T_PROC if it
// needs process metadata.
// AstClass::user1() -> bool. Class member cache has been refreshed.
// Ast{NodeProcedure,CFunc,Begin}::user2() -> uint64_t. Set to >= T_SUSP if
// process/task suspendable
// and to T_PROC if it
// needs process metadata.
// Ast{NodeProcedure,CFunc,Begin}::user3() -> DependencyVertex*. Vertex in m_suspGraph
// Ast{NodeProcedure,CFunc,Begin}::user3() -> DependencyVertex*. Vertex in m_procGraph
const VNUser3InUse m_user3InUse;
+2 -2
View File
@@ -38,8 +38,8 @@ VL_DEFINE_DEBUG_FUNCTIONS;
class WidthCommitVisitor final : public VNVisitor {
// NODE STATE
// AstVar::user1p -> bool. Processed
// AstNodeFTask::user2() -> int. Non-zero if ever referenced (called)
// AstNew::user2() -> int. Count of number of references, minus references in
// AstNodeFTask::user2() -> uint64_t. Non-zero if ever referenced (called)
// AstNew::user2() -> uint64_t. Count of number of references, minus references in
// functions never called
const VNUser1InUse m_inuser1;
const VNUser2InUse m_inuser2;