Skip to content

Remove select_value SIL instruction #66608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3475,8 +3475,6 @@ A value ``%1`` is said to be *value-dependent* on a value ``%0`` if:
with ``tuple_extract``, ``struct_extract``, ``unchecked_enum_data``,
``select_enum``, or ``select_enum_addr``.

- ``%1`` is the result of ``select_value`` and ``%0`` is one of the cases.

- ``%1`` is a basic block parameter and ``%0`` is the corresponding
argument from a branch to that block.

Expand Down Expand Up @@ -7949,45 +7947,6 @@ block. If there is a ``default`` basic block, control is transferred to it if
the value does not match any of the ``case`` values. It is undefined behavior
if the value does not match any cases and no ``default`` branch is provided.

select_value
````````````
::

sil-instruction ::= 'select_value' sil-operand sil-select-value-case*
(',' 'default' sil-value)?
':' sil-type
sil-select-value-case ::= 'case' sil-value ':' sil-value


%n = select_value %0 : $U, \
case %c1: %r1, \
case %c2: %r2, /* ... */ \
default %r3 : $T

// $U must be a builtin type. Only integers types are supported currently.
// c1, c2, etc must be of type $U
// %r1, %r2, %r3, etc. must have type $T
// %n has type $T

Selects one of the "case" or "default" operands based on the case of a
value. This is equivalent to a trivial `switch_value`_ branch sequence::

entry:
switch_value %0 : $U, \
case %c1: bb1, \
case %c2: bb2, /* ... */ \
default bb_default
bb1:
br cont(%r1 : $T) // value for %c1
bb2:
br cont(%r2 : $T) // value for %c2
bb_default:
br cont(%r3 : $T) // value for default
cont(%n : $T):
// use argument %n

but turns the control flow dependency into a data flow dependency.

