12#include "llvm/BinaryFormat/Dwarf.h"
13#include "llvm/Support/Path.h"
17#define GEN_PASS_DEF_DISCOPEFORLLVMFUNCOPPASS
18#include "mlir/Dialect/LLVMIR/Transforms/Passes.h.inc"
26 if (
auto fileLoc = dyn_cast<FileLineColLoc>(loc))
28 if (
auto nameLoc = dyn_cast<NameLoc>(loc))
30 if (
auto opaqueLoc = dyn_cast<OpaqueLoc>(loc))
32 if (
auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
33 for (
auto loc : fusedLoc.getLocations()) {
38 if (
auto callerLoc = dyn_cast<CallSiteLoc>(loc))
47 LLVM::DICompileUnitAttr compileUnitAttr) {
56 LLVM::DIFileAttr fileAttr;
59 line = fileLoc.getLine();
60 StringRef inputFilePath = fileLoc.getFilename().getValue();
62 LLVM::DIFileAttr::get(context, llvm::sys::path::filename(inputFilePath),
63 llvm::sys::path::parent_path(inputFilePath));
65 fileAttr = compileUnitAttr
66 ? compileUnitAttr.getFile()
67 : LLVM::DIFileAttr::get(context,
"<unknown>",
"");
69 auto subroutineTypeAttr =
70 LLVM::DISubroutineTypeAttr::get(context, llvm::dwarf::DW_CC_normal, {});
77 auto subprogramFlags = LLVM::DISubprogramFlags::Optimized;
78 if (!llvmFunc.isExternal()) {
80 subprogramFlags |= LLVM::DISubprogramFlags::Definition;
84 auto funcNameAttr = llvmFunc.getNameAttr();
85 auto subprogramAttr = LLVM::DISubprogramAttr::get(
86 context,
id, compileUnitAttr, fileAttr, funcNameAttr, funcNameAttr,
88 line, line, subprogramFlags, subroutineTypeAttr,
90 llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
98 LLVM::DIFileAttr calleeFileAttr =
99 LLVM::DIFileAttr::get(context, llvm::sys::path::filename(calleeFileName),
100 llvm::sys::path::parent_path(calleeFileName));
101 auto lexicalBlockFileAttr = LLVM::DILexicalBlockFileAttr::get(
102 context, scopeAttr, calleeFileAttr, 0);
105 if (
auto callSiteLoc = dyn_cast<CallSiteLoc>(calleeLoc)) {
106 auto nestedLoc = callSiteLoc.getCallee();
107 loc =
getNestedLoc(op, lexicalBlockFileAttr, nestedLoc);
109 return FusedLoc::get(context, {loc}, lexicalBlockFileAttr);
117 if (
auto callSiteLoc = dyn_cast<CallSiteLoc>(opLoc)) {
118 auto callerLoc = callSiteLoc.getCaller();
119 auto calleeLoc = callSiteLoc.getCallee();
125 llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc())) {
126 scopeAttr = cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
147 StringRef opFile = opFileLoc.
getFilename().getValue();
148 StringRef funcFile = funcFileLoc.
getFilename().getValue();
152 if (opFile != funcFile) {
153 auto funcOpLoc = llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc());
156 auto scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
161 LLVM::DIFileAttr opFileAttr =
162 LLVM::DIFileAttr::get(context, llvm::sys::path::filename(opFile),
163 llvm::sys::path::parent_path(opFile));
165 LLVM::DILexicalBlockFileAttr lexicalBlockFileAttr =
166 LLVM::DILexicalBlockFileAttr::get(context, scopeAttr, opFileAttr, 0);
168 Location newLoc = FusedLoc::get(context, {opLoc}, lexicalBlockFileAttr);
175struct DIScopeForLLVMFuncOpPass
177 DIScopeForLLVMFuncOpPass> {
180 void runOnOperation()
override {
181 ModuleOp module = getOperation();
182 Location loc =
module.getLoc();
186 emitError(loc,
"LLVM dialect is not loaded.");
187 return signalPassFailure();
192 LLVM::DICompileUnitAttr compileUnitAttr;
193 if (
auto fusedCompileUnitAttr =
195 ->findInstanceOf<FusedLocWith<LLVM::DICompileUnitAttr>>()) {
196 compileUnitAttr = fusedCompileUnitAttr.getMetadata();
198 LLVM::DIFileAttr fileAttr;
200 StringRef inputFilePath = fileLoc.getFilename().getValue();
201 fileAttr = LLVM::DIFileAttr::get(
202 context, llvm::sys::path::filename(inputFilePath),
203 llvm::sys::path::parent_path(inputFilePath));
205 fileAttr = LLVM::DIFileAttr::get(context,
"<unknown>",
"");
208 compileUnitAttr = LLVM::DICompileUnitAttr::get(
210 fileAttr, StringAttr::get(context,
"MLIR"),
214 module.walk<WalkOrder::PreOrder>([&](Operation *op) -> void {
215 if (auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op)) {
218 addScopeToFunction(funcOp, compileUnitAttr);
static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr, Location calleeLoc)
static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc, LLVM::DICompileUnitAttr compileUnitAttr)
Creates a DISubprogramAttr with the provided compile unit and attaches it to the function.
static FileLineColLoc extractFileLoc(Location loc)
Attempt to extract a filename for the given loc.
static void setLexicalBlockFileAttr(Operation *op)
Adds DILexicalBlockFileAttr for operations with CallSiteLoc and operations from different files than ...
An attribute that associates a referenced attribute with a unique identifier.
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
An instance of this location represents a tuple of file, line number, and column number.
StringAttr getFilename() const
This class represents a fused location whose metadata is known to be an instance of the given type.
This class represents a LLVM attribute that describes a debug info scope.
T findInstanceOf()
Return an instance of the given location type if one is nested under the current location.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
Operation is the basic unit of execution within MLIR.
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
Location getLoc()
The source location the operation was defined or derived from.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
MLIRContext * getContext()
Return the context this operation is associated with.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.