Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/komaljai/p4c
Browse files Browse the repository at this point in the history
  • Loading branch information
komaljai committed Apr 10, 2024
2 parents ebedafc + b34e458 commit 183ba56
Show file tree
Hide file tree
Showing 105 changed files with 14,067 additions and 10,417 deletions.
37 changes: 16 additions & 21 deletions .github/workflows/ci-static-build-test.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: "static-build-test-p4c"

on:
schedule:
# Every day on midnight UTC
- cron: "0 0 * * *"
push:
branches: [main]
pull_request:
branches: [main]
merge_group:
branches: [main]

# Cancel any preceding run on the pull request.
concurrency:
Expand All @@ -16,11 +17,21 @@ concurrency:
jobs:
# Build a p4c release on Ubuntu 20.04.
build-linux:
# Only run on pull requests with the "run-static" label.
if: ${{ github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'run-static') }}
# Note: Actions have no real ternary condition operator, but this hack works because non-empty
# strings are true.
name: "Dynamic ${{ matrix.dynamic.glibc == 'ON' && 'glibc' || 'stdlib' }}"
strategy:
fail-fast: false
matrix:
dynamic: [{glibc: ON, stdlib: OFF}, {glibc: OFF, stdlib: ON}]
runs-on: ubuntu-20.04
env:
IMAGE_TYPE: test
CMAKE_UNITY_BUILD: ON
BUILD_STATIC_RELEASE_SANS_GLIBC: ON
STATIC_BUILD_WITH_DYNAMIC_GLIBC: "${{ matrix.dynamic.glibc }}"
STATIC_BUILD_WITH_DYNAMIC_STDLIB: "${{ matrix.dynamic.stdlib }}"
ENABLE_TEST_TOOLS: ON
BUILD_GENERATOR: Ninja
steps:
Expand All @@ -38,21 +49,5 @@ jobs:
name: Build (Ubuntu 20.04)
run: |
sudo -E tools/ci-build.sh
# Disabling these checks until we find a better way to build a fully static binary.
# ldd ./build/p4c-bm2-psa 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4c-bm2-ss 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4c-dpdk 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4c-ebpf 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4c-pna-p4tc 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4c-ubpf 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4test 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
# ldd ./build/p4testgen 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
! ldd ./build/p4c-bm2-psa 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4c-bm2-ss 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4c-dpdk 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4c-ebpf 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4c-pna-p4tc 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4c-ubpf 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4test 2>&1 | grep -E "libgc|libboost_iostreams"
! ldd ./build/p4testgen 2>&1 | grep -E "libgc|libboost_iostreams"
./tools/ci-check-static.sh ./build/p4c-bm2-ss ./build/p4c-dpdk ./build/p4c-ebpf \
./build/p4c-pna-p4tc ./build/p4c-ubpf ./build/p4test ./build/p4testgen
28 changes: 21 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,15 @@ OPTION (ENABLE_GC "Use libgc" ON)
OPTION (ENABLE_MULTITHREAD "Use multithreading" OFF)
OPTION (ENABLE_WERROR "Treat warnings as errors" OFF)
OPTION (ENABLE_SANITIZERS "Enable sanitizers" OFF)
OPTION (BUILD_STATIC_RELEASE_SANS_GLIBC
"Build a (mostly) statically linked release binary. Glibc is linked dynamically." OFF
)
if (BUILD_STATIC_RELEASE_SANS_GLIBC)
OPTION (STATIC_BUILD_WITH_DYNAMIC_GLIBC "Build a (mostly) statically linked release binary. \
Glibc is linked dynamically. WARNING: This only works if all dependencies that depend on the C++ \
standard library can be linked statically, otherwise the build will likely be broken and it will \
likely depend on the standard libary anyway. If you have some non-static C++ dependencies, use \
STATIC_BUILD_WITH_DYNAMIC_STDLIB." OFF)
OPTION (STATIC_BUILD_WITH_DYNAMIC_STDLIB "Build a (mostly) statically linked release binary. \
Glibc and C++ standard library is linked dynamically." OFF)

