mirror of https://github.com/llvm/circt.git
[Handshake] Change join to accept all input types (#3860)
This commit lifts the unnecessary limitation of `JoinOp`'s only having one input type.
This commit is contained in:
parent
4f74ca8ec8
commit
d75838177a
|
@ -805,10 +805,10 @@ def JoinOp : Handshake_Op<"join", [
|
|||
|
||||
Example:
|
||||
```mlir
|
||||
%0 = join %a, %b, %c : i32
|
||||
%0 = join %a, %b, %c : i32, i1, none
|
||||
```
|
||||
}];
|
||||
let arguments = (ins Variadic<NoneType> : $data);
|
||||
let arguments = (ins Variadic<AnyType> : $data);
|
||||
let results = (outs NoneType : $result);
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
module {
|
||||
handshake.func @top(%arg0: none, ...) -> (none) attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]}{
|
||||
%3 = buffer [1] seq %f#1 {initValues = [0]}: none
|
||||
%ctrlOut = join %3, %arg0 : none
|
||||
%ctrlOut = join %3, %arg0 : none, none
|
||||
%f:2 = fork [2] %ctrlOut : none
|
||||
return %f#0 : none
|
||||
}
|
||||
|
|
|
@ -1428,28 +1428,34 @@ void JoinOp::build(OpBuilder &builder, OperationState &result,
|
|||
result.types.push_back(type);
|
||||
|
||||
result.addOperands(operands);
|
||||
sost::addAttributes(result, operands.size(), type);
|
||||
result.addAttribute("control", BoolAttr::get(result.getContext(), true));
|
||||
}
|
||||
|
||||
ParseResult JoinOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||
SmallVector<OpAsmParser::UnresolvedOperand, 4> allOperands;
|
||||
Type type;
|
||||
ArrayRef<Type> operandTypes(type);
|
||||
SmallVector<Type, 1> dataOperandsTypes;
|
||||
SmallVector<OpAsmParser::UnresolvedOperand, 4> operands;
|
||||
SmallVector<Type> types;
|
||||
|
||||
llvm::SMLoc allOperandLoc = parser.getCurrentLocation();
|
||||
int size;
|
||||
if (sost::parseOperation(parser, allOperands, result, size, type, false))
|
||||
if (parser.parseOperandList(operands) ||
|
||||
parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
|
||||
parser.parseTypeList(types))
|
||||
return failure();
|
||||
|
||||
dataOperandsTypes.assign(size, type);
|
||||
result.addTypes({type});
|
||||
if (parser.resolveOperands(allOperands, dataOperandsTypes, allOperandLoc,
|
||||
result.operands))
|
||||
if (parser.resolveOperands(operands, types, allOperandLoc, result.operands))
|
||||
return failure();
|
||||
|
||||
if (!result.attributes.get("control"))
|
||||
result.addAttribute("control", BoolAttr::get(result.getContext(), true));
|
||||
|
||||
result.addTypes(NoneType::get(result.getContext()));
|
||||
return success();
|
||||
}
|
||||
|
||||
void JoinOp::print(OpAsmPrinter &p) { sost::printOp(p, *this, false); }
|
||||
void JoinOp::print(OpAsmPrinter &p) {
|
||||
p << " " << data();
|
||||
p.printOptionalAttrDict((*this)->getAttrs(), {"control"});
|
||||
p << " : " << data().getTypes();
|
||||
}
|
||||
|
||||
/// Based on mlir::func::CallOp::verifySymbolUses
|
||||
LogicalResult InstanceOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
|
||||
|
|
|
@ -66,6 +66,6 @@ handshake.func @main(%arg0: index, %arg1: index, %v: i32, %mem : memref<10xi32>,
|
|||
%loadData, %loadAddr = load [%arg0] %ldData, %fCtrl#0 : index, i32
|
||||
%storeData, %storeAddr = store [%arg1] %v, %fCtrl#1 : index, i32
|
||||
sink %loadData : i32
|
||||
%finCtrl = join %stCtrl, %ldCtrl : none
|
||||
%finCtrl = join %stCtrl, %ldCtrl : none, none
|
||||
return %finCtrl : none
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: circt-opt -lower-handshake-to-firrtl %s | FileCheck %s
|
||||
// RUN: circt-opt -split-input-file -lower-handshake-to-firrtl %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: firrtl.circuit "test_join" {
|
||||
// CHECK: firrtl.module @handshake_join_2ins_1outs_ctrl(in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_2:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) {
|
||||
|
@ -17,6 +17,37 @@
|
|||
// CHECK: firrtl.module @test_join(in %[[VAL_11:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_12:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_13:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_14:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out %[[VAL_15:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in %[[VAL_16:.*]]: !firrtl.clock, in %[[VAL_17:.*]]: !firrtl.uint<1>) {
|
||||
// CHECK: %[[VAL_18:.*]], %[[VAL_19:.*]], %[[VAL_20:.*]] = firrtl.instance handshake_join0 @handshake_join_2ins_1outs_ctrl(in [[ARG0:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, in [[ARG1:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>, out [[ARG2:.+]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>)
|
||||
handshake.func @test_join(%arg0: none, %arg1: none, %arg2: none, ...) -> (none, none) {
|
||||
%0 = join %arg0, %arg1 : none
|
||||
%0 = join %arg0, %arg1 : none, none
|
||||
return %0, %arg2 : none, none
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: firrtl.module @handshake_join_in_ui32_ui1_3ins_1outs_ctrl(
|
||||
// CHECK-SAME: in %[[VAL_0:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>,
|
||||
// CHECK-SAME: in %[[VAL_1:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>,
|
||||
// CHECK-SAME: in %[[VAL_2:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>,
|
||||
// CHECK-SAME: out %[[VAL_3:.*]]: !firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) {
|
||||
// CHECK: %[[VAL_4:.*]] = firrtl.subfield %[[VAL_0]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_5:.*]] = firrtl.subfield %[[VAL_0]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_6:.*]] = firrtl.subfield %[[VAL_0]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<32>>) -> !firrtl.uint<32>
|
||||
// CHECK: %[[VAL_7:.*]] = firrtl.subfield %[[VAL_1]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_8:.*]] = firrtl.subfield %[[VAL_1]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_9:.*]] = firrtl.subfield %[[VAL_1]](2) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>, data: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_10:.*]] = firrtl.subfield %[[VAL_2]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_11:.*]] = firrtl.subfield %[[VAL_2]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_12:.*]] = firrtl.subfield %[[VAL_3]](0) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_13:.*]] = firrtl.subfield %[[VAL_3]](1) : (!firrtl.bundle<valid: uint<1>, ready flip: uint<1>>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_14:.*]] = firrtl.and %[[VAL_7]], %[[VAL_4]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_15:.*]] = firrtl.and %[[VAL_10]], %[[VAL_14]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
|
||||
// CHECK: firrtl.connect %[[VAL_12]], %[[VAL_15]] : !firrtl.uint<1>, !firrtl.uint<1>
|
||||
// CHECK: %[[VAL_16:.*]] = firrtl.and %[[VAL_13]], %[[VAL_15]] : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
|
||||
// CHECK: firrtl.connect %[[VAL_5]], %[[VAL_16]] : !firrtl.uint<1>, !firrtl.uint<1>
|
||||
// CHECK: firrtl.connect %[[VAL_8]], %[[VAL_16]] : !firrtl.uint<1>, !firrtl.uint<1>
|
||||
// CHECK: firrtl.connect %[[VAL_11]], %[[VAL_16]] : !firrtl.uint<1>, !firrtl.uint<1>
|
||||
// CHECK: }
|
||||
|
||||
handshake.func @test_join_multi_types(%arg0: i32, %arg1: i1, %arg2: none, ...) -> (none) {
|
||||
%0 = join %arg0, %arg1, %arg2 : i32, i1, none
|
||||
return %0: none
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
handshake.func @main(%arg0: index, %arg1: none, ...) -> none {
|
||||
%0:2 = memory [ld = 1, st= 0] (%addressResults) {id = 0 : i32, lsq = false} : memref<10xi8>, (index) -> (i8, none)
|
||||
%1:2 = fork [2] %arg1 : none
|
||||
%2 = join %1#1, %0#1 : none
|
||||
%2 = join %1#1, %0#1 : none, none
|
||||
%3, %addressResults = load [%arg0] %0#0, %1#0 : index, i8
|
||||
sink %3 : i8
|
||||
return %2 : none
|
||||
|
|
|
@ -72,6 +72,6 @@ handshake.func @main(%ldAddr: index, %stAddr: index, %v: i32, %mem : memref<10xi
|
|||
%loadData, %loadAddr = load [%ldAddr] %ldData, %fCtrl#0 : index, i32
|
||||
%storeData, %storeAddr = store [%stAddr] %v, %fCtrl#1 : index, i32
|
||||
sink %loadData : i32
|
||||
%finCtrl = join %stCtrl, %ldCtrl : none
|
||||
%finCtrl = join %stCtrl, %ldCtrl : none, none
|
||||
return %finCtrl : none
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// RUN: circt-opt -split-input-file %s | circt-opt | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: handshake.func @simple_multi_input(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, %[[VAL_2:.*]]: none, ...) -> none
|
||||
// CHECK: %[[VAL_3:.*]] = join %[[VAL_0]], %[[VAL_1]], %[[VAL_2]] : none, none, none
|
||||
// CHECK: return %[[VAL_3]] : none
|
||||
// CHECK: }
|
||||
|
||||
handshake.func @simple_multi_input(%in0: none, %in1: none, %in2: none, ...) -> (none) {
|
||||
%ctrlOut = join %in0, %in1, %in2 : none, none, none
|
||||
return %ctrlOut : none
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: handshake.func @different_in_types(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: tuple<i64, i32, i64>,
|
||||
// CHECK-SAME: %[[VAL_1:.*]]: none, ...) -> none
|
||||
// CHECK: %[[VAL_2:.*]] = join %[[VAL_0]], %[[VAL_1]] : tuple<i64, i32, i64>, none
|
||||
// CHECK: return %[[VAL_2]] : none
|
||||
// CHECK: }
|
||||
|
||||
handshake.func @different_in_types(%in: tuple<i64, i32, i64>, %arg1: none, ...) -> (none) {
|
||||
%ctrlOut = join %in, %arg1 : tuple<i64, i32, i64>, none
|
||||
return %ctrlOut : none
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: handshake.func @superfluous_ctrl_attr(
|
||||
// CHECK-SAME: %[[VAL_0:.*]]: none, %[[VAL_1:.*]]: none, ...) -> none
|
||||
// CHECK: %[[VAL_2:.*]] = join %[[VAL_0]], %[[VAL_1]] : none, none
|
||||
// CHECK: return %[[VAL_2]] : none
|
||||
// CHECK: }
|
||||
|
||||
handshake.func @superfluous_ctrl_attr(%in: none, %arg1: none, ...) -> (none) {
|
||||
%ctrlOut = join %in, %arg1 {control = true} : none, none
|
||||
return %ctrlOut : none
|
||||
}
|
Loading…
Reference in New Issue