Skip to content

Commit f6b8b7d

Browse files
authored
Merge pull request #8897 from swiftix/new-integer-perf-improvements
Performance improvements for new integers
2 parents 7f75ec2 + e1c3538 commit f6b8b7d

File tree

7 files changed

+618
-102
lines changed

7 files changed

+618
-102
lines changed

lib/SILOptimizer/Mandatory/ConstantPropagation.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ static SILInstruction *constantFoldCompare(BuiltinInst *BI,
232232
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), Res);
233233
}
234234

235+
// Comparisons of an unsigned value with 0.
235236
SILValue Other;
236237
auto MatchNonNegative =
237238
m_BuiltinInst(BuiltinValueKind::AssumeNonNegative, m_ValueBase());
@@ -259,6 +260,132 @@ static SILInstruction *constantFoldCompare(BuiltinInst *BI,
259260
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt(1, 1));
260261
}
261262

263+
// Comparisons with Int.Max.
264+
IntegerLiteralInst *IntMax;
265+
266+
// Check signed comparisons.
267+
if (match(BI,
268+
m_CombineOr(
269+
// Int.max < x
270+
m_BuiltinInst(BuiltinValueKind::ICMP_SLT,
271+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
272+
// x > Int.max
273+
m_BuiltinInst(BuiltinValueKind::ICMP_SGT, m_SILValue(Other),
274+
m_IntegerLiteralInst(IntMax)))) &&
275+
IntMax->getValue().isMaxSignedValue()) {
276+
// Any signed number should be <= then IntMax.
277+
SILBuilderWithScope B(BI);
278+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt());
279+
}
280+
281+
if (match(BI,
282+
m_CombineOr(
283+
m_BuiltinInst(BuiltinValueKind::ICMP_SGE,
284+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
285+
m_BuiltinInst(BuiltinValueKind::ICMP_SLE, m_SILValue(Other),
286+
m_IntegerLiteralInst(IntMax)))) &&
287+
IntMax->getValue().isMaxSignedValue()) {
288+
// Any signed number should be <= then IntMax.
289+
SILBuilderWithScope B(BI);
290+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt(1, 1));
291+
}
292+
293+
// For any x of the same size as Int.max and n>=1 , (x>>n) is always <= Int.max,
294+
// that is (x>>n) <= Int.max and Int.max >= (x>>n) are true.
295+
if (match(BI,
296+
m_CombineOr(
297+
// Int.max >= x
298+
m_BuiltinInst(BuiltinValueKind::ICMP_UGE,
299+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
300+
// x <= Int.max
301+
m_BuiltinInst(BuiltinValueKind::ICMP_ULE, m_SILValue(Other),
302+
m_IntegerLiteralInst(IntMax)),
303+
// Int.max >= x
304+
m_BuiltinInst(BuiltinValueKind::ICMP_SGE,
305+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
306+
// x <= Int.max
307+
m_BuiltinInst(BuiltinValueKind::ICMP_SLE, m_SILValue(Other),
308+
m_IntegerLiteralInst(IntMax)))) &&
309+
IntMax->getValue().isMaxSignedValue()) {
310+
// Check if other is a result of a logical shift right by a strictly
311+
// positive number of bits.
312+
IntegerLiteralInst *ShiftCount;
313+
if (match(Other, m_BuiltinInst(BuiltinValueKind::LShr, m_ValueBase(),
314+
m_IntegerLiteralInst(ShiftCount))) &&
315+
ShiftCount->getValue().isStrictlyPositive()) {
316+
SILBuilderWithScope B(BI);
317+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt(1, 1));
318+
}
319+
}
320+
321+
// At the same time (x>>n) > Int.max and Int.max < (x>>n) is false.
322+
if (match(BI,
323+
m_CombineOr(
324+
// Int.max < x
325+
m_BuiltinInst(BuiltinValueKind::ICMP_ULT,
326+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
327+
// x > Int.max
328+
m_BuiltinInst(BuiltinValueKind::ICMP_UGT, m_SILValue(Other),
329+
m_IntegerLiteralInst(IntMax)),
330+
// Int.max < x
331+
m_BuiltinInst(BuiltinValueKind::ICMP_SLT,
332+
m_IntegerLiteralInst(IntMax), m_SILValue(Other)),
333+
// x > Int.max
334+
m_BuiltinInst(BuiltinValueKind::ICMP_SGT, m_SILValue(Other),
335+
m_IntegerLiteralInst(IntMax)))) &&
336+
IntMax->getValue().isMaxSignedValue()) {
337+
// Check if other is a result of a logical shift right by a strictly
338+
// positive number of bits.
339+
IntegerLiteralInst *ShiftCount;
340+
if (match(Other, m_BuiltinInst(BuiltinValueKind::LShr, m_ValueBase(),
341+
m_IntegerLiteralInst(ShiftCount))) &&
342+
ShiftCount->getValue().isStrictlyPositive()) {
343+
SILBuilderWithScope B(BI);
344+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt());
345+
}
346+
}
347+
348+
// Fold x < 0 into false, if x is known to be a result of an unsigned
349+
// operation with overflow checks enabled.
350+
BuiltinInst *BIOp;
351+
if (match(BI, m_BuiltinInst(BuiltinValueKind::ICMP_SLT,
352+
m_TupleExtractInst(m_BuiltinInst(BIOp), 0),
353+
m_Zero()))) {
354+
// Check if Other is a result of an unsigned operation with overflow.
355+
switch (BIOp->getBuiltinInfo().ID) {
356+
default:
357+
break;
358+
case BuiltinValueKind::UAddOver:
359+
case BuiltinValueKind::USubOver:
360+
case BuiltinValueKind::UMulOver:
361+
// Was it an operation with an overflow check?
362+
if (match(BIOp->getOperand(2), m_One())) {
363+
SILBuilderWithScope B(BI);
364+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt());
365+
}
366+
}
367+
}
368+
369+
// Fold x >= 0 into true, if x is known to be a result of an unsigned
370+
// operation with overflow checks enabled.
371+
if (match(BI, m_BuiltinInst(BuiltinValueKind::ICMP_SGE,
372+
m_TupleExtractInst(m_BuiltinInst(BIOp), 0),
373+
m_Zero()))) {
374+
// Check if Other is a result of an unsigned operation with overflow.
375+
switch (BIOp->getBuiltinInfo().ID) {
376+
default:
377+
break;
378+
case BuiltinValueKind::UAddOver:
379+
case BuiltinValueKind::USubOver:
380+
case BuiltinValueKind::UMulOver:
381+
// Was it an operation with an overflow check?
382+
if (match(BIOp->getOperand(2), m_One())) {
383+
SILBuilderWithScope B(BI);
384+
return B.createIntegerLiteral(BI->getLoc(), BI->getType(), APInt(1, 1));
385+
}
386+
}
387+
}
388+
262389
return nullptr;
263390
}
264391

