Skip to content

Commit

Permalink
Update LLVM version to c89e46e76 (llvm#63)
Browse files Browse the repository at this point in the history
* Update LLVM version to c89e46e76

A small fixup is required to avoid conflicts between ODS-generated build
methods because of default arguments.  Also, since this keeps failing, I've
updated the llvm cache so that it runs in a separate job.  Otherwise the cache is not updated when the CIRCT build fails.

* [LLHD] Add `SigType` conversion

* [LLHD] Add time type and constants conversion

Previously time constants were converted by their users, by creating a constant for each of the three time attributes. This makes time constants LLVM arrays containing the three time values instead, allowing more a more flexible use (e.g. passing time operands as block arguments).
* Add time type conversion.
* Add tme constants conversion.
* Add time operands to the process persistence state.
* Fix affected tests.

* [LLHD] Set LLVM::DialectCastOp as legal during `InstOp` lowering

This works around the PartialConversion failing because of the introduction of (unused) `DialectCastOps`, that will be dealt with later during the full conversion.

Co-authored-by: rodonisi <simon@rodoni.ch>
  • Loading branch information
stephenneuendorffer and rodonisi committed Jul 31, 2020
1 parent 5fd07b2 commit ad07533
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 191 deletions.
31 changes: 30 additions & 1 deletion .github/workflows/buildAndTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,37 @@ name: Build and Test
on: [push, pull_request]

jobs:
build-llvm:
name: Build LLVM
runs-on: ubuntu-latest
steps:
- name: Configure Environment
run: echo "::add-path::$GITHUB_WORKSPACE/llvm/install/bin"
- name: Get CIRCT
uses: actions/checkout@v2
with:
submodules: 'true'
- name: Get LLVM Hash
id: get-llvm-hash
run: echo "::set-output name=hash::$(git submodule status)"
shell: bash
- name: Cache LLVM
id: cache-llvm
uses: actions/cache@v1
with:
path: llvm
key: ${{ runner.os }}-llvm-install-${{ steps.get-llvm-hash.outputs.hash }}
- name: Rebuild and Install LLVM
if: steps.cache-llvm.outputs.cache-hit != 'true'
run: |
mkdir llvm/build
mkdir llvm/install
cd llvm/build
cmake ../llvm -DLLVM_BUILD_EXAMPLES=OFF -DLLVM_TARGETS_TO_BUILD="host" -DCMAKE_INSTALL_PREFIX=../install -DLLVM_ENABLE_PROJECTS='mlir' -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_INSTALL_UTILS=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_ENABLE_LLD=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON
cmake --build . --target install -- -j$(nproc)
build:
name: Build and Test
needs: build-llvm
runs-on: ubuntu-latest
steps:
- name: Configure Environment
Expand All @@ -23,7 +52,7 @@ jobs:
with:
path: llvm
key: ${{ runner.os }}-llvm-install-${{ steps.get-llvm-hash.outputs.hash }}
- name: Install LLVM
- name: Rebuild and Install LLVM
if: steps.cache-llvm.outputs.cache-hit != 'true'
run: |
mkdir llvm/build
Expand Down
131 changes: 64 additions & 67 deletions lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,10 @@ static LLVM::LLVMType getProcPersistenceTy(LLVM::LLVMDialect *dialect,
LLVMTypeConverter &converter,
ProcOp &proc) {
SmallVector<LLVM::LLVMType, 3> types = SmallVector<LLVM::LLVMType, 3>();

auto i32Ty = LLVM::LLVMType::getInt32Ty(dialect);

proc.walk([&](Operation *op) -> void {
if (op->isUsedOutsideOfBlock(op->getBlock())) {
if (op->getResult(0).getType().isa<IntegerType>())
types.push_back(converter.convertType(op->getResult(0).getType())
.cast<LLVM::LLVMType>());
else if (op->getResult(0).getType().isa<SigType>())
types.push_back(i32Ty);
types.push_back(converter.convertType(op->getResult(0).getType())
.cast<LLVM::LLVMType>());
}
});
return LLVM::LLVMType::getStructTy(dialect, types);
Expand Down Expand Up @@ -250,8 +244,7 @@ static void insertPersistence(LLVMTypeConverter &converter,
// Insert operations required to persist values across process suspension.
converted.walk([&](Operation *op) -> void {
if (op->isUsedOutsideOfBlock(op->getBlock()) &&
op->getResult(0) != larg.getResult() &&
!(op->getResult(0).getType().isa<TimeType>())) {
op->getResult(0) != larg.getResult()) {
auto elemTy = stateTy.getStructElementType(3).getStructElementType(i);

// Store the value escaping it's definingn block in the persistence table.
Expand Down Expand Up @@ -298,6 +291,23 @@ static void insertPersistence(LLVMTypeConverter &converter,
});
}

//===----------------------------------------------------------------------===//
// Type conversions
//===----------------------------------------------------------------------===//

static LLVM::LLVMType convertSigType(SigType type,
LLVMTypeConverter &converter) {
auto i64Ty = LLVM::LLVMType::getInt64Ty(converter.getDialect());
auto i8PtrTy = LLVM::LLVMType::getInt8PtrTy(converter.getDialect());
return LLVM::LLVMType::getStructTy(i8PtrTy, i64Ty, i64Ty, i64Ty)
.getPointerTo();
}

static LLVM::LLVMType convertTimeType(TimeType type,
LLVMTypeConverter &converter) {
auto i32Ty = LLVM::LLVMType::getInt32Ty(converter.getDialect());
return LLVM::LLVMType::getArrayTy(i32Ty, 3);
}
//===----------------------------------------------------------------------===//
// Unit conversions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -552,7 +562,7 @@ struct WaitOpConversion : public ConvertToLLVMPattern {
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {
auto waitOp = cast<WaitOp>(op);
WaitOpAdaptor transformed(operands, nullptr);
WaitOpAdaptor transformed(operands, op->getAttrDictionary());
auto llvmFunc = op->getParentOfType<LLVM::LLVMFuncOp>();

auto voidTy = getVoidType();
Expand Down Expand Up @@ -601,28 +611,19 @@ struct WaitOpConversion : public ConvertToLLVMPattern {
}

// Get time constats, if present.
Value realTimeConst;
Value deltaConst;
Value epsConst;
Value realTime;
Value delta;
Value eps;
if (waitOp.timeMutable().size() > 0) {
auto timeAttr = cast<llhd::ConstOp>(waitOp.time().getDefiningOp())
.valueAttr()
.dyn_cast<TimeAttr>();
// Get the real time as an attribute.
auto realTimeAttr = rewriter.getI32IntegerAttr(timeAttr.getTime());
// Create a new time const operation.
realTimeConst =
rewriter.create<LLVM::ConstantOp>(op->getLoc(), i32Ty, realTimeAttr);
// Get the delta step as an attribute.
auto deltaAttr = rewriter.getI32IntegerAttr(timeAttr.getDelta());
// Create a new delta const operation.
deltaConst =
rewriter.create<LLVM::ConstantOp>(op->getLoc(), i32Ty, deltaAttr);
// Get the epsilon step as an attribute.
auto epsAttr = rewriter.getI32IntegerAttr(timeAttr.getEps());
// Create a new eps const operation.
epsConst =
rewriter.create<LLVM::ConstantOp>(op->getLoc(), i32Ty, epsAttr);
realTime = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({0})));
delta = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({1})));
eps = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({2})));
}

