Skip to content

Commit 3fe8992

Browse files
committed
---
yaml --- r: 349353 b: refs/heads/master-next c: 2435173 h: refs/heads/master i: 349351: d75f7b1
1 parent 542e35d commit 3fe8992

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 3574c513bbc5578dd9346b4ea9ab5995c5927bb5
3-
refs/heads/master-next: c29d47c35886b27365d4d7dedc13a04372ede625
3+
refs/heads/master-next: 243517331bf01f62aec4b99a824614bbc80c72b5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea
66
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-b: 66d897bfcf64a82cb9a87f5e663d889189d06d07

branches/master-next/lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,34 @@ case BuiltinValueKind::id:
12981298
return foldFPToIntConversion(BI, Builtin, ResultsInError);
12991299
}
13001300

1301+
case BuiltinValueKind::IntToPtr: {
1302+
if (auto *op = dyn_cast<BuiltinInst>(BI->getOperand(0))) {
1303+
if (auto kind = op->getBuiltinKind()) {
1304+
// If we have a single int_to_ptr user and all of the types line up, we
1305+
// can simplify this instruction.
1306+
if (*kind == BuiltinValueKind::PtrToInt &&
1307+
op->getOperand(0)->getType() == BI->getResult(0)->getType()) {
1308+
return op->getOperand(0);
1309+
}
1310+
}
1311+
}
1312+
break;
1313+
}
1314+
1315+
case BuiltinValueKind::PtrToInt: {
1316+
if (auto *op = dyn_cast<BuiltinInst>(BI->getOperand(0))) {
1317+
if (auto kind = op->getBuiltinKind()) {
1318+
// If we have a single int_to_ptr user and all of the types line up, we
1319+
// can simplify this instruction.
1320+
if (*kind == BuiltinValueKind::IntToPtr &&
1321+
op->getOperand(0)->getType() == BI->getResult(0)->getType()) {
1322+
return op->getOperand(0);
1323+
}
1324+
}
1325+
}
1326+
break;
1327+
}
1328+
13011329
case BuiltinValueKind::AssumeNonNegative: {
13021330
auto *V = dyn_cast<IntegerLiteralInst>(Args[0]);
13031331
if (!V)
@@ -1418,7 +1446,8 @@ static bool isApplyOfStringConcat(SILInstruction &I) {
14181446
}
14191447

14201448
static bool isFoldable(SILInstruction *I) {
1421-
return isa<IntegerLiteralInst>(I) || isa<FloatLiteralInst>(I);
1449+
return isa<IntegerLiteralInst>(I) || isa<FloatLiteralInst>(I) ||
1450+
isa<StringLiteralInst>(I);
14221451
}
14231452

14241453
bool ConstantFolder::constantFoldStringConcatenation(ApplyInst *AI) {
@@ -1550,6 +1579,29 @@ void ConstantFolder::initializeWorklist(SILFunction &F) {
15501579
}
15511580
}
15521581

1582+
/// Returns true if \p i is an instruction that has a stateless inverse. We want
1583+
/// to visit such instructions to eliminate such round-trip unnecessary
1584+
/// operations.
1585+
///
1586+
/// As an example, consider casts, inttoptr, ptrtoint and friends.
1587+
static bool isReadNoneAndInvertible(SILInstruction *i) {
1588+
if (auto *bi = dyn_cast<BuiltinInst>(i)) {
1589+
// Look for ptrtoint and inttoptr for now.
1590+
if (auto kind = bi->getBuiltinKind()) {
1591+
switch (*kind) {
1592+
default:
1593+
return false;
1594+
case BuiltinValueKind::PtrToInt:
1595+
case BuiltinValueKind::IntToPtr:
1596+
return true;
1597+
}
1598+
}
1599+
}
1600+
1601+
// Be conservative and return false if we do not have any information.
1602+
return false;
1603+
}
1604+
15531605
SILAnalysis::InvalidationKind
15541606
ConstantFolder::processWorkList() {
15551607
LLVM_DEBUG(llvm::dbgs() << "*** ConstPropagation processing: \n");
@@ -1721,6 +1773,17 @@ ConstantFolder::processWorkList() {
17211773
if (isa<CondFailInst>(User))
17221774
FoldedUsers.insert(User);
17231775

1776+
// See if we have an instruction that is read none and has a stateless
1777+
// inverse. If we do, add it to the worklist so we can check its users
1778+
// for the inverse operation and see if we can perform constant folding
1779+
// on the inverse operation. This can eliminate annoying "round trip"s.
1780+
//
1781+
// NOTE: We are assuming on purpose that our inverse will be read none,
1782+
// since otherwise we wouldn't be able to constant fold it this way.
1783+
if (isReadNoneAndInvertible(User)) {
1784+
WorkList.insert(User);
1785+
}
1786+
17241787
// Initialize ResultsInError as a None optional.
17251788
//
17261789
// We are essentially using this optional to represent 3 states: true,

branches/master-next/test/SILOptimizer/constant_propagation.sil

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,3 +954,37 @@ bb0:
954954
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
955955
// The semantics attribute is used by the constant folder.
956956
sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
957+
958+
// CHECK-LABEL: sil @string_ptr_to_int_round_trip : $@convention(thin) () -> Builtin.RawPointer {
959+
// CHECK-NOT: builtin
960+
// CHECK: } // end sil function 'string_ptr_to_int_round_trip'
961+
sil @string_ptr_to_int_round_trip : $@convention(thin) () -> Builtin.RawPointer {
962+
bb0:
963+
%0 = string_literal utf8 "constant"
964+
%1 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
965+
%2 = builtin "inttoptr_Word"(%1 : $Builtin.Word) : $Builtin.RawPointer
966+
return %2 : $Builtin.RawPointer
967+
}
968+
969+
// CHECK-LABEL: sil @string_ptr_to_int_round_trip_2 : $@convention(thin) () -> Builtin.Word {
970+
// CHECK-NOT: builtin
971+
// CHECK: } // end sil function 'string_ptr_to_int_round_trip_2'
972+
sil @string_ptr_to_int_round_trip_2 : $@convention(thin) () -> Builtin.Word {
973+
bb0:
974+
%0 = integer_literal $Builtin.Word, 0
975+
%1 = builtin "inttoptr_Word"(%0 : $Builtin.Word) : $Builtin.RawPointer
976+
%2 = builtin "ptrtoint_Word"(%1 : $Builtin.RawPointer) : $Builtin.Word
977+
return %2 : $Builtin.Word
978+
}
979+
980+
// CHECK-LABEL: sil @string_ptr_to_int_round_trip_no_match : $@convention(thin) () -> Builtin.Int32 {
981+
// CHECK: builtin
982+
// CHECK: builtin
983+
// CHECK: } // end sil function 'string_ptr_to_int_round_trip_no_match'
984+
sil @string_ptr_to_int_round_trip_no_match : $@convention(thin) () -> Builtin.Int32 {
985+
bb0:
986+
%0 = integer_literal $Builtin.Word, 0
987+
%1 = builtin "inttoptr_Word"(%0 : $Builtin.Word) : $Builtin.RawPointer
988+
%2 = builtin "ptrtoint_Int32"(%1 : $Builtin.RawPointer) : $Builtin.Int32
989+
return %2 : $Builtin.Int32
990+
}

0 commit comments

Comments
 (0)