Skip to content

Commit 01e7564

Browse files
jpienaarRiver707
andauthored
[mlir] Add FileRange location type. (#80213)
This location type represents a contiguous range inside a file. It is effectively a pair of FileLineCols. Add new type and make FileLineCol a view for case where it matches existing previous one. The location includes filename and optional start line & col, and end line & col. Considered common cases are file:line, file:line:col, file:line:start_col to file:line:end_col and general range within same file. In memory its encoded as trailing objects. This keeps the memory requirement the same as FileLineColLoc today (makes the rather common File:Line cheaper) at the expense of extra work at decoding time. Kept the unsigned type. There was the option to always have file range be castable to FileLineColLoc. This cast would just drop other fields. That may result in some simpler staging. TBD. This is a rather minimal change, it does not yet add bindings (C or Python), lowering to LLVM debug locations etc. that supports end line:cols. --------- Co-authored-by: River Riddle <[email protected]>
1 parent 56feea7 commit 01e7564

File tree

10 files changed

+434
-50
lines changed

10 files changed

+434
-50
lines changed

mlir/include/mlir/IR/Builders.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class AffineExpr;
1919
class IRMapping;
2020
class UnknownLoc;
2121
class FileLineColLoc;
22+
class FileLineColRange;
2223
class Type;
2324
class PrimitiveType;
2425
class IntegerType;

mlir/include/mlir/IR/BuiltinDialectBytecode.td

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,26 @@ def CallSiteLoc : DialectAttribute<(attr
9595
LocationAttr:$caller
9696
)>;
9797

98+
let cType = "FileLineColRange" in {
99+
def FileLineColRange : DialectAttribute<(attr
100+
StringAttr:$filename,
101+
WithBuilder<"$_args",
102+
WithType<"SmallVector<uint64_t>",
103+
WithParser<"succeeded(readFileLineColRangeLocs($_reader, $_var))",
104+
WithPrinter<"writeFileLineColRangeLocs($_writer, $_name)">>>>:$rawLocData
105+
)> {
106+
let cBuilder = "getFileLineColRange(context, filename, rawLocData)";
107+
let printerPredicate = "!::llvm::isa<FileLineColLoc>($_val)";
108+
}
109+
98110
def FileLineColLoc : DialectAttribute<(attr
99111
StringAttr:$filename,
100-
VarInt:$line,
101-
VarInt:$column
102-
)>;
112+
VarInt:$start_line,
113+
VarInt:$start_column
114+
)> {
115+
let printerPredicate = "::llvm::isa<FileLineColLoc>($_val)";
116+
}
117+
}
103118

104119
let cType = "FusedLoc",
105120
cBuilder = "cast<FusedLoc>(get<FusedLoc>(context, $_args))" in {
@@ -321,7 +336,8 @@ def BuiltinDialectAttributes : DialectAttributes<"Builtin"> {
321336
DenseIntOrFPElementsAttr,
322337
DenseStringElementsAttr,
323338
SparseElementsAttr,
324-
DistinctAttr
339+
DistinctAttr,
340+
FileLineColRange,
325341
];
326342
}
327343

mlir/include/mlir/IR/BuiltinLocationAttributes.td

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,46 +60,98 @@ def CallSiteLoc : Builtin_LocationAttr<"CallSiteLoc"> {
6060
}
6161

6262
//===----------------------------------------------------------------------===//
63-
// FileLineColLoc
63+
// FileLineColRange
6464
//===----------------------------------------------------------------------===//
6565

