Skip to content

Commit 4bcf8f6

Browse files
authored
Merge pull request #17361 from rajbarik/raj-globaladdr-refactor
Extend findInitExistential for cases when ApplySite argument is a global_addr
2 parents 3045067 + 392469a commit 4bcf8f6

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

include/swift/SILOptimizer/Utils/Existential.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@
1818
namespace swift {
1919

2020
/// Find InitExistential from global_addr and copy_addr.
21-
SILValue findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
22-
CopyAddrInst *CAI);
21+
SILValue findInitExistentialFromGlobalAddrAndCopyAddr(GlobalAddrInst *GAI,
22+
CopyAddrInst *CAI);
23+
24+
/// Find InitExistential from global_addr and an apply argument.
25+
SILValue findInitExistentialFromGlobalAddrAndApply(GlobalAddrInst *GAI,
26+
ApplySite Apply, int ArgIdx);
2327

2428
/// Returns the address of an object with which the stack location \p ASI is
2529
/// initialized. This is either a init_existential_addr or the destination of a

lib/SILOptimizer/Utils/Existential.cpp

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,24 @@
1818

1919
using namespace swift;
2020

21-
/// Determine the pattern for global_addr.
21+
/// Determine InitExistential from global_addr.
2222
/// %3 = global_addr @$P : $*SomeP
2323
/// %4 = init_existential_addr %3 : $*SomeP, $SomeC
2424
/// %5 = alloc_ref $SomeC
2525
/// store %5 to %4 : $*SomeC
2626
/// %8 = alloc_stack $SomeP
2727
/// copy_addr %3 to [initialization] %8 : $*SomeP
28-
/// %9 = open_existential_addr immutable_access %8 : $*SomeP to $*@opened SomeP
29-
SILValue swift::findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
30-
CopyAddrInst *CAI) {
31-
assert(CAI->getSrc() == SILValue(GAI) &&
32-
"Broken Assumption! Global Addr is not the source of the passed in "
33-
"copy_addr?!");
34-
28+
/// %10 = apply %9(%3) : $@convention(thin) (@in_guaranteed SomeP)
29+
/// Assumptions: Insn is a direct user of GAI (e.g., copy_addr or
30+
/// apply pattern shown above) and that a valid init_existential_addr
31+
/// value is returned only if it can prove that the value it
32+
/// initializes is the same value at the use point.
33+
static SILValue findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
34+
SILInstruction *Insn) {
3535
/// Check for a single InitExistential usage for GAI and
36-
/// a simple dominance check: both InitExistential and CAI are in
36+
/// a simple dominance check: both InitExistential and Insn are in
3737
/// the same basic block and only one InitExistential
38-
/// occurs between GAI and CAI.
38+
/// occurs between GAI and Insn.
3939
llvm::SmallPtrSet<SILInstruction *, 8> IEUses;
4040
for (auto *Use : GAI->getUses()) {
4141
if (auto *InitExistential =
@@ -48,10 +48,11 @@ SILValue swift::findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
4848
if (IEUses.empty())
4949
return SILValue();
5050

51-
/// Walk backwards from CAI instruction till the begining of the basic block
52-
/// looking for InitExistential.
51+
/// Walk backwards from Insn instruction till the begining of the basic block
52+
/// looking for an InitExistential.
5353
SILValue SingleIE;
54-
for (auto II = CAI->getIterator().getReverse(), IE = CAI->getParent()->rend();
54+
for (auto II = Insn->getIterator().getReverse(),
55+
IE = Insn->getParent()->rend();
5556
II != IE; ++II) {
5657
if (!IEUses.count(&*II))
5758
continue;
@@ -63,6 +64,56 @@ SILValue swift::findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
6364
return SingleIE;
6465
}
6566

67+
/// Determine InitExistential from global_addr and copy_addr.
68+
/// %3 = global_addr @$P : $*SomeP
69+
/// %4 = init_existential_addr %3 : $*SomeP, $SomeC
70+
/// %5 = alloc_ref $SomeC
71+
/// store %5 to %4 : $*SomeC
72+
/// %8 = alloc_stack $SomeP
73+
/// copy_addr %3 to [initialization] %8 : $*SomeP
74+
SILValue
75+
swift::findInitExistentialFromGlobalAddrAndCopyAddr(GlobalAddrInst *GAI,
76+
CopyAddrInst *CAI) {
77+
assert(CAI->getSrc() == SILValue(GAI) &&
78+
"Broken Assumption! Global Addr is not the source of the passed in "
79+
"copy_addr?!");
80+
return findInitExistentialFromGlobalAddr(GAI, cast<SILInstruction>(CAI));
81+
}
82+
83+
/// Determine InitExistential from global_addr and an apply argument.
84+
/// Pattern 1
85+
/// %3 = global_addr @$P : $*SomeP
86+
/// %4 = init_existential_addr %3 : $*SomeP, $SomeC
87+
/// %5 = alloc_ref $SomeC
88+
/// store %5 to %4 : $*SomeC
89+
/// %10 = apply %9(%3) : $@convention(thin) (@in_guaranteed SomeP)
90+
/// Pattern 2
91+
/// %3 = global_addr @$P : $*SomeP
92+
/// %9 = open_existential_addr mutable_access %3 : $*SomeP to $*@opened SomeP
93+
/// %15 = apply %11(%9) : $@convention(thin) (@in_guaranteed SomeP)
94+
SILValue swift::findInitExistentialFromGlobalAddrAndApply(GlobalAddrInst *GAI,
95+
ApplySite Apply,
96+
int ArgIdx) {
97+
/// Code to ensure that we are calling only in two pattern matching scenarios.
98+
bool isArg = false;
99+
auto Arg = Apply.getArgument(ArgIdx);
100+
if (auto *ApplyGAI = dyn_cast<GlobalAddrInst>(Arg)) {
101+
if (ApplyGAI->isIdenticalTo(GAI)) {
102+
isArg = true;
103+
}
104+
} else if (auto Open = dyn_cast<OpenExistentialAddrInst>(Arg)) {
105+
auto Op = Open->getOperand();
106+
if (auto *OpGAI = dyn_cast<GlobalAddrInst>(Op)) {
107+
if (OpGAI->isIdenticalTo(GAI)) {
108+
isArg = true;
109+
}
110+
}
111+
}
112+
assert(isArg && "Broken Assumption! Global Addr is not an argument to "
113+
"apply?!");
114+
return findInitExistentialFromGlobalAddr(GAI, Apply.getInstruction());
115+
}
116+
66117
/// Returns the address of an object with which the stack location \p ASI is
67118
/// initialized. This is either a init_existential_addr or the destination of a
68119
/// copy_addr. Returns a null value if the address does not dominate the
@@ -130,7 +181,7 @@ SILValue swift::getAddressOfStackInit(AllocStackInst *ASI,
130181
return getAddressOfStackInit(ASI, CAI, isCopied);
131182
// Check if the CAISrc is a global_addr.
132183
if (auto *GAI = dyn_cast<GlobalAddrInst>(CAISrc)) {
133-
return findInitExistentialFromGlobalAddr(GAI, CAI);
184+
return findInitExistentialFromGlobalAddrAndCopyAddr(GAI, CAI);
134185
}
135186
return CAISrc;
136187
}

0 commit comments

Comments
 (0)