Conversation
6751be6 to
332f9af
Compare
mtsamis
left a comment
There was a problem hiding this comment.
Thanks for the PR, please see some comments for potential improvements.
lib/Transforms/FlattenStructs.cpp
Outdated
|
|
||
| target.addDynamicallyLegalOp<P4HIR::StructExtractOp>([&](P4HIR::StructExtractOp op) { | ||
| return typeConverter.isLegal(op.getInput().getType()); | ||
| }); |
There was a problem hiding this comment.
I assume there is some reason that P4HIR::StructFieldRefOp and P4HIR::StructExtractOp should be explicitly defined in addition to configureUnknownOpDynamicallyLegalByTypes? If so, maybe a comment would be good to explain.
There was a problem hiding this comment.
Since the conversion pattern I added merges together a sequence of struct access ops, I wanted to only declare the "root" operations of a struct access chain as illegal. But given that the conversion happens top-down, the root operation will be the first to match so we can just remove these lines of code
lib/Transforms/FlattenStructs.cpp
Outdated
| isPredicateOrRefToPredicate(resultTy, StructFlatteningTypeConverter::isHeader) || | ||
| isPredicateOrRefToPredicate(resultTy, StructFlatteningTypeConverter::isScalar) || | ||
| isPredicateOrRefToPredicate(resultTy, | ||
| [](Type ty) { return isa<P4HIR::ValidBitType>(ty); }); |
There was a problem hiding this comment.
I think isPredicateOrRefToPredicate doesn't provide a lot of utility or readability here, maybe better to do something like below?
mlir::Type unwrapRef = leafType;
if (auto refType = dyn_cast<P4HIR::ReferenceType>(leafType))
leafType = refType.getObjectType();
bool isLeaf = StructFlatteningTypeConverter::isHeader(leafType)
|| StructFlatteningTypeConverter::isScalar(leafType)
|| isa<P4HIR::ValidBitType>(leafType);
lib/Transforms/FlattenStructs.cpp
Outdated
| ConversionPatternRewriter &rewriter) const { | ||
| return llvm::TypeSwitch<Operation *, LogicalResult>(op) | ||
| .Case([&](P4HIR::StructFieldRefOp fieldRefOp) { | ||
| return processStructAccessOp(fieldRefOp, convertedInput, parentFieldPath, eraseList, |
There was a problem hiding this comment.
If you want to avoid some duplication here you can use this pattern:
.Case<P4HIR::StructFieldRefOp, P4HIR::StructExtractOp>([&](auto op) {
return processStructAccessOp(fieldRefOp, convertedInput, parentFieldPath, eraseList, replacements, rewriter);
}
lib/Transforms/FlattenStructs.cpp
Outdated
| bool outputIsRef = isa<P4HIR::ReferenceType>(op.getResult().getType()); | ||
| Value newResult = | ||
| llvm::TypeSwitch<Type, Value>(convertedInput.getType()) | ||
| .Case<P4HIR::ReferenceType>([&](auto) { |
There was a problem hiding this comment.
This is a bit hard to read due to the identation. I would propose that TypeSwitch doesn't provide a lot of benefit since there's only one case and you could use something like
Value newResult;
if (mlir::isa<P4HIR::ReferenceType>(convertedInput.getType())) {
...
newResult = ...;
} else {
newResult = rewriter.create(...);
}
That should eliminate 3 identation levels and make it easier to read.
lib/Transforms/FlattenStructs.cpp
Outdated
| // For intermediate reads we just process the rest of the tree and add the read to the erase | ||
| // list | ||
| for (auto user : op.getResult().getUsers()) { | ||
| if (!isa<P4HIR::StructFieldRefOp, P4HIR::StructExtractOp>(user)) { |
There was a problem hiding this comment.
Remove brackets for consistency with if below.
lib/Transforms/FlattenStructs.cpp
Outdated
|
|
||
| populateFunctionOpInterfaceTypeConversionPattern<P4HIR::FuncOp>(patterns, typeConverter); | ||
|
|
||
| if (failed(applyPartialConversion(moduleOp, target, std::move(patterns)))) { |
lib/Transforms/FlattenStructs.cpp
Outdated
| auto moduleOp = getOperation(); | ||
|
|
||
| StructFlatteningTypeConverter typeConverter; | ||
|
|
There was a problem hiding this comment.
Can remove empty line here.
lib/Transforms/FlattenStructs.cpp
Outdated
| class StructFlatteningTypeConverter : public P4HIRTypeConverter { | ||
| public: | ||
| StructFlatteningTypeConverter() { | ||
| addConversion([](P4HIR::StructLikeTypeInterface type) -> std::optional<Type> { |
There was a problem hiding this comment.
-> std::optional<Type> shouldn't really be needed here since flattenStructLikeType doesn't return one.
| continue; | ||
| } else { | ||
| llvm::errs() << "Unexpected type " << fieldType << "\n"; | ||
| llvm_unreachable("Unexpected field type during flattening"); |
There was a problem hiding this comment.
llvm::errs + llvm_unreachable feels a bit strange here. Consider that due to llvm_unreachable there (probably) won't be any message printed in a release build, if that case was ever hit.
So, either use llvm_unreachable only with that message, or keep llvm::errs() and don't use unreachable. (I would propose to only keep llvm_unreachable, if this indeed should be unreachable).
There was a problem hiding this comment.
Yeah the errs was left over from debugging, thanks for spotting it. I've removed it
| // CHECK-SAME: %[[ARG0:.*]]: !p4hir.ref<!metadata>, | ||
| // CHECK-SAME: %[[ARG1:.*]]: !p4hir.ref<!b16i>, | ||
| // CHECK-SAME: %[[ARG2:.*]]: !p4hir.ref<!b16i>) { | ||
| // CHECK: %[[VAL_0:.*]] = p4hir.read %[[ARG0]] : <!metadata> |
There was a problem hiding this comment.
Minor thing, but I think it would be better to use CHECK-DAG here, and in the other functions matched.
Signed-off-by: Pietro Ghiglio <pghiglio@accesssoftek.com>
332f9af to
7784f46
Compare
Adds a
FlattenStructspass that ensures that P4HIR Structs only contain Headers or scalars, and that Headers only contain scalars.Addresses #251