Skip to content

Commit aa10de2

Browse files
committed
Add load copy support.
1 parent a81572f commit aa10de2

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LoopInvariantCodeMotion.swift

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ private func analyzeInstructions(
165165
analyzedInstructions.loads.append(loadInst)
166166
case let storeInst as StoreInst:
167167
switch storeInst.storeOwnership {
168-
case .assign, .initialize:
168+
case .assign:
169169
continue // TODO: Add support
170-
case .unqualified, .trivial:
170+
case .unqualified, .trivial, .initialize:
171171
break
172172
}
173173
analyzedInstructions.stores.append(storeInst)
@@ -324,8 +324,7 @@ private func collectMovableInstructions(
324324
case let loadInst as LoadInst:
325325
// Avoid quadratic complexity in corner cases. Usually, this limit will not be exceeded.
326326
if loadInstCounter * analyzedInstructions.loopSideEffects.count < 8000,
327-
!analyzedInstructions.loopSideEffectsMayWriteTo(address: loadInst.operand.value, context.aliasAnalysis),
328-
loadInst.loadOwnership != .take, loadInst.loadOwnership != .copy { // TODO: Add support for take and copy loads.
327+
!analyzedInstructions.loopSideEffectsMayWriteTo(address: loadInst.operand.value, context.aliasAnalysis) {
329328
movableInstructions.hoistUp.append(loadInst)
330329
}
331330

@@ -334,9 +333,9 @@ private func collectMovableInstructions(
334333
movableInstructions.loadsAndStores.append(loadInst)
335334
case let storeInst as StoreInst:
336335
switch storeInst.storeOwnership {
337-
case .assign, .initialize:
336+
case .assign:
338337
continue // TODO: Add support
339-
case .unqualified, .trivial:
338+
case .unqualified, .trivial, .initialize:
340339
break
341340
}
342341
movableInstructions.loadsAndStores.append(storeInst)
@@ -861,7 +860,12 @@ private extension Instruction {
861860
if canHoistArraySemanticsCall(to: terminator, context) {
862861
hoistArraySemanticsCall(before: terminator, context)
863862
} else {
864-
move(before: terminator, context)
863+
if let loadCopyInst = self as? LoadInst, loadCopyInst.loadOwnership == .copy {
864+
hoist(loadCopyInst: loadCopyInst, outOf: loop, context)
865+
return true
866+
} else {
867+
move(before: terminator, context)
868+
}
865869
}
866870

867871
if let singleValueInst = self as? SingleValueInstruction,
@@ -879,6 +883,31 @@ private extension Instruction {
879883
return true
880884
}
881885

886+
private func hoist(loadCopyInst: LoadInst, outOf loop: Loop, _ context: FunctionPassContext) {
887+
if loop.hasNoExitBlocks {
888+
return
889+
}
890+
891+
let preheaderBuilder = Builder(before: loop.preheader!.terminator, context)
892+
let preheaderLoadBorrow = preheaderBuilder.createLoadBorrow(fromAddress: loadCopyInst.address)
893+
894+
let headerBuilder = Builder(before: loadCopyInst, context)
895+
let copyValue = headerBuilder.createCopyValue(operand: preheaderLoadBorrow)
896+
loadCopyInst.replace(with: copyValue, context)
897+
898+
var createdEndBorrow: EndBorrowInst?
899+
for exitBlock in loop.exitBlocks {
900+
assert(exitBlock.hasSinglePredecessor, "Exiting edge should not be critical.")
901+
902+
if let createdEndBorrow {
903+
createdEndBorrow.copy(before: exitBlock.instructions.first!, context)
904+
} else {
905+
let exitBlockBuilder = Builder(before: exitBlock.instructions.first!, context)
906+
createdEndBorrow = exitBlockBuilder.createEndBorrow(of: preheaderLoadBorrow)
907+
}
908+
}
909+
}
910+
882911
func sink(outOf loop: Loop, _ context: FunctionPassContext) -> Bool {
883912
let exitBlocks = loop.exitBlocks
884913
var changed = false

test/SILOptimizer/licm.sil

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,8 +1540,11 @@ bb2:
15401540
}
15411541

15421542
// CHECK-LABEL: sil [ossa] @dont_hoist_non_trivial_load :
1543+
// CHECK: %1 = load_borrow %0
15431544
// CHECK: bb1:
1544-
// CHECK-NEXT: load [copy]
1545+
// CHECK-NEXT: %3 = copy_value %1
1546+
// CHECK: bb3:
1547+
// CHECK-NEXT: end_borrow %1
15451548
// CHECK: } // end sil function 'dont_hoist_non_trivial_load'
15461549
sil [ossa] @dont_hoist_non_trivial_load : $@convention(thin) (@inout Builtin.NativeObject) -> () {
15471550
bb0(%0 : $*Builtin.NativeObject):

0 commit comments

Comments
 (0)