Skip to content

Commit a44ce1b

Browse files
abidhgysit
andauthored
[mlir][debug] Convert DbgIntrOp to DebugRecords directly. (#154926)
Currently the `DbgDeclareOP/DbgValueOP/DbgLabelOp` are first converted to llvm debug intrinsics which are later translated to debug records by a call of `convertToNewDbgValues`. This is not only inefficient but also makes the code that works on intermediate IR unnecessarily complicated. The debug intrinsics are also being phased out. This PR converts these Ops directly to debug records. The conversion is relatively simple but there is a bit of code repetition due to how the APIs in the `DIBuilders` are named. There are few `cast<>` which I would like to do without but could not see a good way around them. Any suggestions welcome here. Also noticed that `DISubprogramAttr` is inherited from `DIScopeAttr` while in llvm, the `DISubprogram` inherits from `DILocalScope`. I am going to fix this separately and then we could use `FusedLocWith<LLVM::DILocalScopeAttr>` and cast to `DILocalScope` will be much safer. As the output remains the same, the existing tests cover this change. I also ran the `GDB` tests with flang and there was no regression. --------- Co-authored-by: Tobias Gysi <[email protected]>
1 parent a0fd716 commit a44ce1b

File tree

3 files changed

+53
-28
lines changed

3 files changed

+53
-28
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -673,22 +673,6 @@ def LLVM_CoroPromiseOp : LLVM_IntrOp<"coro.promise", [], [], [], 1> {
673673

674674
class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
675675
: LLVM_IntrOp<name, [], [], traits, 0> {
676-
let llvmBuilder = [{
677-
// Debug intrinsics without debug locations are invalid.
678-
if(!builder.getCurrentDebugLocation())
679-
return success();
680-
llvm::Module *module = builder.GetInsertBlock()->getModule();
681-
llvm::LLVMContext &ctx = module->getContext();
682-
llvm::Function *fn =
683-
llvm::Intrinsic::getOrInsertDeclaration(module, llvm::Intrinsic::}]
684-
# !subst(".", "_", name) # [{);
685-
builder.CreateCall(fn, {
686-
llvm::MetadataAsValue::get(ctx,
687-
llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
688-
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
689-
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateExpression($locationExpr)),
690-
});
691-
}];
692676
let mlirBuilder = [{
693677
// Add debug intrindic to the list of intrinsics that need to be converted once the
694678
// full function was converted.
@@ -711,6 +695,22 @@ def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr", [
711695
LLVM_DILocalVariableAttr:$varInfo,
712696
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
713697
);
698+
let llvmBuilder = [{
699+
// Debug records without debug locations are invalid.
700+
if(!builder.getCurrentDebugLocation())
701+
return success();
702+
llvm::DILocalScope *scope = getLocalScopeFromLoc(builder, opInst.getLoc(),
703+
moduleTranslation);
704+
705+
llvm::Module *module = builder.GetInsertBlock()->getModule();
706+
llvm::DIBuilder debugInfoBuilder(*module);
707+
debugInfoBuilder.insertDeclare(moduleTranslation.lookupValue(opInst.getOperand(0)),
708+
llvm::cast<llvm::DILocalVariable>(
709+
moduleTranslation.translateDebugInfo($varInfo)),
710+
moduleTranslation.translateExpression($locationExpr),
711+
moduleTranslation.translateLoc(opInst.getLoc(), scope),
712+
builder.GetInsertPoint());
713+
}];
714714
}
715715

716716
def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value",
@@ -721,22 +721,41 @@ def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value",
721721
LLVM_DILocalVariableAttr:$varInfo,
722722
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
723723
);
724+
let llvmBuilder = [{
725+
// Debug records without debug locations are invalid.
726+
if(!builder.getCurrentDebugLocation())
727+
return success();
728+
llvm::DILocalScope *scope = getLocalScopeFromLoc(builder, opInst.getLoc(),
729+
moduleTranslation);
730+
731+
llvm::Module *module = builder.GetInsertBlock()->getModule();
732+
llvm::DIBuilder debugInfoBuilder(*module);
733+
debugInfoBuilder.insertDbgValueIntrinsic(
734+
moduleTranslation.lookupValue(opInst.getOperand(0)),
735+
llvm::cast<llvm::DILocalVariable>(
736+
moduleTranslation.translateDebugInfo($varInfo)),
737+
moduleTranslation.translateExpression($locationExpr),
738+
moduleTranslation.translateLoc(opInst.getLoc(), scope),
739+
builder.GetInsertPoint());
740+
}];
724741
}
725742

