Skip to content

Commit

Permalink
Merge branch 'main' into dev/hidetou/comb-to-aig-add
Browse files Browse the repository at this point in the history
  • Loading branch information
uenoku authored Dec 13, 2024
2 parents 16d3da8 + b7a0513 commit e7370f6
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 29 deletions.
87 changes: 84 additions & 3 deletions include/circt-c/Dialect/FIRRTL.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,74 @@ MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(FIRRTL, firrtl);
// Type API.
//===----------------------------------------------------------------------===//

/// Returns `true` if this is a const type whose value is guaranteed to be
/// unchanging at circuit execution time.
MLIR_CAPI_EXPORTED bool firrtlTypeIsConst(MlirType type);

/// Returns a const or non-const version of this type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetConstType(MlirType type, bool isConst);

/// Gets the bit width for this type, returns -1 if unknown.
///
/// It recursively computes the bit width of aggregate types. For bundle and
/// vectors, recursively get the width of each field element and return the
/// total bit width of the aggregate type. This returns -1, if any of the bundle
/// fields is a flip type, or ground type with unknown bit width.
MLIR_CAPI_EXPORTED int64_t firrtlTypeGetBitWidth(MlirType type,
bool ignoreFlip);

/// Checks if this type is a unsigned integer type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAUInt(MlirType type);

/// Creates a unsigned integer type with the specified width.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetUInt(MlirContext ctx, int32_t width);

/// Checks if this type is a signed integer type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsASInt(MlirType type);

/// Creates a signed integer type with the specified width.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetSInt(MlirContext ctx, int32_t width);

/// Checks if this type is a clock type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAClock(MlirType type);

/// Creates a clock type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetClock(MlirContext ctx);

/// Checks if this type is a reset type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAReset(MlirType type);

/// Creates a reset type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetReset(MlirContext ctx);

/// Creates a async reset type.
/// Checks if this type is an async reset type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAAsyncReset(MlirType type);

/// Creates an async reset type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetAsyncReset(MlirContext ctx);

/// Creates a analog type with the specified width.
/// Checks if this type is an analog type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAAnalog(MlirType type);

/// Creates an analog type with the specified width.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetAnalog(MlirContext ctx, int32_t width);

/// Checks if this type is a vector type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAVector(MlirType type);

/// Creates a vector type with the specified element type and count.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetVector(MlirContext ctx,
MlirType element, size_t count);

/// Returns the element type of a vector type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetVectorElement(MlirType vec);

/// Returns the number of elements in a vector type.
MLIR_CAPI_EXPORTED size_t firrtlTypeGetVectorNumElements(MlirType vec);

/// Returns true if the specified type is a bundle type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsABundle(MlirType type);

/// Returns true if the specified type is an open bundle type.
///
/// An open bundle type means that it contains non FIRRTL base types.
Expand All @@ -139,35 +185,70 @@ MLIR_CAPI_EXPORTED bool firrtlTypeIsAOpenBundle(MlirType type);
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetBundle(
MlirContext ctx, size_t count, const FIRRTLBundleField *fields);

/// Returns the number of fields in the bundle type.
MLIR_CAPI_EXPORTED size_t firrtlTypeGetBundleNumFields(MlirType bundle);

/// Returns the field at the specified index in the bundle type.
MLIR_CAPI_EXPORTED bool
firrtlTypeGetBundleFieldByIndex(MlirType type, size_t index,
FIRRTLBundleField *field);

/// Returns the index of the field with the specified name in the bundle type.
MLIR_CAPI_EXPORTED unsigned
firrtlTypeGetBundleFieldIndex(MlirType type, MlirStringRef fieldName);

/// Checks if this type is a ref type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsARef(MlirType type);

/// Creates a ref type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetRef(MlirType target, bool forceable);

/// Checks if this type is an anyref type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAAnyRef(MlirType type);

/// Creates an anyref type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetAnyRef(MlirContext ctx);

/// Checks if this type is a property integer type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAInteger(MlirType type);

