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
25 changes: 23 additions & 2 deletions cmake/Modules/FindMLIR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,54 @@ else ()
# To be done: add the required MLIR libraries. Hopefully we don't have to manually list all MLIR libs.
if (EXISTS "${MLIR_LIB_DIR}/MLIRIR.lib")
set(MLIR_LIBRARIES
${MLIR_LIB_DIR}/MLIRIR.lib
${MLIR_LIB_DIR}/MLIRSupport.lib
${MLIR_LIB_DIR}/libMLIRAffineOps.lib
${MLIR_LIB_DIR}/libMLIRAffineToStandard.lib
${MLIR_LIB_DIR}/libMLIRAnalysis.lib
${MLIR_LIB_DIR}/libMLIRDialect.lib
${MLIR_LIB_DIR}/libMLIRExecutionEngine.lib
${MLIR_LIB_DIR}/libMLIRIR.lib
${MLIR_LIB_DIR}/libMLIRLLVMIR.lib
${MLIR_LIB_DIR}/libMLIRLoopOps.lib
${MLIR_LIB_DIR}/libMLIRPass.lib
${MLIR_LIB_DIR}/libMLIRStandardOps.lib
${MLIR_LIB_DIR}/libMLIRStandardToLLVM.lib
${MLIR_LIB_DIR}/libMLIRSupport.lib
${MLIR_LIB_DIR}/libMLIRTargetLLVMIR.lib
${MLIR_LIB_DIR}/libMLIRTargetLLVMIRModuleTranslation.lib
${MLIR_LIB_DIR}/libMLIRTransformUtils.lib
${MLIR_LIB_DIR}/libMLIRTransforms.lib
${MLIR_LIB_DIR}/libMLIRTranslation.lib
${MLIR_LIB_DIR}/libLLVMExecutionEngine.lib
${MLIR_LIB_DIR}/libLLVMJITLink.lib
${MLIR_LIB_DIR}/libLLVMOrcJIT.lib
${MLIR_LIB_DIR}/libLLVMOrcError.lib
${MLIR_LIB_DIR}/libLLVMRuntimeDyld.lib
)
elseif (EXISTS "${MLIR_LIB_DIR}/libMLIRIR.a")
set(MLIR_LIBRARIES
${MLIR_LIB_DIR}/libMLIRAffineOps.a
${MLIR_LIB_DIR}/libMLIRAffineToStandard.a
${MLIR_LIB_DIR}/libMLIRAnalysis.a
${MLIR_LIB_DIR}/libMLIRDialect.a
${MLIR_LIB_DIR}/libMLIRExecutionEngine.a
${MLIR_LIB_DIR}/libMLIRIR.a
${MLIR_LIB_DIR}/libMLIRLoopToStandard.a
${MLIR_LIB_DIR}/libMLIRLLVMIR.a
${MLIR_LIB_DIR}/libMLIRLoopOps.a
${MLIR_LIB_DIR}/libMLIRPass.a
${MLIR_LIB_DIR}/libMLIRStandardOps.a
${MLIR_LIB_DIR}/libMLIRStandardToLLVM.a
${MLIR_LIB_DIR}/libMLIRSupport.a
${MLIR_LIB_DIR}/libMLIRTargetLLVMIR.a
${MLIR_LIB_DIR}/libMLIRTargetLLVMIRModuleTranslation.a
${MLIR_LIB_DIR}/libMLIRTransformUtils.a
${MLIR_LIB_DIR}/libMLIRTransforms.a
${MLIR_LIB_DIR}/libMLIRTranslation.a
${MLIR_LIB_DIR}/libLLVMExecutionEngine.a
${MLIR_LIB_DIR}/libLLVMJITLink.a
${MLIR_LIB_DIR}/libLLVMOrcJIT.a
${MLIR_LIB_DIR}/libLLVMOrcError.a
${MLIR_LIB_DIR}/libLLVMRuntimeDyld.a
)
endif ()

Expand Down
7 changes: 7 additions & 0 deletions dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ version (IN_LLVM)
bool fullyQualifiedObjectFiles;
bool cleanupObjectFiles;

//MLIR stuff
bool affineDialect; // Translates D dialect to Affine + Std dialect
bool llvmDialect; // Translates D Affine + Std dialect to LLVM dialect
bool llvmIr; // Codegen LLVM IR from LLVM dialect
bool runJIT; // Run the LLVM IR created with MLIR Framework using the LLVM JIT Compiler
bool enableOpt; // Run optimizations on MLIR dialects

// Profile-guided optimization:
const(char)* datafileInstrProf; // Either the input or output file for PGO data

Expand Down
7 changes: 7 additions & 0 deletions dmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ struct Param
bool fullyQualifiedObjectFiles;
bool cleanupObjectFiles;

