Skip to content

Commit 12da8ef

Browse files
committed
[Flang][Driver] Add location and remark option printing to R_Group Diagnostics
For each R_Group diagnostic produced, this patch gives more information about it by printing the absolute file path, the line and column number the pass was applied to and finally the remark option that was used. Clang does the same with the exception of printing the relative path rather than absolute path. Depends on D159260. That patch adds support for backend passes while this patch adds remark options to the backend test cases. Reviewed By: awarzynski Differential Revision: https://reviews.llvm.org/D159258
1 parent 380c5da commit 12da8ef

File tree

7 files changed

+117
-22
lines changed

7 files changed

+117
-22
lines changed

flang/include/flang/Frontend/TextDiagnosticPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class TextDiagnosticPrinter : public clang::DiagnosticConsumer {
5252

5353
void HandleDiagnostic(clang::DiagnosticsEngine::Level level,
5454
const clang::Diagnostic &info) override;
55+
56+
void printLocForRemarks(llvm::raw_svector_ostream &diagMessageStream,
57+
llvm::StringRef &diagMsg);
5558
};
5659

5760
} // namespace Fortran::frontend

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,21 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
267267
diags, args, clang::driver::options::OPT_Rpass_analysis_EQ,
268268
/*remarkOptName=*/"pass-analysis");
269269

