From c49fad1dbad8fff7a1ded3db8552771c9e9a659d Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 29 Oct 2022 13:22:53 -0400 Subject: [PATCH] drop unneeded module-scoped references --- CHANGELOG.md | 1 + src/Convert/TypeOf.hs | 20 ++++++++++++++++++++ test/core/unneeded_scope.sv | 16 ++++++++++++++++ test/core/unneeded_scope.sv.pat | 5 +++++ test/core/unneeded_scope.v | 12 ++++++++++++ test/lib/functions.sh | 18 ++++++++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 test/core/unneeded_scope.sv create mode 100644 test/core/unneeded_scope.sv.pat create mode 100644 test/core/unneeded_scope.v diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d69d50..fc9fb90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fixed module-level localparams being needlessly inlined when forming longest static prefixes, which could cause deep recursion and run out of memory on some designs +* Fixed unneeded scoping of constant function calls used in type lookups ### Other Enhancements diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index 54fbdd1..9ecbc2f 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -122,6 +122,11 @@ traverseExprM (Cast (Right size) expr) = do expr' <- traverseExprM expr size' <- traverseExprM size elaborateSizeCast size' expr' +traverseExprM orig@(Dot (Ident x) f) = do + unneeded <- unneededModuleScope x f + return $ if unneeded + then Ident f + else orig traverseExprM other = traverseSinglyNestedExprsM traverseExprM other >>= traverseExprTypesM traverseTypeM @@ -150,6 +155,21 @@ isStringParam (Ident x) = do Just (_, _, typ) -> typ == TypeOf (Ident x) isStringParam _ = return False +-- checks if referring to part.wire is needlessly explicit +unneededModuleScope :: Identifier -> Identifier -> ST Bool +unneededModuleScope part wire = do + accessesLocal <- localAccessesM wire + if accessesLocal == accessesTop then + return True + else if head accessesLocal == head accessesTop then do + details <- lookupElemM wire + return $ case details of + Just (accessesFound, _, _) -> accessesTop == accessesFound + _ -> False + else + return False + where accessesTop = [Access part Nil, Access wire Nil] + -- convert TypeOf in a Type traverseTypeM :: Type -> ST Type traverseTypeM (TypeOf expr) = diff --git a/test/core/unneeded_scope.sv b/test/core/unneeded_scope.sv new file mode 100644 index 0000000..04c21a3 --- /dev/null +++ b/test/core/unneeded_scope.sv @@ -0,0 +1,16 @@ +module top; + function automatic integer incr; + input integer inp; + return inp + 1; + endfunction + parameter P = 3; + logic [incr(P):0] x; + logic [$bits(x) * 2:0] y, z; + if (1) begin + assign top.y = {top.x, x}; + end + if (1) begin : blk + wire x; + assign z = {blk.x, top.x}; + end +endmodule diff --git a/test/core/unneeded_scope.sv.pat b/test/core/unneeded_scope.sv.pat new file mode 100644 index 0000000..484e19a --- /dev/null +++ b/test/core/unneeded_scope.sv.pat @@ -0,0 +1,5 @@ +affirm top.y +affirm top.x +affirm blk.x +affirm incr +reject top.incr diff --git a/test/core/unneeded_scope.v b/test/core/unneeded_scope.v new file mode 100644 index 0000000..a378add --- /dev/null +++ b/test/core/unneeded_scope.v @@ -0,0 +1,12 @@ +module top; + parameter P = 3; + wire [P + 1:0] x; + wire [2 * P + 4:0] y, z; + assign y = {x, x}; + generate + if (1) begin : blk + wire x; + end + endgenerate + assign z = {blk.x, x}; +endmodule diff --git a/test/lib/functions.sh b/test/lib/functions.sh index 0055b8d..804873f 100644 --- a/test/lib/functions.sh +++ b/test/lib/functions.sh @@ -45,6 +45,24 @@ assertConverts() { ac_tmpa=$SHUNIT_TMPDIR/ac-conv-tmpa.v convert "1st conversion of $ac_file" $ac_tmpa $ac_file + # check for un/expected output in the converted result + ac_pats=$ac_file.pat + if [ -f $ac_pats ]; then + while read line; do + rule=${line:0:6} + pattern=${line:7} + grep -G "$pattern" < $ac_tmpa > /dev/null + matches=$? + if [ $rule == "affirm" ]; then + assertTrue "conversion of $ac_file does not contain $pattern" $matches + elif [ $rule == "reject" ]; then + assertFalse "conversion of $ac_file contains $pattern" $matches + else + fail "unknown rule type: '$rule'" + fi + done < $ac_pats + fi + ac_tmpb=$SHUNIT_TMPDIR/ac-conv-tmpb.v convert "2nd conversion of $ac_file" $ac_tmpb $ac_tmpa