if (STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB)
# We want to optimize the binary size for a static release binary by default.
set (_ENABLE_LTO_DEFAULT ON)
else()
Expand Down Expand Up @@ -130,9 +135,15 @@ endif ()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Set the required options for a (mostly) static release build.
if(BUILD_STATIC_RELEASE_SANS_GLIBC)
if(STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB)
if (STATIC_BUILD_WITH_DYNAMIC_GLIBC AND STATIC_BUILD_WITH_DYNAMIC_STDLIB)
message(WARNING "Both STATIC_BUILD_WITH_DYNAMIC_GLIBC and STATIC_BUILD_WITH_DYNAMIC_STDLIB "
"enabled at once; using 'DYNAMIC_STDLIB' settings (dynamic glibc and c++ standard library).")
endif()
message(STATUS "Building static release binaries")
message(WARNING "glibc is linked dynamically in current static builds.")
if (NOT STATIC_BUILD_WITH_DYNAMIC_STDLIB)
message(WARNING "glibc is linked dynamically in current static builds.")
endif()
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
# Link Boost statically
Expand All @@ -146,8 +157,11 @@ if(BUILD_STATIC_RELEASE_SANS_GLIBC)
# and see whether static linking improves on Linux.
# Do not bring in dynamic libstdcc and libgcc
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -Wl,-z,muldefs"
"${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -Wl,-z,muldefs"
)
if (NOT STATIC_BUILD_WITH_DYNAMIC_STDLIB)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
endif()
add_definitions(-DP4C_STATIC_BUILD)
endif()