//MLIR stuff
bool affineDialect; // Translates D dialect to Affine + Std dialect
bool llvmDialect; // Translates D Affine + Std dialect to LLVM dialect
bool llvmIr; // Codegen LLVM IR from LLVM dialect
bool runJIT; // Run the LLVM IR created with MLIR Framework using the LLVM JIT Compiler
bool enableOpt; // Run optimizations on MLIR dialects

// Profile-guided optimization:
const char *datafileInstrProf; // Either the input or output file for PGO data

Expand Down
25 changes: 25 additions & 0 deletions driver/cl_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,31 @@ cl::opt<bool> noPLT(
"fno-plt", cl::ZeroOrMore,
cl::desc("Do not use the PLT to make function calls"));

cl::opt<bool, true> affineDialect(
"affineDialect", cl::ZeroOrMore,
cl::desc("Translates D dialect to Affine + Std dialect"),
cl::location(global.params.affineDialect));

cl::opt<bool, true> llvmDialect(
"llvmDialect", cl::ZeroOrMore,
cl::desc("Translates D Affine + Std dialect to LLVM dialect"),
cl::location(global.params.llvmDialect));

cl::opt<bool, true> llvmIr(
"llvmIr", cl::ZeroOrMore,
cl::desc("Codegen LLVM IR from LLVM dialect"),
cl::location(global.params.llvmIr));

cl::opt<bool, true> runJIT(
"runJIT", cl::ZeroOrMore,
cl::desc("Run the LLVM IR created with MLIR Framework using the LLVM JIT "
"Compiler"), cl::location(global.params.runJIT));

cl::opt<bool, true> enableOpt(
"enableOpt", cl::ZeroOrMore,
cl::desc("Run optimizations on MLIR dialects"),
cl::location(global.params.enableOpt));

// Math options
bool fFastMath; // Storage for the dynamically created ffast-math option.
llvm::FastMathFlags defaultFMF;
Expand Down
5 changes: 5 additions & 0 deletions driver/cl_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ extern cl::opt<bool> linkonceTemplates;
extern cl::opt<bool> disableLinkerStripDead;
extern cl::opt<unsigned char> defaultToHiddenVisibility;
extern cl::opt<bool> noPLT;
extern cl::opt<bool, true> affineDialect;
extern cl::opt<bool, true> llvmDialect;
extern cl::opt<bool, true> llvmIr;
extern cl::opt<bool, true> runJIT;
extern cl::opt<bool, true> enableOpt;

