Skip to content

Commit 7942cbf

Browse files
authored
Merge pull request swiftlang#30256 from gottesmm/pr-e7fa33950f580ee9f3bec78206e04a430971107d
[silargument] Implement getIncomingPhiOperand methods and reimplement getIncomingPhiValue methods ontop.
2 parents 60cf68f + bd68964 commit 7942cbf

File tree

4 files changed

+93
-14
lines changed

4 files changed

+93
-14
lines changed

include/swift/SIL/SILArgument.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ class SILArgument : public ValueBase {
144144
getIncomingPhiValues(SmallVectorImpl<std::pair<SILBasicBlock *, SILValue>>
145145
&returnedPredAndPhiValuePairs) const;
146146

147+
/// If this argument is a true phi, populate `OutArray` with the operand in
148+
/// each predecessor block associated with an incoming value.
149+
bool
150+
getIncomingPhiOperands(SmallVectorImpl<Operand *> &returnedPhiOperands) const;
151+
147152
/// Returns true if we were able to find a single terminator operand value for
148153
/// each predecessor of this arguments basic block. The found values are
149154
/// stored in OutArray.
@@ -239,6 +244,11 @@ class SILPhiArgument : public SILArgument {
239244
getIncomingPhiValues(SmallVectorImpl<std::pair<SILBasicBlock *, SILValue>>
240245
&returnedPredAndPhiValuePairs) const;
241246

247+
/// If this argument is a true phi, populate `OutArray` with the operand in
248+
/// each predecessor block associated with an incoming value.
249+
bool
250+
getIncomingPhiOperands(SmallVectorImpl<Operand *> &returnedPhiOperands) const;
251+
242252
/// Returns true if we were able to find a single terminator operand value for
243253
/// each predecessor of this arguments basic block. The found values are
244254
/// stored in OutArray.
@@ -421,6 +431,18 @@ inline TermInst *SILArgument::getSingleTerminator() const {
421431
llvm_unreachable("Covered switch is not covered?!");
422432
}
423433

434+
inline bool SILArgument::getIncomingPhiOperands(
435+
SmallVectorImpl<Operand *> &returnedPhiOperands) const {
436+
switch (getKind()) {
437+
case SILArgumentKind::SILPhiArgument:
438+
return cast<SILPhiArgument>(this)->getIncomingPhiOperands(
439+
returnedPhiOperands);
440+
case SILArgumentKind::SILFunctionArgument:
441+
return false;
442+
}
443+
llvm_unreachable("Covered switch is not covered?!");
444+
}
445+
424446
} // end swift namespace
425447

426448
#endif

include/swift/SIL/SILInstruction.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7420,15 +7420,35 @@ class CondBranchInst final
74207420
OpIndex <= Operands.back().getOperandNumber();
74217421
}
74227422

7423+
/// Returns the operand on the cond_br terminator associated with the value
7424+
/// that will be passed to DestBB in A.
7425+
Operand *getOperandForDestBB(const SILBasicBlock *DestBB,
7426+
const SILArgument *A) const;
7427+
7428+
/// Returns the operand on the cond_br terminator associated with the value
7429+
/// that will be passed as the \p Index argument to DestBB.
7430+
Operand *getOperandForDestBB(const SILBasicBlock *DestBB,
7431+
unsigned ArgIndex) const;
7432+
74237433
/// Returns the argument on the cond_br terminator that will be passed to
74247434
/// DestBB in A.
74257435
SILValue getArgForDestBB(const SILBasicBlock *DestBB,
7426-
const SILArgument *A) const;
7436+
const SILArgument *A) const {
7437+
if (auto *op = getOperandForDestBB(DestBB, A)) {
7438+
return op->get();
7439+
}
7440+
return SILValue();
7441+
}
74277442

74287443
/// Returns the argument on the cond_br terminator that will be passed as the
74297444
/// \p Index argument to DestBB.
74307445
SILValue getArgForDestBB(const SILBasicBlock *DestBB,
7431-
unsigned ArgIndex) const;
7446+
unsigned ArgIndex) const {
7447+
if (auto *op = getOperandForDestBB(DestBB, ArgIndex)) {
7448+
return op->get();
7449+
}
7450+
return SILValue();
7451+
}
74327452

74337453
/// Return the SILPhiArgument from either the true or false destination for
74347454
/// the given operand.

lib/SIL/SILArgument.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,22 @@ bool SILPhiArgument::isPhiArgument() const {
8686
return isa<BranchInst>(termInst) || isa<CondBranchInst>(termInst);
8787
}
8888

