mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
And lastly rename NewProjection to Projection. This is a NFC. rdar://24520269
This commit is contained in:
@@ -76,7 +76,7 @@ struct PointerIntEnumIndexKindValue
|
|||||||
/// determine what cases are pointer and which are indices. For instance the one
|
/// determine what cases are pointer and which are indices. For instance the one
|
||||||
/// used by Projection in swift is:
|
/// used by Projection in swift is:
|
||||||
///
|
///
|
||||||
/// enum class NewProjectionKind : unsigned {
|
/// enum class ProjectionKind : unsigned {
|
||||||
/// // PointerProjectionKinds
|
/// // PointerProjectionKinds
|
||||||
/// Upcast = 0,
|
/// Upcast = 0,
|
||||||
/// RefCast = 1,
|
/// RefCast = 1,
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
class SILBuilder;
|
class SILBuilder;
|
||||||
class NewProjectionPath;
|
class ProjectionPath;
|
||||||
using NewProjectionPathList = llvm::SmallVector<Optional<NewProjectionPath>, 8>;
|
using ProjectionPathList = llvm::SmallVector<Optional<ProjectionPath>, 8>;
|
||||||
|
|
||||||
enum class SubSeqRelation_t : uint8_t {
|
enum class SubSeqRelation_t : uint8_t {
|
||||||
Unknown,
|
Unknown,
|
||||||
@@ -78,9 +78,9 @@ bool getIntegerIndex(SILValue IndexVal, unsigned &IndexConst);
|
|||||||
/// most cases this will not happen. For simplicity, we limit such kinds to use
|
/// most cases this will not happen. For simplicity, we limit such kinds to use
|
||||||
/// no more than 4 bits.
|
/// no more than 4 bits.
|
||||||
///
|
///
|
||||||
/// The NewProjection class contains the logic to use NewProjectionKind in this
|
/// The Projection class contains the logic to use ProjectionKind in this
|
||||||
/// manner.
|
/// manner.
|
||||||
enum class NewProjectionKind : unsigned {
|
enum class ProjectionKind : unsigned {
|
||||||
// PointerProjectionKinds
|
// PointerProjectionKinds
|
||||||
Upcast = 0,
|
Upcast = 0,
|
||||||
RefCast = 1,
|
RefCast = 1,
|
||||||
@@ -90,34 +90,34 @@ enum class NewProjectionKind : unsigned {
|
|||||||
|
|
||||||
// Index Projection Kinds
|
// Index Projection Kinds
|
||||||
FirstIndexKind = 7,
|
FirstIndexKind = 7,
|
||||||
Struct = PointerIntEnumIndexKindValue<0, NewProjectionKind>::value,
|
Struct = PointerIntEnumIndexKindValue<0, ProjectionKind>::value,
|
||||||
Tuple = PointerIntEnumIndexKindValue<1, NewProjectionKind>::value,
|
Tuple = PointerIntEnumIndexKindValue<1, ProjectionKind>::value,
|
||||||
Index = PointerIntEnumIndexKindValue<2, NewProjectionKind>::value,
|
Index = PointerIntEnumIndexKindValue<2, ProjectionKind>::value,
|
||||||
Class = PointerIntEnumIndexKindValue<3, NewProjectionKind>::value,
|
Class = PointerIntEnumIndexKindValue<3, ProjectionKind>::value,
|
||||||
Enum = PointerIntEnumIndexKindValue<4, NewProjectionKind>::value,
|
Enum = PointerIntEnumIndexKindValue<4, ProjectionKind>::value,
|
||||||
Box = PointerIntEnumIndexKindValue<5, NewProjectionKind>::value,
|
Box = PointerIntEnumIndexKindValue<5, ProjectionKind>::value,
|
||||||
LastIndexKind = Enum,
|
LastIndexKind = Enum,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr unsigned MaxPointerProjectionKind = ((1 << TypeAlignInBits) - 1);
|
constexpr unsigned MaxPointerProjectionKind = ((1 << TypeAlignInBits) - 1);
|
||||||
/// Make sure that our tagged pointer assumptions are true. See comment above
|
/// Make sure that our tagged pointer assumptions are true. See comment above
|
||||||
/// the declaration of NewProjectionKind.
|
/// the declaration of ProjectionKind.
|
||||||
static_assert(unsigned(NewProjectionKind::LastPointerKind) <=
|
static_assert(unsigned(ProjectionKind::LastPointerKind) <=
|
||||||
unsigned(MaxPointerProjectionKind),
|
unsigned(MaxPointerProjectionKind),
|
||||||
"Too many projection kinds to fit in Projection");
|
"Too many projection kinds to fit in Projection");
|
||||||
|
|
||||||
static inline bool isCastNewProjectionKind(NewProjectionKind Kind) {
|
static inline bool isCastProjectionKind(ProjectionKind Kind) {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
return true;
|
return true;
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,11 +126,11 @@ static inline bool isCastNewProjectionKind(NewProjectionKind Kind) {
|
|||||||
/// that immediately contains it.
|
/// that immediately contains it.
|
||||||
///
|
///
|
||||||
/// This lightweight utility maps a SIL address projection to an index.
|
/// This lightweight utility maps a SIL address projection to an index.
|
||||||
struct NewProjectionIndex {
|
struct ProjectionIndex {
|
||||||
SILValue Aggregate;
|
SILValue Aggregate;
|
||||||
unsigned Index;
|
unsigned Index;
|
||||||
|
|
||||||
explicit NewProjectionIndex(SILValue V) :Index(~0U) {
|
explicit ProjectionIndex(SILValue V) :Index(~0U) {
|
||||||
switch (V->getKind()) {
|
switch (V->getKind()) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -190,10 +190,10 @@ struct NewProjectionIndex {
|
|||||||
/// projections.
|
/// projections.
|
||||||
///
|
///
|
||||||
/// It is intended to be pointer sized and trivially copyable so that memcpy can
|
/// It is intended to be pointer sized and trivially copyable so that memcpy can
|
||||||
/// be used to copy a NewProjection.
|
/// be used to copy a Projection.
|
||||||
class NewProjection {
|
class Projection {
|
||||||
|
|
||||||
friend NewProjectionPath;
|
friend ProjectionPath;
|
||||||
|
|
||||||
static constexpr unsigned NumPointerKindBits = TypeAlignInBits;
|
static constexpr unsigned NumPointerKindBits = TypeAlignInBits;
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ class NewProjection {
|
|||||||
/// the top of our word.
|
/// the top of our word.
|
||||||
static constexpr unsigned NumIndexKindBits = 4;
|
static constexpr unsigned NumIndexKindBits = 4;
|
||||||
|
|
||||||
using ValueTy = PointerIntEnum<NewProjectionKind, TypeBase *,
|
using ValueTy = PointerIntEnum<ProjectionKind, TypeBase *,
|
||||||
NumPointerKindBits, NumIndexKindBits>;
|
NumPointerKindBits, NumIndexKindBits>;
|
||||||
/// A pointer sized type that is used to store the kind of projection that is
|
/// A pointer sized type that is used to store the kind of projection that is
|
||||||
/// being represented and also all of the necessary information to convert a
|
/// being represented and also all of the necessary information to convert a
|
||||||
@@ -209,25 +209,25 @@ class NewProjection {
|
|||||||
ValueTy Value;
|
ValueTy Value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NewProjection() = delete;
|
Projection() = delete;
|
||||||
|
|
||||||
explicit NewProjection(SILValue V)
|
explicit Projection(SILValue V)
|
||||||
: NewProjection(dyn_cast<SILInstruction>(V)) {}
|
: Projection(dyn_cast<SILInstruction>(V)) {}
|
||||||
explicit NewProjection(SILInstruction *I);
|
explicit Projection(SILInstruction *I);
|
||||||
|
|
||||||
NewProjection(NewProjectionKind Kind, unsigned NewIndex)
|
Projection(ProjectionKind Kind, unsigned NewIndex)
|
||||||
: Value(Kind, NewIndex) {}
|
: Value(Kind, NewIndex) {}
|
||||||
|
|
||||||
NewProjection(NewProjectionKind Kind, TypeBase *Ptr)
|
Projection(ProjectionKind Kind, TypeBase *Ptr)
|
||||||
: Value(Kind, Ptr) {}
|
: Value(Kind, Ptr) {}
|
||||||
|
|
||||||
NewProjection(NewProjection &&P) = default;
|
Projection(Projection &&P) = default;
|
||||||
NewProjection(const NewProjection &P) = default;
|
Projection(const Projection &P) = default;
|
||||||
~NewProjection() = default;
|
~Projection() = default;
|
||||||
|
|
||||||
NewProjection &operator=(const NewProjection &P) = default;
|
Projection &operator=(const Projection &P) = default;
|
||||||
|
|
||||||
NewProjection &operator=(NewProjection &&P) = default;
|
Projection &operator=(Projection &&P) = default;
|
||||||
|
|
||||||
bool isValid() const { return Value.isValid(); }
|
bool isValid() const { return Value.isValid(); }
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ public:
|
|||||||
/// Determine if I is a value projection instruction whose corresponding
|
/// Determine if I is a value projection instruction whose corresponding
|
||||||
/// projection equals this projection.
|
/// projection equals this projection.
|
||||||
bool matchesObjectProjection(SILInstruction *I) const {
|
bool matchesObjectProjection(SILInstruction *I) const {
|
||||||
NewProjection P(I);
|
Projection P(I);
|
||||||
return P.isValid() && P == *this;
|
return P.isValid() && P == *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,21 +274,21 @@ public:
|
|||||||
SILType getType(SILType BaseType, SILModule &M) const {
|
SILType getType(SILType BaseType, SILModule &M) const {
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
return BaseType.getFieldType(getVarDecl(BaseType), M);
|
return BaseType.getFieldType(getVarDecl(BaseType), M);
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M);
|
return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M);
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return SILType::getPrimitiveAddressType(BaseType.castTo<SILBoxType>()->
|
return SILType::getPrimitiveAddressType(BaseType.castTo<SILBoxType>()->
|
||||||
getBoxedType());
|
getBoxedType());
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
return BaseType.getTupleElementType(getIndex());
|
return BaseType.getTupleElementType(getIndex());
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
return getCastType(BaseType);
|
return getCastType(BaseType);
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
// Index types do not change the underlying type.
|
// Index types do not change the underlying type.
|
||||||
return BaseType;
|
return BaseType;
|
||||||
}
|
}
|
||||||
@@ -296,8 +296,8 @@ public:
|
|||||||
|
|
||||||
VarDecl *getVarDecl(SILType BaseType) const {
|
VarDecl *getVarDecl(SILType BaseType) const {
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
assert((getKind() == NewProjectionKind::Struct ||
|
assert((getKind() == ProjectionKind::Struct ||
|
||||||
getKind() == NewProjectionKind::Class));
|
getKind() == ProjectionKind::Class));
|
||||||
assert(BaseType.getNominalOrBoundGenericNominal() &&
|
assert(BaseType.getNominalOrBoundGenericNominal() &&
|
||||||
"This should only be called with a nominal type");
|
"This should only be called with a nominal type");
|
||||||
auto *NDecl = BaseType.getNominalOrBoundGenericNominal();
|
auto *NDecl = BaseType.getNominalOrBoundGenericNominal();
|
||||||
@@ -308,7 +308,7 @@ public:
|
|||||||
|
|
||||||
EnumElementDecl *getEnumElementDecl(SILType BaseType) const {
|
EnumElementDecl *getEnumElementDecl(SILType BaseType) const {
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
assert(getKind() == NewProjectionKind::Enum);
|
assert(getKind() == ProjectionKind::Enum);
|
||||||
assert(BaseType.getEnumOrBoundGenericEnum() && "Expected enum type");
|
assert(BaseType.getEnumOrBoundGenericEnum() && "Expected enum type");
|
||||||
auto Iter = BaseType.getEnumOrBoundGenericEnum()->getAllElements().begin();
|
auto Iter = BaseType.getEnumOrBoundGenericEnum()->getAllElements().begin();
|
||||||
std::advance(Iter, getIndex());
|
std::advance(Iter, getIndex());
|
||||||
@@ -318,39 +318,39 @@ public:
|
|||||||
ValueDecl *getValueDecl(SILType BaseType) const {
|
ValueDecl *getValueDecl(SILType BaseType) const {
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
return getEnumElementDecl(BaseType);
|
return getEnumElementDecl(BaseType);
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
return getVarDecl(BaseType);
|
return getVarDecl(BaseType);
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
llvm_unreachable("NewProjectionKind that does not have a value decl?");
|
llvm_unreachable("ProjectionKind that does not have a value decl?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SILType getCastType(SILType BaseType) const {
|
SILType getCastType(SILType BaseType) const {
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
assert(getKind() == NewProjectionKind::Upcast ||
|
assert(getKind() == ProjectionKind::Upcast ||
|
||||||
getKind() == NewProjectionKind::RefCast ||
|
getKind() == ProjectionKind::RefCast ||
|
||||||
getKind() == NewProjectionKind::BitwiseCast);
|
getKind() == ProjectionKind::BitwiseCast);
|
||||||
auto *Ty = getPointer();
|
auto *Ty = getPointer();
|
||||||
assert(Ty->isCanonical());
|
assert(Ty->isCanonical());
|
||||||
return SILType::getPrimitiveType(Ty->getCanonicalType(),
|
return SILType::getPrimitiveType(Ty->getCanonicalType(),
|
||||||
BaseType.getCategory());
|
BaseType.getCategory());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const NewProjection &Other) const;
|
bool operator<(const Projection &Other) const;
|
||||||
|
|
||||||
bool operator==(const NewProjection &Other) const {
|
bool operator==(const Projection &Other) const {
|
||||||
return Value == Other.Value;
|
return Value == Other.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const NewProjection &Other) const {
|
bool operator!=(const Projection &Other) const {
|
||||||
return !(*this == Other);
|
return !(*this == Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ public:
|
|||||||
SILValue getOperandForAggregate(SILInstruction *I) const;
|
SILValue getOperandForAggregate(SILInstruction *I) const;
|
||||||
|
|
||||||
/// Convenience method for getting the raw underlying kind.
|
/// Convenience method for getting the raw underlying kind.
|
||||||
NewProjectionKind getKind() const { return *Value.getKind(); }
|
ProjectionKind getKind() const { return *Value.getKind(); }
|
||||||
|
|
||||||
/// Returns true if this instruction projects from an address type to an
|
/// Returns true if this instruction projects from an address type to an
|
||||||
/// address subtype.
|
/// address subtype.
|
||||||
@@ -403,7 +403,7 @@ public:
|
|||||||
/// Given a specific SILType, return all first level projections if it is an
|
/// Given a specific SILType, return all first level projections if it is an
|
||||||
/// aggregate.
|
/// aggregate.
|
||||||
static void getFirstLevelProjections(SILType V, SILModule &Mod,
|
static void getFirstLevelProjections(SILType V, SILModule &Mod,
|
||||||
llvm::SmallVectorImpl<NewProjection> &Out);
|
llvm::SmallVectorImpl<Projection> &Out);
|
||||||
|
|
||||||
/// Is this cast which only allows for equality?
|
/// Is this cast which only allows for equality?
|
||||||
///
|
///
|
||||||
@@ -414,32 +414,32 @@ public:
|
|||||||
/// relationships when TBAA would say that aliasing can not occur.
|
/// relationships when TBAA would say that aliasing can not occur.
|
||||||
bool isAliasingCast() const {
|
bool isAliasingCast() const {
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
return true;
|
return true;
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNominalKind() const {
|
bool isNominalKind() const {
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
return true;
|
return true;
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,7 +464,7 @@ private:
|
|||||||
|
|
||||||
/// This is to make sure that new projection is never bigger than a
|
/// This is to make sure that new projection is never bigger than a
|
||||||
/// pointer. This is just for performance.
|
/// pointer. This is just for performance.
|
||||||
static_assert(sizeof(NewProjection) == sizeof(uintptr_t),
|
static_assert(sizeof(Projection) == sizeof(uintptr_t),
|
||||||
"IndexType should be pointer sized");
|
"IndexType should be pointer sized");
|
||||||
|
|
||||||
/// A "path" of projections abstracting either value or aggregate projections
|
/// A "path" of projections abstracting either value or aggregate projections
|
||||||
@@ -476,9 +476,9 @@ static_assert(sizeof(NewProjection) == sizeof(uintptr_t),
|
|||||||
/// 1. Converting value projections to aggregate projections or vis-a-versa.
|
/// 1. Converting value projections to aggregate projections or vis-a-versa.
|
||||||
/// 2. Performing tuple operations on two paths (using the mathematical
|
/// 2. Performing tuple operations on two paths (using the mathematical
|
||||||
/// definition of tuples as ordered sets).
|
/// definition of tuples as ordered sets).
|
||||||
class NewProjectionPath {
|
class ProjectionPath {
|
||||||
public:
|
public:
|
||||||
using PathTy = llvm::SmallVector<NewProjection, 4>;
|
using PathTy = llvm::SmallVector<Projection, 4>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SILType BaseType;
|
SILType BaseType;
|
||||||
@@ -488,30 +488,30 @@ private:
|
|||||||
public:
|
public:
|
||||||
/// Create an empty path which serves as a stack. Use push_back() to populate
|
/// Create an empty path which serves as a stack. Use push_back() to populate
|
||||||
/// the stack with members.
|
/// the stack with members.
|
||||||
NewProjectionPath(SILType Base)
|
ProjectionPath(SILType Base)
|
||||||
: BaseType(Base), MostDerivedType(SILType()), Path() {}
|
: BaseType(Base), MostDerivedType(SILType()), Path() {}
|
||||||
NewProjectionPath(SILType Base, SILType End)
|
ProjectionPath(SILType Base, SILType End)
|
||||||
: BaseType(Base), MostDerivedType(End), Path() {}
|
: BaseType(Base), MostDerivedType(End), Path() {}
|
||||||
~NewProjectionPath() = default;
|
~ProjectionPath() = default;
|
||||||
|
|
||||||
/// Do not allow copy construction. The only way to get one of these is from
|
/// Do not allow copy construction. The only way to get one of these is from
|
||||||
/// getProjectionPath.
|
/// getProjectionPath.
|
||||||
NewProjectionPath(const NewProjectionPath &Other) {
|
ProjectionPath(const ProjectionPath &Other) {
|
||||||
BaseType = Other.BaseType;
|
BaseType = Other.BaseType;
|
||||||
MostDerivedType = Other.MostDerivedType;
|
MostDerivedType = Other.MostDerivedType;
|
||||||
Path = Other.Path;
|
Path = Other.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionPath &operator=(const NewProjectionPath &O) {
|
ProjectionPath &operator=(const ProjectionPath &O) {
|
||||||
BaseType = O.BaseType;
|
BaseType = O.BaseType;
|
||||||
MostDerivedType = O.MostDerivedType;
|
MostDerivedType = O.MostDerivedType;
|
||||||
Path = O.Path;
|
Path = O.Path;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We only allow for moves of NewProjectionPath since we only want them to be
|
/// We only allow for moves of ProjectionPath since we only want them to be
|
||||||
/// able to be constructed by calling our factory method.
|
/// able to be constructed by calling our factory method.
|
||||||
NewProjectionPath(NewProjectionPath &&O) {
|
ProjectionPath(ProjectionPath &&O) {
|
||||||
BaseType = O.BaseType;
|
BaseType = O.BaseType;
|
||||||
MostDerivedType = O.MostDerivedType;
|
MostDerivedType = O.MostDerivedType;
|
||||||
Path = O.Path;
|
Path = O.Path;
|
||||||
@@ -520,7 +520,7 @@ public:
|
|||||||
O.Path.clear();
|
O.Path.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionPath &operator=(NewProjectionPath &&O) {
|
ProjectionPath &operator=(ProjectionPath &&O) {
|
||||||
BaseType = O.BaseType;
|
BaseType = O.BaseType;
|
||||||
MostDerivedType = O.MostDerivedType;
|
MostDerivedType = O.MostDerivedType;
|
||||||
Path = O.Path;
|
Path = O.Path;
|
||||||
@@ -531,7 +531,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Append the projection \p P onto this.
|
/// Append the projection \p P onto this.
|
||||||
NewProjectionPath &append(const NewProjection &P) {
|
ProjectionPath &append(const Projection &P) {
|
||||||
push_back(P);
|
push_back(P);
|
||||||
// Invalidate most derived type.
|
// Invalidate most derived type.
|
||||||
MostDerivedType = SILType();
|
MostDerivedType = SILType();
|
||||||
@@ -539,7 +539,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Append the projections in \p Other onto this.
|
/// Append the projections in \p Other onto this.
|
||||||
NewProjectionPath &append(const NewProjectionPath &Other) {
|
ProjectionPath &append(const ProjectionPath &Other) {
|
||||||
for (auto &X : Other.Path) {
|
for (auto &X : Other.Path) {
|
||||||
push_back(X);
|
push_back(X);
|
||||||
}
|
}
|
||||||
@@ -554,7 +554,7 @@ public:
|
|||||||
/// *NOTE* This method allows for transitions from object types to address
|
/// *NOTE* This method allows for transitions from object types to address
|
||||||
/// types via ref_element_addr. If Start is an address type though, End will
|
/// types via ref_element_addr. If Start is an address type though, End will
|
||||||
/// always also be an address type.
|
/// always also be an address type.
|
||||||
static Optional<NewProjectionPath> getProjectionPath(SILValue Start,
|
static Optional<ProjectionPath> getProjectionPath(SILValue Start,
|
||||||
SILValue End);
|
SILValue End);
|
||||||
|
|
||||||
/// Treating a projection path as an ordered set, if RHS is a prefix of LHS,
|
/// Treating a projection path as an ordered set, if RHS is a prefix of LHS,
|
||||||
@@ -563,8 +563,8 @@ public:
|
|||||||
/// An example of this transformation would be:
|
/// An example of this transformation would be:
|
||||||
///
|
///
|
||||||
/// LHS = [A, B, C, D, E], RHS = [A, B, C] => Result = [D, E]
|
/// LHS = [A, B, C, D, E], RHS = [A, B, C] => Result = [D, E]
|
||||||
static Optional<NewProjectionPath>
|
static Optional<ProjectionPath>
|
||||||
removePrefix(const NewProjectionPath &Path, const NewProjectionPath &Prefix);
|
removePrefix(const ProjectionPath &Path, const ProjectionPath &Prefix);
|
||||||
|
|
||||||
/// Given the SILType Base, expand every leaf nodes in the type tree.
|
/// Given the SILType Base, expand every leaf nodes in the type tree.
|
||||||
///
|
///
|
||||||
@@ -572,7 +572,7 @@ public:
|
|||||||
/// is a leaf node in the type tree.
|
/// is a leaf node in the type tree.
|
||||||
static void expandTypeIntoLeafProjectionPaths(SILType BaseType,
|
static void expandTypeIntoLeafProjectionPaths(SILType BaseType,
|
||||||
SILModule *Mod,
|
SILModule *Mod,
|
||||||
NewProjectionPathList &P);
|
ProjectionPathList &P);
|
||||||
|
|
||||||
/// Given the SILType Base, expand every intermediate and leaf nodes in the
|
/// Given the SILType Base, expand every intermediate and leaf nodes in the
|
||||||
/// type tree.
|
/// type tree.
|
||||||
@@ -581,19 +581,19 @@ public:
|
|||||||
/// is a leaf node in the type tree.
|
/// is a leaf node in the type tree.
|
||||||
static void expandTypeIntoNodeProjectionPaths(SILType BaseType,
|
static void expandTypeIntoNodeProjectionPaths(SILType BaseType,
|
||||||
SILModule *Mod,
|
SILModule *Mod,
|
||||||
NewProjectionPathList &P);
|
ProjectionPathList &P);
|
||||||
|
|
||||||
/// Returns true if the two paths have a non-empty symmetric
|
/// Returns true if the two paths have a non-empty symmetric
|
||||||
/// difference.
|
/// difference.
|
||||||
///
|
///
|
||||||
/// This means that the two objects have the same base but access different
|
/// This means that the two objects have the same base but access different
|
||||||
/// fields of the base object.
|
/// fields of the base object.
|
||||||
bool hasNonEmptySymmetricDifference(const NewProjectionPath &RHS) const;
|
bool hasNonEmptySymmetricDifference(const ProjectionPath &RHS) const;
|
||||||
|
|
||||||
/// Compute the subsequence relation in between LHS and RHS which tells the
|
/// Compute the subsequence relation in between LHS and RHS which tells the
|
||||||
/// user whether or not the two sequences are unrelated, equal, or if one is a
|
/// user whether or not the two sequences are unrelated, equal, or if one is a
|
||||||
/// subsequence of the other.
|
/// subsequence of the other.
|
||||||
SubSeqRelation_t computeSubSeqRelation(const NewProjectionPath &RHS) const;
|
SubSeqRelation_t computeSubSeqRelation(const ProjectionPath &RHS) const;
|
||||||
|
|
||||||
/// Returns true if this is a projection path that takes an address base type
|
/// Returns true if this is a projection path that takes an address base type
|
||||||
/// to an address derived type.
|
/// to an address derived type.
|
||||||
@@ -617,21 +617,21 @@ public:
|
|||||||
SILValue Base);
|
SILValue Base);
|
||||||
|
|
||||||
/// Pushes an element to the path.
|
/// Pushes an element to the path.
|
||||||
void push_back(const NewProjection &Proj) { Path.push_back(Proj); }
|
void push_back(const Projection &Proj) { Path.push_back(Proj); }
|
||||||
|
|
||||||
/// Removes the last element from the path.
|
/// Removes the last element from the path.
|
||||||
void pop_back() { Path.pop_back(); }
|
void pop_back() { Path.pop_back(); }
|
||||||
|
|
||||||
/// Returns the last element of the path.
|
/// Returns the last element of the path.
|
||||||
const NewProjection &back() const { return Path.back(); }
|
const Projection &back() const { return Path.back(); }
|
||||||
|
|
||||||
/// Returns true if LHS and RHS have all the same projections in the same
|
/// Returns true if LHS and RHS have all the same projections in the same
|
||||||
/// order.
|
/// order.
|
||||||
bool operator==(const NewProjectionPath &RHS) const {
|
bool operator==(const ProjectionPath &RHS) const {
|
||||||
return computeSubSeqRelation(RHS) == SubSeqRelation_t::Equal;
|
return computeSubSeqRelation(RHS) == SubSeqRelation_t::Equal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const NewProjectionPath &RHS) const {
|
bool operator!=(const ProjectionPath &RHS) const {
|
||||||
return !(*this == RHS);
|
return !(*this == RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,22 +693,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the hashcode for the new projection path.
|
/// Returns the hashcode for the new projection path.
|
||||||
static inline llvm::hash_code hash_value(const NewProjectionPath &P) {
|
static inline llvm::hash_code hash_value(const ProjectionPath &P) {
|
||||||
return llvm::hash_combine_range(P.begin(), P.end());
|
return llvm::hash_combine_range(P.begin(), P.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the hashcode for the projection path.
|
/// Returns the hashcode for the projection path.
|
||||||
static inline llvm::hash_code hash_value(const NewProjection &P) {
|
static inline llvm::hash_code hash_value(const Projection &P) {
|
||||||
return llvm::hash_combine(static_cast<unsigned>(P.getKind()));
|
return llvm::hash_combine(static_cast<unsigned>(P.getKind()));
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewProjectionTree;
|
class ProjectionTree;
|
||||||
|
|
||||||
class NewProjectionTreeNode {
|
class ProjectionTreeNode {
|
||||||
friend class NewProjectionTree;
|
friend class ProjectionTree;
|
||||||
|
|
||||||
/// The index of the current node in the tree. Can be used to lookup this node
|
/// The index of the current node in the tree. Can be used to lookup this node
|
||||||
/// from the NewProjectionTree. The reason why we use an Index instead of a
|
/// from the ProjectionTree. The reason why we use an Index instead of a
|
||||||
/// pointer is that the SmallVector that we use to store these can reallocate
|
/// pointer is that the SmallVector that we use to store these can reallocate
|
||||||
/// invalidating our pointers.
|
/// invalidating our pointers.
|
||||||
unsigned Index;
|
unsigned Index;
|
||||||
@@ -728,7 +728,7 @@ class NewProjectionTreeNode {
|
|||||||
llvm::SmallVector<SILValue, 4> BaseValues;
|
llvm::SmallVector<SILValue, 4> BaseValues;
|
||||||
|
|
||||||
/// The projection that this node represents. None in the root.
|
/// The projection that this node represents. None in the root.
|
||||||
llvm::Optional<NewProjection> Proj;
|
llvm::Optional<Projection> Proj;
|
||||||
|
|
||||||
/// The index of the parent of this projection tree node in the projection
|
/// The index of the parent of this projection tree node in the projection
|
||||||
/// tree. None in the root.
|
/// tree. None in the root.
|
||||||
@@ -761,13 +761,13 @@ class NewProjectionTreeNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Constructor for the root of the tree.
|
/// Constructor for the root of the tree.
|
||||||
NewProjectionTreeNode(SILType BaseTy)
|
ProjectionTreeNode(SILType BaseTy)
|
||||||
: Index(0), BaseType(BaseTy), BaseValues(), Proj(), Parent(),
|
: Index(0), BaseType(BaseTy), BaseValues(), Proj(), Parent(),
|
||||||
NonProjUsers(), ChildProjections(), Initialized(false), IsLive(false) {}
|
NonProjUsers(), ChildProjections(), Initialized(false), IsLive(false) {}
|
||||||
|
|
||||||
// Normal constructor for non-root nodes.
|
// Normal constructor for non-root nodes.
|
||||||
NewProjectionTreeNode(NewProjectionTreeNode *Parent, unsigned Index, SILType BaseTy,
|
ProjectionTreeNode(ProjectionTreeNode *Parent, unsigned Index, SILType BaseTy,
|
||||||
NewProjection P)
|
Projection P)
|
||||||
: Index(Index), BaseType(BaseTy), BaseValues(), Proj(P),
|
: Index(Index), BaseType(BaseTy), BaseValues(), Proj(P),
|
||||||
Parent(Parent->getIndex()), NonProjUsers(), ChildProjections(),
|
Parent(Parent->getIndex()), NonProjUsers(), ChildProjections(),
|
||||||
Initialized(false), IsLive(false) {}
|
Initialized(false), IsLive(false) {}
|
||||||
@@ -775,14 +775,14 @@ class NewProjectionTreeNode {
|
|||||||
public:
|
public:
|
||||||
class NewAggregateBuilder;
|
class NewAggregateBuilder;
|
||||||
|
|
||||||
~NewProjectionTreeNode() = default;
|
~ProjectionTreeNode() = default;
|
||||||
NewProjectionTreeNode(const NewProjectionTreeNode &) = default;
|
ProjectionTreeNode(const ProjectionTreeNode &) = default;
|
||||||
|
|
||||||
llvm::ArrayRef<unsigned> getChildProjections() {
|
llvm::ArrayRef<unsigned> getChildProjections() {
|
||||||
return llvm::makeArrayRef(ChildProjections);
|
return llvm::makeArrayRef(ChildProjections);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Optional<NewProjection> &getProjection() {
|
llvm::Optional<Projection> &getProjection() {
|
||||||
return Proj;
|
return Proj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,8 +804,8 @@ public:
|
|||||||
return BaseType;
|
return BaseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *getChildForProjection(NewProjectionTree &Tree,
|
ProjectionTreeNode *getChildForProjection(ProjectionTree &Tree,
|
||||||
const NewProjection &P);
|
const Projection &P);
|
||||||
|
|
||||||
NullablePtr<SILInstruction> createProjection(SILBuilder &B, SILLocation Loc,
|
NullablePtr<SILInstruction> createProjection(SILBuilder &B, SILLocation Loc,
|
||||||
SILValue Arg) const;
|
SILValue Arg) const;
|
||||||
@@ -816,17 +816,17 @@ public:
|
|||||||
|
|
||||||
unsigned getIndex() const { return Index; }
|
unsigned getIndex() const { return Index; }
|
||||||
|
|
||||||
NewProjectionTreeNode *getParent(NewProjectionTree &Tree);
|
ProjectionTreeNode *getParent(ProjectionTree &Tree);
|
||||||
const NewProjectionTreeNode *getParent(const NewProjectionTree &Tree) const;
|
const ProjectionTreeNode *getParent(const ProjectionTree &Tree) const;
|
||||||
|
|
||||||
NewProjectionTreeNode *getParentOrNull(NewProjectionTree &Tree) {
|
ProjectionTreeNode *getParentOrNull(ProjectionTree &Tree) {
|
||||||
if (!Parent.hasValue())
|
if (!Parent.hasValue())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return getParent(Tree);
|
return getParent(Tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
llvm::Optional<NewProjection> getProjection() const { return Proj; }
|
llvm::Optional<Projection> getProjection() const { return Proj; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addNonProjectionUser(Operand *Op) {
|
void addNonProjectionUser(Operand *Op) {
|
||||||
@@ -834,42 +834,42 @@ private:
|
|||||||
NonProjUsers.push_back(Op);
|
NonProjUsers.push_back(Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
using ValueNodePair = std::pair<SILValue, NewProjectionTreeNode *>;
|
using ValueNodePair = std::pair<SILValue, ProjectionTreeNode *>;
|
||||||
|
|
||||||
void processUsersOfValue(NewProjectionTree &Tree,
|
void processUsersOfValue(ProjectionTree &Tree,
|
||||||
llvm::SmallVectorImpl<ValueNodePair> &Worklist,
|
llvm::SmallVectorImpl<ValueNodePair> &Worklist,
|
||||||
SILValue Value);
|
SILValue Value);
|
||||||
|
|
||||||
|
|
||||||
void createNextLevelChildren(NewProjectionTree &Tree);
|
void createNextLevelChildren(ProjectionTree &Tree);
|
||||||
|
|
||||||
void createNextLevelChildrenForStruct(NewProjectionTree &Tree, StructDecl *SD);
|
void createNextLevelChildrenForStruct(ProjectionTree &Tree, StructDecl *SD);
|
||||||
|
|
||||||
void createNextLevelChildrenForTuple(NewProjectionTree &Tree, TupleType *TT);
|
void createNextLevelChildrenForTuple(ProjectionTree &Tree, TupleType *TT);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewProjectionTree {
|
class ProjectionTree {
|
||||||
friend class NewProjectionTreeNode;
|
friend class ProjectionTreeNode;
|
||||||
|
|
||||||
SILModule &Mod;
|
SILModule &Mod;
|
||||||
|
|
||||||
llvm::BumpPtrAllocator &Allocator;
|
llvm::BumpPtrAllocator &Allocator;
|
||||||
|
|
||||||
// A common pattern is a 3 field struct.
|
// A common pattern is a 3 field struct.
|
||||||
llvm::SmallVector<NewProjectionTreeNode *, 4> NewProjectionTreeNodes;
|
llvm::SmallVector<ProjectionTreeNode *, 4> ProjectionTreeNodes;
|
||||||
llvm::SmallVector<unsigned, 3> LeafIndices;
|
llvm::SmallVector<unsigned, 3> LeafIndices;
|
||||||
|
|
||||||
using LeafValueMapTy = llvm::DenseMap<unsigned, SILValue>;
|
using LeafValueMapTy = llvm::DenseMap<unsigned, SILValue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Construct a projection tree from BaseTy.
|
/// Construct a projection tree from BaseTy.
|
||||||
NewProjectionTree(SILModule &Mod, llvm::BumpPtrAllocator &Allocator,
|
ProjectionTree(SILModule &Mod, llvm::BumpPtrAllocator &Allocator,
|
||||||
SILType BaseTy);
|
SILType BaseTy);
|
||||||
~NewProjectionTree();
|
~ProjectionTree();
|
||||||
NewProjectionTree(const NewProjectionTree &) = delete;
|
ProjectionTree(const ProjectionTree &) = delete;
|
||||||
NewProjectionTree(NewProjectionTree &&) = default;
|
ProjectionTree(ProjectionTree &&) = default;
|
||||||
NewProjectionTree &operator=(const NewProjectionTree &) = delete;
|
ProjectionTree &operator=(const ProjectionTree &) = delete;
|
||||||
NewProjectionTree &operator=(NewProjectionTree &&) = default;
|
ProjectionTree &operator=(ProjectionTree &&) = default;
|
||||||
|
|
||||||
/// Compute liveness and use information in this projection tree using Base.
|
/// Compute liveness and use information in this projection tree using Base.
|
||||||
/// All debug instructions (debug_value, debug_value_addr) are ignored.
|
/// All debug instructions (debug_value, debug_value_addr) are ignored.
|
||||||
@@ -882,39 +882,39 @@ public:
|
|||||||
llvm::SmallVector<SILValue, 8> &LVs);
|
llvm::SmallVector<SILValue, 8> &LVs);
|
||||||
SILValue computeExplodedArgumentValueInner(SILBuilder &Builder,
|
SILValue computeExplodedArgumentValueInner(SILBuilder &Builder,
|
||||||
SILLocation Loc,
|
SILLocation Loc,
|
||||||
NewProjectionTreeNode *Node,
|
ProjectionTreeNode *Node,
|
||||||
LeafValueMapTy &LeafValues);
|
LeafValueMapTy &LeafValues);
|
||||||
|
|
||||||
/// Return the module associated with this tree.
|
/// Return the module associated with this tree.
|
||||||
SILModule &getModule() const { return Mod; }
|
SILModule &getModule() const { return Mod; }
|
||||||
|
|
||||||
llvm::ArrayRef<NewProjectionTreeNode *> getNewProjectionTreeNodes() {
|
llvm::ArrayRef<ProjectionTreeNode *> getProjectionTreeNodes() {
|
||||||
return llvm::makeArrayRef(NewProjectionTreeNodes);
|
return llvm::makeArrayRef(ProjectionTreeNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over all values in the tree. The function should return false if
|
/// Iterate over all values in the tree. The function should return false if
|
||||||
/// it wants the iteration to end and true if it wants to continue.
|
/// it wants the iteration to end and true if it wants to continue.
|
||||||
void visitNewProjectionTreeNodes(std::function<bool (NewProjectionTreeNode &)> F);
|
void visitProjectionTreeNodes(std::function<bool (ProjectionTreeNode &)> F);
|
||||||
|
|
||||||
NewProjectionTreeNode *getRoot() {
|
ProjectionTreeNode *getRoot() {
|
||||||
return getNode(NewProjectionTreeNode::RootIndex);
|
return getNode(ProjectionTreeNode::RootIndex);
|
||||||
}
|
}
|
||||||
const NewProjectionTreeNode *getRoot() const {
|
const ProjectionTreeNode *getRoot() const {
|
||||||
return getNode(NewProjectionTreeNode::RootIndex);
|
return getNode(ProjectionTreeNode::RootIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *getNode(unsigned i) {
|
ProjectionTreeNode *getNode(unsigned i) {
|
||||||
return NewProjectionTreeNodes[i];
|
return ProjectionTreeNodes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewProjectionTreeNode *getNode(unsigned i) const {
|
const ProjectionTreeNode *getNode(unsigned i) const {
|
||||||
return NewProjectionTreeNodes[i];
|
return ProjectionTreeNodes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSingleton() const {
|
bool isSingleton() const {
|
||||||
// If we only have one root node, there is no interesting explosion
|
// If we only have one root node, there is no interesting explosion
|
||||||
// here. Exit early.
|
// here. Exit early.
|
||||||
if (NewProjectionTreeNodes.size() == 1)
|
if (ProjectionTreeNodes.size() == 1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Now we know that we have multiple level node hierarchy. See if we have a
|
// Now we know that we have multiple level node hierarchy. See if we have a
|
||||||
@@ -938,7 +938,7 @@ public:
|
|||||||
|
|
||||||
void getLeafTypes(llvm::SmallVectorImpl<SILType> &OutArray) const {
|
void getLeafTypes(llvm::SmallVectorImpl<SILType> &OutArray) const {
|
||||||
for (unsigned LeafIndex : LeafIndices) {
|
for (unsigned LeafIndex : LeafIndices) {
|
||||||
const NewProjectionTreeNode *Node = getNode(LeafIndex);
|
const ProjectionTreeNode *Node = getNode(LeafIndex);
|
||||||
assert(Node->IsLive && "We are only interested in leafs that are live");
|
assert(Node->IsLive && "We are only interested in leafs that are live");
|
||||||
OutArray.push_back(Node->getType());
|
OutArray.push_back(Node->getType());
|
||||||
}
|
}
|
||||||
@@ -958,41 +958,41 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void createRoot(SILType BaseTy) {
|
void createRoot(SILType BaseTy) {
|
||||||
assert(NewProjectionTreeNodes.empty() &&
|
assert(ProjectionTreeNodes.empty() &&
|
||||||
"Should only create root when NewProjectionTreeNodes is empty");
|
"Should only create root when ProjectionTreeNodes is empty");
|
||||||
auto *Node = new (Allocator) NewProjectionTreeNode(BaseTy);
|
auto *Node = new (Allocator) ProjectionTreeNode(BaseTy);
|
||||||
NewProjectionTreeNodes.push_back(Node);
|
ProjectionTreeNodes.push_back(Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *createChild(NewProjectionTreeNode *Parent,
|
ProjectionTreeNode *createChild(ProjectionTreeNode *Parent,
|
||||||
SILType BaseTy,
|
SILType BaseTy,
|
||||||
const NewProjection &P) {
|
const Projection &P) {
|
||||||
unsigned Index = NewProjectionTreeNodes.size();
|
unsigned Index = ProjectionTreeNodes.size();
|
||||||
auto *Node = new (Allocator) NewProjectionTreeNode(Parent, Index, BaseTy, P);
|
auto *Node = new (Allocator) ProjectionTreeNode(Parent, Index, BaseTy, P);
|
||||||
NewProjectionTreeNodes.push_back(Node);
|
ProjectionTreeNodes.push_back(Node);
|
||||||
return NewProjectionTreeNodes[Index];
|
return ProjectionTreeNodes[Index];
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
createChildForStruct(NewProjectionTreeNode *Parent, SILType Ty, ValueDecl *VD,
|
createChildForStruct(ProjectionTreeNode *Parent, SILType Ty, ValueDecl *VD,
|
||||||
unsigned Index) {
|
unsigned Index) {
|
||||||
NewProjection P = NewProjection(NewProjectionKind::Struct, Index);
|
Projection P = Projection(ProjectionKind::Struct, Index);
|
||||||
NewProjectionTreeNode *N = createChild(Parent, Ty, P);
|
ProjectionTreeNode *N = createChild(Parent, Ty, P);
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
createChildForClass(NewProjectionTreeNode *Parent, SILType Ty, ValueDecl *VD,
|
createChildForClass(ProjectionTreeNode *Parent, SILType Ty, ValueDecl *VD,
|
||||||
unsigned Index) {
|
unsigned Index) {
|
||||||
NewProjection P = NewProjection(NewProjectionKind::Class, Index);
|
Projection P = Projection(ProjectionKind::Class, Index);
|
||||||
NewProjectionTreeNode *N = createChild(Parent, Ty, P);
|
ProjectionTreeNode *N = createChild(Parent, Ty, P);
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
createChildForTuple(NewProjectionTreeNode *Parent, SILType Ty, unsigned Index) {
|
createChildForTuple(ProjectionTreeNode *Parent, SILType Ty, unsigned Index) {
|
||||||
NewProjection P = NewProjection(NewProjectionKind::Tuple, Index);
|
Projection P = Projection(ProjectionKind::Tuple, Index);
|
||||||
NewProjectionTreeNode *N = createChild(Parent, Ty, P);
|
ProjectionTreeNode *N = createChild(Parent, Ty, P);
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
///
|
///
|
||||||
/// This file defines SILValueProjection, a class containing a SILValue base
|
/// This file defines SILValueProjection, a class containing a SILValue base
|
||||||
/// and a NewProjectionPath. It is used as the base class for LSLocation and
|
/// and a ProjectionPath. It is used as the base class for LSLocation and
|
||||||
/// LSValue.
|
/// LSValue.
|
||||||
///
|
///
|
||||||
/// In the case of LSLocation, the base represents the base of the allocated
|
/// In the case of LSLocation, the base represents the base of the allocated
|
||||||
/// objects and the NewProjectionPath tells which field in the object the
|
/// objects and the ProjectionPath tells which field in the object the
|
||||||
/// LSLocation represents.
|
/// LSLocation represents.
|
||||||
///
|
///
|
||||||
/// In the case of LSValue, the base represents the root of loaded or stored
|
/// In the case of LSValue, the base represents the root of loaded or stored
|
||||||
/// value it represents. And the NewProjectionPath represents the field in the
|
/// value it represents. And the ProjectionPath represents the field in the
|
||||||
/// loaded/store value the LSValue represents.
|
/// loaded/store value the LSValue represents.
|
||||||
///
|
///
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -61,14 +61,14 @@ protected:
|
|||||||
/// Empty key, tombstone key or normal key.
|
/// Empty key, tombstone key or normal key.
|
||||||
KeyKind Kind;
|
KeyKind Kind;
|
||||||
/// The path to reach the accessed field of the object.
|
/// The path to reach the accessed field of the object.
|
||||||
Optional<NewProjectionPath> Path;
|
Optional<ProjectionPath> Path;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructors.
|
/// Constructors.
|
||||||
SILValueProjection() : Base(), Kind(Normal) {}
|
SILValueProjection() : Base(), Kind(Normal) {}
|
||||||
SILValueProjection(KeyKind Kind) : Base(), Kind(Kind) {}
|
SILValueProjection(KeyKind Kind) : Base(), Kind(Kind) {}
|
||||||
SILValueProjection(SILValue B) : Base(B), Kind(Normal) {}
|
SILValueProjection(SILValue B) : Base(B), Kind(Normal) {}
|
||||||
SILValueProjection(SILValue B, const Optional<NewProjectionPath> &P,
|
SILValueProjection(SILValue B, const Optional<ProjectionPath> &P,
|
||||||
KeyKind Kind = Normal)
|
KeyKind Kind = Normal)
|
||||||
: Base(B), Kind(Kind), Path(P) {}
|
: Base(B), Kind(Kind), Path(P) {}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
/// Getters for SILValueProjection.
|
/// Getters for SILValueProjection.
|
||||||
KeyKind getKind() const { return Kind; }
|
KeyKind getKind() const { return Kind; }
|
||||||
SILValue getBase() const { return Base; }
|
SILValue getBase() const { return Base; }
|
||||||
const Optional<NewProjectionPath> &getPath() const { return Path; }
|
const Optional<ProjectionPath> &getPath() const { return Path; }
|
||||||
|
|
||||||
/// Reset the SILValueProjection, i.e. clear base and path.
|
/// Reset the SILValueProjection, i.e. clear base and path.
|
||||||
void reset() {
|
void reset() {
|
||||||
@@ -106,21 +106,21 @@ public:
|
|||||||
virtual bool isValid() const { return Base && Path.hasValue(); }
|
virtual bool isValid() const { return Base && Path.hasValue(); }
|
||||||
|
|
||||||
/// Returns true if the SILValueProjection has a non-empty projection path.
|
/// Returns true if the SILValueProjection has a non-empty projection path.
|
||||||
bool hasEmptyNewProjectionPath() const { return !Path.getValue().size(); }
|
bool hasEmptyProjectionPath() const { return !Path.getValue().size(); }
|
||||||
|
|
||||||
/// return true if that the two objects have the same base but access different
|
/// return true if that the two objects have the same base but access different
|
||||||
/// fields of the base object.
|
/// fields of the base object.
|
||||||
bool hasNonEmptySymmetricPathDifference(const SILValueProjection &RHS) const {
|
bool hasNonEmptySymmetricPathDifference(const SILValueProjection &RHS) const {
|
||||||
const NewProjectionPath &P = RHS.Path.getValue();
|
const ProjectionPath &P = RHS.Path.getValue();
|
||||||
return Path.getValue().hasNonEmptySymmetricDifference(P);
|
return Path.getValue().hasNonEmptySymmetricDifference(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract the given path from the NewProjectionPath.
|
/// Subtract the given path from the ProjectionPath.
|
||||||
void removePathPrefix(Optional<NewProjectionPath> &P) {
|
void removePathPrefix(Optional<ProjectionPath> &P) {
|
||||||
if (!P.hasValue())
|
if (!P.hasValue())
|
||||||
return;
|
return;
|
||||||
// Remove prefix does not modify the Path in-place.
|
// Remove prefix does not modify the Path in-place.
|
||||||
Path = NewProjectionPath::removePrefix(Path.getValue(), P.getValue());
|
Path = ProjectionPath::removePrefix(Path.getValue(), P.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if the RHS have identical projection paths.
|
/// Return true if the RHS have identical projection paths.
|
||||||
@@ -174,13 +174,13 @@ public:
|
|||||||
/// Create a path of AddrProjection or ValueProjection with the given VA
|
/// Create a path of AddrProjection or ValueProjection with the given VA
|
||||||
/// and Path.
|
/// and Path.
|
||||||
static SILValue createExtract(SILValue VA,
|
static SILValue createExtract(SILValue VA,
|
||||||
const Optional<NewProjectionPath> &Path,
|
const Optional<ProjectionPath> &Path,
|
||||||
SILInstruction *Inst, bool IsValExt);
|
SILInstruction *Inst, bool IsValExt);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline llvm::hash_code hash_value(const SILValueProjection &S) {
|
static inline llvm::hash_code hash_value(const SILValueProjection &S) {
|
||||||
const SILValue Base = S.getBase();
|
const SILValue Base = S.getBase();
|
||||||
const Optional<NewProjectionPath> &Path = S.getPath();
|
const Optional<ProjectionPath> &Path = S.getPath();
|
||||||
llvm::hash_code HC = llvm::hash_combine(Base.getOpaqueValue());
|
llvm::hash_code HC = llvm::hash_combine(Base.getOpaqueValue());
|
||||||
if (!Path.hasValue())
|
if (!Path.hasValue())
|
||||||
return HC;
|
return HC;
|
||||||
@@ -234,7 +234,7 @@ using ValueTableMap = llvm::SmallMapVector<unsigned, unsigned, 8>;
|
|||||||
///
|
///
|
||||||
/// LSValue can take 2 forms.
|
/// LSValue can take 2 forms.
|
||||||
///
|
///
|
||||||
/// 1. It can take a concrete value, i.e. with a valid Base and NewProjectionPath.
|
/// 1. It can take a concrete value, i.e. with a valid Base and ProjectionPath.
|
||||||
/// using the extract function, it can be materialized in IR.
|
/// using the extract function, it can be materialized in IR.
|
||||||
///
|
///
|
||||||
/// 2. It can represent a covering set of LSValues from all predecessor
|
/// 2. It can represent a covering set of LSValues from all predecessor
|
||||||
@@ -246,9 +246,9 @@ using ValueTableMap = llvm::SmallMapVector<unsigned, unsigned, 8>;
|
|||||||
/// reduce will create the forwarding SILValue by merging them while
|
/// reduce will create the forwarding SILValue by merging them while
|
||||||
/// creating as few value extraction and aggregation as possible.
|
/// creating as few value extraction and aggregation as possible.
|
||||||
///
|
///
|
||||||
/// NOTE: NewProjectionPath in LSValue could be replaced by the
|
/// NOTE: ProjectionPath in LSValue could be replaced by the
|
||||||
/// NewProjectionPath in the LSLocation, but that would require we break the
|
/// ProjectionPath in the LSLocation, but that would require we break the
|
||||||
/// NewProjectionPath into 2 parts, 1 for the Base to the accessed (aggregate) node
|
/// ProjectionPath into 2 parts, 1 for the Base to the accessed (aggregate) node
|
||||||
/// and another 1 for the accessed (aggregate) node to the leaf node the
|
/// and another 1 for the accessed (aggregate) node to the leaf node the
|
||||||
/// LSLocation represents.
|
/// LSLocation represents.
|
||||||
///
|
///
|
||||||
@@ -263,7 +263,7 @@ class LSValue : public SILValueProjection {
|
|||||||
public:
|
public:
|
||||||
/// Constructors.
|
/// Constructors.
|
||||||
LSValue() : SILValueProjection(), IsCoveringValue(false) {}
|
LSValue() : SILValueProjection(), IsCoveringValue(false) {}
|
||||||
LSValue(SILValue B, const NewProjectionPath &P)
|
LSValue(SILValue B, const ProjectionPath &P)
|
||||||
: SILValueProjection(B, P), IsCoveringValue(false) {
|
: SILValueProjection(B, P), IsCoveringValue(false) {
|
||||||
assert(isValid() && "Trying to create invalid LSValue");
|
assert(isValid() && "Trying to create invalid LSValue");
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// TODO: we do not really need the llvm::DenseMap<LSLocation, LSValue> here
|
/// TODO: we do not really need the llvm::DenseMap<LSLocation, LSValue> here
|
||||||
/// we only need a map between the projection tree of a SILType and the value
|
/// we only need a map between the projection tree of a SILType and the value
|
||||||
/// each leaf node takes. This will be implemented once NewProjectionPath memory
|
/// each leaf node takes. This will be implemented once ProjectionPath memory
|
||||||
/// cost is reduced and made copyable (its copy constructor is deleted at the
|
/// cost is reduced and made copyable (its copy constructor is deleted at the
|
||||||
/// moment).
|
/// moment).
|
||||||
static SILValue reduce(LSLocation &Base, SILModule *Mod,
|
static SILValue reduce(LSLocation &Base, SILModule *Mod,
|
||||||
@@ -404,20 +404,20 @@ class LSLocation : public SILValueProjection {
|
|||||||
public:
|
public:
|
||||||
/// Constructors.
|
/// Constructors.
|
||||||
LSLocation() {}
|
LSLocation() {}
|
||||||
LSLocation(SILValue B, const Optional<NewProjectionPath> &P, KeyKind K = Normal)
|
LSLocation(SILValue B, const Optional<ProjectionPath> &P, KeyKind K = Normal)
|
||||||
: SILValueProjection(B, P, K) {}
|
: SILValueProjection(B, P, K) {}
|
||||||
LSLocation(KeyKind Kind) : SILValueProjection(Kind) {}
|
LSLocation(KeyKind Kind) : SILValueProjection(Kind) {}
|
||||||
/// Use the concatenation of the 2 NewProjectionPaths as the Path.
|
/// Use the concatenation of the 2 ProjectionPaths as the Path.
|
||||||
LSLocation(SILValue B, const NewProjectionPath &BP, const NewProjectionPath &AP)
|
LSLocation(SILValue B, const ProjectionPath &BP, const ProjectionPath &AP)
|
||||||
: SILValueProjection(B) {
|
: SILValueProjection(B) {
|
||||||
NewProjectionPath P((*Base).getType());
|
ProjectionPath P((*Base).getType());
|
||||||
P.append(BP);
|
P.append(BP);
|
||||||
P.append(AP);
|
P.append(AP);
|
||||||
Path = P;
|
Path = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize a location with a new set of base, projectionpath and kind.
|
/// Initialize a location with a new set of base, projectionpath and kind.
|
||||||
void init(SILValue B, const Optional<NewProjectionPath> &P, KeyKind K= Normal) {
|
void init(SILValue B, const Optional<ProjectionPath> &P, KeyKind K= Normal) {
|
||||||
Base = B;
|
Base = B;
|
||||||
Path = P;
|
Path = P;
|
||||||
Kind = K;
|
Kind = K;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ enum class TEKind {
|
|||||||
TENode // Intermediate and leaf nodes expansion.
|
TENode // Intermediate and leaf nodes expansion.
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypeExpansionMap = llvm::DenseMap<SILType, NewProjectionPathList>;
|
using TypeExpansionMap = llvm::DenseMap<SILType, ProjectionPathList>;
|
||||||
|
|
||||||
/// This analysis determines memory effects during destruction.
|
/// This analysis determines memory effects during destruction.
|
||||||
class TypeExpansionAnalysis : public SILAnalysis {
|
class TypeExpansionAnalysis : public SILAnalysis {
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return ProjectionPath to every leaf or intermediate node of the given type.
|
/// Return ProjectionPath to every leaf or intermediate node of the given type.
|
||||||
const NewProjectionPathList &getTypeExpansion(SILType B, SILModule *Mod,
|
const ProjectionPathList &getTypeExpansion(SILType B, SILModule *Mod,
|
||||||
TEKind K);
|
TEKind K);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ SILValue swift::stripClassCasts(SILValue V) {
|
|||||||
SILValue swift::stripAddressProjections(SILValue V) {
|
SILValue swift::stripAddressProjections(SILValue V) {
|
||||||
while (true) {
|
while (true) {
|
||||||
V = stripSinglePredecessorArgs(V);
|
V = stripSinglePredecessorArgs(V);
|
||||||
if (!NewProjection::isAddressProjection(V))
|
if (!Projection::isAddressProjection(V))
|
||||||
return V;
|
return V;
|
||||||
V = cast<SILInstruction>(V)->getOperand(0);
|
V = cast<SILInstruction>(V)->getOperand(0);
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ SILValue swift::stripAddressProjections(SILValue V) {
|
|||||||
SILValue swift::stripUnaryAddressProjections(SILValue V) {
|
SILValue swift::stripUnaryAddressProjections(SILValue V) {
|
||||||
while (true) {
|
while (true) {
|
||||||
V = stripSinglePredecessorArgs(V);
|
V = stripSinglePredecessorArgs(V);
|
||||||
if (!NewProjection::isAddressProjection(V))
|
if (!Projection::isAddressProjection(V))
|
||||||
return V;
|
return V;
|
||||||
auto *Inst = cast<SILInstruction>(V);
|
auto *Inst = cast<SILInstruction>(V);
|
||||||
if (Inst->getNumOperands() > 1)
|
if (Inst->getNumOperands() > 1)
|
||||||
@@ -156,7 +156,7 @@ SILValue swift::stripUnaryAddressProjections(SILValue V) {
|
|||||||
SILValue swift::stripValueProjections(SILValue V) {
|
SILValue swift::stripValueProjections(SILValue V) {
|
||||||
while (true) {
|
while (true) {
|
||||||
V = stripSinglePredecessorArgs(V);
|
V = stripSinglePredecessorArgs(V);
|
||||||
if (!NewProjection::isObjectProjection(V))
|
if (!Projection::isObjectProjection(V))
|
||||||
return V;
|
return V;
|
||||||
V = cast<SILInstruction>(V)->getOperand(0);
|
V = cast<SILInstruction>(V)->getOperand(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ using namespace swift;
|
|||||||
/// These are just for performance and verification. If one needs to make
|
/// These are just for performance and verification. If one needs to make
|
||||||
/// changes that cause the asserts the fire, please update them. The purpose is
|
/// changes that cause the asserts the fire, please update them. The purpose is
|
||||||
/// to prevent these predicates from changing values by mistake.
|
/// to prevent these predicates from changing values by mistake.
|
||||||
static_assert(std::is_standard_layout<NewProjection>::value,
|
static_assert(std::is_standard_layout<Projection>::value,
|
||||||
"Expected projection to be a standard layout type");
|
"Expected projection to be a standard layout type");
|
||||||
|
|
||||||
|
|
||||||
@@ -51,10 +51,10 @@ bool swift::getIntegerIndex(SILValue IndexVal, unsigned &IndexConst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// New Projection
|
// Projection
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
NewProjection::NewProjection(SILInstruction *I) : Value() {
|
Projection::Projection(SILInstruction *I) : Value() {
|
||||||
if (!I)
|
if (!I)
|
||||||
return;
|
return;
|
||||||
/// Initialize given the specific instruction type and verify with asserts
|
/// Initialize given the specific instruction type and verify with asserts
|
||||||
@@ -66,8 +66,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
return;
|
return;
|
||||||
case ValueKind::StructElementAddrInst: {
|
case ValueKind::StructElementAddrInst: {
|
||||||
auto *SEAI = cast<StructElementAddrInst>(I);
|
auto *SEAI = cast<StructElementAddrInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Struct, SEAI->getFieldNo());
|
Value = ValueTy(ProjectionKind::Struct, SEAI->getFieldNo());
|
||||||
assert(getKind() == NewProjectionKind::Struct);
|
assert(getKind() == ProjectionKind::Struct);
|
||||||
assert(getIndex() == SEAI->getFieldNo());
|
assert(getIndex() == SEAI->getFieldNo());
|
||||||
assert(getType(SEAI->getOperand()->getType(), SEAI->getModule()) ==
|
assert(getType(SEAI->getOperand()->getType(), SEAI->getModule()) ==
|
||||||
SEAI->getType());
|
SEAI->getType());
|
||||||
@@ -75,8 +75,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::StructExtractInst: {
|
case ValueKind::StructExtractInst: {
|
||||||
auto *SEI = cast<StructExtractInst>(I);
|
auto *SEI = cast<StructExtractInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Struct, SEI->getFieldNo());
|
Value = ValueTy(ProjectionKind::Struct, SEI->getFieldNo());
|
||||||
assert(getKind() == NewProjectionKind::Struct);
|
assert(getKind() == ProjectionKind::Struct);
|
||||||
assert(getIndex() == SEI->getFieldNo());
|
assert(getIndex() == SEI->getFieldNo());
|
||||||
assert(getType(SEI->getOperand()->getType(), SEI->getModule()) ==
|
assert(getType(SEI->getOperand()->getType(), SEI->getModule()) ==
|
||||||
SEI->getType());
|
SEI->getType());
|
||||||
@@ -84,8 +84,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::RefElementAddrInst: {
|
case ValueKind::RefElementAddrInst: {
|
||||||
auto *REAI = cast<RefElementAddrInst>(I);
|
auto *REAI = cast<RefElementAddrInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Class, REAI->getFieldNo());
|
Value = ValueTy(ProjectionKind::Class, REAI->getFieldNo());
|
||||||
assert(getKind() == NewProjectionKind::Class);
|
assert(getKind() == ProjectionKind::Class);
|
||||||
assert(getIndex() == REAI->getFieldNo());
|
assert(getIndex() == REAI->getFieldNo());
|
||||||
assert(getType(REAI->getOperand()->getType(), REAI->getModule()) ==
|
assert(getType(REAI->getOperand()->getType(), REAI->getModule()) ==
|
||||||
REAI->getType());
|
REAI->getType());
|
||||||
@@ -93,8 +93,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::ProjectBoxInst: {
|
case ValueKind::ProjectBoxInst: {
|
||||||
auto *PBI = cast<ProjectBoxInst>(I);
|
auto *PBI = cast<ProjectBoxInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Box, (unsigned)0);
|
Value = ValueTy(ProjectionKind::Box, (unsigned)0);
|
||||||
assert(getKind() == NewProjectionKind::Box);
|
assert(getKind() == ProjectionKind::Box);
|
||||||
assert(getIndex() == 0);
|
assert(getIndex() == 0);
|
||||||
assert(getType(PBI->getOperand()->getType(), PBI->getModule()) ==
|
assert(getType(PBI->getOperand()->getType(), PBI->getModule()) ==
|
||||||
PBI->getType());
|
PBI->getType());
|
||||||
@@ -103,8 +103,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::TupleExtractInst: {
|
case ValueKind::TupleExtractInst: {
|
||||||
auto *TEI = cast<TupleExtractInst>(I);
|
auto *TEI = cast<TupleExtractInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Tuple, TEI->getFieldNo());
|
Value = ValueTy(ProjectionKind::Tuple, TEI->getFieldNo());
|
||||||
assert(getKind() == NewProjectionKind::Tuple);
|
assert(getKind() == ProjectionKind::Tuple);
|
||||||
assert(getIndex() == TEI->getFieldNo());
|
assert(getIndex() == TEI->getFieldNo());
|
||||||
assert(getType(TEI->getOperand()->getType(), TEI->getModule()) ==
|
assert(getType(TEI->getOperand()->getType(), TEI->getModule()) ==
|
||||||
TEI->getType());
|
TEI->getType());
|
||||||
@@ -112,8 +112,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::TupleElementAddrInst: {
|
case ValueKind::TupleElementAddrInst: {
|
||||||
auto *TEAI = cast<TupleElementAddrInst>(I);
|
auto *TEAI = cast<TupleElementAddrInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Tuple, TEAI->getFieldNo());
|
Value = ValueTy(ProjectionKind::Tuple, TEAI->getFieldNo());
|
||||||
assert(getKind() == NewProjectionKind::Tuple);
|
assert(getKind() == ProjectionKind::Tuple);
|
||||||
assert(getIndex() == TEAI->getFieldNo());
|
assert(getIndex() == TEAI->getFieldNo());
|
||||||
assert(getType(TEAI->getOperand()->getType(), TEAI->getModule()) ==
|
assert(getType(TEAI->getOperand()->getType(), TEAI->getModule()) ==
|
||||||
TEAI->getType());
|
TEAI->getType());
|
||||||
@@ -121,8 +121,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::UncheckedEnumDataInst: {
|
case ValueKind::UncheckedEnumDataInst: {
|
||||||
auto *UEDI = cast<UncheckedEnumDataInst>(I);
|
auto *UEDI = cast<UncheckedEnumDataInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Enum, UEDI->getElementNo());
|
Value = ValueTy(ProjectionKind::Enum, UEDI->getElementNo());
|
||||||
assert(getKind() == NewProjectionKind::Enum);
|
assert(getKind() == ProjectionKind::Enum);
|
||||||
assert(getIndex() == UEDI->getElementNo());
|
assert(getIndex() == UEDI->getElementNo());
|
||||||
assert(getType(UEDI->getOperand()->getType(), UEDI->getModule()) ==
|
assert(getType(UEDI->getOperand()->getType(), UEDI->getModule()) ==
|
||||||
UEDI->getType());
|
UEDI->getType());
|
||||||
@@ -130,8 +130,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
case ValueKind::UncheckedTakeEnumDataAddrInst: {
|
case ValueKind::UncheckedTakeEnumDataAddrInst: {
|
||||||
auto *UTEDAI = cast<UncheckedTakeEnumDataAddrInst>(I);
|
auto *UTEDAI = cast<UncheckedTakeEnumDataAddrInst>(I);
|
||||||
Value = ValueTy(NewProjectionKind::Enum, UTEDAI->getElementNo());
|
Value = ValueTy(ProjectionKind::Enum, UTEDAI->getElementNo());
|
||||||
assert(getKind() == NewProjectionKind::Enum);
|
assert(getKind() == ProjectionKind::Enum);
|
||||||
assert(getIndex() == UTEDAI->getElementNo());
|
assert(getIndex() == UTEDAI->getElementNo());
|
||||||
assert(getType(UTEDAI->getOperand()->getType(), UTEDAI->getModule()) ==
|
assert(getType(UTEDAI->getOperand()->getType(), UTEDAI->getModule()) ==
|
||||||
UTEDAI->getType());
|
UTEDAI->getType());
|
||||||
@@ -148,8 +148,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
if (getIntegerIndex(IAI->getIndex(), NewIndex)) {
|
if (getIntegerIndex(IAI->getIndex(), NewIndex)) {
|
||||||
assert(NewIndex != unsigned(~0) && "NewIndex should have been changed "
|
assert(NewIndex != unsigned(~0) && "NewIndex should have been changed "
|
||||||
"by getIntegerIndex?!");
|
"by getIntegerIndex?!");
|
||||||
Value = ValueTy(NewProjectionKind::Index, NewIndex);
|
Value = ValueTy(ProjectionKind::Index, NewIndex);
|
||||||
assert(getKind() == NewProjectionKind::Index);
|
assert(getKind() == ProjectionKind::Index);
|
||||||
assert(getIndex() == NewIndex);
|
assert(getIndex() == NewIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -157,8 +157,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
case ValueKind::UpcastInst: {
|
case ValueKind::UpcastInst: {
|
||||||
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
||||||
assert(Ty->isCanonical());
|
assert(Ty->isCanonical());
|
||||||
Value = ValueTy(NewProjectionKind::Upcast, Ty);
|
Value = ValueTy(ProjectionKind::Upcast, Ty);
|
||||||
assert(getKind() == NewProjectionKind::Upcast);
|
assert(getKind() == ProjectionKind::Upcast);
|
||||||
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
||||||
I->getType());
|
I->getType());
|
||||||
break;
|
break;
|
||||||
@@ -166,8 +166,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
case ValueKind::UncheckedRefCastInst: {
|
case ValueKind::UncheckedRefCastInst: {
|
||||||
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
||||||
assert(Ty->isCanonical());
|
assert(Ty->isCanonical());
|
||||||
Value = ValueTy(NewProjectionKind::RefCast, Ty);
|
Value = ValueTy(ProjectionKind::RefCast, Ty);
|
||||||
assert(getKind() == NewProjectionKind::RefCast);
|
assert(getKind() == ProjectionKind::RefCast);
|
||||||
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
||||||
I->getType());
|
I->getType());
|
||||||
break;
|
break;
|
||||||
@@ -176,8 +176,8 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
case ValueKind::UncheckedAddrCastInst: {
|
case ValueKind::UncheckedAddrCastInst: {
|
||||||
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
auto *Ty = I->getType().getSwiftRValueType().getPointer();
|
||||||
assert(Ty->isCanonical());
|
assert(Ty->isCanonical());
|
||||||
Value = ValueTy(NewProjectionKind::BitwiseCast, Ty);
|
Value = ValueTy(ProjectionKind::BitwiseCast, Ty);
|
||||||
assert(getKind() == NewProjectionKind::BitwiseCast);
|
assert(getKind() == ProjectionKind::BitwiseCast);
|
||||||
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
assert(getType(I->getOperand(0)->getType(), I->getModule()) ==
|
||||||
I->getType());
|
I->getType());
|
||||||
break;
|
break;
|
||||||
@@ -186,7 +186,7 @@ NewProjection::NewProjection(SILInstruction *I) : Value() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NullablePtr<SILInstruction>
|
NullablePtr<SILInstruction>
|
||||||
NewProjection::createObjectProjection(SILBuilder &B, SILLocation Loc,
|
Projection::createObjectProjection(SILBuilder &B, SILLocation Loc,
|
||||||
SILValue Base) const {
|
SILValue Base) const {
|
||||||
SILType BaseTy = Base->getType();
|
SILType BaseTy = Base->getType();
|
||||||
|
|
||||||
@@ -198,29 +198,29 @@ NewProjection::createObjectProjection(SILBuilder &B, SILLocation Loc,
|
|||||||
// of this projection match and that this projection can be represented as
|
// of this projection match and that this projection can be represented as
|
||||||
// value. Create the instruction if we can. Otherwise, return nullptr.
|
// value. Create the instruction if we can. Otherwise, return nullptr.
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
return B.createStructExtract(Loc, Base, getVarDecl(BaseTy));
|
return B.createStructExtract(Loc, Base, getVarDecl(BaseTy));
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
return B.createTupleExtract(Loc, Base, getIndex());
|
return B.createTupleExtract(Loc, Base, getIndex());
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
return B.createUncheckedEnumData(Loc, Base, getEnumElementDecl(BaseTy));
|
return B.createUncheckedEnumData(Loc, Base, getEnumElementDecl(BaseTy));
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
return B.createUpcast(Loc, Base, getCastType(BaseTy));
|
return B.createUpcast(Loc, Base, getCastType(BaseTy));
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
return B.createUncheckedRefCast(Loc, Base, getCastType(BaseTy));
|
return B.createUncheckedRefCast(Loc, Base, getCastType(BaseTy));
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
return B.createUncheckedBitwiseCast(Loc, Base, getCastType(BaseTy));
|
return B.createUncheckedBitwiseCast(Loc, Base, getCastType(BaseTy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NullablePtr<SILInstruction>
|
NullablePtr<SILInstruction>
|
||||||
NewProjection::createAddressProjection(SILBuilder &B, SILLocation Loc,
|
Projection::createAddressProjection(SILBuilder &B, SILLocation Loc,
|
||||||
SILValue Base) const {
|
SILValue Base) const {
|
||||||
SILType BaseTy = Base->getType();
|
SILType BaseTy = Base->getType();
|
||||||
|
|
||||||
@@ -233,40 +233,40 @@ NewProjection::createAddressProjection(SILBuilder &B, SILLocation Loc,
|
|||||||
// of this projection match and that this projection can be represented as
|
// of this projection match and that this projection can be represented as
|
||||||
// value. Create the instruction if we can. Otherwise, return nullptr.
|
// value. Create the instruction if we can. Otherwise, return nullptr.
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
return B.createStructElementAddr(Loc, Base, getVarDecl(BaseTy));
|
return B.createStructElementAddr(Loc, Base, getVarDecl(BaseTy));
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
return B.createTupleElementAddr(Loc, Base, getIndex());
|
return B.createTupleElementAddr(Loc, Base, getIndex());
|
||||||
case NewProjectionKind::Index: {
|
case ProjectionKind::Index: {
|
||||||
auto IntLiteralTy =
|
auto IntLiteralTy =
|
||||||
SILType::getBuiltinIntegerType(64, B.getModule().getASTContext());
|
SILType::getBuiltinIntegerType(64, B.getModule().getASTContext());
|
||||||
auto IntLiteralIndex =
|
auto IntLiteralIndex =
|
||||||
B.createIntegerLiteral(Loc, IntLiteralTy, getIndex());
|
B.createIntegerLiteral(Loc, IntLiteralTy, getIndex());
|
||||||
return B.createIndexAddr(Loc, Base, IntLiteralIndex);
|
return B.createIndexAddr(Loc, Base, IntLiteralIndex);
|
||||||
}
|
}
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
return B.createUncheckedTakeEnumDataAddr(Loc, Base,
|
return B.createUncheckedTakeEnumDataAddr(Loc, Base,
|
||||||
getEnumElementDecl(BaseTy));
|
getEnumElementDecl(BaseTy));
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
return B.createRefElementAddr(Loc, Base, getVarDecl(BaseTy));
|
return B.createRefElementAddr(Loc, Base, getVarDecl(BaseTy));
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
return B.createProjectBox(Loc, Base);
|
return B.createProjectBox(Loc, Base);
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
return B.createUpcast(Loc, Base, getCastType(BaseTy));
|
return B.createUpcast(Loc, Base, getCastType(BaseTy));
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
return B.createUncheckedAddrCast(Loc, Base, getCastType(BaseTy));
|
return B.createUncheckedAddrCast(Loc, Base, getCastType(BaseTy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewProjection::getFirstLevelProjections(
|
void Projection::getFirstLevelProjections(
|
||||||
SILType Ty, SILModule &Mod, llvm::SmallVectorImpl<NewProjection> &Out) {
|
SILType Ty, SILModule &Mod, llvm::SmallVectorImpl<Projection> &Out) {
|
||||||
if (auto *S = Ty.getStructOrBoundGenericStruct()) {
|
if (auto *S = Ty.getStructOrBoundGenericStruct()) {
|
||||||
unsigned Count = 0;
|
unsigned Count = 0;
|
||||||
for (auto *VDecl : S->getStoredProperties()) {
|
for (auto *VDecl : S->getStoredProperties()) {
|
||||||
(void) VDecl;
|
(void) VDecl;
|
||||||
NewProjection P(NewProjectionKind::Struct, Count++);
|
Projection P(ProjectionKind::Struct, Count++);
|
||||||
DEBUG(NewProjectionPath X(Ty);
|
DEBUG(ProjectionPath X(Ty);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty);
|
assert(X.getMostDerivedType(Mod) == Ty);
|
||||||
X.append(P);
|
X.append(P);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod));
|
assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod));
|
||||||
@@ -278,8 +278,8 @@ void NewProjection::getFirstLevelProjections(
|
|||||||
|
|
||||||
if (auto TT = Ty.getAs<TupleType>()) {
|
if (auto TT = Ty.getAs<TupleType>()) {
|
||||||
for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) {
|
||||||
NewProjection P(NewProjectionKind::Tuple, i);
|
Projection P(ProjectionKind::Tuple, i);
|
||||||
DEBUG(NewProjectionPath X(Ty);
|
DEBUG(ProjectionPath X(Ty);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty);
|
assert(X.getMostDerivedType(Mod) == Ty);
|
||||||
X.append(P);
|
X.append(P);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty.getTupleElementType(i));
|
assert(X.getMostDerivedType(Mod) == Ty.getTupleElementType(i));
|
||||||
@@ -293,8 +293,8 @@ void NewProjection::getFirstLevelProjections(
|
|||||||
unsigned Count = 0;
|
unsigned Count = 0;
|
||||||
for (auto *VDecl : C->getStoredProperties()) {
|
for (auto *VDecl : C->getStoredProperties()) {
|
||||||
(void) VDecl;
|
(void) VDecl;
|
||||||
NewProjection P(NewProjectionKind::Class, Count++);
|
Projection P(ProjectionKind::Class, Count++);
|
||||||
DEBUG(NewProjectionPath X(Ty);
|
DEBUG(ProjectionPath X(Ty);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty);
|
assert(X.getMostDerivedType(Mod) == Ty);
|
||||||
X.append(P);
|
X.append(P);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod));
|
assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod));
|
||||||
@@ -305,8 +305,8 @@ void NewProjection::getFirstLevelProjections(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto Box = Ty.getAs<SILBoxType>()) {
|
if (auto Box = Ty.getAs<SILBoxType>()) {
|
||||||
NewProjection P(NewProjectionKind::Box, (unsigned)0);
|
Projection P(ProjectionKind::Box, (unsigned)0);
|
||||||
DEBUG(NewProjectionPath X(Ty);
|
DEBUG(ProjectionPath X(Ty);
|
||||||
assert(X.getMostDerivedType(Mod) == Ty);
|
assert(X.getMostDerivedType(Mod) == Ty);
|
||||||
X.append(P);
|
X.append(P);
|
||||||
assert(X.getMostDerivedType(Mod) == SILType::getPrimitiveAddressType(
|
assert(X.getMostDerivedType(Mod) == SILType::getPrimitiveAddressType(
|
||||||
@@ -322,9 +322,9 @@ void NewProjection::getFirstLevelProjections(
|
|||||||
// New Projection Path
|
// New Projection Path
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
Optional<NewProjectionPath> NewProjectionPath::getProjectionPath(SILValue Start,
|
Optional<ProjectionPath> ProjectionPath::getProjectionPath(SILValue Start,
|
||||||
SILValue End) {
|
SILValue End) {
|
||||||
NewProjectionPath P(Start->getType(), End->getType());
|
ProjectionPath P(Start->getType(), End->getType());
|
||||||
|
|
||||||
// If Start == End, there is a "trivial" projection path in between the
|
// If Start == End, there is a "trivial" projection path in between the
|
||||||
// two. This is represented by returning an empty ProjectionPath.
|
// two. This is represented by returning an empty ProjectionPath.
|
||||||
@@ -339,7 +339,7 @@ Optional<NewProjectionPath> NewProjectionPath::getProjectionPath(SILValue Start,
|
|||||||
|
|
||||||
auto Iter = End;
|
auto Iter = End;
|
||||||
while (Start != Iter) {
|
while (Start != Iter) {
|
||||||
NewProjection AP(Iter);
|
Projection AP(Iter);
|
||||||
if (!AP.isValid())
|
if (!AP.isValid())
|
||||||
break;
|
break;
|
||||||
P.Path.push_back(AP);
|
P.Path.push_back(AP);
|
||||||
@@ -348,7 +348,7 @@ Optional<NewProjectionPath> NewProjectionPath::getProjectionPath(SILValue Start,
|
|||||||
|
|
||||||
// Return None if we have an empty projection list or if Start == Iter.
|
// Return None if we have an empty projection list or if Start == Iter.
|
||||||
// We do not worry about th implicit #0 in case of index_addr, as the
|
// We do not worry about th implicit #0 in case of index_addr, as the
|
||||||
// NewProjectionPath never allow paths to be compared as a list of indices.
|
// ProjectionPath never allow paths to be compared as a list of indices.
|
||||||
// Only the encoded type+index pair will be compared.
|
// Only the encoded type+index pair will be compared.
|
||||||
if (P.empty() || Start != Iter)
|
if (P.empty() || Start != Iter)
|
||||||
return llvm::NoneType::None;
|
return llvm::NoneType::None;
|
||||||
@@ -364,8 +364,8 @@ Optional<NewProjectionPath> NewProjectionPath::getProjectionPath(SILValue Start,
|
|||||||
///
|
///
|
||||||
/// This means that the two objects have the same base but access different
|
/// This means that the two objects have the same base but access different
|
||||||
/// fields of the base object.
|
/// fields of the base object.
|
||||||
bool NewProjectionPath::hasNonEmptySymmetricDifference(
|
bool ProjectionPath::hasNonEmptySymmetricDifference(
|
||||||
const NewProjectionPath &RHS) const {
|
const ProjectionPath &RHS) const {
|
||||||
// First make sure that both of our base types are the same.
|
// First make sure that both of our base types are the same.
|
||||||
if (BaseType != RHS.BaseType)
|
if (BaseType != RHS.BaseType)
|
||||||
return false;
|
return false;
|
||||||
@@ -389,8 +389,8 @@ bool NewProjectionPath::hasNonEmptySymmetricDifference(
|
|||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (unsigned e = std::min(size(), RHS.size()); i != e; ++i) {
|
for (unsigned e = std::min(size(), RHS.size()); i != e; ++i) {
|
||||||
// Grab the current projections.
|
// Grab the current projections.
|
||||||
const NewProjection &LHSProj = *LHSIter;
|
const Projection &LHSProj = *LHSIter;
|
||||||
const NewProjection &RHSProj = *RHSIter;
|
const Projection &RHSProj = *RHSIter;
|
||||||
|
|
||||||
// If we are accessing different fields of a common object, the two
|
// If we are accessing different fields of a common object, the two
|
||||||
// projection paths may have a non-empty symmetric difference. We check if
|
// projection paths may have a non-empty symmetric difference. We check if
|
||||||
@@ -433,7 +433,7 @@ bool NewProjectionPath::hasNonEmptySymmetricDifference(
|
|||||||
|
|
||||||
/// TODO: Integrate has empty non-symmetric difference into here.
|
/// TODO: Integrate has empty non-symmetric difference into here.
|
||||||
SubSeqRelation_t
|
SubSeqRelation_t
|
||||||
NewProjectionPath::computeSubSeqRelation(const NewProjectionPath &RHS) const {
|
ProjectionPath::computeSubSeqRelation(const ProjectionPath &RHS) const {
|
||||||
// Make sure that both base types are the same. Otherwise, we can not compare
|
// Make sure that both base types are the same. Otherwise, we can not compare
|
||||||
// the projections as sequences.
|
// the projections as sequences.
|
||||||
if (BaseType != RHS.BaseType)
|
if (BaseType != RHS.BaseType)
|
||||||
@@ -451,8 +451,8 @@ NewProjectionPath::computeSubSeqRelation(const NewProjectionPath &RHS) const {
|
|||||||
// For each index i until min path size...
|
// For each index i until min path size...
|
||||||
for (unsigned i = 0; i != MinPathSize; ++i) {
|
for (unsigned i = 0; i != MinPathSize; ++i) {
|
||||||
// Grab the current projections.
|
// Grab the current projections.
|
||||||
const NewProjection &LHSProj = *LHSIter;
|
const Projection &LHSProj = *LHSIter;
|
||||||
const NewProjection &RHSProj = *RHSIter;
|
const Projection &RHSProj = *RHSIter;
|
||||||
|
|
||||||
// If the two projections do not equal exactly, return Unrelated.
|
// If the two projections do not equal exactly, return Unrelated.
|
||||||
//
|
//
|
||||||
@@ -489,7 +489,7 @@ NewProjectionPath::computeSubSeqRelation(const NewProjectionPath &RHS) const {
|
|||||||
return SubSeqRelation_t::RHSStrictSubSeqOfLHS;
|
return SubSeqRelation_t::RHSStrictSubSeqOfLHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewProjectionPath::findMatchingObjectProjectionPaths(
|
bool ProjectionPath::findMatchingObjectProjectionPaths(
|
||||||
SILInstruction *I, SmallVectorImpl<SILInstruction *> &T) const {
|
SILInstruction *I, SmallVectorImpl<SILInstruction *> &T) const {
|
||||||
// We only support unary instructions.
|
// We only support unary instructions.
|
||||||
if (I->getNumOperands() != 1)
|
if (I->getNumOperands() != 1)
|
||||||
@@ -543,9 +543,9 @@ bool NewProjectionPath::findMatchingObjectProjectionPaths(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<NewProjectionPath>
|
Optional<ProjectionPath>
|
||||||
NewProjectionPath::removePrefix(const NewProjectionPath &Path,
|
ProjectionPath::removePrefix(const ProjectionPath &Path,
|
||||||
const NewProjectionPath &Prefix) {
|
const ProjectionPath &Prefix) {
|
||||||
// We can only subtract paths that have the same base.
|
// We can only subtract paths that have the same base.
|
||||||
if (Path.BaseType != Prefix.BaseType)
|
if (Path.BaseType != Prefix.BaseType)
|
||||||
return llvm::NoneType::None;
|
return llvm::NoneType::None;
|
||||||
@@ -559,7 +559,7 @@ NewProjectionPath::removePrefix(const NewProjectionPath &Path,
|
|||||||
return llvm::NoneType::None;
|
return llvm::NoneType::None;
|
||||||
|
|
||||||
// First make sure that the prefix matches.
|
// First make sure that the prefix matches.
|
||||||
Optional<NewProjectionPath> P = NewProjectionPath(Path.BaseType);
|
Optional<ProjectionPath> P = ProjectionPath(Path.BaseType);
|
||||||
for (unsigned i = 0; i < PrefixSize; i++) {
|
for (unsigned i = 0; i < PrefixSize; i++) {
|
||||||
if (Path.Path[i] != Prefix.Path[i]) {
|
if (Path.Path[i] != Prefix.Path[i]) {
|
||||||
P.reset();
|
P.reset();
|
||||||
@@ -575,7 +575,7 @@ NewProjectionPath::removePrefix(const NewProjectionPath &Path,
|
|||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
SILValue NewProjectionPath::createObjectProjections(SILBuilder &B,
|
SILValue ProjectionPath::createObjectProjections(SILBuilder &B,
|
||||||
SILLocation Loc,
|
SILLocation Loc,
|
||||||
SILValue Base) {
|
SILValue Base) {
|
||||||
assert(BaseType.isAddress());
|
assert(BaseType.isAddress());
|
||||||
@@ -588,7 +588,7 @@ SILValue NewProjectionPath::createObjectProjections(SILBuilder &B,
|
|||||||
return Val;
|
return Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) {
|
raw_ostream &ProjectionPath::print(raw_ostream &os, SILModule &M) {
|
||||||
// Match how the memlocation print tests expect us to print projection paths.
|
// Match how the memlocation print tests expect us to print projection paths.
|
||||||
//
|
//
|
||||||
// TODO: It sort of sucks having to print these bottom up computationally. We
|
// TODO: It sort of sucks having to print these bottom up computationally. We
|
||||||
@@ -608,7 +608,7 @@ raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IterProj.getKind() == NewProjectionKind::Tuple) {
|
if (IterProj.getKind() == ProjectionKind::Tuple) {
|
||||||
IterType = IterProj.getType(IterType, M);
|
IterType = IterProj.getType(IterType, M);
|
||||||
os << IterType.getAddressType() << "\n";
|
os << IterType.getAddressType() << "\n";
|
||||||
os << "Index: ";
|
os << "Index: ";
|
||||||
@@ -616,7 +616,7 @@ raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IterProj.getKind() == NewProjectionKind::Box) {
|
if (IterProj.getKind() == ProjectionKind::Box) {
|
||||||
os << "Box: ";
|
os << "Box: ";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -629,7 +629,7 @@ raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) {
|
|||||||
os << "(Projection Path [";
|
os << "(Projection Path [";
|
||||||
SILType NextType = BaseType;
|
SILType NextType = BaseType;
|
||||||
os << NextType;
|
os << NextType;
|
||||||
for (const NewProjection &P : Path) {
|
for (const Projection &P : Path) {
|
||||||
os << ", ";
|
os << ", ";
|
||||||
NextType = P.getType(NextType, M);
|
NextType = P.getType(NextType, M);
|
||||||
os << NextType;
|
os << NextType;
|
||||||
@@ -639,7 +639,7 @@ raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_ostream &NewProjectionPath::printProjections(raw_ostream &os, SILModule &M) const {
|
raw_ostream &ProjectionPath::printProjections(raw_ostream &os, SILModule &M) const {
|
||||||
// Match how the memlocation print tests expect us to print projection paths.
|
// Match how the memlocation print tests expect us to print projection paths.
|
||||||
//
|
//
|
||||||
// TODO: It sort of sucks having to print these bottom up computationally. We
|
// TODO: It sort of sucks having to print these bottom up computationally. We
|
||||||
@@ -652,7 +652,7 @@ raw_ostream &NewProjectionPath::printProjections(raw_ostream &os, SILModule &M)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IterProj.getKind() == NewProjectionKind::Tuple) {
|
if (IterProj.getKind() == ProjectionKind::Tuple) {
|
||||||
os << "Index: " << IterProj.getIndex() << "\n";
|
os << "Index: " << IterProj.getIndex() << "\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -663,16 +663,16 @@ raw_ostream &NewProjectionPath::printProjections(raw_ostream &os, SILModule &M)
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewProjectionPath::dump(SILModule &M) {
|
void ProjectionPath::dump(SILModule &M) {
|
||||||
print(llvm::outs(), M);
|
print(llvm::outs(), M);
|
||||||
llvm::outs() << "\n";
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewProjectionPath::dumpProjections(SILModule &M) const {
|
void ProjectionPath::dumpProjections(SILModule &M) const {
|
||||||
printProjections(llvm::outs(), M);
|
printProjections(llvm::outs(), M);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewProjectionPath::verify(SILModule &M) {
|
void ProjectionPath::verify(SILModule &M) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
SILType IterTy = getBaseType();
|
SILType IterTy = getBaseType();
|
||||||
assert(IterTy);
|
assert(IterTy);
|
||||||
@@ -684,19 +684,19 @@ void NewProjectionPath::verify(SILModule &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
|
||||||
NewProjectionPathList &Paths) {
|
ProjectionPathList &Paths) {
|
||||||
// Perform a BFS to expand the given type into projectionpath each of
|
// Perform a BFS to expand the given type into projectionpath each of
|
||||||
// which contains 1 field from the type.
|
// which contains 1 field from the type.
|
||||||
llvm::SmallVector<NewProjectionPath, 8> Worklist;
|
llvm::SmallVector<ProjectionPath, 8> Worklist;
|
||||||
llvm::SmallVector<NewProjection, 8> Projections;
|
llvm::SmallVector<Projection, 8> Projections;
|
||||||
|
|
||||||
// Push an empty projection path to get started.
|
// Push an empty projection path to get started.
|
||||||
NewProjectionPath P(B);
|
ProjectionPath P(B);
|
||||||
Worklist.push_back(P);
|
Worklist.push_back(P);
|
||||||
do {
|
do {
|
||||||
// Get the next level projections based on current projection's type.
|
// Get the next level projections based on current projection's type.
|
||||||
NewProjectionPath PP = Worklist.pop_back_val();
|
ProjectionPath PP = Worklist.pop_back_val();
|
||||||
// Get the current type to process.
|
// Get the current type to process.
|
||||||
SILType Ty = PP.getMostDerivedType(*Mod);
|
SILType Ty = PP.getMostDerivedType(*Mod);
|
||||||
|
|
||||||
@@ -704,7 +704,7 @@ NewProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
|
|
||||||
// Get the first level projection of the current type.
|
// Get the first level projection of the current type.
|
||||||
Projections.clear();
|
Projections.clear();
|
||||||
NewProjection::getFirstLevelProjections(Ty, *Mod, Projections);
|
Projection::getFirstLevelProjections(Ty, *Mod, Projections);
|
||||||
|
|
||||||
// Reached the end of the projection tree, this field can not be expanded
|
// Reached the end of the projection tree, this field can not be expanded
|
||||||
// anymore.
|
// anymore.
|
||||||
@@ -739,7 +739,7 @@ NewProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
|
|
||||||
// Keep expanding the location.
|
// Keep expanding the location.
|
||||||
for (auto &P : Projections) {
|
for (auto &P : Projections) {
|
||||||
NewProjectionPath X(B);
|
ProjectionPath X(B);
|
||||||
X.append(PP);
|
X.append(PP);
|
||||||
///assert(PP.getMostDerivedType(*Mod) == X.getMostDerivedType(*Mod));
|
///assert(PP.getMostDerivedType(*Mod) == X.getMostDerivedType(*Mod));
|
||||||
X.append(P);
|
X.append(P);
|
||||||
@@ -750,19 +750,19 @@ NewProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod,
|
ProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod,
|
||||||
NewProjectionPathList &Paths) {
|
ProjectionPathList &Paths) {
|
||||||
// Perform a BFS to expand the given type into projectionpath each of
|
// Perform a BFS to expand the given type into projectionpath each of
|
||||||
// which contains 1 field from the type.
|
// which contains 1 field from the type.
|
||||||
llvm::SmallVector<NewProjectionPath, 8> Worklist;
|
llvm::SmallVector<ProjectionPath, 8> Worklist;
|
||||||
llvm::SmallVector<NewProjection, 8> Projections;
|
llvm::SmallVector<Projection, 8> Projections;
|
||||||
|
|
||||||
// Push an empty projection path to get started.
|
// Push an empty projection path to get started.
|
||||||
NewProjectionPath P(B);
|
ProjectionPath P(B);
|
||||||
Worklist.push_back(P);
|
Worklist.push_back(P);
|
||||||
do {
|
do {
|
||||||
// Get the next level projections based on current projection's type.
|
// Get the next level projections based on current projection's type.
|
||||||
NewProjectionPath PP = Worklist.pop_back_val();
|
ProjectionPath PP = Worklist.pop_back_val();
|
||||||
// Get the current type to process.
|
// Get the current type to process.
|
||||||
SILType Ty = PP.getMostDerivedType(*Mod);
|
SILType Ty = PP.getMostDerivedType(*Mod);
|
||||||
|
|
||||||
@@ -770,7 +770,7 @@ NewProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
|
|
||||||
// Get the first level projection of the current type.
|
// Get the first level projection of the current type.
|
||||||
Projections.clear();
|
Projections.clear();
|
||||||
NewProjection::getFirstLevelProjections(Ty, *Mod, Projections);
|
Projection::getFirstLevelProjections(Ty, *Mod, Projections);
|
||||||
|
|
||||||
// Reached the end of the projection tree, this field can not be expanded
|
// Reached the end of the projection tree, this field can not be expanded
|
||||||
// anymore.
|
// anymore.
|
||||||
@@ -809,7 +809,7 @@ NewProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
|
|
||||||
// Keep expanding the location.
|
// Keep expanding the location.
|
||||||
for (auto &P : Projections) {
|
for (auto &P : Projections) {
|
||||||
NewProjectionPath X(B);
|
ProjectionPath X(B);
|
||||||
X.append(PP);
|
X.append(PP);
|
||||||
assert(PP.getMostDerivedType(*Mod) == X.getMostDerivedType(*Mod));
|
assert(PP.getMostDerivedType(*Mod) == X.getMostDerivedType(*Mod));
|
||||||
X.append(P);
|
X.append(P);
|
||||||
@@ -821,7 +821,7 @@ NewProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NewProjection::operator<(const NewProjection &Other) const {
|
Projection::operator<(const Projection &Other) const {
|
||||||
// If we have a nominal kind...
|
// If we have a nominal kind...
|
||||||
if (isNominalKind()) {
|
if (isNominalKind()) {
|
||||||
// And Other is also nominal...
|
// And Other is also nominal...
|
||||||
@@ -845,7 +845,7 @@ NewProjection::operator<(const NewProjection &Other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NullablePtr<SILInstruction>
|
NullablePtr<SILInstruction>
|
||||||
NewProjection::
|
Projection::
|
||||||
createAggFromFirstLevelProjections(SILBuilder &B, SILLocation Loc,
|
createAggFromFirstLevelProjections(SILBuilder &B, SILLocation Loc,
|
||||||
SILType BaseType,
|
SILType BaseType,
|
||||||
llvm::SmallVectorImpl<SILValue> &Values) {
|
llvm::SmallVectorImpl<SILValue> &Values) {
|
||||||
@@ -860,19 +860,19 @@ createAggFromFirstLevelProjections(SILBuilder &B, SILLocation Loc,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SILValue NewProjection::getOperandForAggregate(SILInstruction *I) const {
|
SILValue Projection::getOperandForAggregate(SILInstruction *I) const {
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case NewProjectionKind::Struct:
|
case ProjectionKind::Struct:
|
||||||
if (isa<StructInst>(I))
|
if (isa<StructInst>(I))
|
||||||
return I->getOperand(getIndex());
|
return I->getOperand(getIndex());
|
||||||
break;
|
break;
|
||||||
case NewProjectionKind::Tuple:
|
case ProjectionKind::Tuple:
|
||||||
if (isa<TupleInst>(I))
|
if (isa<TupleInst>(I))
|
||||||
return I->getOperand(getIndex());
|
return I->getOperand(getIndex());
|
||||||
break;
|
break;
|
||||||
case NewProjectionKind::Index:
|
case ProjectionKind::Index:
|
||||||
break;
|
break;
|
||||||
case NewProjectionKind::Enum:
|
case ProjectionKind::Enum:
|
||||||
if (EnumInst *EI = dyn_cast<EnumInst>(I)) {
|
if (EnumInst *EI = dyn_cast<EnumInst>(I)) {
|
||||||
if (EI->getElement() == getEnumElementDecl(I->getType())) {
|
if (EI->getElement() == getEnumElementDecl(I->getType())) {
|
||||||
assert(EI->hasOperand() && "expected data operand");
|
assert(EI->hasOperand() && "expected data operand");
|
||||||
@@ -880,11 +880,11 @@ SILValue NewProjection::getOperandForAggregate(SILInstruction *I) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NewProjectionKind::Class:
|
case ProjectionKind::Class:
|
||||||
case NewProjectionKind::Box:
|
case ProjectionKind::Box:
|
||||||
case NewProjectionKind::Upcast:
|
case ProjectionKind::Upcast:
|
||||||
case NewProjectionKind::RefCast:
|
case ProjectionKind::RefCast:
|
||||||
case NewProjectionKind::BitwiseCast:
|
case ProjectionKind::BitwiseCast:
|
||||||
// There is no SIL instruction to create a class or box by aggregating
|
// There is no SIL instruction to create a class or box by aggregating
|
||||||
// values.
|
// values.
|
||||||
break;
|
break;
|
||||||
@@ -893,14 +893,14 @@ SILValue NewProjection::getOperandForAggregate(SILInstruction *I) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// NewProjectionTreeNode
|
// ProjectionTreeNode
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
NewProjectionTreeNode::getChildForProjection(NewProjectionTree &Tree,
|
ProjectionTreeNode::getChildForProjection(ProjectionTree &Tree,
|
||||||
const NewProjection &P) {
|
const Projection &P) {
|
||||||
for (unsigned Index : ChildProjections) {
|
for (unsigned Index : ChildProjections) {
|
||||||
NewProjectionTreeNode *N = Tree.getNode(Index);
|
ProjectionTreeNode *N = Tree.getNode(Index);
|
||||||
if (N->Proj && N->Proj.getValue() == P) {
|
if (N->Proj && N->Proj.getValue() == P) {
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
@@ -909,22 +909,22 @@ NewProjectionTreeNode::getChildForProjection(NewProjectionTree &Tree,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
NewProjectionTreeNode::getParent(NewProjectionTree &Tree) {
|
ProjectionTreeNode::getParent(ProjectionTree &Tree) {
|
||||||
if (!Parent)
|
if (!Parent)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return Tree.getNode(Parent.getValue());
|
return Tree.getNode(Parent.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewProjectionTreeNode *
|
const ProjectionTreeNode *
|
||||||
NewProjectionTreeNode::getParent(const NewProjectionTree &Tree) const {
|
ProjectionTreeNode::getParent(const ProjectionTree &Tree) const {
|
||||||
if (!Parent)
|
if (!Parent)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return Tree.getNode(Parent.getValue());
|
return Tree.getNode(Parent.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
NullablePtr<SILInstruction>
|
NullablePtr<SILInstruction>
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
createProjection(SILBuilder &B, SILLocation Loc, SILValue Arg) const {
|
createProjection(SILBuilder &B, SILLocation Loc, SILValue Arg) const {
|
||||||
if (!Proj)
|
if (!Proj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -934,8 +934,8 @@ createProjection(SILBuilder &B, SILLocation Loc, SILValue Arg) const {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
processUsersOfValue(NewProjectionTree &Tree,
|
processUsersOfValue(ProjectionTree &Tree,
|
||||||
llvm::SmallVectorImpl<ValueNodePair> &Worklist,
|
llvm::SmallVectorImpl<ValueNodePair> &Worklist,
|
||||||
SILValue Value) {
|
SILValue Value) {
|
||||||
DEBUG(llvm::dbgs() << " Looking at Users:\n");
|
DEBUG(llvm::dbgs() << " Looking at Users:\n");
|
||||||
@@ -948,7 +948,7 @@ processUsersOfValue(NewProjectionTree &Tree,
|
|||||||
DEBUG(llvm::dbgs() << " " << *User);
|
DEBUG(llvm::dbgs() << " " << *User);
|
||||||
|
|
||||||
// First try to create a Projection for User.
|
// First try to create a Projection for User.
|
||||||
auto P = NewProjection::NewProjection(User);
|
auto P = Projection::Projection(User);
|
||||||
|
|
||||||
// If we fail to create a projection, add User as a user to this node and
|
// If we fail to create a projection, add User as a user to this node and
|
||||||
// continue.
|
// continue.
|
||||||
@@ -991,8 +991,8 @@ processUsersOfValue(NewProjectionTree &Tree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
createNextLevelChildrenForStruct(NewProjectionTree &Tree, StructDecl *SD) {
|
createNextLevelChildrenForStruct(ProjectionTree &Tree, StructDecl *SD) {
|
||||||
SILModule &Mod = Tree.getModule();
|
SILModule &Mod = Tree.getModule();
|
||||||
unsigned ChildIndex = 0;
|
unsigned ChildIndex = 0;
|
||||||
SILType Ty = getType();
|
SILType Ty = getType();
|
||||||
@@ -1011,8 +1011,8 @@ createNextLevelChildrenForStruct(NewProjectionTree &Tree, StructDecl *SD) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
createNextLevelChildrenForTuple(NewProjectionTree &Tree, TupleType *TT) {
|
createNextLevelChildrenForTuple(ProjectionTree &Tree, TupleType *TT) {
|
||||||
SILType Ty = getType();
|
SILType Ty = getType();
|
||||||
for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) {
|
||||||
assert(Tree.getNode(Index) == this && "Node is not mapped to itself?");
|
assert(Tree.getNode(Index) == this && "Node is not mapped to itself?");
|
||||||
@@ -1029,8 +1029,8 @@ createNextLevelChildrenForTuple(NewProjectionTree &Tree, TupleType *TT) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
createNextLevelChildren(NewProjectionTree &Tree) {
|
createNextLevelChildren(ProjectionTree &Tree) {
|
||||||
DEBUG(llvm::dbgs() << " Creating children for: " << getType() << "\n");
|
DEBUG(llvm::dbgs() << " Creating children for: " << getType() << "\n");
|
||||||
if (Initialized) {
|
if (Initialized) {
|
||||||
DEBUG(llvm::dbgs() << " Already initialized! bailing!\n");
|
DEBUG(llvm::dbgs() << " Already initialized! bailing!\n");
|
||||||
@@ -1064,7 +1064,7 @@ createNextLevelChildren(NewProjectionTree &Tree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SILInstruction *
|
SILInstruction *
|
||||||
NewProjectionTreeNode::
|
ProjectionTreeNode::
|
||||||
createAggregate(SILBuilder &B, SILLocation Loc, ArrayRef<SILValue> Args) const {
|
createAggregate(SILBuilder &B, SILLocation Loc, ArrayRef<SILValue> Args) const {
|
||||||
assert(Initialized && "Node must be initialized to create aggregates");
|
assert(Initialized && "Node must be initialized to create aggregates");
|
||||||
|
|
||||||
@@ -1081,8 +1081,8 @@ createAggregate(SILBuilder &B, SILLocation Loc, ArrayRef<SILValue> Args) const {
|
|||||||
llvm_unreachable("Unhandled type");
|
llvm_unreachable("Unhandled type");
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewProjectionTreeNode::NewAggregateBuilder {
|
class ProjectionTreeNode::NewAggregateBuilder {
|
||||||
NewProjectionTreeNode *Node;
|
ProjectionTreeNode *Node;
|
||||||
SILBuilder &Builder;
|
SILBuilder &Builder;
|
||||||
SILLocation Loc;
|
SILLocation Loc;
|
||||||
llvm::SmallVector<SILValue, 8> Values;
|
llvm::SmallVector<SILValue, 8> Values;
|
||||||
@@ -1091,7 +1091,7 @@ class NewProjectionTreeNode::NewAggregateBuilder {
|
|||||||
bool Invalidated;
|
bool Invalidated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NewAggregateBuilder(NewProjectionTreeNode *N, SILBuilder &B, SILLocation L)
|
NewAggregateBuilder(ProjectionTreeNode *N, SILBuilder &B, SILLocation L)
|
||||||
: Node(N), Builder(B), Loc(L), Values(), Invalidated(false) {
|
: Node(N), Builder(B), Loc(L), Values(), Invalidated(false) {
|
||||||
assert(N->Initialized && "N must be initialized since we are mapping Node "
|
assert(N->Initialized && "N must be initialized since we are mapping Node "
|
||||||
"Children -> SILValues");
|
"Children -> SILValues");
|
||||||
@@ -1120,7 +1120,7 @@ public:
|
|||||||
return Node->createAggregate(Builder, Loc, Values);
|
return Node->createAggregate(Builder, Loc, Values);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValueForChild(NewProjectionTreeNode *Child, SILValue V) {
|
void setValueForChild(ProjectionTreeNode *Child, SILValue V) {
|
||||||
assert(!Invalidated && "Must not be invalidated to set value for child");
|
assert(!Invalidated && "Must not be invalidated to set value for child");
|
||||||
Values[Child->Proj.getValue().getIndex()] = V;
|
Values[Child->Proj.getValue().getIndex()] = V;
|
||||||
}
|
}
|
||||||
@@ -1128,7 +1128,7 @@ public:
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using NewAggregateBuilder = NewProjectionTreeNode::NewAggregateBuilder;
|
using NewAggregateBuilder = ProjectionTreeNode::NewAggregateBuilder;
|
||||||
|
|
||||||
/// A wrapper around a MapVector with generalized operations on the map.
|
/// A wrapper around a MapVector with generalized operations on the map.
|
||||||
///
|
///
|
||||||
@@ -1138,7 +1138,7 @@ using NewAggregateBuilder = NewProjectionTreeNode::NewAggregateBuilder;
|
|||||||
class NewAggregateBuilderMap {
|
class NewAggregateBuilderMap {
|
||||||
SILBuilder &Builder;
|
SILBuilder &Builder;
|
||||||
SILLocation Loc;
|
SILLocation Loc;
|
||||||
llvm::MapVector<NewProjectionTreeNode *, NewAggregateBuilder> NodeBuilderMap;
|
llvm::MapVector<ProjectionTreeNode *, NewAggregateBuilder> NodeBuilderMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -1147,7 +1147,7 @@ public:
|
|||||||
|
|
||||||
/// Get the NewAggregateBuilder associated with Node or if none is created,
|
/// Get the NewAggregateBuilder associated with Node or if none is created,
|
||||||
/// create one for Node.
|
/// create one for Node.
|
||||||
NewAggregateBuilder &getBuilder(NewProjectionTreeNode *Node) {
|
NewAggregateBuilder &getBuilder(ProjectionTreeNode *Node) {
|
||||||
auto I = NodeBuilderMap.find(Node);
|
auto I = NodeBuilderMap.find(Node);
|
||||||
if (I != NodeBuilderMap.end()) {
|
if (I != NodeBuilderMap.end()) {
|
||||||
return I->second;
|
return I->second;
|
||||||
@@ -1159,33 +1159,33 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the NewAggregateBuilder associated with Node. Assert on failure.
|
/// Get the NewAggregateBuilder associated with Node. Assert on failure.
|
||||||
NewAggregateBuilder &get(NewProjectionTreeNode *Node) {
|
NewAggregateBuilder &get(ProjectionTreeNode *Node) {
|
||||||
auto It = NodeBuilderMap.find(Node);
|
auto It = NodeBuilderMap.find(Node);
|
||||||
assert(It != NodeBuilderMap.end() && "Every item in the worklist should have "
|
assert(It != NodeBuilderMap.end() && "Every item in the worklist should have "
|
||||||
"an NewAggregateBuilder associated with it");
|
"an NewAggregateBuilder associated with it");
|
||||||
return It->second;
|
return It->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isComplete(NewProjectionTreeNode *Node) {
|
bool isComplete(ProjectionTreeNode *Node) {
|
||||||
return get(Node).isComplete();
|
return get(Node).isComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInvalidated(NewProjectionTreeNode *Node) {
|
bool isInvalidated(ProjectionTreeNode *Node) {
|
||||||
return get(Node).isInvalidated();
|
return get(Node).isInvalidated();
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
getNextValidNode(llvm::SmallVectorImpl<NewProjectionTreeNode *> &Worklist,
|
getNextValidNode(llvm::SmallVectorImpl<ProjectionTreeNode *> &Worklist,
|
||||||
bool CheckForDeadLock=false);
|
bool CheckForDeadLock=false);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// NewProjectionTree
|
// ProjectionTree
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
NewProjectionTree::NewProjectionTree(SILModule &Mod, llvm::BumpPtrAllocator &BPA,
|
ProjectionTree::ProjectionTree(SILModule &Mod, llvm::BumpPtrAllocator &BPA,
|
||||||
SILType BaseTy) : Mod(Mod), Allocator(BPA) {
|
SILType BaseTy) : Mod(Mod), Allocator(BPA) {
|
||||||
DEBUG(llvm::dbgs() << "Constructing Projection Tree For : " << BaseTy);
|
DEBUG(llvm::dbgs() << "Constructing Projection Tree For : " << BaseTy);
|
||||||
|
|
||||||
@@ -1195,15 +1195,15 @@ NewProjectionTree::NewProjectionTree(SILModule &Mod, llvm::BumpPtrAllocator &BPA
|
|||||||
// Create the rest of the type tree lazily based on uses.
|
// Create the rest of the type tree lazily based on uses.
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTree::~NewProjectionTree() {
|
ProjectionTree::~ProjectionTree() {
|
||||||
for (auto *N : NewProjectionTreeNodes)
|
for (auto *N : ProjectionTreeNodes)
|
||||||
N->~NewProjectionTreeNode();
|
N->~ProjectionTreeNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
SILValue
|
SILValue
|
||||||
NewProjectionTree::computeExplodedArgumentValueInner(SILBuilder &Builder,
|
ProjectionTree::computeExplodedArgumentValueInner(SILBuilder &Builder,
|
||||||
SILLocation Loc,
|
SILLocation Loc,
|
||||||
NewProjectionTreeNode *Node,
|
ProjectionTreeNode *Node,
|
||||||
LeafValueMapTy &LeafValues) {
|
LeafValueMapTy &LeafValues) {
|
||||||
// Use the child node value if the child is alive.
|
// Use the child node value if the child is alive.
|
||||||
if (Node->ChildProjections.empty()) {
|
if (Node->ChildProjections.empty()) {
|
||||||
@@ -1221,14 +1221,14 @@ NewProjectionTree::computeExplodedArgumentValueInner(SILBuilder &Builder,
|
|||||||
// recursion should be fine.
|
// recursion should be fine.
|
||||||
llvm::SmallVector<SILValue, 8> ChildValues;
|
llvm::SmallVector<SILValue, 8> ChildValues;
|
||||||
for (unsigned ChildIdx : Node->ChildProjections) {
|
for (unsigned ChildIdx : Node->ChildProjections) {
|
||||||
NewProjectionTreeNode *Child = getNode(ChildIdx);
|
ProjectionTreeNode *Child = getNode(ChildIdx);
|
||||||
ChildValues.push_back(computeExplodedArgumentValueInner(Builder, Loc, Child,
|
ChildValues.push_back(computeExplodedArgumentValueInner(Builder, Loc, Child,
|
||||||
LeafValues));
|
LeafValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form and return the aggregate.
|
// Form and return the aggregate.
|
||||||
NullablePtr<swift::SILInstruction> AI =
|
NullablePtr<swift::SILInstruction> AI =
|
||||||
NewProjection::createAggFromFirstLevelProjections(Builder, Loc,
|
Projection::createAggFromFirstLevelProjections(Builder, Loc,
|
||||||
Node->getType(),
|
Node->getType(),
|
||||||
ChildValues);
|
ChildValues);
|
||||||
|
|
||||||
@@ -1237,7 +1237,7 @@ NewProjectionTree::computeExplodedArgumentValueInner(SILBuilder &Builder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SILValue
|
SILValue
|
||||||
NewProjectionTree::computeExplodedArgumentValue(SILBuilder &Builder,
|
ProjectionTree::computeExplodedArgumentValue(SILBuilder &Builder,
|
||||||
SILLocation Loc,
|
SILLocation Loc,
|
||||||
llvm::SmallVector<SILValue, 8> &LeafValues) {
|
llvm::SmallVector<SILValue, 8> &LeafValues) {
|
||||||
// Construct the leaf index to leaf value map.
|
// Construct the leaf index to leaf value map.
|
||||||
@@ -1252,9 +1252,9 @@ NewProjectionTree::computeExplodedArgumentValue(SILBuilder &Builder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
ProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
||||||
// Propagate liveness and users through the tree.
|
// Propagate liveness and users through the tree.
|
||||||
llvm::SmallVector<NewProjectionTreeNode::ValueNodePair, 32> UseWorklist;
|
llvm::SmallVector<ProjectionTreeNode::ValueNodePair, 32> UseWorklist;
|
||||||
UseWorklist.push_back({Base, getRoot()});
|
UseWorklist.push_back({Base, getRoot()});
|
||||||
|
|
||||||
// Then until the worklist is empty...
|
// Then until the worklist is empty...
|
||||||
@@ -1270,7 +1270,7 @@ NewProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
SILValue Value;
|
SILValue Value;
|
||||||
NewProjectionTreeNode *Node;
|
ProjectionTreeNode *Node;
|
||||||
|
|
||||||
// Pop off the top type, value, and node.
|
// Pop off the top type, value, and node.
|
||||||
std::tie(Value, Node) = UseWorklist.pop_back_val();
|
std::tie(Value, Node) = UseWorklist.pop_back_val();
|
||||||
@@ -1289,7 +1289,7 @@ NewProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
|||||||
if (Node->IsLive) {
|
if (Node->IsLive) {
|
||||||
DEBUG(llvm::dbgs() << "Node Is Live. Marking Children Live!\n");
|
DEBUG(llvm::dbgs() << "Node Is Live. Marking Children Live!\n");
|
||||||
for (unsigned ChildIdx : Node->ChildProjections) {
|
for (unsigned ChildIdx : Node->ChildProjections) {
|
||||||
NewProjectionTreeNode *Child = getNode(ChildIdx);
|
ProjectionTreeNode *Child = getNode(ChildIdx);
|
||||||
Child->IsLive = true;
|
Child->IsLive = true;
|
||||||
DEBUG(llvm::dbgs() << " Marking child live: " << Child->getType() << "\n");
|
DEBUG(llvm::dbgs() << " Marking child live: " << Child->getType() << "\n");
|
||||||
UseWorklist.push_back({SILValue(), Child});
|
UseWorklist.push_back({SILValue(), Child});
|
||||||
@@ -1300,10 +1300,10 @@ NewProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
|||||||
// Then setup the leaf list by iterating through our Nodes looking for live
|
// Then setup the leaf list by iterating through our Nodes looking for live
|
||||||
// leafs. We use a DFS order, always processing the left leafs first so that
|
// leafs. We use a DFS order, always processing the left leafs first so that
|
||||||
// we match the order in which we will lay out arguments.
|
// we match the order in which we will lay out arguments.
|
||||||
llvm::SmallVector<NewProjectionTreeNode *, 8> Worklist;
|
llvm::SmallVector<ProjectionTreeNode *, 8> Worklist;
|
||||||
Worklist.push_back(getRoot());
|
Worklist.push_back(getRoot());
|
||||||
while (!Worklist.empty()) {
|
while (!Worklist.empty()) {
|
||||||
NewProjectionTreeNode *Node = Worklist.pop_back_val();
|
ProjectionTreeNode *Node = Worklist.pop_back_val();
|
||||||
|
|
||||||
// If node is not a leaf, add its children to the worklist and continue.
|
// If node is not a leaf, add its children to the worklist and continue.
|
||||||
if (!Node->ChildProjections.empty()) {
|
if (!Node->ChildProjections.empty()) {
|
||||||
@@ -1332,13 +1332,13 @@ NewProjectionTree::computeUsesAndLiveness(SILValue Base) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTree::
|
ProjectionTree::
|
||||||
createTreeFromValue(SILBuilder &B, SILLocation Loc, SILValue NewBase,
|
createTreeFromValue(SILBuilder &B, SILLocation Loc, SILValue NewBase,
|
||||||
llvm::SmallVectorImpl<SILValue> &Leafs) const {
|
llvm::SmallVectorImpl<SILValue> &Leafs) const {
|
||||||
DEBUG(llvm::dbgs() << "Recreating tree from value: " << NewBase);
|
DEBUG(llvm::dbgs() << "Recreating tree from value: " << NewBase);
|
||||||
|
|
||||||
using WorklistEntry =
|
using WorklistEntry =
|
||||||
std::tuple<const NewProjectionTreeNode *, SILValue>;
|
std::tuple<const ProjectionTreeNode *, SILValue>;
|
||||||
llvm::SmallVector<WorklistEntry, 32> Worklist;
|
llvm::SmallVector<WorklistEntry, 32> Worklist;
|
||||||
|
|
||||||
// Start our worklist with NewBase and Root.
|
// Start our worklist with NewBase and Root.
|
||||||
@@ -1347,7 +1347,7 @@ createTreeFromValue(SILBuilder &B, SILLocation Loc, SILValue NewBase,
|
|||||||
// Then until our worklist is clear...
|
// Then until our worklist is clear...
|
||||||
while (Worklist.size()) {
|
while (Worklist.size()) {
|
||||||
// Pop off the top of the list.
|
// Pop off the top of the list.
|
||||||
const NewProjectionTreeNode *Node = std::get<0>(Worklist.back());
|
const ProjectionTreeNode *Node = std::get<0>(Worklist.back());
|
||||||
SILValue V = std::get<1>(Worklist.back());
|
SILValue V = std::get<1>(Worklist.back());
|
||||||
Worklist.pop_back();
|
Worklist.pop_back();
|
||||||
|
|
||||||
@@ -1361,7 +1361,7 @@ createTreeFromValue(SILBuilder &B, SILLocation Loc, SILValue NewBase,
|
|||||||
// Create projections for each one of them and the child node and
|
// Create projections for each one of them and the child node and
|
||||||
// projection to the worklist for processing.
|
// projection to the worklist for processing.
|
||||||
for (unsigned ChildIdx : reversed(Node->ChildProjections)) {
|
for (unsigned ChildIdx : reversed(Node->ChildProjections)) {
|
||||||
const NewProjectionTreeNode *ChildNode = getNode(ChildIdx);
|
const ProjectionTreeNode *ChildNode = getNode(ChildIdx);
|
||||||
SILInstruction *I = ChildNode->createProjection(B, Loc, V).get();
|
SILInstruction *I = ChildNode->createProjection(B, Loc, V).get();
|
||||||
DEBUG(llvm::dbgs() << " Adding Child: " << I->getType() << ": " << *I);
|
DEBUG(llvm::dbgs() << " Adding Child: " << I->getType() << ": " << *I);
|
||||||
Worklist.push_back(std::make_tuple(ChildNode, SILValue(I)));
|
Worklist.push_back(std::make_tuple(ChildNode, SILValue(I)));
|
||||||
@@ -1379,14 +1379,14 @@ createTreeFromValue(SILBuilder &B, SILLocation Loc, SILValue NewBase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionTreeNode *
|
ProjectionTreeNode *
|
||||||
NewAggregateBuilderMap::
|
NewAggregateBuilderMap::
|
||||||
getNextValidNode(llvm::SmallVectorImpl<NewProjectionTreeNode *> &Worklist,
|
getNextValidNode(llvm::SmallVectorImpl<ProjectionTreeNode *> &Worklist,
|
||||||
bool CheckForDeadLock) {
|
bool CheckForDeadLock) {
|
||||||
if (Worklist.empty())
|
if (Worklist.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
NewProjectionTreeNode *Node = Worklist.back();
|
ProjectionTreeNode *Node = Worklist.back();
|
||||||
|
|
||||||
// If the Node is not complete, then we have reached a dead lock. This should never happen.
|
// If the Node is not complete, then we have reached a dead lock. This should never happen.
|
||||||
//
|
//
|
||||||
@@ -1413,21 +1413,21 @@ getNextValidNode(llvm::SmallVectorImpl<NewProjectionTreeNode *> &Worklist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NewProjectionTree::
|
ProjectionTree::
|
||||||
replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
||||||
llvm::SmallVectorImpl<SILValue> &Leafs) {
|
llvm::SmallVectorImpl<SILValue> &Leafs) {
|
||||||
assert(Leafs.size() == LeafIndices.size() && "Leafs and leaf indices must "
|
assert(Leafs.size() == LeafIndices.size() && "Leafs and leaf indices must "
|
||||||
"equal in size.");
|
"equal in size.");
|
||||||
|
|
||||||
NewAggregateBuilderMap AggBuilderMap(Builder, Loc);
|
NewAggregateBuilderMap AggBuilderMap(Builder, Loc);
|
||||||
llvm::SmallVector<NewProjectionTreeNode *, 8> Worklist;
|
llvm::SmallVector<ProjectionTreeNode *, 8> Worklist;
|
||||||
|
|
||||||
DEBUG(llvm::dbgs() << "Replacing all uses in callee with leafs!\n");
|
DEBUG(llvm::dbgs() << "Replacing all uses in callee with leafs!\n");
|
||||||
|
|
||||||
// For each Leaf we have as input...
|
// For each Leaf we have as input...
|
||||||
for (unsigned i = 0, e = Leafs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Leafs.size(); i != e; ++i) {
|
||||||
SILValue Leaf = Leafs[i];
|
SILValue Leaf = Leafs[i];
|
||||||
NewProjectionTreeNode *Node = getNode(LeafIndices[i]);
|
ProjectionTreeNode *Node = getNode(LeafIndices[i]);
|
||||||
|
|
||||||
DEBUG(llvm::dbgs() << " Visiting leaf: " << Leaf);
|
DEBUG(llvm::dbgs() << " Visiting leaf: " << Leaf);
|
||||||
|
|
||||||
@@ -1442,7 +1442,7 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the parent of this node.
|
// Grab the parent of this node.
|
||||||
NewProjectionTreeNode *Parent = Node->getParent(*this);
|
ProjectionTreeNode *Parent = Node->getParent(*this);
|
||||||
DEBUG(llvm::dbgs() << " Visiting parent of leaf: " <<
|
DEBUG(llvm::dbgs() << " Visiting parent of leaf: " <<
|
||||||
Parent->getType() << "\n");
|
Parent->getType() << "\n");
|
||||||
|
|
||||||
@@ -1469,7 +1469,7 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
|||||||
// A utility array to add new Nodes to the list so we maintain while
|
// A utility array to add new Nodes to the list so we maintain while
|
||||||
// processing the current worklist we maintain only completed items at the end
|
// processing the current worklist we maintain only completed items at the end
|
||||||
// of the list.
|
// of the list.
|
||||||
llvm::SmallVector<NewProjectionTreeNode *, 8> NewNodes;
|
llvm::SmallVector<ProjectionTreeNode *, 8> NewNodes;
|
||||||
|
|
||||||
DEBUG(llvm::dbgs() << "Processing worklist!\n");
|
DEBUG(llvm::dbgs() << "Processing worklist!\n");
|
||||||
|
|
||||||
@@ -1480,8 +1480,8 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
|||||||
// TODO: Just change this into a partition method. Should be significantly
|
// TODO: Just change this into a partition method. Should be significantly
|
||||||
// faster.
|
// faster.
|
||||||
std::sort(Worklist.begin(), Worklist.end(),
|
std::sort(Worklist.begin(), Worklist.end(),
|
||||||
[&AggBuilderMap](NewProjectionTreeNode *N1,
|
[&AggBuilderMap](ProjectionTreeNode *N1,
|
||||||
NewProjectionTreeNode *N2) -> bool {
|
ProjectionTreeNode *N2) -> bool {
|
||||||
bool IsComplete1 = AggBuilderMap.isComplete(N1);
|
bool IsComplete1 = AggBuilderMap.isComplete(N1);
|
||||||
bool IsComplete2 = AggBuilderMap.isComplete(N2);
|
bool IsComplete2 = AggBuilderMap.isComplete(N2);
|
||||||
|
|
||||||
@@ -1503,7 +1503,7 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
|||||||
|
|
||||||
// Find the first non invalidated node. If we have all invalidated nodes,
|
// Find the first non invalidated node. If we have all invalidated nodes,
|
||||||
// this will return nullptr.
|
// this will return nullptr.
|
||||||
NewProjectionTreeNode *Node = AggBuilderMap.getNextValidNode(Worklist, true);
|
ProjectionTreeNode *Node = AggBuilderMap.getNextValidNode(Worklist, true);
|
||||||
|
|
||||||
// Then until we find a node that is not complete...
|
// Then until we find a node that is not complete...
|
||||||
while (Node && AggBuilderMap.isComplete(Node)) {
|
while (Node && AggBuilderMap.isComplete(Node)) {
|
||||||
@@ -1517,7 +1517,7 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If this node has a parent and that parent is alive...
|
// If this node has a parent and that parent is alive...
|
||||||
NewProjectionTreeNode *Parent = Node->getParentOrNull(*this);
|
ProjectionTreeNode *Parent = Node->getParentOrNull(*this);
|
||||||
if (Parent && Parent->IsLive) {
|
if (Parent && Parent->IsLive) {
|
||||||
// Create or lookup the node builder for the parent and associate the
|
// Create or lookup the node builder for the parent and associate the
|
||||||
// newly created aggregate with this node.
|
// newly created aggregate with this node.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void SILValueProjection::print(SILModule *Mod) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SILValue SILValueProjection::createExtract(SILValue Base,
|
SILValue SILValueProjection::createExtract(SILValue Base,
|
||||||
const Optional<NewProjectionPath> &Path,
|
const Optional<ProjectionPath> &Path,
|
||||||
SILInstruction *Inst,
|
SILInstruction *Inst,
|
||||||
bool IsValExt) {
|
bool IsValExt) {
|
||||||
// If we found a projection path, but there are no projections, then the two
|
// If we found a projection path, but there are no projections, then the two
|
||||||
@@ -95,7 +95,7 @@ SILValue LSValue::reduce(LSLocation &Base, SILModule *M,
|
|||||||
// First, get a list of all the leaf nodes and intermediate nodes for the
|
// First, get a list of all the leaf nodes and intermediate nodes for the
|
||||||
// Base memory location.
|
// Base memory location.
|
||||||
LSLocationList ALocs;
|
LSLocationList ALocs;
|
||||||
const NewProjectionPath &BasePath = Base.getPath().getValue();
|
const ProjectionPath &BasePath = Base.getPath().getValue();
|
||||||
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TENode)) {
|
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TENode)) {
|
||||||
ALocs.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
ALocs.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ SILValue LSValue::reduce(LSLocation &Base, SILModule *M,
|
|||||||
// empty, keep stripping it.
|
// empty, keep stripping it.
|
||||||
auto Iter = FirstLevel.begin();
|
auto Iter = FirstLevel.begin();
|
||||||
LSValue &FirstVal = Values[*Iter];
|
LSValue &FirstVal = Values[*Iter];
|
||||||
if (FirstLevel.size() == 1 && !FirstVal.hasEmptyNewProjectionPath()) {
|
if (FirstLevel.size() == 1 && !FirstVal.hasEmptyProjectionPath()) {
|
||||||
Values[*I] = FirstVal.stripLastLevelProjection();
|
Values[*I] = FirstVal.stripLastLevelProjection();
|
||||||
// We have a value for the parent, remove all the values for children.
|
// We have a value for the parent, remove all the values for children.
|
||||||
removeLSLocations(Values, FirstLevel);
|
removeLSLocations(Values, FirstLevel);
|
||||||
@@ -143,7 +143,7 @@ SILValue LSValue::reduce(LSLocation &Base, SILModule *M,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FirstLevel.size() > 1 && HasIdenticalValueBase &&
|
if (FirstLevel.size() > 1 && HasIdenticalValueBase &&
|
||||||
!FirstVal.hasEmptyNewProjectionPath()) {
|
!FirstVal.hasEmptyProjectionPath()) {
|
||||||
Values[*I] = FirstVal.stripLastLevelProjection();
|
Values[*I] = FirstVal.stripLastLevelProjection();
|
||||||
// We have a value for the parent, remove all the values for children.
|
// We have a value for the parent, remove all the values for children.
|
||||||
removeLSLocations(Values, FirstLevel);
|
removeLSLocations(Values, FirstLevel);
|
||||||
@@ -171,12 +171,12 @@ SILValue LSValue::reduce(LSLocation &Base, SILModule *M,
|
|||||||
// We use an auto-generated SILLocation for now.
|
// We use an auto-generated SILLocation for now.
|
||||||
// TODO: make the sil location more precise.
|
// TODO: make the sil location more precise.
|
||||||
NullablePtr<swift::SILInstruction> AI =
|
NullablePtr<swift::SILInstruction> AI =
|
||||||
NewProjection::createAggFromFirstLevelProjections(
|
Projection::createAggFromFirstLevelProjections(
|
||||||
Builder, RegularLocation::getAutoGeneratedLocation(),
|
Builder, RegularLocation::getAutoGeneratedLocation(),
|
||||||
I->getType(M).getObjectType(),
|
I->getType(M).getObjectType(),
|
||||||
Vals);
|
Vals);
|
||||||
// This is the Value for the current node.
|
// This is the Value for the current node.
|
||||||
NewProjectionPath P(Base.getType(M));
|
ProjectionPath P(Base.getType(M));
|
||||||
Values[*I] = LSValue(SILValue(AI.get()), P);
|
Values[*I] = LSValue(SILValue(AI.get()), P);
|
||||||
removeLSLocations(Values, FirstLevel);
|
removeLSLocations(Values, FirstLevel);
|
||||||
|
|
||||||
@@ -238,10 +238,10 @@ bool LSLocation::isNonEscapingLocalLSLocation(SILFunction *Fn,
|
|||||||
void LSLocation::getFirstLevelLSLocations(LSLocationList &Locs,
|
void LSLocation::getFirstLevelLSLocations(LSLocationList &Locs,
|
||||||
SILModule *Mod) {
|
SILModule *Mod) {
|
||||||
SILType Ty = getType(Mod);
|
SILType Ty = getType(Mod);
|
||||||
llvm::SmallVector<NewProjection, 8> Out;
|
llvm::SmallVector<Projection, 8> Out;
|
||||||
NewProjection::getFirstLevelProjections(Ty, *Mod, Out);
|
Projection::getFirstLevelProjections(Ty, *Mod, Out);
|
||||||
for (auto &X : Out) {
|
for (auto &X : Out) {
|
||||||
NewProjectionPath P((*Base).getType());
|
ProjectionPath P((*Base).getType());
|
||||||
P.append(Path.getValue());
|
P.append(Path.getValue());
|
||||||
P.append(X);
|
P.append(X);
|
||||||
Locs.push_back(LSLocation(Base, P));
|
Locs.push_back(LSLocation(Base, P));
|
||||||
@@ -256,7 +256,7 @@ void LSLocation::expand(LSLocation Base, SILModule *M, LSLocationList &Locs,
|
|||||||
//
|
//
|
||||||
// Construct the LSLocation by appending the projection path from the
|
// Construct the LSLocation by appending the projection path from the
|
||||||
// accessed node to the leaf nodes.
|
// accessed node to the leaf nodes.
|
||||||
const NewProjectionPath &BasePath = Base.getPath().getValue();
|
const ProjectionPath &BasePath = Base.getPath().getValue();
|
||||||
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TELeaf)) {
|
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TELeaf)) {
|
||||||
Locs.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
Locs.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ void LSLocation::reduce(LSLocation Base, SILModule *M, LSLocationSet &Locs,
|
|||||||
// First, construct the LSLocation by appending the projection path from the
|
// First, construct the LSLocation by appending the projection path from the
|
||||||
// accessed node to the leaf nodes.
|
// accessed node to the leaf nodes.
|
||||||
LSLocationList Nodes;
|
LSLocationList Nodes;
|
||||||
const NewProjectionPath &BasePath = Base.getPath().getValue();
|
const ProjectionPath &BasePath = Base.getPath().getValue();
|
||||||
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TENode)) {
|
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M, TEKind::TENode)) {
|
||||||
Nodes.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
Nodes.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ void LSLocation::enumerateLSLocation(SILModule *M, SILValue Mem,
|
|||||||
|
|
||||||
// Construct a Location to represent the memory written by this instruction.
|
// Construct a Location to represent the memory written by this instruction.
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
LSLocation L(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
LSLocation L(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
|
|
||||||
// If we cant figure out the Base or Projection Path for the memory location,
|
// If we cant figure out the Base or Projection Path for the memory location,
|
||||||
// simply ignore it for now.
|
// simply ignore it for now.
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ AliasResult AliasAnalysis::aliasAddressProjection(SILValue V1, SILValue V2,
|
|||||||
// If V2 is also a gep instruction with a must-alias or not-aliasing base
|
// If V2 is also a gep instruction with a must-alias or not-aliasing base
|
||||||
// pointer, figure out if the indices of the GEPs tell us anything about the
|
// pointer, figure out if the indices of the GEPs tell us anything about the
|
||||||
// derived pointers.
|
// derived pointers.
|
||||||
if (!NewProjection::isAddressProjection(V2)) {
|
if (!Projection::isAddressProjection(V2)) {
|
||||||
// Ok, V2 is not an address projection. See if V2 after stripping casts
|
// Ok, V2 is not an address projection. See if V2 after stripping casts
|
||||||
// aliases O1. If so, then we know that V2 must partially alias V1 via a
|
// aliases O1. If so, then we know that V2 must partially alias V1 via a
|
||||||
// must alias relation on O1. This ensures that given an alloc_stack and a
|
// must alias relation on O1. This ensures that given an alloc_stack and a
|
||||||
@@ -227,9 +227,9 @@ AliasResult AliasAnalysis::aliasAddressProjection(SILValue V1, SILValue V2,
|
|||||||
return AliasResult::MayAlias;
|
return AliasResult::MayAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!NewProjection::isAddressProjection(O1) &&
|
assert(!Projection::isAddressProjection(O1) &&
|
||||||
"underlying object may not be a projection");
|
"underlying object may not be a projection");
|
||||||
assert(!NewProjection::isAddressProjection(O2) &&
|
assert(!Projection::isAddressProjection(O2) &&
|
||||||
"underlying object may not be a projection");
|
"underlying object may not be a projection");
|
||||||
|
|
||||||
// Do the base pointers alias?
|
// Do the base pointers alias?
|
||||||
@@ -241,8 +241,8 @@ AliasResult AliasAnalysis::aliasAddressProjection(SILValue V1, SILValue V2,
|
|||||||
return AliasResult::NoAlias;
|
return AliasResult::NoAlias;
|
||||||
|
|
||||||
// Let's do alias checking based on projections.
|
// Let's do alias checking based on projections.
|
||||||
auto V1Path = NewProjectionPath::getProjectionPath(O1, V1);
|
auto V1Path = ProjectionPath::getProjectionPath(O1, V1);
|
||||||
auto V2Path = NewProjectionPath::getProjectionPath(O2, V2);
|
auto V2Path = ProjectionPath::getProjectionPath(O2, V2);
|
||||||
|
|
||||||
// getUnderlyingPath and findAddressProjectionPathBetweenValues disagree on
|
// getUnderlyingPath and findAddressProjectionPathBetweenValues disagree on
|
||||||
// what the base pointer of the two values are. Be conservative and return
|
// what the base pointer of the two values are. Be conservative and return
|
||||||
@@ -612,15 +612,15 @@ AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
|
|||||||
|
|
||||||
// First if one instruction is a gep and the other is not, canonicalize our
|
// First if one instruction is a gep and the other is not, canonicalize our
|
||||||
// inputs so that V1 always is the instruction containing the GEP.
|
// inputs so that V1 always is the instruction containing the GEP.
|
||||||
if (!NewProjection::isAddressProjection(V1) &&
|
if (!Projection::isAddressProjection(V1) &&
|
||||||
NewProjection::isAddressProjection(V2)) {
|
Projection::isAddressProjection(V2)) {
|
||||||
std::swap(V1, V2);
|
std::swap(V1, V2);
|
||||||
std::swap(O1, O2);
|
std::swap(O1, O2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If V1 is an address projection, attempt to use information from the
|
// If V1 is an address projection, attempt to use information from the
|
||||||
// aggregate type tree to disambiguate it from V2.
|
// aggregate type tree to disambiguate it from V2.
|
||||||
if (NewProjection::isAddressProjection(V1)) {
|
if (Projection::isAddressProjection(V1)) {
|
||||||
AliasResult Result = aliasAddressProjection(V1, V2, O1, O2);
|
AliasResult Result = aliasAddressProjection(V1, V2, O1, O2);
|
||||||
if (Result != AliasResult::MayAlias)
|
if (Result != AliasResult::MayAlias)
|
||||||
return Result;
|
return Result;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ using namespace swift;
|
|||||||
// memory usage of this cache.
|
// memory usage of this cache.
|
||||||
static const int TypeExpansionAnalysisMaxCacheSize = 4096;
|
static const int TypeExpansionAnalysisMaxCacheSize = 4096;
|
||||||
|
|
||||||
const NewProjectionPathList &
|
const ProjectionPathList &
|
||||||
TypeExpansionAnalysis::getTypeExpansion(SILType B, SILModule *Mod, TEKind Kind){
|
TypeExpansionAnalysis::getTypeExpansion(SILType B, SILModule *Mod, TEKind Kind){
|
||||||
// Which cache we should be looking up.
|
// Which cache we should be looking up.
|
||||||
bool IsLeaf = Kind == TEKind::TELeaf;
|
bool IsLeaf = Kind == TEKind::TELeaf;
|
||||||
@@ -42,12 +42,12 @@ TypeExpansionAnalysis::getTypeExpansion(SILType B, SILModule *Mod, TEKind Kind){
|
|||||||
|
|
||||||
// Build the type expansion for the leaf nodes.
|
// Build the type expansion for the leaf nodes.
|
||||||
if (IsLeaf) {
|
if (IsLeaf) {
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(B, Mod, Cache[B]);
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(B, Mod, Cache[B]);
|
||||||
return Cache[B];
|
return Cache[B];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the type expansion for the internal and leaf nodes.
|
// Build the type expansion for the internal and leaf nodes.
|
||||||
NewProjectionPath::expandTypeIntoNodeProjectionPaths(B, Mod, Cache[B]);
|
ProjectionPath::expandTypeIntoNodeProjectionPaths(B, Mod, Cache[B]);
|
||||||
return Cache[B];
|
return Cache[B];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ struct ArgumentDescriptor {
|
|||||||
SILInstruction *CalleeReleaseInThrowBlock;
|
SILInstruction *CalleeReleaseInThrowBlock;
|
||||||
|
|
||||||
/// The projection tree of this arguments.
|
/// The projection tree of this arguments.
|
||||||
NewProjectionTree ProjTree;
|
ProjectionTree ProjTree;
|
||||||
|
|
||||||
ArgumentDescriptor() = delete;
|
ArgumentDescriptor() = delete;
|
||||||
|
|
||||||
|
|||||||
@@ -132,12 +132,12 @@ namespace {
|
|||||||
// Returns the base address, i.e. the first address which is not a
|
// Returns the base address, i.e. the first address which is not a
|
||||||
// projection.
|
// projection.
|
||||||
SILValue scanProjections(SILValue addr,
|
SILValue scanProjections(SILValue addr,
|
||||||
SmallVectorImpl<NewProjection> *Result = nullptr);
|
SmallVectorImpl<Projection> *Result = nullptr);
|
||||||
|
|
||||||
// Get the stored value for a load. The loadInst can be either a real load
|
// Get the stored value for a load. The loadInst can be either a real load
|
||||||
// or a copy_addr.
|
// or a copy_addr.
|
||||||
SILValue getStoredValue(SILInstruction *loadInst,
|
SILValue getStoredValue(SILInstruction *loadInst,
|
||||||
NewProjectionPath &projStack);
|
ProjectionPath &projStack);
|
||||||
|
|
||||||
// Gets the parameter in the caller for a function argument.
|
// Gets the parameter in the caller for a function argument.
|
||||||
SILValue getParam(SILValue value) {
|
SILValue getParam(SILValue value) {
|
||||||
@@ -162,7 +162,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Gets the estimated definition of a value.
|
// Gets the estimated definition of a value.
|
||||||
SILInstruction *getDef(SILValue val, NewProjectionPath &projStack);
|
SILInstruction *getDef(SILValue val, ProjectionPath &projStack);
|
||||||
|
|
||||||
// Gets the estimated integer constant result of a builtin.
|
// Gets the estimated integer constant result of a builtin.
|
||||||
IntConst getBuiltinConst(BuiltinInst *BI, int depth);
|
IntConst getBuiltinConst(BuiltinInst *BI, int depth);
|
||||||
@@ -191,7 +191,7 @@ namespace {
|
|||||||
|
|
||||||
// Gets the estimated definition of a value.
|
// Gets the estimated definition of a value.
|
||||||
SILInstruction *getDef(SILValue val) {
|
SILInstruction *getDef(SILValue val) {
|
||||||
NewProjectionPath projStack(val->getType());
|
ProjectionPath projStack(val->getType());
|
||||||
return getDef(val, projStack);
|
return getDef(val, projStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,12 +285,12 @@ void ConstantTracker::trackInst(SILInstruction *inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SILValue ConstantTracker::scanProjections(SILValue addr,
|
SILValue ConstantTracker::scanProjections(SILValue addr,
|
||||||
SmallVectorImpl<NewProjection> *Result) {
|
SmallVectorImpl<Projection> *Result) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (NewProjection::isAddressProjection(addr)) {
|
if (Projection::isAddressProjection(addr)) {
|
||||||
SILInstruction *I = cast<SILInstruction>(addr);
|
SILInstruction *I = cast<SILInstruction>(addr);
|
||||||
if (Result) {
|
if (Result) {
|
||||||
Result->push_back(NewProjection(I));
|
Result->push_back(Projection(I));
|
||||||
}
|
}
|
||||||
addr = I->getOperand(0);
|
addr = I->getOperand(0);
|
||||||
continue;
|
continue;
|
||||||
@@ -306,7 +306,7 @@ SILValue ConstantTracker::scanProjections(SILValue addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SILValue ConstantTracker::getStoredValue(SILInstruction *loadInst,
|
SILValue ConstantTracker::getStoredValue(SILInstruction *loadInst,
|
||||||
NewProjectionPath &projStack) {
|
ProjectionPath &projStack) {
|
||||||
SILInstruction *store = links[loadInst];
|
SILInstruction *store = links[loadInst];
|
||||||
if (!store && callerTracker)
|
if (!store && callerTracker)
|
||||||
store = callerTracker->links[loadInst];
|
store = callerTracker->links[loadInst];
|
||||||
@@ -315,18 +315,18 @@ SILValue ConstantTracker::getStoredValue(SILInstruction *loadInst,
|
|||||||
assert(isa<LoadInst>(loadInst) || isa<CopyAddrInst>(loadInst));
|
assert(isa<LoadInst>(loadInst) || isa<CopyAddrInst>(loadInst));
|
||||||
|
|
||||||
// Push the address projections of the load onto the stack.
|
// Push the address projections of the load onto the stack.
|
||||||
SmallVector<NewProjection, 4> loadProjections;
|
SmallVector<Projection, 4> loadProjections;
|
||||||
scanProjections(loadInst->getOperand(0), &loadProjections);
|
scanProjections(loadInst->getOperand(0), &loadProjections);
|
||||||
for (const NewProjection &proj : loadProjections) {
|
for (const Projection &proj : loadProjections) {
|
||||||
projStack.push_back(proj);
|
projStack.push_back(proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop the address projections of the store from the stack.
|
// Pop the address projections of the store from the stack.
|
||||||
SmallVector<NewProjection, 4> storeProjections;
|
SmallVector<Projection, 4> storeProjections;
|
||||||
scanProjections(store->getOperand(1), &storeProjections);
|
scanProjections(store->getOperand(1), &storeProjections);
|
||||||
for (auto iter = storeProjections.rbegin(); iter != storeProjections.rend();
|
for (auto iter = storeProjections.rbegin(); iter != storeProjections.rend();
|
||||||
++iter) {
|
++iter) {
|
||||||
const NewProjection &proj = *iter;
|
const Projection &proj = *iter;
|
||||||
// The corresponding load-projection must match the store-projection.
|
// The corresponding load-projection must match the store-projection.
|
||||||
if (projStack.empty() || projStack.back() != proj)
|
if (projStack.empty() || projStack.back() != proj)
|
||||||
return SILValue();
|
return SILValue();
|
||||||
@@ -343,23 +343,23 @@ SILValue ConstantTracker::getStoredValue(SILInstruction *loadInst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the aggregate member based on the top of the projection stack.
|
// Get the aggregate member based on the top of the projection stack.
|
||||||
static SILValue getMember(SILInstruction *inst, NewProjectionPath &projStack) {
|
static SILValue getMember(SILInstruction *inst, ProjectionPath &projStack) {
|
||||||
if (!projStack.empty()) {
|
if (!projStack.empty()) {
|
||||||
const NewProjection &proj = projStack.back();
|
const Projection &proj = projStack.back();
|
||||||
return proj.getOperandForAggregate(inst);
|
return proj.getOperandForAggregate(inst);
|
||||||
}
|
}
|
||||||
return SILValue();
|
return SILValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
SILInstruction *ConstantTracker::getDef(SILValue val,
|
SILInstruction *ConstantTracker::getDef(SILValue val,
|
||||||
NewProjectionPath &projStack) {
|
ProjectionPath &projStack) {
|
||||||
|
|
||||||
// Track the value up the dominator tree.
|
// Track the value up the dominator tree.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (SILInstruction *inst = dyn_cast<SILInstruction>(val)) {
|
if (SILInstruction *inst = dyn_cast<SILInstruction>(val)) {
|
||||||
if (NewProjection::isObjectProjection(inst)) {
|
if (Projection::isObjectProjection(inst)) {
|
||||||
// Extract a member from a struct/tuple/enum.
|
// Extract a member from a struct/tuple/enum.
|
||||||
projStack.push_back(NewProjection(inst));
|
projStack.push_back(Projection(inst));
|
||||||
val = inst->getOperand(0);
|
val = inst->getOperand(0);
|
||||||
continue;
|
continue;
|
||||||
} else if (SILValue member = getMember(inst, projStack)) {
|
} else if (SILValue member = getMember(inst, projStack)) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ COWViewCFGFunction("view-cfg-before-cow-for", llvm::cl::init(""),
|
|||||||
/// either refer to the next element (indexed) or a subelement.
|
/// either refer to the next element (indexed) or a subelement.
|
||||||
static SILValue getAccessPath(SILValue V, SmallVectorImpl<unsigned>& Path) {
|
static SILValue getAccessPath(SILValue V, SmallVectorImpl<unsigned>& Path) {
|
||||||
V = stripCasts(V);
|
V = stripCasts(V);
|
||||||
NewProjectionIndex PI(V);
|
ProjectionIndex PI(V);
|
||||||
if (!PI.isValid() || V->getKind() == ValueKind::IndexAddrInst)
|
if (!PI.isValid() || V->getKind() == ValueKind::IndexAddrInst)
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ protected:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewProjectionIndex PI(UseInst);
|
ProjectionIndex PI(UseInst);
|
||||||
// Do not form a path from an IndexAddrInst without otherwise
|
// Do not form a path from an IndexAddrInst without otherwise
|
||||||
// distinguishing it from subelement addressing.
|
// distinguishing it from subelement addressing.
|
||||||
if (!PI.isValid() || V->getKind() == ValueKind::IndexAddrInst) {
|
if (!PI.isValid() || V->getKind() == ValueKind::IndexAddrInst) {
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ SILInstruction *SILCombiner::visitLoadInst(LoadInst *LI) {
|
|||||||
// Given a load with multiple struct_extracts/tuple_extracts and no other
|
// Given a load with multiple struct_extracts/tuple_extracts and no other
|
||||||
// uses, canonicalize the load into several (struct_element_addr (load))
|
// uses, canonicalize the load into several (struct_element_addr (load))
|
||||||
// pairs.
|
// pairs.
|
||||||
using ProjInstPairTy = std::pair<NewProjection, SILInstruction *>;
|
using ProjInstPairTy = std::pair<Projection, SILInstruction *>;
|
||||||
|
|
||||||
// Go through the loads uses and add any users that are projections to the
|
// Go through the loads uses and add any users that are projections to the
|
||||||
// projection list.
|
// projection list.
|
||||||
@@ -406,7 +406,7 @@ SILInstruction *SILCombiner::visitLoadInst(LoadInst *LI) {
|
|||||||
if (!isa<StructExtractInst>(User) && !isa<TupleExtractInst>(User))
|
if (!isa<StructExtractInst>(User) && !isa<TupleExtractInst>(User))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Projections.push_back({NewProjection(User), User});
|
Projections.push_back({Projection(User), User});
|
||||||
}
|
}
|
||||||
|
|
||||||
// The reason why we sort the list is so that we will process projections with
|
// The reason why we sort the list is so that we will process projections with
|
||||||
@@ -416,7 +416,7 @@ SILInstruction *SILCombiner::visitLoadInst(LoadInst *LI) {
|
|||||||
std::sort(Projections.begin(), Projections.end());
|
std::sort(Projections.begin(), Projections.end());
|
||||||
|
|
||||||
// Go through our sorted list creating new GEPs only when we need to.
|
// Go through our sorted list creating new GEPs only when we need to.
|
||||||
NewProjection *LastProj = nullptr;
|
Projection *LastProj = nullptr;
|
||||||
LoadInst *LastNewLoad = nullptr;
|
LoadInst *LastNewLoad = nullptr;
|
||||||
for (auto &Pair : Projections) {
|
for (auto &Pair : Projections) {
|
||||||
auto &Proj = Pair.first;
|
auto &Proj = Pair.first;
|
||||||
|
|||||||
@@ -463,11 +463,11 @@ recursivelyCollectInteriorUses(ValueBase *DefInst,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Recursively follow projections.
|
// Recursively follow projections.
|
||||||
NewProjectionIndex PI(User);
|
ProjectionIndex PI(User);
|
||||||
if (PI.isValid()) {
|
if (PI.isValid()) {
|
||||||
IndexTrieNode *ProjAddrNode = AddressNode;
|
IndexTrieNode *ProjAddrNode = AddressNode;
|
||||||
bool ProjInteriorAddr = IsInteriorAddress;
|
bool ProjInteriorAddr = IsInteriorAddress;
|
||||||
if (NewProjection::isAddressProjection(User)) {
|
if (Projection::isAddressProjection(User)) {
|
||||||
if (User->getKind() == ValueKind::IndexAddrInst) {
|
if (User->getKind() == ValueKind::IndexAddrInst) {
|
||||||
// Don't support indexing within an interior address.
|
// Don't support indexing within an interior address.
|
||||||
if (IsInteriorAddress)
|
if (IsInteriorAddress)
|
||||||
|
|||||||
@@ -777,7 +777,7 @@ void DSEContext::processRead(SILInstruction *I, BlockState *S, SILValue Mem,
|
|||||||
L = BaseToLocIndex[Mem];
|
L = BaseToLocIndex[Mem];
|
||||||
} else {
|
} else {
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L = LSLocation(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L = LSLocation(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cant figure out the Base or Projection Path for the read instruction,
|
// If we cant figure out the Base or Projection Path for the read instruction,
|
||||||
@@ -862,7 +862,7 @@ void DSEContext::processWrite(SILInstruction *I, BlockState *S, SILValue Val,
|
|||||||
L = BaseToLocIndex[Mem];
|
L = BaseToLocIndex[Mem];
|
||||||
} else {
|
} else {
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L = LSLocation(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L = LSLocation(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cant figure out the Base or Projection Path for the store
|
// If we cant figure out the Base or Projection Path for the store
|
||||||
@@ -943,7 +943,7 @@ void DSEContext::processWrite(SILInstruction *I, BlockState *S, SILValue Val,
|
|||||||
// particular instruction may not be accessing the base, so we need to
|
// particular instruction may not be accessing the base, so we need to
|
||||||
// *rebase* the locations w.r.t. to the current instruction.
|
// *rebase* the locations w.r.t. to the current instruction.
|
||||||
SILValue B = Locs[0].getBase();
|
SILValue B = Locs[0].getBase();
|
||||||
Optional<NewProjectionPath> BP = NewProjectionPath::getProjectionPath(B, Mem);
|
Optional<ProjectionPath> BP = ProjectionPath::getProjectionPath(B, Mem);
|
||||||
// Strip off the projection path from base to the accessed field.
|
// Strip off the projection path from base to the accessed field.
|
||||||
for (auto &X : Alives) {
|
for (auto &X : Alives) {
|
||||||
X.removePathPrefix(BP);
|
X.removePathPrefix(BP);
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ bool BlockState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) {
|
|||||||
L = BaseToLocIndex[Mem];
|
L = BaseToLocIndex[Mem];
|
||||||
} else {
|
} else {
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L = LSLocation(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L = LSLocation(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
LSLocationValueMap Values;
|
LSLocationValueMap Values;
|
||||||
@@ -777,7 +777,7 @@ void BlockState::processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem,
|
|||||||
L = BaseToLocIndex[Mem];
|
L = BaseToLocIndex[Mem];
|
||||||
} else {
|
} else {
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L = LSLocation(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L = LSLocation(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cant figure out the Base or Projection Path for the write,
|
// If we cant figure out the Base or Projection Path for the write,
|
||||||
@@ -834,7 +834,7 @@ void BlockState::processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem,
|
|||||||
L = BaseToLocIndex[Mem];
|
L = BaseToLocIndex[Mem];
|
||||||
} else {
|
} else {
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L = LSLocation(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L = LSLocation(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cant figure out the Base or Projection Path for the read, simply
|
// If we cant figure out the Base or Projection Path for the read, simply
|
||||||
|
|||||||
@@ -319,17 +319,17 @@ static void collectLoads(SILInstruction *I, SmallVectorImpl<LoadInst *> &Loads)
|
|||||||
|
|
||||||
|
|
||||||
static void replaceLoad(LoadInst *LI, SILValue val, AllocStackInst *ASI) {
|
static void replaceLoad(LoadInst *LI, SILValue val, AllocStackInst *ASI) {
|
||||||
NewProjectionPath projections(val->getType());
|
ProjectionPath projections(val->getType());
|
||||||
SILValue op = LI->getOperand();
|
SILValue op = LI->getOperand();
|
||||||
while (op != ASI) {
|
while (op != ASI) {
|
||||||
assert(isa<StructElementAddrInst>(op) || isa<TupleElementAddrInst>(op));
|
assert(isa<StructElementAddrInst>(op) || isa<TupleElementAddrInst>(op));
|
||||||
SILInstruction *Inst = cast<SILInstruction>(op);
|
SILInstruction *Inst = cast<SILInstruction>(op);
|
||||||
projections.push_back(NewProjection(Inst));
|
projections.push_back(Projection(Inst));
|
||||||
op = Inst->getOperand(0);
|
op = Inst->getOperand(0);
|
||||||
}
|
}
|
||||||
SILBuilder builder(LI);
|
SILBuilder builder(LI);
|
||||||
for (auto iter = projections.rbegin(); iter != projections.rend(); ++iter) {
|
for (auto iter = projections.rbegin(); iter != projections.rend(); ++iter) {
|
||||||
const NewProjection &projection = *iter;
|
const Projection &projection = *iter;
|
||||||
val = projection.createObjectProjection(builder, LI->getLoc(), val).get();
|
val = projection.createObjectProjection(builder, LI->getLoc(), val).get();
|
||||||
}
|
}
|
||||||
op = LI->getOperand();
|
op = LI->getOperand();
|
||||||
|
|||||||
@@ -2318,7 +2318,7 @@ class ArgumentSplitter {
|
|||||||
llvm::SmallVector<std::pair<SILBasicBlock *, SILValue>, 8> IncomingValues;
|
llvm::SmallVector<std::pair<SILBasicBlock *, SILValue>, 8> IncomingValues;
|
||||||
|
|
||||||
/// The list of first level projections that Arg can be split into.
|
/// The list of first level projections that Arg can be split into.
|
||||||
llvm::SmallVector<NewProjection, 4> Projections;
|
llvm::SmallVector<Projection, 4> Projections;
|
||||||
|
|
||||||
llvm::Optional<int> FirstNewArgIndex;
|
llvm::Optional<int> FirstNewArgIndex;
|
||||||
|
|
||||||
@@ -2404,7 +2404,7 @@ bool ArgumentSplitter::createNewArguments() {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get the first level projection for the struct or tuple type.
|
// Get the first level projection for the struct or tuple type.
|
||||||
NewProjection::getFirstLevelProjections(Arg->getType(), Mod, Projections);
|
Projection::getFirstLevelProjections(Arg->getType(), Mod, Projections);
|
||||||
|
|
||||||
// We do not want to split arguments with less than 2 projections.
|
// We do not want to split arguments with less than 2 projections.
|
||||||
if (Projections.size() < 2)
|
if (Projections.size() < 2)
|
||||||
@@ -2413,7 +2413,7 @@ bool ArgumentSplitter::createNewArguments() {
|
|||||||
// We do not want to split arguments that have less than 2 non-trivial
|
// We do not want to split arguments that have less than 2 non-trivial
|
||||||
// projections.
|
// projections.
|
||||||
if (std::count_if(Projections.begin(), Projections.end(),
|
if (std::count_if(Projections.begin(), Projections.end(),
|
||||||
[&](const NewProjection &P) {
|
[&](const Projection &P) {
|
||||||
return !P.getType(Ty, Mod).isTrivial(Mod);
|
return !P.getType(Ty, Mod).isTrivial(Mod);
|
||||||
}) < 2)
|
}) < 2)
|
||||||
return false;
|
return false;
|
||||||
@@ -2445,7 +2445,7 @@ bool ArgumentSplitter::createNewArguments() {
|
|||||||
//
|
//
|
||||||
// TODO: What is the right location to use here.
|
// TODO: What is the right location to use here.
|
||||||
auto Loc = RegularLocation::getAutoGeneratedLocation();
|
auto Loc = RegularLocation::getAutoGeneratedLocation();
|
||||||
Agg = NewProjection::createAggFromFirstLevelProjections(
|
Agg = Projection::createAggFromFirstLevelProjections(
|
||||||
B, Loc, Arg->getType(), NewArgumentValues).get();
|
B, Loc, Arg->getType(), NewArgumentValues).get();
|
||||||
assert(Agg->hasValue() && "Expected a result");
|
assert(Agg->hasValue() && "Expected a result");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static llvm::cl::opt<MLKind> LSLocationKinds(
|
|||||||
"only-type-expansion"),
|
"only-type-expansion"),
|
||||||
clEnumValN(MLKind::All, "all", "all"), clEnumValEnd));
|
clEnumValN(MLKind::All, "all", "all"), clEnumValEnd));
|
||||||
|
|
||||||
static llvm::cl::opt<bool> UseNewProjection("lslocation-dump-use-new-projection",
|
static llvm::cl::opt<bool> UseProjection("lslocation-dump-use-new-projection",
|
||||||
llvm::cl::init(false));
|
llvm::cl::init(false));
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
///
|
///
|
||||||
void printTypeExpansion(SILFunction &Fn) {
|
void printTypeExpansion(SILFunction &Fn) {
|
||||||
SILModule *M = &Fn.getModule();
|
SILModule *M = &Fn.getModule();
|
||||||
NewProjectionPathList PPList;
|
ProjectionPathList PPList;
|
||||||
unsigned Counter = 0;
|
unsigned Counter = 0;
|
||||||
for (auto &BB : Fn) {
|
for (auto &BB : Fn) {
|
||||||
for (auto &II : BB) {
|
for (auto &II : BB) {
|
||||||
@@ -78,12 +78,12 @@ public:
|
|||||||
SILValue V = LI->getOperand();
|
SILValue V = LI->getOperand();
|
||||||
// This is an address type, take it object type.
|
// This is an address type, take it object type.
|
||||||
SILType Ty = V->getType().getObjectType();
|
SILType Ty = V->getType().getObjectType();
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
||||||
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
||||||
SILValue V = SI->getDest();
|
SILValue V = SI->getDest();
|
||||||
// This is an address type, take it object type.
|
// This is an address type, take it object type.
|
||||||
SILType Ty = V->getType().getObjectType();
|
SILType Ty = V->getType().getObjectType();
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
||||||
} else {
|
} else {
|
||||||
// Not interested in these instructions yet.
|
// Not interested in these instructions yet.
|
||||||
continue;
|
continue;
|
||||||
@@ -99,9 +99,9 @@ public:
|
|||||||
llvm::outs() << "\n";
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void printTypeExpansionWithNewProjection(SILFunction &Fn) {
|
void printTypeExpansionWithProjection(SILFunction &Fn) {
|
||||||
SILModule *M = &Fn.getModule();
|
SILModule *M = &Fn.getModule();
|
||||||
llvm::SmallVector<Optional<NewProjectionPath>, 8> PPList;
|
llvm::SmallVector<Optional<ProjectionPath>, 8> PPList;
|
||||||
unsigned Counter = 0;
|
unsigned Counter = 0;
|
||||||
for (auto &BB : Fn) {
|
for (auto &BB : Fn) {
|
||||||
for (auto &II : BB) {
|
for (auto &II : BB) {
|
||||||
@@ -111,12 +111,12 @@ public:
|
|||||||
V = LI->getOperand();
|
V = LI->getOperand();
|
||||||
// This is an address type, take it object type.
|
// This is an address type, take it object type.
|
||||||
Ty = V->getType().getObjectType();
|
Ty = V->getType().getObjectType();
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
||||||
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
||||||
V = SI->getDest();
|
V = SI->getDest();
|
||||||
// This is an address type, take it object type.
|
// This is an address type, take it object type.
|
||||||
Ty = V->getType().getObjectType();
|
Ty = V->getType().getObjectType();
|
||||||
NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList);
|
||||||
} else {
|
} else {
|
||||||
// Not interested in these instructions yet.
|
// Not interested in these instructions yet.
|
||||||
continue;
|
continue;
|
||||||
@@ -147,14 +147,14 @@ public:
|
|||||||
if (auto *LI = dyn_cast<LoadInst>(&II)) {
|
if (auto *LI = dyn_cast<LoadInst>(&II)) {
|
||||||
SILValue Mem = LI->getOperand();
|
SILValue Mem = LI->getOperand();
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L.init(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L.init(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
if (!L.isValid())
|
if (!L.isValid())
|
||||||
continue;
|
continue;
|
||||||
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
||||||
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
||||||
SILValue Mem = SI->getDest();
|
SILValue Mem = SI->getDest();
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L.init(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L.init(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
if (!L.isValid())
|
if (!L.isValid())
|
||||||
continue;
|
continue;
|
||||||
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
||||||
@@ -191,14 +191,14 @@ public:
|
|||||||
if (auto *LI = dyn_cast<LoadInst>(&II)) {
|
if (auto *LI = dyn_cast<LoadInst>(&II)) {
|
||||||
SILValue Mem = LI->getOperand();
|
SILValue Mem = LI->getOperand();
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L.init(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L.init(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
if (!L.isValid())
|
if (!L.isValid())
|
||||||
continue;
|
continue;
|
||||||
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
||||||
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
} else if (auto *SI = dyn_cast<StoreInst>(&II)) {
|
||||||
SILValue Mem = SI->getDest();
|
SILValue Mem = SI->getDest();
|
||||||
SILValue UO = getUnderlyingObject(Mem);
|
SILValue UO = getUnderlyingObject(Mem);
|
||||||
L.init(UO, NewProjectionPath::getProjectionPath(UO, Mem));
|
L.init(UO, ProjectionPath::getProjectionPath(UO, Mem));
|
||||||
if (!L.isValid())
|
if (!L.isValid())
|
||||||
continue;
|
continue;
|
||||||
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
LSLocation::expand(L, &Fn.getModule(), Locs, TE);
|
||||||
@@ -239,7 +239,7 @@ public:
|
|||||||
llvm::outs() << "@" << Fn.getName() << "\n";
|
llvm::outs() << "@" << Fn.getName() << "\n";
|
||||||
switch (LSLocationKinds) {
|
switch (LSLocationKinds) {
|
||||||
case MLKind::OnlyTypeExpansion:
|
case MLKind::OnlyTypeExpansion:
|
||||||
printTypeExpansionWithNewProjection(Fn);
|
printTypeExpansionWithProjection(Fn);
|
||||||
break;
|
break;
|
||||||
case MLKind::OnlyExpansion:
|
case MLKind::OnlyExpansion:
|
||||||
printMemExpansion(Fn);
|
printMemExpansion(Fn);
|
||||||
|
|||||||
Reference in New Issue
Block a user