Skip to content

Commit

Permalink
Add basic unary operations
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Korobeynikov <[email protected]>
  • Loading branch information
asl committed Feb 10, 2025
1 parent 079cb86 commit ccf0f2e
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 17 deletions.
36 changes: 36 additions & 0 deletions test/Translate/Ops/unop.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// RUN: p4mlir-translate --typeinference-only %s | FileCheck %s

// NOTE: Assertions have been autogenerated by utils/generate-test-checks.py

// CHECK-LABEL: module
// CHECK-NEXT: %[[VAL_0:.*]] = p4hir.const #p4hir.bool<true> : !p4hir.bool
// CHECK: %[[VAL_1:.*]] = p4hir.alloca !p4hir.bool ["b0", init] : !p4hir.ref<!p4hir.bool>
// CHECK: p4hir.store %[[VAL_0]], %[[VAL_1]] : !p4hir.bool, !p4hir.ref<!p4hir.bool>
// CHECK: %[[VAL_2:.*]] = p4hir.const #p4hir.int<255> : !p4hir.int<32>
// CHECK: %[[VAL_3:.*]] = p4hir.alloca !p4hir.int<32> ["b2", init] : !p4hir.ref<!p4hir.int<32>>
// CHECK: p4hir.store %[[VAL_2]], %[[VAL_3]] : !p4hir.int<32>, !p4hir.ref<!p4hir.int<32>>
// CHECK: %[[VAL_4:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref<!p4hir.int<32>>, !p4hir.int<32>
// CHECK: %[[VAL_5:.*]] = p4hir.unary(minus, %[[VAL_4]]) : !p4hir.int<32>
// CHECK: %[[VAL_6:.*]] = p4hir.alloca !p4hir.int<32> ["b3", init] : !p4hir.ref<!p4hir.int<32>>
// CHECK: p4hir.store %[[VAL_5]], %[[VAL_6]] : !p4hir.int<32>, !p4hir.ref<!p4hir.int<32>>
// CHECK: %[[VAL_7:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref<!p4hir.int<32>>, !p4hir.int<32>
// CHECK: %[[VAL_8:.*]] = p4hir.unary(cmpl, %[[VAL_7]]) : !p4hir.int<32>
// CHECK: %[[VAL_9:.*]] = p4hir.alloca !p4hir.int<32> ["b4", init] : !p4hir.ref<!p4hir.int<32>>
// CHECK: p4hir.store %[[VAL_8]], %[[VAL_9]] : !p4hir.int<32>, !p4hir.ref<!p4hir.int<32>>
// CHECK: %[[VAL_10:.*]] = p4hir.load %[[VAL_1]] : !p4hir.ref<!p4hir.bool>, !p4hir.bool
// CHECK: %[[VAL_11:.*]] = p4hir.unary(not, %[[VAL_10]]) : !p4hir.bool
// CHECK: %[[VAL_12:.*]] = p4hir.alloca !p4hir.bool ["b5", init] : !p4hir.ref<!p4hir.bool>
// CHECK: p4hir.store %[[VAL_11]], %[[VAL_12]] : !p4hir.bool, !p4hir.ref<!p4hir.bool>
// CHECK: %[[VAL_13:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref<!p4hir.int<32>>, !p4hir.int<32>
// CHECK: %[[VAL_14:.*]] = p4hir.unary(plus, %[[VAL_13]]) : !p4hir.int<32>
// CHECK: %[[VAL_15:.*]] = p4hir.alloca !p4hir.int<32> ["b6", init] : !p4hir.ref<!p4hir.int<32>>
// CHECK: p4hir.store %[[VAL_14]], %[[VAL_15]] : !p4hir.int<32>, !p4hir.ref<!p4hir.int<32>>

