mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SIL: Add a switch_int instruction.
This will help represent cleanup blocks in the grown-up Clang way instead of the childish SILGen way, e.g.: retain %x retain %y ... break_branch: %1 = int_literal 1 : $Builtin.Int64 br cleanup(%1) return_branch: %2 = int_literal 2 : $Builtin.Int64 br cleanup(%2) cleanup(%dest : $Builtin.Int64): release %z release %y switch %dest, case 1: break_dest, case 2: return_dest Swift SVN r6753
This commit is contained in:
@@ -551,6 +551,62 @@ OperandValueArrayRef CondBranchInst::getFalseArgs() const {
|
||||
getFalseBB()->bbarg_size());
|
||||
}
|
||||
|
||||
SwitchIntInst::SwitchIntInst(SILLocation Loc, SILValue Operand,
|
||||
SILBasicBlock *DefaultBB,
|
||||
ArrayRef<std::pair<APInt, SILBasicBlock*>> CaseBBs)
|
||||
: TermInst(ValueKind::SwitchIntInst, Loc),
|
||||
Operands(this, Operand),
|
||||
NumCases(CaseBBs.size()),
|
||||
HasDefault(bool(DefaultBB))
|
||||
{
|
||||
// Initialize the case and successor arrays.
|
||||
auto *cases = getCaseBuf();
|
||||
auto *succs = getSuccessorBuf();
|
||||
|
||||
unsigned words = getNumWordsForCase();
|
||||
|
||||
for (unsigned i = 0, size = CaseBBs.size(); i < size; ++i) {
|
||||
assert(CaseBBs[i].first.getBitWidth() == getBitWidthForCase() &&
|
||||
"switch_int case value is not same bit width as operand");
|
||||
memcpy(cases + i*words, CaseBBs[i].first.getRawData(),
|
||||
words * sizeof(llvm::integerPart));
|
||||
::new (succs + i) SILSuccessor(this, CaseBBs[i].second);
|
||||
}
|
||||
|
||||
if (HasDefault)
|
||||
::new (succs + NumCases) SILSuccessor(this, DefaultBB);
|
||||
}
|
||||
|
||||
SwitchIntInst::~SwitchIntInst() {
|
||||
// Destroy the successor records to keep the CFG up to date.
|
||||
auto *succs = getSuccessorBuf();
|
||||
for (unsigned i = 0, end = NumCases + HasDefault; i < end; ++i) {
|
||||
succs[i].~SILSuccessor();
|
||||
}
|
||||
}
|
||||
|
||||
SwitchIntInst *SwitchIntInst::create(SILLocation Loc, SILValue Operand,
|
||||
SILBasicBlock *DefaultBB,
|
||||
ArrayRef<std::pair<APInt, SILBasicBlock *>> CaseBBs,
|
||||
SILFunction &F) {
|
||||
// Allocate enough room for the instruction with tail-allocated data for all
|
||||
// the APInt values and the SILSuccessor arrays. There are `CaseBBs.size()`
|
||||
// APInts (each needing `getNumWords()` `llvm::integerPart`s of storage) and
|
||||
// `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors.
|
||||
unsigned numCases = CaseBBs.size();
|
||||
unsigned numSuccessors = numCases + (DefaultBB ? 1 : 0);
|
||||
|
||||
unsigned bits = Operand.getType().castTo<BuiltinIntegerType>()->getBitWidth();
|
||||
unsigned words = (bits + llvm::integerPartWidth - 1) / llvm::integerPartWidth;
|
||||
|
||||
void *buf = F.getModule().allocate(sizeof(SwitchIntInst)
|
||||
+ sizeof(llvm::integerPart) * numCases
|
||||
* words
|
||||
+ sizeof(SILSuccessor) * numSuccessors,
|
||||
alignof(SwitchIntInst));
|
||||
return ::new (buf) SwitchIntInst(Loc, Operand, DefaultBB, CaseBBs);
|
||||
}
|
||||
|
||||
SwitchOneofInst::SwitchOneofInst(SILLocation Loc, SILValue Operand,
|
||||
SILBasicBlock *DefaultBB,
|
||||
ArrayRef<std::pair<OneOfElementDecl*, SILBasicBlock*>> CaseBBs)
|
||||
@@ -584,8 +640,8 @@ SwitchOneofInst *SwitchOneofInst::create(SILLocation Loc, SILValue Operand,
|
||||
ArrayRef<std::pair<OneOfElementDecl*, SILBasicBlock*>> CaseBBs,
|
||||
SILFunction &F) {
|
||||
// Allocate enough room for the instruction with tail-allocated
|
||||
// OneOfElementDecl and SILSuccessor arrays. There are CaseBBs.size() decls
|
||||
// CaseBBs.size() + (DefaultBB ? 1 : 0) successors.
|
||||
// OneOfElementDecl and SILSuccessor arrays. There are `CaseBBs.size()` decls
|
||||
// and `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors.
|
||||
unsigned numCases = CaseBBs.size();
|
||||
unsigned numSuccessors = numCases + (DefaultBB ? 1 : 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user