66-
def FileLineColLoc : Builtin_LocationAttr<"FileLineColLoc"> {
67-
let summary = "A file:line:column source location";
66+
def FileLineColRange : Builtin_LocationAttr<"FileLineColRange"> {
67+
let summary = "A file:line:column source location range";
6868
let description = [{
6969
Syntax:
7070

7171
```
7272
filelinecol-location ::= string-literal `:` integer-literal `:`
7373
integer-literal
74+
(`to` (integer-literal ?) `:` integer-literal ?)
7475
```
7576

76-
An instance of this location represents a tuple of file, line number, and
77-
column number. This is similar to the type of location that you get from
78-
most source languages.
77+
An instance of this location represents a tuple of file, start and end line
78+
number, and start and end column number. It allows for the following
79+
configurations:
80+
81+
* A single file line location: `file:line`;
82+
* A single file line col location: `file:line:column`;
83+
* A single line range: `file:line:column to :column`;
84+
* A single file range: `file:line:column to line:column`;
7985

8086
Example:
8187

8288
```mlir
83-
loc("mysource.cc":10:8)
89+
loc("mysource.cc":10:8 to 12:18)
8490
```
8591
}];
86-
let parameters = (ins "StringAttr":$filename, "unsigned":$line,
87-
"unsigned":$column);
92+
93+
let parameters = (ins "StringAttr":$filename,
94+
"unsigned":$start_line, "unsigned":$start_column,
95+
"unsigned":$end_line, "unsigned":$end_column);
8896
let builders = [
97+
AttrBuilderWithInferredContext<(ins "StringAttr":$filename), [{
98+
return $_get(filename.getContext(), filename, ArrayRef<unsigned>{});
99+
}]>,
100+
AttrBuilderWithInferredContext<(ins "StringAttr":$filename,
101+
"unsigned":$line), [{
102+
return $_get(filename.getContext(), filename,
103+
ArrayRef<unsigned>{line});
104+
}]>,
89105
AttrBuilderWithInferredContext<(ins "StringAttr":$filename,
90106
"unsigned":$line,
91107
"unsigned":$column), [{
92-
return $_get(filename.getContext(), filename, line, column);
108+
return $_get(filename.getContext(), filename,
109+
ArrayRef<unsigned>{line, column});
93110
}]>,
94-
AttrBuilder<(ins "StringRef":$filename, "unsigned":$line,
95-
"unsigned":$column), [{
111+
AttrBuilder<(ins "::llvm::StringRef":$filename,
112+
"unsigned":$start_line,
113+
"unsigned":$start_column), [{
96114
return $_get($_ctxt,
97-
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
98-
line, column);
99-
}]>
115+
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
116+
ArrayRef<unsigned>{start_line, start_column});
117+
}]>,
118+
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename,
119+
"unsigned":$line,
120+
"unsigned":$start_column,
121+
"unsigned":$end_column), [{
122+
return $_get(filename.getContext(), filename,
123+
ArrayRef<unsigned>{line, start_column, end_column});
124+
}]>,
125+
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename,
126+
"unsigned":$start_line,
127+
"unsigned":$start_column,
128+
"unsigned":$end_line,
129+
"unsigned":$end_column), [{
130+
return $_get(filename.getContext(), filename,
131+
ArrayRef<unsigned>{start_line, start_column, end_column, end_line});
132+
}]>,
133+
AttrBuilder<(ins "::llvm::StringRef":$filename,
134+
"unsigned":$start_line,
135+
"unsigned":$start_column,
136+
"unsigned":$end_line,
137+
"unsigned":$end_column), [{
138+
return $_get($_ctxt,
139+
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
140+
ArrayRef<unsigned>{start_line, start_column, end_column, end_line});
141+
}]>,
100142
];
143+
144+
let extraClassDeclaration = [{
145+
::mlir::StringAttr getFilename() const;
146+
unsigned getStartLine() const;
147+
unsigned getStartColumn() const;
148+
unsigned getEndColumn() const;
149+
unsigned getEndLine() const;
150+
}];
101151
let skipDefaultBuilders = 1;
102-
let attrName = "builtin.file_line_loc";
152+
let genAccessors = 0;
153+
let genStorageClass = 0;
154+
let attrName = "builtin.file_line_range";
103155
}
104156

105157
//===----------------------------------------------------------------------===//

