Skip to content

Commit 46477cf

Browse files
authored
Merge pull request #6595 from ethereum/reduceStackHeight
Split rule list to reduce stack height for 0.4.26
2 parents 0bdcf1b + 91428c0 commit 46477cf

File tree

2 files changed

+129
-13
lines changed

2 files changed

+129
-13
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### 0.4.26 (unreleased)
2+
3+
Bugfixes:
4+
* General: Split rule list such that JavaScript environments with small stacks can use the compiler.
5+
6+
17
### 0.4.25 (2018-09-12)
28

39
Important Bugfixes:

libevmasm/RuleList.h

Lines changed: 123 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,20 @@ template <class S> S modWorkaround(S const& _a, S const& _b)
4444
return (S)(bigint(_a) % bigint(_b));
4545
}
4646

47-
/// @returns a list of simplification rules given certain match placeholders.
48-
/// A, B and C should represent constants, X and Y arbitrary expressions.
49-
/// The simplifications should neven change the order of evaluation of
50-
/// arbitrary operations.
47+
// simplificationRuleList below was split up into parts to prevent
48+
// stack overflows in the JavaScript optimizer for emscripten builds
49+
// that affected certain browser versions.
5150
template <class Pattern>
52-
std::vector<SimplificationRule<Pattern>> simplificationRuleList(
51+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart1(
5352
Pattern A,
5453
Pattern B,
5554
Pattern C,
56-
Pattern X,
57-
Pattern Y
55+
Pattern,
56+
Pattern
5857
)
5958
{
60-
std::vector<SimplificationRule<Pattern>> rules;
61-
rules += std::vector<SimplificationRule<Pattern>>{
62-
// arithmetics on constants
59+
return std::vector<SimplificationRule<Pattern>> {
60+
// arithmetic on constants
6361
{{Instruction::ADD, {A, B}}, [=]{ return A.d() + B.d(); }, false},
6462
{{Instruction::MUL, {A, B}}, [=]{ return A.d() * B.d(); }, false},
6563
{{Instruction::SUB, {A, B}}, [=]{ return A.d() - B.d(); }, false},
@@ -98,8 +96,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
9896
if (A.d() > 255)
9997
return u256(0);
10098
return B.d() >> unsigned(A.d());
101-
}, false},
99+
}, false}
100+
};
101+
}
102102

103+
template <class Pattern>
104+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart2(
105+
Pattern,
106+
Pattern,
107+
Pattern,
108+
Pattern X,
109+
Pattern
110+
)
111+
{
112+
return std::vector<SimplificationRule<Pattern>> {
103113
// invariants involving known constants
104114
{{Instruction::ADD, {X, 0}}, [=]{ return X; }, false},
105115
{{Instruction::ADD, {0, X}}, [=]{ return X; }, false},
@@ -129,8 +139,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
129139
{{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }, true},
130140
{{Instruction::MOD, {0, X}}, [=]{ return u256(0); }, true},
131141
{{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false },
132-
{{Instruction::EQ, {0, X}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false },
142+
{{Instruction::EQ, {0, X}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false }
143+
};
144+
}
133145

146+
template <class Pattern>
147+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart3(
148+
Pattern,
149+
Pattern,
150+
Pattern,
151+
Pattern X,
152+
Pattern
153+
)
154+
{
155+
return std::vector<SimplificationRule<Pattern>> {
134156
// operations involving an expression and itself
135157
{{Instruction::AND, {X, X}}, [=]{ return X; }, true},
136158
{{Instruction::OR, {X, X}}, [=]{ return X; }, true},
@@ -141,8 +163,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
141163
{{Instruction::SLT, {X, X}}, [=]{ return u256(0); }, true},
142164
{{Instruction::GT, {X, X}}, [=]{ return u256(0); }, true},
143165
{{Instruction::SGT, {X, X}}, [=]{ return u256(0); }, true},
144-
{{Instruction::MOD, {X, X}}, [=]{ return u256(0); }, true},
166+
{{Instruction::MOD, {X, X}}, [=]{ return u256(0); }, true}
167+
};
168+
}
145169

170+
template <class Pattern>
171+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart4(
172+
Pattern,
173+
Pattern,
174+
Pattern,
175+
Pattern X,
176+
Pattern Y
177+
)
178+
{
179+
return std::vector<SimplificationRule<Pattern>> {
146180
// logical instruction combinations
147181
{{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }, false},
148182
{{Instruction::XOR, {X, {Instruction::XOR, {X, Y}}}}, [=]{ return Y; }, true},
@@ -162,6 +196,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
162196
{{Instruction::OR, {X, {Instruction::NOT, {X}}}}, [=]{ return ~u256(0); }, true},
163197
{{Instruction::OR, {{Instruction::NOT, {X}}, X}}, [=]{ return ~u256(0); }, true},
164198
};
199+
}
200+
201+
202+
template <class Pattern>
203+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
204+
Pattern,
205+
Pattern,
206+
Pattern,
207+
Pattern X,
208+
Pattern
209+
)
210+
{
211+
std::vector<SimplificationRule<Pattern>> rules;
165212

166213
// Replace MOD X, <power-of-two> with AND X, <power-of-two> - 1
167214
for (size_t i = 0; i < 256; ++i)
@@ -193,7 +240,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
193240
false
194241
});
195242
}
243+
return rules;
244+
}
196245

