And lastly rename NewProjection to Projection. This is a NFC. rdar://24520269

This commit is contained in:
Xin Tong
2016-02-09 17:30:14 -08:00
parent 042c6e033d
commit 84a6ff1d98
19 changed files with 460 additions and 460 deletions

View File

@@ -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,

View File

@@ -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;
} }
}; };

View File

@@ -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;

View File

@@ -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);
}; };
} }

View File

@@ -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);
} }

View File

@@ -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.

View File

@@ -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.

View File

@@ -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;

View File

@@ -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];
} }

View File

@@ -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;

View File

@@ -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)) {

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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");
} }

View File

@@ -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);