Skip to content

Commit 9e6f80f

Browse files
authored
Merge pull request #63240 from atrick/5.8-revert-debugfix
[5.8] Revert "At -Onone preserve debug info after splitting loads"
2 parents c89d777 + 15f4101 commit 9e6f80f

File tree

3 files changed

+13
-122
lines changed

3 files changed

+13
-122
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,16 +1909,14 @@ class AccessUseDefChainCloner
19091909
/// Clone all projections and casts on the access use-def chain until the
19101910
/// checkBase predicate returns a valid base.
19111911
///
1912-
/// Returns the cloned value equivalent to \p addr.
1913-
///
19141912
/// This will not clone ref_element_addr or ref_tail_addr because those aren't
19151913
/// part of the access chain.
19161914
///
19171915
/// CheckBase is a unary predicate that takes the next source address and either
19181916
/// returns a valid SILValue to use as the base of the cloned access path, or an
19191917
/// invalid SILValue to continue cloning.
19201918
///
1921-
/// CheckBase must return a valid SILValue before attempting to clone the
1919+
/// CheckBase must return a valid SILValue either before attempting to clone the
19221920
/// access base. The most basic valid predicate is:
19231921
///
19241922
/// auto checkBase = [&](SILValue srcAddr) {
@@ -1933,8 +1931,6 @@ SILValue cloneUseDefChain(SILValue addr, SILInstruction *insertionPoint,
19331931

19341932
/// Analog to cloneUseDefChain to check validity. begin_borrow and
19351933
/// mark_dependence currently cannot be cloned.
1936-
///
1937-
/// Returns the cloned value equivalent to \p addr.
19381934
template <typename CheckBase>
19391935
bool canCloneUseDefChain(SILValue addr, CheckBase checkBase) {
19401936
return AccessUseDefChainCloner<CheckBase>(checkBase, nullptr)

lib/SILOptimizer/Utils/CanonicalizeInstruction.cpp

Lines changed: 12 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "swift/SILOptimizer/Utils/CanonicalizeInstruction.h"
2222
#include "swift/SIL/DebugUtils.h"
2323
#include "swift/SIL/InstructionUtils.h"
24-
#include "swift/SIL/MemAccessUtils.h"
2524
#include "swift/SIL/Projection.h"
2625
#include "swift/SIL/SILBuilder.h"
2726
#include "swift/SIL/SILFunction.h"
@@ -138,77 +137,6 @@ static void replaceUsesOfExtract(SingleValueInstruction *extract,
138137
extract->replaceAllUsesWith(loadedVal);
139138
}
140139

141-
// If \p loadInst has an debug uses, then move it into a separate unsafe access
142-
// scope. This hides it from the exclusivity checker.
143-
//
144-
// If \p loadInst was successfully hidden, then this returns the next
145-
// instruction following \p loadInst and following any newly inserted
146-
// instructions. Otherwise this returns nullptr. Returning nullptr is a signal
147-
// to delete \p loadInst.
148-
//
149-
// Before:
150-
//
151-
// %a = begin_access %0 [read] [unknown]
152-
// %proj = some_projections %a
153-
// %whole = load %proj // <-- loadInst
154-
// %field = struct_element_addr %proj, #field
155-
// %part = load %field
156-
//
157-
// After:
158-
//
159-
// %a = begin_access %0 [read] [unknown]
160-
// %proj = some_projections %a
161-
// %a2 = begin_access %0 [read] [unsafe] // NEW
162-
// %proj2 = some_projections %a // CLONED
163-
// %whole = load %proj2 // <-- loadInst
164-
// end_access %a2 // NEW
165-
// %field = struct_element_addr %proj, #field
166-
// %part = load %field
167-
//
168-
static SILInstruction *
169-
moveLoadToUnsafeAccessScope(LoadInst *loadInst,
170-
CanonicalizeInstruction &pass) {
171-
if (llvm::none_of(loadInst->getUses(), [](Operand *use) {
172-
return use->getUser()->isDebugInstruction();
173-
})) {
174-
return nullptr;
175-
}
176-
SILValue accessScope = getAccessScope(loadInst->getOperand());
177-
auto *access = dyn_cast<BeginAccessInst>(accessScope);
178-
if (access && access->getEnforcement() == SILAccessEnforcement::Unsafe)
179-
return nullptr;
180-
181-
auto checkBaseAddress = [=](SILValue addr) {
182-
if (addr != accessScope)
183-
return SILValue();
184-
185-
// the base of the new unsafe scope
186-
if (access)
187-
return access->getOperand();
188-
189-
return accessScope;
190-
};
191-
192-
if (!canCloneUseDefChain(loadInst->getOperand(), checkBaseAddress))
193-
return nullptr;
194-
195-
SILValue newBase =
196-
cloneUseDefChain(loadInst->getOperand(), loadInst, checkBaseAddress);
197-
198-
auto *beginUnsafe = SILBuilderWithScope(loadInst).createBeginAccess(
199-
loadInst->getLoc(), newBase, SILAccessKind::Read,
200-
SILAccessEnforcement::Unsafe, true, false);
201-
loadInst->setOperand(beginUnsafe);
202-
auto nextInst = loadInst->getNextInstruction();
203-
auto *endUnsafe = SILBuilderWithScope(nextInst).createEndAccess(
204-
loadInst->getLoc(), beginUnsafe, false);
205-
206-
pass.notifyNewInstruction(beginUnsafe);
207-
pass.notifyNewInstruction(endUnsafe);
208-
209-
return nextInst;
210-
}
211-
212140
// Given a load with multiple struct_extracts/tuple_extracts and no other uses,
213141
// canonicalize the load into several (struct_element_addr (load)) pairs.
214142
//
@@ -373,9 +301,16 @@ splitAggregateLoad(LoadOperation loadInst, CanonicalizeInstruction &pass) {
373301
}
374302
pass.notifyNewInstruction(**lastNewLoad);
375303

376-
// FIXME: At -O, create "debug fragments" recover as much debug info as
377-
// possible by creating debug_value fragments for each new partial
378-
// load. Currently disabled because it caused on LLVM back-end crash.
304+
// FIXME: This drops debug info at -Onone load-splitting is required at
305+
// -Onone for exclusivity diagnostics. Fix this by
306+
//
307+
// 1. At -Onone, preserve the original load when pass.preserveDebugInfo is
308+
// true, but moving it out of its current access scope and into an "unknown"
309+
// access scope, which won't be enforced as an exclusivity violation.
310+
//
311+
// 2. At -O, create "debug fragments" recover as much debug info as possible
312+
// by creating debug_value fragments for each new partial load. Currently
313+
// disabled because of LLVM back-end crashes.
379314
if (!pass.preserveDebugInfo && EnableLoadSplittingDebugInfo) {
380315
createDebugFragments(*loadInst, proj, lastNewLoad->getLoadInst());
381316
}
@@ -405,23 +340,13 @@ splitAggregateLoad(LoadOperation loadInst, CanonicalizeInstruction &pass) {
405340
for (auto *borrow : borrows)
406341
nextII = killInstAndIncidentalUses(borrow, nextII, pass);
407342

408-
// When pass.preserveDebugInfo is true, keep the original load so that debug
409-
// info refers to the loaded value, rather than a memory location which may
410-
// not be reused. Move the wide load out of its current access scope and into
411-
// an "unknown" access scope, which won't be enforced as an exclusivity
412-
// violation.
413-
if (pass.preserveDebugInfo) {
414-
if (auto *regularLoad = dyn_cast<LoadInst>(loadInst.getLoadInst())) {
415-
if (auto *nextInst = moveLoadToUnsafeAccessScope(regularLoad, pass))
416-
return nextInst->getIterator();
417-
}
418-
}
419343
// Erase the old load.
420344
for (auto *destroy : lifetimeEndingInsts)
421345
nextII = killInstruction(destroy, nextII, pass);
422346

423347
// FIXME: remove this temporary hack to advance the iterator beyond
424-
// debug_value.
348+
// debug_value. A soon-to-be merged commit migrates CanonicalizeInstruction to
349+
// use InstructionDeleter.
425350
while (nextII != loadInst->getParent()->end()
426351
&& nextII->isDebugInstruction()) {
427352
++nextII;

test/SILOptimizer/silgen_cleanup.sil

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -362,33 +362,3 @@ bb9(%0 : @owned $Klass):
362362
destroy_value %0 : $Klass
363363
return %v : $Builtin.Int64
364364
}
365-
366-
// debug_value must be preserved after splitting loads
367-
368-
struct IntWrapper {
369-
var _value : Int
370-
}
371-
372-
sil_scope 5 { loc "./test.swift":3:6 parent @testSplitLoadDebug : $@convention(thin) (@in_guaranteed IntWrapper) -> Builtin.Int32 }
373-
sil_scope 6 { loc "./test.swift":3:10 parent 5 }
374-
375-
// CHECK-LABEL: sil hidden [ossa] @testSplitLoadDebug : $@convention(thin) (@in_guaranteed IntWrapper) -> Builtin.Int32 {
376-
// CHECK: bb0(%0 : $*IntWrapper):
377-
// CHECKDEB: [[A1:%.*]] = struct_element_addr %0 : $*IntWrapper, #IntWrapper._value
378-
// CHECKDEB: [[A2:%.*]] = struct_element_addr [[A1]] : $*Int, #Int._value
379-
// CHECKDEB: [[SPLIT:%.*]] = load [trivial] %2 : $*Builtin.Int32
380-
// CHECKDEB: [[A3:%.*]] = struct_element_addr %0 : $*IntWrapper, #IntWrapper._value
381-
// CHECKDEB: [[A4:%.*]] = begin_access [read] [unsafe] [no_nested_conflict] [[A3]] : $*Int
382-
// CHECKDEB: [[OLD:%.*]] = load [trivial] [[A4]] : $*Int
383-
// CHECKDEB: end_access [[A4]] : $*Int
384-
// CHECKDEB: debug_value [[OLD]] : $Int, let, name "flag"
385-
// CHECKDEB: return [[SPLIT]] : $Builtin.Int32
386-
// CHECK-LABEL: } // end sil function 'testSplitLoadDebug'
387-
sil hidden [ossa] @testSplitLoadDebug : $@convention(thin) (@in_guaranteed IntWrapper) -> Builtin.Int32 {
388-
bb0(%0: $*IntWrapper):
389-
%1 = struct_element_addr %0 : $*IntWrapper, #IntWrapper._value
390-
%2 = load [trivial] %1 : $*Int
391-
debug_value %2 : $Int, let, name "flag", loc "./test.swift":4:7, scope 6
392-
%4 = struct_extract %2 : $Int, #Int._value
393-
return %4 : $Builtin.Int32
394-
}

0 commit comments

Comments
 (0)