// Math options
extern bool fFastMath;
Expand Down
158 changes: 132 additions & 26 deletions driver/codegenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/Passes.h"
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/Target/LLVMIR.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/FormattedStream.h"
#endif
#include "gen/dynamiccompile.h"
#include "gen/logger.h"
Expand Down Expand Up @@ -74,7 +82,7 @@ createAndSetDiagnosticsOutputFile(IRState &irs, llvm::LLVMContext &ctx,
// If there is instrumentation data available, also output function hotness
const bool withHotness = opts::isUsingPGOProfile();

#if LDC_LLVM_VER >= 1100
#if LDC_LLVM_VER >= 1100
auto remarksFileOrError = llvm::setupLLVMOptimizationRemarks(
#elif LDC_LLVM_VER >= 900
auto remarksFileOrError = llvm::setupOptimizationRemarks(
Expand Down Expand Up @@ -392,8 +400,9 @@ void CodeGenerator::emitMLIR(Module *m) {

mlir::registerPassManagerCLOptions();
mlir::OwningModuleRef module = ldc_mlir::mlirGen(mlirContext_, m);
if(!module){
const auto llpath = replaceExtensionWith(global.mlir_ext, m->objfile.toChars());
if (!module) {
const auto llpath =
replaceExtensionWith(global.mlir_ext, m->objfile.toChars());
IF_LOG Logger::println("Error generating MLIR:'%s'", llpath.c_str());
fatal();
}
Expand All @@ -405,55 +414,152 @@ void CodeGenerator::emitMLIR(Module *m) {
}
}

int runJit(mlir::ModuleOp module) {
// Initialize LLVM targets.
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();

// An optimization pipeline to use within the execution engine.
auto optPipeline = mlir::makeOptimizingTransformer(
/*optLevel=*/0 ? 3 : 0, /*sizeLevel=*/0,
/*targetMachine=*/nullptr);

// Create an MLIR execution engine. The execution engine eagerly JIT-compiles
// the module.
auto maybeEngine = mlir::ExecutionEngine::create(module, optPipeline);
assert(maybeEngine && "failed to construct an execution engine");
auto &engine = maybeEngine.get();

// Invoke the JIT-compiled function.
auto invocationResult = engine->invoke("main");
if (invocationResult) {
llvm::errs() << "JIT invocation failed\n";
return -1;
}

return 0;
}

void emitLLVMIR(mlir::ModuleOp module, const char *filename) {
auto llvmModule = mlir::translateModuleToLLVMIR(module);
if (!llvmModule) {
llvm::errs() << "Failed to emit LLVM IR\n";
fatal();
}

bool enableOpt = global.params.enableOpt;

// Initialize LLVM targets.
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
mlir::ExecutionEngine::setupTargetTriple(llvmModule.get());

/// Optionally run an optimization pipeline over the llvm module.
auto optPipeline = mlir::makeOptimizingTransformer(
/*optLevel=*/enableOpt ? 3 : 0, /*sizeLevel=*/0,
/*targetMachine=*/nullptr);
if (auto err = optPipeline(llvmModule.get())) {
llvm::errs() << "Failed to optimize LLVM IR " << err << "\n";
fatal();
}

// llvm::errs() << *llvmModule << "\n";

if (llvmModule) {
llvm::SmallString<128> buffer(filename);
llvm::sys::path::replace_extension(
buffer, llvm::StringRef(global.bc_ext.ptr, global.bc_ext.length));
std::error_code errinfo;
const auto bcpath = std::string(buffer.data(), buffer.size());
llvm::raw_fd_ostream baba(bcpath, errinfo, llvm::sys::fs::F_None);
const auto &M = *llvmModule;
llvm::WriteBitcodeToFile(M, baba);
}
}

void CodeGenerator::writeMLIRModule(mlir::OwningModuleRef *module,
const char *filename) {
// Write MLIR
if (global.params.output_mlir) {
const auto llpath = replaceExtensionWith(global.mlir_ext, filename);
Logger::println("Writting MLIR to %s\n", llpath.c_str());
const auto mlirpath = replaceExtensionWith(global.mlir_ext, filename);
Logger::println("Writting MLIR to %s\n", mlirpath.c_str());
std::error_code errinfo;
llvm::raw_fd_ostream aos(llpath, errinfo, llvm::sys::fs::F_None);
llvm::raw_fd_ostream aos(mlirpath, errinfo, llvm::sys::fs::F_None);

if (aos.has_error()) {
error(Loc(), "Cannot write MLIR file '%s': %s", llpath.c_str(),
error(Loc(), "Cannot write MLIR file '%s': %s", mlirpath.c_str(),
errinfo.message().c_str());
fatal();
}

mlir::PassManager pm(&mlirContext_);
// pm.addPass(mlir::createInlinerPass());
// pm.addPass(mlir::createInlinerPass());

// Apply any generic pass manager command line options and run the pipeline.
mlir::applyPassManagerCLOptions(pm);

mlir::OpPassManager &optPM = pm.nest<mlir::FuncOp>();
optPM.addPass(mlir::createCanonicalizerPass());
//optPM.addPass(mlir::createCSEPass());
bool isLoweringToAffine = global.params.affineDialect;
bool isLoweringToLLVM = global.params.llvmDialect;
bool printLLVMIR = global.params.llvmIr;
bool enableJIT = global.params.runJIT;
bool enableOpt = global.params.enableOpt;

//TODO:Needs to set a flag to lowering D->MLIR->Affine+std
bool isLoweringToAffine = true;
if(isLoweringToAffine){
pm.addPass(mlir::D::createLowerToAffinePass());
if (enableOpt || isLoweringToAffine) {
// Inline all functions into main and then delete them.
pm.addPass(mlir::createInlinerPass());

mlir::OpPassManager &optPM = pm.nest<mlir::FuncOp>();
optPM.addPass(mlir::createCanonicalizerPass());
optPM.addPass(mlir::createCSEPass());

// Add optimizations if enabled.
if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createMemRefDataFlowOptPass());
}
}

//TODO: Needs to set a flag to enaple opt
// bool enableOpt = 1;
// if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createMemRefDataFlowOptPass());
// }
if (isLoweringToAffine) {
// Finish lowering the toy IR to the LLVM dialect.
pm.addPass(mlir::D::createLowerToAffinePass());

mlir::OpPassManager &optPM = pm.nest<mlir::FuncOp>();
optPM.addPass(mlir::createCanonicalizerPass());
optPM.addPass(mlir::createCSEPass());

if(mlir::failed(pm.run(module->get()))){
IF_LOG Logger::println("Failed on running passes!");
return;
// Add optimizations if enabled.
if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createMemRefDataFlowOptPass());
}
}
if(!module->get()){
IF_LOG Logger::println("Cannot write MLIR file to '%s'", llpath.c_str());

if (isLoweringToLLVM) {
// Finish lowering the toy IR to the LLVM dialect.
pm.addPass(mlir::D::createLowerToLLVMPass());
}

if (mlir::failed(pm.run(module->get()))) {
IF_LOG Logger::println("Failed on running passes!");
return;
}

if (!module->get()) {
IF_LOG Logger::println("Cannot write MLIR file to '%s'",
mlirpath.c_str());
fatal();
}

module->get().print(aos);

if (printLLVMIR) {
emitLLVMIR(module->get(), filename);
}

if (enableJIT) {
assert(isLoweringToLLVM);
runJit(module->get());
}
}
}

Expand Down
Loading