mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Internals: Change user1-4 storage to uint64 (#8317)
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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),
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user