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

External build #46

Merged
merged 12 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}
max-size: 2G

# --------
# Build and test MLIR. Use cache when available.
Expand All @@ -49,7 +50,6 @@ jobs:
key: ${{ runner.os }}-llvm-${{ steps.get-llvm-hash.outputs.hash }}-${{ steps.get-workflow-hash.outputs.hash }}

- name: Install requirements
if: steps.cache-llvm.outputs.cache-hit != 'true'
run: |
build_tools/ubuntu_install_mlir_requirements.sh

Expand All @@ -64,4 +64,4 @@ jobs:

- name: Build and test P4MLIR
run: |
build_tools/build_p4mlir.sh
build_tools/build_p4c_with_p4mlir_ext.sh
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "third_party/llvm-project"]
path = third_party/llvm-project
url = https://github.com/llvm/llvm-project.git
[submodule "third_party/p4c"]
path = third_party/p4c
url = https://github.com/p4lang/p4c.git
40 changes: 16 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,45 +1,37 @@
cmake_minimum_required(VERSION 3.20.0)
project(p4mlir LANGUAGES CXX C)
project(p4mlir LANGUAGES CXX)

set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)

set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
find_package(MLIR REQUIRED CONFIG)

message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
find_package(MLIR REQUIRED CONFIG)
message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})
# FIXME: This is likely incorrect, though it seems to be used
# only for locating python packages for tests
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})

list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")

include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(HandleLLVMOptions)
else()
# Build via external projects mechanism
set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../mlir)
set(MLIR_INCLUDE_DIR ${MLIR_MAIN_SRC_DIR}/include)
set(MLIR_GENERATED_INCLUDE_DIR ${LLVM_BINARY_DIR}/tools/mlir/include)
set(MLIR_INCLUDE_DIRS "${MLIR_INCLUDE_DIR};${MLIR_GENERATED_INCLUDE_DIR}")
endif()
include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(HandleLLVMOptions)