switch_enum
```````````
::
Expand Down
8 changes: 0 additions & 8 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1730,14 +1730,6 @@ class SILBuilder {
getModule(), CaseCounts, DefaultCount));
}

SelectValueInst *createSelectValue(
SILLocation Loc, SILValue Operand, SILType Ty, SILValue DefaultResult,
ArrayRef<std::pair<SILValue, SILValue>> CaseValuesAndResult) {
return insert(SelectValueInst::create(getSILDebugLocation(Loc), Operand, Ty,
DefaultResult, CaseValuesAndResult,
getModule()));
}

TupleExtractInst *createTupleExtract(SILLocation Loc, SILValue Operand,
unsigned FieldNo, SILType ResultTy) {
return createTupleExtract(Loc, Operand, FieldNo, ResultTy,
Expand Down
18 changes: 0 additions & 18 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -3251,24 +3251,6 @@ SILCloner<ImplClass>::visitSelectEnumAddrInst(SelectEnumAddrInst *Inst) {
CaseResults));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitSelectValueInst(SelectValueInst *Inst) {
SILValue DefaultResult;
if (Inst->hasDefault())
DefaultResult = getOpValue(Inst->getDefaultResult());
SmallVector<std::pair<SILValue, SILValue>, 8> CaseResults;
for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i)
CaseResults.push_back(std::make_pair(getOpValue(Inst->getCase(i).first),
getOpValue(Inst->getCase(i).second)));

getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
recordClonedInstruction(
Inst, getBuilder().createSelectValue(
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
getOpType(Inst->getType()), DefaultResult, CaseResults));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitDynamicMethodBranchInst(
DynamicMethodBranchInst *Inst) {
Expand Down
49 changes: 2 additions & 47 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,6 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) {
case SILInstructionKind::ObjectInst:
case SILInstructionKind::EnumInst:
case SILInstructionKind::UncheckedEnumDataInst:
case SILInstructionKind::SelectValueInst:
case SILInstructionKind::OpenExistentialRefInst:
case SILInstructionKind::InitExistentialRefInst:
case SILInstructionKind::MarkDependenceInst:
Expand Down Expand Up @@ -6659,8 +6658,8 @@ class UncheckedTakeEnumDataAddrInst
}
};

// Abstract base class of all select instructions like select_enum,
// select_value, etc. The template parameter represents a type of case values
// Abstract base class of all select instructions like select_enum.
// The template parameter represents a type of case values
// to be compared with the operand of a select instruction.
//
// Subclasses must provide tail allocated storage.
Expand Down Expand Up @@ -6878,50 +6877,6 @@ class SelectEnumAddrInst final
ProfileCounter DefaultCount);
};

/// Select on a value of a builtin integer type.
///
/// There is 'the' operand, followed by pairs of operands for each case,
/// followed by an optional default operand.
class SelectValueInst final
: public InstructionBaseWithTrailingOperands<
SILInstructionKind::SelectValueInst, SelectValueInst,
SelectInstBase<SelectValueInst, SILValue, SingleValueInstruction>> {
friend SILBuilder;

SelectValueInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
SILValue DefaultResult,
ArrayRef<SILValue> CaseValuesAndResults);

static SelectValueInst *
create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
SILValue DefaultValue,
ArrayRef<std::pair<SILValue, SILValue>> CaseValues, SILModule &M);

public:
std::pair<SILValue, SILValue>
getCase(unsigned i) const {
auto cases = getAllOperands().slice(1);
return {cases[i*2].get(), cases[i*2+1].get()};
}

unsigned getNumCases() const {
// Ignore the first non-case operand.
auto count = getAllOperands().size() - 1;
// This implicitly ignore the optional default operand.
return count / 2;
}

bool hasDefault() const {
// If the operand count is even, then we have a default value.
return (getAllOperands().size() & 1) == 0;
}

SILValue getDefaultResult() const {
assert(hasDefault() && "doesn't have a default");
return getAllOperands().back().get();
}
};

/// MetatypeInst - Represents the production of an instance of a given metatype
/// named statically.
class MetatypeInst final
Expand Down
2 changes: 0 additions & 2 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,6 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
SingleValueInstruction, None, DoesNotRelease)
SINGLE_VALUE_INST(SelectEnumAddrInst, select_enum_addr,
SingleValueInstruction, MayRead, DoesNotRelease)
SINGLE_VALUE_INST(SelectValueInst, select_value,
SingleValueInstruction, None, DoesNotRelease)

// Protocol and Protocol Composition Types
SINGLE_VALUE_INST(InitExistentialAddrInst, init_existential_addr,
Expand Down
22 changes: 0 additions & 22 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,6 @@ class IRGenSILFunction :
void visitInitEnumDataAddrInst(InitEnumDataAddrInst *i);
void visitSelectEnumInst(SelectEnumInst *i);
void visitSelectEnumAddrInst(SelectEnumAddrInst *i);
void visitSelectValueInst(SelectValueInst *i);
void visitUncheckedEnumDataInst(UncheckedEnumDataInst *i);
void visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *i);
void visitInjectEnumAddrInst(InjectEnumAddrInst *i);
Expand Down Expand Up @@ -4658,27 +4657,6 @@ void IRGenSILFunction::visitSelectEnumAddrInst(SelectEnumAddrInst *inst) {
// emitBBMapForSelectEnum set up a phi node to receive the result.
Builder.SetInsertPoint(contBB);
}

setLoweredValue(inst,
getLoweredValueForSelect(*this, result, inst));
}

void IRGenSILFunction::visitSelectValueInst(SelectValueInst *inst) {
Explosion value = getLoweredExplosion(inst->getOperand());

// Map the SIL dest bbs to their LLVM bbs.
SmallVector<std::pair<SILValue, llvm::BasicBlock*>, 4> dests;
llvm::BasicBlock *defaultDest;
Explosion result;
auto *contBB = emitBBMapForSelect(*this, result, dests, defaultDest, inst);

// Emit the dispatch.
emitSwitchValueDispatch(*this, inst->getOperand()->getType(), value, dests,
defaultDest);

// emitBBMapForSelectEnum set up a continuation block and phi nodes to
// receive the result.
Builder.SetInsertPoint(contBB);

setLoweredValue(inst,
getLoweredValueForSelect(*this, result, inst));
Expand Down
2 changes: 0 additions & 2 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ OPERAND_OWNERSHIP(TrivialUse, PointerToAddress)
OPERAND_OWNERSHIP(TrivialUse, ProjectBlockStorage)
OPERAND_OWNERSHIP(TrivialUse, RawPointerToRef)
OPERAND_OWNERSHIP(TrivialUse, SelectEnumAddr)
// select_value is only supported for integer types currently.
OPERAND_OWNERSHIP(TrivialUse, SelectValue)
OPERAND_OWNERSHIP(TrivialUse, StructElementAddr)
OPERAND_OWNERSHIP(TrivialUse, SwitchEnumAddr)
OPERAND_OWNERSHIP(TrivialUse, SwitchValue)
Expand Down
19 changes: 0 additions & 19 deletions lib/SIL/IR/SILInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,25 +688,6 @@ namespace {
return visitSelectEnumInstBase(RHS);
}

bool visitSelectValueInst(const SelectValueInst *RHS) {
// Check that the instructions match cases in the same order.
auto *X = cast<SelectValueInst>(LHS);

if (X->getNumCases() != RHS->getNumCases())
return false;
if (X->hasDefault() != RHS->hasDefault())
return false;

for (unsigned i = 0, e = X->getNumCases(); i < e; ++i) {
if (X->getCase(i).first != RHS->getCase(i).first)
return false;
if (X->getCase(i).second != RHS->getCase(i).second)
return false;
}

return true;
}

// Conversion instructions.
// All of these just return true as they have already had their
// operands and types checked
Expand Down
29 changes: 0 additions & 29 deletions lib/SIL/IR/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1975,35 +1975,6 @@ SwitchValueInst *SwitchValueInst::create(
return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs);
}

SelectValueInst::SelectValueInst(SILDebugLocation DebugLoc, SILValue Operand,
SILType Type, SILValue DefaultResult,
ArrayRef<SILValue> CaseValuesAndResults)
: InstructionBaseWithTrailingOperands(Operand, CaseValuesAndResults,
DebugLoc, Type) {}

SelectValueInst *
SelectValueInst::create(SILDebugLocation Loc, SILValue Operand, SILType Type,
SILValue DefaultResult,
ArrayRef<std::pair<SILValue, SILValue>> CaseValues,
SILModule &M) {
// Allocate enough room for the instruction with tail-allocated data for all
// the case values and the SILSuccessor arrays. There are `CaseBBs.size()`
// SILValues and `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors.
SmallVector<SILValue, 8> CaseValuesAndResults;
for (auto pair : CaseValues) {
CaseValuesAndResults.push_back(pair.first);
CaseValuesAndResults.push_back(pair.second);
}

