Skip to content

Commit 681e226

Browse files
committed
[WIP]: try to fix things & add many debug logs
1 parent d0e519f commit 681e226

File tree

4 files changed

+134
-2
lines changed

4 files changed

+134
-2
lines changed

lib/SILGen/SILGenDecl.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include "llvm/Support/ErrorHandling.h"
4141
#include <iterator>
4242

43+
#define DEBUG_TYPE "SILGenDecl"
44+
4345
using namespace swift;
4446
using namespace Lowering;
4547

@@ -781,6 +783,7 @@ class LetValueInitialization : public Initialization {
781783
// There are four cases we need to handle here: parameters, initialized (or
782784
// bound) decls, uninitialized ones, and async let declarations.
783785
bool needsTemporaryBuffer;
786+
bool isUninitialized = false;
784787

785788
assert(!isa<ParamDecl>(vd)
786789
&& "should not bind function params on this path");
@@ -789,12 +792,14 @@ class LetValueInitialization : public Initialization {
789792
// If this is a let-value without an initializer, then we need a temporary
790793
// buffer. DI will make sure it is only assigned to once.
791794
needsTemporaryBuffer = true;
795+
isUninitialized = true;
792796
} else if (vd->isAsyncLet()) {
793797
// If this is an async let, treat it like a let-value without an
794798
// initializer. The initializer runs concurrently in a child task,
795799
// and value will be initialized at the point the variable in the
796800
// async let is used.
797801
needsTemporaryBuffer = true;
802+
isUninitialized = true;
798803
} else {
799804
// If this is a let with an initializer or bound value, we only need a
800805
// buffer if the type is address only or is noncopyable.
@@ -805,6 +810,12 @@ class LetValueInitialization : public Initialization {
805810
lowering->getLoweredType().isMoveOnly(/*orWrapped=*/false);
806811
}
807812

813+
// auto parentInit = vd->getParentInitializer();
814+
// if (isa<CallExpr>(parentInit)) {
815+
// auto fn = cast<CallExpr>(parentInit)->getSemanticFn();
816+
// isUninitialized = isa<AbstractClosureExpr>(fn);
817+
// }
818+
808819
// Make sure that we have a non-address only type when binding a
809820
// @_noImplicitCopy let.
810821
if (lowering->isAddressOnly() && vd->isNoImplicitCopy()) {
@@ -813,6 +824,10 @@ class LetValueInitialization : public Initialization {
813824
}
814825

815826
if (needsTemporaryBuffer) {
827+
LLVM_DEBUG({
828+
llvm::dbgs() << "JQ: need tmp buffer\n";
829+
vd->dump(llvm::dbgs());
830+
});
816831
bool lexicalLifetimesEnabled =
817832
SGF.getASTContext().SILOpts.supportsLexicalLifetimes(SGF.getModule());
818833
auto lifetime = SGF.F.getLifetime(vd, lowering->getLoweredType());
@@ -824,7 +839,8 @@ class LetValueInitialization : public Initialization {
824839

825840
// Ensure DI always checks this to avoid cases where an address-only
826841
// value is referenced in a closure that is part of its initializer.
827-
address = SGF.B.createMarkUninitializedVar(vd, address);
842+
if (true || isUninitialized)
843+
address = SGF.B.createMarkUninitializedVar(vd, address);
828844

829845
DestroyCleanup = SGF.enterDormantTemporaryCleanup(address, *lowering);
830846
SGF.VarLocs[vd] = SILGenFunction::VarLoc(address,
@@ -834,7 +850,7 @@ class LetValueInitialization : public Initialization {
834850
// inactive until the variable is initialized: if control flow exits the
835851
// before the value is bound, we don't want to destroy the value.
836852
//
837-
// Cleanups are required for all lexically scoped variables to delimite
853+
// Cleanups are required for all lexically scoped variables to delimit
838854
// the variable scope, even if the cleanup does nothing.
839855
SGF.Cleanups.pushCleanupInState<DestroyLocalVariable>(
840856
CleanupState::Dormant, vd);

lib/SILGen/SILGenFunction.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,16 @@ void SILGenFunction::emitCaptures(SILLocation loc,
590590
break;
591591
}
592592

593+
LLVM_DEBUG({
594+
llvm::dbgs() << "JQ: emit captures running\n";
595+
for (auto capture : captureInfo.getCaptures()) {
596+
llvm::dbgs() << " cap: '" << capture.getDecl()->getName() << "'\n";
597+
}
598+
llvm::dbgs()
599+
<< " canGuarantee: '" << canGuarantee << "'\n"
600+
<< " capCanEscape: '" << captureCanEscape << "'\n";
601+
});
602+
593603
auto expansion = getTypeExpansionContext();
594604

595605
for (auto capture : captureInfo.getCaptures()) {
@@ -609,6 +619,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
609619
if (capture.isOpaqueValue() || capture.isPackElement()) {
610620
capturedArgs.push_back(
611621
emitRValueAsSingleValue(capture.getExpr()).ensurePlusOne(*this, loc));
622+
LLVM_DEBUG(llvm::dbgs() << "JQ: cap emit early ret: opaque || pack\n");
612623
continue;
613624
}
614625

@@ -632,6 +643,52 @@ void SILGenFunction::emitCaptures(SILLocation loc,
632643
auto valueType = FunctionDC->mapTypeIntoContext(
633644
interfaceType->getReferenceStorageReferent());
634645

646+
LLVM_DEBUG(
647+
{
648+
llvm::dbgs() << "=== DEBUG: VarLocs contents for capture of '"
649+
<< vd->getBaseIdentifier() << "' ===\n";
650+
llvm::dbgs() << "Total entries in VarLocs: " << VarLocs.size() << "\n";
651+
652+
for (auto &entry : VarLocs) {
653+
auto *var = entry.first;
654+
auto &loc = entry.second;
655+
656+
llvm::dbgs() << " - Variable: " << var->getBaseIdentifier() << "\n";
657+
// llvm::errs() << " Type: " << var->getType() << "\n";
658+
llvm::dbgs() << " Value type: " << loc.value->getType() << "\n";
659+
llvm::dbgs() << " Value kind: ";
660+
661+
if (isa<SILUndef>(loc.value)) {
662+
llvm::dbgs() << "SILUndef (UNINITIALIZED)\n";
663+
} else if (isa<SILArgument>(loc.value)) {
664+
llvm::dbgs() << "SILArgument\n";
665+
} else if (isa<AllocStackInst>(loc.value)) {
666+
llvm::dbgs() << "AllocStackInst\n";
667+
} else if (isa<AllocBoxInst>(loc.value)) {
668+
llvm::dbgs() << "AllocBoxInst\n";
669+
} else {
670+
llvm::dbgs() << "some other inst\n";
671+
}
672+
673+
if (loc.box) {
674+
llvm::dbgs() << " Has box: yes\n";
675+
}
676+
677+
llvm::dbgs() << "\n";
678+
}
679+
680+
llvm::dbgs() << "Looking for variable: " << vd->getBaseIdentifier() << "\n";
681+
auto found = VarLocs.find(vd);
682+
if (found == VarLocs.end()) {
683+
llvm::dbgs() << " Result: NOT FOUND in VarLocs\n";
684+
} else {
685+
llvm::dbgs() << " Result: FOUND in VarLocs\n";
686+
llvm::dbgs() << " Value is undef: "
687+
<< (isa<SILUndef>(found->second.value) ? "YES" : "NO") << "\n";
688+
}
689+
llvm::dbgs() << "===================================\n\n";
690+
});
691+
635692
//
636693
// If we haven't emitted the captured value yet, we're forming a closure
637694
// to a local function before all of its captures have been emitted. Eg,
@@ -695,6 +752,12 @@ void SILGenFunction::emitCaptures(SILLocation loc,
695752
// expansion context without opaque archetype substitution.
696753
auto getAddressValue = [&](SILValue entryValue, bool forceCopy,
697754
bool forLValue) -> SILValue {
755+
LLVM_DEBUG({
756+
llvm::dbgs() << "JQ: get addr value, force copy: " << forceCopy
757+
<< ", for lval: " << forLValue << "\n";
758+
entryValue->getDefiningInstruction()->print(llvm::dbgs());
759+
});
760+
698761
if (!SGM.M.useLoweredAddresses() && !forLValue && !isPack) {
699762
// In opaque values mode, addresses aren't used except by lvalues.
700763
auto &lowering = getTypeLowering(entryValue->getType());
@@ -775,6 +838,11 @@ void SILGenFunction::emitCaptures(SILLocation loc,
775838
auto &Entry = found->second;
776839
auto val = Entry.value;
777840

841+
LLVM_DEBUG({
842+
auto capKind = SGM.Types.getDeclCaptureKind(capture, expansion);
843+
llvm::dbgs() << "JQ: cap kind:: " << (unsigned)capKind << "\n";
844+
});
845+
778846
switch (SGM.Types.getDeclCaptureKind(capture, expansion)) {
779847
case CaptureKind::Constant: {
780848
assert(!isPack);
@@ -855,6 +923,12 @@ void SILGenFunction::emitCaptures(SILLocation loc,
855923
}
856924
capturedArgs.push_back(ManagedValue::forOwnedAddressRValue(
857925
addr, CleanupHandle::invalid()));
926+
927+
// LLVM_DEBUG({
928+
// llvm::dbgs() << "JQ: adding escape to mark for: \n";
929+
// val->getDefiningInstruction()->print(llvm::dbgs());
930+
// });
931+
// escapesToMark.push_back(val);
858932
}
859933
break;
860934
}

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,27 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
823823
continue;
824824
}
825825

826+
if (false || (isa<UnconditionalCheckedCastAddrInst>(User) ||
827+
isa<CheckedCastAddrBranchInst>(User))) {
828+
LLVM_DEBUG({
829+
llvm::dbgs() << "JQ: DI found unchecked addr cast:\n"
830+
<< Op;
831+
});
832+
833+
DIUseKind Kind;
834+
Kind = DIUseKind::Initialization;
835+
// if (Op->getOperandNumber() == 0)
836+
// Kind = DIUseKind::Load;
837+
// else
838+
// Kind = InStructSubElement ? DIUseKind::PartialStore
839+
// : DIUseKind::Initialization;
840+
841+
// TODO: what about enum sub elt? do we need to even special case things here?
842+
843+
addElementUses(BaseEltNo, PointeeType, User, Kind);
844+
continue;
845+
}
846+
826847
// Look through mark_unresolved_non_copyable_value. To us, it is not
827848
// interesting.
828849
if (auto *mmi = dyn_cast<MarkUnresolvedNonCopyableValueInst>(User)) {

test/SILOptimizer/definite_init_address_only_let.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,25 @@ func uninit_closure_reference() {
4848
let initMe = passthrough { initMe }
4949
// expected-error @-1 {{constant 'initMe' used before being initialized}}
5050
// expected-note @-2 {{defined here}}
51+
52+
let inline = { () -> Any in inline }()
53+
// expected-error @-1 {{constant 'inline' used before being initialized}}
54+
// expected-note @-2 {{defined here}}
55+
56+
// these should not regress
57+
func castAny(_ a: Any) {
58+
let directUncond = a as! Int
59+
_ = directUncond
60+
61+
let directCond = a as? Int
62+
_ = directCond
63+
64+
let twoPhaseUncond: Int
65+
twoPhaseUncond = a as! Int
66+
_ = twoPhaseUncond
67+
68+
let twoPhasCond: Int?
69+
twoPhasCond = a as? Int
70+
_ = twoPhasCond
71+
}
5172
}

0 commit comments

Comments
 (0)