[LLVMdev] [llvm-commits] [PATCH] Allow per-thread re-direction of outs()/errs()

Chris Lattner clattner at apple.com
Sun Jun 3 12:11:22 PDT 2012


On Jun 2, 2012, at 10:12 AM, Justin Holewinski wrote:
>> If so, how do you feel about introducing a new global stream, logs()?  This could replace all uses of outs()/errs() in the LLVM libraries, and default to errs().  Existing command-line tools could just use this default, but compilers that are hosted inside of libraries or other non-command line scenarios can attach a custom stream to logs() that captures all LLVM output, including DEBUG and any legitimate pass output.  Command-line tools can continue to use outs()/errs() just as they do now.  Nothing would really change in the way LLVM operates by default
> 
> In fact, before we had raw_ostream, we had a dbgs() sort of stream, which was intended to be used in debug statements.  I'm not strongly opposed to this (it would be much better than violating the sanctity of outs() :), but I'm still unclear why you care so much about DEBUG output.  If we had a dbgs() again, it should *only* be used from within DEBUG macros (for example, the linker shouldn't use it).  Would that be enough to achieve your goal?
> 
> It's not so much DEBUG output that I care specifically about, that's just an example of a place where the LLVM libraries assume an stderr stream exists and is freely writable.

Ok, then lets ignore DEBUG.  It is completely irrelevant to any software that ships with disabled assertions.  The reason that this came up was because of your assertion that LLVM writes to outs() and errs() all over the place.  This simply isn't true if you ignore DEBUG.

> It sounds like dbgs() is not really the solution here, since I want to capture more than just DEBUG output.  

Right.

> What I really want is a way to capture *all* LLVM library output that would normally go to stderr, similar to how Clang has its Diagnostic functionality that allows a driver to collect all output messages.

Fine, this should be done by fixing the few places (like the linker) that are misbehaving.

> There are legitimate cases where passes may output warnings or even errors that the compiler should be able to direct to the user.  errs() is fine for this if you know you're working with a command-line tool, but that's not always true.
> 
>  If the module linker wants to output a warning, I want to capture that.  If an optimization pass wants to emit a performance warning, I want to capture that too.  Neither of these cases are DEBUG-only.

Neither of these use cases are a good use for raw_ostream.  We have a diagnostics API that the backend uses.  A random optimization pass should *not* use errs() ever, it should use the diagnostics API (see llvm/Support/ErrorHandling.h).

> I see two possible solutions:
> For every pass (or class) that may emit warnings/errors, provide it a raw_ostream instance.  This seems to be how some of the utility classes work now, but this puts a burden on the compiler to know which passes actually need a raw_ostream parameter.  If you want to add a warning output to any pass, you need to change its interface (create***Pass and constructor) to add the raw_ostream parameter.
> Provide a generic mechanism through which passes and any other utility classes can write warning/error information.  This gives more control to the compiler without introducing any interface changes.
We already have #2.  It supports (for example) source location information, and is already used by clang and the backend in some places.

> Option (1) is do-able, but option (2) seems more general.  The specifics of the implementation that I envision are:
> logs() is added as another stream to raw_ostream.h
> By default, logs() forwards to errs()  [no change in the way LLVM works in the default case]
> Any pass or utility class that wants to emit warnings/errors should write to logs() instead of errs()
> DEBUG code should use logs() instead of errs()  [again, this will default to errs()]
> An API is provided that allows a client to re-direct logs() to any arbitrary raw_ostream, on a per-thread level

Please stop focusing on *streams*.  If you actually want to capture useful diagnostic output, starting with text is already a lost cause. 

-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120603/1362b78e/attachment.html>


More information about the llvm-dev mailing list