mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Track dependencies of SIL instructions on opened archetypes which they use
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype. This patch does the following: - Map opened archetypes to the instructions defining them, i.e. to open_existential instructions. - Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings. - Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes. - Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files. - SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
This commit is contained in:
@@ -662,16 +662,65 @@ namespace {
|
||||
}
|
||||
#include "swift/SIL/SILNodes.def"
|
||||
};
|
||||
|
||||
#define IMPLEMENTS_METHOD(DerivedClass, BaseClass, MemberName, ExpectedType) \
|
||||
(!::std::is_same<BaseClass, GET_IMPLEMENTING_CLASS(DerivedClass, MemberName,\
|
||||
ExpectedType)>::value)
|
||||
|
||||
class OpenedArchetypeOperandsAccessor
|
||||
: public SILVisitor<OpenedArchetypeOperandsAccessor,
|
||||
ArrayRef<Operand>> {
|
||||
public:
|
||||
#define VALUE(CLASS, PARENT) \
|
||||
ArrayRef<Operand> visit##CLASS(const CLASS *I) { \
|
||||
llvm_unreachable("accessing non-instruction " #CLASS); \
|
||||
}
|
||||
#define INST(CLASS, PARENT, MEMBEHAVIOR, RELEASINGBEHAVIOR) \
|
||||
ArrayRef<Operand> visit##CLASS(const CLASS *I) { \
|
||||
if (!IMPLEMENTS_METHOD(CLASS, SILInstruction, getOpenedArchetypeOperands, \
|
||||
ArrayRef<Operand>() const)) \
|
||||
return {}; \
|
||||
return I->getOpenedArchetypeOperands(); \
|
||||
}
|
||||
#include "swift/SIL/SILNodes.def"
|
||||
};
|
||||
|
||||
class OpenedArchetypeOperandsMutableAccessor
|
||||
: public SILVisitor<OpenedArchetypeOperandsMutableAccessor,
|
||||
MutableArrayRef<Operand> > {
|
||||
public:
|
||||
#define VALUE(CLASS, PARENT) \
|
||||
MutableArrayRef<Operand> visit##CLASS(const CLASS *I) { \
|
||||
llvm_unreachable("accessing non-instruction " #CLASS); \
|
||||
}
|
||||
#define INST(CLASS, PARENT, MEMBEHAVIOR, RELEASINGBEHAVIOR) \
|
||||
MutableArrayRef<Operand> visit##CLASS(CLASS *I) { \
|
||||
if (!IMPLEMENTS_METHOD(CLASS, SILInstruction, getOpenedArchetypeOperands, \
|
||||
MutableArrayRef<Operand>())) \
|
||||
return {}; \
|
||||
return I->getOpenedArchetypeOperands(); \
|
||||
}
|
||||
#include "swift/SIL/SILNodes.def"
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
ArrayRef<Operand> SILInstruction::getAllOperands() const {
|
||||
return AllOperandsAccessor().visit(const_cast<SILInstruction*>(this));
|
||||
return AllOperandsAccessor().visit(const_cast<SILInstruction *>(this));
|
||||
}
|
||||
|
||||
MutableArrayRef<Operand> SILInstruction::getAllOperands() {
|
||||
return AllOperandsMutableAccessor().visit(this);
|
||||
}
|
||||
|
||||
ArrayRef<Operand> SILInstruction::getOpenedArchetypeOperands() const {
|
||||
return OpenedArchetypeOperandsAccessor().visit(
|
||||
const_cast<SILInstruction *>(this));
|
||||
}
|
||||
|
||||
MutableArrayRef<Operand> SILInstruction::getOpenedArchetypeOperands() {
|
||||
return OpenedArchetypeOperandsMutableAccessor().visit(this);
|
||||
}
|
||||
|
||||
/// getOperandNumber - Return which operand this is in the operand list of the
|
||||
/// using instruction.
|
||||
unsigned Operand::getOperandNumber() const {
|
||||
|
||||
Reference in New Issue
Block a user