diff --git a/include/circt/Dialect/LLHD/LLHDOps.h b/include/circt/Dialect/LLHD/LLHDOps.h index 3655ebbda22b..1e3729e87958 100644 --- a/include/circt/Dialect/LLHD/LLHDOps.h +++ b/include/circt/Dialect/LLHD/LLHDOps.h @@ -14,6 +14,7 @@ #include "circt/Dialect/LLHD/LLHDEnums.h.inc" #include "circt/Dialect/LLHD/LLHDTypes.h" #include "circt/Support/LLVM.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/Interfaces/CallInterfaces.h" #include "mlir/Interfaces/ControlFlowInterfaces.h" @@ -32,15 +33,6 @@ namespace llhd { unsigned getLLHDTypeWidth(Type type); Type getLLHDElementType(Type type); -/// Signals that an operations regions are procedural. -template -class ProceduralRegion - : public mlir::OpTrait::TraitBase { - static LogicalResult verifyTrait(Operation *op) { - return mlir::OpTrait::impl::verifyNRegions(op, 1); - } -}; - void registerDestructableIntegerExternalModel(mlir::DialectRegistry ®istry); } // namespace llhd diff --git a/include/circt/Dialect/LLHD/LLHDOps.td b/include/circt/Dialect/LLHD/LLHDOps.td index 67aa9c5da25a..04f5f7b30324 100644 --- a/include/circt/Dialect/LLHD/LLHDOps.td +++ b/include/circt/Dialect/LLHD/LLHDOps.td @@ -11,6 +11,7 @@ include "circt/Dialect/LLHD/LLHDDialect.td" include "circt/Dialect/LLHD/LLHDTypes.td" +include "circt/Support/ProceduralRegionTrait.td" include "mlir/IR/EnumAttr.td" include "mlir/IR/OpAsmInterface.td" include "mlir/IR/SymbolInterfaces.td" @@ -54,10 +55,6 @@ class SmallerOrEqualResultTypeWidthConstraint CPred<"llhd::getLLHDTypeWidth($" # result # ".getType()) <= " # "llhd::getLLHDTypeWidth($" # input # ".getType())">>; -def ProceduralRegion : NativeOpTrait<"ProceduralRegion"> { - let cppNamespace = "::circt::llhd"; -} - //===----------------------------------------------------------------------===// // Constants //===----------------------------------------------------------------------===// diff --git a/include/circt/Dialect/SV/SV.td b/include/circt/Dialect/SV/SV.td index 1a781fb964af..7902aaa27fbe 100644 --- a/include/circt/Dialect/SV/SV.td +++ b/include/circt/Dialect/SV/SV.td @@ -13,6 +13,7 @@ #ifndef CIRCT_DIALECT_SV_SV #define CIRCT_DIALECT_SV_SV +include "circt/Support/ProceduralRegionTrait.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/OpBase.td" include "mlir/IR/OpAsmInterface.td" @@ -25,10 +26,6 @@ include "circt/Dialect/SV/SVDialect.td" class SVOp traits = []> : Op; -def ProceduralRegion : NativeOpTrait<"ProceduralRegion"> { - let cppNamespace = "::circt::sv"; -} - def ProceduralOp : NativeOpTrait<"ProceduralOp"> { let cppNamespace = "::circt::sv"; } diff --git a/include/circt/Dialect/SV/SVOps.h b/include/circt/Dialect/SV/SVOps.h index 700f324b3bac..f84b81fe3180 100644 --- a/include/circt/Dialect/SV/SVOps.h +++ b/include/circt/Dialect/SV/SVOps.h @@ -20,6 +20,7 @@ #include "circt/Dialect/SV/SVAttributes.h" #include "circt/Dialect/SV/SVDialect.h" #include "circt/Dialect/SV/SVTypes.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/OpImplementation.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Interfaces/CallInterfaces.h" @@ -170,15 +171,6 @@ LogicalResult verifyInProceduralRegion(Operation *op); /// Return true if the specified operation is not in a procedural region. LogicalResult verifyInNonProceduralRegion(Operation *op); -/// Signals that an operations regions are procedural. -template -class ProceduralRegion - : public mlir::OpTrait::TraitBase { - static LogicalResult verifyTrait(Operation *op) { - return mlir::OpTrait::impl::verifyAtLeastNRegions(op, 1); - } -}; - /// This class verifies that the specified op is located in a procedural region. template class ProceduralOp diff --git a/include/circt/Support/ProceduralRegionTrait.h b/include/circt/Support/ProceduralRegionTrait.h new file mode 100644 index 000000000000..a2be345d7723 --- /dev/null +++ b/include/circt/Support/ProceduralRegionTrait.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This header file defines the `ProceduralRegion` trait. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_SUPPORT_PROCEDURALREGIONTRAIT_H +#define CIRCT_SUPPORT_PROCEDURALREGIONTRAIT_H + +#include "circt/Support/LLVM.h" +#include "mlir/IR/OpDefinition.h" +#include "llvm/Support/LogicalResult.h" + +namespace circt { + +/// Signals that an operation's regions are procedural. +template +class ProceduralRegion + : public mlir::OpTrait::TraitBase { + static LogicalResult verifyTrait(Operation *op) { + return mlir::OpTrait::impl::verifyNRegions(op, 1); + } +}; + +} // namespace circt + +#endif // CIRCT_SUPPORT_PROCEDURALREGIONTRAIT_H diff --git a/include/circt/Support/ProceduralRegionTrait.td b/include/circt/Support/ProceduralRegionTrait.td new file mode 100644 index 000000000000..a1653a967d97 --- /dev/null +++ b/include/circt/Support/ProceduralRegionTrait.td @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_SUPPORT_PROCDURALREGIONTRAIT_TD +#define CIRCT_SUPPORT_PROCDURALREGIONTRAIT_TD + +include "mlir/IR/OpBase.td" + +def ProceduralRegion : NativeOpTrait<"ProceduralRegion"> { + let cppNamespace = "::circt"; +} + +#endif // CIRCT_SUPPORT_PROCDURALREGIONTRAIT_TD diff --git a/lib/Conversion/ExportVerilog/ExportVerilog.cpp b/lib/Conversion/ExportVerilog/ExportVerilog.cpp index 7a426c39dbd6..c210208395e5 100644 --- a/lib/Conversion/ExportVerilog/ExportVerilog.cpp +++ b/lib/Conversion/ExportVerilog/ExportVerilog.cpp @@ -37,6 +37,7 @@ #include "circt/Support/Path.h" #include "circt/Support/PrettyPrinter.h" #include "circt/Support/PrettyPrinterHelpers.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "circt/Support/Version.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/ImplicitLocOpBuilder.h" diff --git a/lib/Conversion/ExportVerilog/PrepareForEmission.cpp b/lib/Conversion/ExportVerilog/PrepareForEmission.cpp index 8a8192cdce8f..d0840f59a261 100644 --- a/lib/Conversion/ExportVerilog/PrepareForEmission.cpp +++ b/lib/Conversion/ExportVerilog/PrepareForEmission.cpp @@ -24,6 +24,7 @@ #include "circt/Dialect/LTL/LTLDialect.h" #include "circt/Dialect/Verif/VerifDialect.h" #include "circt/Support/LoweringOptions.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/ImplicitLocOpBuilder.h" #include "mlir/Interfaces/CallInterfaces.h" #include "mlir/Pass/Pass.h" diff --git a/lib/Conversion/SimToSV/SimToSV.cpp b/lib/Conversion/SimToSV/SimToSV.cpp index 965ac5cd38b1..cef99575ae74 100644 --- a/lib/Conversion/SimToSV/SimToSV.cpp +++ b/lib/Conversion/SimToSV/SimToSV.cpp @@ -19,6 +19,7 @@ #include "circt/Dialect/Sim/SimDialect.h" #include "circt/Dialect/Sim/SimOps.h" #include "circt/Support/Namespace.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/Builders.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/IR/ImplicitLocOpBuilder.h" @@ -398,7 +399,7 @@ static bool moveOpsIntoIfdefGuardsAndProcesses(Operation *rootOp) { // If there was no pre-existing guard, create one. if (!block) { OpBuilder builder(op); - if (op->getParentOp()->hasTrait()) + if (op->getParentOp()->hasTrait()) block = sv::IfDefProceduralOp::create( builder, loc, "SYNTHESIS", [] {}, [] {}) .getElseBlock(); diff --git a/lib/Dialect/SV/SVOps.cpp b/lib/Dialect/SV/SVOps.cpp index 12d1288ab61d..b4a7bf1c49c2 100644 --- a/lib/Dialect/SV/SVOps.cpp +++ b/lib/Dialect/SV/SVOps.cpp @@ -21,6 +21,7 @@ #include "circt/Dialect/HW/ModuleImplementation.h" #include "circt/Dialect/SV/SVAttributes.h" #include "circt/Support/CustomDirectiveImpl.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Matchers.h" @@ -56,14 +57,14 @@ bool sv::isExpression(Operation *op) { } LogicalResult sv::verifyInProceduralRegion(Operation *op) { - if (op->getParentOp()->hasTrait()) + if (op->getParentOp()->hasTrait()) return success(); op->emitError() << op->getName() << " should be in a procedural region"; return failure(); } LogicalResult sv::verifyInNonProceduralRegion(Operation *op) { - if (!op->getParentOp()->hasTrait()) + if (!op->getParentOp()->hasTrait()) return success(); op->emitError() << op->getName() << " should be in a non-procedural region"; return failure(); diff --git a/lib/Dialect/SV/Transforms/HWCleanup.cpp b/lib/Dialect/SV/Transforms/HWCleanup.cpp index 3c5e5a7730df..941848fb83d3 100644 --- a/lib/Dialect/SV/Transforms/HWCleanup.cpp +++ b/lib/Dialect/SV/Transforms/HWCleanup.cpp @@ -17,6 +17,7 @@ #include "circt/Dialect/SV/SVAttributes.h" #include "circt/Dialect/SV/SVOps.h" #include "circt/Dialect/SV/SVPasses.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/Pass/Pass.h" namespace circt { @@ -144,7 +145,7 @@ void HWCleanupPass::runOnOperation() { /// Recursively process all of the regions in the specified op, dispatching to /// graph or procedural processing as appropriate. void HWCleanupPass::runOnRegionsInOp(Operation &op) { - if (op.hasTrait()) { + if (op.hasTrait()) { for (auto ®ion : op.getRegions()) runOnProceduralRegion(region); } else { diff --git a/lib/Dialect/SV/Transforms/HWLegalizeModules.cpp b/lib/Dialect/SV/Transforms/HWLegalizeModules.cpp index 6587c383047a..e4ee0ee262a3 100644 --- a/lib/Dialect/SV/Transforms/HWLegalizeModules.cpp +++ b/lib/Dialect/SV/Transforms/HWLegalizeModules.cpp @@ -20,6 +20,7 @@ #include "circt/Dialect/SV/SVOps.h" #include "circt/Dialect/SV/SVPasses.h" #include "circt/Support/LoweringOptions.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/IR/Builders.h" #include "mlir/Pass/Pass.h" @@ -288,7 +289,7 @@ Value HWLegalizeModulesPass::lowerLookupToCasez(Operation &op, Value input, // A casez is a procedural operation, so if we're in a // non-procedural region we need to inject an always_comb // block. - if (!op.getParentOp()->hasTrait()) { + if (!op.getParentOp()->hasTrait()) { auto alwaysComb = sv::AlwaysCombOp::create(builder, loc); builder.setInsertionPointToEnd(alwaysComb.getBodyBlock()); } diff --git a/lib/Dialect/Sim/SimOps.cpp b/lib/Dialect/Sim/SimOps.cpp index 92dc72ff735c..3e74b53b51dd 100644 --- a/lib/Dialect/Sim/SimOps.cpp +++ b/lib/Dialect/Sim/SimOps.cpp @@ -15,6 +15,7 @@ #include "circt/Dialect/HW/HWTypes.h" #include "circt/Dialect/SV/SVOps.h" #include "circt/Support/CustomDirectiveImpl.h" +#include "circt/Support/ProceduralRegionTrait.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Dialect/LLVMIR/LLVMTypes.h" #include "mlir/IR/PatternMatch.h" @@ -639,7 +640,7 @@ LogicalResult PrintFormattedProcOp::verify() { } if (isa_and_nonnull(parentOp->getDialect())) { - if (!parentOp->hasTrait()) + if (!parentOp->hasTrait()) return emitOpError("must be within a procedural region."); return success(); }