Skip to content

Commit b716b56

Browse files
committed
Visitor: encapsulate projection encoding in a wrapper struct
Also change the encoding to use the MSB but not negation. This shouldn't make a big difference, but if anything is probably slightly better.
1 parent 3858d65 commit b716b56

File tree

2 files changed

+46
-19
lines changed

2 files changed

+46
-19
lines changed

include/llvm-dialects/Dialect/Visitor.h

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,36 @@ using VisitorCallback = void(const VisitorCallbackData &, void *,
142142
using PayloadProjectionCallback = void *(void *);
143143

144144
struct VisitorHandler {
145-
// If non-negative, a byte offset to apply to the payload. If negative,
146-
// a shifted index into the payload projections vector.
147-
ssize_t projection = 0;
145+
// Either a byte offset to apply to the payload or an index into the payload
146+
// projections vector for more complex projections.
147+
struct Projection {
148+
static constexpr std::size_t Msb = (std::size_t)1
149+
<< (8 * sizeof(std::size_t) - 1);
150+
151+
std::size_t data = 0;
152+
153+
void setOffset(std::size_t offset) {
154+
assert((offset & Msb) == 0);
155+
data = offset;
156+
}
157+
158+
void setIndex(std::size_t index) {
159+
assert((index & Msb) == 0);
160+
data = index | Msb;
161+
}
162+
163+
bool isOffset() const { return (data & Msb) == 0; }
164+
std::size_t getOffset() const {
165+
assert((data & Msb) == 0);
166+
return data;
167+
}
168+
std::size_t getIndex() const {
169+
assert((data & Msb) != 0);
170+
return data & ~Msb;
171+
}
172+
};
173+
174+
Projection projection;
148175

149176
VisitorCallback *callback = nullptr;
150177
VisitorCallbackData data;
@@ -173,7 +200,7 @@ class VisitorTemplate {
173200
public:
174201
void setStrategy(VisitorStrategy strategy);
175202
void add(VisitorKey key, VisitorCallback *fn, VisitorCallbackData data,
176-
ssize_t projection);
203+
VisitorHandler::Projection projection);
177204

178205
private:
179206
VisitorStrategy m_strategy = VisitorStrategy::Default;
@@ -225,7 +252,7 @@ class VisitorBuilderBase {
225252

226253
VisitorTemplate m_ownedTemplate;
227254
VisitorTemplate *m_template;
228-
ssize_t m_projection;
255+
VisitorHandler::Projection m_projection;
229256
};
230257

231258
/// @brief Base class for Visitors

lib/Dialect/Visitor.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ void VisitorTemplate::setStrategy(VisitorStrategy strategy) {
4545
}
4646

4747
void VisitorTemplate::add(VisitorKey key, VisitorCallback *fn,
48-
VisitorCallbackData data, ssize_t projection) {
48+
VisitorCallbackData data,
49+
VisitorHandler::Projection projection) {
4950
VisitorHandler handler;
5051
handler.callback = fn;
5152
handler.data = data;
@@ -84,20 +85,19 @@ void VisitorTemplate::add(VisitorKey key, VisitorCallback *fn,
8485
}
8586
}
8687

87-
VisitorBuilderBase::VisitorBuilderBase()
88-
: m_template(&m_ownedTemplate), m_projection(0) {}
88+
VisitorBuilderBase::VisitorBuilderBase() : m_template(&m_ownedTemplate) {}
8989

9090
VisitorBuilderBase::VisitorBuilderBase(VisitorBuilderBase *parent,
9191
PayloadProjectionCallback *projection)
9292
: m_template(parent->m_template) {
9393
// Extract and update the parent's projection.
9494
SmallVector<PayloadProjection> sequence;
9595

96-
if (parent->m_projection >= 0) {
96+
if (parent->m_projection.isOffset()) {
9797
sequence.emplace_back();
98-
sequence.back().offset = parent->m_projection;
98+
sequence.back().offset = parent->m_projection.getOffset();
9999
} else {
100-
for (size_t idx = -parent->m_projection - 1;; ++idx) {
100+
for (size_t idx = parent->m_projection.getIndex();; ++idx) {
101101
sequence.push_back(m_template->m_projections[idx]);
102102
if (!sequence.back().projection)
103103
break;
@@ -108,7 +108,7 @@ VisitorBuilderBase::VisitorBuilderBase(VisitorBuilderBase *parent,
108108
sequence.emplace_back();
109109

110110
// Setup our projection.
111-
m_projection = -(m_template->m_projections.size() + 1);
111+
m_projection.setIndex(m_template->m_projections.size());
112112
m_template->m_projections.insert(m_template->m_projections.end(),
113113
sequence.begin(), sequence.end());
114114
}
@@ -118,20 +118,20 @@ VisitorBuilderBase::VisitorBuilderBase(VisitorBuilderBase *parent,
118118
: m_template(parent->m_template) {
119119
if (offset == 0) {
120120
m_projection = parent->m_projection;
121-
} else if (parent->m_projection >= 0) {
122-
m_projection = parent->m_projection + offset;
121+
} else if (parent->m_projection.isOffset()) {
122+
m_projection.setOffset(parent->m_projection.getOffset() + offset);
123123
} else {
124124
// Extract and update the parent's projection.
125125
SmallVector<PayloadProjection> sequence;
126-
for (size_t idx = -parent->m_projection - 1;; ++idx) {
126+
for (size_t idx = parent->m_projection.getIndex();; ++idx) {
127127
sequence.push_back(m_template->m_projections[idx]);
128128
if (!sequence.back().projection)
129129
break;
130130
}
131131
sequence.back().offset += offset;
132132

133133
// Setup our projection.
134-
m_projection = -(m_template->m_projections.size() + 1);
134+
m_projection.setIndex(m_template->m_projections.size());
135135
m_template->m_projections.insert(m_template->m_projections.end(),
136136
sequence.begin(), sequence.end());
137137
}
@@ -212,10 +212,10 @@ void VisitorBase::call(HandlerRange handlers, void *payload,
212212

213213
void VisitorBase::call(const VisitorHandler &handler, void *payload,
214214
Instruction &inst) const {
215-
if (handler.projection >= 0) {
216-
payload = (char *)payload + handler.projection;
215+
if (handler.projection.isOffset()) {
216+
payload = (char *)payload + handler.projection.getOffset();
217217
} else {
218-
for (size_t idx = -handler.projection - 1;; ++idx) {
218+
for (size_t idx = handler.projection.getIndex();; ++idx) {
219219
payload = (char *)payload + m_projections[idx].offset;
220220
if (!m_projections[idx].projection)
221221
break;

0 commit comments

Comments
 (0)