Skip to content

Commit

Permalink
Add pure/localState/packetStata annotations
Browse files Browse the repository at this point in the history
- add annotations in appropriate places in v1mode.p4 and psa.p4
- fix resolveReferences to look at parameters
  • Loading branch information
Chris Dodd authored and Chris Dodd committed Jan 8, 2025
1 parent 80ef07c commit 690438c
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 8 deletions.
6 changes: 5 additions & 1 deletion frontends/common/resolveReferences/resolveReferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,11 @@ bool ResolveReferences::preorder(const IR::P4Parser *p) {

bool ResolveReferences::preorder(const IR::Function *function) {
refMap->usedName(function->name.name);
checkShadowing(function);
return true;
}

bool ResolveReferences::preorder(const IR::Method *method) {
refMap->usedName(method->name.name);
return true;
}

Expand Down
1 change: 1 addition & 0 deletions frontends/common/resolveReferences/resolveReferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class ResolveReferences : public Inspector, private ResolutionContext {
bool preorder(const IR::P4Parser *t) override;
bool preorder(const IR::P4Action *t) override;
bool preorder(const IR::Function *t) override;
bool preorder(const IR::Method *t) override;
bool preorder(const IR::TableProperties *t) override;
bool preorder(const IR::Type_Method *t) override;
bool preorder(const IR::ParserState *t) override;
Expand Down
3 changes: 3 additions & 0 deletions frontends/p4/parseAnnotations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ ParseAnnotations::HandlerMap ParseAnnotations::standardHandlers() {
PARSE_EMPTY(IR::Annotation::optionalAnnotation),
PARSE_EMPTY(IR::Annotation::pureAnnotation),
PARSE_EMPTY(IR::Annotation::noSideEffectsAnnotation),
PARSE_EMPTY(IR::Annotation::localStateAnnotation),
PARSE_EMPTY(IR::Annotation::packetStateAnnotation),
PARSE(IR::Annotation::localIndexedStateAnnotation, Expression),
PARSE_EMPTY("disable_optimization"_cs),
PARSE_EMPTY("unroll"_cs),
PARSE_EMPTY("nounroll"_cs),
Expand Down
3 changes: 3 additions & 0 deletions ir/annotations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const cstring IR::Annotation::deprecatedAnnotation = "deprecated"_cs;
const cstring IR::Annotation::synchronousAnnotation = "synchronous"_cs;
const cstring IR::Annotation::pureAnnotation = "pure"_cs;
const cstring IR::Annotation::noSideEffectsAnnotation = "noSideEffects"_cs;
const cstring IR::Annotation::localStateAnnotation = "localState"_cs;
const cstring IR::Annotation::packetStateAnnotation = "packetState"_cs;
const cstring IR::Annotation::localIndexedStateAnnotation = "localIndexedState"_cs;
const cstring IR::Annotation::noWarnAnnotation = "noWarn"_cs;
const cstring IR::Annotation::matchAnnotation = "match"_cs;
const cstring IR::Annotation::fieldListAnnotation = "field_list"_cs;
Expand Down
5 changes: 4 additions & 1 deletion ir/base.def
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,14 @@ class Annotation {
static const cstring synchronousAnnotation; /// Synchronous annotation.
static const cstring pureAnnotation; /// extern function/method annotation.
static const cstring noSideEffectsAnnotation; /// extern function/method annotation.
static const cstring noWarnAnnotation; /// noWarn annotation.
static const cstring localStateAnnotation; /// extern function/method annotation.
static const cstring packetStateAnnotation; /// extern function/method annotation.
static const cstring localIndexedStateAnnotation; /// extern function/method annotation.
static const cstring matchAnnotation; /// Match annotation (for value sets).
static const cstring fieldListAnnotation; /// Used for recirculate, etc.
static const cstring debugLoggingAnnotation; /// Used by compiler implementer to limit debug log to the annotated IR context.
static const cstring disableOptimizationAnnotation; /// annotation to disable certain optimization
static const cstring noWarnAnnotation; /// noWarn annotation.

toString{ return absl::StrCat("@", name); }
validate{
Expand Down
25 changes: 21 additions & 4 deletions p4include/bmv2/psa.p4
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ extern bool psa_recirculate(in psa_egress_output_metadata_t istd,
* because, if you follow this advice, your program will behave the
* same way when assert statements are removed.
*/
@localState
extern void assert(in bool check);

/***
Expand Down Expand Up @@ -407,6 +408,7 @@ extern void assert(in bool check);
* condition ever evaluates to false when operating in a network, it
* is likely that your assumption was wrong, and should be reexamined.
*/
@localState
extern void assume(in bool check);

// BEGIN:Match_kinds
Expand Down Expand Up @@ -542,13 +544,15 @@ extern Checksum<W> {
/// time the object is instantiated, that is, whenever the parser or control
/// containing the Checksum object are applied.
/// All state maintained by the Checksum object is independent per packet.
@packetState
void clear();

/// Add data to checksum
@packetState
void update<T>(in T data);

/// Get checksum for data added (and not removed) since last clear
@noSideEffects
@packetState @noSideEffects
W get();
}
// END:Checksum_extern
Expand All @@ -566,29 +570,33 @@ extern InternetChecksum {
/// initialized as if clear() had been called on it, once for each
/// time the parser or control it is instantiated within is
/// executed. All state maintained by it is independent per packet.
@packetState
void clear();

/// Add data to checksum. data must be a multiple of 16 bits long.
@packetState
void add<T>(in T data);

/// Subtract data from existing checksum. data must be a multiple of
/// 16 bits long.
@packetState
void subtract<T>(in T data);

/// Get checksum for data added (and not removed) since last clear
@noSideEffects
@packetState @noSideEffects
bit<16> get();

/// Get current state of checksum computation. The return value is
/// only intended to be used for a future call to the set_state
/// method.
@noSideEffects
@packetState @noSideEffects
bit<16> get_state();

/// Restore the state of the InternetChecksum instance to one
/// returned from an earlier call to the get_state method. This
/// state could have been returned from the same instance of the
/// InternetChecksum extern, or a different one.
@packetState
void set_state(in bit<16> checksum_state);
}
// END:InternetChecksum_extern
Expand All @@ -608,6 +616,7 @@ enum PSA_CounterType_t {
@noWarn("unused")
extern Counter<W, S> {
Counter(bit<32> n_counters, PSA_CounterType_t type);
@localIndexedState(index)
void count(in S index);
}
// END:Counter_extern
Expand All @@ -616,6 +625,7 @@ extern Counter<W, S> {
@noWarn("unused")
extern DirectCounter<W> {
DirectCounter(PSA_CounterType_t type);
@localState
void count();
}
// END:DirectCounter_extern
Expand All @@ -640,11 +650,13 @@ extern Meter<S> {
// Use this method call to perform a color aware meter update (see
// RFC 2698). The color of the packet before the method call was
// made is specified by the color parameter.
@localIndexedState(index)
PSA_MeterColor_t execute(in S index, in PSA_MeterColor_t color);

// Use this method call to perform a color blind meter update (see
// RFC 2698). It may be implemented via a call to execute(index,
// MeterColor_t.GREEN), which has the same behavior.
@localIndexedState(index)
PSA_MeterColor_t execute(in S index);
}
// END:Meter_extern
Expand All @@ -653,7 +665,9 @@ extern Meter<S> {
extern DirectMeter {
DirectMeter(PSA_MeterType_t type);
// See the corresponding methods for extern Meter.
@localState
PSA_MeterColor_t execute(in PSA_MeterColor_t color);
@localState
PSA_MeterColor_t execute();
}
// END:DirectMeter_extern
Expand All @@ -667,8 +681,9 @@ extern Register<T, S> {
/// initial_value.
Register(bit<32> size, T initial_value);

@noSideEffects
@localIndexedState(index) @noSideEffects
T read (in S index);
@localIndexedState(index)
void write (in S index, in T value);
}
// END:Register_extern
Expand All @@ -682,6 +697,7 @@ extern Random<T> {
/// arguments to such values if they wish to maximize portability.

Random(T min, T max);
@localState
T read();
}
// END:Random_extern
Expand All @@ -706,6 +722,7 @@ extern ActionSelector {
// BEGIN:Digest_extern
extern Digest<T> {
Digest(); /// define a digest stream to the control plane
@localState
void pack(in T data); /// emit data into the stream
}
// END:Digest_extern
Expand Down
25 changes: 23 additions & 2 deletions p4include/v1model.p4
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ extern counter
* size-1]. If index >= size, no counter state will be
* updated.
*/
@localIndexedState(index)
#if V1MODEL_VERSION >= 20200408
void count(in I index);
#else
Expand Down Expand Up @@ -195,6 +196,7 @@ extern direct_counter {
* packets, regardless of whether the count() method is called in
* the body of that action.
*/
@localState
void count();
}

Expand Down Expand Up @@ -243,6 +245,7 @@ extern meter
* range, the final value of result is not specified,
* and should be ignored by the caller.
*/
@localIndexedState(index)
#if V1MODEL_VERSION >= 20200408
void execute_meter<T>(in I index, out T result);
#else
Expand Down Expand Up @@ -283,6 +286,7 @@ extern direct_meter<T> {
* color YELLOW, and 2 for color RED (see RFC 2697
* and RFC 2698 for the meaning of these colors).
*/
@noSideEffects @localState
void read(out T result);
}

Expand Down Expand Up @@ -317,7 +321,7 @@ extern register<T>
* value of result is not specified, and should be
* ignored by the caller.
*/
@noSideEffects
@noSideEffects @localIndexedState(index)
#if V1MODEL_VERSION >= 20200408
void read(out T result, in I index);
#else
Expand Down Expand Up @@ -345,6 +349,7 @@ extern register<T>
* parameter's value is written into the register
* array element specified by index.
*/
@localIndexedState(index)
#if V1MODEL_VERSION >= 20200408
void write(in I index, in T value);
#else
Expand All @@ -364,6 +369,7 @@ extern action_profile {
*
* @param T Must be a type bit<W>
*/
@localState
extern void random<T>(out T result, in T lo, in T hi);

/***
Expand All @@ -389,6 +395,7 @@ extern void random<T>(out T result, in T lo, in T hi);
* The BMv2 implementation of the v1model architecture ignores the
* value of the receiver parameter.
*/
@packetState
extern void digest<T>(in bit<32> receiver, in T data);

enum HashAlgorithm {
Expand All @@ -403,6 +410,7 @@ enum HashAlgorithm {
}

@deprecated("Please use mark_to_drop(standard_metadata) instead.")
@packetState
extern void mark_to_drop();

/***
Expand Down Expand Up @@ -480,6 +488,7 @@ extern Checksum16 {
* may be supported). Must be a compile-time
* constant.
*/
@packetState
extern void verify_checksum<T, O>(in bool condition, in T data, in O checksum, HashAlgorithm algo);

/***
Expand Down Expand Up @@ -513,6 +522,7 @@ extern void update_checksum<T, O>(in bool condition, in T data, inout O checksum
* Calling verify_checksum_with_payload is only supported in the
* VerifyChecksum control.
*/
@packetState
extern void verify_checksum_with_payload<T, O>(in bool condition, in T data, in O checksum, HashAlgorithm algo);

/**
Expand All @@ -524,7 +534,7 @@ extern void verify_checksum_with_payload<T, O>(in bool condition, in T data, in
* Calling update_checksum_with_payload is only supported in the
* ComputeChecksum control.
*/
@noSideEffects
@noSideEffects @packetState
extern void update_checksum_with_payload<T, O>(in bool condition, in T data, inout O checksum, HashAlgorithm algo);

/***
Expand All @@ -536,6 +546,7 @@ extern void update_checksum_with_payload<T, O>(in bool condition, in T data, ino
*/
extern void clone(in CloneType type, in bit<32> session);

@packetState
@deprecated("Please use 'resubmit_preserving_field_list' instead")
extern void resubmit<T>(in T data);
/***
Expand Down Expand Up @@ -572,8 +583,10 @@ extern void resubmit<T>(in T data);
* and preserve fields x and y of the user metadata. Calling
* resubmit_preserving_field_list(2) will only preserve field y.
*/
@packetState
extern void resubmit_preserving_field_list(bit<8> index);

@packetState
@deprecated("Please use 'recirculate_preserving_field_list' instead")
extern void recirculate<T>(in T data);
/***
Expand All @@ -598,8 +611,10 @@ extern void recirculate<T>(in T data);
* are preserved. See the v1model architecture documentation (Note 1)
* for more details.
*/
@packetState
extern void recirculate_preserving_field_list(bit<8> index);

@packetState
@deprecated("Please use 'clone_preserving_field_list' instead")
extern void clone3<T>(in CloneType type, in bit<32> session, in T data);

Expand Down Expand Up @@ -637,8 +652,10 @@ extern void clone3<T>(in CloneType type, in bit<32> session, in T data);
* control, only the last clone session and index are used. See the
* v1model architecture documentation (Note 1) for more details.
*/
@packetState
extern void clone_preserving_field_list(in CloneType type, in bit<32> session, bit<8> index);

@packetState
extern void truncate(in bit<32> length);

/***
Expand All @@ -665,6 +682,7 @@ extern void truncate(in bit<32> length);
* because, if you follow this advice, your program will behave the
* same way when assert statements are removed.
*/
@localState
extern void assert(in bool check);

/***
Expand Down Expand Up @@ -700,14 +718,17 @@ extern void assert(in bool check);
* condition ever evaluates to false when operating in a network, it
* is likely that your assumption was wrong, and should be reexamined.
*/
@localState
extern void assume(in bool check);

/*
* Log user defined messages
* Example: log_msg("User defined message");
* or log_msg("Value1 = {}, Value2 = {}",{value1, value2});
*/
@localState
extern void log_msg(string msg);
@localState
extern void log_msg<T>(string msg, in T data);

// The name 'standard_metadata' is reserved
Expand Down

0 comments on commit 690438c

Please sign in to comment.