action foo() {
bool b0 = true;
int<32> b2 = 32s0xFF;
int<32> b3 = -b2;
int<32> b4 = ~b2;
bool b5 = !b0;
int<32> b6 = +b2;
}
93 changes: 76 additions & 17 deletions tools/p4mlir-translate/translate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
#include "ir/ir.h"
#include "ir/visitor.h"
#include "lib/big_int.h"
#include "lib/indent.h"
#include "lib/log.h"
#include "llvm/Support/raw_ostream.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_Attrs.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_Dialect.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_Ops.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_OpsEnums.h"
#include "p4mlir/Dialect/P4HIR/P4HIR_Types.h"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributeInterfaces.h"
Expand Down Expand Up @@ -60,6 +63,15 @@ mlir::APInt toAPInt(const P4::big_int &value, unsigned bitWidth = 0) {
class P4HIRConverter;
class P4TypeConverter;

class ConversionTracer {
public:
ConversionTracer(const char *Kind, const P4::IR::Node *node) {
// TODO: Add TimeTrace here
LOG4(P4::IndentCtl::indent << Kind << dbp(node));
}
~ConversionTracer() { LOG4_UNINDENT; }
};

// A dedicated converter for conversion of the P4 types to their destination
// representation.
class P4TypeConverter : public P4::Inspector {
Expand Down Expand Up @@ -88,7 +100,7 @@ class P4TypeConverter : public P4::Inspector {
bool preorder(const P4::IR::Type_Boolean *type) override;
bool preorder(const P4::IR::Type_Unknown *type) override;
bool preorder(const P4::IR::Type_Typedef *type) override {
LOG4("TypeConverting " << dbp(type));
ConversionTracer trace("TypeConverting ", type);
visit(type->type);
return false;
}
Expand Down Expand Up @@ -206,6 +218,13 @@ class P4HIRConverter : public P4::Inspector, public P4::ResolutionContext {
}

mlir::Value setValue(const P4::IR::Node *node, mlir::Value value) {
if (LOGGING(4)) {
std::string s;
llvm::raw_string_ostream os(s);
value.print(os);
LOG4("Converted " << dbp(node) << " -> \"" << s << "\"");
}

auto [it, inserted] = p4Values.try_emplace(node, value);
BUG_CHECK(inserted, "duplicate conversion of %1%", node);
return it->second;
Expand All @@ -219,7 +238,7 @@ class P4HIRConverter : public P4::Inspector, public P4::ResolutionContext {
}

bool preorder(const P4::IR::Type *type) override {
LOG4("Converting " << dbp(type));
ConversionTracer trace("Converting ", type);
P4TypeConverter cvt(*this);
type->apply(cvt);
return false;
Expand Down Expand Up @@ -250,49 +269,57 @@ class P4HIRConverter : public P4::Inspector, public P4::ResolutionContext {
return false;
}

bool preorder(const P4::IR::Cast *cast) override { return true; }
#define HANDLE_IN_POSTORDER(NodeTy) \
bool preorder(const P4::IR::NodeTy *) override { return true; } \
void postorder(const P4::IR::NodeTy *) override;

bool preorder(const P4::IR::Declaration_Constant *decl) override;
HANDLE_IN_POSTORDER(Cast)
HANDLE_IN_POSTORDER(Neg)
HANDLE_IN_POSTORDER(LNot)
HANDLE_IN_POSTORDER(UPlus)
HANDLE_IN_POSTORDER(Cmpl)
HANDLE_IN_POSTORDER(Declaration_Variable)

#undef HANDLE_IN_POSTORDER

bool preorder(const P4::IR::Declaration_Variable *) override { return true; }
void postorder(const P4::IR::Declaration_Variable *decl) override;
void postorder(const P4::IR::Cast *cast) override;
mlir::Value emitUnOp(const P4::IR::Operation_Unary *unop, P4HIR::UnaryOpKind kind);
bool preorder(const P4::IR::Declaration_Constant *decl) override;
};

bool P4TypeConverter::preorder(const P4::IR::Type_Bits *type) {
if ((this->type = converter.findType(type))) return false;

LOG4("TypeConverting " << dbp(type));
ConversionTracer trace("TypeConverting ", type);
auto mlirType = P4HIR::BitsType::get(converter.context(), type->width_bits(), type->isSigned);
return setType(type, mlirType);
}

bool P4TypeConverter::preorder(const P4::IR::Type_InfInt *type) {
if ((this->type = converter.findType(type))) return false;

LOG4("TypeConverting " << dbp(type));
ConversionTracer trace("TypeConverting ", type);
auto mlirType = P4HIR::InfIntType::get(converter.context());
return setType(type, mlirType);
}

bool P4TypeConverter::preorder(const P4::IR::Type_Boolean *type) {
if ((this->type = converter.findType(type))) return false;

LOG4("TypeConverting " << dbp(type));
ConversionTracer trace("TypeConverting ", type);
auto mlirType = P4HIR::BoolType::get(converter.context());
return setType(type, mlirType);
}

bool P4TypeConverter::preorder(const P4::IR::Type_Unknown *type) {
if ((this->type = converter.findType(type))) return false;

LOG4("TypeConverting " << dbp(type));
ConversionTracer trace("TypeConverting ", type);
auto mlirType = P4HIR::UnknownType::get(converter.context());
return setType(type, mlirType);
}

bool P4TypeConverter::preorder(const P4::IR::Type_Name *name) {
LOG4("TypeConverting " << dbp(name));
ConversionTracer trace("TypeConverting ", name);
const auto *type = converter.resolveType(name);
CHECK_NULL(type);
visit(type);
Expand Down Expand Up @@ -352,17 +379,23 @@ mlir::TypedAttr P4HIRConverter::resolveConstantExpr(const P4::IR::Expression *ex
}

mlir::Value P4HIRConverter::materializeConstantExpr(const P4::IR::Expression *expr) {
LOG4("Materializing constant expression " << dbp(expr));
ConversionTracer trace("Materializing constant expression ", expr);

auto type = getOrCreateType(expr->type);
auto init = getOrCreateConstantExpr(expr);
auto loc = getLoc(builder, expr);

// Hack: type inference sometimes keeps `Type_Unknown` for some constants, in such case
// use type from the initializer
if (mlir::isa<P4HIR::UnknownType>(type)) type = init.getType();

auto val = builder.create<P4HIR::ConstOp>(loc, type, init);
return setValue(expr, val);
}

bool P4HIRConverter::preorder(const P4::IR::Declaration_Constant *decl) {
LOG4("Converting " << dbp(decl));
ConversionTracer trace("Converting ", decl);

auto type = getOrCreateType(decl->type);
auto init = getOrCreateConstantExpr(decl->initializer);
auto loc = getLoc(builder, decl);
Expand All @@ -374,7 +407,8 @@ bool P4HIRConverter::preorder(const P4::IR::Declaration_Constant *decl) {
}

void P4HIRConverter::postorder(const P4::IR::Declaration_Variable *decl) {
LOG4("Converting " << dbp(decl));
ConversionTracer trace("Converting ", decl);

const auto *init = decl->initializer;
mlir::Type objectType;
if (init) objectType = getOrCreateType(init);
Expand All @@ -396,13 +430,38 @@ void P4HIRConverter::postorder(const P4::IR::Declaration_Variable *decl) {
}

void P4HIRConverter::postorder(const P4::IR::Cast *cast) {
LOG4("Converting " << dbp(cast));
ConversionTracer trace("Converting ", cast);

auto src = getValue(cast->expr);
auto destType = getOrCreateType(cast->destType);

setValue(cast, builder.create<P4HIR::CastOp>(getLoc(builder, cast), destType, src));
}

mlir::Value P4HIRConverter::emitUnOp(const P4::IR::Operation_Unary *unop, P4HIR::UnaryOpKind kind) {
return builder.create<P4HIR::UnaryOp>(getLoc(builder, unop), kind, getValue(unop->expr));
}

void P4HIRConverter::postorder(const P4::IR::Neg *neg) {
ConversionTracer trace("Converting ", neg);
setValue(neg, emitUnOp(neg, P4HIR::UnaryOpKind::Neg));
}

void P4HIRConverter::postorder(const P4::IR::LNot *lnot) {
ConversionTracer trace("Converting ", lnot);
setValue(lnot, emitUnOp(lnot, P4HIR::UnaryOpKind::LNot));
}

void P4HIRConverter::postorder(const P4::IR::UPlus *plus) {
ConversionTracer trace("Converting ", plus);
setValue(plus, emitUnOp(plus, P4HIR::UnaryOpKind::UPlus));
}

void P4HIRConverter::postorder(const P4::IR::Cmpl *cmpl) {
ConversionTracer trace("Converting ", cmpl);
setValue(cmpl, emitUnOp(cmpl, P4HIR::UnaryOpKind::Cmpl));
}

} // namespace

namespace P4::P4MLIR {
Expand Down

0 comments on commit ccf0f2e

Please sign in to comment.