[enhancement] missed optimization opportunity for duplicated logic in `sel` branches
What's hard to do? (limit 100 words)
When refactoring deep if branches for readability in DSLX code one sometime encapsulates logic into fns that get called w/ a few different parameters and return the same result type.
This can negatively impact the PPA:
- logic get duplicated across
selbranches, bumping the gate count and the resulting area. selwould get wider to accomodate unified return type resulting in worst timing.
(convoluted) example
The following code:
fn opt1(sign: u1, a: u8, b: u1) -> u8 {
a + if sign {
// sign positive: increment a w/ b
b
} else {
// sign negative: invert increment
!b
} as u8
}
results in the following schedule:
and the following BoM:
While the "refactored" version:
fn sign_positive (a:u8, b:u1) -> u8 {
a + b as u8
}
fn sign_negative(a:u8, b:u1) -> u8 {
a + !b as u8
}
fn opt2(sign: u1, a: u8, b: u1) -> u8 {
if sign == u1:0 {
sign_positive(a, b)
} else {
sign_negative(a, b)
}
}
results in a worst schedule (+40ps, because of the wider sel):
and an increased BoM (1 additional add(u8, u8)):
Current best alternative workaround (limit 100 words)
One workaround could be to add additional arguments to the refactored function to share some common computation done ahead of the sel and return intermediate result to narrow the size of sel; lessening encapsulation and potentially going back to negatively impacting readability.
Your view of the "best case XLS enhancement" (limit 100 words)
It would be nice if opt_main could detect sel w/ logic duplicated on each branches and move the common logic ahead of the sel.
This would likely result in sensible area saving and (limited) timing improvement.