-
Notifications
You must be signed in to change notification settings - Fork 177
Fix memory annotation deduplication #2286
Fix memory annotation deduplication #2286
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. Thanks for tackling this, @jared-barocsi!
I have some thoughts about the dependencies for this transform included inline.
override def prerequisites = firrtl.stage.Forms.LowForm | ||
|
||
override def optionalPrerequisites = Nil | ||
|
||
override def optionalPrerequisiteOf = firrtl.stage.Forms.BackendEmitters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this actually has no prerequisites
and no optionalPrerequisiteOf
.
@@ -84,7 +84,8 @@ object Forms { | |||
Dependency(passes.PadWidths), | |||
Dependency(passes.memlib.VerilogMemDelays), | |||
Dependency(passes.SplitExpressions), | |||
Dependency[firrtl.transforms.LegalizeAndReductionsTransform] | |||
Dependency[firrtl.transforms.LegalizeAndReductionsTransform], | |||
Dependency[firrtl.transforms.DedupAnnotationsTransform] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should actually be part of ChirrtlForm
and EliminateTargetPaths
invalidates it. Also, any transform which implements the ResolvedAnnotationPaths
trait would now invalidate annotation deduplication.
Does that make sense to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that does make sense. I noticed that the actually deduplication passes themselves were in HighForm
, but I was previously pointed to VerilogMinimumOptimized
being where I would put this pass. Clearly that approach ends up breaking some tests, along with LowFormMinimumOptimized
, so I'll try and get some more clarification on where it should belong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, any change to Forms.scala
will cause the LoweringCompilersSpec
to break. That is a super-legacy thing that is hard-coding the transform order before the Dependency API was added. It then compares the new order, computed from the Dependency API, applies any "patches" to that order, and then checks that it matches. That test always needs to be updated if anything in Forms.scala
changes or if dependencies change.
(It's expected that that will break with the change you made here! That will need a patch.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that adding DedupAnnotationsTransform
to Deduped
, which is then appended to HighForm
, does not require a change to LoweringCompilersSpec
bca5359
to
c873e99
Compare
c873e99
to
80c9f71
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good start, thanks for the working test!
I want to take this in a slightly different direction, my suggestion comment ended up getting really long so it might be helpful to meet to discuss it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really great, excellent work @jared-barocsi!
I left some comments inline and 1 more thing I'd like to see is the Verilog Emitter to error if the annotations were unable to be deduped. I think that logic would live here:
private[firrtl] class EmissionOptions(annotations: AnnotationSeq) { |
* Returning None signifies this annotation will not deduplicate. | ||
* @return | ||
*/ | ||
private[firrtl] def dedup: Option[((ReferenceTarget, Any), Annotation, ReferenceTarget)] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private[firrtl] def dedup: Option[((ReferenceTarget, Any), Annotation, ReferenceTarget)] = None | |
private[firrtl] def dedup: Option[(Any, Annotation, ReferenceTarget)] = None |
Since (ReferenceTarget, Any)
is itself an Any
, I think the key should just be Any
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be private to firrtl? I may be wrong but it seems to me to be pretty important to annotation writers.
It would be useful to have a generic mixin that automagically defines this, by grabbing all the parameters of the case class and filtering out the target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree this could be important, I don't want it to be public yet. I mainly want to get this fix in and released as 1.4.4 while we discuss what the user-facing API should be.
…rtl into fix-memory-anno-dedups
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great work!
* Add transform to deduplicate memory annotations * Add annotation deduplication to Dedup stage * ResolveAnnotationPaths and EliminateTargetPaths now invalidate the dedup annotations transform * Verilog emitter now throws exception when memory annotations fail to dedup Co-authored-by: Jack Koenig <koenig@sifive.com> (cherry picked from commit 4081d9f)
The problem I reported here doesn't seem to be resolved.
@jackkoenig Do you think it could be a different issue? |
@kammoh, |
Would you be able to provide a default implementation for all |
I don't think this is possible because the tuple ('dedup key') that's used to sort all of the annotations into deduplicatable groups contains the annotation's value, and that is different across implementations of
|
🤔 I think what you may need here is to define "annotation value equality". Given both the existing I think you could then group all annotations that are "annotation value equal" and, for their targets, deduplicate those and generate new annotations. I.e., produce fewer annotations or annotations with simpler targets. I'm just spitballing here and trying to reuse as much work as possible. 😄 What do you think? I admit |
+1 for @seldridge's idea, but I think Jack was concerned about the API leaking out before a longer-term annotation deduplication strategy is worked out. At very least, it could be done for SingleTargetAnnotations and kept package private for now. I'd also like see inline attributes fixed in the next 1.4.x release. |
* Fix memory annotation deduplication (#2286) * Add transform to deduplicate memory annotations * Add annotation deduplication to Dedup stage * ResolveAnnotationPaths and EliminateTargetPaths now invalidate the dedup annotations transform * Verilog emitter now throws exception when memory annotations fail to dedup Co-authored-by: Jack Koenig <koenig@sifive.com> (cherry picked from commit 4081d9f) * Fix binary compatibility issues with memory anno dedup transform (#2295) * Remove unused exception in dedup transform * Fold Annotation.dedup() into dedup transform for binary compatibility * ResolvedAnnotationPaths no longer invalidates any transforms * Use Annotation.copy() instead of constructor in dedup logic Co-authored-by: Jared Barocsi <82000041+jared-barocsi@users.noreply.github.com>
Contributor Checklist
Type of Improvement
API Impact
No changes to any API
Backend Code Generation Impact
MemoryInitAnnotations
and its subclasses are 're-localized' after module deduplication, which will result in the correct Verilog being emitted for memories with these annotations.Desired Merge Strategy
Squash and merge
Release Notes
Reviewer Checklist (only modified by reviewer)
Please Merge
?