google / google/xls

const if / for / match / fn proposal

Open
#3,483 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.9k
Forks
283
Avg merge
2d 10h
Merged PRs (30d)
135

Description

Related issues:
[support for const if expr in proc config](https://github.com/google/xls/issues/1749)
[DSLX Constexpr-If Semantics](https://github.com/google/xls/issues/2468)
[Conditional proc instantiation based on parameter values](https://github.com/google/xls/issues/2029)

This is a proposal for compile time `if` expressions. Also `match`, `for` and `fn` keywords are included here to allow a discussion that can lead to a consistent solution for them as well.

## Why
The issues reported so far express the need for `if` expressions that:
* have the condition evaluated in compile time,
* allow spawning procs based on the if condition,
* allow creating branches that use types valid when the branch is chosen, not necessarily otherwise.

This is an example of a (currently unusable) way to spawn procs conditionally:
```
proc Add3Adv {
type InData = uN[IN_W];
type OutData = uN[OUT_W];

config(
data_r: chan in,
data_s: chan out
) {
if IN_W != OUT_W {
let (conn_s, conn_r) = chan("conn");
spawn Adapter(data_r, conn_s);
spawn Add3(conn_r, data_s);
} else {
spawn Add3(data_r, data_s)
};
}

init { () }
next(state: ()) { }
}
```

Another example, where depending on the parameter value, which is known at compile time, type checking fails on the unused branch:

```
fn f(a : u32) -> u32 {
if A == u32:0 {
a
} else {
let b : u32[A] = u32[A]:[u32:1,];
for (i, acc) in u32:0..A {
b[i] + acc
} (u32:0)
}
}
```

## Solution

1. Allow using compilation time if expressions, worded as `const if`, `const_if!`, `constexpr if`, `if constexpr` or another way that may be proposed in discussion here.
2. Evaluate the condition and drop the unused branch before type checking, or skip type checking for it.
3. Treat as errors in case the condition is not in fact possible to evaluate.

### Considerations about the keywords

As DSLX mimics Rust, it's worth noting that while Rust provides various ways for compile time evaluations [see Tracking Issue for inline const patterns](https://github.com/rust-lang/rust/issues/76001), all the existing solutions enforce type checking.

[Another issue](https://github.com/rust-lang/rfcs/issues/3582) is open for a `const if` evaluation that would not perform type checking on the unused branch.

#### `const if` / `const match` / `const for` / `const fn`
\+ As it's proposed in Rust, we might have the same in DSLX, which has been worded in opinions in the linked issues already.
\+ It would allow consistency with other expressions like `const match`, `const for`, `const fn`.
\- is not the same as `const` currently used in DSLX, so the meaning of `const` would depend on the use (*The const keyword is used to define module-level constant values.*)

#### `const_if!` / `const_match!` / `const_for!`
\+ Considering Rust, this actually reflects the fact that macros are the construct allowing skipping type checking for unused code.
\- Using `const_fn!` to define a function would be unconventional. If we consider `const fn` for functions, this would be inconsistent.
\+ No need to change the meaning of `const` in DSLX.

#### `constexpr if` / `constexpr match` / `constexpr for` / `constexpr fn`
\+ in C++, `if constexpr` reflects the goal of the proposal here
\+ no need to change the meaning of `const` in DSLX
\- longer keyword
\- doesn't mimic Rust

This issue has been created to encourage discussions about the addition to DSLX, the keywords used, and the existing constructs that might be replaced by this and become legacy (like `unroll_for!`).

You can see a WIP PR with `const if` implementation in: https://github.com/google/xls/pull/3268

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.