Skip to content

Commit

Permalink
[#4661] Do not unconditionally mark extern method calls as compile-ti…
Browse files Browse the repository at this point in the history
…me constants. (#4726)

* Do not mark argument-less extern method calls as compile-time constants.

Signed-off-by: kfcripps <[email protected]>

* Only mark pure extern function calls with const args as compile-time constants

Signed-off-by: kfcripps <[email protected]>

* Add tests

Signed-off-by: kfcripps <[email protected]>

* Fixes for static_assert() and factory extern functions

Signed-off-by: kfcripps <[email protected]>

* Appease cpplint

Signed-off-by: kfcripps <[email protected]>

* Do not unconditionally mark results of pure extern method function calls as compile-time constants

Signed-off-by: kfcripps <[email protected]>

* Also check for IR::Type_SpecializedCanonical with base type of IR::Type_Extern

Signed-off-by: kfcripps <[email protected]>

---------

Signed-off-by: kfcripps <[email protected]>
  • Loading branch information
kfcripps authored Jul 11, 2024
1 parent 3e60b5d commit f24aacc
Show file tree
Hide file tree
Showing 14 changed files with 445 additions and 7 deletions.
17 changes: 13 additions & 4 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3862,10 +3862,19 @@ const IR::Node *TypeInference::postorder(IR::MethodCallExpression *expression) {
return expression;
}

if (mi->is<ExternFunction>() && constArgs) {
// extern functions with constant args are compile-time constants
setCompileTimeConstant(expression);
setCompileTimeConstant(getOriginal<IR::Expression>());
if (const auto *ef = mi->to<ExternFunction>()) {
const IR::Type *baseReturnType = returnType;
if (const auto *sc = returnType->to<IR::Type_SpecializedCanonical>())
baseReturnType = sc->baseType;
const bool factoryOrStaticAssert =
baseReturnType->is<IR::Type_Extern>() || ef->method->name == "static_assert";
if (constArgs && factoryOrStaticAssert) {
// factory extern function calls (those that return extern objects) with constant
// args are compile-time constants.
// The result of a static_assert call is also a compile-time constant.
setCompileTimeConstant(expression);
setCompileTimeConstant(getOriginal<IR::Expression>());
}
}

auto bi = mi->to<BuiltInMethod>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <core.p4>

extern void foo();
extern void bar();
extern bit<8> baz();
action a(){}
action b(){}
control c() {
table t {
actions = { a ; b; }
}
apply {
switch(baz()) {
1 : { foo(); }
4 : { bar(); }
}
t.apply();
}
}

control C();
package top(C c);

top(c()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <core.p4>

extern void foo();
extern void bar();
@pure extern bit<8> baz();
action a(){}
action b(){}
control c() {
table t {
actions = { a ; b; }
}
apply {
switch(baz()) {
1 : { foo(); }
4 : { bar(); }
}
t.apply();
}
}

control C();
package top(C c);

top(c()) main;
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
issue4656_const_fold_generic_switch_label_expr.p4(13): [--Wwarn=mismatch] warning: baz(): constant expression in switch
switch(baz()) {
^^^^^
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <core.p4>

extern void foo();
extern void bar();
extern bit<8> baz();
action a() {
}
action b() {
}
control c() {
table t {
actions = {
a();
b();
@defaultonly NoAction();
}
default_action = NoAction();
}
apply {
switch (baz()) {
8w1: {
foo();
}
8w4: {
bar();
}
}
t.apply();
}
}

control C();
package top(C c);
top(c()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <core.p4>

extern void foo();
extern void bar();
extern bit<8> baz();
control c() {
@name("c.tmp") bit<8> tmp;
@name(".a") action a_0() {
}
@name(".b") action b_0() {
}
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("c.t") table t_0 {
actions = {
a_0();
b_0();
@defaultonly NoAction_1();
}
default_action = NoAction_1();
}
apply {
tmp = baz();
switch (tmp) {
8w1: {
foo();
}
8w4: {
bar();
}
}
t_0.apply();
}
}

control C();
package top(C c);
top(c()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <core.p4>

extern void foo();
extern void bar();
extern bit<8> baz();
control c() {
@name("c.tmp") bit<8> tmp;
@name(".a") action a_0() {
}
@name(".b") action b_0() {
}
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("c.t") table t_0 {
actions = {
a_0();
b_0();
@defaultonly NoAction_1();
}
default_action = NoAction_1();
}
@hidden action switch_0_case() {
}
@hidden action switch_0_case_0() {
}
@hidden action switch_0_case_1() {
}
@hidden table switch_0_table {
key = {
tmp: exact;
}
actions = {
switch_0_case();
switch_0_case_0();
switch_0_case_1();
}
const default_action = switch_0_case_1();
const entries = {
const 8w1 : switch_0_case();
const 8w4 : switch_0_case_0();
}
}
@hidden action issue4661_non_pure_extern_function_const_args14() {
foo();
}
@hidden action issue4661_non_pure_extern_function_const_args15() {
bar();
}
@hidden action act() {
tmp = baz();
}
@hidden table tbl_act {
actions = {
act();
}
const default_action = act();
}
@hidden table tbl_issue4661_non_pure_extern_function_const_args14 {
actions = {
issue4661_non_pure_extern_function_const_args14();
}
const default_action = issue4661_non_pure_extern_function_const_args14();
}
@hidden table tbl_issue4661_non_pure_extern_function_const_args15 {
actions = {
issue4661_non_pure_extern_function_const_args15();
}
const default_action = issue4661_non_pure_extern_function_const_args15();
}
apply {
tbl_act.apply();
switch (switch_0_table.apply().action_run) {
switch_0_case: {
tbl_issue4661_non_pure_extern_function_const_args14.apply();
}
switch_0_case_0: {
tbl_issue4661_non_pure_extern_function_const_args15.apply();
}
switch_0_case_1: {
}
}
t_0.apply();
}
}

control C();
package top(C c);
top(c()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <core.p4>

extern void foo();
extern void bar();
extern bit<8> baz();
action a() {
}
action b() {
}
control c() {
table t {
actions = {
a;
b;
}
}
apply {
switch (baz()) {
1: {
foo();
}
4: {
bar();
}
}
t.apply();
}
}

control C();
package top(C c);
top(c()) main;
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <core.p4>

extern void foo();
extern void bar();
@pure extern bit<8> baz();
action a() {
}
action b() {
}
control c() {
table t {
actions = {
a();
b();
@defaultonly NoAction();
}
default_action = NoAction();
}
apply {
switch (baz()) {
8w1: {
foo();
}
8w4: {
bar();
}
}
t.apply();
}
}

control C();
package top(C c);
top(c()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <core.p4>

extern void foo();
extern void bar();
@pure extern bit<8> baz();
control c() {
@name("c.tmp") bit<8> tmp;
@name(".a") action a_0() {
}
@name(".b") action b_0() {
}
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("c.t") table t_0 {
actions = {
a_0();
b_0();
@defaultonly NoAction_1();
}
default_action = NoAction_1();
}
apply {
tmp = baz();
switch (tmp) {
8w1: {
foo();
}
8w4: {
bar();
}
}
t_0.apply();
}
}

control C();
package top(C c);
top(c()) main;
Loading

0 comments on commit f24aacc

Please sign in to comment.