Skip to content

Commit 9fc9ed3

Browse files
committed
[mlir] Add FileRange location type.
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.
1 parent 173907b commit 9fc9ed3

File tree

11 files changed

+410
-48
lines changed

11 files changed

+410
-48
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+
PresentOptionalVarInt:$start_line,
113+
PresentOptionalVarInt:$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: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,46 +60,97 @@ 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+
// Note: this only shows the parameters for which accessors are generated. The
94+
// locations are only set in storage.
95+
let parameters = (ins "StringAttr":$filename);
8896
let builders = [
97+
98+
AttrBuilderWithInferredContext<(ins "StringAttr":$filename), [{
99+
return $_get(filename.getContext(), filename, ArrayRef<unsigned>{});
100+
}]>,
101+
AttrBuilderWithInferredContext<(ins "StringAttr":$filename,
102+
"unsigned":$line), [{
103+
return $_get(filename.getContext(), filename,
104+
ArrayRef<unsigned>{line});
105+
}]>,
89106
AttrBuilderWithInferredContext<(ins "StringAttr":$filename,
90107
"unsigned":$line,
91108
"unsigned":$column), [{
92-
return $_get(filename.getContext(), filename, line, column);
109+
return $_get(filename.getContext(), filename,
110+
ArrayRef<unsigned>{line, column});
93111
}]>,
94-
AttrBuilder<(ins "StringRef":$filename, "unsigned":$line,
95-
"unsigned":$column), [{
112+
AttrBuilder<(ins "::llvm::StringRef":$filename,
113+
"unsigned":$start_line,
114+
"unsigned":$start_column), [{
96115
return $_get($_ctxt,
97-
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
98-
line, column);
99-
}]>
116+
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
117+
ArrayRef<unsigned>{start_line, start_column});
118+
}]>,
119+
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename,
120+
"unsigned":$line,
121+
"unsigned":$start_column,
122+
"unsigned":$end_column), [{
123+
return $_get(filename.getContext(), filename,
124+
ArrayRef<unsigned>{line, start_column, end_column});
125+
}]>,
126+
AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename,
127+
"unsigned":$start_line,
128+
"unsigned":$start_column,
129+
"unsigned":$end_line,
130+
"unsigned":$end_column), [{
131+
return $_get(filename.getContext(), filename,
132+
ArrayRef<unsigned>{start_line, start_column, end_column, end_line});
133+
}]>,
134+
AttrBuilder<(ins "::llvm::StringRef":$filename,
135+
"unsigned":$start_line,
136+
"unsigned":$start_column,
137+
"unsigned":$end_line,
138+
"unsigned":$end_column), [{
139+
return $_get($_ctxt,
140+
StringAttr::get($_ctxt, filename.empty() ? "-" : filename),
141+
ArrayRef<unsigned>{start_line, start_column, end_column, end_line});
142+
}]>,
100143
];
144+
145+
let extraClassDeclaration = [{
146+
std::optional<unsigned> getStartLine() const;
147+
std::optional<unsigned> getStartColumn() const;
148+
std::optional<unsigned> getEndColumn() const;
149+
std::optional<unsigned> getEndLine() const;
150+
}];
101151
let skipDefaultBuilders = 1;
102-
let attrName = "builtin.file_line_loc";
152+
let genStorageClass = 0;
153+
let attrName = "builtin.file_line_range";
103154
}
104155

105156
//===----------------------------------------------------------------------===//

mlir/include/mlir/IR/BytecodeBase.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ def VarInt :
8282
WithBuilder<"$_args",
8383
WithPrinter<"$_writer.writeVarInt($_getter)",
8484
WithType <"uint64_t">>>>;
85+
// This is for optional ints which are guaranteed to be present.
86+
def PresentOptionalVarInt :
87+
WithParser <"succeeded($_reader.readVarInt($_var))",
88+
WithBuilder<"$_args",
89+
WithPrinter<"$_writer.writeVarInt(*$_getter)",
90+
WithType <"uint64_t">>>>;
8591
def SignedVarInt :
8692
WithParser <"succeeded($_reader.readSignedVarInt($_var))",
8793
WithBuilder<"$_args",

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
@@ -305,7 +305,7 @@ class Parser {
305305
ParseResult parseFusedLocation(LocationAttr &loc);
306306

307307
/// Parse a name or FileLineCol location instance.
308-
ParseResult parseNameOrFileLineColLocation(LocationAttr &loc);
308+
ParseResult parseNameOrFileLineColRange(LocationAttr &loc);
309309

310310
//===--------------------------------------------------------------------===//
311311
// Affine Parsing

mlir/lib/IR/AsmPrinter.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,12 +2009,21 @@ 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+
os << ':' << *loc.getStartLine();
2018+
if (loc.getStartColumn()) {
2019+
os << ':' << *loc.getStartColumn();
2020+
if (loc.getEndColumn().has_value() || loc.getEndLine().has_value())
2021+
os << " to ";
2022+
if (loc.getEndLine().has_value())
2023+
os << *loc.getEndLine();
2024+
if (loc.getEndColumn().has_value())
2025+
os << ':' << *loc.getEndColumn();
2026+
}
20182027
})
20192028
.Case<NameLoc>([&](NameLoc loc) {
20202029
printEscapedString(loc.getName());

0 commit comments

Comments
 (0)