Skip to content

Commit 31c89a5

Browse files
authored
Merge pull request #1279 from swiftwasm/master
[pull] swiftwasm from master
2 parents 8bd68b3 + 1902ff2 commit 31c89a5

File tree

16 files changed

+1515
-28
lines changed

16 files changed

+1515
-28
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,12 @@ class SILInstruction
375375
/// The instruction may read memory.
376376
MayRead,
377377
/// The instruction may write to memory.
378+
/// This includes destroying or taking from memory (e.g. destroy_addr,
379+
/// copy_addr [take], load [take]).
380+
/// Although, physically, destroying or taking does not modify the memory,
381+
/// it is important to model it is a write. Optimizations must not assume
382+
/// that the value stored in memory is still available for loading after
383+
/// the memory is destroyed or taken.
378384
MayWrite,
379385
/// The instruction may read or write memory.
380386
MayReadWrite,

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ PASS(PerformanceSILLinker, "performance-linker",
283283
"Deserialize all referenced SIL functions")
284284
PASS(RawSILInstLowering, "raw-sil-inst-lowering",
285285
"Lower all raw SIL instructions to canonical equivalents.")
286+
PASS(TempLValueOpt, "temp-lvalue-opt",
287+
"Remove short-lived immutable temporary l-values")
286288
PASS(TempRValueOpt, "temp-rvalue-opt",
287289
"Remove short-lived immutable temporary copies")
288290
PASS(SideEffectsDumper, "side-effects-dump",

lib/SILOptimizer/Analysis/AliasAnalysis.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,15 @@ AliasResult AliasAnalysis::alias(SILValue V1, SILValue V2,
569569
return Result;
570570
}
571571

572+
/// Get the underlying object, looking through init_enum_data_addr and
573+
/// init_existential_addr.
574+
static SILValue stripInitEnumAndExistentialAddr(SILValue v) {
575+
while (isa<InitEnumDataAddrInst>(v) || isa<InitExistentialAddrInst>(v)) {
576+
v = getUnderlyingObject(cast<SingleValueInstruction>(v)->getOperand(0));
577+
}
578+
return v;
579+
}
580+
572581
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt
573582
/// to disambiguate the two values.
574583
AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
@@ -614,9 +623,12 @@ AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
614623
LLVM_DEBUG(llvm::dbgs() << " Underlying V1:" << *O1);
615624
LLVM_DEBUG(llvm::dbgs() << " Underlying V2:" << *O2);
616625

617-
// If O1 and O2 do not equal, see if we can prove that they cannot be the
618-
// same object. If we can, return No Alias.
619-
if (O1 != O2 && aliasUnequalObjects(O1, O2))
626+
// If the underlying objects are not equal, see if we can prove that they
627+
// cannot be the same object. If we can, return No Alias.
628+
// For this we even look through init_enum_data_addr and init_existential_addr.
629+
SILValue StrippedO1 = stripInitEnumAndExistentialAddr(O1);
630+
SILValue StrippedO2 = stripInitEnumAndExistentialAddr(O2);
631+
if (StrippedO1 != StrippedO2 && aliasUnequalObjects(StrippedO1, StrippedO2))
620632
return AliasResult::NoAlias;
621633

622634
// Ok, either O1, O2 are the same or we could not prove anything based off of

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class MemoryBehaviorVisitor
174174

175175
MemBehavior visitLoadInst(LoadInst *LI);
176176
MemBehavior visitStoreInst(StoreInst *SI);
177+
MemBehavior visitCopyAddrInst(CopyAddrInst *CAI);
177178
MemBehavior visitApplyInst(ApplyInst *AI);
178179
MemBehavior visitTryApplyInst(TryApplyInst *AI);
179180
MemBehavior visitBuiltinInst(BuiltinInst *BI);
@@ -245,6 +246,10 @@ MemBehavior MemoryBehaviorVisitor::visitLoadInst(LoadInst *LI) {
245246
if (!mayAlias(LI->getOperand()))
246247
return MemBehavior::None;
247248

249+
// A take is modelled as a write. See MemoryBehavior::MayWrite.
250+
if (LI->getOwnershipQualifier() == LoadOwnershipQualifier::Take)
251+
return MemBehavior::MayReadWrite;
252+
248253
LLVM_DEBUG(llvm::dbgs() << " Could not prove that load inst does not alias "
249254
"pointer. Returning may read.\n");
250255
return MemBehavior::MayRead;
@@ -268,6 +273,34 @@ MemBehavior MemoryBehaviorVisitor::visitStoreInst(StoreInst *SI) {
268273
return MemBehavior::MayWrite;
269274
}
270275

276+
MemBehavior MemoryBehaviorVisitor::visitCopyAddrInst(CopyAddrInst *CAI) {
277+
// If it's an assign to the destination, a destructor might be called on the
278+
// old value. This can have any side effects.
279+
// We could also check if it's a trivial type (which cannot have any side
280+
// effect on destruction), but such copy_addr instructions are optimized to
281+
// load/stores anyway, so it's probably not worth it.
282+
if (!CAI->isInitializationOfDest())
283+
return MemBehavior::MayHaveSideEffects;
284+
285+
bool mayWrite = mayAlias(CAI->getDest());
286+
bool mayRead = mayAlias(CAI->getSrc());
287+
288+
if (mayRead) {
289+
if (mayWrite)
290+
return MemBehavior::MayReadWrite;
291+
292+
// A take is modelled as a write. See MemoryBehavior::MayWrite.
293+
if (CAI->isTakeOfSrc())
294+
return MemBehavior::MayReadWrite;
295+
296+
return MemBehavior::MayRead;
297+
}
298+
if (mayWrite)
299+
return MemBehavior::MayWrite;
300+
301+
return MemBehavior::None;
302+
}
303+
271304
MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) {
272305
// If our callee is not a builtin, be conservative and return may have side
273306
// effects.

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ void addFunctionPasses(SILPassPipelinePlan &P,
283283
// splits up copy_addr.
284284
P.addCopyForwarding();
285285

286+
// Optimize copies from a temporary (an "l-value") to a destination.
287+
P.addTempLValueOpt();
288+
286289
// Split up opaque operations (copy_addr, retain_value, etc.).
287290
P.addLowerAggregateInstrs();
288291

lib/SILOptimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ target_sources(swiftSILOptimizer PRIVATE
3838
Sink.cpp
3939
SpeculativeDevirtualizer.cpp
4040
StackPromotion.cpp
41+
TempLValueOpt.cpp
4142
TempRValueElimination.cpp
4243
UnsafeGuaranteedPeephole.cpp)

0 commit comments

Comments
 (0)