Skip to content

Commit bd68964

Browse files
committed
[silargument] Implement getIncomingPhiOperand methods and reimplement getIncomingPhiValue methods ontop.
Operands are generally better to return than values since the operand also enables you to get to the terminator instruction as well. Since so much code in the compiler already uses the getIncomingPhiValue methods, I reimplemented them on top of the operand methods.
1 parent 711fc48 commit bd68964

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)