if ((bool)DefaultResult)
CaseValuesAndResults.push_back(DefaultResult);

auto Size = totalSizeToAlloc<swift::Operand>(CaseValuesAndResults.size() + 1);
auto Buf = M.allocateInst(Size, alignof(SelectValueInst));
return ::new (Buf)
SelectValueInst(Loc, Operand, Type, DefaultResult, CaseValuesAndResults);
}

template <typename SELECT_ENUM_INST>
SELECT_ENUM_INST *SelectEnumInstBase::createSelectEnum(
SILDebugLocation Loc, SILValue Operand, SILType Ty, SILValue DefaultValue,
Expand Down
15 changes: 0 additions & 15 deletions lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2712,21 +2712,6 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
printSelectEnumInst(SEI);
}

void visitSelectValueInst(SelectValueInst *SVI) {
*this << getIDAndType(SVI->getOperand());

for (unsigned i = 0, e = SVI->getNumCases(); i < e; ++i) {
SILValue casevalue;
SILValue result;
std::tie(casevalue, result) = SVI->getCase(i);
*this << ", case " << Ctx.getID(casevalue) << ": " << Ctx.getID(result);
}
if (SVI->hasDefault())
*this << ", default " << Ctx.getID(SVI->getDefaultResult());

*this << " : " << SVI->getType();
}

