Skip to content

Commit c8e44e5

Browse files
committed
Merge remote-tracking branch 'upstream/main' into delayed_privatization_15
2 parents 0d6aff2 + 16bd10a commit c8e44e5

File tree

84 files changed

+4916
-2355
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+4916
-2355
lines changed

clang/docs/UsersManual.rst

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,8 @@ are listed below.
23192319
on ELF targets when using the integrated assembler. This flag currently
23202320
only has an effect on ELF targets.
23212321

2322+
.. _funique_internal_linkage_names:
2323+
23222324
.. option:: -f[no]-unique-internal-linkage-names
23232325

23242326
Controls whether Clang emits a unique (best-effort) symbol name for internal
@@ -2448,27 +2450,41 @@ usual build cycle when using sample profilers for optimization:
24482450
usual build flags that you always build your application with. The only
24492451
requirement is that DWARF debug info including source line information is
24502452
generated. This DWARF information is important for the profiler to be able
2451-
to map instructions back to source line locations.
2453+
to map instructions back to source line locations. The usefulness of this
2454+
DWARF information can be improved with the ``-fdebug-info-for-profiling``
2455+
and ``-funique-internal-linkage-names`` options.
24522456

2453-
On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:
2457+
On Linux:
24542458

24552459
.. code-block:: console
24562460
2457-
$ clang++ -O2 -gline-tables-only code.cc -o code
2461+
$ clang++ -O2 -gline-tables-only \
2462+
-fdebug-info-for-profiling -funique-internal-linkage-names \
2463+
code.cc -o code
24582464
24592465
While MSVC-style targets default to CodeView debug information, DWARF debug
24602466
information is required to generate source-level LLVM profiles. Use
24612467
``-gdwarf`` to include DWARF debug information:
24622468

2463-
.. code-block:: console
2469+
.. code-block:: winbatch
2470+
2471+
> clang-cl /O2 -gdwarf -gline-tables-only ^
2472+
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
2473+
code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
2474+
2475+
.. note::
24642476

2465-
$ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld -link -debug:dwarf
2477+
:ref:`-funique-internal-linkage-names <funique_internal_linkage_names>`
2478+
generates unique names based on given command-line source file paths. If
2479+
your build system uses absolute source paths and these paths may change
2480+
between steps 1 and 4, then the uniqued function names may change and result
2481+
in unused profile data. Consider omitting this option in such cases.
24662482

24672483
2. Run the executable under a sampling profiler. The specific profiler
24682484
you use does not really matter, as long as its output can be converted
24692485
into the format that the LLVM optimizer understands.
24702486

2471-
Two such profilers are the the Linux Perf profiler
2487+
Two such profilers are the Linux Perf profiler
24722488
(https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),
24732489
available as part of `Intel VTune
24742490
<https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/vtune-profiler.html>`_.
@@ -2482,7 +2498,9 @@ usual build cycle when using sample profilers for optimization:
24822498

24832499
.. code-block:: console
24842500
2485-
$ perf record -b ./code
2501+
$ perf record -b -e BR_INST_RETIRED.NEAR_TAKEN:uppp ./code
2502+
2503+
If the event above is unavailable, ``branches:u`` is probably next-best.
24862504

24872505
Note the use of the ``-b`` flag. This tells Perf to use the Last Branch
24882506
Record (LBR) to record call chains. While this is not strictly required,
@@ -2532,21 +2550,42 @@ usual build cycle when using sample profilers for optimization:
25322550
that executes faster than the original one. Note that you are not
25332551
required to build the code with the exact same arguments that you
25342552
used in the first step. The only requirement is that you build the code
2535-
with ``-gline-tables-only`` and ``-fprofile-sample-use``.
2553+
with the same debug info options and ``-fprofile-sample-use``.
2554+
2555+
On Linux:
25362556

25372557
.. code-block:: console
25382558
2539-
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
2559+
$ clang++ -O2 -gline-tables-only \
2560+
-fdebug-info-for-profiling -funique-internal-linkage-names \
2561+
-fprofile-sample-use=code.prof code.cc -o code
25402562
2541-
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
2542-
edge counters. The profile inference algorithm (profi) can be used to infer
2543-
missing blocks and edge counts, and improve the quality of profile data.
2544-
Enable it with ``-fsample-profile-use-profi``.
2563+
On Windows:
25452564

