-
Notifications
You must be signed in to change notification settings - Fork 177
Conversation
val defAnnotatedMemories: collection.mutable.ListBuffer[DefAnnotatedMemory] = | ||
collection.mutable.ListBuffer[DefAnnotatedMemory]() |
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 shouldn't be public, and also must be cleared each time the transform is run. Ideally we wouldn't have a class field for this information (arguments are better), but that obviously would be a much more intrusive change.
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 use this to replace writer
, I think it is the cheapest patch version. ;p
I will make it private.
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 shouldn't be public, and also must be cleared each time the transform is run.
Are you telling me that if my Transform is a class, only a single instance is created and could be used for multiple calls to execute
? If that is the case, shouldn't all transforms be object
instead of class
?
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, the dependency manager will only construct one instance of a class if it needs to run multiple times. Maybe this wasn't the best idea, but the intent was to reuse existing transforms to solve lowerings due to invalidations. This can be a source of bugs (like this) where there is state in the transform.
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.
Got it. So here are two options:
- remove
defAnnotatedMemories
, but which might introduce a bigger diff. - clean up
defAnnotatedMemories
at last of this transform.
Which one should I adopt? I personally prefer using the second one currently, and open another PR for dependency API until we get vlsi_mem_gen
into firrtl.
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.
Maybe this wasn't the best idea, but the intent was to reuse existing transforms to solve lowerings due to invalidations.
I see. I guess that would mean that eventually we just migrate all transforms to be object
and then maybe we can deprecate Dependency[..]
and leave Dependency(...)
as the only option.
(Note: sorry for hijacking this thread)
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.
(2) may also require defining a critical region to serialize accesses to the mutable internals. I think there can be bugs when working in a parallel environment using the same stage. This can happen in tests.
@ekiwi: That seems very reasonable, though a long, painful deprecation road. :)
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.
(2) may also require defining a critical region to serialize accesses to the mutable internals. I think there can be bugs when working in a parallel environment using the same stage. This can happen in tests.
Got it, I will directly refactor it ;)
(Note: sorry for hijacking this thread)
Haha, no worries, I think this did help me understand what I should do for this PR.
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.
ready for review again: 6ac90a3
e3f0fdf
to
57ba733
Compare
57ba733
to
2561c01
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.
I like the overall idea, would like some clarification about the plan: is this just slated for 1.5 in which case we can backport some deprecations and then break APIs or should we instead work on making things binary compatible (honestly, doesn't seem worth it)?
I also really don't like the mutability of MemLibOutConfigFileAnnotation
}.mkString("\n").getBytes | ||
} | ||
|
||
trait HasAnnotatedMemories { |
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.
Why make this a trait (especially unsealed) rather than just methods on the class?
More problematic, I don't love the mutability here. Why not have 2 different annotations (shared functionality in a trait perhaps 😉), 1 before the information is evaluated and 1 after?
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 removed this API and added private[memlib] case class AnnotatedMemoriesCollectorAnnotation() extends NoTargetAnnotation
, I don't like mutable neither, but I think in this transform we must have a mutable thing to store those DefAnnotatedMemory
, during walking the entire circuit: originally it was the config writer, in b385574, it was HasAnnotatedMemories
, and in 7f82ea1, it is AnnotatedMemoriesCollectorAnnotation
, I use insert
and done
function to make sure it only can be written during walking the circuit at first time, so I think it's safe here.
So generally I'd like to make a binary incompatible change in this PR, since
I'll create 2 annotations, one annotation for collect |
a946ba2
to
7f82ea1
Compare
@jackkoenig Need review again :) |
def updateMemMods( | ||
namespace: Namespace, | ||
nameMap: NameMap, | ||
memMods: Modules, | ||
insertFunc: DefAnnotatedMemory => Unit | ||
)(m: DefModule | ||
) = { |
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 these methods should be private (since we're changing them anyway, might as well take the opportunity).
Also, rather than using insertFunc
to mutate an Annotation, why not just pass a ListBuffer[DefAnnotatedMemory]
here and get rid of AnnotatedMemoriesCollectorAnnotation
altogether? It's all private, I don't think there's any need for that annotation when we could just use the mutable collection directly and construct MemLibOutConfigFileAnnotation
at the end.
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.
get rid of
AnnotatedMemoriesCollectorAnnotation
I personal prefer using an standalone Annotation to store this mutable data,so in the DumpMemoryAnnotations
Transform, we can directly convert this annotation to other annotations, in current case only the configure file, in the next PRs, InlinedBlackBoxes
can be converted to.
That’s the reason why I add this intermediate annotation.
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.
And another question is if we use mutable collection here, when I switch to dependency API, will it be thread safe? As @seldridge said,
I think there can be bugs when working in a parallel environment using the same stage. This can happen in tests.
this is the reason I put mutable thing in annotations, which makes transform fully immutable.
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 these methods should be private (since we're changing them anyway, might as well take the opportunity).
Sure, I’ll add private keywords when finishing review for a easy rebasing flow.
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.
And another question is if we use mutable collection here, when I switch to dependency API, will it be thread safe?
You just need to create one instance of the collection for every call to the execute
function. Like do not make it a member of the class, instead create it in execute
and give a reference to it to every function that needs to mutate.
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.
Got it, fixed :)
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.
Hi, @jackkoenig
Also, rather than using insertFunc to mutate an Annotation, why not just pass a ListBuffer[DefAnnotatedMemory] here and get rid of AnnotatedMemoriesCollectorAnnotation altogether?
Done. I have removed that annotation. But still have the AnnotatedMemoriesAnnotation
For transform to other annotations. Is that ok? As @ekiwi suggested, mutable is in execute function now.
It's all private, I don't think there's any need for that annotation when we could just use the mutable collection directly and construct MemLibOutConfigFileAnnotation at the end.
Since after this PR, I wanna transform to Verilog blackboxes annotations, thus create the intermediate annotation, and consume it in next transform.
7f82ea1
to
40b7bc2
Compare
40b7bc2
to
99e205e
Compare
5e5fb72
to
ee9861c
Compare
ee9861c
to
5dd5d80
Compare
5dd5d80
to
d561ed8
Compare
0. replace AnnotatedMemoriesCollectorAnnotation with immutable AnnotatedMemoriesAnnotation. 1. add ListBuffer[DefAnnotatedMemory] in ReplaceMemMacros.execute.
d561ed8
to
4a6036d
Compare
(cherry picked from commit 33c0b43) Co-authored-by: Jiuyang Liu <[email protected]>
@sequencer , the behavior after this change is that |
I thought |
btw, XiangShan projects has switched to new memlib pass in this PR: https://github.com/OpenXiangShan/XiangShan/pull/1000/files, hope this helps |
This PR depends on #2199
PLCT intern @sinofp is working on rewriting
vlsi_mem_gen
into a Firrtl Transform.This PR refactor Memlib to pave the path for him to add Annotations for memlib.
Generally this PR try to replace
firrtl/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
Lines 135 to 145 in bf1cf3d
with Annotation, to make memlib transforms be able to digest Annotation and generate another Annotation, rather than directly write the conf file.
Contributor Checklist
Type of Improvement
API Impact
Deprecate CreateMemoryAnnotations, ConfWriter
Backend Code Generation Impact
None
Desired Merge Strategy
Release Notes
Reviewer Checklist (only modified by reviewer)
Please Merge
?