Building on the existing MLIR integer interval range analysis framework, build the interface for the comb dialect. Use the interval range analysis to develop a comb opt narrowing pass, that reduces a comb opt based on the interval range of the operation. Currently this is only supported for addition, subtraction and multiplication, but this could be extended in the future. Future work will leverage the interval analysis to validate the combination of consecutive addition operators into a multi-operand addition.
In some cases, the "DUT" might be an extmodule from a separate
compilation unit, and we still want all the old legacy "is DUT" logic
to work. To support this, we need applyDUTAnno to allow the annotation
to be applied to an extmodule, and we need extractDUT and its users to
work with FModuleLikes instead of FModuleOp. The only other thing that
appears to be using this "is DUT" logic is the newer InstanceInfo
helper, which already works with igraph::ModuleOpInterfaces and seems
to work fine with extmodules as the "DUT".
Fix a bug in the `InstanceInfo` analysis where the analysis would be
different after running the `LowerLayers` pass. The problem here is that
`LowerLayers` converts a layer to a bound module. This could then cause
the new bound module to be in the design when it is not.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add a test of the `InstanceInfo` for a circuit which contains a Grand
Central companion, but does not contain a design-under-test.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Change the InstanceInfo analysis to record Grand Central Companions as
being _not_ in the design. These are functionally the same as layers
except that this is represented as a module as opposed to an operation
with a block. This is done as part of updating passes to use the
`InstanceInfo` analysis as opposed to relying on their own, individual
computations of what modules are in or not in the "design".
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add a test to check that the FIRRTL `InstanceInfo` analysis treates an
uninstantiated module as being part of the "effective" design. This is
also tested in tests of the `CreateSiFiveMetadata` pass. However, it is
better to test this directly.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Expand the API of the InstanceInfo analysis to include queries for if
something is in the "effective" design. This is equivalent to querying if
something is not under a layer.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Extend the existing InstanceInfo analysis to track information about if a
module is in the "design". The design is defined is everything that is or
is under the design-under-test, but is not in a layer. I.e., this
excludes things that are in layers.
This is added because it is not possible to compute this using the
existing information about something being under the DUT or under a layer.
A module could have mixed instantiation under the DUT and mixed
instantiation under a layer, yet not be in the design.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Fix a bug where the internal `underDut` member was not correctly asserted
if the top module is the DUT.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Change the functions for the `InstanceInfo` analysis to use "any" instead
of "atLeastOne". The former is far simpler and better aligns with the
"all" member functions.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add two new functions for computing if a module is under the "effective"
design-under-test (DUT):
- atLeastOneInstanceUnderEffectiveDut
- allInstancesUnderEffectiveDut
These functions are very simple. However, their use comes up in a number
of passes and this makes _reading_ those passes more straightforward.
I.e., it's quicker to grok what is going on with these functions than with
`!hasDut() || atLeastOneInstanceUnderEffectiveDut()`.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
[FIRRTL] Add features, cleanup InstanceInfo (again)
This fixes problems with a commit [[1]] that was reverted [[2]]. The commit
message below is unchanged.
Add a number of new features to FIRRTL's `InstanceInfo` analysis. These
changes were made after downstream efforts (uncommitted work) to use this
in the `AddSeqMemPorts` pass. These new features include:
- `hasDut` to check if a circuit has a design-under-test
- `getDut` to get the design-under-test if it exists
- `getEffectiveDut` to get the "effective" design-under-test
- `isEffectiveDut` to check if a module is the "effective"
design-under-test
The "effective" design-under-test (DUT) is a weird artifact of how some
SFC-derived passes have historically worked. If a circuit has no
DUT (indicated by a circuit which contains no module annotated with a
`MarkDUTAnnotation`), then some passes will treat the top module as if it
were the DUT. This "effective" DUT concept shows up in `AddSeqMemPorts`,
`GrandCentral`, and other passes. For now, enshrine the _computation_ of
this in the `InstanceInfo` analysis to avoid having to scatter logic for
computing this across serverl passes.
Widen the accepted type of parameters that can be passed to `InstanceInfo`
member functions from `FModuleOp` to `igraph::ModuleOpInterface`. This
already works without modifications and makes these member functions much
more usable.
[1]: 7e9cedd07
[2]: 2683f6772
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This reverts commit 7e9cedd07b. This commit
is showing problems with short integration tests hanging. I'm reverting
it temporarily to prevent any issues from leaking into main.
Add a number of new features to FIRRTL's `InstanceInfo` analysis. These
changes were made after downstream efforts (uncommitted work) to use this
in the `AddSeqMemPorts` pass. These new features include:
- `hasDut` to check if a circuit has a design-under-test
- `getDut` to get the design-under-test if it exists
- `getEffectiveDut` to get the "effective" design-under-test
- `isEffectiveDut` to check if a module is the "effective"
design-under-test
The "effective" design-under-test (DUT) is a weird artifact of how some
SFC-derived passes have historically worked. If a circuit has no
DUT (indicated by a circuit which contains no module annotated with a
`MarkDUTAnnotation`), then some passes will treat the top module as if it
were the DUT. This "effective" DUT concept shows up in `AddSeqMemPorts`,
`GrandCentral`, and other passes. For now, enshrine the _computation_ of
this in the `InstanceInfo` analysis to avoid having to scatter logic for
computing this across serverl passes.
Widen the accepted type of parameters that can be passed to `InstanceInfo`
member functions from `FModuleOp` to `igraph::ModuleOpInterface`. This
already works without modifications and makes these member functions much
more usable.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add a new InstanceInfo analysis. This analysis provides common
information which can be computed from a single walk of the InstanceGraph.
The idea behind this is that there are a large amount of common
information that different passes want to compute which all follows this
same walk (and therefore has the same algorithmic complexity to compute
it). Move all this information into a single, common analysis.
This analysis currently enables O(1) queries of if something is the DUT,
is instantiated under the DUT, or is instantiated under a layer. More
queries can be added as they are identified.
This new analysis naturally depends on the InstanceGraph analysis.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add the `dbg.scope` operation to the debug dialect. The op creates an
additional level of hierarchy in the DI, a "scope", which can be used to
group variables and other scopes.
Operations such as `hw.module` introduce an implicit scope. All debug
operations within a module are added to that implicit scope, unless they
have an explicit `scope` operand. Providing an explicit scope can be
used to represent inlined modules.
Scopes in DI do not necessarily have to correspond to levels of a module
hierarchy. They can also be used to model things like control flow
scopes, call stacks, and other source-language concepts.
This commit also introduces an optional `scope` operand on
`dbg.variable`. The `DebugInfo` analysis, which traverses the IR and
builds up a canonical representation of the DI, honors this operand and
adds the variables to the corresponding scope.
Add the `DebugAnalysis` which marks values and operations that only feed
into debug info. This will later allow ExportVerilog to skip expressions
and statements that are exclusively used by debug ops and are irrelevant
for synthesis and simulation.
The analysis is fairly straightforward at the moment. In the future, we
may want to be more clever about what we mark as debug-only. For
example, certain debug info output formats may allow us to emit entire
expressions and state machines, such that those can be stripped from the
Verilog output. In that case, we'd want to look through expressions,
wires, and registers when marking ops as debug-only. But some other
formats may only allow us to point at named signals in the Verilog, such
that any expression or register has to remain in Verilog, and possibly
be visible under a name for the debug info to make use of it.
This commit also bundles the `DebugInfo` analysis, which extracts the
source language hierarchy and variable layout from the IR, together with
this new `DebugAnalysis`, which marks ops as debug-only.
When traversing the IR in the `DebugInfo` analysis, consider
`dbg.variable` operations when populating the scope of local names for a
module. The current implementation is fairly straightforward, but as the
debug dialect evolves and we begin to track module inlining and
outlining, this analysis will become more involved and do more of the
heavy lifting necessary to extract a clean debug hierarchy from the IR.
CIRCT will eventually want to be able to emit debugging information
alongside its Verilog and other outputs. This commit adds a basic
`DebugInfo` analysis that traverses the IR, collects information in
whichever format we chose to annotate it in the IR, and forms a separate
graph of DI nodes that can be inspected easily.
The rationale behind a separate DI graph is to decouple debug info
formats from in-IR storage. For example, we may want to emit the DI into
a JSON file (which is what the experimental HGLDD does), or dump the DI
in a human-readable form for testing. In the IR, it is not yet clear if
we respresent DI as separate ops, attributes on existing ops, and how
attributes express the DI graph. For example, do modules list their
variables, which makes removal hard, or do variables point to their
parent modules? The `DebugInfo` analysis abstracts over this IR encoding
matter and presents the DI in a format that is easily emitted. (Modules
list their contained variables.)
This commit also adds a `DebugInfo` MLIR translation library to CIRCT.
It implements DI emission as straightforward translations, allowing for
DI to be emitted as:
- `circt-translate --dump-di` for human-readable testing; and
- `circt-translate --emit-hgldd` and
`circt-translate --emit-split-hgldd` for an experimental JSON format
When compiling a design with firtool, the `--emit-hgldd` option can be
used to generate `*.dd` companion files alongside its SV output. This
relies on Verilog emission locations to be annotated in the IR, which
is done separately in PR #6092.
This is quite invasive. This converts from the functiontype printer to the moduletype printer.
---------
Co-authored-by: Mike Urbach <mikeurbach@gmail.com>
This bumps llvm. There is an upstream bug which affects DC.join. Some folders and tests are disabled due to this.
---------
Co-authored-by: Andrew Young <youngar17@gmail.com>
Co-authored-by: Andrew Lenharth <andrew@lenharth.org>
This commit adds support for inferring a top-level module in an InstanceGraph.
The implementation is based on a topological sort of the instance graph. Through this, error messages will be generated in case of a cycle in the instance graph or when multiple candidate top modules are found.
This commit factors out the top level loop analysis used in StandardToHandshake and adds tests for it. While not being a feature complete loop analysis, this is the first step in building a uniform loop analysis that might be upstreamed to MLIR one day.
* LLVM bump (as we know it)
* minor format fix
* DCMAKE_BUILD_TYPE=?
* Update lib/Dialect/MSFT/MSFTOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* Update lib/Dialect/FIRRTL/FIRRTLOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* Update lib/Dialect/Calyx/CalyxOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* removed anon module test
Co-authored-by: Andrew Young <youngar17@gmail.com>
This generalizes the auxiliary dependences added for control flow to
support both Affine and SCF IfOps. Similarly, the auxiliary dependence
from the stores to the terminator are generalized to support both
Affine and MemRef StoreOp. With these enhancements, this analysis now
supports the SCF and MemRef dialects, provided the memory dependences
are correctly assigned.
This analysis depends on the MemoryDependenceAnalysis and uses the
dependences to compute a partially complete CyclicProblem for each
AffineForOp loop nest.
This is currently not considered by the upstream analysis, but is
crucial for informing scheduling decisions. Add the new logic here
until we know if there is a home for it upstream.
This is currently a simple class that traverses pairs of Affine memory
access operations and uses the upstream `checkMemrefAccessDependence`
function. The results are stored in a convenient data structure that
can be queried to inform scheduling decisions. A test pass is added,
which outputs the results as attributes for verification.