Skip to content

Commit ff77d77

Browse files
authored
Merge branch 'main' into vineet-work
2 parents fde4323 + 9ca48e2 commit ff77d77

27 files changed

+373
-165
lines changed

.github/workflows/ci-ubuntu-p4tc-stf.yml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
ENABLE_GTESTS: ${{ matrix.gtest }}
2222
CMAKE_UNITY_BUILD: ${{ matrix.unity }}
2323
BUILD_GENERATOR: Ninja
24+
INSTALL_STF_P4TC_DEPENDENCIES: ON
2425
steps:
2526
- uses: actions/checkout@v4
2627
with:

backends/tc/CMakeLists.txt

-43
Original file line numberDiff line numberDiff line change
@@ -14,49 +14,6 @@
1414
# and limitations under the License.
1515
#*****************************************************************************/
1616

17-
if(NOT APPLE)
18-
# Fetch and declare the libbpf library. Print out download state while setting up libbpf.
19-
set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET})
20-
set(FETCHCONTENT_QUIET OFF)
21-
fetchcontent_declare(
22-
p4cbpfrepo
23-
URL https://github.com/libbpf/libbpf/archive/refs/tags/v1.5.0.tar.gz
24-
URL_HASH SHA256=53492aff6dd47e4da04ef5e672d753b9743848bdb38e9d90eafbe190b7983c44
25-
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/runtime/libbpf
26-
USES_TERMINAL_DOWNLOAD TRUE
27-
GIT_PROGRESS TRUE
28-
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
29-
)
30-
fetchcontent_makeavailable(p4cbpfrepo)
31-
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})
32-
message("Building libbpf...")
33-
execute_process(
34-
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/runtime/build-libbpf
35-
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
36-
COMMAND_ECHO STDOUT
37-
)
38-
message("Done with setting up libbpf for P4C.")
39-
40-
fetchcontent_declare(
41-
iproute2repo
42-
URL https://github.com/p4tc-dev/iproute2-p4tc-pub/archive/refs/tags/release-v17-rc6.tar.gz
43-
URL_HASH SHA256=624c32a571f9f30d1070d9b23e96121ac79f9273df9ff6db4ee6d034ab983c5d
44-
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/runtime/iproute2-p4tc-pub
45-
USES_TERMINAL_DOWNLOAD TRUE
46-
GIT_PROGRESS TRUE
47-
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
48-
)
49-
fetchcontent_makeavailable(iproute2repo)
50-
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})
51-
message("Building iproute2...")
52-
execute_process(
53-
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/runtime/build-iproute2 ${CMAKE_CURRENT_SOURCE_DIR}/runtime
54-
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
55-
COMMAND_ECHO STDOUT
56-
)
57-
message("Done with setting up iproute2 for P4C.")
58-
endif()
59-
6017
set(P4TC_BACKEND_SOURCES
6118
backend.cpp
6219
ebpfCodeGen.cpp

frontends/common/constantFolding.cpp

+34-2
Original file line numberDiff line numberDiff line change
@@ -1108,15 +1108,47 @@ const IR::Node *DoConstantFolding::postorder(IR::SelectExpression *expression) {
11081108
return result;
11091109
}
11101110

1111+
class FilterLikelyAnnot : public Transform {
1112+
IR::Statement *preorder(IR::Statement *stmt) {
1113+
prune();
1114+
return stmt;
1115+
}
1116+
IR::BlockStatement *preorder(IR::BlockStatement *stmt) {
1117+
prune();
1118+
visit(stmt->annotations, "annotations");
1119+
return stmt;
1120+
}
1121+
IR::Annotation *preorder(IR::Annotation *annot) {
1122+
prune();
1123+
if (annot->name == IR::Annotation::likelyAnnotation) return nullptr;
1124+
if (annot->name == IR::Annotation::unlikelyAnnotation) {
1125+
// FIXME -- disable this warning due to worries it will trigger too often
1126+
warning(ErrorType::WARN_BRANCH_HINT, "ignoring %1% on always taken statement", annot);
1127+
return nullptr;
1128+
}
1129+
return annot;
1130+
}
1131+
};
1132+
11111133
const IR::Node *DoConstantFolding::postorder(IR::IfStatement *ifstmt) {
11121134
if (auto cond = ifstmt->condition->to<IR::BoolLiteral>()) {
11131135
if (cond->value) {
1114-
return ifstmt->ifTrue;
1136+
if (auto blk = ifstmt->ifFalse ? ifstmt->ifFalse->to<IR::BlockStatement>() : nullptr) {
1137+
if (auto annot = blk->getAnnotation(IR::Annotation::likelyAnnotation))
1138+
warning(ErrorType::WARN_BRANCH_HINT, "ignoring %1% on never taken statement",
1139+
annot);
1140+
}
1141+
return ifstmt->ifTrue->apply(FilterLikelyAnnot());
11151142
} else {
1143+
if (auto blk = ifstmt->ifTrue->to<IR::BlockStatement>()) {
1144+
if (auto annot = blk->getAnnotation(IR::Annotation::likelyAnnotation))
1145+
warning(ErrorType::WARN_BRANCH_HINT, "ignoring %1% on never taken statement",
1146+
annot);
1147+
}
11161148
if (ifstmt->ifFalse == nullptr) {
11171149
return new IR::EmptyStatement(ifstmt->srcInfo);
11181150
} else {
1119-
return ifstmt->ifFalse;
1151+
return ifstmt->ifFalse->apply(FilterLikelyAnnot());
11201152
}
11211153
}
11221154
}

frontends/p4/dontcareArgs.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ class DontcareArgs : public Transform, public ResolutionContext {
4040
IR::IndexedVector<IR::StatOrDecl> body;
4141
for (auto d : toAdd) body.push_back(d);
4242
body.append(function->body->components);
43-
function->body = new IR::BlockStatement(function->body->srcInfo, body);
43+
function->body =
44+
new IR::BlockStatement(function->body->srcInfo, function->body->annotations, body);
4445
toAdd.clear();
4546
return function;
4647
}
4748
const IR::Node *postorder(IR::P4Action *action) override {
4849
IR::IndexedVector<IR::StatOrDecl> body;
4950
for (auto d : toAdd) body.push_back(d);
5051
body.append(action->body->components);
51-
action->body = new IR::BlockStatement(action->body->srcInfo, body);
52+
action->body =
53+
new IR::BlockStatement(action->body->srcInfo, action->body->annotations, body);
5254
toAdd.clear();
5355
return action;
5456
}

frontends/p4/parseAnnotations.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ namespace P4 {
2121
ParseAnnotations::HandlerMap ParseAnnotations::standardHandlers() {
2222
return {
2323
// These annotations have empty bodies.
24-
PARSE_EMPTY(IR::Annotation::tableOnlyAnnotation),
24+
PARSE_EMPTY(IR::Annotation::atomicAnnotation),
2525
PARSE_EMPTY(IR::Annotation::defaultOnlyAnnotation),
2626
PARSE_EMPTY(IR::Annotation::hiddenAnnotation),
27-
PARSE_EMPTY(IR::Annotation::atomicAnnotation),
27+
PARSE_EMPTY(IR::Annotation::likelyAnnotation),
28+
PARSE_EMPTY(IR::Annotation::noSideEffectsAnnotation),
2829
PARSE_EMPTY(IR::Annotation::optionalAnnotation),
2930
PARSE_EMPTY(IR::Annotation::pureAnnotation),
30-
PARSE_EMPTY(IR::Annotation::noSideEffectsAnnotation),
31+
PARSE_EMPTY(IR::Annotation::tableOnlyAnnotation),
32+
PARSE_EMPTY(IR::Annotation::unlikelyAnnotation),
3133
PARSE_EMPTY("disable_optimization"_cs),
3234
PARSE_EMPTY("unroll"_cs),
3335
PARSE_EMPTY("nounroll"_cs),

frontends/p4/removeParameters.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ const IR::Node *DoRemoveActionParameters::postorder(IR::P4Action *action) {
155155
body.append(postamble);
156156

157157
action->parameters = new IR::ParameterList(action->parameters->srcInfo, std::move(leftParams));
158-
action->body = new IR::BlockStatement(action->body->srcInfo, std::move(body));
158+
action->body =
159+
new IR::BlockStatement(action->body->srcInfo, action->body->annotations, std::move(body));
159160
LOG1("To replace " << dbp(action));
160161
result->push_back(action);
161162
return result;

frontends/p4/removeReturns.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ const IR::Node *DoRemoveReturns::preorder(IR::ExitStatement *statement) {
215215
}
216216

217217
const IR::Node *DoRemoveReturns::preorder(IR::BlockStatement *statement) {
218-
auto block = new IR::BlockStatement;
218+
auto block = new IR::BlockStatement(statement->srcInfo, statement->annotations);
219219
auto currentBlock = block;
220220
TernaryBool ret = TernaryBool::No;
221221
for (auto s : statement->components) {

frontends/p4/sideEffects.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ const IR::Node *DoSimplifyExpressions::preorder(IR::MethodCallExpression *mce) {
580580

581581
const IR::Node *DoSimplifyExpressions::postorder(IR::Function *function) {
582582
if (toInsert.empty()) return function;
583-
auto body = new IR::BlockStatement(function->body->srcInfo);
583+
auto body = new IR::BlockStatement(function->body->srcInfo, function->body->annotations);
584584
for (auto a : toInsert) body->push_back(a);
585585
for (auto s : function->body->components) body->push_back(s);
586586
function->body = body;
@@ -604,7 +604,7 @@ const IR::Node *DoSimplifyExpressions::postorder(IR::P4Control *control) {
604604

605605
const IR::Node *DoSimplifyExpressions::postorder(IR::P4Action *action) {
606606
if (toInsert.empty()) return action;
607-
auto body = new IR::BlockStatement(action->body->srcInfo);
607+
auto body = new IR::BlockStatement(action->body->srcInfo, action->body->annotations);
608608
for (auto a : toInsert) body->push_back(a);
609609
for (auto s : action->body->components) body->push_back(s);
610610
action->body = body;

frontends/p4/simplify.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ namespace P4 {
2424
const IR::Node *DoSimplifyControlFlow::postorder(IR::BlockStatement *statement) {
2525
LOG3("Visiting " << dbp(getOriginal()));
2626
if (statement->hasAnnotations() &&
27-
!(foldInlinedFrom && statement->hasOnlyAnnotation(IR::Annotation::inlinedFromAnnotation)))
28-
return statement;
27+
!(foldInlinedFrom && statement->hasOnlyAnnotation(IR::Annotation::inlinedFromAnnotation))) {
28+
if (auto *pblk = getParent<IR::BlockStatement>()) {
29+
for (auto *annot : statement->annotations) {
30+
if (auto *p = pblk->getAnnotation(annot->name); !p || !p->equiv(*annot))
31+
return statement;
32+
}
33+
} else {
34+
return statement;
35+
}
36+
}
2937
auto parent = getContext()->node;
3038
CHECK_NULL(parent);
3139
if (parent->is<IR::SwitchCase>() || parent->is<IR::P4Control>() || parent->is<IR::Function>() ||

ir/annotations.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ const cstring IR::Annotation::fieldListAnnotation = "field_list"_cs;
3939
const cstring IR::Annotation::debugLoggingAnnotation = "__debug"_cs;
4040
const cstring IR::Annotation::disableOptimizationAnnotation = "disable_optimization"_cs;
4141
const cstring IR::Annotation::inlinedFromAnnotation = "inlinedFrom"_cs;
42+
const cstring IR::Annotation::likelyAnnotation = "likely"_cs;
43+
const cstring IR::Annotation::unlikelyAnnotation = "unlikely"_cs;
4244

4345
namespace Annotations {
4446
void addIfNew(Vector<Annotation> &annotations, cstring name, const Expression *expr,

ir/base.def

+2-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ class Annotation {
291291
static const cstring debugLoggingAnnotation; /// Used by compiler implementer to limit debug log to the annotated IR context.
292292
static const cstring disableOptimizationAnnotation; /// annotation to disable certain optimization
293293
static const cstring inlinedFromAnnotation; /// annotation to mark block of inlined function
294-
294+
static const cstring likelyAnnotation; /// annotation for likely taken blocks/branchs
295+
static const cstring unlikelyAnnotation; /// annotation for likely not taken blocks/branchs
295296
toString{ return absl::StrCat("@", name); }
296297
validate{
297298
BUG_CHECK(!name.name.isNullOrEmpty(), "empty annotation name");

ir/json_generator.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ class JSONGenerator {
135135
break;
136136
case OBJ_END:
137137
break;
138-
default:
138+
case TOP:
139+
case VEC_START:
140+
case VEC_MID:
141+
case OBJ_AFTERTAG:
139142
BUG("invalid json output state in end_object");
140143
break;
141144
}

lib/error_catalog.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818

1919
#include <map>
2020

21+
#include "error_reporter.h"
2122
#include "lib/cstring.h"
2223

2324
namespace P4 {
@@ -71,6 +72,7 @@ const int ErrorType::WARN_ENTRIES_OUT_OF_ORDER = 1022;
7172
const int ErrorType::WARN_MULTI_HDR_EXTRACT = 1023;
7273
const int ErrorType::WARN_EXPRESSION = 1024;
7374
const int ErrorType::WARN_DUPLICATE = 1025;
75+
const int ErrorType::WARN_BRANCH_HINT = 1026;
7476

7577
// ------ Info messages -----------
7678
const int ErrorType::INFO_INFERRED = WARN_MAX + 1;
@@ -124,9 +126,16 @@ std::map<int, cstring> ErrorCatalog::errorCatalog = {
124126
{ErrorType::WARN_MULTI_HDR_EXTRACT, "multi_header_extract"_cs},
125127
{ErrorType::WARN_EXPRESSION, "expr"_cs},
126128
{ErrorType::WARN_DUPLICATE, "duplicate"_cs},
129+
{ErrorType::WARN_BRANCH_HINT, "branch"_cs},
127130

128131
// Info messages
129132
{ErrorType::INFO_INFERRED, "inferred"_cs},
130133
{ErrorType::INFO_PROGRESS, "progress"_cs}};
131134

135+
void ErrorCatalog::initReporter(ErrorReporter &reporter) {
136+
// by default, ignore warnings about branch hints -- user can turn them
137+
// on with --Wwarn=branch
138+
reporter.setDiagnosticAction("branch"_cs, DiagnosticAction::Ignore);
139+
}
140+
132141
} // namespace P4

lib/error_catalog.h

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace P4 {
2828

2929
using MessageType = ErrorMessage::MessageType;
3030

31+
class ErrorReporter;
32+
3133
/// enumerate supported errors
3234
/// It is a class and not an enum class because in C++11 you can't extend an enum class
3335
class ErrorType {
@@ -85,6 +87,7 @@ class ErrorType {
8587
static const int WARN_MULTI_HDR_EXTRACT; // same header may be extracted more than once
8688
static const int WARN_EXPRESSION; // expression related warnings
8789
static const int WARN_DUPLICATE; // duplicate objects
90+
static const int WARN_BRANCH_HINT; // branch frequency/likely hints
8891
// Backends should extend this class with additional warnings in the range 1500-2141.
8992
static const int WARN_MIN_BACKEND = 1500; // first allowed backend warning code
9093
static const int WARN_MAX = 2141; // last allowed warning code
@@ -155,6 +158,8 @@ class ErrorCatalog {
155158
return error;
156159
}
157160

161+
void initReporter(ErrorReporter &reporter);
162+
158163
private:
159164
ErrorCatalog() {}
160165

lib/error_reporter.h

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class ErrorReporter {
9191
defaultInfoDiagnosticAction(DiagnosticAction::Info),
9292
defaultWarningDiagnosticAction(DiagnosticAction::Warn) {
9393
outputstream = &std::cerr;
94+
ErrorCatalog::getCatalog().initReporter(*this);
9495
}
9596
virtual ~ErrorReporter() = default;
9697

midend/flattenUnions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ const IR::Node *HandleValidityHeaderUnion::postorder(IR::MethodCallStatement *mc
169169

170170
const IR::Node *HandleValidityHeaderUnion::postorder(IR::P4Action *action) {
171171
if (toInsert.empty()) return action;
172-
auto body = new IR::BlockStatement(action->body->srcInfo);
172+
auto body = new IR::BlockStatement(action->body->srcInfo, action->body->annotations);
173173
for (auto a : toInsert) body->push_back(a);
174174
for (auto s : action->body->components) body->push_back(s);
175175
action->body = body;
@@ -380,7 +380,7 @@ const IR::Node *DoFlattenHeaderUnion::postorder(IR::P4Action *action) {
380380
}
381381
}
382382
}
383-
auto body = new IR::BlockStatement(action->body->srcInfo);
383+
auto body = new IR::BlockStatement(action->body->srcInfo, action->body->annotations);
384384
for (auto a : actiondecls) body->push_back(a);
385385
action->body = body;
386386
return action;

midend/removeExits.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const IR::Node *DoRemoveExits::preorder(IR::P4Control *control) {
128128
}
129129

130130
const IR::Node *DoRemoveExits::preorder(IR::BlockStatement *statement) {
131-
auto block = new IR::BlockStatement;
131+
auto block = new IR::BlockStatement(statement->srcInfo, statement->annotations);
132132
auto currentBlock = block;
133133
TernaryBool ret = TernaryBool::No;
134134
for (auto s : statement->components) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <core.p4>
2+
3+
@command_line("--Wwarn=branch")
4+
5+
struct Headers {
6+
bit<8> a;
7+
bit<8> b;
8+
}
9+
10+
control ingress(inout Headers h) {
11+
apply {
12+
if (true) @likely {
13+
h.a = 0;
14+
}
15+
if (true) @unlikely {
16+
h.b = 0;
17+
}
18+
if (h.a != h.a) @likely {
19+
h.b = 1;
20+
}
21+
}
22+
}
23+
24+
control c<T>(inout T d);
25+
package top<T>(c<T> _c);
26+
27+
top(ingress()) main;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <core.p4>
2+
3+
@command_line("--Wwarn=branch") struct Headers {
4+
bit<8> a;
5+
bit<8> b;
6+
}
7+
8+
control ingress(inout Headers h) {
9+
apply {
10+
h.a = 8w0;
11+
h.b = 8w0;
12+
if (h.a != h.a) @likely {
13+
h.b = 8w1;
14+
}
15+
}
16+
}
17+
18+
control c<T>(inout T d);
19+
package top<T>(c<T> _c);
20+
top<Headers>(ingress()) main;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <core.p4>
2+
3+
@command_line("--Wwarn=branch") struct Headers {
4+
bit<8> a;
5+
bit<8> b;
6+
}
7+
8+
control ingress(inout Headers h) {
9+
apply {
10+
h.a = 8w0;
11+
h.b = 8w0;
12+
if (h.a != h.a) @likely {
13+
h.b = 8w1;
14+
}
15+
}
16+
}
17+
18+
control c<T>(inout T d);
19+
package top<T>(c<T> _c);
20+
top<Headers>(ingress()) main;

0 commit comments

Comments
 (0)