diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -32,13 +32,17 @@ namespace LLVM { +namespace detail { +class DebugTranslation; +} // end namespace detail + class LLVMFuncOp; -// Implementation class for module translation. Holds a reference to the module -// being translated, and the mappings between the original and the translated -// functions, basic blocks and values. It is practically easier to hold these -// mappings in one class since the conversion of control flow operations -// needs to look up block and function mappings. +/// Implementation class for module translation. Holds a reference to the module +/// being translated, and the mappings between the original and the translated +/// functions, basic blocks and values. It is practically easier to hold these +/// mappings in one class since the conversion of control flow operations +/// needs to look up block and function mappings. class ModuleTranslation { public: template @@ -51,8 +55,7 @@ if (!llvmModule) return nullptr; - T translator(m); - translator.llvmModule = std::move(llvmModule); + T translator(m, std::move(llvmModule)); translator.convertGlobals(); if (failed(translator.convertFunctions())) return nullptr; @@ -65,14 +68,12 @@ static Block &getModuleBody(Operation *m) { return m->getRegion(0).front(); } protected: - // Translate the given MLIR module expressed in MLIR LLVM IR dialect into an - // LLVM IR module. The MLIR LLVM IR dialect holds a pointer to an - // LLVMContext, the LLVM IR module will be created in that context. - explicit ModuleTranslation(Operation *module) : mlirModule(module) { - assert(satisfiesLLVMModule(mlirModule) && - "mlirModule should honor LLVM's module semantics."); - } - virtual ~ModuleTranslation() {} + /// Translate the given MLIR module expressed in MLIR LLVM IR dialect into an + /// LLVM IR module. The MLIR LLVM IR dialect holds a pointer to an + /// LLVMContext, the LLVM IR module will be created in that context. + ModuleTranslation(Operation *module, + std::unique_ptr llvmModule); + virtual ~ModuleTranslation(); virtual LogicalResult convertOperation(Operation &op, llvm::IRBuilder<> &builder); @@ -94,15 +95,18 @@ llvm::Constant *getLLVMConstant(llvm::Type *llvmType, Attribute attr, Location loc); - // Original and translated module. + /// Original and translated module. Operation *mlirModule; std::unique_ptr llvmModule; - // Mappings between llvm.mlir.global definitions and corresponding globals. + /// A converter for translating debug information. + std::unique_ptr debugTranslation; + + /// Mappings between llvm.mlir.global definitions and corresponding globals. DenseMap globalsMapping; protected: - // Mappings between original and translated values, used for lookups. + /// Mappings between original and translated values, used for lookups. llvm::StringMap functionMapping; DenseMap valueMapping; DenseMap blockMapping; diff --git a/mlir/include/mlir/Transforms/Passes.h b/mlir/include/mlir/Transforms/Passes.h --- a/mlir/include/mlir/Transforms/Passes.h +++ b/mlir/include/mlir/Transforms/Passes.h @@ -118,7 +118,7 @@ std::unique_ptr> createMemRefDataFlowOptPass(); /// Creates a pass to strip debug information from a function. -std::unique_ptr> createStripDebugInfoPass(); +std::unique_ptr createStripDebugInfoPass(); /// Creates a pass which tests loop fusion utilities. std::unique_ptr> createTestLoopFusionPass(); diff --git a/mlir/lib/Target/CMakeLists.txt b/mlir/lib/Target/CMakeLists.txt --- a/mlir/lib/Target/CMakeLists.txt +++ b/mlir/lib/Target/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(MLIRTargetLLVMIRModuleTranslation + LLVMIR/DebugTranslation.cpp LLVMIR/ModuleTranslation.cpp ADDITIONAL_HEADER_DIRS diff --git a/mlir/lib/Target/LLVMIR/ConvertToNVVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToNVVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertToNVVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertToNVVMIR.cpp @@ -48,11 +48,8 @@ namespace { class ModuleTranslation : public LLVM::ModuleTranslation { - public: - explicit ModuleTranslation(Operation *module) - : LLVM::ModuleTranslation(module) {} - ~ModuleTranslation() override {} + using LLVM::ModuleTranslation::ModuleTranslation; protected: LogicalResult convertOperation(Operation &opInst, @@ -66,7 +63,6 @@ } // namespace std::unique_ptr mlir::translateModuleToNVVMIR(Operation *m) { - ModuleTranslation translation(m); auto llvmModule = LLVM::ModuleTranslation::translateModule(m); if (!llvmModule) diff --git a/mlir/lib/Target/LLVMIR/ConvertToROCDLIR.cpp b/mlir/lib/Target/LLVMIR/ConvertToROCDLIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertToROCDLIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertToROCDLIR.cpp @@ -57,11 +57,8 @@ namespace { class ModuleTranslation : public LLVM::ModuleTranslation { - public: - explicit ModuleTranslation(Operation *module) - : LLVM::ModuleTranslation(module) {} - ~ModuleTranslation() override {} + using LLVM::ModuleTranslation::ModuleTranslation; protected: LogicalResult convertOperation(Operation &opInst, @@ -75,8 +72,6 @@ } // namespace std::unique_ptr mlir::translateModuleToROCDLIR(Operation *m) { - ModuleTranslation translation(m); - // lower MLIR (with RODL Dialect) to LLVM IR (with ROCDL intrinsics) auto llvmModule = LLVM::ModuleTranslation::translateModule(m); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h new file mode 100644 --- /dev/null +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -0,0 +1,74 @@ +//===- DebugTranslation.h - MLIR to LLVM Debug conversion -------*- 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 file implements the translation between an MLIR debug information and +// the corresponding LLVMIR representation. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_ +#define MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_ + +#include "mlir/IR/Location.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/DIBuilder.h" + +namespace mlir { +class Operation; + +namespace LLVM { +class LLVMFuncOp; + +namespace detail { +class DebugTranslation { +public: + DebugTranslation(Operation *module, llvm::Module &llvmModule); + + /// Finalize the translation of debug information. + void finalize(); + + /// Translate the given location to an llvm debug location. + const llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope); + + /// Translate the debug information for the given function. + void translate(LLVMFuncOp func, llvm::Function &llvmFunc); + +private: + /// Translate the given location to an llvm debug location with the given + /// scope and inlinedAt parameters. + const llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope, + const llvm::DILocation *inlinedAt); + + /// Create an llvm debug file for the given file path. + llvm::DIFile *translateFile(StringRef fileName); + + /// A mapping between mlir location+scope and the corresponding llvm debug + /// metadata. + DenseMap, const llvm::DILocation *> + locationToLoc; + + /// A mapping between filename and llvm debug file. + /// TODO(riverriddle) Change this to DenseMap when we can + /// access the Identifier filename in FileLineColLoc. + llvm::StringMap fileMap; + + /// A string containing the current working directory of the compiler. + SmallString<256> currentWorkingDir; + + /// Debug information fields. + llvm::DIBuilder builder; + llvm::LLVMContext &llvmCtx; + llvm::DICompileUnit *compileUnit; +}; + +} // end namespace detail +} // end namespace LLVM +} // end namespace mlir + +#endif // MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_ diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -0,0 +1,194 @@ +//===- DebugTranslation.cpp - MLIR to LLVM Debug conversion ---------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DebugTranslation.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace mlir; +using namespace mlir::LLVM; +using namespace mlir::LLVM::detail; + +/// A utility walker that interrupts if the operation has valid debug +/// information. +static WalkResult interruptIfValidLocation(Operation *op) { + return op->getLoc().isa() ? WalkResult::advance() + : WalkResult::interrupt(); +} + +DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule) + : builder(llvmModule), llvmCtx(llvmModule.getContext()), + compileUnit(nullptr) { + + // If the module has no location information, there is nothing to do. + if (!module->walk(interruptIfValidLocation).wasInterrupted()) + return; + + // TODO(riverriddle) Several parts of this are incorrect. Different source + // languages may interpret different parts of the debug information + // differently. Frontends will also want to pipe in various information, like + // flags. This is fine for now as we only emit line-table information and not + // types or variables. This should disappear as the debug information story + // evolves; i.e. when we have proper attributes for LLVM debug metadata. + compileUnit = builder.createCompileUnit( + llvm::dwarf::DW_LANG_C, + builder.createFile(llvmModule.getModuleIdentifier(), "/"), + /*Producer=*/"mlir", /*isOptimized=*/true, /*Flags=*/"", /*RV=*/0); + + // Mark this module as having debug information. + StringRef debugVersionKey = "Debug Info Version"; + if (!llvmModule.getModuleFlag(debugVersionKey)) + llvmModule.addModuleFlag(llvm::Module::Warning, debugVersionKey, + llvm::DEBUG_METADATA_VERSION); +} + +/// Finalize the translation of debug information. +void DebugTranslation::finalize() { builder.finalize(); } + +/// Attempt to extract a filename for the given loc. +static FileLineColLoc extractFileLoc(Location loc) { + if (auto fileLoc = loc.dyn_cast()) + return fileLoc; + if (auto nameLoc = loc.dyn_cast()) + return extractFileLoc(nameLoc.getChildLoc()); + if (auto opaqueLoc = loc.dyn_cast()) + return extractFileLoc(opaqueLoc.getFallbackLocation()); + return FileLineColLoc(); +} + +/// Translate the debug information for the given function. +void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) { + // If the function doesn't have location information, there is nothing to + // translate. + if (!compileUnit || !func.walk(interruptIfValidLocation).wasInterrupted()) + return; + + FileLineColLoc fileLoc = extractFileLoc(func.getLoc()); + auto *file = translateFile(fileLoc ? fileLoc.getFilename() : ""); + unsigned line = fileLoc ? fileLoc.getLine() : 0; + + // TODO(riverriddle) This is the bare essentials for now. We will likely end + // up with wrapper metadata around LLVMs metadata in the future, so this + // doesn't need to be smart until then. + llvm::DISubroutineType *type = + builder.createSubroutineType(builder.getOrCreateTypeArray(llvm::None)); + llvm::DISubprogram::DISPFlags spFlags = llvm::DISubprogram::SPFlagDefinition | + llvm::DISubprogram::SPFlagOptimized; + llvm::DISubprogram *program = + builder.createFunction(compileUnit, func.getName(), func.getName(), file, + line, type, line, llvm::DINode::FlagZero, spFlags); + llvmFunc.setSubprogram(program); + builder.finalizeSubprogram(program); +} + +//===----------------------------------------------------------------------===// +// Locations +//===----------------------------------------------------------------------===// + +/// Translate the given location to an llvm debug location. +const llvm::DILocation * +DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) { + if (!compileUnit) + return nullptr; + return translateLoc(loc, scope, /*inlinedAt=*/nullptr); +} + +/// Translate the given location to an llvm DebugLoc. +const llvm::DILocation * +DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope, + const llvm::DILocation *inlinedAt) { + // LLVM doesn't have a representation for unknown. + if (!scope || loc.isa()) + return nullptr; + + // Check for a cached instance. + const auto *&llvmLoc = locationToLoc[std::make_pair(loc, scope)]; + if (llvmLoc) + return llvmLoc; + + switch (loc->getKind()) { + case StandardAttributes::CallSiteLocation: { + auto callLoc = loc.dyn_cast(); + + // For callsites, the caller is fed as the inlinedAt for the callee. + const auto *callerLoc = translateLoc(callLoc.getCaller(), scope, inlinedAt); + llvmLoc = translateLoc(callLoc.getCallee(), scope, callerLoc); + break; + } + case StandardAttributes::FileLineColLocation: { + auto fileLoc = loc.dyn_cast(); + auto *file = translateFile(fileLoc.getFilename()); + auto *fileScope = builder.createLexicalBlockFile(scope, file); + llvmLoc = llvm::DILocation::get(llvmCtx, fileLoc.getLine(), + fileLoc.getColumn(), fileScope, + const_cast(inlinedAt)); + break; + } + case StandardAttributes::FusedLocation: { + auto fusedLoc = loc.dyn_cast(); + ArrayRef locations = fusedLoc.getLocations(); + + // For fused locations, merge each of the nodes. + llvmLoc = translateLoc(locations.front(), scope, inlinedAt); + for (Location locIt : locations.drop_front()) { + llvmLoc = llvm::DILocation::getMergedLocation( + llvmLoc, translateLoc(locIt, scope, inlinedAt)); + } + break; + } + case StandardAttributes::NameLocation: + llvmLoc = translateLoc(loc.cast().getChildLoc(), scope, inlinedAt); + break; + case StandardAttributes::OpaqueLocation: + llvmLoc = translateLoc(loc.cast().getFallbackLocation(), scope, + inlinedAt); + break; + default: + llvm_unreachable("unknown location kind"); + } + return llvmLoc; +} + +/// Create an llvm debug file for the given file path. +llvm::DIFile *DebugTranslation::translateFile(StringRef fileName) { + auto *&file = fileMap[fileName]; + if (file) + return file; + + // Make sure the current working directory is up-to-date. + if (currentWorkingDir.empty()) + llvm::sys::fs::current_path(currentWorkingDir); + + StringRef directory = currentWorkingDir; + SmallString<128> dirBuf; + SmallString<128> fileBuf; + if (llvm::sys::path::is_absolute(fileName)) { + // Strip the common prefix (if it is more than just "/") from current + // directory and FileName for a more space-efficient encoding. + auto fileIt = llvm::sys::path::begin(fileName); + auto fileE = llvm::sys::path::end(fileName); + auto curDirIt = llvm::sys::path::begin(directory); + auto curDirE = llvm::sys::path::end(directory); + for (; curDirIt != curDirE && *curDirIt == *fileIt; ++curDirIt, ++fileIt) + llvm::sys::path::append(dirBuf, *curDirIt); + if (std::distance(llvm::sys::path::begin(directory), curDirIt) == 1) { + // Don't strip the common prefix if it is only the root "/" since that + // would make LLVM diagnostic locations confusing. + directory = StringRef(); + } else { + for (; fileIt != fileE; ++fileIt) + llvm::sys::path::append(fileBuf, *fileIt); + directory = dirBuf; + fileName = fileBuf; + } + } + return (file = builder.createFile(fileName, directory)); +} diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -13,6 +13,7 @@ #include "mlir/Target/LLVMIR/ModuleTranslation.h" +#include "DebugTranslation.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/Module.h" @@ -30,6 +31,7 @@ using namespace mlir; using namespace mlir::LLVM; +using namespace mlir::LLVM::detail; #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc" @@ -265,6 +267,16 @@ llvm_unreachable("incorrect atomic ordering"); } +ModuleTranslation::ModuleTranslation(Operation *module, + std::unique_ptr llvmModule) + : mlirModule(module), llvmModule(std::move(llvmModule)), + debugTranslation( + std::make_unique(module, *this->llvmModule)) { + assert(satisfiesLLVMModule(mlirModule) && + "mlirModule should honor LLVM's module semantics."); +} +ModuleTranslation::~ModuleTranslation() {} + /// Given a single MLIR operation, create the corresponding LLVM IR operation /// using the `builder`. LLVM IR Builder does not have a generic interface so /// this has to be a long chain of `if`s calling different functions with a @@ -371,6 +383,7 @@ /// are not connected to the source basic blocks, which may not exist yet. LogicalResult ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) { llvm::IRBuilder<> builder(blockMapping[&bb]); + auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram(); // Before traversing operations, make block arguments available through // value remapping and PHI nodes, but do not add incoming edges for the PHI @@ -395,6 +408,10 @@ // Traverse operations. for (auto &op : bb) { + // Set the current debug location within the builder. + builder.SetCurrentDebugLocation( + debugTranslation->translateLoc(op.getLoc(), subprogram)); + if (failed(convertOperation(op, builder))) return failure(); } @@ -520,6 +537,10 @@ blockMapping.clear(); valueMapping.clear(); llvm::Function *llvmFunc = functionMapping.lookup(func.getName()); + + // Translate the debug information for this function. + debugTranslation->translate(func, *llvmFunc); + // Add function arguments to the value remapping table. // If there was noalias info then we decorate each argument accordingly. unsigned int argIdx = 0; diff --git a/mlir/lib/Transforms/StripDebugInfo.cpp b/mlir/lib/Transforms/StripDebugInfo.cpp --- a/mlir/lib/Transforms/StripDebugInfo.cpp +++ b/mlir/lib/Transforms/StripDebugInfo.cpp @@ -14,24 +14,21 @@ using namespace mlir; namespace { -struct StripDebugInfo : public FunctionPass { - void runOnFunction() override; +struct StripDebugInfo : public OperationPass { + void runOnOperation() override; }; } // end anonymous namespace -void StripDebugInfo::runOnFunction() { - FuncOp func = getFunction(); +void StripDebugInfo::runOnOperation() { + // Strip the debug info from all operations. auto unknownLoc = UnknownLoc::get(&getContext()); - - // Strip the debug info from the function and its operations. - func.setLoc(unknownLoc); - func.walk([&](Operation *op) { op->setLoc(unknownLoc); }); + getOperation()->walk([&](Operation *op) { op->setLoc(unknownLoc); }); } /// Creates a pass to strip debug information from a function. -std::unique_ptr> mlir::createStripDebugInfoPass() { +std::unique_ptr mlir::createStripDebugInfoPass() { return std::make_unique(); } static PassRegistration - pass("strip-debuginfo", "Strip debug info from functions and operations"); + pass("strip-debuginfo", "Strip debug info from all operations"); diff --git a/mlir/test/Target/llvmir-debug.mlir b/mlir/test/Target/llvmir-debug.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Target/llvmir-debug.mlir @@ -0,0 +1,35 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// CHECK-LABEL: define void @func_no_debug() +// CHECK-NOT: !dbg +llvm.func @func_no_debug() { + llvm.return loc(unknown) +} loc(unknown) + +// CHECK-LABEL: define void @func_with_debug() +// CHECK-SAME: !dbg ![[FUNC_LOC:[0-9]+]] +llvm.func @func_with_debug() { + // CHECK: call void @func_no_debug() + // CHECK-NOT: !dbg + llvm.call @func_no_debug() : () -> () loc(unknown) + + // CHECK: call void @func_no_debug(), !dbg ![[CALLSITE_LOC:[0-9]+]] + llvm.call @func_no_debug() : () -> () loc(callsite("mysource.cc":3:4 at "mysource.cc":5:6)) + + // CHECK: call void @func_no_debug(), !dbg ![[FILE_LOC:[0-9]+]] + llvm.call @func_no_debug() : () -> () loc("foo.mlir":1:2) + + // CHECK: call void @func_no_debug(), !dbg ![[NAMED_LOC:[0-9]+]] + llvm.call @func_no_debug() : () -> () loc("named"("foo.mlir":10:10)) + + // CHECK: call void @func_no_debug(), !dbg ![[FUSED_LOC:[0-9]+]] + llvm.call @func_no_debug() : () -> () loc(fused[callsite("mysource.cc":1:1 at "mysource.cc":5:6), "mysource.cc":1:1]) + + llvm.return +} loc("foo.mlir":1:1) + +// CHECK-DAG: ![[FUNC_LOC]] = distinct !DISubprogram{{.*}}, line: 1 +// CHECK-DAG: ![[CALLSITE_LOC]] = !DILocation(line: 3, column: 4, +// CHECK-DAG: ![[FILE_LOC]] = !DILocation(line: 1, column: 2, +// CHECK-DAG: ![[NAMED_LOC]] = !DILocation(line: 10, column: 10 +// CHECK-DAG: ![[FUSED_LOC]] = !DILocation(line: 1, column: 1 diff --git a/mlir/test/Target/llvmir.mlir b/mlir/test/Target/llvmir.mlir --- a/mlir/test/Target/llvmir.mlir +++ b/mlir/test/Target/llvmir.mlir @@ -74,7 +74,7 @@ // phi nodes, scalar type conversion, arithmetic operations. // -// CHECK-LABEL: define void @empty() { +// CHECK-LABEL: define void @empty() // CHECK-NEXT: ret void // CHECK-NEXT: } llvm.func @empty() { @@ -102,7 +102,7 @@ llvm.func @body(!llvm.i64) -// CHECK-LABEL: define void @simple_loop() { +// CHECK-LABEL: define void @simple_loop() llvm.func @simple_loop() { // CHECK: br label %[[SIMPLE_bb1:[0-9]+]] llvm.br ^bb1 @@ -139,7 +139,7 @@ llvm.return } -// CHECK-LABEL: define void @simple_caller() { +// CHECK-LABEL: define void @simple_caller() // CHECK-NEXT: call void @simple_loop() // CHECK-NEXT: ret void // CHECK-NEXT: } @@ -155,7 +155,7 @@ // return //} -// CHECK-LABEL: define void @ml_caller() { +// CHECK-LABEL: define void @ml_caller() // CHECK-NEXT: call void @simple_loop() // CHECK-NEXT: call void @more_imperfectly_nested_loops() // CHECK-NEXT: ret void @@ -171,7 +171,7 @@ // CHECK-LABEL: declare i32 @other(i64, i32) llvm.func @other(!llvm.i64, !llvm.i32) -> !llvm.i32 -// CHECK-LABEL: define i32 @func_args(i32 {{%.*}}, i32 {{%.*}}) { +// CHECK-LABEL: define i32 @func_args(i32 {{%.*}}, i32 {{%.*}}) // CHECK-NEXT: br label %[[ARGS_bb1:[0-9]+]] llvm.func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 { %0 = llvm.mlir.constant(0 : i32) : !llvm.i32 @@ -226,7 +226,7 @@ // CHECK: declare void @post(i64) llvm.func @post(!llvm.i64) -// CHECK-LABEL: define void @imperfectly_nested_loops() { +// CHECK-LABEL: define void @imperfectly_nested_loops() // CHECK-NEXT: br label %[[IMPER_bb1:[0-9]+]] llvm.func @imperfectly_nested_loops() { llvm.br ^bb1 @@ -301,7 +301,7 @@ llvm.func @body3(!llvm.i64, !llvm.i64) // A complete function transformation check. -// CHECK-LABEL: define void @more_imperfectly_nested_loops() { +// CHECK-LABEL: define void @more_imperfectly_nested_loops() // CHECK-NEXT: br label %1 // CHECK: 1: ; preds = %0 // CHECK-NEXT: br label %2 @@ -638,7 +638,7 @@ llvm.return } -// CHECK-LABEL: define { float*, i64 } @memref_args_rets({ float* } {{%.*}}, { float*, i64 } {{%.*}}, { float*, i64 } {{%.*}}) { +// CHECK-LABEL: define { float*, i64 } @memref_args_rets({ float* } {{%.*}}, { float*, i64 } {{%.*}}, { float*, i64 } {{%.*}}) llvm.func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }">, %arg2: !llvm<"{ float*, i64 }">) -> !llvm<"{ float*, i64 }"> { %0 = llvm.mlir.constant(7 : index) : !llvm.i64 // CHECK-NEXT: %{{[0-9]+}} = call i64 @get_index() @@ -718,7 +718,7 @@ llvm.func @get_f32() -> !llvm.float llvm.func @get_memref() -> !llvm<"{ float*, i64, i64 }"> -// CHECK-LABEL: define { i64, float, { float*, i64, i64 } } @multireturn() { +// CHECK-LABEL: define { i64, float, { float*, i64, i64 } } @multireturn() llvm.func @multireturn() -> !llvm<"{ i64, float, { float*, i64, i64 } }"> { %0 = llvm.call @get_i64() : () -> !llvm.i64 %1 = llvm.call @get_f32() : () -> !llvm.float @@ -735,7 +735,7 @@ } -// CHECK-LABEL: define void @multireturn_caller() { +// CHECK-LABEL: define void @multireturn_caller() llvm.func @multireturn_caller() { // CHECK-NEXT: %1 = call { i64, float, { float*, i64, i64 } } @multireturn() // CHECK-NEXT: [[ret0:%[0-9]+]] = extractvalue { i64, float, { float*, i64, i64 } } %1, 0 @@ -769,7 +769,7 @@ llvm.return } -// CHECK-LABEL: define <4 x float> @vector_ops(<4 x float> {{%.*}}, <4 x i1> {{%.*}}, <4 x i64> {{%.*}}) { +// CHECK-LABEL: define <4 x float> @vector_ops(<4 x float> {{%.*}}, <4 x i1> {{%.*}}, <4 x i64> {{%.*}}) llvm.func @vector_ops(%arg0: !llvm<"<4 x float>">, %arg1: !llvm<"<4 x i1>">, %arg2: !llvm<"<4 x i64>">) -> !llvm<"<4 x float>"> { %0 = llvm.mlir.constant(dense<4.200000e+01> : vector<4xf32>) : !llvm<"<4 x float>"> // CHECK-NEXT: %4 = fadd <4 x float> %0, @@ -883,7 +883,7 @@ // Indirect function calls // -// CHECK-LABEL: define void @indirect_const_call(i64 {{%.*}}) { +// CHECK-LABEL: define void @indirect_const_call(i64 {{%.*}}) llvm.func @indirect_const_call(%arg0: !llvm.i64) { // CHECK-NEXT: call void @body(i64 %0) %0 = llvm.mlir.constant(@body) : !llvm<"void (i64)*"> @@ -892,7 +892,7 @@ llvm.return } -// CHECK-LABEL: define i32 @indirect_call(i32 (float)* {{%.*}}, float {{%.*}}) { +// CHECK-LABEL: define i32 @indirect_call(i32 (float)* {{%.*}}, float {{%.*}}) llvm.func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm.float) -> !llvm.i32 { // CHECK-NEXT: %3 = call i32 %0(float %1) %0 = llvm.call %arg0(%arg1) : (!llvm.float) -> !llvm.i32 @@ -905,7 +905,7 @@ // predecessor more than once. // -// CHECK-LABEL: define void @cond_br_arguments(i1 {{%.*}}, i1 {{%.*}}) { +// CHECK-LABEL: define void @cond_br_arguments(i1 {{%.*}}, i1 {{%.*}}) llvm.func @cond_br_arguments(%arg0: !llvm.i1, %arg1: !llvm.i1) { // CHECK-NEXT: br i1 %0, label %3, label %5 llvm.cond_br %arg0, ^bb1(%arg0 : !llvm.i1), ^bb2 @@ -922,7 +922,7 @@ llvm.br ^bb1(%arg1 : !llvm.i1) } -// CHECK-LABEL: define void @llvm_noalias(float* noalias {{%*.}}) { +// CHECK-LABEL: define void @llvm_noalias(float* noalias {{%*.}}) llvm.func @llvm_noalias(%arg0: !llvm<"float*"> {llvm.noalias = true}) { llvm.return } diff --git a/mlir/tools/mlir-cuda-runner/mlir-cuda-runner.cpp b/mlir/tools/mlir-cuda-runner/mlir-cuda-runner.cpp --- a/mlir/tools/mlir-cuda-runner/mlir-cuda-runner.cpp +++ b/mlir/tools/mlir-cuda-runner/mlir-cuda-runner.cpp @@ -28,6 +28,7 @@ #include "mlir/Pass/PassManager.h" #include "mlir/Support/JitRunner.h" #include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/Passes.h" #include "cuda.h" @@ -106,6 +107,7 @@ pm.addPass(createGpuKernelOutliningPass()); auto &kernelPm = pm.nest(); + kernelPm.addPass(createStripDebugInfoPass()); kernelPm.addPass(createLowerGpuOpsToNVVMOpsPass()); kernelPm.addPass(createConvertGPUKernelToCubinPass(&compilePtxToCubin)); pm.addPass(createLowerToLLVMPass());