Update to MLIR 84a6da67e6b2a7 (#96)

Mostly this fixes changes in how APInt is used for op and builder interfaces.
Overall, we are able to remove extra APIs that used to exist to provide int/unsigned
native type interfaces.
This commit is contained in:
stephenneuendorffer 2020-09-21 13:20:00 -07:00 committed by GitHub
parent 7cc6518de0
commit 26d4f4861d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 36 additions and 87 deletions

View File

@ -51,13 +51,6 @@ def MemOp : FIRRTLOp<"mem", [/*MemAlloc*/]> {
$ruw attr-dict `:` type($result)
}];
let builders = [
OpBuilder<"OpBuilder &builder, OperationState &result, "
"FIRRTLType resultType, unsigned readLatency, "
"unsigned writeLatency, uint64_t depth, RUWAttr ruw, "
"StringAttr name = {}">
];
let extraClassDeclaration = [{
enum class PortKind { Read, Write, ReadWrite };
@ -66,10 +59,6 @@ def MemOp : FIRRTLOp<"mem", [/*MemAlloc*/]> {
static FIRRTLType getTypeForPortList(uint64_t depth, FIRRTLType dataType,
ArrayRef<std::pair<Identifier, PortKind>> ports);
uint64_t getDepth() { return depth().getLimitedValue(); }
unsigned getReadLatency() { return readLatency().getLimitedValue(); }
unsigned getWriteLatency() { return writeLatency().getLimitedValue(); }
/// Return the name and kind of ports supported by this memory.
void getPorts(SmallVectorImpl<std::pair<Identifier, PortKind>> &result);

View File

@ -242,12 +242,6 @@ def BitsPrimOp : PrimOp<"bits"> {
];
let extraClassDeclaration = [{
/// Return the highest bit included in the result.
unsigned getHi() { return hi().getLimitedValue(); }
/// Return the lowest bit included in the result.
unsigned getLo() { return lo().getLimitedValue(); }
/// Return the result for inputs with the specified type, returning a null
/// type if the input types are invalid.
static FIRRTLType getResultType(FIRRTLType input, int32_t high,
@ -272,8 +266,6 @@ def HeadPrimOp : PrimOp<"head"> {
let hasCanonicalizer = 1;
let extraClassDeclaration = [{
unsigned getAmount() { return amount().getLimitedValue(); }
/// Return the result for inputs with the specified type, returning a null
/// type if the input types are invalid.
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
@ -348,9 +340,6 @@ class ShiftPrimOp<string mnemonic> : PrimOp<mnemonic> {
}];
let extraClassDeclaration = [{
/// Return the shift amount.
unsigned getAmount() { return amount().getLimitedValue(); }
/// Return the result for inputs with the specified type, returning a null
/// type if the input types are invalid.
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
@ -385,8 +374,6 @@ def TailPrimOp : PrimOp<"tail"> {
let hasCanonicalizer = 1;
let extraClassDeclaration = [{
unsigned getAmount() { return amount().getLimitedValue(); }
/// Return the result for inputs with the specified type, returning a null
/// type if the input types are invalid.
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);

View File

@ -143,15 +143,6 @@ def ExtractOp : RTLOp<"extract", [NoSideEffect]> {
$input `from` $lowBit attr-dict `:` functional-type($input, $result)
}];
let builders = [
OpBuilder<"OpBuilder &builder, OperationState &result, Type resultType, "
"Value input, unsigned lowBit">
];
let extraClassDeclaration = [{
unsigned getLowBit() { return lowBit().getZExtValue(); }
}];
let hasFolder = 1;
let verifier = [{ return ::verifyExtractOp(*this); }];
}

View File

@ -1364,7 +1364,7 @@ struct HandshakeInsertBufferPass
auto bufferOp = builder.create<handshake::BufferOp>(
op->getLoc(), value.getType(), value, /*sequential=*/true,
/*control=*/value.getType().isa<NoneType>(),
/*slots=*/APInt(32, 2));
/*slots=*/2);
value.replaceUsesWithIf(
bufferOp,
function_ref<bool(OpOperand &)>([](OpOperand &operand) -> bool {

View File

@ -482,8 +482,8 @@ LogicalResult FIRRTLLowering::visitExpr(BitsPrimOp op) {
if (!input)
return failure();
Type resultType = builder->getIntegerType(op.getHi() - op.getLo() + 1);
return setLoweringTo<rtl::ExtractOp>(op, resultType, input, op.getLo());
Type resultType = builder->getIntegerType(op.hi() - op.lo() + 1);
return setLoweringTo<rtl::ExtractOp>(op, resultType, input, op.lo());
}
LogicalResult FIRRTLLowering::visitExpr(HeadPrimOp op) {
@ -492,9 +492,9 @@ LogicalResult FIRRTLLowering::visitExpr(HeadPrimOp op) {
return failure();
auto inWidth = input.getType().cast<IntegerType>().getWidth();
Type resultType = builder->getIntegerType(op.getAmount());
Type resultType = builder->getIntegerType(op.amount());
return setLoweringTo<rtl::ExtractOp>(op, resultType, input,
inWidth - op.getAmount());
inWidth - op.amount());
}
LogicalResult FIRRTLLowering::visitExpr(ShlPrimOp op) {
@ -503,12 +503,12 @@ LogicalResult FIRRTLLowering::visitExpr(ShlPrimOp op) {
return failure();
// Handle the degenerate case.
if (op.getAmount() == 0)
if (op.amount() == 0)
return setLowering(op, input);
// TODO: We could keep track of zeros and implicitly CSE them.
auto zero =
builder->create<rtl::ConstantOp>(op.getLoc(), APInt(op.getAmount(), 0));
builder->create<rtl::ConstantOp>(op.getLoc(), APInt(op.amount(), 0));
return setLoweringTo<rtl::ConcatOp>(op, ValueRange({input, zero}));
}
@ -519,7 +519,7 @@ LogicalResult FIRRTLLowering::visitExpr(ShrPrimOp op) {
// Handle the special degenerate cases.
auto inWidth = input.getType().cast<IntegerType>().getWidth();
auto shiftAmount = op.getAmount();
auto shiftAmount = op.amount();
if (shiftAmount == inWidth) {
// Unsigned shift by full width returns a single-bit zero.
if (op.input().getType().cast<IntType>().isUnsigned())
@ -539,7 +539,7 @@ LogicalResult FIRRTLLowering::visitExpr(TailPrimOp op) {
return failure();
auto inWidth = input.getType().cast<IntegerType>().getWidth();
Type resultType = builder->getIntegerType(inWidth - op.getAmount());
Type resultType = builder->getIntegerType(inWidth - op.amount());
return setLoweringTo<rtl::ExtractOp>(op, resultType, input, 0);
}
@ -641,7 +641,7 @@ LogicalResult FIRRTLLowering::visitStmt(StopOp op) {
// Emit the sv.fatal or sv.finish.
builder->setInsertionPointToStart(svIf.getBodyBlock());
if (op.exitCode().getLimitedValue())
if (op.exitCode())
builder->create<sv::FatalOp>(op.getLoc());
else
builder->create<sv::FinishOp>(op.getLoc());

View File

@ -163,7 +163,7 @@ void CatPrimOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
if (auto rhsBits =
dyn_cast_or_null<BitsPrimOp>(op.rhs().getDefiningOp())) {
if (lhsBits.input() == rhsBits.input() &&
lhsBits.getLo() - 1 == rhsBits.getHi()) {
lhsBits.lo() - 1 == rhsBits.hi()) {
rewriter.replaceOpWithNewOp<BitsPrimOp>(
op, op.getType(), lhsBits.input(), lhsBits.hi(), rhsBits.lo());
return success();
@ -188,8 +188,7 @@ OpFoldResult BitsPrimOp::fold(ArrayRef<Attribute> operands) {
APInt value;
if (inputType.cast<IntType>().hasWidth() &&
matchPattern(input(), m_FConstant(value)))
return getIntAttr(value.lshr(getLo()).trunc(getHi() - getLo() + 1),
getContext());
return getIntAttr(value.lshr(lo()).trunc(hi() - lo() + 1), getContext());
return {};
}
@ -205,8 +204,8 @@ void BitsPrimOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
auto inputOp = op.input().getDefiningOp();
// bits(bits(x, ...), ...) -> bits(x, ...).
if (auto innerBits = dyn_cast_or_null<BitsPrimOp>(inputOp)) {
auto newLo = op.getLo() + innerBits.getLo();
auto newHi = newLo + op.getHi() - op.getLo();
auto newLo = op.lo() + innerBits.lo();
auto newHi = newLo + op.hi() - op.lo();
rewriter.replaceOpWithNewOp<BitsPrimOp>(op, innerBits.input(), newHi,
newLo);
return success();
@ -249,7 +248,7 @@ void HeadPrimOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
return failure();
// If we know the input width, we can canonicalize this into a BitsPrimOp.
unsigned keepAmount = op.getAmount();
unsigned keepAmount = op.amount();
replaceWithBits(op, op.input(), inputWidth - 1, inputWidth - keepAmount,
rewriter);
return success();
@ -328,7 +327,7 @@ OpFoldResult ShlPrimOp::fold(ArrayRef<Attribute> operands) {
auto input = this->input();
auto inputType =
input.getType().cast<FIRRTLType>().getPassiveType().cast<IntType>();
int shiftAmount = getAmount();
int shiftAmount = amount();
// shl(x, 0) -> x
if (shiftAmount == 0)
@ -350,7 +349,7 @@ OpFoldResult ShrPrimOp::fold(ArrayRef<Attribute> operands) {
auto input = this->input();
auto inputType =
input.getType().cast<FIRRTLType>().getPassiveType().cast<IntType>();
int shiftAmount = getAmount();
int shiftAmount = amount();
// shl(x, 0) -> x
if (shiftAmount == 0)
@ -395,7 +394,7 @@ void ShrPrimOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
return failure();
// If we know the input width, we can canonicalize this into a BitsPrimOp.
unsigned shiftAmount = op.getAmount();
unsigned shiftAmount = op.amount();
if (int(shiftAmount) == inputWidth) {
// shift(x, 32) => 0 when x has 32 bits. This is handled by fold().
if (op.getType().cast<IntType>().isUnsigned())
@ -432,7 +431,7 @@ void TailPrimOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
// If we know the input width, we can canonicalize this into a
// BitsPrimOp.
unsigned dropAmount = op.getAmount();
unsigned dropAmount = op.amount();
replaceWithBits(op, op.input(), inputWidth - dropAmount - 1, 0, rewriter);
return success();
}

View File

@ -364,14 +364,6 @@ static LogicalResult verifyFModuleOp(FModuleOp module) {
// Declarations
//===----------------------------------------------------------------------===//
void MemOp::build(OpBuilder &builder, OperationState &result,
FIRRTLType resultType, unsigned readLatency,
unsigned writeLatency, uint64_t depth, RUWAttr ruw,
StringAttr name) {
build(builder, result, resultType, llvm::APInt(32, readLatency),
llvm::APInt(32, writeLatency), llvm::APInt(64, depth), ruw, name);
}
/// Return the type of a mem given a list of named ports and their kind.
/// This returns a null type if there are duplicate port names.
FIRRTLType
@ -927,7 +919,7 @@ void BitsPrimOp::build(OpBuilder &builder, OperationState &result, Value input,
auto type = getResultType(input.getType().cast<FIRRTLType>().getPassiveType(),
high, low);
assert(type && "invalid inputs building BitsPrimOp!");
build(builder, result, type, input, APInt(32, high), APInt(32, low));
build(builder, result, type, input, high, low);
}
FIRRTLType HeadPrimOp::getResultType(FIRRTLType input, int32_t amount) {

View File

@ -337,15 +337,10 @@ void ConcatOp::build(OpBuilder &builder, OperationState &result,
build(builder, result, builder.getIntegerType(resultWidth), inputs);
}
void ExtractOp::build(OpBuilder &builder, OperationState &result,
Type resultType, Value input, unsigned lowBit) {
build(builder, result, resultType, input, llvm::APInt(32, lowBit));
}
static LogicalResult verifyExtractOp(ExtractOp op) {
unsigned srcWidth = op.input().getType().cast<IntegerType>().getWidth();
unsigned dstWidth = op.getType().cast<IntegerType>().getWidth();
if (op.getLowBit() >= srcWidth || srcWidth - op.getLowBit() < dstWidth)
if (op.lowBit() >= srcWidth || srcWidth - op.lowBit() < dstWidth)
return op.emitOpError("from bit too large for input"), failure();
return success();
@ -360,7 +355,7 @@ OpFoldResult ExtractOp::fold(ArrayRef<Attribute> operands) {
APInt value;
if (mlir::matchPattern(input(), m_RConstant(value))) {
unsigned dstWidth = getType().cast<IntegerType>().getWidth();
return getIntAttr(value.lshr(getLowBit()).trunc(dstWidth), getContext());
return getIntAttr(value.lshr(lowBit()).trunc(dstWidth), getContext());
}
return {};
}

View File

@ -816,14 +816,13 @@ private:
SubExprInfo visitExpr(CatPrimOp op) { return emitCat({op.lhs(), op.rhs()}); }
SubExprInfo visitExpr(CvtPrimOp op);
SubExprInfo visitExpr(BitsPrimOp op) {
return emitBitSelect(op.getOperand(), op.hi().getLimitedValue(),
op.lo().getLimitedValue());
return emitBitSelect(op.getOperand(), op.hi(), op.lo());
}
SubExprInfo visitExpr(HeadPrimOp op);
SubExprInfo visitExpr(TailPrimOp op);
SubExprInfo visitExpr(PadPrimOp op);
SubExprInfo visitExpr(ShlPrimOp op) { // shl(x, 4) ==> {x, 4'h0}
auto shAmt = op.amount().getLimitedValue();
auto shAmt = op.amount();
if (shAmt)
return emitCat(op.getOperand(), "", llvm::utostr(shAmt) + "'h0");
return emitNoopCast(op);
@ -1078,8 +1077,7 @@ SubExprInfo ExprEmitter::visitComb(rtl::ConcatOp op) {
SubExprInfo ExprEmitter::visitComb(rtl::ExtractOp op) {
unsigned dstWidth = op.getType().cast<IntegerType>().getWidth();
return emitBitSelect(op.input(), op.getLowBit() + dstWidth - 1,
op.getLowBit());
return emitBitSelect(op.input(), op.lowBit() + dstWidth - 1, op.lowBit());
}
/// Emit a verilog bit selection operation like x[4:0], the bit numbers are
@ -1191,7 +1189,7 @@ SubExprInfo ExprEmitter::visitExpr(HeadPrimOp op) {
auto width = getPassiveTypeOf<IntType>(op.getOperand()).getWidthOrSentinel();
if (width == -1)
return visitUnhandledExpr(op);
auto numBits = op.amount().getLimitedValue();
auto numBits = op.amount();
return emitBitSelect(op.getOperand(), width - 1, width - numBits);
}
@ -1199,7 +1197,7 @@ SubExprInfo ExprEmitter::visitExpr(TailPrimOp op) {
auto width = getPassiveTypeOf<IntType>(op.getOperand()).getWidthOrSentinel();
if (width == -1)
return visitUnhandledExpr(op);
auto numBits = op.amount().getLimitedValue();
auto numBits = op.amount();
return emitBitSelect(op.getOperand(), width - 1 - numBits, 0);
}
@ -1208,7 +1206,7 @@ SubExprInfo ExprEmitter::visitExpr(PadPrimOp op) {
auto inWidth = inType.getWidthOrSentinel();
if (inWidth == -1)
return visitUnhandledExpr(op);
auto destWidth = op.amount().getLimitedValue();
auto destWidth = op.amount();
// If the destination width is smaller than the input width, then this is a
// truncation.
@ -1248,7 +1246,7 @@ SubExprInfo ExprEmitter::visitExpr(PadPrimOp op) {
// apparently only needed for width inference.
SubExprInfo ExprEmitter::visitExpr(ShrPrimOp op) {
auto width = getPassiveTypeOf<IntType>(op.getOperand()).getWidthOrSentinel();
unsigned shiftAmount = op.amount().getLimitedValue();
unsigned shiftAmount = op.amount();
if (width == -1 || shiftAmount >= unsigned(width))
return visitUnhandledExpr(op);
@ -1422,7 +1420,7 @@ void ModuleEmitter::emitStatement(StopOp op) {
auto condExpr = "`STOP_COND_ && " +
emitExpressionToString(op.cond(), ops, AndShortCircuit);
const char *action = op.exitCode().getLimitedValue() ? "$fatal;" : "$finish;";
const char *action = op.exitCode() ? "$fatal;" : "$finish;";
auto locInfo = getLocationInfoAsString(ops);
addAtPosEdge(action, locInfo, clockExpr, "!SYNTHESIS", condExpr);
@ -1680,7 +1678,7 @@ void ModuleEmitter::emitDecl(RegInitOp op) {
void ModuleEmitter::emitDecl(MemOp op) {
// Check that the MemOp has been properly lowered before this.
if (op.getReadLatency() != 0 || op.getWriteLatency() != 1) {
if (op.readLatency() != 0 || op.writeLatency() != 1) {
// FIXME: This should be an error.
op.emitWarning("FIXME: need to support mem read/write latency correctly");
}
@ -1688,7 +1686,7 @@ void ModuleEmitter::emitDecl(MemOp op) {
ops.insert(op);
auto memName = getName(op.getResult());
uint64_t depth = op.getDepth();
uint64_t depth = op.depth();
auto locInfo = getLocationInfoAsString(ops);
// If we haven't already emitted a declaration of initvar, do so.
@ -1849,8 +1847,7 @@ static bool isExpressionUnableToInline(Operation *op) {
if (auto pad = dyn_cast<PadPrimOp>(user)) {
auto inType = getPassiveTypeOf<IntType>(pad.getOperand());
auto inWidth = inType.getWidthOrSentinel();
if (unsigned(inWidth) > pad.amount().getLimitedValue() &&
!isOkToBitSelectFrom(op))
if (unsigned(inWidth) > pad.amount() && !isOkToBitSelectFrom(op))
return true;
}
}
@ -2005,7 +2002,7 @@ void ModuleEmitter::collectNamesEmitDecls(Block &block) {
if (auto dataType = memOp.getDataTypeOrNull())
flattenBundleTypes(dataType, "", false, fieldTypes);
uint64_t depth = memOp.getDepth();
uint64_t depth = memOp.depth();
for (const auto &elt : fieldTypes) {
indent() << "reg";
os.indent(maxDeclNameWidth - 3 + 1);

View File

@ -64,8 +64,7 @@ LogicalResult VerilogPrinter::printModule(ModuleOp module) {
if (!entryBlock.args_empty()) {
out << "(";
for (unsigned int i = 0, e = entryBlock.getNumArguments(); i < e; ++i) {
out << (i > 0 ? ", " : "")
<< (i < entity.ins().getZExtValue() ? "input " : "output ");
out << (i > 0 ? ", " : "") << (i < entity.ins() ? "input " : "output ");
printType(entryBlock.getArgument(i).getType());
out << " " << getVariableName(entryBlock.getArgument(i));
}

2
llvm

@ -1 +1 @@
Subproject commit 1d3d9b9cd808ef37f3dacd3ada81bff1353cd24b
Subproject commit 84a6da67e6b2a76b15ad1862f4cbb7625fe318df