Expand Down
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ ARG CMAKE_UNITY_BUILD=ON
# Whether to enable translation validation
ARG VALIDATION=OFF
# This creates a release build that includes link time optimization and links
# all libraries statically.
ARG BUILD_STATIC_RELEASE_SANS_GLIBC=OFF
# all libraries except for glibc statically.
ARG STATIC_BUILD_WITH_DYNAMIC_GLIBC=OFF
# This creates a release build that includes link time optimization and links
# all libraries except for glibc and libstdc++ statically.
ARG STATIC_BUILD_WITH_DYNAMIC_STDLIB=OFF
# No questions asked during package installation.
ARG DEBIAN_FRONTEND=noninteractive
# Whether to install dependencies required to run PTF-ebpf tests
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,31 @@
[![Validation](https://github.com/p4lang/p4c/actions/workflows/ci-validation-nightly.yml/badge.svg)](https://github.com/p4lang/p4c/actions/workflows/ci-validation-nightly.yml)
[![Docker Container](https://github.com/p4lang/p4c/actions/workflows/ci-container-image.yml/badge.svg)](https://github.com/p4lang/p4c/actions/workflows/ci-container-image.yml)

# p4c

p4c
=================

* [Getting started](#getting-started)
* [Installing packaged versions of p4c](#installing-packaged-versions-of-p4c)
* [Installing p4c from source](#installing-p4c-from-source)
* [Dependencies](#dependencies)
* [Ubuntu dependencies](#ubuntu-dependencies)
* [Fedora dependencies](#fedora-dependencies)
* [macOS dependencies](#macos-dependencies)
* [Garbage collector](#garbage-collector)
* [Crash dumps](#crash-dumps)
* [Development tools](#development-tools)
* [Git setup](#git-setup)
* [Docker](#docker)
* [Bazel](#bazel)
* [Build system](#build-system)
* [Defining new CMake targets](#defining-new-cmake-targets)
* [Known issues](#known-issues)
* [Frontend](#frontend)
* [Backends](#backends)
* [How to Contribute](#how-to-contribute)
* [P4 Compiler Onboarding](#p4-compiler-onboarding)
* [Contact](#contact)

p4c is a reference compiler for the P4 programming language.
It supports both P4-14 and P4-16; you can find more information about P4
Expand Down
9 changes: 7 additions & 2 deletions backends/bmv2/common/JsonObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -101,7 +101,12 @@ void JsonObjects::add_meta_info() {
meta->emplace("compiler", "https://github.com/p4lang/p4c");
toplevel->emplace("__meta__", meta);
}

/// Create a header type in json.
/// @param name header name
/// @param type header type
/// @param max_length maximum length for a header with varbit fields;
/// if 0 header does not contain varbit fields
/// @param fields a JsonArray for the fields in the header
unsigned JsonObjects::add_header_type(const cstring &name, Util::JsonArray *&fields,
unsigned max_length) {
std::string sname(name, name.size());
Expand Down
2 changes: 1 addition & 1 deletion backends/bmv2/common/JsonObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class JsonObjects {
/// @param name The name of the primitive.
/// @return A pointer to the newly created primitive JsonObject.
Util::JsonObject *create_primitive(Util::JsonArray *parent, cstring name);

/// Given a field list id returns the array of values called "elements".
/// @brief Retrieves the contents of a field list identified by its ID.
/// @param id The ID of the field list.
/// @return A pointer to the JsonArray containing the field list's elements, or nullptr if not
Expand Down
4 changes: 1 addition & 3 deletions backends/bmv2/common/annotations.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ limitations under the License.

namespace BMV2 {

/*
* Parses BMV2-specific annotations.
*/
/// Parses BMV2-specific annotations.
class ParseAnnotations : public P4::ParseAnnotations {
public:
ParseAnnotations()
Expand Down
42 changes: 18 additions & 24 deletions backends/bmv2/common/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ enum block_t {

class ExpressionConverter;

// Backend is a the base class for SimpleSwitchBackend and PortableSwitchBackend.
/// Backend is a the base class for SimpleSwitchBackend and PortableSwitchBackend.
class Backend {
public:
BMV2Options &options;
Expand All @@ -81,15 +81,13 @@ class Backend {
virtual void convert(const IR::ToplevelBlock *block) = 0;
};

/**
This class implements a policy suitable for the SynthesizeActions pass.
The policy is: do not synthesize actions for the controls whose names
are in the specified set.
For example, we expect that the code in the deparser will not use any
tables or actions.
*/
/// This class implements a policy suitable for the SynthesizeActions pass.
// The policy is: do not synthesize actions for the controls whose names
/// are in the specified set.
/// For example, we expect that the code in the deparser will not use any
/// tables or actions.
class SkipControls : public P4::ActionSynthesisPolicy {
// set of controls where actions are not synthesized
/// set of controls where actions are not synthesized
const std::set<cstring> *skip;

public:
Expand All @@ -100,13 +98,11 @@ class SkipControls : public P4::ActionSynthesisPolicy {
}
};

/**
This class implements a policy suitable for the RemoveComplexExpression pass.
The policy is: only remove complex expression for the controls whose names
are in the specified set.
For example, we expect that the code in ingress and egress will have complex
expression removed.
*/
/// This class implements a policy suitable for the RemoveComplexExpression pass.
/// The policy is: only remove complex expression for the controls whose names
/// are in the specified set.
/// For example, we expect that the code in ingress and egress will have complex
/// expression removed.
class ProcessControls : public P4::RemoveComplexExpressionsPolicy {
const std::set<cstring> *process;

Expand All @@ -120,17 +116,15 @@ class ProcessControls : public P4::RemoveComplexExpressionsPolicy {
}
};

/**
This pass adds @name annotations to all fields of the user metadata
structure so that they do not clash with fields of the headers
structure. This is necessary because both of them become global
objects in the output json.
*/
/// This pass adds @name annotations to all fields of the user metadata
/// structure so that they do not clash with fields of the headers
/// structure. This is necessary because both of them become global
/// objects in the output json.
class RenameUserMetadata : public Transform {
P4::ReferenceMap *refMap;
const IR::Type_Struct *userMetaType;
// Used as a prefix for the fields of the userMetadata structure
// and also as a name for the userMetadata type clone.
/// Used as a prefix for the fields of the userMetadata structure
/// and also as a name for the userMetadata type clone.
cstring namePrefix;
bool renamed = false;

Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/common/controlFlowGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ bool CFG::EdgeSet::checkSame(const CFG::EdgeSet &other) const {
return true;
}

// We check whether a table always jumps to the same destination,
// even if it appears multiple times in the CFG.
/// We check whether a table always jumps to the same destination,
/// even if it appears multiple times in the CFG.
bool CFG::checkMergeable(std::set<TableNode *> nodes) const {
TableNode *first = nullptr;
for (auto tn : nodes) {
Expand Down
8 changes: 2 additions & 6 deletions backends/bmv2/common/controlFlowGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,14 @@ class CFG final : public IHasDbPrint {
enum class EdgeType { Unconditional, True, False, Label };

public:
/**
* A CFG Edge; can be an in-edge or out-edge.
*/
/// A CFG Edge; can be an in-edge or out-edge.
class Edge final {
protected:
EdgeType type;
Edge(Node *node, EdgeType type, cstring label) : type(type), endpoint(node), label(label) {}

public:
/**
* The destination node of the edge. The source node is not known by the edge
*/
/// The destination node of the edge. The source node is not known by the edge
Node *endpoint;
cstring label; // only present if type == Label

Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/common/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,8 @@ bool ExpressionConverter::isArrayIndexRuntime(const IR::Expression *e) {
return false;
}

// doFixup = true -> insert masking operations for proper arithmetic implementation
// see below for wrap
/// doFixup = true -> insert masking operations for proper arithmetic implementation
/// see below for wrap.
Util::IJson *ExpressionConverter::convert(const IR::Expression *e, bool doFixup, bool wrap,
bool convertBool) {
const IR::Expression *expr = e;
Expand Down
38 changes: 17 additions & 21 deletions backends/bmv2/common/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ limitations under the License.

namespace BMV2 {

/**
Inserts casts and narrowing operations to implement correctly the semantics of
P4-16 arithmetic on top of unbounded precision arithmetic. For example,
in P4-16 adding two 32-bit values should produce a 32-bit value, but using
unbounded arithmetic, as in BMv2, it could produce a 33-bit value.
*/
/// Inserts casts and narrowing operations to implement correctly the semantics of
/// P4-16 arithmetic on top of unbounded precision arithmetic. For example,
/// in P4-16 adding two 32-bit values should produce a 32-bit value, but using
/// unbounded arithmetic, as in BMv2, it could produce a 33-bit value.
class ArithmeticFixup : public Transform {
P4::TypeMap *typeMap;

Expand Down Expand Up @@ -86,26 +84,24 @@ class ExpressionConverter : public Inspector {
/// Non-null if the expression refers to a parameter from the enclosing control
const IR::Parameter *enclosingParamReference(const IR::Expression *expression);

// Each architecture typically has some special parameters that requires
// special handling. The examples are standard_metadata in the v1model and
// packet path related metadata in PSA. Each target should subclass the
// ExpressionConverter and implement this function with target-specific
// handling code to deal with the special parameters.
/// Each architecture typically has some special parameters that requires
/// special handling. The examples are standard_metadata in the v1model and
/// packet path related metadata in PSA. Each target should subclass the
/// ExpressionConverter and implement this function with target-specific
/// handling code to deal with the special parameters.
virtual Util::IJson *convertParam(const IR::Parameter *param, cstring fieldName) = 0;

Util::IJson *get(const IR::Expression *expression) const;
Util::IJson *fixLocal(Util::IJson *json);

/**
* Convert an expression into JSON
* @param e expression to convert
* @param doFixup Insert masking operations for operands to ensure that the result
* matches the specification. BMv2 does arithmetic using unbounded
* precision, but the spec requires fixed precision, specified by the types.
* @param wrap Wrap the result into an additiona JSON expression block.
* See the BMv2 JSON spec.
* @param convertBool Wrap the result into a cast from boolean to data (b2d JSON).
*/
/// Convert an expression into JSON
/// @param e expression to convert
/// @param doFixup Insert masking operations for operands to ensure that the result
/// matches the specification. BMv2 does arithmetic using unbounded
/// precision, but the spec requires fixed precision, specified by the types.
/// @param wrap Wrap the result into an additiona JSON expression block.
/// See the BMv2 JSON spec.
/// @param convertBool Wrap the result into a cast from boolean to data (b2d JSON).
Util::IJson *convert(const IR::Expression *e, bool doFixup = true, bool wrap = true,
bool convertBool = false);
Util::IJson *convertLeftValue(const IR::Expression *e);
Expand Down
Loading

0 comments on commit 183ba56

Please sign in to comment.