Skip to content

Commit 2a03543

Browse files
committed
SILOptimizer: make a separate SROA pass for high-level SIL, which doesn't split String types.
The StringOptimization relies on seeing String values a a whole and not being split.
1 parent 568c156 commit 2a03543

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ PASS(SILCombine, "sil-combine",
299299
"Combine SIL Instructions via Peephole Optimization")
300300
PASS(SILDebugInfoGenerator, "sil-debuginfo-gen",
301301
"Generate Debug Information with Source Locations into Textual SIL")
302+
PASS(EarlySROA, "early-sroa",
303+
"Scalar Replacement of Aggregate Stack Objects on high-level SIL")
302304
PASS(SROA, "sroa",
303305
"Scalar Replacement of Aggregate Stack Objects")
304306
PASS(SROABBArgs, "sroa-bb-args",

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ void addHighLevelLoopOptPasses(SILPassPipelinePlan &P) {
222222
// Perform classic SSA optimizations for cleanup.
223223
P.addLowerAggregateInstrs();
224224
P.addSILCombine();
225-
P.addSROA();
225+
P.addEarlySROA();
226226
P.addMem2Reg();
227227
P.addDCE();
228228
P.addSILCombine();
@@ -290,7 +290,11 @@ void addFunctionPasses(SILPassPipelinePlan &P,
290290
P.addLowerAggregateInstrs();
291291

292292
// Split up operations on stack-allocated aggregates (struct, tuple).
293-
P.addSROA();
293+
if (OpLevel == OptimizationLevelKind::HighLevel) {
294+
P.addEarlySROA();
295+
} else {
296+
P.addSROA();
297+
}
294298

295299
// Promote stack allocations to values.
296300
P.addMem2Reg();

lib/SILOptimizer/Transforms/SILSROA.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,33 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
301301
eraseFromParentWithDebugInsts(AI);
302302
}
303303

304-
static bool runSROAOnFunction(SILFunction &Fn) {
304+
/// Returns true, if values of \ty should be ignored, because \p ty is known
305+
/// by a high-level SIL optimization. Values of that type must not be split
306+
/// so that those high-level optimizations can analyze the code.
307+
static bool isSemanticType(ASTContext &ctxt, SILType ty) {
308+
NominalTypeDecl *stringDecl = ctxt.getStringDecl();
309+
if (ty.getStructOrBoundGenericStruct() == stringDecl)
310+
return true;
311+
return false;
312+
}
313+
314+
static bool runSROAOnFunction(SILFunction &Fn, bool splitSemanticTypes) {
305315
std::vector<AllocStackInst *> Worklist;
306316
bool Changed = false;
317+
ASTContext &ctxt = Fn.getModule().getASTContext();
307318

308319
// For each basic block BB in Fn...
309320
for (auto &BB : Fn)
310321
// For each instruction in BB...
311322
for (auto &I : BB)
312323
// If the instruction is an alloc stack inst, add it to the worklist.
313-
if (auto *AI = dyn_cast<AllocStackInst>(&I))
324+
if (auto *AI = dyn_cast<AllocStackInst>(&I)) {
325+
if (!splitSemanticTypes && isSemanticType(ctxt, AI->getElementType()))
326+
continue;
327+
314328
if (shouldExpand(Fn.getModule(), AI->getElementType()))
315329
Worklist.push_back(AI);
330+
}
316331

317332
while (!Worklist.empty()) {
318333
AllocStackInst *AI = Worklist.back();
@@ -332,6 +347,11 @@ static bool runSROAOnFunction(SILFunction &Fn) {
332347
namespace {
333348
class SILSROA : public SILFunctionTransform {
334349

350+
bool splitSemanticTypes;
351+
352+
public:
353+
SILSROA(bool splitSemanticTypes) : splitSemanticTypes(splitSemanticTypes) { }
354+
335355
/// The entry point to the transformation.
336356
void run() override {
337357
SILFunction *F = getFunction();
@@ -343,7 +363,7 @@ class SILSROA : public SILFunctionTransform {
343363
LLVM_DEBUG(llvm::dbgs() << "***** SROA on function: " << F->getName()
344364
<< " *****\n");
345365

346-
if (runSROAOnFunction(*F))
366+
if (runSROAOnFunction(*F, splitSemanticTypes))
347367
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
348368
}
349369

@@ -352,5 +372,9 @@ class SILSROA : public SILFunctionTransform {
352372

353373

354374
SILTransform *swift::createSROA() {
355-
return new SILSROA();
375+
return new SILSROA(/*splitSemanticTypes*/ true);
376+
}
377+
378+
SILTransform *swift::createEarlySROA() {
379+
return new SILSROA(/*splitSemanticTypes*/ false);
356380
}

0 commit comments

Comments
 (0)