89+
static Operand *getIncomingPhiOperandForPred(const SILBasicBlock *parentBlock,
90+
const SILBasicBlock *predBlock,
91+
unsigned argIndex) {
92+
auto *predBlockTermInst = predBlock->getTerminator();
93+
if (auto *bi = dyn_cast<BranchInst>(predBlockTermInst)) {
94+
return &const_cast<BranchInst *>(bi)->getAllOperands()[argIndex];
95+
}
96+
97+
// FIXME: Disallowing critical edges in SIL would enormously simplify phi and
98+
// branch handling and reduce expensive analysis invalidation. If that is
99+
// done, then only BranchInst will participate in phi operands, eliminating
100+
// the need to search for the appropriate CondBranchInst operand.
101+
return cast<CondBranchInst>(predBlockTermInst)
102+
->getOperandForDestBB(parentBlock, argIndex);
103+
}
104+
89105
static SILValue getIncomingPhiValueForPred(const SILBasicBlock *parentBlock,
90106
const SILBasicBlock *predBlock,
91107
unsigned argIndex) {
@@ -135,6 +151,24 @@ bool SILPhiArgument::getIncomingPhiValues(
135151
return true;
136152
}
137153

154+
bool SILPhiArgument::getIncomingPhiOperands(
155+
SmallVectorImpl<Operand *> &returnedPhiOperands) const {
156+
if (!isPhiArgument())
157+
return false;
158+
159+
const auto *parentBlock = getParent();
160+
assert(!parentBlock->pred_empty());
161+
162+
unsigned argIndex = getIndex();
163+
for (auto *predBlock : getParent()->getPredecessorBlocks()) {
164+
Operand *incomingOperand =
165+
getIncomingPhiOperandForPred(parentBlock, predBlock, argIndex);
166+
assert(incomingOperand);
167+
returnedPhiOperands.push_back(incomingOperand);
168+
}
169+
return true;
170+
}
171+
138172
bool SILPhiArgument::getIncomingPhiValues(
139173
SmallVectorImpl<std::pair<SILBasicBlock *, SILValue>>
140174
&returnedPredBBAndPhiValuePairs) const {

lib/SIL/SILInstructions.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,26 +1348,29 @@ CondBranchInst::create(SILDebugLocation Loc, SILValue Condition,
13481348
TrueBBCount, FalseBBCount);
13491349
}
13501350

1351-
SILValue CondBranchInst::getArgForDestBB(const SILBasicBlock *DestBB,
1352-
const SILArgument *Arg) const {
1353-
return getArgForDestBB(DestBB, Arg->getIndex());
1351+
Operand *CondBranchInst::getOperandForDestBB(const SILBasicBlock *destBlock,
1352+
const SILArgument *arg) const {
1353+
return getOperandForDestBB(destBlock, arg->getIndex());
13541354
}
13551355

1356-
SILValue CondBranchInst::getArgForDestBB(const SILBasicBlock *DestBB,
1357-
unsigned ArgIndex) const {
1356+
Operand *CondBranchInst::getOperandForDestBB(const SILBasicBlock *destBlock,
1357+
unsigned argIndex) const {
13581358
// If TrueBB and FalseBB equal, we cannot find an arg for this DestBB so
13591359
// return an empty SILValue.
13601360
if (getTrueBB() == getFalseBB()) {
1361-
assert(DestBB == getTrueBB() && "DestBB is not a target of this cond_br");
1362-
return SILValue();
1361+
assert(destBlock == getTrueBB() &&
1362+
"DestBB is not a target of this cond_br");
1363+
return nullptr;
13631364
}
13641365

1365-
if (DestBB == getTrueBB())
1366-
return getAllOperands()[NumFixedOpers + ArgIndex].get();
1366+
auto *self = const_cast<CondBranchInst *>(this);
1367+
if (destBlock == getTrueBB()) {
1368+
return &self->getAllOperands()[NumFixedOpers + argIndex];
1369+
}
13671370

1368-
assert(DestBB == getFalseBB()
1369-
&& "By process of elimination BB must be false BB");
1370-
return getAllOperands()[NumFixedOpers + getNumTrueArgs() + ArgIndex].get();
1371+
assert(destBlock == getFalseBB() &&
1372+
"By process of elimination BB must be false BB");
1373+
return &self->getAllOperands()[NumFixedOpers + getNumTrueArgs() + argIndex];
13711374
}
13721375

13731376
void CondBranchInst::swapSuccessors() {

0 commit comments

Comments
 (0)