Skip to content

Commit dc3c191

Browse files
committed
PMO: Don't block pmo for large types - rather only block expansion of tuples
1 parent 6755d0e commit dc3c191

File tree

6 files changed

+52
-39
lines changed

6 files changed

+52
-39
lines changed

Diff for: include/swift/SIL/InstructionUtils.h

+6
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ bool visitExplodedTupleValue(SILValue value,
236236
std::pair<SILFunction *, SILWitnessTable *>
237237
lookUpFunctionInWitnessTable(WitnessMethodInst *wmi, SILModule::LinkingMode linkingMode);
238238

239+
/// True if a type can be expanded without a significant increase to code size.
240+
///
241+
/// False if expanding a type is invalid. For example, expanding a
242+
/// struct-with-deinit drops the deinit.
243+
bool shouldExpand(SILModule &module, SILType ty);
244+
239245
} // end namespace swift
240246

241247
#endif

Diff for: include/swift/SILOptimizer/Utils/InstOptUtils.h

-6
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,6 @@ ignore_expect_uses(ValueBase *value) {
417417
/// operations from it. These can be simplified and removed.
418418
bool simplifyUsers(SingleValueInstruction *inst);
419419

420-
/// True if a type can be expanded without a significant increase to code size.
421-
///
422-
/// False if expanding a type is invalid. For example, expanding a
423-
/// struct-with-deinit drops the deinit.
424-
bool shouldExpand(SILModule &module, SILType ty);
425-
426420
/// Check if the value of value is computed by means of a simple initialization.
427421
/// Store the actual SILValue into \p Val and the reversed list of instructions
428422
/// initializing it in \p Insns.

Diff for: lib/SIL/Utils/InstructionUtils.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@
2727
#include "swift/SIL/SILVisitor.h"
2828

2929
#include "clang/AST/DeclObjC.h"
30+
#include "llvm/Support/CommandLine.h"
3031

3132
using namespace swift;
3233

34+
static llvm::cl::opt<bool> EnableExpandAll("enable-expand-all",
35+
llvm::cl::init(false));
36+
37+
3338
SILValue swift::lookThroughOwnershipInsts(SILValue v) {
3439
while (true) {
3540
switch (v->getKind()) {
@@ -1411,3 +1416,29 @@ swift::lookUpFunctionInWitnessTable(WitnessMethodInst *wmi,
14111416
return mod.lookUpFunctionInWitnessTable(wmi->getConformance(), wmi->getMember(),
14121417
wmi->isSpecialized(), linkingMode);
14131418
}
1419+
1420+
// True if a type can be expanded without a significant increase to code size.
1421+
//
1422+
// False if expanding a type is invalid. For example, expanding a
1423+
// struct-with-deinit drops the deinit.
1424+
bool swift::shouldExpand(SILModule &module, SILType ty) {
1425+
// FIXME: Expansion
1426+
auto expansion = TypeExpansionContext::minimal();
1427+
1428+
if (module.Types.getTypeLowering(ty, expansion).isAddressOnly()) {
1429+
return false;
1430+
}
1431+
// A move-only-with-deinit type cannot be SROA.
1432+
//
1433+
// TODO: we could loosen this requirement if all paths lead to a drop_deinit.
1434+
if (auto *nominalTy = ty.getNominalOrBoundGenericNominal()) {
1435+
if (nominalTy->getValueTypeDestructor())
1436+
return false;
1437+
}
1438+
if (EnableExpandAll) {
1439+
return true;
1440+
}
1441+
1442+
unsigned numFields = module.Types.countNumberOfFields(ty, expansion);
1443+
return (numFields <= 6);
1444+
}

Diff for: lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,14 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
286286
continue;
287287
}
288288

289+
auto &mod = User->getFunction()->getModule();
290+
bool shouldScalarizeTuple =
291+
!mod.getOptions().UseAggressiveReg2MemForCodeSize ||
292+
shouldExpand(mod, PointeeType);
293+
289294
// Loads are a use of the value.
290295
if (isa<LoadInst>(User) || isa<LoadBorrowInst>(User)) {
291-
if (PointeeType.is<TupleType>())
296+
if (PointeeType.is<TupleType>() && shouldScalarizeTuple)
292297
UsesToScalarize.push_back(User);
293298
else
294299
Uses.emplace_back(User, PMOUseKind::Load);
@@ -300,7 +305,8 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
300305
if (UI->getOperandNumber() == StoreInst::Dest) {
301306
if (auto tupleType = PointeeType.getAs<TupleType>()) {
302307
if (!tupleType->isEqual(Module.getASTContext().TheEmptyTupleType) &&
303-
!tupleType->containsPackExpansionType()) {
308+
!tupleType->containsPackExpansionType() &&
309+
shouldScalarizeTuple) {
304310
UsesToScalarize.push_back(User);
305311
continue;
306312
}
@@ -337,7 +343,8 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
337343
// have an access that crosses elements.
338344
if (auto tupleType = PointeeType.getAs<TupleType>()) {
339345
if (!tupleType->isEqual(Module.getASTContext().TheEmptyTupleType) &&
340-
!tupleType->containsPackExpansionType()) {
346+
!tupleType->containsPackExpansionType() &&
347+
shouldScalarizeTuple) {
341348
UsesToScalarize.push_back(CAI);
342349
continue;
343350
}

Diff for: lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838

3939
using namespace swift;
4040

41+
static llvm::cl::opt<bool> EnableAggressiveExpansionBlocking(
42+
"enable-aggressive-expansion-blocking", llvm::cl::init(false));
43+
4144
STATISTIC(NumLoadPromoted, "Number of loads promoted");
4245
STATISTIC(NumLoadTakePromoted, "Number of load takes promoted");
4346
STATISTIC(NumDestroyAddrPromoted, "Number of destroy_addrs promoted");
@@ -3156,7 +3159,8 @@ static AllocationInst *getOptimizableAllocation(SILInstruction *i) {
31563159

31573160
// Don't promote large types.
31583161
auto &mod = alloc->getFunction()->getModule();
3159-
if (mod.getOptions().UseAggressiveReg2MemForCodeSize &&
3162+
if (EnableAggressiveExpansionBlocking &&
3163+
mod.getOptions().UseAggressiveReg2MemForCodeSize &&
31603164
!shouldExpand(mod, alloc->getType().getObjectType()))
31613165
return nullptr;
31623166

Diff for: lib/SILOptimizer/Utils/InstOptUtils.cpp

-29
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949

5050
using namespace swift;
5151

52-
static llvm::cl::opt<bool> EnableExpandAll("enable-expand-all",
53-
llvm::cl::init(false));
54-
5552
static llvm::cl::opt<bool> KeepWillThrowCall(
5653
"keep-will-throw-call", llvm::cl::init(false),
5754
llvm::cl::desc(
@@ -1269,32 +1266,6 @@ bool swift::simplifyUsers(SingleValueInstruction *inst) {
12691266
return changed;
12701267
}
12711268

1272-
// True if a type can be expanded without a significant increase to code size.
1273-
//
1274-
// False if expanding a type is invalid. For example, expanding a
1275-
// struct-with-deinit drops the deinit.
1276-
bool swift::shouldExpand(SILModule &module, SILType ty) {
1277-
// FIXME: Expansion
1278-
auto expansion = TypeExpansionContext::minimal();
1279-
1280-
if (module.Types.getTypeLowering(ty, expansion).isAddressOnly()) {
1281-
return false;
1282-
}
1283-
// A move-only-with-deinit type cannot be SROA.
1284-
//
1285-
// TODO: we could loosen this requirement if all paths lead to a drop_deinit.
1286-
if (auto *nominalTy = ty.getNominalOrBoundGenericNominal()) {
1287-
if (nominalTy->getValueTypeDestructor())
1288-
return false;
1289-
}
1290-
if (EnableExpandAll) {
1291-
return true;
1292-
}
1293-
1294-
unsigned numFields = module.Types.countNumberOfFields(ty, expansion);
1295-
return (numFields <= 6);
1296-
}
1297-
12981269
/// Some support functions for the global-opt and let-properties-opts
12991270

13001271
// Encapsulate the state used for recursive analysis of a static

0 commit comments

Comments
 (0)