Skip to content

Commit cd5ee27

Browse files
authored
[reland][flang] Initial debug info support for local variables (#92304)
This is same as #90905 with an added fix. The issue was that we generated variable info even when user asked for line-tables-only. This caused llvm dwarf generation code to fail an assertion as it expected an empty variable list. Fixed by not generating debug info for variables when user wants only line table. I also updated a test check for this case.
1 parent dcd32bd commit cd5ee27

File tree

14 files changed

+361
-47
lines changed

14 files changed

+361
-47
lines changed

flang/lib/Optimizer/CodeGen/CGOps.h renamed to flang/include/flang/Optimizer/CodeGen/CGOps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef OPTIMIZER_CODEGEN_CGOPS_H
1414
#define OPTIMIZER_CODEGEN_CGOPS_H
1515

16+
#include "flang/Optimizer/Dialect/FIRAttr.h"
1617
#include "flang/Optimizer/Dialect/FIRType.h"
1718
#include "mlir/Dialect/Func/IR/FuncOps.h"
1819

flang/include/flang/Optimizer/CodeGen/CGOps.td

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
include "mlir/IR/SymbolInterfaces.td"
1818
include "flang/Optimizer/Dialect/FIRTypes.td"
19+
include "flang/Optimizer/Dialect/FIRAttr.td"
20+
include "mlir/IR/BuiltinAttributes.td"
1921

2022
def fircg_Dialect : Dialect {
2123
let name = "fircg";
@@ -202,4 +204,36 @@ def fircg_XArrayCoorOp : fircg_Op<"ext_array_coor", [AttrSizedOperandSegments]>
202204
}];
203205
}
204206

207+
// Extended Declare operation.
208+
def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
209+
let summary = "for internal conversion only";
210+
211+
let description = [{
212+
Prior to lowering to LLVM IR dialect, a DeclareOp will
213+
be converted to an extended DeclareOp.
214+
}];
215+
216+
let arguments = (ins
217+
AnyRefOrBox:$memref,
218+
Variadic<AnyIntegerType>:$shape,
219+
Variadic<AnyIntegerType>:$shift,
220+
Variadic<AnyIntegerType>:$typeparams,
221+
Optional<fir_DummyScopeType>:$dummy_scope,
222+
Builtin_StringAttr:$uniq_name
223+
);
224+
let results = (outs AnyRefOrBox);
225+
226+
let assemblyFormat = [{
227+
$memref (`(` $shape^ `)`)? (`origin` $shift^)? (`typeparams` $typeparams^)?
228+
(`dummy_scope` $dummy_scope^)?
229+
attr-dict `:` functional-type(operands, results)
230+
}];
231+
232+
let extraClassDeclaration = [{
233+
// Shape is optional, but if it exists, it will be at offset 1.
234+
unsigned shapeOffset() { return 1; }
235+
unsigned shiftOffset() { return shapeOffset() + getShape().size(); }
236+
}];
237+
}
238+
205239
#endif

