-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-spec and Implement OutlineCfg rewrite #225
Conversation
…r::create_with_io
@@ -513,23 +513,14 @@ pub(crate) mod test { | |||
// entry -> head -> split > merge -> tail -> exit | |||
// | \-> right -/ | | |||
// \---<---<---<---<---<---<---<---<---/ | |||
// split is unique successor of head |
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 was a driveby, but I'm doing the same in the new code. (It seemed small enough just to duplicate.)
Maybe this is the excuse we need to make the CFG's entry node special, exactly mirroring the exit node -- so it would not be a At the cost of introducing an extra node, if it makes the replacement API simpler I think it may be worth it. Thoughts? |
@@ -95,6 +97,20 @@ impl<B: AsMut<Hugr> + AsRef<Hugr>> CFGBuilder<B> { | |||
inputs: Some(input), | |||
}) | |||
} | |||
pub(crate) fn from_existing(base: B, cfg_node: Node) -> Result<Self, BuildError> { |
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 probably add a docstring for this?
I must be missing something here but I don't see how we get away with throwing away the entry node...
Is there a test for this method?
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's not pub - but yes, docstring added.
I've clued about the entry node (the thing is that creating a CFGBuilder doesn't create an entry node - you have to do that explicitly later using e.g. simple_entry_builder
and it will prepend that onto the list of children rather than append).
And added a test. (That creates a disconnected basic block, but it'll do for the test.)
} | ||
|
||
impl Rewrite for OutlineCfg { | ||
type Error = OutlineCfgError; |
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 this, is it used?
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's required for the Rewrite
trait, as the type of errors that can be returned by the apply
method
|
||
impl Rewrite for OutlineCfg { | ||
type Error = OutlineCfgError; | ||
const UNCHANGED_ON_FAILURE: bool = true; |
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.
Is this used?
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.
again, required for Rewrite
trait. (If you put anything in the impl <Trait> for ....
block that isn't part of the Trait, you'll get an error. Methods "private" to OutlineCfg would be in impl OutlineCfg
i.e. not for any trait.)
Yes, I had been wondering something similar. (Actually I'd been wishing we'd done that thing whereby Entry/Exit, and Input/Output for DFGs, were edges to/from the parent/container node, but never mind ;-) ). There are some possibilities:
The latter seems both the most sensible and also a bit weird. Hmmm, I'll keep thinking. I was also wondering if maybe we should just allow the set of blocks to include the entry block. Since the entry block may have other predecessors too, it may still share most of the code with the standard case (where entry block is not in the set of blocks) - I think I will code this up first and see how it looks. |
I'm thinking some sort of hybrid of these ideas:
|
…g op_types" This reverts commit 47cdc3f.
Ok, I've gone with allowing the set to include the entry node (because it is, after all, just another DFB). You can see the changes necessary in this commit: ddf8fb6 - not that hard at all. Beyond that I've added a test of moving the entry node, refactoring some other test code in (Contrastingly allowing the exit block is much harder, somewhat because it's a separate block type, also the second node in children not the first, and if we move the exit block into the sub-cfg, we need a new exit block because the sub-cfg cannot be the exit block - whereas it can be the entry block.) I wonder if we need a testutils file/class, maybe even a test_cfgs library - |
If we want to add another BasicBlock type, etc., I think that's a wider change, and best in another PR - we could do that after this, but I don't think this is so bad that we have to do that first (and quite possibly not at all) |
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.
Looks good, just a few textual suggestions.
nest_cfgs.rs
analysis will be the next PR. At the least, I'll need a way to apply rewrites to a HugrView/HugrMut/subregion-of-a-Hugr...