mlir/include/mlir/IR/Location.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ inline ::llvm::hash_code hash_value(Location arg) {
136136
// Tablegen Attribute Declarations
137137
//===----------------------------------------------------------------------===//
138138

139+
// Forward declaration for class created later.
140+
namespace mlir::detail {
141+
struct FileLineColRangeAttrStorage;
142+
} // namespace mlir::detail
143+
139144
#define GET_ATTRDEF_CLASSES
140145
#include "mlir/IR/BuiltinLocationAttributes.h.inc"
141146

@@ -164,6 +169,32 @@ class FusedLocWith : public FusedLoc {
164169
}
165170
};
166171

172+
//===----------------------------------------------------------------------===//
173+
// FileLineColLoc
174+
//===----------------------------------------------------------------------===//
175+
176+
/// An instance of this location represents a tuple of file, line number, and
177+
/// column number. This is similar to the type of location that you get from
178+
/// most source languages.
179+
///
180+
/// FileLineColLoc is a FileLineColRange with exactly one line and column.
181+
class FileLineColLoc : public FileLineColRange {
182+
public:
183+
using FileLineColRange::FileLineColRange;
184+
185+
static FileLineColLoc get(StringAttr filename, unsigned line,
186+
unsigned column);
187+
static FileLineColLoc get(MLIRContext *context, StringRef fileName,
188+
unsigned line, unsigned column);
189+
190+
StringAttr getFilename() const;
191+
unsigned getLine() const;
192+
unsigned getColumn() const;
193+
194+
/// Methods for support type inquiry through isa, cast, and dyn_cast.
195+
static bool classof(Attribute attr);
196+
};
197+
167198
//===----------------------------------------------------------------------===//
168199
// OpaqueLoc
169200
//===----------------------------------------------------------------------===//

mlir/lib/AsmParser/LocationParser.cpp

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mlir/IR/BuiltinAttributes.h"
1313
#include "mlir/IR/Location.h"
1414
#include "mlir/Support/LLVM.h"
15+
#include <optional>
1516

1617
using namespace mlir;
1718
using namespace mlir::detail;
@@ -97,37 +98,82 @@ ParseResult Parser::parseFusedLocation(LocationAttr &loc) {
9798
return success();
9899
}
99100

100-
ParseResult Parser::parseNameOrFileLineColLocation(LocationAttr &loc) {
101+
ParseResult Parser::parseNameOrFileLineColRange(LocationAttr &loc) {
101102
auto *ctx = getContext();
102103
auto str = getToken().getStringValue();
103104
consumeToken(Token::string);
104105

106+
std::optional<unsigned> startLine, startColumn, endLine, endColumn;
107+
105108
// If the next token is ':' this is a filelinecol location.
106109
if (consumeIf(Token::colon)) {
107110
// Parse the line number.
108111
if (getToken().isNot(Token::integer))
109112
return emitWrongTokenError(
110-
"expected integer line number in FileLineColLoc");
111-
auto line = getToken().getUnsignedIntegerValue();
112-
if (!line)
113+
"expected integer line number in FileLineColRange");
114+
startLine = getToken().getUnsignedIntegerValue();
115+
if (!startLine)
113116
return emitWrongTokenError(
114-
"expected integer line number in FileLineColLoc");
117+
"expected integer line number in FileLineColRange");
115118
consumeToken(Token::integer);
116119

117120
// Parse the ':'.
118-
if (parseToken(Token::colon, "expected ':' in FileLineColLoc"))
119-
return failure();
121+
if (getToken().isNot(Token::colon)) {
122+
loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine);
123+
return success();
124+
}
125+
consumeToken(Token::colon);
120126