flang/include/flang/Optimizer/CodeGen/CGPasses.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def CodeGenRewrite : Pass<"cg-rewrite", "mlir::ModuleOp"> {
4747
let dependentDialects = [
4848
"fir::FIROpsDialect", "fir::FIRCodeGenDialect"
4949
];
50+
let options = [
51+
Option<"preserveDeclare", "preserve-declare", "bool", /*default=*/"false",
52+
"Preserve DeclareOp during pre codegen re-write.">
53+
];
5054
let statistics = [
5155
Statistic<"numDCE", "num-dce'd", "Number of operations eliminated">
5256
];

flang/include/flang/Optimizer/CodeGen/CodeGen.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ struct NameUniquer;
3030

3131
/// Prerequiste pass for code gen. Perform intermediate rewrites to perform
3232
/// the code gen (to LLVM-IR dialect) conversion.
33-
std::unique_ptr<mlir::Pass> createFirCodeGenRewritePass();
33+
std::unique_ptr<mlir::Pass> createFirCodeGenRewritePass(
34+
CodeGenRewriteOptions Options = CodeGenRewriteOptions{});
3435

3536
/// FirTargetRewritePass options.
3637
struct TargetRewriteOptions {
@@ -88,7 +89,8 @@ void populateFIRToLLVMConversionPatterns(fir::LLVMTypeConverter &converter,
8889
fir::FIRToLLVMPassOptions &options);
8990

9091
/// Populate the pattern set with the PreCGRewrite patterns.
91-
void populatePreCGRewritePatterns(mlir::RewritePatternSet &patterns);
92+
void populatePreCGRewritePatterns(mlir::RewritePatternSet &patterns,
93+
bool preserveDeclare);
9294

9395
// declarative passes
9496
#define GEN_PASS_REGISTRATION

flang/include/flang/Tools/CLOptions.inc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,11 @@ inline void addMemoryAllocationOpt(mlir::PassManager &pm) {
174174
}
175175

176176
#if !defined(FLANG_EXCLUDE_CODEGEN)
177-
inline void addCodeGenRewritePass(mlir::PassManager &pm) {
178-
addPassConditionally(
179-
pm, disableCodeGenRewrite, fir::createFirCodeGenRewritePass);
177+
inline void addCodeGenRewritePass(mlir::PassManager &pm, bool preserveDeclare) {
178+
fir::CodeGenRewriteOptions options;
179+
options.preserveDeclare = preserveDeclare;
180+
addPassConditionally(pm, disableCodeGenRewrite,
181+
[&]() { return fir::createFirCodeGenRewritePass(options); });
180182
}
181183

182184
inline void addTargetRewritePass(mlir::PassManager &pm) {
@@ -358,7 +360,8 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
358360
MLIRToLLVMPassPipelineConfig config, llvm::StringRef inputFilename = {}) {
359361
fir::addBoxedProcedurePass(pm);
360362
addNestedPassToAllTopLevelOperations(pm, fir::createAbstractResultOpt);
361-
fir::addCodeGenRewritePass(pm);
363+
fir::addCodeGenRewritePass(
364+
pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo));
362365
fir::addTargetRewritePass(pm);
363366
fir::addExternalNameConversionPass(pm, config.Underscoring);
364367
fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename);

flang/lib/Optimizer/CodeGen/CGOps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "CGOps.h"
13+
#include "flang/Optimizer/CodeGen/CGOps.h"
1414
#include "flang/Optimizer/Dialect/FIRDialect.h"
1515
#include "flang/Optimizer/Dialect/FIROps.h"
1616
#include "flang/Optimizer/Dialect/FIRType.h"

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#include "flang/Optimizer/CodeGen/CodeGen.h"
1414

15-
#include "CGOps.h"
15+
#include "flang/Optimizer/CodeGen/CGOps.h"
1616
#include "flang/Optimizer/CodeGen/CodeGenOpenMP.h"
1717
#include "flang/Optimizer/CodeGen/FIROpPatterns.h"
1818
#include "flang/Optimizer/CodeGen/TypeConverter.h"
@@ -170,6 +170,28 @@ genAllocationScaleSize(OP op, mlir::Type ity,
170170
return nullptr;
171171
}
172172

173+
namespace {
174+
struct DeclareOpConversion : public fir::FIROpConversion<fir::cg::XDeclareOp> {
175+
public:
176+
using FIROpConversion::FIROpConversion;
177+
mlir::LogicalResult
178+
matchAndRewrite(fir::cg::XDeclareOp declareOp, OpAdaptor adaptor,
179+
mlir::ConversionPatternRewriter &rewriter) const override {
180+
auto memRef = adaptor.getOperands()[0];
181+
if (auto fusedLoc = mlir::dyn_cast<mlir::FusedLoc>(declareOp.getLoc())) {
182+
if (auto varAttr =
183+
mlir::dyn_cast_or_null<mlir::LLVM::DILocalVariableAttr>(
184+
fusedLoc.getMetadata())) {
185+
rewriter.create<mlir::LLVM::DbgDeclareOp>(memRef.getLoc(), memRef,
186+
varAttr, nullptr);
187+
}
188+
}
189+
rewriter.replaceOp(declareOp, memRef);
190+
return mlir::success();
191+
}
192+
};
193+
} // namespace
194+
173195
namespace {
174196
/// convert to LLVM IR dialect `alloca`
175197
struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
@@ -3714,19 +3736,19 @@ void fir::populateFIRToLLVMConversionPatterns(
37143736
BoxOffsetOpConversion, BoxProcHostOpConversion, BoxRankOpConversion,
37153737
BoxTypeCodeOpConversion, BoxTypeDescOpConversion, CallOpConversion,
37163738
CmpcOpConversion, ConstcOpConversion, ConvertOpConversion,
3717-
CoordinateOpConversion, DTEntryOpConversion, DivcOpConversion,
3718-
EmboxOpConversion, EmboxCharOpConversion, EmboxProcOpConversion,
3719-
ExtractValueOpConversion, FieldIndexOpConversion, FirEndOpConversion,
3720-
FreeMemOpConversion, GlobalLenOpConversion, GlobalOpConversion,
3721-
HasValueOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion,
3722-
IsPresentOpConversion, LenParamIndexOpConversion, LoadOpConversion,
3723-
MulcOpConversion, NegcOpConversion, NoReassocOpConversion,
3724-
SelectCaseOpConversion, SelectOpConversion, SelectRankOpConversion,
3725-
SelectTypeOpConversion, ShapeOpConversion, ShapeShiftOpConversion,
3726-
ShiftOpConversion, SliceOpConversion, StoreOpConversion,
3727-
StringLitOpConversion, SubcOpConversion, TypeDescOpConversion,
3728-
TypeInfoOpConversion, UnboxCharOpConversion, UnboxProcOpConversion,
3729-
UndefOpConversion, UnreachableOpConversion,
3739+
CoordinateOpConversion, DTEntryOpConversion, DeclareOpConversion,
3740+
DivcOpConversion, EmboxOpConversion, EmboxCharOpConversion,
3741+
EmboxProcOpConversion, ExtractValueOpConversion, FieldIndexOpConversion,
3742+
FirEndOpConversion, FreeMemOpConversion, GlobalLenOpConversion,
3743+
GlobalOpConversion, HasValueOpConversion, InsertOnRangeOpConversion,
3744+
InsertValueOpConversion, IsPresentOpConversion, LenParamIndexOpConversion,
3745+
LoadOpConversion, MulcOpConversion, NegcOpConversion,
3746+
NoReassocOpConversion, SelectCaseOpConversion, SelectOpConversion,
3747+
SelectRankOpConversion, SelectTypeOpConversion, ShapeOpConversion,
3748+
ShapeShiftOpConversion, ShiftOpConversion, SliceOpConversion,
3749+
StoreOpConversion, StringLitOpConversion, SubcOpConversion,
3750+
TypeDescOpConversion, TypeInfoOpConversion, UnboxCharOpConversion,
3751+
UnboxProcOpConversion, UndefOpConversion, UnreachableOpConversion,
37303752
UnrealizedConversionCastOpConversion, XArrayCoorOpConversion,
37313753
XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(converter,
37323754
options);

flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
#include "flang/Optimizer/CodeGen/CodeGen.h"
1414

15-
#include "CGOps.h"
1615
#include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done
16+
#include "flang/Optimizer/CodeGen/CGOps.h"
1717
#include "flang/Optimizer/Dialect/FIRDialect.h"
1818
#include "flang/Optimizer/Dialect/FIROps.h"
1919
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -270,13 +270,43 @@ class ArrayCoorConversion : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
270270
};
271271

272272
class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
273+
bool preserveDeclare;
274+
273275
public:
274276
using OpRewritePattern::OpRewritePattern;
277+
DeclareOpConversion(mlir::MLIRContext *ctx, bool preserveDecl)
278+
: OpRewritePattern(ctx), preserveDeclare(preserveDecl) {}
275279

276280
mlir::LogicalResult
277281
matchAndRewrite(fir::DeclareOp declareOp,
278282
mlir::PatternRewriter &rewriter) const override {
279-
rewriter.replaceOp(declareOp, declareOp.getMemref());
283+
if (!preserveDeclare) {
284+
rewriter.replaceOp(declareOp, declareOp.getMemref());
285+
return mlir::success();
286+
}
287+
auto loc = declareOp.getLoc();
288+
llvm::SmallVector<mlir::Value> shapeOpers;
289+
llvm::SmallVector<mlir::Value> shiftOpers;
290+
if (auto shapeVal = declareOp.getShape()) {
291+
if (auto shapeOp = mlir::dyn_cast<fir::ShapeOp>(shapeVal.getDefiningOp()))
292+
populateShape(shapeOpers, shapeOp);
293+
else if (auto shiftOp =
294+
mlir::dyn_cast<fir::ShapeShiftOp>(shapeVal.getDefiningOp()))
295+
populateShapeAndShift(shapeOpers, shiftOpers, shiftOp);
296+
else if (auto shiftOp =
297+
mlir::dyn_cast<fir::ShiftOp>(shapeVal.getDefiningOp()))
298+
populateShift(shiftOpers, shiftOp);
299+
else
300+
return mlir::failure();
301+
}
302+
// FIXME: Add FortranAttrs and CudaAttrs
303+
auto xDeclOp = rewriter.create<fir::cg::XDeclareOp>(
304+
loc, declareOp.getType(), declareOp.getMemref(), shapeOpers, shiftOpers,
305+
declareOp.getTypeparams(), declareOp.getDummyScope(),
306+
declareOp.getUniqName());
307+
LLVM_DEBUG(llvm::dbgs()
308+
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');
309+
rewriter.replaceOp(declareOp, xDeclOp.getOperation()->getResults());
280310
return mlir::success();
281311
}
282312
};
@@ -297,6 +327,7 @@ class DummyScopeOpConversion
297327

298328
class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
299329
public:
330+
CodeGenRewrite(fir::CodeGenRewriteOptions opts) : Base(opts) {}
300331
void runOnOperation() override final {
301332
mlir::ModuleOp mod = getOperation();
302333

@@ -314,7 +345,7 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
314345
mlir::cast<fir::BaseBoxType>(embox.getType()).getEleTy()));
315346
});
316347
mlir::RewritePatternSet patterns(&context);
317-
fir::populatePreCGRewritePatterns(patterns);
348+
fir::populatePreCGRewritePatterns(patterns, preserveDeclare);
318349
if (mlir::failed(
319350
mlir::applyPartialConversion(mod, target, std::move(patterns)))) {
320351
mlir::emitError(mlir::UnknownLoc::get(&context),
@@ -330,12 +361,14 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
330361

331362
} // namespace
332363

333-
std::unique_ptr<mlir::Pass> fir::createFirCodeGenRewritePass() {
334-
return std::make_unique<CodeGenRewrite>();
364+
std::unique_ptr<mlir::Pass>
365+
fir::createFirCodeGenRewritePass(fir::CodeGenRewriteOptions Options) {
366+
return std::make_unique<CodeGenRewrite>(Options);
335367
}
336368

337-
void fir::populatePreCGRewritePatterns(mlir::RewritePatternSet &patterns) {
369+
void fir::populatePreCGRewritePatterns(mlir::RewritePatternSet &patterns,
370+
bool preserveDeclare) {
338371
patterns.insert<EmboxConversion, ArrayCoorConversion, ReboxConversion,
339-
DeclareOpConversion, DummyScopeOpConversion>(
340-
patterns.getContext());
372+
DummyScopeOpConversion>(patterns.getContext());
373+
patterns.add<DeclareOpConversion>(patterns.getContext(), preserveDeclare);
341374
}

flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "flang/Common/Version.h"
1616
#include "flang/Optimizer/Builder/FIRBuilder.h"
1717
#include "flang/Optimizer/Builder/Todo.h"
18+
#include "flang/Optimizer/CodeGen/CGOps.h"
1819
#include "flang/Optimizer/Dialect/FIRDialect.h"
1920
#include "flang/Optimizer/Dialect/FIROps.h"
2021
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -45,13 +46,59 @@ namespace fir {
4546
namespace {
4647

4748
class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
49+
void handleDeclareOp(fir::cg::XDeclareOp declOp,
50+
mlir::LLVM::DIFileAttr fileAttr,
51+
mlir::LLVM::DIScopeAttr scopeAttr,
52+
fir::DebugTypeGenerator &typeGen);
53+
4854
public:
4955
AddDebugInfoPass(fir::AddDebugInfoOptions options) : Base(options) {}
5056
void runOnOperation() override;
5157
};
5258

59+
static uint32_t getLineFromLoc(mlir::Location loc) {
60+
uint32_t line = 1;
61+
if (auto fileLoc = mlir::dyn_cast<mlir::FileLineColLoc>(loc))
62+
line = fileLoc.getLine();
63+
return line;
64+
}
65+
5366
} // namespace
5467

68+
void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
69+
mlir::LLVM::DIFileAttr fileAttr,
70+
mlir::LLVM::DIScopeAttr scopeAttr,
71+
fir::DebugTypeGenerator &typeGen) {
72+
mlir::MLIRContext *context = &getContext();
73+
mlir::OpBuilder builder(context);
74+
auto result = fir::NameUniquer::deconstruct(declOp.getUniqName());
75+
76+
if (result.first != fir::NameUniquer::NameKind::VARIABLE)
77+
return;
78+
79+
// Only accept local variables.
80+
if (result.second.procs.empty())
81+
return;
82+
83+
// FIXME: There may be cases where an argument is processed a bit before
84+
// DeclareOp is generated. In that case, DeclareOp may point to an
85+
// intermediate op and not to BlockArgument. We need to find those cases and
86+
// walk the chain to get to the actual argument.
87+
88+
unsigned argNo = 0;
89+
if (auto Arg = llvm::dyn_cast<mlir::BlockArgument>(declOp.getMemref()))
90+
argNo = Arg.getArgNumber() + 1;
91+
92+
auto tyAttr = typeGen.convertType(fir::unwrapRefType(declOp.getType()),
93+
fileAttr, scopeAttr, declOp.getLoc());
94+
95+
auto localVarAttr = mlir::LLVM::DILocalVariableAttr::get(
96+
context, scopeAttr, mlir::StringAttr::get(context, result.second.name),
97+
fileAttr, getLineFromLoc(declOp.getLoc()), argNo, /* alignInBits*/ 0,
98+
tyAttr);
99+
declOp->setLoc(builder.getFusedLoc({declOp->getLoc()}, localVarAttr));
100+
}
101+
55102
void AddDebugInfoPass::runOnOperation() {
56103
mlir::ModuleOp module = getOperation();
57104
mlir::MLIRContext *context = &getContext();
@@ -144,14 +191,19 @@ void AddDebugInfoPass::runOnOperation() {
144191
subprogramFlags =
145192
subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
146193
}
147-
unsigned line = 1;
148-
if (auto funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l))
149-
line = funcLoc.getLine();
150-
194+
unsigned line = getLineFromLoc(l);
151195
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
152196
context, id, compilationUnit, fileAttr, funcName, fullName,
153197
funcFileAttr, line, line, subprogramFlags, subTypeAttr);
154198
funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr));
199+
200+
// Don't process variables if user asked for line tables only.
201+
if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
202+
return;
203+
204+
funcOp.walk([&](fir::cg::XDeclareOp declOp) {
205+
handleDeclareOp(declOp, fileAttr, spAttr, typeGen);
206+
});
155207
});
156208
}
157209

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
2424
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
2525
}
2626

27-
static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
28-
return mlir::LLVM::DIBasicTypeAttr::get(
29-
context, llvm::dwarf::DW_TAG_base_type, "void", 32, 1);
30-
}
31-
3227
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
3328
mlir::StringAttr name,
3429
unsigned bitSize,
@@ -37,6 +32,11 @@ static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
3732
context, llvm::dwarf::DW_TAG_base_type, name, bitSize, decoding);
3833
}
3934

35+
static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
36+
return genBasicType(context, mlir::StringAttr::get(context, "integer"), 32,
37+
llvm::dwarf::DW_ATE_signed);
38+
}
39+
4040
mlir::LLVM::DITypeAttr
4141
DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
4242
mlir::LLVM::DIScopeAttr scope,

0 commit comments

Comments
 (0)