Merge branch 'master' into develop-v5

This commit is contained in:
Geza Lore
2022-07-29 12:04:24 +01:00
25 changed files with 472 additions and 75 deletions
+3 -1
View File
@@ -6127,7 +6127,9 @@ public:
class AstCLog2 final : public AstNodeUniop {
public:
AstCLog2(FileLine* fl, AstNode* lhsp)
: ASTGEN_SUPER_CLog2(fl, lhsp) {}
: ASTGEN_SUPER_CLog2(fl, lhsp) {
dtypeSetSigned32();
}
ASTNODE_NODE_FUNCS(CLog2)
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opCLog2(lhs); }
virtual string emitVerilog() override { return "%f$clog2(%l)"; }
+30 -16
View File
@@ -566,9 +566,35 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
const AstConst* const constp = VN_CAST(lhsp, Const);
CONST_BITOP_RETURN_IF(!constp, nodep->lhsp());
const bool maskFlip = isOrTree();
const V3Number& compNum = constp->num();
auto setPolarities = [this, &compNum](const LeafInfo& ref, const V3Number* maskp) {
const bool maskFlip = isOrTree();
int constantWidth = compNum.width();
if (maskp) constantWidth = std::max(constantWidth, maskp->width());
const int maxBitIdx = std::max(ref.lsb() + constantWidth, ref.msb() + 1);
// Mark all bits checked by this comparison
for (int bitIdx = ref.lsb(); bitIdx < maxBitIdx; ++bitIdx) {
const int maskIdx = bitIdx - ref.lsb();
const bool mask0 = maskp && maskp->bitIs0(maskIdx);
const bool outOfRange = bitIdx > ref.msb();
if (mask0 || outOfRange) { // RHS is 0
if (compNum.bitIs1(maskIdx)) {
// LHS is 1
// And tree: 1 == 0 => always false, set v && !v
// Or tree : 1 != 0 => always true, set v || !v
m_bitPolarities.emplace_back(ref, true, 0);
m_bitPolarities.emplace_back(ref, false, 0);
break;
} else { // This bitIdx is irrelevant
continue;
}
}
const bool polarity = compNum.bitIs1(maskIdx) != maskFlip;
m_bitPolarities.emplace_back(ref, polarity, bitIdx);
}
};
if (const AstAnd* const andp = VN_CAST(nodep->rhsp(), And)) { // comp == (mask & v)
const LeafInfo& mask = findLeaf(andp->lhsp(), true);
CONST_BITOP_RETURN_IF(!mask.constp() || mask.lsb() != 0, andp->lhsp());
@@ -583,14 +609,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
incrOps(nodep, __LINE__);
incrOps(andp, __LINE__);
// Mark all bits checked by this comparison
const int maxBitIdx = std::min(ref.lsb() + maskNum.width(), ref.msb() + 1);
for (int bitIdx = ref.lsb(); bitIdx < maxBitIdx; ++bitIdx) {
const int maskIdx = bitIdx - ref.lsb();
if (maskNum.bitIs0(maskIdx)) continue;
const bool polarity = compNum.bitIs1(maskIdx) != maskFlip;
m_bitPolarities.emplace_back(ref, polarity, bitIdx);
}
setPolarities(ref, &maskNum);
} else { // comp == v
const LeafInfo& ref = findLeaf(nodep->rhsp(), false);
CONST_BITOP_RETURN_IF(!ref.refp(), nodep->rhsp());
@@ -599,13 +618,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
incrOps(nodep, __LINE__);
// Mark all bits checked by this comparison
const int maxBitIdx = std::min(ref.lsb() + compNum.width(), ref.msb() + 1);
for (int bitIdx = ref.lsb(); bitIdx < maxBitIdx; ++bitIdx) {
const int maskIdx = bitIdx - ref.lsb();
const bool polarity = compNum.bitIs1(maskIdx) != maskFlip;
m_bitPolarities.emplace_back(ref, polarity, bitIdx);
}
setPolarities(ref, nullptr);
}
} else {
CONST_BITOP_SET_FAILED("Mixture of different ops cannot be optimized", nodep);
@@ -1751,6 +1764,7 @@ private:
lp->rhsp(lrp);
nodep->lhsp(llp);
nodep->rhsp(rlp);
nodep->dtypep(llp->dtypep()); // dtype of Biop is before shift.
VL_DO_DANGLING(rp->deleteTree(), rp);
VL_DO_DANGLING(rrp->deleteTree(), rrp);
// nodep->dumpTree(cout, " repShiftSame_new: ");
+1 -1
View File
@@ -247,7 +247,7 @@ public:
// OPERATORS
void v3errorEnd(std::ostringstream& str, const string& extra = "");
void v3errorEndFatal(std::ostringstream& str);
void v3errorEndFatal(std::ostringstream& str) VL_ATTR_NORETURN;
/// When building an error, prefix for printing continuation lines
/// e.g. information referring to the same FileLine as before
string warnMore() const;
+2
View File
@@ -790,6 +790,8 @@ private:
// otherwise end the current merge. Return ture if added, false if ended merge.
bool addIfHelpfulElseEndMerge(AstNodeStmt* nodep) {
UASSERT_OBJ(m_mgFirstp, nodep, "List must be open");
if (!checkOrMakeMergeable(nodep)) return false;
if (!m_mgFirstp) return false; // If 'checkOrMakeMergeable' closed the list
if (m_mgNextp == nodep) {
if (isSimplifiableNode(nodep)) {
if (addToList(nodep, nullptr)) return true;
+2 -2
View File
@@ -1010,11 +1010,11 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
if (!strcmp(valp, "clang")) {
m_compLimitBlocks = 80; // limit unknown
m_compLimitMembers = 64; // soft limit, has slowdown bug as of clang++ 3.8
m_compLimitParens = 80; // limit unknown
m_compLimitParens = 240; // controlled by -fbracket-depth, which defaults to 256
} else if (!strcmp(valp, "gcc")) {
m_compLimitBlocks = 0; // Bug free
m_compLimitMembers = 64; // soft limit, has slowdown bug as of g++ 7.1
m_compLimitParens = 0; // Bug free
m_compLimitParens = 240; // Unlimited, but generate same code as for clang
} else if (!strcmp(valp, "msvc")) {
m_compLimitBlocks = 80; // 128, but allow some room
m_compLimitMembers = 0; // probably ok, and AFAIK doesn't support anon structs
+1 -1
View File
@@ -315,7 +315,7 @@ private:
int m_compLimitBlocks = 0; // compiler selection; number of nested blocks
int m_compLimitMembers = 64; // compiler selection; number of members in struct before make anon array
int m_compLimitParens = 0; // compiler selection; number of nested parens
int m_compLimitParens = 240; // compiler selection; number of nested parens
string m_bin; // main switch: --bin {binary}
string m_exeName; // main switch: -o {name}
+59 -37
View File
@@ -1248,10 +1248,7 @@ private:
}
}
virtual void visit(AstCLog2* nodep) override {
if (m_vup->prelim()) {
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
nodep->dtypeSetSigned32();
}
if (m_vup->prelim()) { iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH); }
}
virtual void visit(AstPow* nodep) override {
// Pow is special, output sign only depends on LHS sign, but
@@ -3564,50 +3561,66 @@ private:
// which member each AstPatMember corresponds to before we can
// determine the dtypep for that PatMember's value, and then
// width the initial value appropriately.
using PatMap = std::map<const AstMemberDType*, AstPatMember*>;
using PatMap = std::map<const AstMemberDType*, AstPatMember*>; // Store member: value
using DTypeMap
= std::map<const std::string, AstPatMember*>; // Store data_type: default_value
PatMap patmap;
DTypeMap dtypemap;
{
const AstMemberDType* memp = vdtypep->membersp();
AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember);
for (; memp || patp;) {
while (patp) {
do {
if (patp) {
if (patp->keyp()) {
if (const AstText* textp = VN_CAST(patp->keyp(), Text)) {
memp = vdtypep->findMember(textp->text());
if (!memp) {
patp->keyp()->v3error("Assignment pattern key '"
<< textp->text()
<< "' not found as member");
break;
}
if (patp->keyp()) {
// '{member:value} or '{data_type: default_value}
if (const AstText* textp = VN_CAST(patp->keyp(), Text)) {
// member: value
memp = vdtypep->findMember(textp->text());
if (!memp) {
patp->keyp()->v3error("Assignment pattern key '"
<< textp->text() << "' not found as member");
break;
} else {
patp->keyp()->v3error(
"Assignment pattern key not supported/understood: "
<< patp->keyp()->prettyTypeName());
const std::pair<PatMap::iterator, bool> ret
= patmap.emplace(memp, patp);
if (!ret.second) {
patp->v3error("Assignment pattern contains duplicate entry: "
<< VN_AS(patp->keyp(), Text)->text());
}
memp = VN_AS(memp->nextp(), MemberDType);
}
} else if (const AstNodeDType* nodedtypep
= VN_CAST(patp->keyp(), NodeDType)) {
// data_type: default_value
const string dtype = nodedtypep->dtypep()->prettyDTypeName();
auto it = dtypemap.find(dtype);
if (it == dtypemap.end()) {
dtypemap.emplace(dtype, patp);
} else {
// Override stored default_value
it->second = patp->cloneTree(false);
}
} else {
// Undefined pattern
patp->keyp()->v3error(
"Assignment pattern key not supported/understood: "
<< patp->keyp()->prettyTypeName());
}
}
if (memp && !patp) {
// Missing init elements, warn below
memp = nullptr;
patp = nullptr;
break;
} else if (!memp && patp) {
patp->v3error("Assignment pattern contains too many elements");
memp = nullptr;
patp = nullptr;
break;
} else {
const std::pair<PatMap::iterator, bool> ret = patmap.emplace(memp, patp);
if (!ret.second) {
patp->v3error("Assignment pattern contains duplicate entry: "
<< VN_AS(patp->keyp(), Text)->text());
// constant expr
if (memp) {
const std::pair<PatMap::iterator, bool> ret
= patmap.emplace(memp, patp);
if (!ret.second) {
patp->v3error("Assignment pattern contains duplicate entry: "
<< VN_AS(patp->keyp(), Text)->text());
}
memp = VN_AS(memp->nextp(), MemberDType);
}
}
} while (false);
// Next
if (memp) memp = VN_AS(memp->nextp(), MemberDType);
if (patp) patp = VN_AS(patp->nextp(), PatMember);
}
}
@@ -3618,13 +3631,22 @@ private:
AstPatMember* newpatp = nullptr;
AstPatMember* patp = nullptr;
if (it == patmap.end()) {
if (defaultp) {
const string memp_DType = memp->virtRefDTypep()->prettyDTypeName();
const auto it2 = dtypemap.find(memp_DType);
if (it2 != dtypemap.end()) {
// default_value for data_type
patp = it2->second;
newpatp = patp->cloneTree(false);
patp = newpatp;
} else if (defaultp) {
// default_value for any unassigned member yet
newpatp = defaultp->cloneTree(false);
patp = newpatp;
} else {
if (!VN_IS(vdtypep, UnionDType)) {
nodep->v3error("Assignment pattern missed initializing elements: "
<< memp->prettyTypeName());
<< memp->virtRefDTypep()->prettyDTypeName() << " "
<< memp->prettyName());
}
}
} else {
+1
View File
@@ -3545,6 +3545,7 @@ patternKey<nodep>: // IEEE: merge structure_pattern_key, array_patt
| yaFLOATNUM { $$ = new AstConst($<fl>1,AstConst::RealDouble(),$1); }
| id { $$ = new AstText($<fl>1,*$1); }
| strAsInt { $$ = $1; }
| simple_type { $$ = $1; }
;
assignment_pattern<patternp>: // ==IEEE: assignment_pattern