Skip to content

Commit a349133

Browse files
committed
Added getArgForOperand for BranchInst and CondBranchInst.
Allows a SIL pass to follow a def-use chain through phis. Other terminators can also propagate values through block arguments, but they always need special handling.
1 parent f8e5ebe commit a349133

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class SILInstructionResultArray;
6262
class SILOpenedArchetypesState;
6363
class SILType;
6464
class SILArgument;
65+
class SILPHIArgument;
6566
class SILUndef;
6667
class Stmt;
6768
class StringLiteralExpr;
@@ -6835,6 +6836,11 @@ class BranchInst final
68356836

68366837
unsigned getNumArgs() const { return getAllOperands().size(); }
68376838
SILValue getArg(unsigned i) const { return getAllOperands()[i].get(); }
6839+
6840+
/// Return the SILPHIArgument for the given operand.
6841+
///
6842+
/// See SILArgument.cpp.
6843+
const SILPHIArgument *getArgForOperand(const Operand *oper) const;
68386844
};
68396845

68406846
/// A conditional branch.
@@ -6976,6 +6982,15 @@ class CondBranchInst final
69766982
SILValue getArgForDestBB(const SILBasicBlock *DestBB,
69776983
unsigned ArgIndex) const;
69786984

6985+
/// Return the SILPHIArgument from either the true or false destination for
6986+
/// the given operand.
6987+
///
6988+
/// Returns nullptr for an operand with no block argument
6989+
/// (i.e the branch condition).
6990+
///
6991+
/// See SILArgument.cpp.
6992+
const SILPHIArgument *getArgForOperand(const Operand *oper) const;
6993+
69796994
void swapSuccessors();
69806995
};
69816996

lib/SIL/SILArgument.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ SILValue SILPHIArgument::getIncomingValue(SILBasicBlock *BB) {
188188
return getIncomingValueForPred(Parent, BB, Index);
189189
}
190190

191+
const SILPHIArgument *BranchInst::getArgForOperand(const Operand *oper) const {
192+
assert(oper->getUser() == this);
193+
return cast<SILPHIArgument>(
194+
getDestBB()->getArgument(oper->getOperandNumber()));
195+
}
196+
197+
const SILPHIArgument *
198+
CondBranchInst::getArgForOperand(const Operand *oper) const {
199+
assert(oper->getUser() == this);
200+
201+
unsigned operIdx = oper->getOperandNumber();
202+
if (isTrueOperandIndex(operIdx)) {
203+
return cast<SILPHIArgument>(getTrueBB()->getArgument(
204+
operIdx - getTrueOperands().front().getOperandNumber()));
205+
}
206+
if (isFalseOperandIndex(operIdx)) {
207+
return cast<SILPHIArgument>(getFalseBB()->getArgument(
208+
operIdx - getFalseOperands().front().getOperandNumber()));
209+
}
210+
return nullptr;
211+
}
212+
191213
//===----------------------------------------------------------------------===//
192214
// SILFunctionArgument
193215
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)