Skip to content
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

Introduce local compile-time known values #1213

Merged
merged 23 commits into from
Jun 3, 2024
Merged
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f7b8a19
Introduce local compile-time known values
jnfoster Jan 9, 2023
0c7d00e
Fix bugs and streamline definitions with @apinski-cavium's input
jnfoster Jan 9, 2023
f631b9b
Add missing operators and fix formatting
jnfoster Jan 31, 2023
d656502
Address comment from Jonathan
jnfoster Jun 6, 2023
c53da39
Merge branch 'main' into local-compile-time-known
jnfoster Jul 10, 2023
273f207
Rebase and resolve conflicts
jnfoster Jan 5, 2024
ad2e692
Fix bugs and streamline definitions with @apinski-cavium's input
jnfoster Jan 9, 2023
f83ec5d
Add missing operators and fix formatting
jnfoster Jan 31, 2023
82320a9
Address comment from Jonathan
jnfoster Jun 6, 2023
49db57e
Detangle conflicts
jnfoster Jan 5, 2024
518cf10
Polish text for local compile-time known values.
jnfoster Jan 8, 2024
b518e6c
Address nits from Jonathan's review
jnfoster Jan 9, 2024
83313bf
Update p4-16/spec/P4-16-spec.mdk
jnfoster May 13, 2024
93f85f7
Update p4-16/spec/P4-16-spec.mdk
jnfoster May 13, 2024
ce69975
Update p4-16/spec/P4-16-spec.mdk
jnfoster May 13, 2024
27cb1ab
Remove spurious file from PR
jnfoster May 13, 2024
63260e8
Remove spurious file from PR
jnfoster May 13, 2024
f3dc4b9
Fix comments from @vlstill's review
jnfoster May 13, 2024
f92db37
Merge branch 'main' into local-compile-time-known
jnfoster Jun 3, 2024
8fb0338
Clarify note about calling convention
jnfoster Jun 3, 2024
d5f5d02
Restore spuriously deleted file
jnfoster Jun 3, 2024
037f603
Remove spurious edits to experimental bison notes
jnfoster Jun 3, 2024
630a54c
Remove more spurious edits to experimental bison notes
jnfoster Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 44 additions & 28 deletions p4-16/spec/P4-16-spec.mdk
Original file line number Diff line number Diff line change
Expand Up @@ -1660,7 +1660,7 @@ directions:
parameters in this case behave like `in` parameters.
See Section [#sec-invoke-actions] for further details.
- Default parameter values are only allowed for 'in' or direction-less parameters;
these values must evaluate to compile-time constants.
these values must evaluate to compile-time known values.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved

### Optional parameters { #sec-optional-parameters }

Expand Down Expand Up @@ -1775,8 +1775,7 @@ P4 supports the following built-in base types:
restricted circumstances.
- The `error` type, which is used to convey errors in a
target-independent, compiler-managed way.
- The `string` type, which can be used only for compile-time
constant string values.
- The `string` type, which can be used only for compile-time known constant string values.
- The `match_kind` type, which is used for describing the implementation of
table lookups,
- `bool`, which represents Boolean values
Expand Down Expand Up @@ -1866,7 +1865,7 @@ string values; one cannot declare variables with a `string` type.
Parameters with type `string` can be only directionless (see Section
[#sec-calling-convention]). P4 does not support string manipulation
in the dataplane; the `string` type is only allowed for denoting
compile-time constant string values. These may be useful, for
compile-time known constant string values. These may be useful, for
example, a specific target architecture may support an extern function
for logging with the following signature:

Expand Down Expand Up @@ -1937,7 +1936,7 @@ behavior should match this specification.
An unsigned integer (which we also call a "bit-string") has an
arbitrary width, expressed in bits. A bit-string of width `W` is
declared as: `bit<W>`. `W` must be an expression that evaluates to a
compile-time known value (see Section [#sec-ct-constants]) that is a
local compile-time known value (see Section [#sec-ct-constants]) that is a
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
non-negative integer. When using an expression for
the size, the expression must be parenthesized. Bitstrings with width 0 are
allowed; they have no actual bits, and can only have the value 0. See
Expand Down Expand Up @@ -1970,7 +1969,7 @@ described in Section [#sec-bit-ops].

Signed integers are represented using two's complement. An integer with `W`
bits is declared as: `int<W>`. `W` must be an expression that evaluates to
a compile-time known value that is a positive integer.
a local compile-time known value that is a positive integer.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved

Bits within an integer are numbered from `0` to `W-1`. Bit `0`
is the least significant, and bit `W-1` is the sign bit.
Expand All @@ -1997,7 +1996,7 @@ values, P4 provides a special bit-string type whose size is set at
runtime, called a `varbit`.

The type `varbit<W>` denotes a bit-string with a width of at most `W`
bits, where `W` must be a non-negative integer that is a compile-time
bits, where `W` must be a non-negative integer that is a local compile-time
known value. For example, the type `varbit<120>` denotes the type
of bit-string values that may have between 0 and 120 bits. Most
operations that are applicable to fixed-size bit-strings (unsigned
Expand Down Expand Up @@ -3377,7 +3376,7 @@ Bit-strings also support the following operations:
produces a result where all bits are zero.
- Extraction of a set of contiguous bits, also known as a slice,
denoted by `[H:L]`, where `H` and `L` must be expressions that evaluate to
non-negative compile-time known values, and `H >= L`. The types of `H` and `L`
non-negative, local compile-time known values, and `H >= L`. The types of `H` and `L`
(which do not need to be identical) must be one of the following:

- `int` - an arbitrary-precision integer
Expand All @@ -3395,7 +3394,7 @@ Bit-strings also support the following operations:
`0 <= L <= H < W` are checked statically (where `W` is
the length of the source bit-string). Note that both endpoints of
the extraction are inclusive. The bounds are required to be
known-at-compile-time values so that the result width can be computed
local, compile-time known values so that the result width can be computed
at compile time. Slices are also l-values, which means that P4 supports
assigning to a slice: ` e[H:L] = x `.
The effect of this statement is to set bits `H` through `L` (inclusive of
Expand Down Expand Up @@ -3474,7 +3473,7 @@ The `int<W>` datatype also support the following operations:
- all result bits are one when shifting a negative value right
- Extraction of a set of contiguous bits, also known as a slice,
denoted by `[H:L]`, where `H` and `L` must be expressions that evaluate to
non-negative compile-time known values, and `H >= L` must be true.
non-negative, local compile-time known values, and `H >= L` must be true.
The types of `H` and `L` (which do not need to be identical)
must be one of the following:

Expand Down Expand Up @@ -3525,7 +3524,7 @@ expressions of type `int` must be compile-time known values. The type
The expression `a << b` is equal to $a \times 2^b$ while `a >> b`
is equal to $\lfloor{a / 2^b}\rfloor$.
- Bit slices, denoted by `[H:L]`, where `H` and `L` must be expressions that evaluate to
non-negative compile-time known values, and `H >= L` must be true.
non-negative, local compile-time known values, and `H >= L` must be true.
The types of `H` and `L` (which do not need to be identical)
must be one of the following:

Expand Down Expand Up @@ -4783,7 +4782,7 @@ H h3 = { ... }; // initialize h3 with a header that is valid, field f1 0, field

The method calls `minSizeInBits`, `minSizeInBytes`, `maxSizeInBits`,
and `maxSizeInBytes` can be applied to some expressions. Each of
these method calls evaluate to compile-time known values that return
these method calls evaluate to local compile-time known values that return
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
the minimum size in bits required to store the expression (thus the
result type of these methods has type `int`). None of these methods
evaluates the expression itself. In consequence, the expression may
Expand Down Expand Up @@ -7182,28 +7181,44 @@ The evaluation of a P4 program is done in two stages:
executed to completion, in isolation, when it receives control from the
architecture

## Compile-time known values { #sec-ct-constants }
## Compile-time known and local compile-time known values { #sec-ct-constants }

The following are compile-time known values:
Certain expressions in a P4 program have the property that their value
can be determined at compile time. Moreover, for some of these
expressions, their value can be determined only using information in
the current scope. We call these _compile-time known values_ and
_local compile-time known values_ respectively.

The following are local compile-time known values:

- Integer literals, Boolean literals, and string literals.
- Identifiers declared in an `error`, `enum`, or `match_kind`
declaration.
- Identifiers declared in an `error`, `enum`, or `match_kind` declaration.
- The `default` identifier.
- The `size` field of a value with type header stack.
- The `_` identifier when used as a `select` expression label
- Identifiers that represent declared types, actions, tables, parsers,
controls, or packages.
- Tuple expression where all components are compile-time known values.
- Structure-valued expressions, where all fields are compile-time
known values.
- Instances constructed by instance declarations (Section
[#sec-instantiations]) and constructor invocations.
- The following expressions (`+`, `-`, `*`, `/ `, `%`, `cast`, `!`, `&`, `|`, `&&`, `||`, `<< `, `>> `, `~` `, `\ `>`, `<`, `==`, `!=`, `<=`, `>=`, `++`, `[:]`, `?:`)
when their operands are all compile-time known values.
- Identifiers that represent declared types, actions, tables, parsers, controls, or packages.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
- Tuple expression where all components are local compile-time known values.
- Structure-valued expressions, where all fields are local compile-time known values.
- Instances constructed by instance declarations (Section [#sec-instantiations]) and constructor invocations.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
- The following expressions (`+`, `-`, `*`, `/ `, `%`, `cast`, `!`, `&`, `|`, `&&`, `||`, `<< `, `>> `, `~` `, `\ `>`, `<`, `==`, `!=`, `<=`, `>=`, `++`, `[:]`, `?:`) when their operands are all local compile-time known values.
- Identifiers declared as constants using the `const` keyword.
- Expressions of the form `e.minSizeInBits()`, `e.minSizeInBytes()`,
`e.maxSizeInBits()` and `e.maxSizeInBytes()`
- Expressions of the form `e.minSizeInBits()`, `e.minSizeInBytes()`, `e.maxSizeInBits()` and `e.maxSizeInBytes()`
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
jnfoster marked this conversation as resolved.
Show resolved Hide resolved

The following are compile-time known values:

- All local compile-time known values.
- Tuple expression where all components are compile-time known values.
- Structure-valued expressions, where all fields are compile-time known values.
- The following expressions (`+`, `-`, `*`, `/ `, `%`, `cast`, `!`, `&`, `|`, `&&`, `||`, `<< `, `>> `, `~` `, `\ `>`, `<`, `==`, `!=`, `<=`, `>=`, `++`, `[:]`, `?:`) when their operands are all compile-time known values.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
- Constructor parameters.
jnfoster marked this conversation as resolved.
Show resolved Hide resolved

Intuitively, the main difference between _compile-time known values_
and _local compile-time known values_ is that the former also contains
constructor parameters. The distinction is important when it comes to
defining the meaning of features like types. For example, in the type
`bit<e>`, the expression `e` must be a local compile-time known value
as the value of a constructor parameter, is only determined when the
jnfoster marked this conversation as resolved.
Show resolved Hide resolved
constructor is applied to a value.

## Compile-time Evaluation { #sec-ct-eval }

Expand Down Expand Up @@ -7645,7 +7660,7 @@ extern bool static_assert(bool check, string message);
extern bool static_assert(bool check);

These functions both return boolean values. Since the parameters are
directionless, these functions require compile-time constant values as
directionless, these functions require compile-time known values as
arguments, thus they can be used to enforce compile-time invariants.
Since P4 does not allow statements at the program top-level (outside
of apply blocks), these functions can be used at the top-level by
Expand Down Expand Up @@ -8052,6 +8067,7 @@ The P4 compiler should provide:

## Summary of changes made in version 1.2.4

* Introduced distinction between local compile-time known and compile-time known values (Section[#sec-ct-constants]).
* Specified that algorithm for generating control-plane names for keys is optional (Section [#sec-cp-keys]).
* Clarified types of expressions that may appear in `select` (Section [#sec-select]).
* Explicitly disallow overloading of parsers, controls, and packages (Section [#sec-extern-objects]).
Expand Down