void visitDynamicMethodBranchInst(DynamicMethodBranchInst *DMBI) {
*this << getIDAndType(DMBI->getOperand()) << ", " << DMBI->getMember()
<< ", " << Ctx.getID(DMBI->getHasMethodBB()) << ", "
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/IR/ValueOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ CONSTANT_OWNERSHIP_INST(None, RefElementAddr)
CONSTANT_OWNERSHIP_INST(None, RefTailAddr)
CONSTANT_OWNERSHIP_INST(None, RefToRawPointer)
CONSTANT_OWNERSHIP_INST(None, SelectEnumAddr)
CONSTANT_OWNERSHIP_INST(None, SelectValue)
CONSTANT_OWNERSHIP_INST(None, StringLiteral)
CONSTANT_OWNERSHIP_INST(None, StructElementAddr)
CONSTANT_OWNERSHIP_INST(None, SuperMethod)
Expand Down
60 changes: 0 additions & 60 deletions lib/SIL/Parser/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6098,66 +6098,6 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
ResultVal = B.createSwitchValue(InstLoc, Val, DefaultBB, CaseBBs);
break;
}
case SILInstructionKind::SelectValueInst: {
if (parseTypedValueRef(Val, B))
return true;

SmallVector<std::pair<UnresolvedValueName, UnresolvedValueName>, 4>
CaseValueAndResultNames;
Optional<UnresolvedValueName> DefaultResultName;
while (P.consumeIf(tok::comma)) {
Identifier BBName;
SourceLoc BBLoc;
// Parse 'default' sil-value.
UnresolvedValueName tmp;
if (P.consumeIf(tok::kw_default)) {
if (parseValueName(tmp))
return true;
DefaultResultName = tmp;
break;
}

// Parse 'case' sil-decl-ref ':' sil-value.
if (P.consumeIf(tok::kw_case)) {
UnresolvedValueName casevalue;
parseValueName(casevalue);
P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":");
parseValueName(tmp);
CaseValueAndResultNames.push_back(std::make_pair(casevalue, tmp));
continue;
}

P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "case or default");
return true;
}

if (!DefaultResultName) {
P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "default");
return true;
}

// Parse the type of the result operands.
SILType ResultType;
if (P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":") ||
parseSILType(ResultType) || parseSILDebugLocation(InstLoc, B))
return true;

// Resolve the results.
SmallVector<std::pair<SILValue, SILValue>, 4> CaseValues;
SILValue DefaultValue;
if (DefaultResultName)
DefaultValue =
getLocalValue(*DefaultResultName, ResultType, InstLoc, B);
SILType ValType = Val->getType();
for (auto &caseName : CaseValueAndResultNames)
CaseValues.push_back(std::make_pair(
getLocalValue(caseName.first, ValType, InstLoc, B),
getLocalValue(caseName.second, ResultType, InstLoc, B)));

ResultVal = B.createSelectValue(InstLoc, Val, ResultType, DefaultValue,
CaseValues);
break;
}
case SILInstructionKind::DeinitExistentialAddrInst: {
if (parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))
return true;
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/Utils/InstructionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
case SILInstructionKind::SelectEnumInst:
case SILInstructionKind::SelectEnumAddrInst:
case SILInstructionKind::SelectValueInst:
case SILInstructionKind::OpenExistentialMetatypeInst:
case SILInstructionKind::OpenExistentialBoxInst:
case SILInstructionKind::OpenExistentialValueInst:
Expand Down
Loading