[llvm] r181463 - Add line tracking support to FormattedStream

Malea, Daniel daniel.malea at intel.com
Tue May 21 10:08:13 PDT 2013


Hi Chris,

DebugIR is a pass that replaces source-level debug metadata with metadata
that points to the LLVM IR of the program that's being run so users can
step through IR in LLDB or GDB. Here's a screenshot of stepping through
some exception-catching machinery in GDB: http://i.imgur.com/OG6rUIE.png.
Some folks who generate LLVM IR find this useful; it's been asked for
repeatedly on the lists/IRC...

As for the slowdown this commit introduces, I have not measured it but I'd
be happy to do so; is there a benchmark or use-case you've got in mind?

Although this patch does increase the size of the formatted_raw_ostream
class (by one 'unsigned int' member) as well as the complexity of the
UpdatePosition function (previously, the analogous function contained a
two-branch if condition, whereas now it's a three-branch case statement) I
didn't feel this was a significant enough boost of complexity to warrant
another class.

That said, nothing (except for DebugIR) really needs the line-counting
functionality this commit adds to the stream class. I'd be happy to factor
it out into a line_counting_formatted_raw_ostream class if you'd prefer to
have formatted_raw_ostream count only columns as it did before.

I'm not sure if this is the case, but if formatted_raw_ostream is on a
performance-critical path, maybe it should not count columns either as
AFAIK that's just used for nicer more readable formatting?


Dan


On 2013-05-20 11:05 AM, "Chris Lattner" <clattner at apple.com> wrote:

>On May 8, 2013, at 1:29 PM, Daniel Malea <daniel.malea at intel.com> wrote:
>> URL: http://llvm.org/viewvc/llvm-project?rev=181463&view=rev
>> Log:
>> Add line tracking support to FormattedStream
>> - previously formatted_raw_ostream tracked columns, now it tracks lines
>>too
>> - used by (upcoming) DebugIR pass to know the line number to connect to
>>each IR
>>  instruction
>
>Hi Daniel,
>
>Did you quantify the slowdown that this imposes on existing clients?  It
>is really unfortunate that you have to modify such a core bit of
>functionality to add a new leaf feature like DebugIR.  I guess I missed
>the discussion, but what is the motivation for DebugIR in the first place?
>
>-Chris
>
>> 
>> 
>> Modified:
>>    llvm/trunk/include/llvm/Support/FormattedStream.h
>>    llvm/trunk/lib/Support/FormattedStream.cpp
>> 
>> Modified: llvm/trunk/include/llvm/Support/FormattedStream.h
>> URL: 
>>http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Forma
>>ttedStream.h?rev=181463&r1=181462&r2=181463&view=diff
>> 
>>=========================================================================
>>=====
>> --- llvm/trunk/include/llvm/Support/FormattedStream.h (original)
>> +++ llvm/trunk/include/llvm/Support/FormattedStream.h Wed May  8
>>15:29:10 2013
>> @@ -16,11 +16,13 @@
>> #define LLVM_SUPPORT_FORMATTEDSTREAM_H
>> 
>> #include "llvm/Support/raw_ostream.h"
>> +#include <utility>
>> 
>> namespace llvm {
>> 
>> /// formatted_raw_ostream - A raw_ostream that wraps another one and
>>keeps track
>> -/// of column position, allowing padding out to specific column
>>boundaries.
>> +/// of line and column position, allowing padding out to specific
>>column
>> +/// boundaries and querying the number of lines written to the stream.
>> ///
>> class formatted_raw_ostream : public raw_ostream {
>> public:
>> @@ -44,11 +46,11 @@ private:
>>   ///
>>   bool DeleteStream;
>> 
>> -  /// ColumnScanned - The current output column of the data that's
>> +  /// Position - The current output column and line of the data that's
>>   /// been flushed and the portion of the buffer that's been
>> -  /// scanned.  The column scheme is zero-based.
>> +  /// scanned.  The line and column scheme is zero-based.
>>   ///
>> -  unsigned ColumnScanned;
>> +  std::pair<unsigned, unsigned> Position;
>> 
>>   /// Scanned - This points to one past the last character in the
>>   /// buffer we've scanned.
>> @@ -66,10 +68,10 @@ private:
>>     return TheStream->tell();
>>   }
>> 
>> -  /// ComputeColumn - Examine the given output buffer and figure out
>>which
>> -  /// column we end up in after output.
>> +  /// ComputePosition - Examine the given output buffer and figure out
>>the new
>> +  /// position after output.
>>   ///
>> -  void ComputeColumn(const char *Ptr, size_t size);
>> +  void ComputePosition(const char *Ptr, size_t size);
>> 
>> public:
>>   /// formatted_raw_ostream - Open the specified file for
>> @@ -83,11 +85,11 @@ public:
>>   /// underneath it.
>>   ///
>>   formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
>> -    : raw_ostream(), TheStream(0), DeleteStream(false),
>>ColumnScanned(0) {
>> +    : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0)
>>{
>>     setStream(Stream, Delete);
>>   }
>>   explicit formatted_raw_ostream()
>> -    : raw_ostream(), TheStream(0), DeleteStream(false),
>>ColumnScanned(0) {
>> +    : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0)
>>{
>>     Scanned = 0;
>>   }
>> 
>> @@ -122,6 +124,12 @@ public:
>>   /// \param NewCol - The column to move to.
>>   formatted_raw_ostream &PadToColumn(unsigned NewCol);
>> 
>> +  /// getColumn - Return the column number
>> +  unsigned getColumn() { return Position.first; }
>> +
>> +  /// getLine - Return the line number
>> +  unsigned getLine() { return Position.second; }
>> +
>> private:
>>   void releaseStream() {
>>     // Delete the stream if needed. Otherwise, transfer the buffer
>> 
>> Modified: llvm/trunk/lib/Support/FormattedStream.cpp
>> URL: 
>>http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FormattedStrea
>>m.cpp?rev=181463&r1=181462&r2=181463&view=diff
>> 
>>=========================================================================
>>=====
>> --- llvm/trunk/lib/Support/FormattedStream.cpp (original)
>> +++ llvm/trunk/lib/Support/FormattedStream.cpp Wed May  8 15:29:10 2013
>> @@ -17,38 +17,43 @@
>> 
>> using namespace llvm;
>> 
>> -/// CountColumns - Examine the given char sequence and figure out which
>> -/// column we end up in after output.
>> +/// UpdatePosition - Examine the given char sequence and figure out
>>which
>> +/// column we end up in after output, and how many line breaks are
>>contained.
>> ///
>> -static unsigned CountColumns(unsigned Column, const char *Ptr, size_t
>>Size) {
>> -  // Keep track of the current column by scanning the string for
>> -  // special characters
>> +static void UpdatePosition(std::pair<unsigned, unsigned> &Position,
>>const char *Ptr, size_t Size) {
>> +  unsigned &Column = Position.first;
>> +  unsigned &Line = Position.second;
>> 
>> +  // Keep track of the current column and line by scanning the string
>>for
>> +  // special characters
>>   for (const char *End = Ptr + Size; Ptr != End; ++Ptr) {
>>     ++Column;
>> -    if (*Ptr == '\n' || *Ptr == '\r')
>> +    switch (*Ptr) {
>> +    case '\n':
>> +      Line += 1;
>> +    case '\r':
>>       Column = 0;
>> -    else if (*Ptr == '\t')
>> +      break;
>> +    case '\t':
>>       // Assumes tab stop = 8 characters.
>>       Column += (8 - (Column & 0x7)) & 0x7;
>> +      break;
>> +    }
>>   }
>> -
>> -  return Column;
>> }
>> 
>> -/// ComputeColumn - Examine the current output and figure out which
>> -/// column we end up in after output.
>> -void formatted_raw_ostream::ComputeColumn(const char *Ptr, size_t
>>Size) {
>> +/// ComputePosition - Examine the current output and update line and
>>column
>> +/// counts.
>> +void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t
>>Size) {
>>   // If our previous scan pointer is inside the buffer, assume we
>>already
>>   // scanned those bytes. This depends on raw_ostream to not change our
>>buffer
>>   // in unexpected ways.
>> -  if (Ptr <= Scanned && Scanned <= Ptr + Size) {
>> +  if (Ptr <= Scanned && Scanned <= Ptr + Size)
>>     // Scan all characters added since our last scan to determine the
>>new
>>     // column.
>> -    ColumnScanned = CountColumns(ColumnScanned, Scanned,
>> -                                 Size - (Scanned - Ptr));
>> -  } else
>> -    ColumnScanned = CountColumns(ColumnScanned, Ptr, Size);
>> +    UpdatePosition(Position, Scanned, Size - (Scanned - Ptr));
>> +  else
>> +    UpdatePosition(Position, Ptr, Size);
>> 
>>   // Update the scanning pointer.
>>   Scanned = Ptr + Size;
>> @@ -60,16 +65,16 @@ void formatted_raw_ostream::ComputeColum
>> ///
>> formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned
>>NewCol) { 
>>   // Figure out what's in the buffer and add it to the column count.
>> -  ComputeColumn(getBufferStart(), GetNumBytesInBuffer());
>> +  ComputePosition(getBufferStart(), GetNumBytesInBuffer());
>> 
>>   // Output spaces until we reach the desired column.
>> -  indent(std::max(int(NewCol - ColumnScanned), 1));
>> +  indent(std::max(int(NewCol - getColumn()), 1));
>>   return *this;
>> }
>> 
>> void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
>>   // Figure out what's in the buffer and add it to the column count.
>> -  ComputeColumn(Ptr, Size);
>> +  ComputePosition(Ptr, Size);
>> 
>>   // Write the data to the underlying stream (which is unbuffered, so
>>   // the data will be immediately written out).
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>





More information about the llvm-commits mailing list