Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions include/circt/Conversion/ConvertToLLVM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===- ConvertToLLVM.h - ConvertToLLVM pass entry point ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header file defines prototypes that expose the ConvertToLLVM pass
// constructors.
//
//===----------------------------------------------------------------------===//

#ifndef CIRCT_CONVERSION_CONVERTTOLLVM_H
#define CIRCT_CONVERSION_CONVERTTOLLVM_H

#include "circt/Support/LLVM.h"
#include <memory>

namespace circt {

#define GEN_PASS_DECL_CONVERTTOLLVM
#include "circt/Conversion/Passes.h.inc"

} // namespace circt

#endif // CIRCT_CONVERSION_CONVERTTOLLVM_H
5 changes: 5 additions & 0 deletions include/circt/Conversion/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "circt/Conversion/CombToSMT.h"
#include "circt/Conversion/CombToSynth.h"
#include "circt/Conversion/ConvertToArcs.h"
#include "circt/Conversion/ConvertToLLVM.h"
#include "circt/Conversion/DCToHW.h"
#include "circt/Conversion/DatapathToComb.h"
#include "circt/Conversion/DatapathToSMT.h"
Expand Down Expand Up @@ -56,6 +57,10 @@

namespace circt {

// Generate pass declarations.
#define GEN_PASS_DECL_CONVERTTOLLVM
#include "circt/Conversion/Passes.h.inc"

// Generate the code for registering conversion passes.
#define GEN_PASS_REGISTRATION
#include "circt/Conversion/Passes.h.inc"
Expand Down
17 changes: 17 additions & 0 deletions include/circt/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,23 @@ def ConvertHWToLLVM : Pass<"convert-hw-to-llvm", "mlir::ModuleOp"> {
let dependentDialects = ["mlir::LLVM::LLVMDialect"];
}

//===----------------------------------------------------------------------===//
// ConvertToLLVM
//===----------------------------------------------------------------------===//

def ConvertToLLVM : Pass<"convert-to-llvm", "mlir::ModuleOp"> {
let summary = "Convert Comb and HW to LLVM";
let description = [{
This pass translates Comb and HW operations inside func.func to LLVM IR.
It combines both HW and Comb conversion patterns to provide a complete
lowering from hardware description to LLVM IR.
}];
let dependentDialects = [
"mlir::LLVM::LLVMDialect",
"mlir::arith::ArithDialect"
];
}

//===----------------------------------------------------------------------===//
// HWArithToHW
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions lib/CAPI/Conversion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_circt_public_c_api_library(CIRCTCAPIConversion
CIRCTCombToLLVM
CIRCTCombToSMT
CIRCTConvertToArcs
CIRCTConvertToLLVM
CIRCTDatapathToComb
CIRCTDatapathToSMT
CIRCTDCToHW
Expand Down
1 change: 1 addition & 0 deletions lib/Conversion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_subdirectory(CombToLLVM)
add_subdirectory(CombToSMT)
add_subdirectory(CombToSynth)
add_subdirectory(ConvertToArcs)
add_subdirectory(ConvertToLLVM)
add_subdirectory(DatapathToComb)
add_subdirectory(DatapathToSMT)
add_subdirectory(DCToHW)
Expand Down
18 changes: 16 additions & 2 deletions lib/Conversion/CombToLLVM/CombToLLVM.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//===- CombToLLVM.cpp - Comb to LLVM Conversion Pass ----------------------===//
//===- CombToLLVM.cpp - Comb to LLVM Conversion Patterns ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is the main Comb to LLVM Conversion Pass Implementation.
// This file implements Comb to LLVM conversion patterns.
//
//===----------------------------------------------------------------------===//

Expand All @@ -23,7 +23,13 @@ using namespace mlir;
using namespace circt;

namespace {

//===----------------------------------------------------------------------===//
// Comb Operation Conversion Patterns
//===----------------------------------------------------------------------===//

/// Convert a comb::ParityOp to the LLVM dialect.
/// This is the only Comb operation that doesn't have a Comb-to-Arith pattern.
struct CombParityOpConversion : public ConvertToLLVMPattern {
explicit CombParityOpConversion(MLIRContext *ctx,
LLVMTypeConverter &typeConverter)
Expand All @@ -43,9 +49,17 @@ struct CombParityOpConversion : public ConvertToLLVMPattern {
return success();
}
};

} // namespace

//===----------------------------------------------------------------------===//
// Pattern Population Functions
//===----------------------------------------------------------------------===//

void circt::populateCombToLLVMConversionPatterns(LLVMTypeConverter &converter,
RewritePatternSet &patterns) {
// Only add patterns for operations that don't have Comb-to-Arith patterns
// Most Comb operations are handled by the Comb-to-Arith + Arith-to-LLVM
// pipeline
patterns.add<CombParityOpConversion>(patterns.getContext(), converter);
}
25 changes: 25 additions & 0 deletions lib/Conversion/ConvertToLLVM/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
add_circt_conversion_library(CIRCTConvertToLLVM
ConvertToLLVM.cpp

DEPENDS
CIRCTConversionPassIncGen

LINK_COMPONENTS
Core

LINK_LIBS PUBLIC
CIRCTComb
CIRCTCombToArith
CIRCTCombToLLVM
CIRCTHW
CIRCTHWToLLVM
CIRCTSupport
MLIRArithToLLVM
MLIRControlFlowToLLVM
MLIRFuncToLLVM
MLIRIndexToLLVM
MLIRLLVMCommonConversion
MLIRSCFToControlFlow
MLIRTransforms
)

109 changes: 109 additions & 0 deletions lib/Conversion/ConvertToLLVM/ConvertToLLVM.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//===- ConvertToLLVM.cpp - ConvertToLLVM Pass ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the ConvertToLLVM pass.
//
//===----------------------------------------------------------------------===//

#include "circt/Conversion/ConvertToLLVM.h"
#include "circt/Conversion/CombToArith.h"
#include "circt/Conversion/CombToLLVM.h"
#include "circt/Conversion/HWToLLVM.h"
#include "circt/Dialect/Comb/CombOps.h"
#include "circt/Dialect/SV/SVOps.h"
#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"

using namespace mlir;
using namespace circt;

namespace circt {
#define GEN_PASS_DEF_CONVERTTOLLVM
#include "circt/Conversion/Passes.h.inc"

namespace impl {

//===----------------------------------------------------------------------===//
// Pass Implementation
//===----------------------------------------------------------------------===//

struct ConvertToLLVMPass : public ConvertToLLVMBase<ConvertToLLVMPass> {
void runOnOperation() override;

private:
void convertFuncOp(func::FuncOp funcOp);
};

void ConvertToLLVMPass::runOnOperation() {
// Iterate over all func.func operations in the module and convert them
for (auto funcOp :
llvm::make_early_inc_range(getOperation().getOps<func::FuncOp>())) {
convertFuncOp(funcOp);
}
}

void ConvertToLLVMPass::convertFuncOp(func::FuncOp funcOp) {
MLIRContext *context = &getContext();
RewritePatternSet patterns(context);
auto converter = mlir::LLVMTypeConverter(context);

// Add HW to LLVM type conversions
populateHWToLLVMTypeConversions(converter);

LLVMConversionTarget target(*context);
target.addIllegalDialect<comb::CombDialect>();
target.addIllegalDialect<arith::ArithDialect>();

// Mark HW and SV dialects as legal - we only convert operations inside
// func.func
target.addLegalDialect<hw::HWDialect>();
target.addLegalDialect<sv::SVDialect>();

// Setup the conversion patterns in the correct order:
// 1. SCF to ControlFlow (for structured control flow)
populateSCFToControlFlowConversionPatterns(patterns);

// 2. Func to LLVM (for function operations)
populateFuncToLLVMConversionPatterns(converter, patterns);

// 3. ControlFlow to LLVM (for control flow operations)
cf::populateControlFlowToLLVMConversionPatterns(converter, patterns);

// 4. Comb to Arith (for most combinational operations)
populateCombToArithConversionPatterns(converter, patterns);

// 5. Arith to LLVM (for arithmetic operations)
arith::populateArithToLLVMConversionPatterns(converter, patterns);

// 6. Index to LLVM (for index operations)
index::populateIndexToLLVMConversionPatterns(converter, patterns);

// 7. Any function op interface type conversion
populateAnyFunctionOpInterfaceTypeConversionPattern(patterns, converter);

// 8. Comb to LLVM (for operations without Comb-to-Arith patterns, like
// parity)
populateCombToLLVMConversionPatterns(converter, patterns);

// Apply the partial conversion only to this func.func operation
if (failed(applyPartialConversion(funcOp, target, std::move(patterns))))
signalPassFailure();
}

} // namespace impl
} // namespace circt
Loading