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.
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 problem with the InstanceInfo analysis stemming from the use of
`InstanceGraphNode *` to track the design-under-test (DUT) and "effective"
DUT. If the instance graph changed, then these would be invalidated.
Instead use a `igraph::ModuleOpInterface` which is going to be stable.
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 `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.
This change moves InstanceGraphBase to support, and introduces an interface for driving the implementation, `InstanceGraphInterface`, which essentially is an extraction of the name- and lookup related functions of `HWModuleLike/HWInstanceLike` (which now inherit from the `InstanceGraph` interfaces).
The motivation for this is that multiple things in CIRCT may benefit from having graph iterators, and most/all of these will need an implementation exactly as what is given in InstanceGraphBase. My immediate usecase is to provide a graph for Ibis classes/containers, but things like handshake and FSM are other obvious users of this.
The interface is named `InstanceGraphInterface`, but in practice naming it `CIRCTModuleInterface` or something similar would probably be more apt, seeing as the `InstanceGraph` is just a generic view of module-like things in CIRCT (which in turn is more generic than HWModule like) - LMKWYT.
Implementing this change also performs some housekeeping in ensuring that all ops who inherit from the `HWModuleLike/HWInstanceLike` interfaces actually implements the name-related parts of the interface.
Co-authored-by: Morten Borup Petersen <mpetersen@microsoft.com>
Co-authored-by: Andrew Lenharth <andrew@lenharth.org>
Primarily:
getValue -> value
hasValue -> has_value
Value accesses not dominated by a presence check use 'value'.
(only use 'operator *' when clearly dominated by check)
"operator bool" and "operator *" used only when meaning was clear
(if variable looks like an integer, like getBitWidth(),
don't use operator bool unless the code already does so;
if returning result of a presence check prefer has_value, etc.)
Few places are slightly simplified, such as: using value_or,
avoiding calling same method for presence check and for the value,
and X.getValue().y -> X->y.
Fixes#3552.
(LLVM will be deprecating the old method names)
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.
* [FIRRTL][Dedup] Fix hash() to work with new SHA256.final() return type.
This follows the commit in upstream llvm,
330268ba346b679af786879d8f696c8c412a40eb, which changed SHA256.final()
to return a std::array<uint8_t, 32> instead of a StringRef. Although it
would be nice to directly use the SHA digest bytes as the hash key,
DenseMap does not have an implementation of DenseMapInfo for
std::array<uint8_t, N>, so it's easier to continue converting this to a
string for now.
* [LLHD][SCFToCalyx] Update getSuccessorOperands() to match upstream MLIR.
Commit 0c789db541c236abf47265331a2f2b0945aa7b93 in upstream llvm changed
BranchOpInterface's interfaces for getting successor operands.
It removed getMutableSuccessorOperands() and it changed
getSuccessorOperands() to return a new SuccessorOperands object instead
of an Optional<OperandRange>.
This affected LLHD's WaitOp, which implements the BranchOpInterface, and
SCFToCalyx, which calls some of the methods on BranchOpInterface.
For llhd::WaitOp, we now implement getSuccessorOperands() instead of
getMutableSuccessorOperands(), with the appropriate return type.
For SCFToCalyx, we now always work with a non-Optional SuccessorOperands
object, which required updating a few of the usages to not call Optional
methods.
* [Analysis][Scheduling] Explicitly set TypeID for test passes in anonymous namespaces.
This matches upstream LLVM commit
5e50dd048e3a20cde5da5d7a754dfee775ef35d6, where types defined in
anonymous namespaces are no longer allowed to have implicit TypeIDs.
This mostly only affects test passes.
* Bump llvm to 3d4ca8a8c39f772dd6c022220a6eef23238a77f6.
* [LLHD] Mark probeCSE test with XFAIL.
This test started failing after an LLVM submodule update. It is possibly
related to upstream LLVM commit
02da9643506dee4a82353e0f911513279634d846, which changes the behavior of
the upstream MLIR CSE pass to be able to optimize the case where there
are side effectful reads without an intermediate side effectful write.
This test case is now CSE'ing the `llhd.prb` ops into a single op and
returning both copies of it.
This analysis depends on the MemoryDependenceAnalysis and uses the
dependences to compute a partially complete CyclicProblem for each
AffineForOp loop nest.
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.