This is an archive of the discontinued LLVM Phabricator instance.

Add support for optimization reports.
ClosedPublic

Authored by dnovillo on Mar 31 2014, 9:26 AM.

Details

Reviewers
qcolombet
rsmith
Summary

This patch adds a new flag -Rpass=. The flag indicates the name
of the optimization pass that should emit remarks stating when it
made a transformation to the code.

This implements the design I proposed in:

https://docs.google.com/document/d/1FYUatSjZZO-zmFBxjOiuOzAy9mhHA8hqdvklZv68WuQ/edit?usp=sharing

Diff Detail

Event Timeline

Couple of comments here:

a) The WRPass thing is awkward. No, I don't know how to fix it offhand.

The rest are inline.

-eric

lib/CodeGen/CodeGenAction.cpp
390

I'm not sure we can get back to the same encoding, but it could be useful if we wanted to map accordingly.

Also did you want the discriminator here?

lib/Driver/Tools.cpp
3418

Extra braces?

lib/Frontend/CompilerInvocation.cpp
536

I think this will just set line tables only as opposed to the greater of line-tables-only and whatever we've currently got.

dnovillo updated this revision to Unknown Object (????).Mar 31 2014, 2:53 PM
  • Tolerate lack of debug information.

When emitting an optimization report diagnostic, the lack of debug
information sometimes causes internal failures. If debug information
is not present, the diagnostic uses "<unknown>:0:0" as the location
string.

rsmith added inline comments.Mar 31 2014, 3:06 PM
include/clang/Basic/DiagnosticGroups.td
668

Do you intend for this to be controlled by -WRpass? I don't think you should add a DiagGroup for this one at all.

include/clang/Driver/Options.td
257–260

Should we have a -Rno-pass=... too?

lib/CodeGen/CodeGenAction.cpp
387–389

Maybe add a DefaultRemark to Diagnostic.td, and then add DefaultRemark to the def for your Remark to enable it by default, and drop this?

393–396

Yuck. :( It's not correct to rely on diagnostics being formatted this way: we support several output formats that don't use the 'file:line:col: ' formatting.

Could we annotate the raw form of Clang's SourceLocation onto the IR so that we can use it here? Failing that, you can map the filename/line/column back to a SourceLocation by asking the clang::SourceManager nicely (see SourceManager::translateFileLineCol and FileManager::getFile).

397–399

I think this'll report the wrong warning flag, something like:

remark: something happened [-WRpass]

Ideally we should report

remark: something happened [-Rpass=passname]

You'll probably need to add an optional warning flag name override to DiagnosticsEngine to support this (and use it as an override in printDiagnosticOptions in TextDiagnosticPrinter.cpp).

Hi Diego,

I prefer not to comment on the front-end part, I do not know it well enough. I think Richard and Eric's comments do the trick :).

For the diagnostic handler, the way we handle it seems a bit odd. See my inline comment.

Thanks,
-Quentin

lib/CodeGen/CodeGenAction.cpp
441

This does not follow the same pattern as the previous handler, i.e., with the fall through setting the DiagID to use the default handler (the ComputeDiagID part etc.).

My guess is we want to push the check of CodeGenOpts.OptimizationReportPattern into OptimizationReportHandler and check the return of that.

If we do not want to follow the same pattern, we should comment on that. Indeed, I think it is important to explain why we are not reporting anything when CodeGenOpts.OptimizationReportPattern is not set.

dnovillo updated this revision to Unknown Object (????).Apr 2 2014, 7:03 PM

Address review feedback

  • When emitting an optimization report diagnostic, the lack of debug information sometimes causes internal failures. If debug information is not present, the diagnostic uses "<unknown>:0:0" as the location string.
  • Rename OptimizationReport to OptimizationRemark.
  • Only enable line table generation if no debug information had been requested.
  • Add a default remark diagnostic class to enable -Rpass diagnostics.
  • Change the diagnostic group for BackendOptimizationRemark to "pass".
  • Add DiagnosticIDs::isRemark(). Use it in printDiagnosticOptions to print "-R" instead of "-W" in the diagnostic message.
  • Re-word the help text for -Rpass=.
  • In BackendConsumer::OptimizationRemarkHandler, get a SourceLocation object out of the file name, line and column number. Use that location in the call to Diags.Report().
  • If -Rpass= is used, also enable column information by adding -dwarf-column-info to the backend command line.
  • Add test for -Rpass=. Document OptimizationRemarkHandler.
dnovillo updated this revision to Unknown Object (????).Apr 2 2014, 7:12 PM
  • Rename optimization report as optimization remark.

Looks mostly fine. I'm concerned about a -R option affecting the debug info that ends up in the object file. I'm also concerned that the diagnostic quality will degrade if you build with no debug info enabled at all.

It seems to me that if we can afford the IR size increase from -dwarf-column-info, we can afford the IR size increase from storing the frontend's notion of 'source location' into the IR, and that would allow us to do the right thing without -g and to deal properly with macro expansions etc. (It's only 32 bits per location...)

lib/Driver/Tools.cpp
3422

I don't think it's OK for a diagnostic option to affect the contents of the object file.

lib/Frontend/CompilerInvocation.cpp
523