270+
if (opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo) {
271+
// If the user requested a flag that requires source locations available in
272+
// the backend, make sure that the backend tracks source location
273+
// information.
274+
bool needLocTracking = !opts.OptRecordFile.empty() ||
275+
!opts.OptRecordPasses.empty() ||
276+
!opts.OptRecordFormat.empty() ||
277+
opts.OptimizationRemark.hasValidPattern() ||
278+
opts.OptimizationRemarkMissed.hasValidPattern() ||
279+
opts.OptimizationRemarkAnalysis.hasValidPattern();
280+
281+
if (needLocTracking)
282+
opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
283+
}
284+
270285
if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ))
271286
opts.SaveTempsDir = a->getValue();
272287

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,19 @@ class BackendRemarkConsumer : public llvm::DiagnosticHandler {
957957

958958
std::string msg;
959959
llvm::raw_string_ostream msgStream(msg);
960+
961+
if (diagInfo.isLocationAvailable()) {
962+
// Clang contains a SourceManager class which handles loading
963+
// and caching of source files into memory and it can be used to
964+
// query SourceLocation data. The SourceLocation data is what is
965+
// needed here as it contains the full include stack which gives
966+
// line and column number as well as file name and location.
967+
// Since Flang doesn't have SourceManager, send file name and absolute
968+
// path through msgStream, to use for printing.
969+
msgStream << diagInfo.getLocationStr() << ";;"
970+
<< diagInfo.getAbsolutePath() << ";;";
971+
}
972+
960973
msgStream << diagInfo.getMsg();
961974

962975
// Emit message.

flang/lib/Frontend/TextDiagnosticPrinter.cpp

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
#include "flang/Frontend/TextDiagnostic.h"
1919
#include "clang/Basic/DiagnosticOptions.h"
2020
#include "llvm/ADT/SmallString.h"
21+
#include "llvm/ADT/SmallVector.h"
22+
#include "llvm/ADT/StringRef.h"
2123
#include "llvm/Support/ErrorHandling.h"
24+
#include "llvm/Support/Path.h"
2225
#include "llvm/Support/raw_ostream.h"
2326

2427
using namespace Fortran::frontend;
@@ -29,6 +32,62 @@ TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &diagOs,
2932

3033
TextDiagnosticPrinter::~TextDiagnosticPrinter() {}
3134

35+
// For remarks only, print the remark option and pass name that was used to a
36+
// raw_ostream. This also supports warnings from invalid remark arguments
37+
// provided.
38+
static void printRemarkOption(llvm::raw_ostream &os,
39+
clang::DiagnosticsEngine::Level level,
40+
const clang::Diagnostic &info) {
41+
llvm::StringRef opt =
42+
clang::DiagnosticIDs::getWarningOptionForDiag(info.getID());
43+
if (!opt.empty()) {
44+
// We still need to check if the level is a Remark since, an unknown option
45+
// warning could be printed i.e. [-Wunknown-warning-option]
46+
os << " [" << (level == clang::DiagnosticsEngine::Remark ? "-R" : "-W")
47+
<< opt;
48+
llvm::StringRef optValue = info.getDiags()->getFlagValue();
49+
if (!optValue.empty())
50+
os << "=" << optValue;
51+
os << ']';
52+
}
53+
}
54+
55+
// For remarks only, if we are receiving a message of this format
56+
// [file location with line and column];;[path to file];;[the remark message]
57+
// then print the absolute file path, line and column number.
58+
void TextDiagnosticPrinter::printLocForRemarks(
59+
llvm::raw_svector_ostream &diagMessageStream, llvm::StringRef &diagMsg) {
60+
// split incoming string to get the absolute path and filename in the
61+
// case we are receiving optimization remarks from BackendRemarkConsumer
62+
diagMsg = diagMessageStream.str();
63+
llvm::StringRef delimiter = ";;";
64+
65+
size_t pos = 0;
66+
llvm::SmallVector<llvm::StringRef> tokens;
67+
while ((pos = diagMsg.find(delimiter)) != std::string::npos) {
68+
tokens.push_back(diagMsg.substr(0, pos));
69+
diagMsg = diagMsg.drop_front(pos + delimiter.size());
70+
}
71+
72+
// tokens will always be of size 2 in the case of optimization
73+
// remark message received
74+
if (tokens.size() == 2) {
75+
// Extract absolute path
76+
llvm::SmallString<128> absPath = llvm::sys::path::relative_path(tokens[1]);
77+
llvm::sys::path::remove_filename(absPath);
78+
// Add the last separator before the file name
79+
llvm::sys::path::append(absPath, llvm::sys::path::get_separator());
80+
llvm::sys::path::make_preferred(absPath);
81+
82+
// Used for changing only the bold attribute
83+
if (diagOpts->ShowColors)
84+
os.changeColor(llvm::raw_ostream::SAVEDCOLOR, true);
85+
86+
// Print path, file name, line and column
87+
os << absPath << tokens[0] << ": ";
88+
}
89+
}
90+
3291
void TextDiagnosticPrinter::HandleDiagnostic(
3392
clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
3493
// Default implementation (Warnings/errors count).
@@ -40,6 +99,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(
4099
info.FormatDiagnostic(outStr);
41100

42101
llvm::raw_svector_ostream diagMessageStream(outStr);
102+
printRemarkOption(diagMessageStream, level, info);
43103

44104
if (!prefix.empty())
45105
os << prefix << ": ";
@@ -48,12 +108,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(
48108
assert(!info.getLocation().isValid() &&
49109
"Diagnostics with valid source location are not supported");
50110

111+
llvm::StringRef diagMsg;
112+
printLocForRemarks(diagMessageStream, diagMsg);
113+
51114
Fortran::frontend::TextDiagnostic::printDiagnosticLevel(os, level,
52115
diagOpts->ShowColors);
53116
Fortran::frontend::TextDiagnostic::printDiagnosticMessage(
54117
os,
55-
/*IsSupplemental=*/level == clang::DiagnosticsEngine::Note,
56-
diagMessageStream.str(), diagOpts->ShowColors);
118+
/*IsSupplemental=*/level == clang::DiagnosticsEngine::Note, diagMsg,
119+
diagOpts->ShowColors);
57120

58121
os.flush();
59122
}

flang/test/Driver/optimization-remark-backend.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
! Check full -Rpass-analysis message is emitted
1010
! RUN: %flang %s -O1 -Rpass-analysis %{output} 2>&1 | FileCheck %s --check-prefix=ANALYSIS
1111

12-
! MISSED: remark: {{[0-9]+}} virtual registers copies {{.*}} total copies cost generated in function
12+
! MISSED: remark: {{[0-9]+}} virtual registers copies {{.*}} total copies cost generated in function [-Rpass-missed=regalloc]
1313
! ANALYSIS: remark: BasicBlock:
14+
! ANALYSIS: [-Rpass-analysis=asm-printer]
1415

1516
program forttest
1617
implicit none

flang/test/Driver/optimization-remark-invalid.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
! RUN: %flang %s -O1 -Rpas -c 2>&1 | FileCheck %s --check-prefix=WARN-SUGGEST
1313

1414
! REGEX-INVALID: error: in pattern '-Rpass=[': brackets ([ ]) not balanced
15-
! WARN: warning: unknown remark option '-R'
16-
! WARN-SUGGEST: warning: unknown remark option '-Rpas'; did you mean '-Rpass'?
15+
! WARN: warning: unknown remark option '-R' [-Wunknown-warning-option]
16+
! WARN-SUGGEST: warning: unknown remark option '-Rpas'; did you mean '-Rpass'? [-Wunknown-warning-option]
1717

1818
program forttest
1919
end program forttest

flang/test/Driver/optimization-remark.f90

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,29 @@
4040
! With plain -Rpass, -Rpass-missed or -Rpass-analysis, we expect remarks related to 2 opportunities (loop vectorisation / loop delete and load hoisting).
4141
! Once we start filtering, this is reduced to 1 one of the loop passes.
4242

43-
! PASS-REGEX-LOOP-ONLY-NOT: remark: hoisting load
44-
! PASS-REGEX-LOOP-ONLY: remark: Loop deleted because it is invariant
43+
! PASS-REGEX-LOOP-ONLY-NOT: optimization-remark.f90:77:7: remark: hoisting load [-Rpass=licm]
44+
! PASS-REGEX-LOOP-ONLY: optimization-remark.f90:83:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]
4545

46-
! MISSED-REGEX-LOOP-ONLY-NOT: remark: failed to hoist load with loop-invariant address because load is conditionally executed
47-
! MISSED-REGEX-LOOP-ONLY: remark: loop not vectorized
46+
! MISSED-REGEX-LOOP-ONLY-NOT: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
47+
! MISSED-REGEX-LOOP-ONLY: optimization-remark.f90:76:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
4848

4949

50-
! ANALYSIS-REGEX-LOOP-ONLY: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
51-
! ANALYSIS-REGEX-LOOP-ONLY: Unknown data dependence.
52-
! ANALYSIS-REGEX-LOOP-ONLY-NOT: remark:{{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}}
50+
! ANALYSIS-REGEX-LOOP-ONLY: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
51+
! ANALYSIS-REGEX-LOOP-ONLY: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]
52+
! ANALYSIS-REGEX-LOOP-ONLY-NOT: remark: {{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}} [-Rpass-analysis=size-info]
5353

54-
! PASS: remark: hoisting load
55-
! PASS: remark: Loop deleted because it is invariant
54+
! PASS: optimization-remark.f90:77:7: remark: hoisting load [-Rpass=licm]
55+
! PASS: optimization-remark.f90:83:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]
5656

57-
! MISSED: remark: failed to hoist load with loop-invariant address because load is conditionally executed
58-
! MISSED: remark: loop not vectorized
59-
! MISSED-NOT: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
60-
! MISSED-NOT: Unknown data dependence.
57+
! MISSED: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
58+
! MISSED: optimization-remark.f90:76:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
59+
! MISSED-NOT: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
60+
! MISSED-NOT: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]
6161

62-
! ANALYSIS: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
63-
! ANALYSIS: Unknown data dependence.
64-
! ANALYSIS: remark: {{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}}
65-
! ANALYSIS-NOT: remark: failed to hoist load with loop-invariant address because load is conditionally executed
62+
! ANALYSIS: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
63+
! ANALYSIS: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]
64+
! ANALYSIS: remark: {{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}} [-Rpass-analysis=size-info]
65+
! ANALYSIS-NOT: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
6666

6767
subroutine swap_real(a1, a2)
6868
implicit none

0 commit comments

Comments
 (0)