lib/SILOptimizer/SILCombiner/SILCombinerBuiltinVisitors.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,19 @@ SILInstruction *SILCombiner::optimizeBuiltinCompareEq(BuiltinInst *BI,
5555
IsZeroKind RHS = isZeroValue(BI->getArguments()[1]);
5656

5757
// Can't handle unknown values.
58-
if (LHS == IsZeroKind::Unknown || RHS == IsZeroKind::Unknown)
58+
if (LHS == IsZeroKind::Unknown) {
5959
return nullptr;
60+
}
61+
62+
// Canonicalize i1_const == X to X == i1_const.
63+
// Canonicalize i1_const != X to X != i1_const.
64+
if (RHS == IsZeroKind::Unknown) {
65+
auto *CanonI =
66+
Builder.createBuiltin(BI->getLoc(), BI->getName(), BI->getType(), {},
67+
{BI->getArguments()[1], BI->getArguments()[0]});
68+
replaceInstUsesWith(*BI, CanonI);
69+
return eraseInstFromFunction(*BI);
70+
}
6071

6172
// Can't handle non-zero ptr values.
6273
if (LHS == IsZeroKind::NotZero && RHS == IsZeroKind::NotZero)

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,9 +1075,22 @@ SILInstruction *SILCombiner::visitStrongReleaseInst(StrongReleaseInst *SRI) {
10751075

10761076
SILInstruction *SILCombiner::visitCondBranchInst(CondBranchInst *CBI) {
10771077
// cond_br(xor(x, 1)), t_label, f_label -> cond_br x, f_label, t_label
1078+
// cond_br(x == 0), t_label, f_label -> cond_br x, f_label, t_label
1079+
// cond_br(x != 1), t_label, f_label -> cond_br x, f_label, t_label
10781080
SILValue X;
1079-
if (match(CBI->getCondition(), m_ApplyInst(BuiltinValueKind::Xor,
1080-
m_SILValue(X), m_One()))) {
1081+
if (match(CBI->getCondition(),
1082+
m_CombineOr(
1083+
// xor(x, 1)
1084+
m_ApplyInst(BuiltinValueKind::Xor, m_SILValue(X), m_One()),
1085+
// xor(1,x)
1086+
m_ApplyInst(BuiltinValueKind::Xor, m_One(), m_SILValue(X)),
1087+
// x == 0
1088+
m_ApplyInst(BuiltinValueKind::ICMP_EQ, m_SILValue(X), m_Zero()),
1089+
// x != 1
1090+
m_ApplyInst(BuiltinValueKind::ICMP_NE, m_SILValue(X),
1091+
m_One()))) &&
1092+
X->getType() ==
1093+
SILType::getBuiltinIntegerType(1, CBI->getModule().getASTContext())) {
10811094
SmallVector<SILValue, 4> OrigTrueArgs, OrigFalseArgs;
10821095
for (const auto &Op : CBI->getTrueArgs())
10831096
OrigTrueArgs.push_back(Op);

0 commit comments

Comments
 (0)