Skip to content

Commit 7b86576

Browse files
committed
Unique vector
1 parent 3e98130 commit 7b86576

File tree

2 files changed

+60
-44
lines changed

2 files changed

+60
-44
lines changed

libsolutil/CommonData.h

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,6 @@ inline std::multiset<T...>& operator-=(std::multiset<T...>& _a, C const& _b)
159159
return _a;
160160
}
161161

162-
/// Remove the elements of a container from a vector
163-
template <class T, class U> std::vector<T>& operator-=(std::vector<T>& _a, U& _b)
164-
{
165-
for (auto const& i: _b)
166-
_a.erase(std::find(_a.begin(), _a.end(), i));
167-
return _a;
168-
}
169-
170162
namespace solidity::util
171163
{
172164

@@ -351,6 +343,49 @@ void joinMap(std::map<K, V>& _a, std::map<K, V>&& _b, F _conflictSolver)
351343
}
352344
}
353345

346+
template<typename T>
347+
class UniqueVector
348+
{
349+
public:
350+
std::vector<T>& contents() { return m_contents; }
351+
size_t size() const { return m_contents.size(); }
352+
bool empty() const { return m_contents.empty(); }
353+
auto begin() const { return m_contents.begin(); }
354+
auto end() const { return m_contents.end(); }
355+
void clear() { m_contents.clear(); }
356+
bool contains(T const& _value) const
357+
{
358+
return std::find(m_contents.begin(), m_contents.end(), _value) != m_contents.end();
359+
}
360+
361+
void pushBack(T _value)
362+
{
363+
if (!contains(_value))
364+
m_contents.emplace_back(std::move(_value));
365+
}
366+
367+
void pushBack(UniqueVector<T> const& _values)
368+
{
369+
for (auto&& value: _values)
370+
pushBack(value);
371+
}
372+
373+
void removeAll(std::vector<T> const& _values)
374+
{
375+
for (auto const& value: _values)
376+
m_contents.erase(std::find(m_contents.begin(), m_contents.end(), value));
377+
}
378+
379+
private:
380+
std::vector<T> m_contents;
381+
};
382+
383+
template<typename T>
384+
void swap(UniqueVector<T>& _lhs, UniqueVector<T>& _rhs)
385+
{
386+
std::swap(_lhs.contents(), _rhs.contents());
387+
}
388+
354389
namespace detail
355390
{
356391

@@ -458,24 +493,6 @@ bool contains_if(T const& _t, Predicate const& _p)
458493
return std::end(_t) != std::find_if(std::begin(_t), std::end(_t), _p);
459494
}
460495

461-
/// Function that insert @param _elem into a vector @param _destination only if _elem is not
462-
/// already present in _destination vector.
463-
template <class T>
464-
void tryEmplaceBack(std::vector<T>& _destination, T _elem)
465-
{
466-
if (!contains(_destination, _elem))
467-
_destination.emplace_back(std::move(_elem));
468-
}
469-
470-
/// Function that takes vector @param _destination and appends vector @param _source,
471-
/// whilst only taking into account unique elements of _source.
472-
template <class T>
473-
void appendMissing(std::vector<T>& _destination, std::vector<T> const& _source)
474-
{
475-
for (auto&& elem: _source)
476-
tryEmplaceBack(_destination, elem);
477-
}
478-
479496
/// Function that iterates over a vector, calling a function on each of its
480497
/// elements. If that function returns a vector, the element is replaced by
481498
/// the returned vector. During the iteration, the original vector is only valid

libyul/optimiser/SSATransform.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -167,22 +167,22 @@ class IntroduceControlFlowSSA: public ASTModifier
167167
/// Variables (that are to be replaced) currently in scope.
168168
std::set<YulString> m_variablesInScope;
169169
/// Variables that do not have a specific value.
170-
std::vector<YulString> m_variablesToReassign;
170+
util::UniqueVector<YulString> m_variablesToReassign;
171171
TypeInfo const& m_typeInfo;
172172
};
173173