... so we take the last -Rpass= option, rather than combining them? I find that unintuitive, FWIW, but maybe this is the right model.

Hi Diego,

For the part I can comment on (OptimizationRemarkHandler), this LGTM.
For the rest, I leave to Richard the final OK.

Thanks,
Quentin

dnovillo updated this revision to Unknown Object (????).Apr 11 2014, 3:48 PM

In this update:

  • Do not force line/column info generation. Rather, warn when -Rpass is used without debug info.
  • Fix BackendConsumer::OptimizationRemarkHandler to operate the same way as the other diagnostic handlers. If no debug information is available, use an empty SourceLocation object.
  • Fix the -Rpass test to make it independent of the optimization level used.
rsmith added inline comments.Apr 13 2014, 3:56 PM
include/clang/Basic/DiagnosticDriverKinds.td
119–121

I think this would make more sense as a note on the diagnostic we produce, if we ever actually produce one.

include/clang/Basic/DiagnosticFrontendKinds.td
35–42

I assume that these shouldn't all be Remarks?

Notes should not have an InGroup.

Please put a space to the left of the : (this file is inconsistent on this, but spaces on both sides is the established convention elsewhere).

Are you actually using any of these except for the remark_... form?

include/clang/Driver/Options.td
259

No full stop here, please. (I think we're inconsistent on this too.)

lib/Frontend/CompilerInvocation.cpp
526

It looks like this is leaked. Maybe use an llvm::Optional<llvm::Regex> instead?

dnovillo added inline comments.Apr 14 2014, 8:04 AM
include/clang/Basic/DiagnosticDriverKinds.td
119–121

Oh, yeah, much better. Done. One question, however, this will cause the note to be emitted on every remark we print. Should I try to reduce the noise by making sure it's only emitted once?

include/clang/Basic/DiagnosticFrontendKinds.td
35–42

I fixed them to be the right type. They are not really used, except by the boilerplate macro ComputeDiagRemarkID() in lib/CodeGen/CodeGenAction.cpp. I replicated the behaviour of all the other handlers. I am not really sure what they are supposed to do.

include/clang/Driver/Options.td
259

Done.

lib/Frontend/CompilerInvocation.cpp
526

I tried but llvm::Regex has an explicitly deleted constructor. I'm not sure how to deal with that, so I ended up using regular pointer semantics.

dnovillo updated this revision to Unknown Object (????).Apr 14 2014, 8:04 AM

Address review feedback.

rsmith added inline comments.Apr 14 2014, 5:14 PM
include/clang/Basic/DiagnosticFrontendKinds.td
40–42

Maybe better phrased as:

"use -gline-tables-only -gcolumn-info to track source location information for this optimization remark"
lib/CodeGen/CodeGenAction.cpp
441

It looks like we get here (and potentially use the error/warning forms of the remark diagnostic) if the diagnostic severity isn't DS_Remark. I don't think this is what we want -- maybe the severity check in OptimizationRemarkHandler should be an assert?

lib/Frontend/CompilerInvocation.cpp
526

llvm::Optional shouldn't call the llvm::Regex default constructor.

dnovillo added inline comments.Apr 15 2014, 12:10 PM
include/clang/Basic/DiagnosticFrontendKinds.td
40–42

Done.

lib/CodeGen/CodeGenAction.cpp
441

OK. This takes me back to my previous version, where I would not try to handle anything other than remarks. This means that the other codes I was forced to add can disappear.

lib/Frontend/CompilerInvocation.cpp
526

Sure, but it's trying to when instantiating CodeGenOptions:

llvm/include/llvm/ADT/Optional.h:39:28: error: call to deleted constructor of 'llvm::Regex'

new (storage.buffer) T(*O);
                     ^ ~~

llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h:39:7: note: in instantiation of member function 'llvm::Optional<llvm::Regex>::Optional' requested here
class CodeGenOptions : public CodeGenOptionsBase {

^

llvm/include/llvm/Support/Regex.h:49:5: note: 'Regex' has been explicitly marked deleted here

Regex(const Regex &) LLVM_DELETED_FUNCTION;
^

1 error generated.

I'm not quite sure how to deal with this. All I'm doing is:

  • llvm::Regex *OptimizationRemarkPattern;

+ llvm::Optional<llvm::Regex> OptimizationRemarkPattern;

I feel like I'm missing something.

dnovillo updated this revision to Unknown Object (????).Apr 15 2014, 12:11 PM

Address review feedback.

rsmith accepted this revision.Apr 15 2014, 2:45 PM

LGTM with a fix for the memory leak.

lib/Frontend/CompilerInvocation.cpp
526

Oh, I see. What this crummy diagnostic is trying to tell you is that Regex isn't copyable, but someone is trying to make a copy of the CodeGenOptions object somewhere (we don't actually say where, due to an interaction of recursive special member generation and delayed function template instantiation...). CodeGeneratorImpl::CodeGenOpts does this, there might be other places.

Next idea: use std::shared_ptr<llvm::Regex>.

dnovillo updated this revision to Unknown Object (????).Apr 16 2014, 5:07 AM
  • Change OptimizationRemarkPattern into a shared_ptr to avoid memory leaks.
dnovillo closed this revision.Apr 16 2014, 1:54 PM