// Update and store the new resume index in the process state.
Expand All @@ -635,8 +636,7 @@ struct WaitOpConversion : public ConvertToLLVMPattern {
procState, ArrayRef<Value>({zeroC, oneC}));
rewriter.create<LLVM::StoreOp>(op->getLoc(), resumeIdxC, resumeIdxPtr);

std::array<Value, 5> args(
{statePtr, procStateBC, realTimeConst, deltaConst, epsConst});
std::array<Value, 5> args({statePtr, procStateBC, realTime, delta, eps});
rewriter.create<LLVM::CallOp>(
op->getLoc(), voidTy, rewriter.getSymbolRefAttr(llhdSuspendFunc), args);

Expand Down Expand Up @@ -1022,32 +1022,20 @@ struct DrvOpConversion : public ConvertToLLVMPattern {
rewriter.create<LLVM::StoreOp>(op->getLoc(), transformed.value(), alloca);
auto bc = rewriter.create<LLVM::BitcastOp>(op->getLoc(), i8PtrTy, alloca);

// Get the constant time operation.
auto timeAttr = cast<llhd::ConstOp>(drvOp.time().getDefiningOp())
.valueAttr()
.dyn_cast<TimeAttr>();
// Get the real time as an attribute.
auto realTimeAttr = rewriter.getI32IntegerAttr(timeAttr.getTime());
// Create a new time const operation.
auto realTimeConst = rewriter.create<LLVM::ConstantOp>(
op->getLoc(), LLVM::LLVMType::getInt32Ty(typeConverter.getDialect()),
realTimeAttr);
// Get the delta step as an attribute.
auto deltaAttr = rewriter.getI32IntegerAttr(timeAttr.getDelta());
// Create a new delta const operation.
auto deltaConst = rewriter.create<LLVM::ConstantOp>(
op->getLoc(), LLVM::LLVMType::getInt32Ty(typeConverter.getDialect()),
deltaAttr);
// Get the epsilon step as an attribute.
auto epsAttr = rewriter.getI32IntegerAttr(timeAttr.getEps());
// Create a new eps const operation.
auto epsConst = rewriter.create<LLVM::ConstantOp>(
op->getLoc(), LLVM::LLVMType::getInt32Ty(typeConverter.getDialect()),
epsAttr);
// Get the time values.
auto realTime = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({0})));
auto delta = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({1})));
auto eps = rewriter.create<LLVM::ExtractValueOp>(
op->getLoc(), i32Ty, transformed.time(),
rewriter.getI32ArrayAttr(ArrayRef<int32_t>({2})));

