Skip to content
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
24 changes: 24 additions & 0 deletions include/circt/Dialect/RTG/IR/RTGInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,28 @@ def ValidationTypeInterface : TypeInterface<"ValidationTypeInterface"> {
];
}

def ImplicitConstraintOpInterface : OpInterface<"ImplicitConstraintOpInterface"> {
let description = [{
This interface should be implemented by operations that implicitly enforce
a constraint. This is used to automatically materialize constraints that
are not explicitly specified by the user.
}];
let cppNamespace = "::circt::rtg";

let methods = [
InterfaceMethod<[{
Returns whether the constraint enforced by this operation has already
been materialized.
}], "bool", "isConstraintMaterialized">,
InterfaceMethod<[{
Materialize the constraint enforced by this operation. The operation
itself may be modified in place (return itself) or a new operation may
be returned to be replaced with this operation. Returning `nullptr` means
the operation should be erased without being replaced (only valid for
operations without results).
}], "mlir::Operation *", "materializeConstraint", (ins
"mlir::OpBuilder &":$builder)>,
];
}

#endif // CIRCT_DIALECT_RTG_IR_RTGINTERFACES_TD
4 changes: 4 additions & 0 deletions include/circt/Dialect/RTG/Transforms/RTGPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,8 @@ def SimpleTestInlinerPass : Pass<"rtg-simple-test-inliner", "mlir::ModuleOp"> {
}];
}

def MaterializeConstraintsPass : Pass<"rtg-materialize-constraints"> {
let summary = "materialize implicit constraints";
}

#endif // CIRCT_DIALECT_RTG_TRANSFORMS_RTGPASSES_TD
7 changes: 7 additions & 0 deletions include/circt/Dialect/RTGTest/IR/RTGTestOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ def GetHartIdOp : RTGTestOp<"get_hartid", [Pure]> {
let hasFolder = 1;
}

def ImplicitConstraintTestOp : RTGTestOp<"implicit_constraint_op", [
DeclareOpInterfaceMethods<ImplicitConstraintOpInterface>,
]> {
let arguments = (ins UnitAttr:$implicitConstraint);
let assemblyFormat = "(`implicit_constraint` $implicitConstraint^)? attr-dict";
}

//===- Instruction Formats -------------------------------------------------===//

class InstFormatIOpBase<string mnemonic, int opcode7, int funct3>
Expand Down
1 change: 1 addition & 0 deletions lib/Dialect/RTG/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_circt_dialect_library(CIRCTRTGTransforms
LinearScanRegisterAllocationPass.cpp
LowerUniqueLabelsPass.cpp
LowerValidateToLabelsPass.cpp
MaterializeConstraintsPass.cpp
MemoryAllocationPass.cpp
PrintTestNamesPass.cpp
RTGPassPipelines.cpp
Expand Down
54 changes: 54 additions & 0 deletions lib/Dialect/RTG/Transforms/MaterializeConstraintsPass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "circt/Dialect/RTG/IR/RTGOpInterfaces.h"
#include "circt/Dialect/RTG/Transforms/RTGPasses.h"
#include "mlir/IR/PatternMatch.h"

namespace circt {
namespace rtg {
#define GEN_PASS_DEF_MATERIALIZECONSTRAINTSPASS
#include "circt/Dialect/RTG/Transforms/RTGPasses.h.inc"
} // namespace rtg
} // namespace circt

using namespace mlir;
using namespace circt;
using namespace circt::rtg;

//===----------------------------------------------------------------------===//
// Materialize Constraints Pass
//===----------------------------------------------------------------------===//

namespace {
struct MaterializeConstraintsPass
: public rtg::impl::MaterializeConstraintsPassBase<
MaterializeConstraintsPass> {
using Base::Base;
void runOnOperation() override;
};
} // namespace

void MaterializeConstraintsPass::runOnOperation() {
getOperation()->walk([&](ImplicitConstraintOpInterface op) {
if (op.isConstraintMaterialized())
return;

OpBuilder builder(op);
builder.setInsertionPointAfter(op);
auto *newOp = op.materializeConstraint(builder);
if (newOp == op)
return;
if (newOp && op->getNumResults() > 0)
op->replaceAllUsesWith(newOp);
assert(newOp ||
op->getNumResults() == 0 &&
"cannot erase operation without result value replacements");
op->erase();
});
}
16 changes: 16 additions & 0 deletions lib/Dialect/RTGTest/IR/RTGTestOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ mlir::OpFoldResult GetHartIdOp::fold(FoldAdaptor adaptor) {
return {};
}

//===----------------------------------------------------------------------===//
// ImplicitConstraintTestOp
//===----------------------------------------------------------------------===//

bool ImplicitConstraintTestOp::isConstraintMaterialized() {
return !getImplicitConstraint();
}

Operation *ImplicitConstraintTestOp::materializeConstraint(OpBuilder &builder) {
auto val =
rtg::ConstantOp::create(builder, getLoc(), builder.getBoolAttr(true));
rtg::ConstraintOp::create(builder, getLoc(), val);
setImplicitConstraint(false);
return getOperation();
}

//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
Expand Down
12 changes: 12 additions & 0 deletions test/Dialect/RTG/Transform/materialize-constraints.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: circt-opt %s --rtg-materialize-constraints | FileCheck %s

// CHECK-LABEL: @test
rtg.test @test() {
// CHECK-NEXT: rtgtest.implicit_constraint_op{{$}}
// CHECK-NEXT: [[V0:%.+]] = rtg.constant true
// CHECK-NEXT: rtg.constraint [[V0]]
rtgtest.implicit_constraint_op implicit_constraint
// CHECK-NEXT: rtgtest.implicit_constraint_op{{$}}
rtgtest.implicit_constraint_op
// CHECK-NEXT: }
}