From 0c2f9ee188b3ddb8d2d0b1803bd99d9b99b4c859 Mon Sep 17 00:00:00 2001 From: chhzh123 Date: Wed, 16 Mar 2022 20:41:22 -0400 Subject: [PATCH] [Op][Backend][Binding] Add ReverseOp (Fix #42) --- include/hcl/Bindings/Python/hcl/build_ir.py | 10 ++++++++++ include/hcl/Dialect/HeteroCLOps.td | 9 +++++++++ include/hcl/Dialect/Visitor.h | 3 ++- lib/Translation/EmitHLSCpp.cpp | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/hcl/Bindings/Python/hcl/build_ir.py b/include/hcl/Bindings/Python/hcl/build_ir.py index a292d2ba..0aaa4304 100644 --- a/include/hcl/Bindings/Python/hcl/build_ir.py +++ b/include/hcl/Bindings/Python/hcl/build_ir.py @@ -493,6 +493,11 @@ def __setitem__(self, indices, expr): indices = indices[0] return SetBitOp(self, indices, expr) + def reverse(self): + if not is_integer_type(self.dtype): + raise RuntimeError("Only integers can reverse the bits") + return BitReverseOp(self) + def __nonzero__(self): raise RuntimeError( "1) Cannot use and / or / not operator to Expr, " @@ -1057,6 +1062,11 @@ def __init__(self, val): ) # use the same op +class BitReverseOp(UnaryOp): + def __init__(self, val): + super().__init__(hcl_d.BitReverseOp, val.dtype, val) + + class BitCastOp(UnaryOp): def __init__(self, dtype, val): super().__init__(arith.BitcastOp, dtype, val) diff --git a/include/hcl/Dialect/HeteroCLOps.td b/include/hcl/Dialect/HeteroCLOps.td index 5bf8dffb..72d4fdc3 100644 --- a/include/hcl/Dialect/HeteroCLOps.td +++ b/include/hcl/Dialect/HeteroCLOps.td @@ -441,4 +441,13 @@ def SetIntSliceOp : HeteroCL_Op<"set_slice"> { }]; } +def BitReverseOp : HeteroCL_Op<"bit_reverse", [SameOperandsAndResultType]> { + let summary = "reverse bits of an integer"; + let arguments = (ins SignlessIntegerLike:$num); + let results = (outs SignlessIntegerLike:$result); + let assemblyFormat = [{ + `(` $num `:` type($num) `)` attr-dict + }]; +} + #endif // HCL_OPS diff --git a/include/hcl/Dialect/Visitor.h b/include/hcl/Dialect/Visitor.h index cbbc8855..c25378ea 100644 --- a/include/hcl/Dialect/Visitor.h +++ b/include/hcl/Dialect/Visitor.h @@ -61,7 +61,7 @@ class HLSCppVisitorBase { // Logical expressions. arith::XOrIOp, arith::AndIOp, arith::OrIOp, arith::ShLIOp, arith::ShRSIOp, arith::ShRUIOp, hcl::GetIntBitOp, hcl::SetIntBitOp, - hcl::GetIntSliceOp, hcl::SetIntSliceOp, + hcl::GetIntSliceOp, hcl::SetIntSliceOp, hcl::BitReverseOp, // Special operations. CallOp, ReturnOp, SelectOp, ConstantOp, arith::ConstantOp, arith::TruncIOp, arith::TruncFOp, arith::ExtUIOp, arith::ExtSIOp, @@ -186,6 +186,7 @@ class HLSCppVisitorBase { HANDLE(hcl::SetIntBitOp); HANDLE(hcl::GetIntSliceOp); HANDLE(hcl::SetIntSliceOp); + HANDLE(hcl::BitReverseOp); // Special operations. HANDLE(CallOp); diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 95b1478f..4576c1a4 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -285,6 +285,7 @@ class ModuleEmitter : public HCLEmitterBase { void emitSetBit(hcl::SetIntBitOp op); void emitGetSlice(hcl::GetIntSliceOp op); void emitSetSlice(hcl::SetIntSliceOp op); + void emitBitReverse(hcl::BitReverseOp op); void emitBitcast(arith::BitcastOp op); /// Top-level MLIR module emitter. @@ -503,6 +504,9 @@ class ExprVisitor : public HLSCppVisitorBase { bool visitOp(hcl::SetIntBitOp op) { return emitter.emitSetBit(op), true; } bool visitOp(hcl::GetIntSliceOp op) { return emitter.emitGetSlice(op), true; } bool visitOp(hcl::SetIntSliceOp op) { return emitter.emitSetSlice(op), true; } + bool visitOp(hcl::BitReverseOp op) { + return emitter.emitBitReverse(op), true; + } /// Unary expressions. bool visitOp(math::AbsOp op) { return emitter.emitUnary(op, "abs"), true; } @@ -1407,6 +1411,17 @@ void ModuleEmitter::emitSetSlice(hcl::SetIntSliceOp op) { emitInfoAndNewLine(op); } +void ModuleEmitter::emitBitReverse(hcl::BitReverseOp op) { + indent(); + Value result = op.getResult(); + fixUnsignedType(result, op->hasAttr("unsigned")); + emitValue(result); + os << " = "; + emitValue(op.num()); + os << ".reverse();"; + emitInfoAndNewLine(op); +} + void ModuleEmitter::emitSelect(SelectOp op) { unsigned rank = emitNestedLoopHead(op.getResult()); unsigned conditionRank = rank;