726743
def LLVM_DbgLabelOp : LLVM_IntrOp<"dbg.label", [], [], [], 0> {
727744
let summary = "Relates the program to a debug information label.";
728745
let arguments = (ins LLVM_DILabelAttr:$label);
729746
let llvmBuilder = [{
730-
// Debug intrinsics without debug locations are invalid.
747+
// Debug records without debug locations are invalid.
731748
if(!builder.getCurrentDebugLocation())
732749
return success();
750+
llvm::DILocalScope *scope = getLocalScopeFromLoc(builder, opInst.getLoc(),
751+
moduleTranslation);
752+
733753
llvm::Module *module = builder.GetInsertBlock()->getModule();
734-
llvm::LLVMContext &ctx = module->getContext();
735-
llvm::Function *fn =
736-
llvm::Intrinsic::getOrInsertDeclaration(module, llvm::Intrinsic::dbg_label);
737-
builder.CreateCall(fn, {
738-
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($label))
739-
});
754+
llvm::DIBuilder debugInfoBuilder(*module);
755+
debugInfoBuilder.insertLabel(
756+
llvm::cast<llvm::DILabel>(moduleTranslation.translateDebugInfo($label)),
757+
moduleTranslation.translateLoc(opInst.getLoc(), scope),
758+
builder.GetInsertPoint());
740759
}];
741760
let mlirBuilder = [{
742761
DILabelAttr labelAttr = $_label_attr($label);

mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
1919

2020
#include "llvm/ADT/TypeSwitch.h"
21+
#include "llvm/IR/DIBuilder.h"
2122
#include "llvm/IR/IRBuilder.h"
2223
#include "llvm/IR/InlineAsm.h"
2324
#include "llvm/IR/Instructions.h"
@@ -358,6 +359,16 @@ static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
358359
}
359360
}
360361

362+
static llvm::DILocalScope *
363+
getLocalScopeFromLoc(llvm::IRBuilderBase &builder, Location loc,
364+
LLVM::ModuleTranslation &moduleTranslation) {
365+
if (auto scopeLoc = loc->findInstanceOf<FusedLocWith<LLVM::DIScopeAttr>>())
366+
if (auto *localScope = llvm::dyn_cast<llvm::DILocalScope>(
367+
moduleTranslation.translateDebugInfo(scopeLoc.getMetadata())))
368+
return localScope;
369+
return builder.GetInsertBlock()->getParent()->getSubprogram();
370+
}
371+
361372
static LogicalResult
362373
convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
363374
LLVM::ModuleTranslation &moduleTranslation) {

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,11 +2403,6 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
24032403
if (failed(translator.convertUnresolvedBlockAddress()))
24042404
return nullptr;
24052405

2406-
// Once we've finished constructing elements in the module, we should convert
2407-
// it to use the debug info format desired by LLVM.
2408-
// See https://llvm.org/docs/RemoveDIsDebugInfo.html
2409-
translator.llvmModule->convertToNewDbgValues();
2410-
24112406
// Add the necessary debug info module flags, if they were not encoded in MLIR
24122407
// beforehand.
24132408
translator.debugTranslation->addModuleFlagsIfNotPresent();

0 commit comments

Comments
 (0)