121127
// Parse the column number.
122-
if (getToken().isNot(Token::integer))
128+
if (getToken().isNot(Token::integer)) {
129+
return emitWrongTokenError(
130+
"expected integer column number in FileLineColRange");
131+
}
132+
startColumn = getToken().getUnsignedIntegerValue();
133+
if (!startColumn.has_value())
134+
return emitError("expected integer column number in FileLineColRange");
135+
consumeToken(Token::integer);
136+
137+
if (!isCurrentTokenAKeyword() || getTokenSpelling() != "to") {
138+
loc = FileLineColLoc::get(ctx, str, *startLine, *startColumn);
139+
return success();
140+
}
141+
consumeToken();
142+
143+
// Parse the line number.
144+
if (getToken().is(Token::integer)) {
145+
endLine = getToken().getUnsignedIntegerValue();
146+
if (!endLine) {
147+
return emitWrongTokenError(
148+
"expected integer line number in FileLineColRange");
149+
}
150+
consumeToken(Token::integer);
151+
}
152+
153+
// Parse the ':'.
154+
if (getToken().isNot(Token::colon)) {
155+
return emitWrongTokenError(
156+
"expected either integer or `:` post `to` in FileLineColRange");
157+
}
158+
consumeToken(Token::colon);
159+
160+
// Parse the column number.
161+
if (getToken().isNot(Token::integer)) {
123162
return emitWrongTokenError(
124-
"expected integer column number in FileLineColLoc");
125-
auto column = getToken().getUnsignedIntegerValue();
126-
if (!column.has_value())
127-
return emitError("expected integer column number in FileLineColLoc");
163+
"expected integer column number in FileLineColRange");
164+
}
165+
endColumn = getToken().getUnsignedIntegerValue();
166+
if (!endColumn.has_value())
167+
return emitError("expected integer column number in FileLineColRange");
128168
consumeToken(Token::integer);
129169

130-
loc = FileLineColLoc::get(ctx, str, *line, *column);
170+
if (endLine.has_value()) {
171+
loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine,
172+
*startColumn, *endLine, *endColumn);
173+
} else {
174+
loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine,
175+
*startColumn, *endColumn);
176+
}
131177
return success();
132178
}
133179

@@ -166,7 +212,7 @@ ParseResult Parser::parseLocationInstance(LocationAttr &loc) {
166212

167213
// Handle either name or filelinecol locations.
168214
if (getToken().is(Token::string))
169-
return parseNameOrFileLineColLocation(loc);
215+
return parseNameOrFileLineColRange(loc);
170216

171217
// Bare tokens required for other cases.
172218
if (!getToken().is(Token::bare_identifier))

mlir/lib/AsmParser/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ class Parser {
310310
ParseResult parseFusedLocation(LocationAttr &loc);
311311

312312
/// Parse a name or FileLineCol location instance.
313-
ParseResult parseNameOrFileLineColLocation(LocationAttr &loc);
313+
ParseResult parseNameOrFileLineColRange(LocationAttr &loc);
314314

315315
//===--------------------------------------------------------------------===//
316316
// Affine Parsing

mlir/lib/IR/AsmPrinter.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,12 +2009,23 @@ void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty,
20092009
else
20102010
os << "unknown";
20112011
})
2012-
.Case<FileLineColLoc>([&](FileLineColLoc loc) {
2012+
.Case<FileLineColRange>([&](FileLineColRange loc) {
20132013
if (pretty)
20142014
os << loc.getFilename().getValue();
20152015
else
20162016
printEscapedString(loc.getFilename());
2017-
os << ':' << loc.getLine() << ':' << loc.getColumn();
2017+
if (loc.getEndColumn() == loc.getStartColumn() &&
2018+
loc.getStartLine() == loc.getEndLine()) {
2019+
os << ':' << loc.getStartLine() << ':' << loc.getStartColumn();
2020+
return;
2021+
}
2022+
if (loc.getStartLine() == loc.getEndLine()) {
2023+
os << ':' << loc.getStartLine() << ':' << loc.getStartColumn()
2024+
<< " to :" << loc.getEndColumn();
2025+
return;
2026+
}
2027+
os << ':' << loc.getStartLine() << ':' << loc.getStartColumn() << " to "
2028+
<< loc.getEndLine() << ':' << loc.getEndColumn();
20182029
})
20192030
.Case<NameLoc>([&](NameLoc loc) {
20202031
printEscapedString(loc.getName());

0 commit comments

Comments
 (0)