174174
void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function)
175175
{
176176
std::set<YulString> varsInScope;
177177
std::swap(varsInScope, m_variablesInScope);
178-
std::vector<YulString> toReassign;
178+
util::UniqueVector<YulString> toReassign;
179179
std::swap(toReassign, m_variablesToReassign);
180180

181181
for (auto const& param: _function.parameters)
182182
if (m_variablesToReplace.count(param.name))
183183
{
184184
m_variablesInScope.insert(param.name);
185-
m_variablesToReassign.push_back(param.name);
185+
m_variablesToReassign.pushBack(param.name);
186186
}
187187

188188
ASTModifier::operator()(_function);
@@ -196,8 +196,8 @@ void IntroduceControlFlowSSA::operator()(ForLoop& _for)
196196
yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run.");
197197

198198
for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post))
199-
if (util::contains(m_variablesInScope,var) && !util::contains(m_variablesToReassign, var))
200-
m_variablesToReassign.push_back(var);
199+
if (util::contains(m_variablesInScope,var))
200+
m_variablesToReassign.pushBack(var);
201201

202202
(*this)(_for.body);
203203
(*this)(_for.post);
@@ -207,20 +207,20 @@ void IntroduceControlFlowSSA::operator()(Switch& _switch)
207207
{
208208
yulAssert(m_variablesToReassign.empty(), "");
209209

210-
std::vector<YulString> toReassign;
210+
util::UniqueVector<YulString> toReassign;
211211
for (auto& c: _switch.cases)
212212
{
213213
(*this)(c.body);
214-
util::appendMissing(toReassign, m_variablesToReassign);
214+
toReassign.pushBack(m_variablesToReassign);
215215
}
216216

217-
util::appendMissing(m_variablesToReassign, toReassign);
217+
m_variablesToReassign.pushBack(toReassign);
218218
}
219219

220220
void IntroduceControlFlowSSA::operator()(Block& _block)
221221
{
222-
std::vector<YulString> variablesDeclaredHere;
223-
std::vector<YulString> assignedVariables;
222+
util::UniqueVector<YulString> variablesDeclaredHere;
223+
util::UniqueVector<YulString> assignedVariables;
224224

225225
util::iterateReplacing(
226226
_block.statements,
@@ -235,8 +235,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
235235
{TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}},
236236
std::make_unique<Expression>(Identifier{debugDataOf(_s), toReassign})
237237
});
238-
if (!util::contains(assignedVariables, toReassign))
239-
assignedVariables.push_back(toReassign);
238+
assignedVariables.pushBack(toReassign);
240239
}
241240
m_variablesToReassign.clear();
242241

@@ -246,16 +245,16 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
246245
for (auto const& var: varDecl.variables)
247246
if (m_variablesToReplace.count(var.name))
248247
{
249-
util::tryEmplaceBack(variablesDeclaredHere, var.name);
248+
variablesDeclaredHere.pushBack(var.name);
250249
m_variablesInScope.insert(var.name);
251250
}
252251
}
253252
else if (std::holds_alternative<Assignment>(_s))
254253
{
255254
Assignment& assignment = std::get<Assignment>(_s);
256255
for (auto const& var: assignment.variableNames)
257-
if (m_variablesToReplace.count(var.name) && !util::contains(assignedVariables, var.name))
258-
assignedVariables.push_back(var.name);
256+
if (m_variablesToReplace.count(var.name))
257+
assignedVariables.pushBack(var.name);
259258
}
260259
else
261260
visit(_s);
@@ -270,9 +269,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
270269
}
271270
);
272271

273-
util::appendMissing(m_variablesToReassign, assignedVariables);
274-
m_variablesInScope -= variablesDeclaredHere;
275-
m_variablesToReassign -= variablesDeclaredHere;
272+
m_variablesToReassign.pushBack(assignedVariables);
273+
m_variablesInScope -= variablesDeclaredHere.contents();
274+
m_variablesToReassign.removeAll(variablesDeclaredHere.contents());
276275
}
277276

278277
/**

0 commit comments

Comments
 (0)