246+
template <class Pattern>
247+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart6(
248+
Pattern,
249+
Pattern,
250+
Pattern,
251+
Pattern X,
252+
Pattern Y
253+
)
254+
{
255+
std::vector<SimplificationRule<Pattern>> rules;
197256
// Double negation of opcodes with boolean result
198257
for (auto const& op: std::vector<Instruction>{
199258
Instruction::EQ,
@@ -220,6 +279,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
220279
false
221280
});
222281

282+
return rules;
283+
}
284+
285+
template <class Pattern>
286+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart7(
287+
Pattern A,
288+
Pattern B,
289+
Pattern,
290+
Pattern X,
291+
Pattern Y
292+
)
293+
{
294+
std::vector<SimplificationRule<Pattern>> rules;
223295
// Associative operations
224296
for (auto const& opFun: std::vector<std::pair<Instruction,std::function<u256(u256 const&,u256 const&)>>>{
225297
{Instruction::ADD, std::plus<u256>()},
@@ -259,6 +331,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
259331
}};
260332
}
261333
}
334+
return rules;
335+
}
336+
337+
template <class Pattern>
338+
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart8(
339+
Pattern A,
340+
Pattern,
341+
Pattern,
342+
Pattern X,
343+
Pattern Y
344+
)
345+
{
346+
std::vector<SimplificationRule<Pattern>> rules;
262347

263348
// move constants across subtractions
264349
rules += std::vector<SimplificationRule<Pattern>>{
@@ -292,5 +377,30 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
292377
return rules;
293378
}
294379

380+
/// @returns a list of simplification rules given certain match placeholders.
381+
/// A, B and C should represent constants, X and Y arbitrary expressions.
382+
/// The simplifications should never change the order of evaluation of
383+
/// arbitrary operations.
384+
template <class Pattern>
385+
std::vector<SimplificationRule<Pattern>> simplificationRuleList(
386+
Pattern A,
387+
Pattern B,
388+
Pattern C,
389+
Pattern X,
390+
Pattern Y
391+
)
392+
{
393+
std::vector<SimplificationRule<Pattern>> rules;
394+
rules += simplificationRuleListPart1(A, B, C, X, Y);
395+
rules += simplificationRuleListPart2(A, B, C, X, Y);
396+
rules += simplificationRuleListPart3(A, B, C, X, Y);
397+
rules += simplificationRuleListPart4(A, B, C, X, Y);
398+
rules += simplificationRuleListPart5(A, B, C, X, Y);
399+
rules += simplificationRuleListPart6(A, B, C, X, Y);
400+
rules += simplificationRuleListPart7(A, B, C, X, Y);
401+
rules += simplificationRuleListPart8(A, B, C, X, Y);
402+
return rules;
403+
}
404+
295405
}
296406
}

0 commit comments

Comments
 (0)