mirror of https://github.com/llvm/circt.git
Bump LLVM to 5cd9fa551e (#2789)
- `AttrDef` and `TypeDef` custom assembly has changed: https://reviews.llvm.org/D121505 - `FunctionOpInterface::getType()` renamed to `getFunctionType()` https://reviews.llvm.org/D121762
This commit is contained in:
parent
702aa29743
commit
1d59e2e074
|
@ -20,7 +20,9 @@
|
||||||
|
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
struct DependenceComponent;
|
struct DependenceComponent;
|
||||||
|
namespace func {
|
||||||
class FuncOp;
|
class FuncOp;
|
||||||
|
} // namespace func
|
||||||
} // namespace mlir
|
} // namespace mlir
|
||||||
|
|
||||||
namespace circt {
|
namespace circt {
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
class AnalysisManager;
|
class AnalysisManager;
|
||||||
|
namespace func {
|
||||||
class FuncOp;
|
class FuncOp;
|
||||||
|
} // namespace func
|
||||||
} // namespace mlir
|
} // namespace mlir
|
||||||
|
|
||||||
using namespace mlir;
|
using namespace mlir;
|
||||||
|
|
|
@ -19,7 +19,7 @@ include "mlir/Pass/PassBase.td"
|
||||||
// AffineToStaticLogic
|
// AffineToStaticLogic
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def AffineToStaticLogic : Pass<"convert-affine-to-staticlogic", "mlir::FuncOp"> {
|
def AffineToStaticLogic : Pass<"convert-affine-to-staticlogic", "mlir::func::FuncOp"> {
|
||||||
let summary = "Convert Affine dialect to StaticLogic pipelines";
|
let summary = "Convert Affine dialect to StaticLogic pipelines";
|
||||||
let description = [{
|
let description = [{
|
||||||
This pass analyzes Affine loops and control flow, creates a Scheduling
|
This pass analyzes Affine loops and control flow, creates a Scheduling
|
||||||
|
@ -227,7 +227,7 @@ def HandshakeRemoveBlock : Pass<"handshake-remove-block-structure", "handshake::
|
||||||
// StandardToStaticLogic
|
// StandardToStaticLogic
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def CreatePipeline : Pass<"create-pipeline", "mlir::FuncOp"> {
|
def CreatePipeline : Pass<"create-pipeline", "mlir::func::FuncOp"> {
|
||||||
let summary = "Create StaticLogic pipeline operations";
|
let summary = "Create StaticLogic pipeline operations";
|
||||||
let constructor = "circt::createCreatePipelinePass()";
|
let constructor = "circt::createCreatePipelinePass()";
|
||||||
let dependentDialects = ["staticlogic::StaticLogicDialect"];
|
let dependentDialects = ["staticlogic::StaticLogicDialect"];
|
||||||
|
|
|
@ -220,4 +220,5 @@ def PadLibOp : UnaryLibraryOp<"pad"> {
|
||||||
def SliceLibOp : UnaryLibraryOp<"slice"> {
|
def SliceLibOp : UnaryLibraryOp<"slice"> {
|
||||||
let hasVerifier = 1;
|
let hasVerifier = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def NotLibOp : UnaryLibraryOp<"not"> {}
|
def NotLibOp : UnaryLibraryOp<"not"> {}
|
||||||
|
|
|
@ -101,20 +101,20 @@ def ComponentOp : CalyxOp<"component", [
|
||||||
using mlir::detail::FunctionOpInterfaceTrait<ComponentOp>::getBody;
|
using mlir::detail::FunctionOpInterfaceTrait<ComponentOp>::getBody;
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError("requires '" + getTypeAttrName() +
|
||||||
"' attribute of function type");
|
"' attribute of function type");
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#ifndef ESI_TD
|
#ifndef ESI_TD
|
||||||
#define ESI_TD
|
#define ESI_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ def Channel : ESI_Port<"Channel"> {
|
||||||
|
|
||||||
let mnemonic = "channel";
|
let mnemonic = "channel";
|
||||||
let parameters = (ins "Type":$inner);
|
let parameters = (ins "Type":$inner);
|
||||||
|
|
||||||
|
let assemblyFormat = "`<` $inner `>`";
|
||||||
}
|
}
|
||||||
|
|
||||||
def ChannelType :
|
def ChannelType :
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef CHIRRTL_TD
|
#ifndef CHIRRTL_TD
|
||||||
#define CHIRRTL_TD
|
#define CHIRRTL_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
include "circt/Dialect/FIRRTL/FIRRTLDialect.td"
|
include "circt/Dialect/FIRRTL/FIRRTLDialect.td"
|
||||||
|
@ -69,6 +70,7 @@ def CMemoryType : TypeDef<CHIRRTLDialect, "CMemory"> {
|
||||||
];
|
];
|
||||||
|
|
||||||
let genVerifyDecl = 1;
|
let genVerifyDecl = 1;
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def CMemoryPortType : TypeDef<CHIRRTLDialect, "CMemoryPort"> {
|
def CMemoryPortType : TypeDef<CHIRRTLDialect, "CMemoryPort"> {
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
#ifndef FIRRTL_TD
|
#ifndef FIRRTL_TD
|
||||||
#define FIRRTL_TD
|
#define FIRRTL_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
|
include "mlir/IR/PatternBase.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
include "mlir/IR/RegionKindInterface.td"
|
include "mlir/IR/RegionKindInterface.td"
|
||||||
include "mlir/IR/FunctionInterfaces.td"
|
include "mlir/IR/FunctionInterfaces.td"
|
||||||
|
|
|
@ -38,6 +38,8 @@ def SubAnnotationAttr : AttrDef<FIRRTLDialect, "SubAnnotation"> {
|
||||||
}];
|
}];
|
||||||
let mnemonic = "subAnno";
|
let mnemonic = "subAnno";
|
||||||
let parameters = (ins "int64_t":$fieldID, "DictionaryAttr":$annotations);
|
let parameters = (ins "int64_t":$fieldID, "DictionaryAttr":$annotations);
|
||||||
|
|
||||||
|
let assemblyFormat = "`<` `fieldID` `=` $fieldID `,` $annotations `>`";
|
||||||
}
|
}
|
||||||
|
|
||||||
def PortAnnotationsAttr : ArrayAttrBase<
|
def PortAnnotationsAttr : ArrayAttrBase<
|
||||||
|
@ -62,6 +64,8 @@ def InvalidValueAttr : AttrDef<FIRRTLDialect, "InvalidValue"> {
|
||||||
let mnemonic = "invalidvalue";
|
let mnemonic = "invalidvalue";
|
||||||
let parameters = (ins AttributeSelfTypeParameter<"">:$type);
|
let parameters = (ins AttributeSelfTypeParameter<"">:$type);
|
||||||
|
|
||||||
|
let assemblyFormat = "`<` $type `>`";
|
||||||
|
|
||||||
let builders = [
|
let builders = [
|
||||||
AttrBuilderWithInferredContext<(ins "Type":$type),
|
AttrBuilderWithInferredContext<(ins "Type":$type),
|
||||||
"return $_get(type.getContext(), type);">
|
"return $_get(type.getContext(), type);">
|
||||||
|
@ -157,6 +161,8 @@ def ParamDeclAttr : AttrDef<FIRRTLDialect, "ParamDecl"> {
|
||||||
"::mlir::Attribute":$value);
|
"::mlir::Attribute":$value);
|
||||||
let mnemonic = "param.decl";
|
let mnemonic = "param.decl";
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let builders = [
|
let builders = [
|
||||||
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$name,
|
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$name,
|
||||||
"::mlir::Type":$type),
|
"::mlir::Type":$type),
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef CIRCT_DIALECT_FSM_TD
|
#ifndef CIRCT_DIALECT_FSM_TD
|
||||||
#define CIRCT_DIALECT_FSM_TD
|
#define CIRCT_DIALECT_FSM_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/FunctionInterfaces.td"
|
include "mlir/IR/FunctionInterfaces.td"
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,13 @@ def MachineOp : FSMOp<"machine", [HasParent<"mlir::ModuleOp">, FunctionOpInterfa
|
||||||
includes a `$body` region that contains internal variables and states.
|
includes a `$body` region that contains internal variables and states.
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let arguments = (ins StrAttr:$sym_name, TypeAttr:$stateType, TypeAttr:$type);
|
let arguments = (ins StrAttr:$sym_name, TypeAttr:$stateType,
|
||||||
|
TypeAttrOf<FunctionType>:$function_type);
|
||||||
let regions = (region SizedRegion<1>:$body);
|
let regions = (region SizedRegion<1>:$body);
|
||||||
|
|
||||||
let builders = [
|
let builders = [
|
||||||
OpBuilder<(ins "StringRef":$name, "Type":$stateType, "FunctionType":$type,
|
OpBuilder<(ins "StringRef":$name, "Type":$stateType,
|
||||||
|
"FunctionType":$function_type,
|
||||||
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
|
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
|
||||||
CArg<"ArrayRef<DictionaryAttr>", "{}">:$argAttrs)>
|
CArg<"ArrayRef<DictionaryAttr>", "{}">:$argAttrs)>
|
||||||
];
|
];
|
||||||
|
@ -41,20 +43,20 @@ def MachineOp : FSMOp<"machine", [HasParent<"mlir::ModuleOp">, FunctionOpInterfa
|
||||||
void getHWPortInfo(SmallVectorImpl<hw::PortInfo> &);
|
void getHWPortInfo(SmallVectorImpl<hw::PortInfo> &);
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError("requires '" + getTypeAttrName() +
|
||||||
"' attribute of function type");
|
"' attribute of function type");
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef HW_TD
|
#ifndef HW_TD
|
||||||
#define HW_TD
|
#define HW_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
|
|
|
@ -97,6 +97,7 @@ def ArraySliceOp : HWOp<"array_slice", [NoSideEffect]> {
|
||||||
|
|
||||||
let arguments = (ins ArrayType:$input, HWIntegerType:$lowIndex);
|
let arguments = (ins ArrayType:$input, HWIntegerType:$lowIndex);
|
||||||
let results = (outs ArrayType:$dst);
|
let results = (outs ArrayType:$dst);
|
||||||
|
|
||||||
let hasVerifier = 1;
|
let hasVerifier = 1;
|
||||||
|
|
||||||
let assemblyFormat = [{
|
let assemblyFormat = [{
|
||||||
|
|
|
@ -50,6 +50,8 @@ def OutputFileAttr : AttrDef<HWDialect, "OutputFile"> {
|
||||||
}]>,
|
}]>,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Get an OutputFileAttr from a string filename, canonicalizing the
|
/// Get an OutputFileAttr from a string filename, canonicalizing the
|
||||||
/// filename.
|
/// filename.
|
||||||
|
@ -110,6 +112,8 @@ def FileListAttr : AttrDef<HWDialect, "FileList"> {
|
||||||
}]>,
|
}]>,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let assemblyFormat = "`<` $filename `>`";
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Get an OutputFileAttr from a string filename, canonicalizing the
|
/// Get an OutputFileAttr from a string filename, canonicalizing the
|
||||||
/// filename.
|
/// filename.
|
||||||
|
@ -134,6 +138,8 @@ def ParamDeclAttr : AttrDef<HWDialect, "ParamDecl"> {
|
||||||
"::mlir::Attribute":$value);
|
"::mlir::Attribute":$value);
|
||||||
let mnemonic = "param.decl";
|
let mnemonic = "param.decl";
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let builders = [
|
let builders = [
|
||||||
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$name,
|
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$name,
|
||||||
"::mlir::Type":$type),
|
"::mlir::Type":$type),
|
||||||
|
@ -181,6 +187,8 @@ def ParamDeclRefAttr : AttrDef<HWDialect, "ParamDeclRef"> {
|
||||||
return get(name.getContext(), name, type);
|
return get(name.getContext(), name, type);
|
||||||
}]>
|
}]>
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def ParamVerbatimAttr : AttrDef<HWDialect, "ParamVerbatim"> {
|
def ParamVerbatimAttr : AttrDef<HWDialect, "ParamVerbatim"> {
|
||||||
|
@ -189,6 +197,8 @@ def ParamVerbatimAttr : AttrDef<HWDialect, "ParamVerbatim"> {
|
||||||
let parameters = (ins "::mlir::StringAttr":$value,
|
let parameters = (ins "::mlir::StringAttr":$value,
|
||||||
AttributeSelfTypeParameter<"">:$type);
|
AttributeSelfTypeParameter<"">:$type);
|
||||||
let mnemonic = "param.verbatim";
|
let mnemonic = "param.verbatim";
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,6 +253,8 @@ def ParamExprAttr : AttrDef<HWDialect, "ParamExpr"> {
|
||||||
return get(opcode, operands);
|
return get(opcode, operands);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ def InnerRefAttr : AttrDef<HWDialect, "InnerRef"> {
|
||||||
return get(module.getContext(), module, name);
|
return get(module.getContext(), module, name);
|
||||||
}]>,
|
}]>,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Get the InnerRefAttr for an operation and add the sym on it.
|
/// Get the InnerRefAttr for an operation and add the sym on it.
|
||||||
static InnerRefAttr getFromOperation(mlir::Operation *op,
|
static InnerRefAttr getFromOperation(mlir::Operation *op,
|
||||||
|
@ -43,6 +46,8 @@ def GlobalRefAttr : AttrDef<HWDialect, "GlobalRef"> {
|
||||||
}]>,
|
}]>,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let assemblyFormat = "`<` $glblSym `>`";
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
static constexpr char DialectAttrName[] = "circt.globalRef";
|
static constexpr char DialectAttrName[] = "circt.globalRef";
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -129,25 +129,28 @@ def HWModuleOp : HWModuleOpBase<"module",
|
||||||
mlir::OpAsmSetValueNameFn setNameFn);
|
mlir::OpAsmSetValueNameFn setNameFn);
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError("requires '" + getTypeAttrName() +
|
||||||
"' attribute of function type");
|
"' attribute of function type");
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifies the body of the function.
|
||||||
|
LogicalResult verifyBody();
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let hasCustomAssemblyFormat = 1;
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
@ -233,20 +236,20 @@ def HWModuleExternOp : HWModuleOpBase<"module.extern",
|
||||||
mlir::OpAsmSetValueNameFn setNameFn);
|
mlir::OpAsmSetValueNameFn setNameFn);
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError("requires '" + getTypeAttrName() +
|
||||||
"' attribute of function type");
|
"' attribute of function type");
|
||||||
|
@ -345,25 +348,27 @@ def HWModuleGeneratedOp : HWModuleOpBase<"module.generated",
|
||||||
mlir::OpAsmSetValueNameFn setNameFn);
|
mlir::OpAsmSetValueNameFn setNameFn);
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError("requires '" + getTypeAttrName() +
|
||||||
"' attribute of function type");
|
"' attribute of function type");
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeAttr getTypeAttr();
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let hasCustomAssemblyFormat = 1;
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
@ -446,8 +451,6 @@ def InstanceOp : HWOp<"instance", [
|
||||||
instanceNameAttr(name);
|
instanceNameAttr(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult verifyCustom();
|
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// SymbolOpInterface Methods
|
// SymbolOpInterface Methods
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
|
@ -489,13 +492,9 @@ def GlobalRefOp : HWOp<"globalRef", [IsolatedFromAbove, Symbol]> {
|
||||||
This also lets components of the path point to a common entity.
|
This also lets components of the path point to a common entity.
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
|
||||||
LogicalResult verifyGlobalRef();
|
|
||||||
}];
|
|
||||||
|
|
||||||
let arguments = (ins SymbolNameAttr:$sym_name, NameRefArrayAttr:$namepath);
|
let arguments = (ins SymbolNameAttr:$sym_name, NameRefArrayAttr:$namepath);
|
||||||
|
|
||||||
let assemblyFormat = [{ $sym_name $namepath attr-dict}];
|
let assemblyFormat = [{ $sym_name $namepath attr-dict }];
|
||||||
|
|
||||||
let hasVerifier = 1;
|
let hasVerifier = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ def IntTypeImpl : HWType<"Int"> {
|
||||||
let mnemonic = "int";
|
let mnemonic = "int";
|
||||||
let parameters = (ins "::mlir::Attribute":$width);
|
let parameters = (ins "::mlir::Attribute":$width);
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let skipDefaultBuilders = 1;
|
let skipDefaultBuilders = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
|
@ -52,6 +54,8 @@ def ArrayTypeImpl : HWType<"Array"> {
|
||||||
let parameters = (ins "::mlir::Type":$elementType, "size_t":$size);
|
let parameters = (ins "::mlir::Type":$elementType, "size_t":$size);
|
||||||
let genVerifyDecl = 1;
|
let genVerifyDecl = 1;
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
static ArrayType get(Type elementType, size_t size) {
|
static ArrayType get(Type elementType, size_t size) {
|
||||||
return get(elementType.getContext(), elementType, size);
|
return get(elementType.getContext(), elementType, size);
|
||||||
|
@ -71,6 +75,8 @@ def UnpackedArrayType : HWType<"UnpackedArray"> {
|
||||||
let parameters = (ins "::mlir::Type":$elementType, "size_t":$size);
|
let parameters = (ins "::mlir::Type":$elementType, "size_t":$size);
|
||||||
let genVerifyDecl = 1;
|
let genVerifyDecl = 1;
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
static UnpackedArrayType get(Type elementType, size_t size) {
|
static UnpackedArrayType get(Type elementType, size_t size) {
|
||||||
return get(elementType.getContext(), elementType, size);
|
return get(elementType.getContext(), elementType, size);
|
||||||
|
@ -90,6 +96,8 @@ def InOutTypeImpl : HWType<"InOut"> {
|
||||||
let parameters = (ins "::mlir::Type":$elementType);
|
let parameters = (ins "::mlir::Type":$elementType);
|
||||||
let genVerifyDecl = 1;
|
let genVerifyDecl = 1;
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
static InOutType get(Type elementType) {
|
static InOutType get(Type elementType) {
|
||||||
return get(elementType.getContext(), elementType);
|
return get(elementType.getContext(), elementType);
|
||||||
|
@ -106,6 +114,8 @@ def StructTypeImpl : HWType<"Struct"> {
|
||||||
}];
|
}];
|
||||||
let mnemonic = "struct";
|
let mnemonic = "struct";
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let parameters = (
|
let parameters = (
|
||||||
ins ArrayRefParameter<
|
ins ArrayRefParameter<
|
||||||
"::circt::hw::StructType::FieldInfo", "struct fields">: $elements
|
"::circt::hw::StructType::FieldInfo", "struct fields">: $elements
|
||||||
|
@ -129,6 +139,8 @@ def UnionTypeImpl : HWType<"Union"> {
|
||||||
);
|
);
|
||||||
let mnemonic = "union";
|
let mnemonic = "union";
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
using FieldInfo = ::circt::hw::detail::FieldInfo;
|
using FieldInfo = ::circt::hw::detail::FieldInfo;
|
||||||
mlir::Type getFieldType(mlir::StringRef fieldName);
|
mlir::Type getFieldType(mlir::StringRef fieldName);
|
||||||
|
@ -157,6 +169,8 @@ def TypeAliasType : HWType<"TypeAlias"> {
|
||||||
"mlir::Type":$canonicalType
|
"mlir::Type":$canonicalType
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let builders = [
|
let builders = [
|
||||||
TypeBuilderWithInferredContext<(ins
|
TypeBuilderWithInferredContext<(ins
|
||||||
"mlir::SymbolRefAttr":$ref, "mlir::Type":$innerType)>
|
"mlir::SymbolRefAttr":$ref, "mlir::Type":$innerType)>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define HANDSHAKE_TD
|
#define HANDSHAKE_TD
|
||||||
|
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
|
include "mlir/IR/PatternBase.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
include "mlir/IR/RegionKindInterface.td"
|
include "mlir/IR/RegionKindInterface.td"
|
||||||
include "mlir/IR/FunctionInterfaces.td"
|
include "mlir/IR/FunctionInterfaces.td"
|
||||||
|
|
|
@ -20,12 +20,14 @@
|
||||||
#include "mlir/IR/BuiltinOps.h"
|
#include "mlir/IR/BuiltinOps.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
#include "mlir/IR/Dialect.h"
|
#include "mlir/IR/Dialect.h"
|
||||||
|
#include "mlir/IR/FunctionInterfaces.h"
|
||||||
#include "mlir/IR/OpDefinition.h"
|
#include "mlir/IR/OpDefinition.h"
|
||||||
#include "mlir/IR/OpImplementation.h"
|
#include "mlir/IR/OpImplementation.h"
|
||||||
#include "mlir/IR/Operation.h"
|
#include "mlir/IR/Operation.h"
|
||||||
#include "mlir/IR/RegionKindInterface.h"
|
#include "mlir/IR/RegionKindInterface.h"
|
||||||
#include "mlir/IR/TypeSupport.h"
|
#include "mlir/IR/TypeSupport.h"
|
||||||
#include "mlir/IR/Types.h"
|
#include "mlir/IR/Types.h"
|
||||||
|
#include "mlir/Interfaces/CallInterfaces.h"
|
||||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||||
#include "mlir/Pass/Pass.h"
|
#include "mlir/Pass/Pass.h"
|
||||||
#include "llvm/ADT/Any.h"
|
#include "llvm/ADT/Any.h"
|
||||||
|
|
|
@ -46,20 +46,19 @@ def FuncOp : Op<Handshake_Dialect, "func", [
|
||||||
// to match the signature of the function.
|
// to match the signature of the function.
|
||||||
Block *addEntryBlock();
|
Block *addEntryBlock();
|
||||||
|
|
||||||
FunctionType getType() {
|
/// Returns the type of this function.
|
||||||
return (*this)->getAttrOfType<TypeAttr>(getTypeAttrName())
|
FunctionType getFunctionType() {
|
||||||
.getValue()
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
.cast<FunctionType>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement RegionKindInterface.
|
/// Implement RegionKindInterface.
|
||||||
static RegionKind getRegionKind(unsigned index) { return RegionKind::Graph; }
|
static RegionKind getRegionKind(unsigned index) { return RegionKind::Graph; }
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Returns the names of the arguments to this function.
|
/// Returns the names of the arguments to this function.
|
||||||
ArrayAttr getArgNames() {
|
ArrayAttr getArgNames() {
|
||||||
|
@ -91,10 +90,11 @@ def FuncOp : Op<Handshake_Dialect, "func", [
|
||||||
/// getType, getNumFuncArguments, and getNumFuncResults can be called
|
/// getType, getNumFuncArguments, and getNumFuncResults can be called
|
||||||
/// safely.
|
/// safely.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError(
|
||||||
"' attribute of function type");
|
"requires '" + mlir::function_interface_impl::getTypeAttrName() +
|
||||||
|
"' attribute of function type");
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ def InstanceOp : Handshake_Op<"instance", [CallOpInterface]> {
|
||||||
(ins "FuncOp":$module, CArg<"ValueRange", "{}">:$operands), [{
|
(ins "FuncOp":$module, CArg<"ValueRange", "{}">:$operands), [{
|
||||||
$_state.addOperands(operands);
|
$_state.addOperands(operands);
|
||||||
$_state.addAttribute("module", SymbolRefAttr::get(module));
|
$_state.addAttribute("module", SymbolRefAttr::get(module));
|
||||||
$_state.addTypes(module.getType().getResults());
|
$_state.addTypes(module.getResultTypes());
|
||||||
$_state.addTypes({$_builder.getType<::mlir::NoneType>()});
|
$_state.addTypes({$_builder.getType<::mlir::NoneType>()});
|
||||||
}]>, OpBuilder<
|
}]>, OpBuilder<
|
||||||
(ins "SymbolRefAttr":$module, "TypeRange":$results,
|
(ins "SymbolRefAttr":$module, "TypeRange":$results,
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
#ifndef CIRCT_DIALECT_LLHD_IR_LLHD
|
#ifndef CIRCT_DIALECT_LLHD_IR_LLHD
|
||||||
#define CIRCT_DIALECT_LLHD_IR_LLHD
|
#define CIRCT_DIALECT_LLHD_IR_LLHD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
|
include "mlir/IR/PatternBase.td"
|
||||||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||||
include "mlir/Interfaces/ControlFlowInterfaces.td"
|
include "mlir/Interfaces/ControlFlowInterfaces.td"
|
||||||
include "mlir/Interfaces/CallInterfaces.td"
|
include "mlir/Interfaces/CallInterfaces.td"
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "circt/Dialect/LLHD/IR/LLHDTypes.h"
|
#include "circt/Dialect/LLHD/IR/LLHDTypes.h"
|
||||||
#include "circt/Support/LLVM.h"
|
#include "circt/Support/LLVM.h"
|
||||||
#include "mlir/IR/BuiltinTypes.h"
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
|
#include "mlir/IR/FunctionInterfaces.h"
|
||||||
|
#include "mlir/Interfaces/CallInterfaces.h"
|
||||||
#include "mlir/Interfaces/ControlFlowInterfaces.h"
|
#include "mlir/Interfaces/ControlFlowInterfaces.h"
|
||||||
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
#include "mlir/Interfaces/InferTypeOpInterface.h"
|
||||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||||
|
|
|
@ -86,6 +86,8 @@ def LLHD_TimeAttr : AttrDef<LLHD_Dialect, "Time", []> {
|
||||||
let storageType= [{ llhd::TimeAttr }];
|
let storageType= [{ llhd::TimeAttr }];
|
||||||
let genVerifyDecl = 1;
|
let genVerifyDecl = 1;
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
let parameters = (ins AttributeSelfTypeParameter<"", "llhd::TimeType">:$type,
|
let parameters = (ins AttributeSelfTypeParameter<"", "llhd::TimeType">:$type,
|
||||||
"unsigned":$time,
|
"unsigned":$time,
|
||||||
StringRefParameter<"SI time unit">:$timeUnit,
|
StringRefParameter<"SI time unit">:$timeUnit,
|
||||||
|
|
|
@ -56,18 +56,15 @@ def LLHD_EntityOp : LLHD_Op<"entity", [
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use FunctionOpInterface traits's getBody method.
|
|
||||||
using mlir::detail::FunctionOpInterfaceTrait<EntityOp>::getBody;
|
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
|
@ -76,6 +73,10 @@ def LLHD_EntityOp : LLHD_Op<"entity", [
|
||||||
/// Verifies the body of the function.
|
/// Verifies the body of the function.
|
||||||
LogicalResult verifyBody();
|
LogicalResult verifyBody();
|
||||||
|
|
||||||
|
// Use FunctionOpInterface traits's getBody method.
|
||||||
|
using mlir::detail::FunctionOpInterfaceTrait<EntityOp>::getBody;
|
||||||
|
|
||||||
|
/// Return the block corresponding to the region.
|
||||||
Block *getBodyBlock() { return &body().front(); }
|
Block *getBodyBlock() { return &body().front(); }
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -129,15 +130,15 @@ def LLHD_ProcOp : LLHD_Op<"proc", [
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef MSFT_TD
|
#ifndef MSFT_TD
|
||||||
#define MSFT_TD
|
#define MSFT_TD
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
|
|
|
@ -38,6 +38,8 @@ def PhysLocation : MSFT_Attr<"PhysLocation"> {
|
||||||
let parameters = (ins
|
let parameters = (ins
|
||||||
"PrimitiveTypeAttr":$primitiveType,
|
"PrimitiveTypeAttr":$primitiveType,
|
||||||
"uint64_t":$x, "uint64_t":$y, "uint64_t":$num);
|
"uint64_t":$x, "uint64_t":$y, "uint64_t":$num);
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def PhysicalBounds : MSFT_Attr<"PhysicalBounds"> {
|
def PhysicalBounds : MSFT_Attr<"PhysicalBounds"> {
|
||||||
|
@ -53,6 +55,8 @@ def PhysicalBounds : MSFT_Attr<"PhysicalBounds"> {
|
||||||
"uint64_t":$yMin,
|
"uint64_t":$yMin,
|
||||||
"uint64_t":$yMax
|
"uint64_t":$yMax
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
def PhysicalBoundsArray : TypedArrayAttrBase<PhysicalBounds,
|
def PhysicalBoundsArray : TypedArrayAttrBase<PhysicalBounds,
|
||||||
|
|
|
@ -127,23 +127,24 @@ def MSFTModuleOp : MSFTOp<"module",
|
||||||
mlir::OpAsmSetValueNameFn setNameFn);
|
mlir::OpAsmSetValueNameFn setNameFn);
|
||||||
|
|
||||||
/// Returns the type of this function.
|
/// Returns the type of this function.
|
||||||
FunctionType getType() {
|
FunctionType getFunctionType() {
|
||||||
return getTypeAttr().getValue().cast<FunctionType>();
|
return getFunctionTypeAttr().getValue().cast<FunctionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the argument types of this function.
|
/// Returns the argument types of this function.
|
||||||
ArrayRef<Type> getArgumentTypes() { return getType().getInputs(); }
|
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getInputs(); }
|
||||||
|
|
||||||
/// Returns the result types of this function.
|
/// Returns the result types of this function.
|
||||||
ArrayRef<Type> getResultTypes() { return getType().getResults(); }
|
ArrayRef<Type> getResultTypes() { return getFunctionType().getResults(); }
|
||||||
|
|
||||||
/// Verify the type attribute of this function. Returns failure and emits
|
/// Verify the type attribute of this function. Returns failure and emits
|
||||||
/// an error if the attribute is invalid.
|
/// an error if the attribute is invalid.
|
||||||
LogicalResult verifyType() {
|
LogicalResult verifyType() {
|
||||||
auto type = getTypeAttr().getValue();
|
auto type = getFunctionTypeAttr().getValue();
|
||||||
if (!type.isa<FunctionType>())
|
if (!type.isa<FunctionType>())
|
||||||
return emitOpError("requires '" + getTypeAttrName() +
|
return emitOpError(
|
||||||
"' attribute of function type");
|
"requires '" + mlir::function_interface_impl::getTypeAttrName() +
|
||||||
|
"' attribute of function type");
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef CIRCT_DIALECT_MOORE_MOORE
|
#ifndef CIRCT_DIALECT_MOORE_MOORE
|
||||||
#define CIRCT_DIALECT_MOORE_MOORE
|
#define CIRCT_DIALECT_MOORE_MOORE
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef CIRCT_DIALECT_SV_SV
|
#ifndef CIRCT_DIALECT_SV_SV
|
||||||
#define CIRCT_DIALECT_SV_SV
|
#define CIRCT_DIALECT_SV_SV
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
include "mlir/IR/OpBase.td"
|
include "mlir/IR/OpBase.td"
|
||||||
include "mlir/IR/OpAsmInterface.td"
|
include "mlir/IR/OpAsmInterface.td"
|
||||||
include "mlir/IR/SymbolInterfaces.td"
|
include "mlir/IR/SymbolInterfaces.td"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
|
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
|
||||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
||||||
#include "mlir/Dialect/Affine/LoopUtils.h"
|
#include "mlir/Dialect/Affine/LoopUtils.h"
|
||||||
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||||
#include "mlir/IR/BuiltinOps.h"
|
#include "mlir/IR/BuiltinOps.h"
|
||||||
|
|
||||||
using namespace mlir;
|
using namespace mlir;
|
||||||
|
@ -124,7 +125,7 @@ static void checkMemrefDependence(SmallVectorImpl<Operation *> &memoryOps,
|
||||||
/// MemoryDependenceResult, which can by queried by Operation.
|
/// MemoryDependenceResult, which can by queried by Operation.
|
||||||
circt::analysis::MemoryDependenceAnalysis::MemoryDependenceAnalysis(
|
circt::analysis::MemoryDependenceAnalysis::MemoryDependenceAnalysis(
|
||||||
Operation *op) {
|
Operation *op) {
|
||||||
auto funcOp = cast<FuncOp>(op);
|
auto funcOp = cast<func::FuncOp>(op);
|
||||||
|
|
||||||
// Collect affine loops grouped by nesting depth.
|
// Collect affine loops grouped by nesting depth.
|
||||||
std::vector<SmallVector<AffineForOp, 2>> depthToLoops;
|
std::vector<SmallVector<AffineForOp, 2>> depthToLoops;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "circt/Scheduling/Problems.h"
|
#include "circt/Scheduling/Problems.h"
|
||||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
||||||
#include "mlir/Dialect/Affine/LoopUtils.h"
|
#include "mlir/Dialect/Affine/LoopUtils.h"
|
||||||
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||||
#include "mlir/Dialect/SCF/SCF.h"
|
#include "mlir/Dialect/SCF/SCF.h"
|
||||||
#include "mlir/IR/BuiltinOps.h"
|
#include "mlir/IR/BuiltinOps.h"
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "circt/Scheduling/Problems.h"
|
#include "circt/Scheduling/Problems.h"
|
||||||
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
|
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
|
||||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
||||||
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||||
#include "mlir/Pass/Pass.h"
|
#include "mlir/Pass/Pass.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ class ModuleLike:
|
||||||
if len(parameters) > 0 or "parameters" not in attributes:
|
if len(parameters) > 0 or "parameters" not in attributes:
|
||||||
attributes["parameters"] = ArrayAttr.get(parameters)
|
attributes["parameters"] = ArrayAttr.get(parameters)
|
||||||
|
|
||||||
attributes["type"] = TypeAttr.get(
|
attributes["function_type"] = TypeAttr.get(
|
||||||
FunctionType.get(inputs=input_types, results=output_types))
|
FunctionType.get(inputs=input_types, results=output_types))
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
@ -180,7 +180,7 @@ class ModuleLike:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
return FunctionType(TypeAttr(self.attributes["type"]).value)
|
return FunctionType(TypeAttr(self.attributes["function_type"]).value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
|
@ -112,7 +112,7 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
|
||||||
matchAndRewrite(HWModuleOp module, OpAdaptor adaptor,
|
matchAndRewrite(HWModuleOp module, OpAdaptor adaptor,
|
||||||
ConversionPatternRewriter &rewriter) const override {
|
ConversionPatternRewriter &rewriter) const override {
|
||||||
// Collect the HW module's port types.
|
// Collect the HW module's port types.
|
||||||
FunctionType moduleType = module.getType();
|
FunctionType moduleType = module.getFunctionType();
|
||||||
unsigned numInputs = moduleType.getNumInputs();
|
unsigned numInputs = moduleType.getNumInputs();
|
||||||
TypeRange moduleInputs = moduleType.getInputs();
|
TypeRange moduleInputs = moduleType.getInputs();
|
||||||
TypeRange moduleOutputs = moduleType.getResults();
|
TypeRange moduleOutputs = moduleType.getResults();
|
||||||
|
|
|
@ -596,7 +596,7 @@ static FModuleOp createTopModuleOp(handshake::FuncOp funcOp, unsigned numClocks,
|
||||||
auto funcLoc = funcOp.getLoc();
|
auto funcLoc = funcOp.getLoc();
|
||||||
|
|
||||||
// Add all outputs of funcOp.
|
// Add all outputs of funcOp.
|
||||||
for (auto portType : llvm::enumerate(funcOp.getType().getResults())) {
|
for (auto portType : llvm::enumerate(funcOp.getResultTypes())) {
|
||||||
auto portName = funcOp.getResName(portType.index());
|
auto portName = funcOp.getResName(portType.index());
|
||||||
auto bundlePortType = getBundleType(portType.value());
|
auto bundlePortType = getBundleType(portType.value());
|
||||||
|
|
||||||
|
|
|
@ -168,10 +168,10 @@ private:
|
||||||
auto inF = [&](unsigned idx) { return op.getArgName(idx).str(); };
|
auto inF = [&](unsigned idx) { return op.getArgName(idx).str(); };
|
||||||
auto outF = [&](unsigned idx) { return op.getResName(idx).str(); };
|
auto outF = [&](unsigned idx) { return op.getResName(idx).str(); };
|
||||||
llvm::transform(
|
llvm::transform(
|
||||||
llvm::enumerate(op.getType().getInputs()), std::back_inserter(inputs),
|
llvm::enumerate(op.getArgumentTypes()), std::back_inserter(inputs),
|
||||||
[&](auto it) { return builder.getStringAttr(inF(it.index())); });
|
[&](auto it) { return builder.getStringAttr(inF(it.index())); });
|
||||||
llvm::transform(
|
llvm::transform(
|
||||||
llvm::enumerate(op.getType().getResults()), std::back_inserter(outputs),
|
llvm::enumerate(op.getResultTypes()), std::back_inserter(outputs),
|
||||||
[&](auto it) { return builder.getStringAttr(outF(it.index())); });
|
[&](auto it) { return builder.getStringAttr(outF(it.index())); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,9 +333,8 @@ static HWModuleExternOp createSubModuleOp(ModuleOp parentModule,
|
||||||
|
|
||||||
static hw::HWModuleOp createTopModuleOp(handshake::FuncOp funcOp,
|
static hw::HWModuleOp createTopModuleOp(handshake::FuncOp funcOp,
|
||||||
ConversionPatternRewriter &rewriter) {
|
ConversionPatternRewriter &rewriter) {
|
||||||
llvm::SmallVector<PortInfo, 8> ports =
|
llvm::SmallVector<PortInfo, 8> ports = getPortInfoForOp(
|
||||||
getPortInfoForOp(rewriter, funcOp, funcOp.getType().getInputs(),
|
rewriter, funcOp, funcOp.getArgumentTypes(), funcOp.getResultTypes());
|
||||||
funcOp.getType().getResults());
|
|
||||||
|
|
||||||
// Create a HW module.
|
// Create a HW module.
|
||||||
auto hwModuleOp = rewriter.create<hw::HWModuleOp>(
|
auto hwModuleOp = rewriter.create<hw::HWModuleOp>(
|
||||||
|
|
|
@ -166,11 +166,11 @@ static void populateLegality(ConversionTarget &target) {
|
||||||
addGenericLegality<func::CallOp>(target);
|
addGenericLegality<func::CallOp>(target);
|
||||||
addGenericLegality<func::ReturnOp>(target);
|
addGenericLegality<func::ReturnOp>(target);
|
||||||
|
|
||||||
target.addDynamicallyLegalOp<mlir::FuncOp>([](mlir::FuncOp op) {
|
target.addDynamicallyLegalOp<FuncOp>([](FuncOp op) {
|
||||||
auto argsConverted = llvm::none_of(op.getBlocks(), [](auto &block) {
|
auto argsConverted = llvm::none_of(op.getBlocks(), [](auto &block) {
|
||||||
return hasMooreType(block.getArguments());
|
return hasMooreType(block.getArguments());
|
||||||
});
|
});
|
||||||
auto resultsConverted = !hasMooreType(op.getType().getResults());
|
auto resultsConverted = !hasMooreType(op.getResultTypes());
|
||||||
return argsConverted && resultsConverted;
|
return argsConverted && resultsConverted;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,8 +195,8 @@ static void populateOpConversion(RewritePatternSet &patterns,
|
||||||
.add<ConstantOpConv, VariableDeclOpConv, AssignOpConv, ReturnOpConversion,
|
.add<ConstantOpConv, VariableDeclOpConv, AssignOpConv, ReturnOpConversion,
|
||||||
CondBranchOpConversion, BranchOpConversion, CallOpConversion>(
|
CondBranchOpConversion, BranchOpConversion, CallOpConversion>(
|
||||||
typeConverter, context);
|
typeConverter, context);
|
||||||
mlir::populateFunctionOpInterfaceTypeConversionPattern<mlir::FuncOp>(
|
mlir::populateFunctionOpInterfaceTypeConversionPattern<FuncOp>(patterns,
|
||||||
patterns, typeConverter);
|
typeConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -35,6 +35,7 @@ class LLVMDialect;
|
||||||
|
|
||||||
namespace func {
|
namespace func {
|
||||||
class FuncDialect;
|
class FuncDialect;
|
||||||
|
class FuncOp;
|
||||||
} // namespace func
|
} // namespace func
|
||||||
} // namespace mlir
|
} // namespace mlir
|
||||||
|
|
||||||
|
|
|
@ -1539,7 +1539,7 @@ struct FuncOpConversion : public FuncOpPartialLoweringPattern {
|
||||||
/// Create I/O ports. Maintain separate in/out port vectors to determine
|
/// Create I/O ports. Maintain separate in/out port vectors to determine
|
||||||
/// which port index each function argument will eventually map to.
|
/// which port index each function argument will eventually map to.
|
||||||
SmallVector<calyx::PortInfo> inPorts, outPorts;
|
SmallVector<calyx::PortInfo> inPorts, outPorts;
|
||||||
FunctionType funcType = funcOp.getType();
|
FunctionType funcType = funcOp.getFunctionType();
|
||||||
unsigned extMemCounter = 0;
|
unsigned extMemCounter = 0;
|
||||||
for (auto &arg : enumerate(funcOp.getArguments())) {
|
for (auto &arg : enumerate(funcOp.getArguments())) {
|
||||||
if (arg.value().getType().isa<MemRefType>()) {
|
if (arg.value().getType().isa<MemRefType>()) {
|
||||||
|
@ -1577,7 +1577,7 @@ struct FuncOpConversion : public FuncOpPartialLoweringPattern {
|
||||||
|
|
||||||
/// Create a calyx::ComponentOp corresponding to the to-be-lowered function.
|
/// Create a calyx::ComponentOp corresponding to the to-be-lowered function.
|
||||||
auto compOp = rewriter.create<calyx::ComponentOp>(
|
auto compOp = rewriter.create<calyx::ComponentOp>(
|
||||||
funcOp.getLoc(), rewriter.getStringAttr(funcOp.sym_name()), ports);
|
funcOp.getLoc(), rewriter.getStringAttr(funcOp.getSymName()), ports);
|
||||||
|
|
||||||
/// Mark this component as the toplevel.
|
/// Mark this component as the toplevel.
|
||||||
compOp->setAttr("toplevel", rewriter.getUnitAttr());
|
compOp->setAttr("toplevel", rewriter.getUnitAttr());
|
||||||
|
@ -1949,7 +1949,7 @@ class BuildReturnRegs : public FuncOpPartialLoweringPattern {
|
||||||
PartiallyLowerFuncToComp(mlir::FuncOp funcOp,
|
PartiallyLowerFuncToComp(mlir::FuncOp funcOp,
|
||||||
PatternRewriter &rewriter) const override {
|
PatternRewriter &rewriter) const override {
|
||||||
|
|
||||||
for (auto argType : enumerate(funcOp.getType().getResults())) {
|
for (auto argType : enumerate(funcOp.getResultTypes())) {
|
||||||
auto convArgType = convIndexType(rewriter, argType.value());
|
auto convArgType = convIndexType(rewriter, argType.value());
|
||||||
assert(convArgType.isa<IntegerType>() && "unsupported return type");
|
assert(convArgType.isa<IntegerType>() && "unsupported return type");
|
||||||
unsigned width = convArgType.getIntOrFloatBitWidth();
|
unsigned width = convArgType.getIntOrFloatBitWidth();
|
||||||
|
@ -2459,7 +2459,7 @@ public:
|
||||||
/// a single function, else, throw error.
|
/// a single function, else, throw error.
|
||||||
auto funcOps = moduleOp.getOps<mlir::FuncOp>();
|
auto funcOps = moduleOp.getOps<mlir::FuncOp>();
|
||||||
if (std::distance(funcOps.begin(), funcOps.end()) == 1)
|
if (std::distance(funcOps.begin(), funcOps.end()) == 1)
|
||||||
topLevelFunction = (*funcOps.begin()).sym_name().str();
|
topLevelFunction = (*funcOps.begin()).getSymName().str();
|
||||||
else {
|
else {
|
||||||
moduleOp.emitError()
|
moduleOp.emitError()
|
||||||
<< "Module contains multiple functions, but no top level "
|
<< "Module contains multiple functions, but no top level "
|
||||||
|
@ -2508,7 +2508,7 @@ public:
|
||||||
target.addLegalOp<AddIOp, SubIOp, CmpIOp, ShLIOp, ShRUIOp, ShRSIOp, AndIOp,
|
target.addLegalOp<AddIOp, SubIOp, CmpIOp, ShLIOp, ShRUIOp, ShRSIOp, AndIOp,
|
||||||
XOrIOp, OrIOp, ExtUIOp, TruncIOp, CondBranchOp, BranchOp,
|
XOrIOp, OrIOp, ExtUIOp, TruncIOp, CondBranchOp, BranchOp,
|
||||||
MulIOp, DivUIOp, RemUIOp, ReturnOp, arith::ConstantOp,
|
MulIOp, DivUIOp, RemUIOp, ReturnOp, arith::ConstantOp,
|
||||||
IndexCastOp>();
|
IndexCastOp, mlir::FuncOp>();
|
||||||
|
|
||||||
RewritePatternSet legalizePatterns(&getContext());
|
RewritePatternSet legalizePatterns(&getContext());
|
||||||
legalizePatterns.add<DummyPattern>(&getContext());
|
legalizePatterns.add<DummyPattern>(&getContext());
|
||||||
|
|
|
@ -201,7 +201,7 @@ public:
|
||||||
|
|
||||||
LogicalResult finalize(ConversionPatternRewriter &rewriter,
|
LogicalResult finalize(ConversionPatternRewriter &rewriter,
|
||||||
TypeRange argTypes, TypeRange resTypes,
|
TypeRange argTypes, TypeRange resTypes,
|
||||||
mlir::FuncOp origFunc);
|
func::FuncOp origFunc);
|
||||||
|
|
||||||
// Partial lowering driver. This function will instantiate a new
|
// Partial lowering driver. This function will instantiate a new
|
||||||
// partial lowering call, creating a conversion rewriter context which is then
|
// partial lowering call, creating a conversion rewriter context which is then
|
||||||
|
@ -1807,7 +1807,7 @@ FuncOpLowering::replaceCallOps(ConversionPatternRewriter &rewriter) {
|
||||||
|
|
||||||
LogicalResult FuncOpLowering::finalize(ConversionPatternRewriter &rewriter,
|
LogicalResult FuncOpLowering::finalize(ConversionPatternRewriter &rewriter,
|
||||||
TypeRange argTypes, TypeRange resTypes,
|
TypeRange argTypes, TypeRange resTypes,
|
||||||
mlir::FuncOp origFunc) {
|
func::FuncOp origFunc) {
|
||||||
SmallVector<Type> newArgTypes(argTypes);
|
SmallVector<Type> newArgTypes(argTypes);
|
||||||
newArgTypes.push_back(rewriter.getNoneType());
|
newArgTypes.push_back(rewriter.getNoneType());
|
||||||
|
|
||||||
|
@ -1828,8 +1828,9 @@ LogicalResult FuncOpLowering::finalize(ConversionPatternRewriter &rewriter,
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult lowerFuncOp(mlir::FuncOp funcOp, MLIRContext *ctx,
|
static LogicalResult lowerFuncOp(func::FuncOp funcOp, MLIRContext *ctx,
|
||||||
bool sourceConstants, bool disableTaskPipelining) {
|
bool sourceConstants,
|
||||||
|
bool disableTaskPipelining) {
|
||||||
// Only retain those attributes that are not constructed by build.
|
// Only retain those attributes that are not constructed by build.
|
||||||
SmallVector<NamedAttribute, 4> attributes;
|
SmallVector<NamedAttribute, 4> attributes;
|
||||||
for (const auto &attr : funcOp->getAttrs()) {
|
for (const auto &attr : funcOp->getAttrs()) {
|
||||||
|
@ -1848,15 +1849,15 @@ LogicalResult lowerFuncOp(mlir::FuncOp funcOp, MLIRContext *ctx,
|
||||||
|
|
||||||
// Get function results
|
// Get function results
|
||||||
llvm::SmallVector<mlir::Type, 8> resTypes;
|
llvm::SmallVector<mlir::Type, 8> resTypes;
|
||||||
for (auto arg : funcOp.getType().getResults())
|
for (auto arg : funcOp.getResultTypes())
|
||||||
resTypes.push_back(arg);
|
resTypes.push_back(arg);
|
||||||
|
|
||||||
handshake::FuncOp newFuncOp;
|
handshake::FuncOp newFuncOp;
|
||||||
|
|
||||||
// Add control input/output to function arguments/results and create a
|
// Add control input/output to function arguments/results and create a
|
||||||
// handshake::FuncOp of appropriate type
|
// handshake::FuncOp of appropriate type
|
||||||
returnOnError(partiallyLowerFuncOp<mlir::FuncOp>(
|
returnOnError(partiallyLowerFuncOp<func::FuncOp>(
|
||||||
[&](mlir::FuncOp funcOp, PatternRewriter &rewriter) {
|
[&](func::FuncOp funcOp, PatternRewriter &rewriter) {
|
||||||
auto noneType = rewriter.getNoneType();
|
auto noneType = rewriter.getNoneType();
|
||||||
resTypes.push_back(noneType);
|
resTypes.push_back(noneType);
|
||||||
auto func_type = rewriter.getFunctionType(argTypes, resTypes);
|
auto func_type = rewriter.getFunctionType(argTypes, resTypes);
|
||||||
|
@ -1937,7 +1938,7 @@ struct StandardToHandshakePass
|
||||||
void runOnOperation() override {
|
void runOnOperation() override {
|
||||||
ModuleOp m = getOperation();
|
ModuleOp m = getOperation();
|
||||||
|
|
||||||
for (auto funcOp : llvm::make_early_inc_range(m.getOps<mlir::FuncOp>())) {
|
for (auto funcOp : llvm::make_early_inc_range(m.getOps<func::FuncOp>())) {
|
||||||
if (failed(lowerFuncOp(funcOp, &getContext(), sourceConstants,
|
if (failed(lowerFuncOp(funcOp, &getContext(), sourceConstants,
|
||||||
disableTaskPipelining))) {
|
disableTaskPipelining))) {
|
||||||
signalPassFailure();
|
signalPassFailure();
|
||||||
|
|
|
@ -62,7 +62,7 @@ valueVector getPipelineResults(Block &block) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createPipeline(mlir::FuncOp f, OpBuilder &builder) {
|
static void createPipeline(mlir::func::FuncOp f, OpBuilder &builder) {
|
||||||
for (Block &block : f) {
|
for (Block &block : f) {
|
||||||
if (!block.front().mightHaveTrait<OpTrait::IsTerminator>()) {
|
if (!block.front().mightHaveTrait<OpTrait::IsTerminator>()) {
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ namespace {
|
||||||
|
|
||||||
struct CreatePipelinePass : public CreatePipelineBase<CreatePipelinePass> {
|
struct CreatePipelinePass : public CreatePipelineBase<CreatePipelinePass> {
|
||||||
void runOnOperation() override {
|
void runOnOperation() override {
|
||||||
mlir::FuncOp f = getOperation();
|
auto f = getOperation();
|
||||||
auto builder = OpBuilder(f.getContext());
|
auto builder = OpBuilder(f.getContext());
|
||||||
createPipeline(f, builder);
|
createPipeline(f, builder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,13 +365,8 @@ Value calyx::ComponentOp::getDonePort() {
|
||||||
return getBlockArgumentWithName("done", *this);
|
return getBlockArgumentWithName("done", *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of the given component as a function type.
|
|
||||||
static FunctionType getComponentType(ComponentOp component) {
|
|
||||||
return component.getTypeAttr().getValue().cast<FunctionType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector<PortInfo> ComponentOp::getPortInfo() {
|
SmallVector<PortInfo> ComponentOp::getPortInfo() {
|
||||||
auto portTypes = getComponentType(*this).getInputs();
|
auto portTypes = getArgumentTypes();
|
||||||
ArrayAttr portNamesAttr = portNames(), portAttrs = portAttributes();
|
ArrayAttr portNamesAttr = portNames(), portAttrs = portAttributes();
|
||||||
APInt portDirectionsAttr = portDirections();
|
APInt portDirectionsAttr = portDirections();
|
||||||
|
|
||||||
|
@ -433,7 +428,8 @@ void ComponentOp::print(OpAsmPrinter &p) {
|
||||||
/*printEmptyBlock=*/false);
|
/*printEmptyBlock=*/false);
|
||||||
|
|
||||||
SmallVector<StringRef> elidedAttrs = {"portAttributes", "portNames",
|
SmallVector<StringRef> elidedAttrs = {"portAttributes", "portNames",
|
||||||
"portDirections", "sym_name", "type"};
|
"portDirections", "sym_name",
|
||||||
|
ComponentOp::getTypeAttrName()};
|
||||||
p.printOptionalAttrDict((*this)->getAttrs(), elidedAttrs);
|
p.printOptionalAttrDict((*this)->getAttrs(), elidedAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,11 +693,10 @@ void SeqOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
|
||||||
|
|
||||||
LogicalResult ParOp::verify() {
|
LogicalResult ParOp::verify() {
|
||||||
llvm::SmallSet<StringRef, 8> groupNames;
|
llvm::SmallSet<StringRef, 8> groupNames;
|
||||||
Block *body = getBody();
|
|
||||||
|
|
||||||
// Add loose requirement that the body of a ParOp may not enable the same
|
// Add loose requirement that the body of a ParOp may not enable the same
|
||||||
// Group more than once, e.g. calyx.par { calyx.enable @G calyx.enable @G }
|
// Group more than once, e.g. calyx.par { calyx.enable @G calyx.enable @G }
|
||||||
for (EnableOp op : body->getOps<EnableOp>()) {
|
for (EnableOp op : getBody()->getOps<EnableOp>()) {
|
||||||
StringRef groupName = op.groupName();
|
StringRef groupName = op.groupName();
|
||||||
if (groupNames.count(groupName))
|
if (groupNames.count(groupName))
|
||||||
return emitOpError() << "cannot enable the same group: \"" << groupName
|
return emitOpError() << "cannot enable the same group: \"" << groupName
|
||||||
|
@ -727,12 +722,12 @@ LogicalResult WiresOp::verify() {
|
||||||
auto control = component.getControlOp();
|
auto control = component.getControlOp();
|
||||||
|
|
||||||
// Verify each group is referenced in the control section.
|
// Verify each group is referenced in the control section.
|
||||||
for (auto &&op : *this->getBody()) {
|
for (auto &&op : *getBody()) {
|
||||||
if (!isa<GroupInterface>(op))
|
if (!isa<GroupInterface>(op))
|
||||||
continue;
|
continue;
|
||||||
auto group = cast<GroupInterface>(op);
|
auto group = cast<GroupInterface>(op);
|
||||||
auto groupName = group.symName();
|
auto groupName = group.symName();
|
||||||
if (::mlir::SymbolTable::symbolKnownUseEmpty(groupName, control))
|
if (mlir::SymbolTable::symbolKnownUseEmpty(groupName, control))
|
||||||
return op.emitOpError() << "with name: " << groupName
|
return op.emitOpError() << "with name: " << groupName
|
||||||
<< " is unused in the control execution schedule";
|
<< " is unused in the control execution schedule";
|
||||||
}
|
}
|
||||||
|
@ -786,7 +781,6 @@ static LogicalResult isCombinational(Value value, GroupInterface group) {
|
||||||
/// Verifies a combinational group may contain only combinational primitives or
|
/// Verifies a combinational group may contain only combinational primitives or
|
||||||
/// perform combinational logic.
|
/// perform combinational logic.
|
||||||
LogicalResult CombGroupOp::verify() {
|
LogicalResult CombGroupOp::verify() {
|
||||||
|
|
||||||
for (auto &&op : *getBody()) {
|
for (auto &&op : *getBody()) {
|
||||||
auto assign = dyn_cast<AssignOp>(op);
|
auto assign = dyn_cast<AssignOp>(op);
|
||||||
if (assign == nullptr)
|
if (assign == nullptr)
|
||||||
|
@ -1416,10 +1410,10 @@ void MemoryOp::build(OpBuilder &builder, OperationState &state,
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult MemoryOp::verify() {
|
LogicalResult MemoryOp::verify() {
|
||||||
ArrayRef<Attribute> sizes = this->sizes().getValue();
|
ArrayRef<Attribute> opSizes = sizes().getValue();
|
||||||
ArrayRef<Attribute> addrSizes = this->addrSizes().getValue();
|
ArrayRef<Attribute> opAddrSizes = addrSizes().getValue();
|
||||||
size_t numDims = this->sizes().size();
|
size_t numDims = sizes().size();
|
||||||
size_t numAddrs = this->addrSizes().size();
|
size_t numAddrs = addrSizes().size();
|
||||||
if (numDims != numAddrs)
|
if (numDims != numAddrs)
|
||||||
return emitOpError("mismatched number of dimensions (")
|
return emitOpError("mismatched number of dimensions (")
|
||||||
<< numDims << ") and address sizes (" << numAddrs << ")";
|
<< numDims << ") and address sizes (" << numAddrs << ")";
|
||||||
|
@ -1430,8 +1424,8 @@ LogicalResult MemoryOp::verify() {
|
||||||
<< numAddrs;
|
<< numAddrs;
|
||||||
|
|
||||||
for (size_t i = 0; i < numDims; ++i) {
|
for (size_t i = 0; i < numDims; ++i) {
|
||||||
int64_t size = sizes[i].cast<IntegerAttr>().getInt();
|
int64_t size = opSizes[i].cast<IntegerAttr>().getInt();
|
||||||
int64_t addrSize = addrSizes[i].cast<IntegerAttr>().getInt();
|
int64_t addrSize = opAddrSizes[i].cast<IntegerAttr>().getInt();
|
||||||
if (llvm::Log2_64_Ceil(size) > addrSize)
|
if (llvm::Log2_64_Ceil(size) > addrSize)
|
||||||
return emitOpError("address size (")
|
return emitOpError("address size (")
|
||||||
<< addrSize << ") for dimension " << i
|
<< addrSize << ") for dimension " << i
|
||||||
|
@ -1447,15 +1441,15 @@ LogicalResult MemoryOp::verify() {
|
||||||
LogicalResult EnableOp::verify() {
|
LogicalResult EnableOp::verify() {
|
||||||
auto component = (*this)->getParentOfType<ComponentOp>();
|
auto component = (*this)->getParentOfType<ComponentOp>();
|
||||||
auto wiresOp = component.getWiresOp();
|
auto wiresOp = component.getWiresOp();
|
||||||
StringRef groupName = this->groupName();
|
StringRef name = groupName();
|
||||||
|
|
||||||
auto groupOp = wiresOp.lookupSymbol<GroupInterface>(groupName);
|
auto groupOp = wiresOp.lookupSymbol<GroupInterface>(name);
|
||||||
if (!groupOp)
|
if (!groupOp)
|
||||||
return emitOpError() << "with group '" << groupName
|
return emitOpError() << "with group '" << name
|
||||||
<< "', which does not exist.";
|
<< "', which does not exist.";
|
||||||
|
|
||||||
if (isa<CombGroupOp>(groupOp))
|
if (isa<CombGroupOp>(groupOp))
|
||||||
return emitOpError() << "with group '" << groupName
|
return emitOpError() << "with group '" << name
|
||||||
<< "', which is a combinational group.";
|
<< "', which is a combinational group.";
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
|
|
@ -181,22 +181,21 @@ LogicalResult ReplicateOp::verify() {
|
||||||
// Variadic operations
|
// Variadic operations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static LogicalResult verifyUTVariadicOp(Operation *op) {
|
static LogicalResult verifyUTBinOp(Operation *op) {
|
||||||
if (op->getOperands().empty())
|
if (op->getOperands().empty())
|
||||||
return op->emitOpError("requires 1 or more args");
|
return op->emitOpError("requires 1 or more args");
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult AddOp::verify() { return verifyUTVariadicOp(*this); }
|
LogicalResult AddOp::verify() { return verifyUTBinOp(*this); }
|
||||||
|
|
||||||
LogicalResult MulOp::verify() { return verifyUTVariadicOp(*this); }
|
LogicalResult MulOp::verify() { return verifyUTBinOp(*this); }
|
||||||
|
|
||||||
LogicalResult AndOp::verify() { return verifyUTVariadicOp(*this); }
|
LogicalResult AndOp::verify() { return verifyUTBinOp(*this); }
|
||||||
|
|
||||||
LogicalResult OrOp::verify() { return verifyUTVariadicOp(*this); }
|
LogicalResult OrOp::verify() { return verifyUTBinOp(*this); }
|
||||||
|
|
||||||
LogicalResult XorOp::verify() { return verifyUTVariadicOp(*this); }
|
LogicalResult XorOp::verify() { return verifyUTBinOp(*this); }
|
||||||
|
|
||||||
/// Return true if this is a two operand xor with an all ones constant as its
|
/// Return true if this is a two operand xor with an all ones constant as its
|
||||||
/// RHS operand.
|
/// RHS operand.
|
||||||
|
|
|
@ -413,7 +413,7 @@ static StringAttr appendToRtlName(StringAttr base, StringRef suffix) {
|
||||||
/// Convert all input and output ChannelPorts into valid/ready wires. Try not to
|
/// Convert all input and output ChannelPorts into valid/ready wires. Try not to
|
||||||
/// change the order and materialize ops in reasonably intuitive locations.
|
/// change the order and materialize ops in reasonably intuitive locations.
|
||||||
bool ESIPortsPass::updateFunc(HWModuleOp mod) {
|
bool ESIPortsPass::updateFunc(HWModuleOp mod) {
|
||||||
auto funcType = mod.getType();
|
auto funcType = mod.getFunctionType();
|
||||||
// Build ops in the module.
|
// Build ops in the module.
|
||||||
ImplicitLocOpBuilder modBuilder(mod.getLoc(), mod.getBody());
|
ImplicitLocOpBuilder modBuilder(mod.getLoc(), mod.getBody());
|
||||||
Type i1 = modBuilder.getI1Type();
|
Type i1 = modBuilder.getI1Type();
|
||||||
|
@ -433,7 +433,7 @@ bool ESIPortsPass::updateFunc(HWModuleOp mod) {
|
||||||
SmallVector<std::pair<Value, StringAttr>, 8> newReadySignals;
|
SmallVector<std::pair<Value, StringAttr>, 8> newReadySignals;
|
||||||
SmallVector<Attribute> newArgNames;
|
SmallVector<Attribute> newArgNames;
|
||||||
|
|
||||||
for (size_t argNum = 0, blockArgNum = 0, e = funcType.getNumInputs();
|
for (size_t argNum = 0, blockArgNum = 0, e = mod.getNumArguments();
|
||||||
argNum < e; ++argNum, ++blockArgNum) {
|
argNum < e; ++argNum, ++blockArgNum) {
|
||||||
Type argTy = funcType.getInput(argNum);
|
Type argTy = funcType.getInput(argNum);
|
||||||
auto argNameAttr = getModuleArgumentNameAttr(mod, argNum);
|
auto argNameAttr = getModuleArgumentNameAttr(mod, argNum);
|
||||||
|
@ -626,7 +626,6 @@ void ESIPortsPass::updateInstance(HWModuleOp mod, InstanceOp inst) {
|
||||||
/// over all the module updates.
|
/// over all the module updates.
|
||||||
bool ESIPortsPass::updateFunc(HWModuleExternOp mod) {
|
bool ESIPortsPass::updateFunc(HWModuleExternOp mod) {
|
||||||
auto *ctxt = &getContext();
|
auto *ctxt = &getContext();
|
||||||
auto funcType = mod.getType();
|
|
||||||
|
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
|
|
||||||
|
@ -636,7 +635,7 @@ bool ESIPortsPass::updateFunc(HWModuleExternOp mod) {
|
||||||
// port is found.
|
// port is found.
|
||||||
SmallVector<Type, 16> newArgTypes;
|
SmallVector<Type, 16> newArgTypes;
|
||||||
size_t nextArgNo = 0;
|
size_t nextArgNo = 0;
|
||||||
for (auto argTy : funcType.getInputs()) {
|
for (auto argTy : mod.getArgumentTypes()) {
|
||||||
auto chanTy = argTy.dyn_cast<ChannelPort>();
|
auto chanTy = argTy.dyn_cast<ChannelPort>();
|
||||||
newArgNames.push_back(getModuleArgumentNameAttr(mod, nextArgNo++));
|
newArgNames.push_back(getModuleArgumentNameAttr(mod, nextArgNo++));
|
||||||
|
|
||||||
|
@ -657,7 +656,8 @@ bool ESIPortsPass::updateFunc(HWModuleExternOp mod) {
|
||||||
// operand.
|
// operand.
|
||||||
SmallVector<Type, 8> newResultTypes;
|
SmallVector<Type, 8> newResultTypes;
|
||||||
SmallVector<DictionaryAttr, 4> newResultAttrs;
|
SmallVector<DictionaryAttr, 4> newResultAttrs;
|
||||||
for (size_t resNum = 0, numRes = funcType.getNumResults(); resNum < numRes;
|
auto funcType = mod.getFunctionType();
|
||||||
|
for (size_t resNum = 0, numRes = mod.getNumResults(); resNum < numRes;
|
||||||
++resNum) {
|
++resNum) {
|
||||||
Type resTy = funcType.getResult(resNum);
|
Type resTy = funcType.getResult(resNum);
|
||||||
auto chanTy = resTy.dyn_cast<ChannelPort>();
|
auto chanTy = resTy.dyn_cast<ChannelPort>();
|
||||||
|
@ -734,7 +734,7 @@ static std::string &constructInstanceName(Value operand, InterfaceOp iface,
|
||||||
void ESIPortsPass::updateInstance(HWModuleExternOp mod, InstanceOp inst) {
|
void ESIPortsPass::updateInstance(HWModuleExternOp mod, InstanceOp inst) {
|
||||||
using namespace circt::sv;
|
using namespace circt::sv;
|
||||||
circt::ImplicitLocOpBuilder instBuilder(inst.getLoc(), inst);
|
circt::ImplicitLocOpBuilder instBuilder(inst.getLoc(), inst);
|
||||||
FunctionType funcTy = mod.getType();
|
FunctionType funcTy = mod.getFunctionType();
|
||||||
|
|
||||||
// op counter for error reporting purposes.
|
// op counter for error reporting purposes.
|
||||||
size_t opNum = 0;
|
size_t opNum = 0;
|
||||||
|
|
|
@ -21,19 +21,6 @@
|
||||||
using namespace circt;
|
using namespace circt;
|
||||||
using namespace circt::esi;
|
using namespace circt::esi;
|
||||||
|
|
||||||
Type ChannelPort::parse(AsmParser &p) {
|
|
||||||
Type inner;
|
|
||||||
if (p.parseLess() || p.parseType(inner) || p.parseGreater())
|
|
||||||
return Type();
|
|
||||||
return get(p.getContext(), inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChannelPort::print(AsmPrinter &p) const {
|
|
||||||
p << "<";
|
|
||||||
p.printType(getInner());
|
|
||||||
p << ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_TYPEDEF_CLASSES
|
#define GET_TYPEDEF_CLASSES
|
||||||
#include "circt/Dialect/ESI/ESITypes.cpp.inc"
|
#include "circt/Dialect/ESI/ESITypes.cpp.inc"
|
||||||
|
|
||||||
|
|
|
@ -20,41 +20,6 @@ using namespace firrtl;
|
||||||
#define GET_ATTRDEF_CLASSES
|
#define GET_ATTRDEF_CLASSES
|
||||||
#include "circt/Dialect/FIRRTL/FIRRTLAttributes.cpp.inc"
|
#include "circt/Dialect/FIRRTL/FIRRTLAttributes.cpp.inc"
|
||||||
|
|
||||||
Attribute InvalidValueAttr::parse(AsmParser &p, Type typeX) {
|
|
||||||
FIRRTLType type;
|
|
||||||
if (p.parseLess() || p.parseType(type) || p.parseGreater())
|
|
||||||
return Attribute();
|
|
||||||
return InvalidValueAttr::get(p.getContext(), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InvalidValueAttr::print(AsmPrinter &p) const {
|
|
||||||
p << '<' << getType() << '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// SubAnnotationAttr
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
Attribute SubAnnotationAttr::parse(AsmParser &p, Type type) {
|
|
||||||
int64_t fieldID;
|
|
||||||
DictionaryAttr annotations;
|
|
||||||
StringRef fieldIDKeyword;
|
|
||||||
|
|
||||||
if (p.parseLess() || p.parseKeyword(&fieldIDKeyword) || p.parseEqual() ||
|
|
||||||
p.parseInteger(fieldID) || p.parseComma() ||
|
|
||||||
p.parseAttribute<DictionaryAttr>(annotations) || p.parseGreater())
|
|
||||||
return Attribute();
|
|
||||||
|
|
||||||
if (fieldIDKeyword != "fieldID")
|
|
||||||
return Attribute();
|
|
||||||
|
|
||||||
return SubAnnotationAttr::get(p.getContext(), fieldID, annotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubAnnotationAttr::print(AsmPrinter &p) const {
|
|
||||||
p << "<fieldID = " << getFieldID() << ", " << getAnnotations() << ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Utilities related to Direction
|
// Utilities related to Direction
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -3151,7 +3151,7 @@ LogicalResult BitCastOp::verify() {
|
||||||
auto inTypeBits = getBitWidth(getOperand().getType().cast<FIRRTLType>());
|
auto inTypeBits = getBitWidth(getOperand().getType().cast<FIRRTLType>());
|
||||||
auto resTypeBits = getBitWidth(getType());
|
auto resTypeBits = getBitWidth(getType());
|
||||||
if (inTypeBits.hasValue() && resTypeBits.hasValue()) {
|
if (inTypeBits.hasValue() && resTypeBits.hasValue()) {
|
||||||
// Bitwidths must match for valid bitcast.
|
// Bitwidths must match for valid bit
|
||||||
if (inTypeBits.getValue() == resTypeBits.getValue())
|
if (inTypeBits.getValue() == resTypeBits.getValue())
|
||||||
return success();
|
return success();
|
||||||
return emitError("the bitwidth of input (")
|
return emitError("the bitwidth of input (")
|
||||||
|
|
|
@ -45,7 +45,7 @@ StateOp MachineOp::getDefaultState() { return *getOps<StateOp>().begin(); }
|
||||||
/// Get the port information of the machine.
|
/// Get the port information of the machine.
|
||||||
void MachineOp::getHWPortInfo(SmallVectorImpl<hw::PortInfo> &ports) {
|
void MachineOp::getHWPortInfo(SmallVectorImpl<hw::PortInfo> &ports) {
|
||||||
ports.clear();
|
ports.clear();
|
||||||
auto machineType = getType();
|
auto machineType = getFunctionType();
|
||||||
auto builder = Builder(*this);
|
auto builder = Builder(*this);
|
||||||
|
|
||||||
for (unsigned i = 0, e = machineType.getNumInputs(); i < e; ++i) {
|
for (unsigned i = 0, e = machineType.getNumInputs(); i < e; ++i) {
|
||||||
|
@ -78,9 +78,7 @@ ParseResult MachineOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineOp::print(OpAsmPrinter &p) {
|
void MachineOp::print(OpAsmPrinter &p) {
|
||||||
FunctionType fnType = getType();
|
function_interface_impl::printFunctionOp(p, *this, /*isVariadic=*/false);
|
||||||
function_interface_impl::printFunctionOp(
|
|
||||||
p, *this, fnType.getInputs(), /*isVariadic=*/false, fnType.getResults());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LogicalResult compareTypes(TypeRange rangeA, TypeRange rangeB) {
|
static LogicalResult compareTypes(TypeRange rangeA, TypeRange rangeB) {
|
||||||
|
@ -108,12 +106,12 @@ LogicalResult MachineOp::verify() {
|
||||||
// Verify that the argument list of the function and the arg list of the entry
|
// Verify that the argument list of the function and the arg list of the entry
|
||||||
// block line up. The trait already verified that the number of arguments is
|
// block line up. The trait already verified that the number of arguments is
|
||||||
// the same between the signature and the block.
|
// the same between the signature and the block.
|
||||||
if (failed(compareTypes(getType().getInputs(), front().getArgumentTypes())))
|
if (failed(compareTypes(getArgumentTypes(), front().getArgumentTypes())))
|
||||||
return emitOpError(
|
return emitOpError(
|
||||||
"entry block argument types must match the machine input types");
|
"entry block argument types must match the machine input types");
|
||||||
|
|
||||||
// Verify that the machine only has one block terminated with OutputOp.
|
// Verify that the machine only has one block terminated with OutputOp.
|
||||||
if (!llvm::hasSingleElement((*this)))
|
if (!llvm::hasSingleElement(*this))
|
||||||
return emitOpError("must only have a single block");
|
return emitOpError("must only have a single block");
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
@ -130,10 +128,9 @@ MachineOp InstanceOp::getMachine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult InstanceOp::verify() {
|
LogicalResult InstanceOp::verify() {
|
||||||
auto machine = getMachine();
|
auto m = getMachine();
|
||||||
if (!machine)
|
if (!m)
|
||||||
return emitError("cannot find machine definition '")
|
return emitError("cannot find machine definition '") << machine() << "'";
|
||||||
<< this->machine() << "'";
|
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
@ -154,8 +151,8 @@ static LogicalResult verifyCallerTypes(OpType op) {
|
||||||
return op.emitError("cannot find machine definition");
|
return op.emitError("cannot find machine definition");
|
||||||
|
|
||||||
// Check operand types first.
|
// Check operand types first.
|
||||||
if (failed(compareTypes(machine.getType().getInputs(),
|
if (failed(
|
||||||
op.inputs().getTypes()))) {
|
compareTypes(machine.getArgumentTypes(), op.inputs().getTypes()))) {
|
||||||
auto diag =
|
auto diag =
|
||||||
op.emitOpError("operand types must match the machine input types");
|
op.emitOpError("operand types must match the machine input types");
|
||||||
diag.attachNote(machine->getLoc()) << "original machine declared here";
|
diag.attachNote(machine->getLoc()) << "original machine declared here";
|
||||||
|
@ -163,8 +160,7 @@ static LogicalResult verifyCallerTypes(OpType op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check result types.
|
// Check result types.
|
||||||
if (failed(compareTypes(machine.getType().getResults(),
|
if (failed(compareTypes(machine.getResultTypes(), op.outputs().getTypes()))) {
|
||||||
op.outputs().getTypes()))) {
|
|
||||||
auto diag =
|
auto diag =
|
||||||
op.emitOpError("result types must match the machine output types");
|
op.emitOpError("result types must match the machine output types");
|
||||||
diag.attachNote(machine->getLoc()) << "original machine declared here";
|
diag.attachNote(machine->getLoc()) << "original machine declared here";
|
||||||
|
@ -233,7 +229,7 @@ LogicalResult OutputOp::verify() {
|
||||||
// Verify that the result list of the machine and the operand list of the
|
// Verify that the result list of the machine and the operand list of the
|
||||||
// OutputOp line up.
|
// OutputOp line up.
|
||||||
auto machine = (*this)->getParentOfType<MachineOp>();
|
auto machine = (*this)->getParentOfType<MachineOp>();
|
||||||
if (failed(compareTypes(machine.getType().getResults(), getOperandTypes())))
|
if (failed(compareTypes(machine.getResultTypes(), getOperandTypes())))
|
||||||
return emitOpError("operand types must match the machine output types");
|
return emitOpError("operand types must match the machine output types");
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
@ -298,7 +294,7 @@ LogicalResult TransitionOp::verify() {
|
||||||
return emitOpError("action region must not return any value");
|
return emitOpError("action region must not return any value");
|
||||||
|
|
||||||
// Verify the transition is located in the correct region.
|
// Verify the transition is located in the correct region.
|
||||||
if ((*this)->getParentRegion() != &(*this).getCurrentState().transitions())
|
if ((*this)->getParentRegion() != &getCurrentState().transitions())
|
||||||
return emitOpError("must only be located in the transitions region");
|
return emitOpError("must only be located in the transitions region");
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
|
|
@ -161,21 +161,6 @@ void OutputFileAttr::print(AsmPrinter &p) const {
|
||||||
// FileListAttr
|
// FileListAttr
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Option ::= 'includeReplicatedOp'
|
|
||||||
/// OutputFileAttr ::= 'output_file<' name (',' Option)* '>'
|
|
||||||
Attribute FileListAttr::parse(AsmParser &p, Type type) {
|
|
||||||
StringAttr filename;
|
|
||||||
if (p.parseLess() || p.parseAttribute<StringAttr>(filename) ||
|
|
||||||
p.parseGreater())
|
|
||||||
return Attribute();
|
|
||||||
auto *context = p.getContext();
|
|
||||||
return FileListAttr::get(context, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileListAttr::print(AsmPrinter &p) const {
|
|
||||||
p << "<" << getFilename() << ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
FileListAttr FileListAttr::getFromFilename(MLIRContext *context,
|
FileListAttr FileListAttr::getFromFilename(MLIRContext *context,
|
||||||
const Twine &filename) {
|
const Twine &filename) {
|
||||||
auto canonicalized = canonicalizeFilename("", filename);
|
auto canonicalized = canonicalizeFilename("", filename);
|
||||||
|
@ -220,24 +205,6 @@ InnerRefAttr InnerRefAttr::getFromOperation(mlir::Operation *op,
|
||||||
return InnerRefAttr::get(moduleName, attr);
|
return InnerRefAttr::get(moduleName, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// GlobalRefAttr
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
Attribute GlobalRefAttr::parse(AsmParser &p, Type type) {
|
|
||||||
FlatSymbolRefAttr attr;
|
|
||||||
if (p.parseLess() || p.parseAttribute<FlatSymbolRefAttr>(attr) ||
|
|
||||||
p.parseGreater())
|
|
||||||
return Attribute();
|
|
||||||
return GlobalRefAttr::get(p.getContext(), attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlobalRefAttr::print(AsmPrinter &p) const {
|
|
||||||
p << "<";
|
|
||||||
p.printSymbolName(getGlblSym().getValue());
|
|
||||||
p << ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ParamDeclAttr
|
// ParamDeclAttr
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -276,7 +276,7 @@ static void printParamValue(OpAsmPrinter &p, Operation *, Attribute value,
|
||||||
LogicalResult ParamValueOp::verify() {
|
LogicalResult ParamValueOp::verify() {
|
||||||
// Check that the attribute expression is valid in this module.
|
// Check that the attribute expression is valid in this module.
|
||||||
return checkParameterInContext(
|
return checkParameterInContext(
|
||||||
value(), (*this)->getParentOfType<hw::HWModuleOp>(), (*this));
|
value(), (*this)->getParentOfType<hw::HWModuleOp>(), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpFoldResult ParamValueOp::fold(ArrayRef<Attribute> constants) {
|
OpFoldResult ParamValueOp::fold(ArrayRef<Attribute> constants) {
|
||||||
|
@ -502,7 +502,6 @@ void hw::modifyModulePorts(
|
||||||
ArrayRef<unsigned> removeInputs, ArrayRef<unsigned> removeOutputs) {
|
ArrayRef<unsigned> removeInputs, ArrayRef<unsigned> removeOutputs) {
|
||||||
auto moduleOp = cast<mlir::FunctionOpInterface>(op);
|
auto moduleOp = cast<mlir::FunctionOpInterface>(op);
|
||||||
|
|
||||||
FunctionType type = moduleOp.getType().cast<FunctionType>();
|
|
||||||
auto arrayOrEmpty = [](ArrayAttr attr) {
|
auto arrayOrEmpty = [](ArrayAttr attr) {
|
||||||
return attr ? attr.getValue() : ArrayRef<Attribute>{};
|
return attr ? attr.getValue() : ArrayRef<Attribute>{};
|
||||||
};
|
};
|
||||||
|
@ -510,14 +509,14 @@ void hw::modifyModulePorts(
|
||||||
// Dig up the old argument and result data.
|
// Dig up the old argument and result data.
|
||||||
ArrayRef<Attribute> oldArgNames =
|
ArrayRef<Attribute> oldArgNames =
|
||||||
moduleOp->getAttrOfType<ArrayAttr>("argNames").getValue();
|
moduleOp->getAttrOfType<ArrayAttr>("argNames").getValue();
|
||||||
ArrayRef<Type> oldArgTypes = type.getInputs();
|
ArrayRef<Type> oldArgTypes = moduleOp.getArgumentTypes();
|
||||||
ArrayRef<Attribute> oldArgAttrs =
|
ArrayRef<Attribute> oldArgAttrs =
|
||||||
arrayOrEmpty(moduleOp->getAttrOfType<ArrayAttr>(
|
arrayOrEmpty(moduleOp->getAttrOfType<ArrayAttr>(
|
||||||
mlir::function_interface_impl::getArgDictAttrName()));
|
mlir::function_interface_impl::getArgDictAttrName()));
|
||||||
|
|
||||||
ArrayRef<Attribute> oldResultNames =
|
ArrayRef<Attribute> oldResultNames =
|
||||||
moduleOp->getAttrOfType<ArrayAttr>("resultNames").getValue();
|
moduleOp->getAttrOfType<ArrayAttr>("resultNames").getValue();
|
||||||
ArrayRef<Type> oldResultTypes = type.getResults();
|
ArrayRef<Type> oldResultTypes = moduleOp.getResultTypes();
|
||||||
ArrayRef<Attribute> oldResultAttrs =
|
ArrayRef<Attribute> oldResultAttrs =
|
||||||
arrayOrEmpty(moduleOp->getAttrOfType<ArrayAttr>(
|
arrayOrEmpty(moduleOp->getAttrOfType<ArrayAttr>(
|
||||||
mlir::function_interface_impl::getResultDictAttrName()));
|
mlir::function_interface_impl::getResultDictAttrName()));
|
||||||
|
@ -1017,9 +1016,9 @@ static LogicalResult verifyModuleCommon(Operation *module) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult HWModuleOp::verify() { return verifyModuleCommon((*this)); }
|
LogicalResult HWModuleOp::verify() { return verifyModuleCommon(*this); }
|
||||||
|
|
||||||
LogicalResult HWModuleExternOp::verify() { return verifyModuleCommon((*this)); }
|
LogicalResult HWModuleExternOp::verify() { return verifyModuleCommon(*this); }
|
||||||
|
|
||||||
void HWModuleOp::getAsmBlockArgumentNames(mlir::Region ®ion,
|
void HWModuleOp::getAsmBlockArgumentNames(mlir::Region ®ion,
|
||||||
mlir::OpAsmSetValueNameFn setNameFn) {
|
mlir::OpAsmSetValueNameFn setNameFn) {
|
||||||
|
@ -1039,7 +1038,7 @@ Operation *HWModuleGeneratedOp::getGeneratorKindOp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult HWModuleGeneratedOp::verify() {
|
LogicalResult HWModuleGeneratedOp::verify() {
|
||||||
if (failed(verifyModuleCommon((*this))))
|
if (failed(verifyModuleCommon(*this)))
|
||||||
return failure();
|
return failure();
|
||||||
|
|
||||||
auto *referencedKind = getGeneratorKindOp();
|
auto *referencedKind = getGeneratorKindOp();
|
||||||
|
@ -1071,6 +1070,8 @@ void HWModuleGeneratedOp::getAsmBlockArgumentNames(
|
||||||
getAsmBlockArgumentNamesImpl(region, setNameFn);
|
getAsmBlockArgumentNamesImpl(region, setNameFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogicalResult HWModuleOp::verifyBody() { return success(); }
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// InstanceOp
|
// InstanceOp
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1230,7 +1231,7 @@ LogicalResult InstanceOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult InstanceOp::verifyCustom() {
|
LogicalResult InstanceOp::verify() {
|
||||||
// Check that all the parameter values specified to the instance are
|
// Check that all the parameter values specified to the instance are
|
||||||
// structurally valid.
|
// structurally valid.
|
||||||
for (auto param : parameters()) {
|
for (auto param : parameters()) {
|
||||||
|
@ -1360,8 +1361,6 @@ void InstanceOp::print(OpAsmPrinter &p) {
|
||||||
"moduleName", "argNames", "resultNames", "parameters"});
|
"moduleName", "argNames", "resultNames", "parameters"});
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult InstanceOp::verify() { return this->verifyCustom(); }
|
|
||||||
|
|
||||||
/// Return the name of the specified input port or null if it cannot be
|
/// Return the name of the specified input port or null if it cannot be
|
||||||
/// determined.
|
/// determined.
|
||||||
StringAttr InstanceOp::getArgumentName(size_t idx) {
|
StringAttr InstanceOp::getArgumentName(size_t idx) {
|
||||||
|
|
|
@ -484,7 +484,7 @@ LogicalResult FuncOp::verify() {
|
||||||
// Verify that the argument list of the function and the arg list of the
|
// Verify that the argument list of the function and the arg list of the
|
||||||
// entry block line up. The trait already verified that the number of
|
// entry block line up. The trait already verified that the number of
|
||||||
// arguments is the same between the signature and the block.
|
// arguments is the same between the signature and the block.
|
||||||
auto fnInputTypes = getType().getInputs();
|
auto fnInputTypes = getArgumentTypes();
|
||||||
Block &entryBlock = front();
|
Block &entryBlock = front();
|
||||||
|
|
||||||
for (unsigned i = 0, e = entryBlock.getNumArguments(); i != e; ++i)
|
for (unsigned i = 0, e = entryBlock.getNumArguments(); i != e; ++i)
|
||||||
|
@ -601,13 +601,12 @@ static void addStringToStringArrayAttr(Builder &builder, Operation *op,
|
||||||
}
|
}
|
||||||
|
|
||||||
void handshake::FuncOp::resolveArgAndResNames() {
|
void handshake::FuncOp::resolveArgAndResNames() {
|
||||||
auto type = getType();
|
|
||||||
Builder builder(getContext());
|
Builder builder(getContext());
|
||||||
|
|
||||||
/// Generate a set of fallback names. These are used in case names are
|
/// Generate a set of fallback names. These are used in case names are
|
||||||
/// missing from the currently set arg- and res name attributes.
|
/// missing from the currently set arg- and res name attributes.
|
||||||
auto fallbackArgNames = getFuncOpNames(builder, type.getInputs(), "in");
|
auto fallbackArgNames = getFuncOpNames(builder, getArgumentTypes(), "in");
|
||||||
auto fallbackResNames = getFuncOpNames(builder, type.getResults(), "out");
|
auto fallbackResNames = getFuncOpNames(builder, getResultTypes(), "out");
|
||||||
auto argNames = getArgNames().getValue();
|
auto argNames = getArgNames().getValue();
|
||||||
auto resNames = getResNames().getValue();
|
auto resNames = getResNames().getValue();
|
||||||
|
|
||||||
|
@ -666,10 +665,7 @@ ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuncOp::print(OpAsmPrinter &p) {
|
void FuncOp::print(OpAsmPrinter &p) {
|
||||||
FunctionType fnType = getType();
|
mlir::function_interface_impl::printFunctionOp(p, *this, /*isVariadic=*/true);
|
||||||
mlir::function_interface_impl::printFunctionOp(p, *this, fnType.getInputs(),
|
|
||||||
/*isVariadic=*/true,
|
|
||||||
fnType.getResults());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1109,7 +1105,7 @@ std::string handshake::MemoryOp::getResultName(unsigned int idx) {
|
||||||
return getMemoryResultName(ldCount(), stCount(), idx);
|
return getMemoryResultName(ldCount(), stCount(), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult handshake::MemoryOp::verify() {
|
LogicalResult MemoryOp::verify() {
|
||||||
auto memrefType = memRefType();
|
auto memrefType = memRefType();
|
||||||
|
|
||||||
if (memrefType.getNumDynamicDims() != 0)
|
if (memrefType.getNumDynamicDims() != 0)
|
||||||
|
@ -1118,8 +1114,8 @@ LogicalResult handshake::MemoryOp::verify() {
|
||||||
if (memrefType.getShape().size() != 1)
|
if (memrefType.getShape().size() != 1)
|
||||||
return emitOpError() << "memref must have only a single dimension.";
|
return emitOpError() << "memref must have only a single dimension.";
|
||||||
|
|
||||||
unsigned stCount = this->stCount();
|
unsigned opStCount = stCount();
|
||||||
unsigned ldCount = this->ldCount();
|
unsigned opLdCount = ldCount();
|
||||||
int addressCount = memrefType.getShape().size();
|
int addressCount = memrefType.getShape().size();
|
||||||
|
|
||||||
auto inputType = inputs().getType();
|
auto inputType = inputs().getType();
|
||||||
|
@ -1128,21 +1124,21 @@ LogicalResult handshake::MemoryOp::verify() {
|
||||||
|
|
||||||
unsigned numOperands = static_cast<int>(inputs().size());
|
unsigned numOperands = static_cast<int>(inputs().size());
|
||||||
unsigned numResults = static_cast<int>(outputs().size());
|
unsigned numResults = static_cast<int>(outputs().size());
|
||||||
if (numOperands != (1 + addressCount) * stCount + addressCount * ldCount)
|
if (numOperands != (1 + addressCount) * opStCount + addressCount * opLdCount)
|
||||||
return emitOpError("number of operands ")
|
return emitOpError("number of operands ")
|
||||||
<< numOperands << " does not match number expected of "
|
<< numOperands << " does not match number expected of "
|
||||||
<< 2 * stCount + ldCount << " with " << addressCount
|
<< 2 * opStCount + opLdCount << " with " << addressCount
|
||||||
<< " address inputs per port";
|
<< " address inputs per port";
|
||||||
|
|
||||||
if (numResults != stCount + 2 * ldCount)
|
if (numResults != opStCount + 2 * opLdCount)
|
||||||
return emitOpError("number of results ")
|
return emitOpError("number of results ")
|
||||||
<< numResults << " does not match number expected of "
|
<< numResults << " does not match number expected of "
|
||||||
<< stCount + 2 * ldCount << " with " << addressCount
|
<< opStCount + 2 * opLdCount << " with " << addressCount
|
||||||
<< " address inputs per port";
|
<< " address inputs per port";
|
||||||
|
|
||||||
Type addressType = stCount > 0 ? inputType[1] : inputType[0];
|
Type addressType = opStCount > 0 ? inputType[1] : inputType[0];
|
||||||
|
|
||||||
for (unsigned i = 0; i < stCount; i++) {
|
for (unsigned i = 0; i < opStCount; i++) {
|
||||||
if (inputType[2 * i] != dataType)
|
if (inputType[2 * i] != dataType)
|
||||||
return emitOpError("data type for store port ")
|
return emitOpError("data type for store port ")
|
||||||
<< i << ":" << inputType[2 * i] << " doesn't match memory type "
|
<< i << ":" << inputType[2 * i] << " doesn't match memory type "
|
||||||
|
@ -1152,27 +1148,27 @@ LogicalResult handshake::MemoryOp::verify() {
|
||||||
<< i << ":" << inputType[2 * i + 1]
|
<< i << ":" << inputType[2 * i + 1]
|
||||||
<< " doesn't match address type " << addressType;
|
<< " doesn't match address type " << addressType;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < ldCount; i++) {
|
for (unsigned i = 0; i < opLdCount; i++) {
|
||||||
Type ldAddressType = inputType[2 * stCount + i];
|
Type ldAddressType = inputType[2 * opStCount + i];
|
||||||
if (ldAddressType != addressType)
|
if (ldAddressType != addressType)
|
||||||
return emitOpError("address type for load port ")
|
return emitOpError("address type for load port ")
|
||||||
<< i << ":" << ldAddressType << " doesn't match address type "
|
<< i << ":" << ldAddressType << " doesn't match address type "
|
||||||
<< addressType;
|
<< addressType;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < ldCount; i++) {
|
for (unsigned i = 0; i < opLdCount; i++) {
|
||||||
if (outputType[i] != dataType)
|
if (outputType[i] != dataType)
|
||||||
return emitOpError("data type for load port ")
|
return emitOpError("data type for load port ")
|
||||||
<< i << ":" << outputType[i] << " doesn't match memory type "
|
<< i << ":" << outputType[i] << " doesn't match memory type "
|
||||||
<< dataType;
|
<< dataType;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < stCount; i++) {
|
for (unsigned i = 0; i < opStCount; i++) {
|
||||||
Type syncType = outputType[ldCount + i];
|
Type syncType = outputType[opLdCount + i];
|
||||||
if (!syncType.isa<NoneType>())
|
if (!syncType.isa<NoneType>())
|
||||||
return emitOpError("data type for sync port for store port ")
|
return emitOpError("data type for sync port for store port ")
|
||||||
<< i << ":" << syncType << " is not 'none'";
|
<< i << ":" << syncType << " is not 'none'";
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < ldCount; i++) {
|
for (unsigned i = 0; i < opLdCount; i++) {
|
||||||
Type syncType = outputType[ldCount + stCount + i];
|
Type syncType = outputType[opLdCount + opStCount + i];
|
||||||
if (!syncType.isa<NoneType>())
|
if (!syncType.isa<NoneType>())
|
||||||
return emitOpError("data type for sync port for load port ")
|
return emitOpError("data type for sync port for load port ")
|
||||||
<< i << ":" << syncType << " is not 'none'";
|
<< i << ":" << syncType << " is not 'none'";
|
||||||
|
@ -1383,7 +1379,7 @@ static LogicalResult verifyMemoryAccessOp(TMemoryOp op) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult LoadOp::verify() { return verifyMemoryAccessOp((*this)); }
|
LogicalResult LoadOp::verify() { return verifyMemoryAccessOp(*this); }
|
||||||
|
|
||||||
std::string handshake::StoreOp::getResultName(unsigned int idx) {
|
std::string handshake::StoreOp::getResultName(unsigned int idx) {
|
||||||
std::string resName;
|
std::string resName;
|
||||||
|
@ -1410,7 +1406,7 @@ void handshake::StoreOp::build(OpBuilder &builder, OperationState &result,
|
||||||
result.types.append(indices.size(), builder.getIndexType());
|
result.types.append(indices.size(), builder.getIndexType());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult StoreOp::verify() { return verifyMemoryAccessOp((*this)); }
|
LogicalResult StoreOp::verify() { return verifyMemoryAccessOp(*this); }
|
||||||
|
|
||||||
ParseResult StoreOp::parse(OpAsmParser &parser, OperationState &result) {
|
ParseResult StoreOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||||
return parseMemoryAccessOp(parser, result);
|
return parseMemoryAccessOp(parser, result);
|
||||||
|
@ -1469,7 +1465,7 @@ LogicalResult ReturnOp::verify() {
|
||||||
return emitOpError("must have a handshake.func parent");
|
return emitOpError("must have a handshake.func parent");
|
||||||
|
|
||||||
// The operand number and types must match the function signature.
|
// The operand number and types must match the function signature.
|
||||||
const auto &results = function.getType().getResults();
|
const auto &results = function.getResultTypes();
|
||||||
if (getNumOperands() != results.size())
|
if (getNumOperands() != results.size())
|
||||||
return emitOpError("has ")
|
return emitOpError("has ")
|
||||||
<< getNumOperands() << " operands, but enclosing function returns "
|
<< getNumOperands() << " operands, but enclosing function returns "
|
||||||
|
|
|
@ -618,7 +618,7 @@ LogicalResult llhd::EntityOp::verify() {
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult circt::llhd::EntityOp::verifyType() {
|
LogicalResult circt::llhd::EntityOp::verifyType() {
|
||||||
FunctionType type = getType();
|
FunctionType type = getFunctionType();
|
||||||
|
|
||||||
// Fail if function returns any values. An entity's outputs are specially
|
// Fail if function returns any values. An entity's outputs are specially
|
||||||
// marked arguments.
|
// marked arguments.
|
||||||
|
@ -672,7 +672,7 @@ Region *llhd::EntityOp::getCallableRegion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<Type> llhd::EntityOp::getCallableResults() {
|
ArrayRef<Type> llhd::EntityOp::getCallableResults() {
|
||||||
return getType().getResults();
|
return getFunctionType().getResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -699,7 +699,7 @@ LogicalResult circt::llhd::ProcOp::verifyType() {
|
||||||
|
|
||||||
LogicalResult circt::llhd::ProcOp::verifyBody() { return success(); }
|
LogicalResult circt::llhd::ProcOp::verifyBody() { return success(); }
|
||||||
|
|
||||||
LogicalResult circt::llhd::ProcOp::verify() {
|
LogicalResult llhd::ProcOp::verify() {
|
||||||
// Check that the ins attribute is smaller or equal the number of
|
// Check that the ins attribute is smaller or equal the number of
|
||||||
// arguments
|
// arguments
|
||||||
uint64_t numArgs = getNumArguments();
|
uint64_t numArgs = getNumArguments();
|
||||||
|
@ -822,7 +822,7 @@ static void printProcArguments(OpAsmPrinter &p, Operation *op,
|
||||||
}
|
}
|
||||||
|
|
||||||
void llhd::ProcOp::print(OpAsmPrinter &printer) {
|
void llhd::ProcOp::print(OpAsmPrinter &printer) {
|
||||||
FunctionType type = getType();
|
FunctionType type = getFunctionType();
|
||||||
printer << ' ';
|
printer << ' ';
|
||||||
printer.printSymbolName(getName());
|
printer.printSymbolName(getName());
|
||||||
printProcArguments(printer, getOperation(), type.getInputs(),
|
printProcArguments(printer, getOperation(), type.getInputs(),
|
||||||
|
@ -836,7 +836,7 @@ Region *llhd::ProcOp::getCallableRegion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<Type> llhd::ProcOp::getCallableResults() {
|
ArrayRef<Type> llhd::ProcOp::getCallableResults() {
|
||||||
return getType().getResults();
|
return getFunctionType().getResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -852,7 +852,7 @@ LogicalResult llhd::InstOp::verify() {
|
||||||
auto proc = (*this)->getParentOfType<ModuleOp>().lookupSymbol<llhd::ProcOp>(
|
auto proc = (*this)->getParentOfType<ModuleOp>().lookupSymbol<llhd::ProcOp>(
|
||||||
calleeAttr.getValue());
|
calleeAttr.getValue());
|
||||||
if (proc) {
|
if (proc) {
|
||||||
auto type = proc.getType();
|
auto type = proc.getFunctionType();
|
||||||
|
|
||||||
if (proc.ins() != inputs().size())
|
if (proc.ins() != inputs().size())
|
||||||
return emitOpError("incorrect number of inputs for proc instantiation");
|
return emitOpError("incorrect number of inputs for proc instantiation");
|
||||||
|
@ -872,7 +872,7 @@ LogicalResult llhd::InstOp::verify() {
|
||||||
(*this)->getParentOfType<ModuleOp>().lookupSymbol<llhd::EntityOp>(
|
(*this)->getParentOfType<ModuleOp>().lookupSymbol<llhd::EntityOp>(
|
||||||
calleeAttr.getValue());
|
calleeAttr.getValue());
|
||||||
if (entity) {
|
if (entity) {
|
||||||
auto type = entity.getType();
|
auto type = entity.getFunctionType();
|
||||||
|
|
||||||
if (entity.ins() != inputs().size())
|
if (entity.ins() != inputs().size())
|
||||||
return emitOpError("incorrect number of inputs for entity instantiation");
|
return emitOpError("incorrect number of inputs for entity instantiation");
|
||||||
|
@ -893,7 +893,7 @@ LogicalResult llhd::InstOp::verify() {
|
||||||
(*this)->getParentOfType<ModuleOp>().lookupSymbol<hw::HWModuleOp>(
|
(*this)->getParentOfType<ModuleOp>().lookupSymbol<hw::HWModuleOp>(
|
||||||
calleeAttr.getValue());
|
calleeAttr.getValue());
|
||||||
if (module) {
|
if (module) {
|
||||||
auto type = module.getType();
|
auto type = module.getFunctionType();
|
||||||
|
|
||||||
if (type.getNumInputs() != inputs().size())
|
if (type.getNumInputs() != inputs().size())
|
||||||
return emitOpError(
|
return emitOpError(
|
||||||
|
|
|
@ -44,7 +44,7 @@ void FunctionEliminationPass::runOnOperation() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.walk([](mlir::FuncOp op) { op.erase(); });
|
module.walk([](mlir::func::FuncOp op) { op.erase(); });
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ void ProcessLoweringPass::runOnOperation() {
|
||||||
// Move all blocks from the process to the entity, the process does not have
|
// Move all blocks from the process to the entity, the process does not have
|
||||||
// a region afterwards.
|
// a region afterwards.
|
||||||
entity.body().takeBody(op.body());
|
entity.body().takeBody(op.body());
|
||||||
entity->setAttr("type", op->getAttr("type"));
|
entity->setAttr("function_type", op->getAttr("function_type"));
|
||||||
// In the case that wait is used to suspend the process, we need to merge
|
// In the case that wait is used to suspend the process, we need to merge
|
||||||
// the two blocks as we needed the second block to have a target for wait
|
// the two blocks as we needed the second block to have a target for wait
|
||||||
// (the entry block cannot be targeted).
|
// (the entry block cannot be targeted).
|
||||||
|
|
|
@ -145,7 +145,7 @@ InstanceOp::verifySignatureMatch(const hw::ModulePortInfo &ports) {
|
||||||
/// Consider adding a `HasModulePorts` op interface to facilitate.
|
/// Consider adding a `HasModulePorts` op interface to facilitate.
|
||||||
hw::ModulePortInfo MSFTModuleOp::getPorts() {
|
hw::ModulePortInfo MSFTModuleOp::getPorts() {
|
||||||
SmallVector<hw::PortInfo> inputs, outputs;
|
SmallVector<hw::PortInfo> inputs, outputs;
|
||||||
auto argTypes = getType().getInputs();
|
auto argTypes = getArgumentTypes();
|
||||||
|
|
||||||
auto argNames = this->argNames();
|
auto argNames = this->argNames();
|
||||||
for (unsigned i = 0, e = argTypes.size(); i < e; ++i) {
|
for (unsigned i = 0, e = argTypes.size(); i < e; ++i) {
|
||||||
|
@ -163,7 +163,7 @@ hw::ModulePortInfo MSFTModuleOp::getPorts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resultNames = this->resultNames();
|
auto resultNames = this->resultNames();
|
||||||
auto resultTypes = getType().getResults();
|
auto resultTypes = getResultTypes();
|
||||||
for (unsigned i = 0, e = resultTypes.size(); i < e; ++i) {
|
for (unsigned i = 0, e = resultTypes.size(); i < e; ++i) {
|
||||||
outputs.push_back({resultNames[i].cast<StringAttr>(),
|
outputs.push_back({resultNames[i].cast<StringAttr>(),
|
||||||
hw::PortDirection::OUTPUT, resultTypes[i], i});
|
hw::PortDirection::OUTPUT, resultTypes[i], i});
|
||||||
|
@ -175,12 +175,11 @@ SmallVector<BlockArgument>
|
||||||
MSFTModuleOp::addPorts(ArrayRef<std::pair<StringAttr, Type>> inputs,
|
MSFTModuleOp::addPorts(ArrayRef<std::pair<StringAttr, Type>> inputs,
|
||||||
ArrayRef<std::pair<StringAttr, Value>> outputs) {
|
ArrayRef<std::pair<StringAttr, Value>> outputs) {
|
||||||
auto *ctxt = getContext();
|
auto *ctxt = getContext();
|
||||||
FunctionType ftype = getType();
|
|
||||||
Block *body = getBodyBlock();
|
Block *body = getBodyBlock();
|
||||||
|
|
||||||
// Append new inputs.
|
// Append new inputs.
|
||||||
SmallVector<Type, 32> modifiedArgs(ftype.getInputs().begin(),
|
SmallVector<Type, 32> modifiedArgs(getArgumentTypes().begin(),
|
||||||
ftype.getInputs().end());
|
getArgumentTypes().end());
|
||||||
SmallVector<Attribute> modifiedArgNames(argNames().getAsRange<Attribute>());
|
SmallVector<Attribute> modifiedArgNames(argNames().getAsRange<Attribute>());
|
||||||
SmallVector<BlockArgument> newBlockArgs;
|
SmallVector<BlockArgument> newBlockArgs;
|
||||||
for (auto ttPair : inputs) {
|
for (auto ttPair : inputs) {
|
||||||
|
@ -192,8 +191,8 @@ MSFTModuleOp::addPorts(ArrayRef<std::pair<StringAttr, Type>> inputs,
|
||||||
argNamesAttr(ArrayAttr::get(ctxt, modifiedArgNames));
|
argNamesAttr(ArrayAttr::get(ctxt, modifiedArgNames));
|
||||||
|
|
||||||
// Append new outputs.
|
// Append new outputs.
|
||||||
SmallVector<Type, 32> modifiedResults(ftype.getResults().begin(),
|
SmallVector<Type, 32> modifiedResults(getResultTypes().begin(),
|
||||||
ftype.getResults().end());
|
getResultTypes().end());
|
||||||
SmallVector<Attribute> modifiedResultNames(
|
SmallVector<Attribute> modifiedResultNames(
|
||||||
resultNames().getAsRange<Attribute>());
|
resultNames().getAsRange<Attribute>());
|
||||||
Operation *terminator = body->getTerminator();
|
Operation *terminator = body->getTerminator();
|
||||||
|
@ -215,7 +214,7 @@ MSFTModuleOp::addPorts(ArrayRef<std::pair<StringAttr, Type>> inputs,
|
||||||
SmallVector<unsigned> MSFTModuleOp::removePorts(llvm::BitVector inputs,
|
SmallVector<unsigned> MSFTModuleOp::removePorts(llvm::BitVector inputs,
|
||||||
llvm::BitVector outputs) {
|
llvm::BitVector outputs) {
|
||||||
MLIRContext *ctxt = getContext();
|
MLIRContext *ctxt = getContext();
|
||||||
FunctionType ftype = getType();
|
FunctionType ftype = getFunctionType();
|
||||||
Block *body = getBodyBlock();
|
Block *body = getBodyBlock();
|
||||||
Operation *terminator = body->getTerminator();
|
Operation *terminator = body->getTerminator();
|
||||||
|
|
||||||
|
@ -460,9 +459,8 @@ ParseResult MSFTModuleOp::parse(OpAsmParser &parser, OperationState &result) {
|
||||||
void MSFTModuleOp::print(OpAsmPrinter &p) {
|
void MSFTModuleOp::print(OpAsmPrinter &p) {
|
||||||
using namespace mlir::function_interface_impl;
|
using namespace mlir::function_interface_impl;
|
||||||
|
|
||||||
FunctionType fnType = getType();
|
auto argTypes = getArgumentTypes();
|
||||||
auto argTypes = fnType.getInputs();
|
auto resultTypes = getResultTypes();
|
||||||
auto resultTypes = fnType.getResults();
|
|
||||||
|
|
||||||
// Print the operation and the function name.
|
// Print the operation and the function name.
|
||||||
p << ' ';
|
p << ' ';
|
||||||
|
|
|
@ -581,9 +581,8 @@ SmallVector<InstanceOp, 1> &PassCommon::updateInstances(
|
||||||
for (InstanceOp inst : moduleInstantiations[mod]) {
|
for (InstanceOp inst : moduleInstantiations[mod]) {
|
||||||
assert(inst->getParentOp());
|
assert(inst->getParentOp());
|
||||||
OpBuilder b(inst);
|
OpBuilder b(inst);
|
||||||
auto newInst =
|
auto newInst = b.create<InstanceOp>(inst.getLoc(), mod.getResultTypes(),
|
||||||
b.create<InstanceOp>(inst.getLoc(), mod.getType().getResults(),
|
inst.getOperands(), inst->getAttrs());
|
||||||
inst.getOperands(), inst->getAttrs());
|
|
||||||
|
|
||||||
SmallVector<Value> newOperands;
|
SmallVector<Value> newOperands;
|
||||||
getOperandsFunc(newInst, inst, newOperands);
|
getOperandsFunc(newInst, inst, newOperands);
|
||||||
|
@ -1128,7 +1127,7 @@ static SmallVector<unsigned> makeSequentialRange(unsigned size) {
|
||||||
|
|
||||||
void PartitionPass::bubbleUp(MSFTModuleOp mod, Block *partBlock) {
|
void PartitionPass::bubbleUp(MSFTModuleOp mod, Block *partBlock) {
|
||||||
auto *ctxt = mod.getContext();
|
auto *ctxt = mod.getContext();
|
||||||
FunctionType origType = mod.getType();
|
FunctionType origType = mod.getFunctionType();
|
||||||
std::string nameBuffer;
|
std::string nameBuffer;
|
||||||
|
|
||||||
//*************
|
//*************
|
||||||
|
@ -1483,7 +1482,7 @@ void PassCommon::dedupOutputs(MSFTModuleOp mod) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.removePorts(llvm::BitVector(mod.getNumArguments()), outputPortsToRemove);
|
mod.removePorts(llvm::BitVector(mod.getNumArguments()), outputPortsToRemove);
|
||||||
updateInstances(mod, makeSequentialRange(mod.getType().getNumResults()),
|
updateInstances(mod, makeSequentialRange(mod.getNumResults()),
|
||||||
[&](InstanceOp newInst, InstanceOp oldInst,
|
[&](InstanceOp newInst, InstanceOp oldInst,
|
||||||
SmallVectorImpl<Value> &newOperands) {
|
SmallVectorImpl<Value> &newOperands) {
|
||||||
// Operands don't change.
|
// Operands don't change.
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
using namespace circt;
|
using namespace circt;
|
||||||
using namespace sv;
|
using namespace sv;
|
||||||
|
|
||||||
static LogicalResult verifyIndexedPartSelectOp(Operation *op);
|
|
||||||
/// Return true if the specified operation is an expression.
|
/// Return true if the specified operation is an expression.
|
||||||
bool sv::isExpression(Operation *op) {
|
bool sv::isExpression(Operation *op) {
|
||||||
return isa<VerbatimExprOp, VerbatimExprSEOp, GetModportOp,
|
return isa<VerbatimExprOp, VerbatimExprSEOp, GetModportOp,
|
||||||
|
@ -212,7 +211,7 @@ void LocalParamOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
|
||||||
LogicalResult LocalParamOp::verify() {
|
LogicalResult LocalParamOp::verify() {
|
||||||
// Verify that this is a valid parameter value.
|
// Verify that this is a valid parameter value.
|
||||||
return hw::checkParameterInContext(
|
return hw::checkParameterInContext(
|
||||||
value(), (*this)->getParentOfType<hw::HWModuleOp>(), (*this));
|
value(), (*this)->getParentOfType<hw::HWModuleOp>(), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -873,7 +872,7 @@ void InterfaceModportOp::build(OpBuilder &builder, OperationState &state,
|
||||||
|
|
||||||
/// Ensure that the symbol being instantiated exists and is an InterfaceOp.
|
/// Ensure that the symbol being instantiated exists and is an InterfaceOp.
|
||||||
LogicalResult InterfaceInstanceOp::verify() {
|
LogicalResult InterfaceInstanceOp::verify() {
|
||||||
auto *symtable = SymbolTable::getNearestSymbolTable((*this));
|
auto *symtable = SymbolTable::getNearestSymbolTable(*this);
|
||||||
if (!symtable)
|
if (!symtable)
|
||||||
return emitError("sv.interface.instance must exist within a region "
|
return emitError("sv.interface.instance must exist within a region "
|
||||||
"which has a symbol table.");
|
"which has a symbol table.");
|
||||||
|
@ -891,7 +890,7 @@ LogicalResult InterfaceInstanceOp::verify() {
|
||||||
/// Ensure that the symbol being instantiated exists and is an
|
/// Ensure that the symbol being instantiated exists and is an
|
||||||
/// InterfaceModportOp.
|
/// InterfaceModportOp.
|
||||||
LogicalResult GetModportOp::verify() {
|
LogicalResult GetModportOp::verify() {
|
||||||
auto *symtable = SymbolTable::getNearestSymbolTable((*this));
|
auto *symtable = SymbolTable::getNearestSymbolTable(*this);
|
||||||
if (!symtable)
|
if (!symtable)
|
||||||
return emitError("sv.interface.instance must exist within a region "
|
return emitError("sv.interface.instance must exist within a region "
|
||||||
"which has a symbol table.");
|
"which has a symbol table.");
|
||||||
|
@ -1131,7 +1130,29 @@ LogicalResult IndexedPartSelectInOutOp::inferReturnTypes(
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult IndexedPartSelectInOutOp::verify() {
|
LogicalResult IndexedPartSelectInOutOp::verify() {
|
||||||
return verifyIndexedPartSelectOp(*this);
|
unsigned inputWidth = 0, resultWidth = 0;
|
||||||
|
auto opWidth = width();
|
||||||
|
|
||||||
|
if (auto i = input()
|
||||||
|
.getType()
|
||||||
|
.cast<InOutType>()
|
||||||
|
.getElementType()
|
||||||
|
.dyn_cast<IntegerType>())
|
||||||
|
inputWidth = i.getWidth();
|
||||||
|
else
|
||||||
|
return emitError("input element type must be Integer");
|
||||||
|
|
||||||
|
if (auto resType =
|
||||||
|
getType().cast<InOutType>().getElementType().dyn_cast<IntegerType>())
|
||||||
|
resultWidth = resType.getWidth();
|
||||||
|
else
|
||||||
|
return emitError("result element type must be Integer");
|
||||||
|
|
||||||
|
if (opWidth > inputWidth)
|
||||||
|
return emitError("slice width should not be greater than input width");
|
||||||
|
if (opWidth != resultWidth)
|
||||||
|
return emitError("result width must be equal to slice width");
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpFoldResult IndexedPartSelectInOutOp::fold(ArrayRef<Attribute> constants) {
|
OpFoldResult IndexedPartSelectInOutOp::fold(ArrayRef<Attribute> constants) {
|
||||||
|
@ -1151,10 +1172,6 @@ void IndexedPartSelectOp::build(OpBuilder &builder, OperationState &result,
|
||||||
build(builder, result, resultType, input, base, width, decrement);
|
build(builder, result, resultType, input, base, width, decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalResult IndexedPartSelectOp::verify() {
|
|
||||||
return verifyIndexedPartSelectOp(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogicalResult IndexedPartSelectOp::inferReturnTypes(
|
LogicalResult IndexedPartSelectOp::inferReturnTypes(
|
||||||
MLIRContext *context, Optional<Location> loc, ValueRange operands,
|
MLIRContext *context, Optional<Location> loc, ValueRange operands,
|
||||||
DictionaryAttr attrs, mlir::RegionRange regions,
|
DictionaryAttr attrs, mlir::RegionRange regions,
|
||||||
|
@ -1168,44 +1185,18 @@ LogicalResult IndexedPartSelectOp::inferReturnTypes(
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
static LogicalResult verifyIndexedPartSelectOp(Operation *op) {
|
LogicalResult IndexedPartSelectOp::verify() {
|
||||||
return TypeSwitch<Operation *, LogicalResult>(op)
|
auto opWidth = width();
|
||||||
.Case<IndexedPartSelectOp, IndexedPartSelectInOutOp>(
|
|
||||||
[&](auto p) -> LogicalResult {
|
|
||||||
unsigned inputWidth = 0, resultWidth = 0;
|
|
||||||
auto width = p.width();
|
|
||||||
if (isa<IndexedPartSelectInOutOp>(p)) {
|
|
||||||
if (auto i = p.input()
|
|
||||||
.getType()
|
|
||||||
.template cast<InOutType>()
|
|
||||||
.getElementType()
|
|
||||||
.template dyn_cast<IntegerType>())
|
|
||||||
inputWidth = i.getWidth();
|
|
||||||
else
|
|
||||||
return op->emitError("input element type must be Integer");
|
|
||||||
if (auto resType = p.getType()
|
|
||||||
.template cast<InOutType>()
|
|
||||||
.getElementType()
|
|
||||||
.template dyn_cast<IntegerType>())
|
|
||||||
resultWidth = resType.getWidth();
|
|
||||||
else
|
|
||||||
return op->emitError("result element type must be Integer");
|
|
||||||
} else {
|
|
||||||
resultWidth = p.getType().template cast<IntegerType>().getWidth();
|
|
||||||
inputWidth =
|
|
||||||
p.input().getType().template cast<IntegerType>().getWidth();
|
|
||||||
}
|
|
||||||
if (width > inputWidth)
|
|
||||||
return op->emitError(
|
|
||||||
"slice width should not be greater than input width");
|
|
||||||
if (width != resultWidth)
|
|
||||||
return op->emitError("result width must be equal to slice width");
|
|
||||||
return success();
|
|
||||||
})
|
|
||||||
.Default([&](auto) { return failure(); });
|
|
||||||
|
|
||||||
|
unsigned resultWidth = getType().cast<IntegerType>().getWidth();
|
||||||
|
unsigned inputWidth = input().getType().cast<IntegerType>().getWidth();
|
||||||
|
|
||||||
|
if (opWidth > inputWidth)
|
||||||
|
return emitError("slice width should not be greater than input width");
|
||||||
|
if (opWidth != resultWidth)
|
||||||
|
return emitError("result width must be equal to slice width");
|
||||||
return success();
|
return success();
|
||||||
}
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// StructFieldInOutOp
|
// StructFieldInOutOp
|
||||||
|
|
|
@ -292,8 +292,8 @@ LogicalResult PipelineTerminatorOp::verify() {
|
||||||
"'iter_args' must be defined by a 'staticlogic.pipeline.stage'");
|
"'iter_args' must be defined by a 'staticlogic.pipeline.stage'");
|
||||||
|
|
||||||
// Verify pipeline terminates with the same result types as the pipeline.
|
// Verify pipeline terminates with the same result types as the pipeline.
|
||||||
auto results = (*this).results();
|
auto opResults = results();
|
||||||
TypeRange terminatorResultTypes = results.getTypes();
|
TypeRange terminatorResultTypes = opResults.getTypes();
|
||||||
TypeRange pipelineResultTypes = pipeline.getResultTypes();
|
TypeRange pipelineResultTypes = pipeline.getResultTypes();
|
||||||
if (terminatorResultTypes != pipelineResultTypes)
|
if (terminatorResultTypes != pipelineResultTypes)
|
||||||
return emitOpError("'results' types (")
|
return emitOpError("'results' types (")
|
||||||
|
@ -301,7 +301,7 @@ LogicalResult PipelineTerminatorOp::verify() {
|
||||||
<< pipelineResultTypes << ")";
|
<< pipelineResultTypes << ")";
|
||||||
|
|
||||||
// Verify `results` are defined by a pipeline stage.
|
// Verify `results` are defined by a pipeline stage.
|
||||||
for (auto result : results)
|
for (auto result : opResults)
|
||||||
if (result.getDefiningOp<PipelineStageOp>() == nullptr)
|
if (result.getDefiningOp<PipelineStageOp>() == nullptr)
|
||||||
return emitOpError(
|
return emitOpError(
|
||||||
"'results' must be defined by a 'staticlogic.pipeline.stage'");
|
"'results' must be defined by a 'staticlogic.pipeline.stage'");
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "circt/Scheduling/Algorithms.h"
|
#include "circt/Scheduling/Algorithms.h"
|
||||||
|
|
||||||
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/Pass/Pass.h"
|
#include "mlir/Pass/Pass.h"
|
||||||
|
|
||||||
|
|
|
@ -248,17 +248,16 @@ static void populateFlattenMemRefsLegality(ConversionTarget &target) {
|
||||||
addGenericLegalityConstraint<func::CallOp>(target);
|
addGenericLegalityConstraint<func::CallOp>(target);
|
||||||
addGenericLegalityConstraint<func::ReturnOp>(target);
|
addGenericLegalityConstraint<func::ReturnOp>(target);
|
||||||
|
|
||||||
target.addDynamicallyLegalOp<mlir::FuncOp>([](mlir::FuncOp op) {
|
target.addDynamicallyLegalOp<FuncOp>([](FuncOp op) {
|
||||||
auto argsConverted = llvm::none_of(op.getBlocks(), [](auto &block) {
|
auto argsConverted = llvm::none_of(op.getBlocks(), [](auto &block) {
|
||||||
return hasMultiDimMemRef(block.getArguments());
|
return hasMultiDimMemRef(block.getArguments());
|
||||||
});
|
});
|
||||||
|
|
||||||
auto resultsConverted =
|
auto resultsConverted = llvm::all_of(op.getResultTypes(), [](Type type) {
|
||||||
llvm::all_of(op.getType().getResults(), [](Type type) {
|
if (auto memref = type.dyn_cast<MemRefType>())
|
||||||
if (auto memref = type.dyn_cast<MemRefType>())
|
return isUniDimensional(memref);
|
||||||
return isUniDimensional(memref);
|
return true;
|
||||||
return true;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return argsConverted && resultsConverted;
|
return argsConverted && resultsConverted;
|
||||||
});
|
});
|
||||||
|
|
2
llvm
2
llvm
|
@ -1 +1 @@
|
||||||
Subproject commit 61814586620deca51ecf6477e19c6afa8e28ad90
|
Subproject commit 5cd9fa551e4f22de63351bda44113428fe53fcdb
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
firrtl.circuit "OperandTypeIsFIRRTL" {
|
firrtl.circuit "OperandTypeIsFIRRTL" {
|
||||||
firrtl.module @OperandTypeIsFIRRTL() { }
|
firrtl.module @OperandTypeIsFIRRTL() { }
|
||||||
builtin.func @Test() {
|
func.func @Test() {
|
||||||
// expected-error @+1 {{Found unhandled FIRRTL operation 'firrtl.constant'}}
|
// expected-error @+1 {{Found unhandled FIRRTL operation 'firrtl.constant'}}
|
||||||
%a = firrtl.constant 0 : !firrtl.uint<1>
|
%a = firrtl.constant 0 : !firrtl.uint<1>
|
||||||
return
|
return
|
||||||
|
@ -29,7 +29,7 @@ firrtl.circuit "ResultTypeIsFIRRTL" {
|
||||||
|
|
||||||
firrtl.circuit "RecursiveCheck" {
|
firrtl.circuit "RecursiveCheck" {
|
||||||
firrtl.module @RecursiveCheck() { }
|
firrtl.module @RecursiveCheck() { }
|
||||||
builtin.func private @CheckRecursive() {
|
func.func private @CheckRecursive() {
|
||||||
// expected-error @+1 {{fake_op' op found unhandled FIRRTL type}}
|
// expected-error @+1 {{fake_op' op found unhandled FIRRTL type}}
|
||||||
%1 = "fake_op"() : () -> (!firrtl.uint<1>)
|
%1 = "fake_op"() : () -> (!firrtl.uint<1>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,25 +9,25 @@
|
||||||
// CHECK-NEXT: %[[P0:.*]] = llhd.prb %[[ARG0]]
|
// CHECK-NEXT: %[[P0:.*]] = llhd.prb %[[ARG0]]
|
||||||
%1 = llhd.prb %arg0 : !llhd.sig<i64>
|
%1 = llhd.prb %arg0 : !llhd.sig<i64>
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
}) {sym_name="foo", ins=2, type=(!llhd.sig<i64>, !llhd.sig<i64>, !llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="foo", ins=2, function_type=(!llhd.sig<i64>, !llhd.sig<i64>, !llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
||||||
// check 0 inputs, empty body
|
// check 0 inputs, empty body
|
||||||
// CHECK-NEXT: llhd.entity @bar () -> (%{{.*}} : !llhd.sig<i64>) {
|
// CHECK-NEXT: llhd.entity @bar () -> (%{{.*}} : !llhd.sig<i64>) {
|
||||||
"llhd.entity"() ({
|
"llhd.entity"() ({
|
||||||
^body(%0 : !llhd.sig<i64>):
|
^body(%0 : !llhd.sig<i64>):
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
}) {sym_name="bar", ins=0, type=(!llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="bar", ins=0, function_type=(!llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
||||||
// check 0 outputs, empty body
|
// check 0 outputs, empty body
|
||||||
// CHECK-NEXT: llhd.entity @baz (%{{.*}} : !llhd.sig<i64>) -> () {
|
// CHECK-NEXT: llhd.entity @baz (%{{.*}} : !llhd.sig<i64>) -> () {
|
||||||
"llhd.entity"() ({
|
"llhd.entity"() ({
|
||||||
^body(%arg0 : !llhd.sig<i64>):
|
^body(%arg0 : !llhd.sig<i64>):
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
}) {sym_name="baz", ins=1, type=(!llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="baz", ins=1, function_type=(!llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
||||||
//check 0 arguments, empty body
|
//check 0 arguments, empty body
|
||||||
// CHECK-NEXT: llhd.entity @out_of_names () -> () {
|
// CHECK-NEXT: llhd.entity @out_of_names () -> () {
|
||||||
"llhd.entity"() ({
|
"llhd.entity"() ({
|
||||||
^body:
|
^body:
|
||||||
// CHECK-NEXT : }
|
// CHECK-NEXT : }
|
||||||
}) {sym_name="out_of_names", ins=0, type=()->()} : () -> ()
|
}) {sym_name="out_of_names", ins=0, function_type=()->()} : () -> ()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// CHECK: llhd.halt
|
// CHECK: llhd.halt
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
"llhd.halt"() {} : () -> ()
|
"llhd.halt"() {} : () -> ()
|
||||||
}) {sym_name="empty", ins=0, type=()->()} : () -> ()
|
}) {sym_name="empty", ins=0, function_type=()->()} : () -> ()
|
||||||
|
|
||||||
// two inputs, one output
|
// two inputs, one output
|
||||||
// CHECK-NEXT: llhd.proc @inputandoutput(%{{.*}} : !llhd.sig<i64>, %{{.*}} : !llhd.sig<i64>) -> (%{{.*}} : !llhd.sig<i64>) {
|
// CHECK-NEXT: llhd.proc @inputandoutput(%{{.*}} : !llhd.sig<i64>, %{{.*}} : !llhd.sig<i64>) -> (%{{.*}} : !llhd.sig<i64>) {
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
^body(%arg0 : !llhd.sig<i64>, %arg1 : !llhd.sig<i64>, %out0 : !llhd.sig<i64>):
|
^body(%arg0 : !llhd.sig<i64>, %arg1 : !llhd.sig<i64>, %out0 : !llhd.sig<i64>):
|
||||||
"llhd.halt"() {} : () -> ()
|
"llhd.halt"() {} : () -> ()
|
||||||
}) {sym_name="inputandoutput", ins=2, type=(!llhd.sig<i64>, !llhd.sig<i64>, !llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="inputandoutput", ins=2, function_type=(!llhd.sig<i64>, !llhd.sig<i64>, !llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
||||||
// zero inputs, one output
|
// zero inputs, one output
|
||||||
// CHECK-NEXT: llhd.proc @output() -> (%{{.*}} : !llhd.sig<i64>) {
|
// CHECK-NEXT: llhd.proc @output() -> (%{{.*}} : !llhd.sig<i64>) {
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
^body(%0 : !llhd.sig<i64>):
|
^body(%0 : !llhd.sig<i64>):
|
||||||
"llhd.halt"() {} : () -> ()
|
"llhd.halt"() {} : () -> ()
|
||||||
}) {sym_name="output", ins=0, type=(!llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="output", ins=0, function_type=(!llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
||||||
// one input, zero outputs
|
// one input, zero outputs
|
||||||
// CHECK-NEXT: llhd.proc @input(%{{.*}} : !llhd.sig<i64>) -> () {
|
// CHECK-NEXT: llhd.proc @input(%{{.*}} : !llhd.sig<i64>) -> () {
|
||||||
|
@ -33,4 +33,4 @@
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
^body(%arg0 : !llhd.sig<i64>):
|
^body(%arg0 : !llhd.sig<i64>):
|
||||||
"llhd.halt"() {} : () -> ()
|
"llhd.halt"() {} : () -> ()
|
||||||
}) {sym_name="input", ins=1, type=(!llhd.sig<i64>)->()} : () -> ()
|
}) {sym_name="input", ins=1, function_type=(!llhd.sig<i64>)->()} : () -> ()
|
||||||
|
|
|
@ -559,8 +559,7 @@ LogicalResult HandshakeExecuter::execute(mlir::CallOpInterface callOp,
|
||||||
auto op = callOp.getOperation();
|
auto op = callOp.getOperation();
|
||||||
mlir::Operation *calledOp = callOp.resolveCallable();
|
mlir::Operation *calledOp = callOp.resolveCallable();
|
||||||
if (auto funcOp = dyn_cast<mlir::FuncOp>(calledOp)) {
|
if (auto funcOp = dyn_cast<mlir::FuncOp>(calledOp)) {
|
||||||
mlir::FunctionType ftype = funcOp.getType();
|
unsigned outputs = funcOp.getNumResults();
|
||||||
unsigned outputs = ftype.getNumResults();
|
|
||||||
llvm::DenseMap<mlir::Value, Any> newValueMap;
|
llvm::DenseMap<mlir::Value, Any> newValueMap;
|
||||||
llvm::DenseMap<mlir::Value, double> newTimeMap;
|
llvm::DenseMap<mlir::Value, double> newTimeMap;
|
||||||
std::vector<Any> results(outputs);
|
std::vector<Any> results(outputs);
|
||||||
|
@ -602,7 +601,7 @@ LogicalResult HandshakeExecuter::execute(handshake::InstanceOp instanceOp,
|
||||||
/// intanceOp - available in the enclosing scope value map - and the
|
/// intanceOp - available in the enclosing scope value map - and the
|
||||||
/// argument SSA values within the called function of the InstanceOp.
|
/// argument SSA values within the called function of the InstanceOp.
|
||||||
|
|
||||||
const unsigned nRealFuncOuts = func.getType().getNumResults() - 1;
|
const unsigned nRealFuncOuts = func.getNumResults() - 1;
|
||||||
mlir::Block &entryBlock = func.getBody().front();
|
mlir::Block &entryBlock = func.getBody().front();
|
||||||
mlir::Block::BlockArgListType instanceBlockArgs =
|
mlir::Block::BlockArgListType instanceBlockArgs =
|
||||||
entryBlock.getArguments();
|
entryBlock.getArguments();
|
||||||
|
@ -915,25 +914,25 @@ bool simulate(StringRef toplevelFunction, ArrayRef<std::string> inputArgs,
|
||||||
|
|
||||||
if (mlir::FuncOp toplevel =
|
if (mlir::FuncOp toplevel =
|
||||||
module->lookupSymbol<mlir::FuncOp>(toplevelFunction)) {
|
module->lookupSymbol<mlir::FuncOp>(toplevelFunction)) {
|
||||||
ftype = toplevel.getType();
|
ftype = toplevel.getFunctionType();
|
||||||
mlir::Block &entryBlock = toplevel.getBody().front();
|
mlir::Block &entryBlock = toplevel.getBody().front();
|
||||||
blockArgs = entryBlock.getArguments();
|
blockArgs = entryBlock.getArguments();
|
||||||
|
|
||||||
// Get the primary inputs of toplevel off the command line.
|
// Get the primary inputs of toplevel off the command line.
|
||||||
inputs = ftype.getNumInputs();
|
inputs = toplevel.getNumArguments();
|
||||||
realInputs = inputs;
|
realInputs = inputs;
|
||||||
outputs = ftype.getNumResults();
|
outputs = toplevel.getNumResults();
|
||||||
realOutputs = outputs;
|
realOutputs = outputs;
|
||||||
} else if (handshake::FuncOp toplevel =
|
} else if (handshake::FuncOp toplevel =
|
||||||
module->lookupSymbol<handshake::FuncOp>(toplevelFunction)) {
|
module->lookupSymbol<handshake::FuncOp>(toplevelFunction)) {
|
||||||
ftype = toplevel.getType();
|
ftype = toplevel.getFunctionType();
|
||||||
mlir::Block &entryBlock = toplevel.getBody().front();
|
mlir::Block &entryBlock = toplevel.getBody().front();
|
||||||
blockArgs = entryBlock.getArguments();
|
blockArgs = entryBlock.getArguments();
|
||||||
|
|
||||||
// Get the primary inputs of toplevel off the command line.
|
// Get the primary inputs of toplevel off the command line.
|
||||||
inputs = ftype.getNumInputs();
|
inputs = toplevel.getNumArguments();
|
||||||
realInputs = inputs - 1;
|
realInputs = inputs - 1;
|
||||||
outputs = ftype.getNumResults();
|
outputs = toplevel.getNumResults();
|
||||||
realOutputs = outputs - 1;
|
realOutputs = outputs - 1;
|
||||||
if (inputs == 0) {
|
if (inputs == 0) {
|
||||||
errs() << "Function " << toplevelFunction << " is expected to have "
|
errs() << "Function " << toplevelFunction << " is expected to have "
|
||||||
|
|
Loading…
Reference in New Issue