2546-
.. code-block:: console
2565+
.. code-block:: winbatch
2566+
2567+
> clang-cl /O2 -gdwarf -gline-tables-only ^
2568+
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
2569+
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
2570+
2571+
[OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/
2572+
edge counters. The profile inference algorithm (profi) can be used to infer
2573+
missing blocks and edge counts, and improve the quality of profile data.
2574+
Enable it with ``-fsample-profile-use-profi``. For example, on Linux:
2575+
2576+
.. code-block:: console
2577+
2578+
$ clang++ -fsample-profile-use-profi -O2 -gline-tables-only \
2579+
-fdebug-info-for-profiling -funique-internal-linkage-names \
2580+
-fprofile-sample-use=code.prof code.cc -o code
2581+
2582+
On Windows:
2583+
2584+
.. code-block:: winbatch
25472585
2548-
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof \
2549-
-fsample-profile-use-profi code.cc -o code
2586+
> clang-cl /clang:-fsample-profile-use-profi /O2 -gdwarf -gline-tables-only ^
2587+
/clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^
2588+
/fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf
25502589
25512590
Sample Profile Formats
25522591
""""""""""""""""""""""

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
496496
if (mlir::isa<fir::SequenceType>(symTy) &&
497497
!Fortran::semantics::IsAllocatableOrPointer(sym)) {
498498
mlir::Type eleTy = mlir::cast<fir::SequenceType>(symTy).getEleTy();
499-
if (eleTy.isa<mlir::IntegerType, mlir::FloatType, fir::ComplexType,
500-
fir::LogicalType>()) {
499+
if (mlir::isa<mlir::IntegerType, mlir::FloatType, fir::ComplexType,
500+
fir::LogicalType>(eleTy)) {
501501
const auto *details =
502502
sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
503503
if (details->init()) {

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,12 +1964,12 @@ struct ValueOpCommon {
19641964
mlir::ArrayAttr arrAttr) {
19651965
llvm::SmallVector<int64_t> indices;
19661966
for (auto i = arrAttr.begin(), e = arrAttr.end(); i != e; ++i) {
1967-
if (auto intAttr = i->dyn_cast<mlir::IntegerAttr>()) {
1967+
if (auto intAttr = mlir::dyn_cast<mlir::IntegerAttr>(*i)) {
19681968
indices.push_back(intAttr.getInt());
19691969
} else {
1970-
auto fieldName = i->cast<mlir::StringAttr>().getValue();
1970+
auto fieldName = mlir::cast<mlir::StringAttr>(*i).getValue();
19711971
++i;
1972-
auto ty = i->cast<mlir::TypeAttr>().getValue();
1972+
auto ty = mlir::cast<mlir::TypeAttr>(*i).getValue();
19731973
auto index = mlir::cast<fir::RecordType>(ty).getFieldIndex(fieldName);
19741974
indices.push_back(index);
19751975
}
@@ -3014,7 +3014,7 @@ static void selectMatchAndRewrite(const fir::LLVMTypeConverter &lowering,
30143014
caseValues.push_back(intAttr.getInt());
30153015
continue;
30163016
}
3017-
assert(attr.template dyn_cast_or_null<mlir::UnitAttr>());
3017+
assert(mlir::dyn_cast_or_null<mlir::UnitAttr>(attr));
30183018
assert((t + 1 == conds) && "unit must be last");
30193019
defaultDestination = dest;
30203020
defaultOperands = destOps ? *destOps : mlir::ValueRange{};

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,10 +2498,8 @@ static constexpr llvm::StringRef getTargetOffsetAttr() {
24982498

24992499
template <typename OpT>
25002500
static mlir::LogicalResult verifyIntegralSwitchTerminator(OpT op) {
2501-
if (!op.getSelector()
2502-
.getType()
2503-
.template isa<mlir::IntegerType, mlir::IndexType,
2504-
fir::IntegerType>())
2501+
if (!mlir::isa<mlir::IntegerType, mlir::IndexType, fir::IntegerType>(
2502+
op.getSelector().getType()))
25052503
return op.emitOpError("must be an integer");
25062504
auto cases =
25072505
op->template getAttrOfType<mlir::ArrayAttr>(op.getCasesAttr()).getValue();
@@ -2576,7 +2574,7 @@ static void printIntegralSwitchTerminator(OpT op, mlir::OpAsmPrinter &p) {
25762574
if (i)
25772575
p << ", ";
25782576
auto &attr = cases[i];
2579-
if (auto intAttr = attr.template dyn_cast_or_null<mlir::IntegerAttr>())
2577+
if (auto intAttr = mlir::dyn_cast_or_null<mlir::IntegerAttr>(attr))
25802578
p << intAttr.getValue();
25812579
else
25822580
p.printAttribute(attr);

flang/lib/Optimizer/Dialect/FIRType.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,9 @@ BoxProcType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
695695
}
696696

697697
static bool cannotBePointerOrHeapElementType(mlir::Type eleTy) {
698-
return eleTy.isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
698+
return mlir::isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
699699
SliceType, FieldType, LenType, HeapType, PointerType,
700-
ReferenceType, TypeDescType>();
700+
ReferenceType, TypeDescType>(eleTy);
701701
}
702702

703703
//===----------------------------------------------------------------------===//
@@ -776,10 +776,10 @@ void fir::CharacterType::print(mlir::AsmPrinter &printer) const {
776776
mlir::LogicalResult
777777
fir::ClassType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
778778
mlir::Type eleTy) {
779-
if (eleTy.isa<fir::RecordType, fir::SequenceType, fir::HeapType,
779+
if (mlir::isa<fir::RecordType, fir::SequenceType, fir::HeapType,
780780
fir::PointerType, mlir::NoneType, mlir::IntegerType,
781781
mlir::FloatType, fir::CharacterType, fir::LogicalType,
782-
fir::ComplexType, mlir::ComplexType>())
782+
fir::ComplexType, mlir::ComplexType>(eleTy))
783783
return mlir::success();
784784
return emitError() << "invalid element type\n";
785785
}
@@ -1050,8 +1050,8 @@ void fir::ReferenceType::print(mlir::AsmPrinter &printer) const {
10501050
mlir::LogicalResult fir::ReferenceType::verify(
10511051
llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
10521052
mlir::Type eleTy) {
1053-
if (eleTy.isa<ShapeType, ShapeShiftType, SliceType, FieldType, LenType,
1054-
ReferenceType, TypeDescType>())
1053+
if (mlir::isa<ShapeType, ShapeShiftType, SliceType, FieldType, LenType,
1054+
ReferenceType, TypeDescType>(eleTy))
10551055
return emitError() << "cannot build a reference to type: " << eleTy << '\n';
10561056
return mlir::success();
10571057
}
@@ -1126,9 +1126,9 @@ mlir::LogicalResult fir::SequenceType::verify(
11261126
llvm::ArrayRef<int64_t> shape, mlir::Type eleTy,
11271127
mlir::AffineMapAttr layoutMap) {
11281128
// DIMENSION attribute can only be applied to an intrinsic or record type
1129-
if (eleTy.isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
1129+
if (mlir::isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
11301130
ShiftType, SliceType, FieldType, LenType, HeapType, PointerType,
1131-
ReferenceType, TypeDescType, SequenceType>())
1131+
ReferenceType, TypeDescType, SequenceType>(eleTy))
11321132
return emitError() << "cannot build an array of this element type: "
11331133
<< eleTy << '\n';
11341134
return mlir::success();
@@ -1199,9 +1199,9 @@ void fir::TypeDescType::print(mlir::AsmPrinter &printer) const {
11991199
mlir::LogicalResult fir::TypeDescType::verify(
12001200
llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
12011201
mlir::Type eleTy) {
1202-
if (eleTy.isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
1202+
if (mlir::isa<BoxType, BoxCharType, BoxProcType, ShapeType, ShapeShiftType,
12031203
ShiftType, SliceType, FieldType, LenType, ReferenceType,
1204-
TypeDescType>())
1204+
TypeDescType>(eleTy))
12051205
return emitError() << "cannot build a type descriptor of type: " << eleTy
12061206
<< '\n';
12071207
return mlir::success();

flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/// This pass populates some debug information for the module and functions.
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "DebugTypeGenerator.h"
1415
#include "flang/Common/Version.h"
1516
#include "flang/Optimizer/Builder/FIRBuilder.h"
1617
#include "flang/Optimizer/Builder/Todo.h"
@@ -106,14 +107,27 @@ void AddDebugInfoPass::runOnOperation() {
106107
filePath = llvm::sys::path::parent_path(funcLoc.getFilename().getValue());
107108
}
108109

109-
mlir::StringAttr funcName =
110+
mlir::StringAttr fullName =
110111
mlir::StringAttr::get(context, funcOp.getName());
111-
mlir::LLVM::DIBasicTypeAttr bT = mlir::LLVM::DIBasicTypeAttr::get(
112-
context, llvm::dwarf::DW_TAG_base_type, "void", /*sizeInBits=*/0,
113-
/*encoding=*/1);
114-
// FIXME: Provide proper type for subroutine
112+
auto result = fir::NameUniquer::deconstruct(funcOp.getName());
113+
mlir::StringAttr funcName =
114+
mlir::StringAttr::get(context, result.second.name);
115+
116+
llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
117+
fir::DebugTypeGenerator typeGen(module);
118+
for (auto resTy : funcOp.getResultTypes()) {
119+
auto tyAttr =
120+
typeGen.convertType(resTy, fileAttr, cuAttr, funcOp.getLoc());
121+
types.push_back(tyAttr);
122+
}
123+
for (auto inTy : funcOp.getArgumentTypes()) {
124+
auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
125+
cuAttr, funcOp.getLoc());
126+
types.push_back(tyAttr);
127+
}
128+
115129
mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
116-
mlir::LLVM::DISubroutineTypeAttr::get(context, CC, {bT, bT});
130+
mlir::LLVM::DISubroutineTypeAttr::get(context, CC, types);
117131
mlir::LLVM::DIFileAttr funcFileAttr =
118132
mlir::LLVM::DIFileAttr::get(context, fileName, filePath);
119133

@@ -130,11 +144,13 @@ void AddDebugInfoPass::runOnOperation() {
130144
subprogramFlags =
131145
subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
132146
}
133-
// FIXME: Provide proper line and scopeline.
147+
unsigned line = 1;
148+
if (auto funcLoc = l.dyn_cast<mlir::FileLineColLoc>())
149+
line = funcLoc.getLine();
150+
134151
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
135-
context, id, compilationUnit, fileAttr, funcName, funcName,
136-
funcFileAttr, /*line=*/1, /*scopeline=*/1, subprogramFlags,
137-
subTypeAttr);
152+
context, id, compilationUnit, fileAttr, funcName, fullName,
153+
funcFileAttr, line, line, subprogramFlags, subTypeAttr);
138154
funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr));
139155
});
140156
}

flang/lib/Optimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_flang_library(FIRTransforms
2222
OMPMarkDeclareTarget.cpp
2323
VScaleAttr.cpp
2424
FunctionAttr.cpp
25+
DebugTypeGenerator.cpp
2526

2627
DEPENDS
2728
FIRDialect
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===-- DebugTypeGenerator.cpp -- type conversion ---------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#define DEBUG_TYPE "flang-debug-type-generator"
14+
15+
#include "DebugTypeGenerator.h"
16+
#include "llvm/ADT/ScopeExit.h"
17+
#include "llvm/BinaryFormat/Dwarf.h"
18+
#include "llvm/Support/Debug.h"
19+
20+
namespace fir {
21+
22+
DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
23+
: module(m), kindMapping(getKindMapping(m)) {
24+
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
25+
}
26+
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+
32+
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
33+
mlir::StringAttr name,
34+
unsigned bitSize,
35+
unsigned decoding) {
36+
return mlir::LLVM::DIBasicTypeAttr::get(
37+
context, llvm::dwarf::DW_TAG_base_type, name, bitSize, decoding);
38+
}
39+
40+
mlir::LLVM::DITypeAttr
41+
DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
42+
mlir::LLVM::DIScopeAttr scope,
43+
mlir::Location loc) {
44+
mlir::MLIRContext *context = module.getContext();
45+
if (Ty.isIntOrIndex()) {
46+
return genBasicType(context, mlir::StringAttr::get(context, "integer"),
47+
Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_signed);
48+
} else if (Ty.isa<mlir::FloatType>() || Ty.isa<fir::RealType>()) {
49+
return genBasicType(context, mlir::StringAttr::get(context, "real"),
50+
Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_float);
51+
} else if (auto logTy = Ty.dyn_cast_or_null<fir::LogicalType>()) {
52+
return genBasicType(context,
53+
mlir::StringAttr::get(context, logTy.getMnemonic()),
54+
kindMapping.getLogicalBitsize(logTy.getFKind()),
55+
llvm::dwarf::DW_ATE_boolean);
56+
} else {
57+
// FIXME: These types are currently unhandled. We are generating a
58+
// placeholder type to allow us to test supported bits.
59+
return genPlaceholderType(context);
60+
}
61+
}
62+
63+
} // namespace fir

0 commit comments

Comments
 (0)