/// Creates a property integer type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetInteger(MlirContext ctx);

/// Checks if this type is a property double type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsADouble(MlirType type);

/// Creates a property double type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetDouble(MlirContext ctx);

/// Checks if this type is a property string type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAString(MlirType type);

/// Creates a property string type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetString(MlirContext ctx);

/// Checks if this type is a property boolean type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsABoolean(MlirType type);

/// Creates a property boolean type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetBoolean(MlirContext ctx);

/// Checks if this type is a property path type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAPath(MlirType type);

/// Creates a property path type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetPath(MlirContext ctx);

/// Creates a property path type with the specified element type.
/// Checks if this type is a property list type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAList(MlirType type);

/// Creates a property list type with the specified element type.
MLIR_CAPI_EXPORTED MlirType firrtlTypeGetList(MlirContext ctx,
MlirType elementType);

/// Checks if this type is a class type.
MLIR_CAPI_EXPORTED bool firrtlTypeIsAClass(MlirType type);

/// Creates a class type with the specified name and elements.
MLIR_CAPI_EXPORTED MlirType
firrtlTypeGetClass(MlirContext ctx, MlirAttribute name, size_t numberOfElements,
Expand Down
2 changes: 1 addition & 1 deletion include/circt/Dialect/FSM/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
include "mlir/Pass/PassBase.td"

def PrintFSMGraph : Pass<"fsm-print-graph", "mlir::ModuleOp"> {
let summary = "Print a DOT graph of the module hierarchy.";
let summary = "Print a DOT graph of an FSM's structure.";
let constructor = "circt::fsm::createPrintFSMGraphPass()";
}

Expand Down
1 change: 1 addition & 0 deletions include/circt/Support/FVInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ class FVInt {
SmallString<16> toString(unsigned radix = 10, bool uppercase = true) const {
SmallString<16> str;
bool success = tryToString(str, radix, uppercase);
(void)success;
assert(success && "radix cannot represent FVInt");
return str;
}
Expand Down
98 changes: 98 additions & 0 deletions lib/CAPI/Dialect/FIRRTL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,80 @@ MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(FIRRTL, firrtl,
// Type API.
//===----------------------------------------------------------------------===//

bool firrtlTypeIsConst(MlirType type) { return isConst(unwrap(type)); }

MlirType firrtlTypeGetConstType(MlirType type, bool isConst) {
return wrap(cast<FIRRTLBaseType>(unwrap(type)).getConstType(isConst));
}

int64_t firrtlTypeGetBitWidth(MlirType type, bool ignoreFlip) {
return getBitWidth(cast<FIRRTLBaseType>(unwrap(type)), ignoreFlip)
.value_or(-1);
}

bool firrtlTypeIsAUInt(MlirType type) { return isa<UIntType>(unwrap(type)); }

MlirType firrtlTypeGetUInt(MlirContext ctx, int32_t width) {
return wrap(UIntType::get(unwrap(ctx), width));
}

bool firrtlTypeIsASInt(MlirType type) { return isa<SIntType>(unwrap(type)); }

MlirType firrtlTypeGetSInt(MlirContext ctx, int32_t width) {
return wrap(SIntType::get(unwrap(ctx), width));
}

bool firrtlTypeIsAClock(MlirType type) { return isa<ClockType>(unwrap(type)); }

MlirType firrtlTypeGetClock(MlirContext ctx) {
return wrap(ClockType::get(unwrap(ctx)));
}

bool firrtlTypeIsAReset(MlirType type) { return isa<ResetType>(unwrap(type)); }

MlirType firrtlTypeGetReset(MlirContext ctx) {
return wrap(ResetType::get(unwrap(ctx)));
}

bool firrtlTypeIsAAsyncReset(MlirType type) {
return isa<AsyncResetType>(unwrap(type));
}

MlirType firrtlTypeGetAsyncReset(MlirContext ctx) {
return wrap(AsyncResetType::get(unwrap(ctx)));
}

bool firrtlTypeIsAAnalog(MlirType type) {
return isa<AnalogType>(unwrap(type));
}

MlirType firrtlTypeGetAnalog(MlirContext ctx, int32_t width) {
return wrap(AnalogType::get(unwrap(ctx), width));
}

bool firrtlTypeIsAVector(MlirType type) {
return isa<FVectorType>(unwrap(type));
}

MlirType firrtlTypeGetVector(MlirContext ctx, MlirType element, size_t count) {
auto baseType = cast<FIRRTLBaseType>(unwrap(element));
assert(baseType && "element must be base type");

return wrap(FVectorType::get(baseType, count));
}

MlirType firrtlTypeGetVectorElement(MlirType vec) {
return wrap(cast<FVectorType>(unwrap(vec)).getElementType());
}

size_t firrtlTypeGetVectorNumElements(MlirType vec) {
return cast<FVectorType>(unwrap(vec)).getNumElements();
}

bool firrtlTypeIsABundle(MlirType type) {
return isa<BundleType>(unwrap(type));
}

bool firrtlTypeIsAOpenBundle(MlirType type) {
return isa<OpenBundleType>(unwrap(type));
}
Expand Down Expand Up @@ -98,6 +141,35 @@ MlirType firrtlTypeGetBundle(MlirContext ctx, size_t count,
return wrap(OpenBundleType::get(unwrap(ctx), bundleFields));
}

size_t firrtlTypeGetBundleNumFields(MlirType bundle) {
if (auto bundleType = dyn_cast<BundleType>(unwrap(bundle))) {
return bundleType.getNumElements();
} else if (auto bundleType = dyn_cast<OpenBundleType>(unwrap(bundle))) {
return bundleType.getNumElements();
} else {
llvm_unreachable("must be a bundle type");
}
}

bool firrtlTypeGetBundleFieldByIndex(MlirType type, size_t index,
FIRRTLBundleField *field) {
auto unwrapped = unwrap(type);

auto cvt = [field](auto element) {
field->name = wrap(element.name);
field->isFlip = element.isFlip;
field->type = wrap(element.type);
};
if (auto bundleType = dyn_cast<BundleType>(unwrapped)) {
cvt(bundleType.getElement(index));
return true;
} else if (auto bundleType = dyn_cast<OpenBundleType>(unwrapped)) {
cvt(bundleType.getElement(index));
return true;
}
return false;
}

unsigned firrtlTypeGetBundleFieldIndex(MlirType type, MlirStringRef fieldName) {
std::optional<unsigned> fieldIndex;
if (auto bundleType = dyn_cast<BundleType>(unwrap(type))) {
Expand All @@ -111,44 +183,70 @@ unsigned firrtlTypeGetBundleFieldIndex(MlirType type, MlirStringRef fieldName) {
return fieldIndex.value();
}

bool firrtlTypeIsARef(MlirType type) { return isa<RefType>(unwrap(type)); }

MlirType firrtlTypeGetRef(MlirType target, bool forceable) {
auto baseType = dyn_cast<FIRRTLBaseType>(unwrap(target));
assert(baseType && "target must be base type");

return wrap(RefType::get(baseType, forceable));
}

bool firrtlTypeIsAAnyRef(MlirType type) {
return isa<AnyRefType>(unwrap(type));
}

MlirType firrtlTypeGetAnyRef(MlirContext ctx) {
return wrap(AnyRefType::get(unwrap(ctx)));
}

bool firrtlTypeIsAInteger(MlirType type) {
return isa<FIntegerType>(unwrap(type));
}

MlirType firrtlTypeGetInteger(MlirContext ctx) {
return wrap(FIntegerType::get(unwrap(ctx)));
}

bool firrtlTypeIsADouble(MlirType type) {
return isa<DoubleType>(unwrap(type));
}

MlirType firrtlTypeGetDouble(MlirContext ctx) {
return wrap(DoubleType::get(unwrap(ctx)));
}

bool firrtlTypeIsAString(MlirType type) {
return isa<StringType>(unwrap(type));
}

MlirType firrtlTypeGetString(MlirContext ctx) {
return wrap(StringType::get(unwrap(ctx)));
}

bool firrtlTypeIsABoolean(MlirType type) { return isa<BoolType>(unwrap(type)); }

MlirType firrtlTypeGetBoolean(MlirContext ctx) {
return wrap(BoolType::get(unwrap(ctx)));
}

bool firrtlTypeIsAPath(MlirType type) { return isa<PathType>(unwrap(type)); }

MlirType firrtlTypeGetPath(MlirContext ctx) {
return wrap(PathType::get(unwrap(ctx)));
}

bool firrtlTypeIsAList(MlirType type) { return isa<ListType>(unwrap(type)); }

MlirType firrtlTypeGetList(MlirContext ctx, MlirType elementType) {
auto type = dyn_cast<PropertyType>(unwrap(elementType));
assert(type && "element must be property type");

return wrap(ListType::get(unwrap(ctx), type));
}

bool firrtlTypeIsAClass(MlirType type) { return isa<ClassType>(unwrap(type)); }

MlirType firrtlTypeGetClass(MlirContext ctx, MlirAttribute name,
size_t numberOfElements,
const FIRRTLClassElement *elements) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Conversion/SCFToCalyx/SCFToCalyx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern {
if (auto fileLoc = dyn_cast<mlir::FileLineColLoc>(funcOp->getLoc())) {
std::string filename = fileLoc.getFilename().str();
std::filesystem::path path(filename);
std::string jsonFileName = writeJson.append(".json");
std::string jsonFileName = writeJson.getValue() + ".json";
auto outFileName = path.parent_path().append(jsonFileName);
std::ofstream outFile(outFileName);

Expand Down
2 changes: 2 additions & 0 deletions lib/Dialect/AIG/Transforms/LowerVariadic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ static Value lowerVariadicAndInverterOp(AndInverterOp op, OperandRange operands,
inverts.drop_front(firstHalf), rewriter);
return rewriter.create<AndInverterOp>(op.getLoc(), lhs, rhs);
}

return Value();
}

struct VariadicOpConversion : OpRewritePattern<aig::AndInverterOp> {
Expand Down
3 changes: 1 addition & 2 deletions lib/Dialect/FIRRTL/Transforms/IMDeadCodeElim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,7 @@ void IMDeadCodeElimPass::visitSubelement(Operation *op) {
}

void IMDeadCodeElimPass::rewriteModuleBody(FModuleOp module) {
auto *body = module.getBodyBlock();
assert(isBlockExecutable(body) &&
assert(isBlockExecutable(module.getBodyBlock()) &&
"unreachable modules must be already deleted");

auto removeDeadNonLocalAnnotations = [&](int _, Annotation anno) -> bool {
Expand Down
1 change: 1 addition & 0 deletions lib/Dialect/LLHD/IR/LLHDOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ DeletionKind SigArrayGetOp::rewire(const DestructurableMemorySlot &slot,
const DataLayout &dataLayout) {
APInt idx;
bool result = matchPattern(getIndex(), m_ConstantInt(&idx));
(void)result;
assert(result);
auto index =
IntegerAttr::get(IndexType::get(getContext()), idx.getZExtValue());
Expand Down
1 change: 1 addition & 0 deletions lib/Dialect/LLHD/Transforms/TemporalCodeMotionPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ LogicalResult TemporalCodeMotionPass::runOnProcess(llhd::ProcessOp procOp) {
// TODO: consider the case where a wait brances to itself
for (unsigned currTR = 0; currTR < numTRs; ++currTR) {
unsigned numTRSuccs = trAnalysis.getNumTRSuccessors(currTR);
(void)numTRSuccs;
// NOTE: Above error checks make this impossible to trigger, but the above
// are changed this one might have to be promoted to a proper error message.
assert((numTRSuccs == 1 ||
Expand Down
Loading

0 comments on commit e7370f6

Please sign in to comment.