set(P4MLIR_SOURCE_DIR ${PROJECT_SOURCE_DIR})
set(P4MLIR_BINARY_DIR ${PROJECT_BINARY_DIR})
set(LLVM_RUNTIME_OUTPUT_INTDIR ${PROJECT_BINARY_DIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${PROJECT_BINARY_DIR}/lib)

include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
include_directories(${P4MLIR_SOURCE_DIR}/include)
include_directories(${P4MLIR_BINARY_DIR}/include)
link_directories(${LLVM_BUILD_LIBRARY_DIR})
add_definitions(${LLVM_DEFINITIONS})

add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(test)
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,21 @@ cd third_party/llvm-project/build
ninja check-mlir
```

#### Build P4MLIR from source
*IMPORTANT*: P4C uses C++ RTTI and Exceptions. These are turned off by default
in LLVM and therefore LLVM/MLIR prebuilt binaries that is likely available from
your distribution will be not usable with P4MLIR. One needs to build LLVM/MLIR
from source enabling RTTI (`-DLLVM_ENABLE_RTTI=ON`) and exceptions
(`-DLLVM_ENABLE_EH=ON`).

#### Build P4C with P4MLIR extension from source

```shell
./build_tools/build_p4mlir.sh
./build_tools/build_p4c_with_p4mlir_ext.sh
```

### Testing

```shell
cd build
cd third_party/p4c/build
ninja check-p4mlir
```
6 changes: 5 additions & 1 deletion build_tools/build_mlir.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LLVM_INSTALL_DIR=$P4MLIR_REPO_DIR/install
mkdir -p "$LLVM_BUILD_DIR"
cd "$LLVM_BUILD_DIR"

# Note that P4C uses both RTTI and C++ exceptions, so we need to build LLVM/MLIR having them enabled as well
cmake -G Ninja "$LLVM_REPO_DIR"/llvm \
-DCMAKE_INSTALL_PREFIX="$LLVM_INSTALL_DIR" \
-DLLVM_ENABLE_PROJECTS=mlir \
Expand All @@ -26,7 +27,10 @@ cmake -G Ninja "$LLVM_REPO_DIR"/llvm \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_ENABLE_LLD=ON \
-DLLVM_CCACHE_BUILD=ON \
-DLLVM_INSTALL_UTILS=ON
-DLLVM_INSTALL_UTILS=ON \
-DLLVM_INCLUDE_BENCHMARKS=OFF \
-DLLVM_ENABLE_RTTI=ON \
-DLLVM_ENABLE_EH=ON

ninja
ninja check-mlir
Expand Down
64 changes: 64 additions & 0 deletions build_tools/build_p4c_with_p4mlir_ext.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
#
# Reference:
# - https://mlir.llvm.org/getting_started/
# - https://github.com/llvm/llvm-project/tree/main/mlir/examples/standalone

set -ex

# https://stackoverflow.com/a/246128
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # p4mlir/build_tools
P4MLIR_REPO_DIR=$( cd "$SCRIPT_DIR"/.. &> /dev/null && pwd )

LLVM_REPO_DIR=$P4MLIR_REPO_DIR/third_party/llvm-project
LLVM_BUILD_DIR=$LLVM_REPO_DIR/build
LLVM_INSTALL_DIR=$P4MLIR_REPO_DIR/install

P4C_REPO_DIR=$P4MLIR_REPO_DIR/third_party/p4c
P4C_BUILD_DIR=$P4C_REPO_DIR/build
P4C_EXT_DIR=$P4C_REPO_DIR/extensions

P4C_P4MLIR_EXT_DIR=$P4C_EXT_DIR/p4mlir
P4C_P4MLIR_EXT_SYMLINK=$(realpath -s --relative-to="$(dirname "$P4C_P4MLIR_EXT_DIR")" "$P4MLIR_REPO_DIR")

# Link P4MLIR as P4C extension
mkdir -p "$P4C_EXT_DIR"
if [ ! -d "$P4C_P4MLIR_EXT_DIR" ]; then
ln -s "$P4C_P4MLIR_EXT_SYMLINK" "$P4C_P4MLIR_EXT_DIR"
fi

# Configure CMake flags
CMAKE_FLAGS="-DCMAKE_C_COMPILER=clang"
CMAKE_FLAGS+=" -DCMAKE_CXX_COMPILER=clang++"

# Configure P4C CMake flags
# https://github.com/p4lang/p4c/blob/main/CMakeLists.txt
CMAKE_FLAGS+=" -DENABLE_DOCS=OFF"
CMAKE_FLAGS+=" -DENABLE_GTESTS=ON"
CMAKE_FLAGS+=" -DENABLE_BMV2=OFF"
CMAKE_FLAGS+=" -DENABLE_EBPF=OFF"
CMAKE_FLAGS+=" -DENABLE_UBPF=OFF"
CMAKE_FLAGS+=" -DENABLE_DPDK=OFF"
CMAKE_FLAGS+=" -DENABLE_TOFINO=OFF"
CMAKE_FLAGS+=" -DENABLE_P4TC=OFF"
CMAKE_FLAGS+=" -DENABLE_P4FMT=OFF"
CMAKE_FLAGS+=" -DENABLE_P4TEST=ON"
CMAKE_FLAGS+=" -DENABLE_TEST_TOOLS=OFF"
CMAKE_FLAGS+=" -DENABLE_P4C_GRAPHS=OFF"

# Configure P4MLIR CMake flags
CMAKE_FLAGS+=" -DCMAKE_INSTALL_PREFIX=$LLVM_INSTALL_DIR"
CMAKE_FLAGS+=" -DMLIR_DIR=$LLVM_INSTALL_DIR/lib/cmake/mlir"
CMAKE_FLAGS+=" -DLLVM_EXTERNAL_LIT=$LLVM_BUILD_DIR/bin/llvm-lit"

# Build P4C with P4MLIR extension
mkdir -p "$P4C_BUILD_DIR"
cd "$P4C_BUILD_DIR"
cmake -G Ninja "$P4C_REPO_DIR" $CMAKE_FLAGS
ninja

# Run some tests
ninja check-p4mlir

# Install
ninja install
28 changes: 0 additions & 28 deletions build_tools/build_p4mlir.sh

This file was deleted.

23 changes: 18 additions & 5 deletions build_tools/ubuntu_install_mlir_requirements.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env bash
#
# Reference:
# - https://mlir.llvm.org/getting_started/
# - https://llvm.org/docs/GettingStarted.html#requirements
# Install common build tools

set -ex

Expand All @@ -13,10 +11,25 @@ sudo apt-get install -y \
clang \
lld \
ninja-build \
pkg-config \
python-is-python3 \
python3 \
python3-pip \
zlib1g-dev
python3-pip

pip install --upgrade \
cmake

# Install additional LLVM & MLIR dependencies
# https://llvm.org/docs/GettingStarted.html#requirements
# https://mlir.llvm.org/getting_started/
sudo apt-get install -y \
zlib1g-dev

# Install additional P4C dependencies
# https://github.com/p4lang/p4c/blob/main/README.md#ubuntu-dependencies
sudo apt-get install -y \
bison \
flex \
libboost-dev \
libboost-iostreams-dev \
libfl-dev
3 changes: 3 additions & 0 deletions include/p4mlir/Dialect/P4HIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ mlir_tablegen(P4HIR_Ops.h.inc -gen-op-decls)
mlir_tablegen(P4HIR_Ops.cpp.inc -gen-op-defs)
mlir_tablegen(P4HIR_Types.h.inc -gen-typedef-decls -typedefs-dialect=p4hir)
mlir_tablegen(P4HIR_Types.cpp.inc -gen-typedef-defs -typedefs-dialect=p4hir)
mlir_tablegen(P4HIR_Attrs.h.inc -gen-attrdef-decls -attrdefs-dialect=p4hir)
mlir_tablegen(P4HIR_Attrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=p4hir)

add_public_tablegen_target(P4MLIR_P4HIR_IncGen)
add_dependencies(mlir-headers P4MLIR_P4HIR_IncGen)
14 changes: 14 additions & 0 deletions include/p4mlir/Dialect/P4HIR/P4HIR_Attrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_H
#define P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_H

// We explicitly do not use push / pop for diagnostic in
// order to propagate pragma further on
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include "mlir/IR/BuiltinAttributes.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_Types.h"

#define GET_ATTRDEF_CLASSES
#include "p4mlir/Dialect/P4HIR/P4HIR_Attrs.h.inc"

#endif // P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_H
62 changes: 62 additions & 0 deletions include/p4mlir/Dialect/P4HIR/P4HIR_Attrs.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_TD
#define P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_TD

include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/EnumAttr.td"

include "p4mlir/Dialect/P4HIR/P4HIR_Dialect.td"

class P4HIR_Attr<string name, string attrMnemonic, list<Trait> traits = []>
: AttrDef<P4HIR_Dialect, name, traits> {
let mnemonic = attrMnemonic;
}

//===----------------------------------------------------------------------===//
// BoolAttr
//===----------------------------------------------------------------------===//

def P4HIR_BoolAttr : P4HIR_Attr<"Bool", "bool", [TypedAttrInterface]> {
let summary = "Represent true/false for !p4hir.bool types";
let description = [{
The BoolAttr represents a 'true' or 'false' value.
}];

let parameters = (ins AttributeSelfTypeParameter<"", "BoolType">:$type,
"bool":$value);

let assemblyFormat = [{
`<` $value `>`
}];
}

//===----------------------------------------------------------------------===//
// IntAttr
//===----------------------------------------------------------------------===//

def P4HIR_IntAttr : P4HIR_Attr<"Int", "int", [TypedAttrInterface]> {
let summary = "An Attribute containing a integer value";
let description = [{
An integer attribute is a literal attribute that represents an integral
value of the specified integer type.
}];
let parameters = (ins AttributeSelfTypeParameter<"">:$type, "llvm::APInt":$value);
let builders = [
AttrBuilderWithInferredContext<(ins "mlir::Type":$type, "const llvm::APInt &":$value), [{
return $_get(type.getContext(), type, value);
}]>,
AttrBuilderWithInferredContext<(ins "mlir::Type":$type, "int64_t":$value), [{
BitsType intType = mlir::cast<BitsType>(type);
mlir::APInt apValue(intType.getWidth(), value, intType.isSigned());
return $_get(intType.getContext(), intType, apValue);
}]>,
];
let extraClassDeclaration = [{
int64_t getSInt() const { return getValue().getSExtValue(); }
uint64_t getUInt() const { return getValue().getZExtValue(); }
bool isNullValue() const { return getValue() == 0; }
}];
let genVerifyDecl = 1;
let hasCustomAssemblyFormat = 1;
}

#endif // P4MLIR_DIALECT_P4HIR_P4HIR_ATTRS_TD
6 changes: 5 additions & 1 deletion include/p4mlir/Dialect/P4HIR/P4HIR_Dialect.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#ifndef P4MLIR_DIALECT_P4HIR_P4HIR_DIALECT_H
#define P4MLIR_DIALECT_P4HIR_P4HIR_DIALECT_H

// We explicitly do not use push / pop for diagnostic in
// order to propagate pragma further on
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Dialect.h"

#include "p4mlir/Dialect/P4HIR/P4HIR_Dialect.h.inc"

#endif // P4MLIR_DIALECT_P4HIR_P4HIR_DIALECT_H
#endif // P4MLIR_DIALECT_P4HIR_P4HIR_DIALECT_H
11 changes: 10 additions & 1 deletion include/p4mlir/Dialect/P4HIR/P4HIR_Dialect.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ def P4HIR_Dialect : Dialect {
}];
let cppNamespace = "::P4::P4MLIR::P4HIR";

let useDefaultTypePrinterParser = 1;
let useDefaultTypePrinterParser = 0;
let useDefaultAttributePrinterParser = 1;

let extraClassDeclaration = [{
mlir::Type parseType(mlir::DialectAsmParser &parser) const override;
void printType(mlir::Type type, mlir::DialectAsmPrinter &printer) const override;

void registerAttributes();
void registerTypes();
}];
}

#endif // P4MLIR_DIALECT_P4HIR_P4HIR_DIALECT_TD
4 changes: 4 additions & 0 deletions include/p4mlir/Dialect/P4HIR/P4HIR_Ops.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef P4MLIR_DIALECT_P4HIR_P4HIR_OPS_H
#define P4MLIR_DIALECT_P4HIR_P4HIR_OPS_H

// We explicitly do not use push / pop for diagnostic in
// order to propagate pragma further on
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
Expand Down
Loading