// Define the drive_signal library call arguments.
std::array<Value, 7> args({statePtr, transformed.signal(), bc, widthConst,
realTimeConst, deltaConst, epsConst});
std::array<Value, 7> args(
{statePtr, transformed.signal(), bc, widthConst, realTime, delta, eps});
// Create the library call.
rewriter.create<LLVM::CallOp>(op->getLoc(), voidTy,
rewriter.getSymbolRefAttr(drvFunc), args);
Expand Down Expand Up @@ -1267,10 +1255,9 @@ using XorOpConversion = OneToOneConvertToLLVMPattern<llhd::XorOp, LLVM::XOrOp>;
//===----------------------------------------------------------------------===//

namespace {
/// Lower an LLHD constant operation to LLVM dialect. Time constant are treated
/// as a special case, by just erasing them. Operations that use time constants
/// are assumed to extract and convert the elements they require. The other
/// const types are lowered to an equivalent `llvm.mlir.constant` operation.
/// Lower an LLHD constant operation to LLVM dialect. Time constants are lowered
/// to an array of 3 integers, containing the 3 time values. The other const
/// types are lowered to an equivalent `llvm.mlir.constant` operation.
struct ConstOpConversion : public ConvertToLLVMPattern {
explicit ConstOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter)
: ConvertToLLVMPattern(llhd::ConstOp::getOperationName(), ctx,
Expand All @@ -1283,9 +1270,14 @@ struct ConstOpConversion : public ConvertToLLVMPattern {
auto constOp = cast<ConstOp>(op);
// Get the constant's attribute.
auto attr = constOp.value();
// Handle the time const special case.
if (!attr.getType().isa<IntegerType>()) {
rewriter.eraseOp(op);
// Handle the time const special case: create a new array containing the
// three time values.
if (auto timeAttr = attr.dyn_cast<TimeAttr>()) {
auto timeTy = typeConverter.convertType(constOp.getResult().getType());
auto denseAttr = DenseElementsAttr::get(
VectorType::get(3, rewriter.getI32Type()),
{timeAttr.getTime(), timeAttr.getDelta(), timeAttr.getEps()});
rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(op, timeTy, denseAttr);
return success();
}
// Get the converted llvm type.
Expand Down Expand Up @@ -1397,8 +1389,7 @@ void llhd::populateLLHDToLLVMConversionPatterns(
// Bitwise conversion patterns.
patterns.insert<NotOpConversion, ShrOpConversion, ShlOpConversion>(ctx,
converter);
patterns.insert<AndOpConversion, OrOpConversion, XorOpConversion>(
converter, LowerToLLVMOptions::getDefaultOptions());
patterns.insert<AndOpConversion, OrOpConversion, XorOpConversion>(converter);

// Unit conversion patterns.
patterns.insert<EntityOpConversion, TerminatorOpConversion, ProcOpConversion,
Expand All @@ -1412,13 +1403,18 @@ void llhd::populateLLHDToLLVMConversionPatterns(
void LLHDToLLVMLoweringPass::runOnOperation() {
OwningRewritePatternList patterns;
auto converter = mlir::LLVMTypeConverter(&getContext());
converter.addConversion(
[&](SigType sig) { return convertSigType(sig, converter); });
converter.addConversion(
[&](TimeType time) { return convertTimeType(time, converter); });

// Apply a partial conversion first, lowering only the instances, to generate
// the init function.
patterns.insert<InstOpConversion>(&getContext(), converter);

LLVMConversionTarget target(getContext());
target.addIllegalOp<InstOp>();
target.addLegalOp<LLVM::DialectCastOp>();

// Apply the partial conversion.
if (failed(applyPartialConversion(getOperation(), target, patterns)))
Expand All @@ -1430,6 +1426,7 @@ void LLHDToLLVMLoweringPass::runOnOperation() {

target.addLegalDialect<LLVM::LLVMDialect>();
target.addLegalOp<ModuleOp, ModuleTerminatorOp>();
target.addIllegalOp<LLVM::DialectCastOp>();

// Apply the full conversion.
if (failed(applyFullConversion(getOperation(), target, patterns)))
Expand Down
4 changes: 2 additions & 2 deletions lib/Dialect/FIRRTL/LowerToRTL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ LogicalResult FIRRTLLowering::lowerBinOpToVariadic(Operation *op) {
if (!lhs || !rhs)
return failure();

return setLoweringTo<ResultOpType>(op, ValueRange({lhs, rhs}));
return setLoweringTo<ResultOpType>(op, ValueRange({lhs, rhs}), std::vector<NamedAttribute>{});
}

template <typename ResultOpType>
Expand Down Expand Up @@ -401,4 +401,4 @@ LogicalResult FIRRTLLowering::visitExpr(TailPrimOp op) {
auto inWidth = input.getType().cast<IntegerType>().getWidth();
Type resultType = builder->getIntegerType(inWidth - op.getAmount());
return setLoweringTo<rtl::ExtractOp>(op, resultType, input, 0);
}
}
2 changes: 1 addition & 1 deletion llvm
Submodule llvm updated 5474 files
Loading

0 comments on commit ad07533

Please sign in to comment.