@@ -69,123 +69,130 @@ static cl::opt<bool>
69
69
ForceSSAUpdater (" force-ssa-updater" , cl::init(false ), cl::Hidden);
70
70
71
71
namespace {
72
- // / \brief Alloca partitioning representation.
73
- // /
74
- // / This class represents a partitioning of an alloca into slices, and
75
- // / information about the nature of uses of each slice of the alloca. The goal
76
- // / is that this information is sufficient to decide if and how to split the
77
- // / alloca apart and replace slices with scalars. It is also intended that this
78
- // / structure can capture the relevant information needed both to decide about
79
- // / and to enact these transformations.
80
- class AllocaPartitioning {
81
- public:
82
- // / \brief A common base class for representing a half-open byte range.
83
- struct ByteRange {
84
- // / \brief The beginning offset of the range.
85
- uint64_t BeginOffset;
72
+ // / \brief A common base class for representing a half-open byte range.
73
+ struct ByteRange {
74
+ // / \brief The beginning offset of the range.
75
+ uint64_t BeginOffset;
86
76
87
- // / \brief The ending offset, not included in the range.
88
- uint64_t EndOffset;
77
+ // / \brief The ending offset, not included in the range.
78
+ uint64_t EndOffset;
89
79
90
- ByteRange () : BeginOffset(), EndOffset() {}
91
- ByteRange (uint64_t BeginOffset, uint64_t EndOffset)
92
- : BeginOffset(BeginOffset), EndOffset(EndOffset) {}
80
+ ByteRange () : BeginOffset(), EndOffset() {}
81
+ ByteRange (uint64_t BeginOffset, uint64_t EndOffset)
82
+ : BeginOffset(BeginOffset), EndOffset(EndOffset) {}
93
83
94
- // / \brief Support for ordering ranges.
95
- // /
96
- // / This provides an ordering over ranges such that start offsets are
97
- // / always increasing, and within equal start offsets, the end offsets are
98
- // / decreasing. Thus the spanning range comes first in a cluster with the
99
- // / same start position.
100
- bool operator <(const ByteRange &RHS) const {
101
- if (BeginOffset < RHS.BeginOffset ) return true ;
102
- if (BeginOffset > RHS.BeginOffset ) return false ;
103
- if (EndOffset > RHS.EndOffset ) return true ;
104
- return false ;
105
- }
84
+ // / \brief Support for ordering ranges.
85
+ // /
86
+ // / This provides an ordering over ranges such that start offsets are
87
+ // / always increasing, and within equal start offsets, the end offsets are
88
+ // / decreasing. Thus the spanning range comes first in a cluster with the
89
+ // / same start position.
90
+ bool operator <(const ByteRange &RHS) const {
91
+ if (BeginOffset < RHS.BeginOffset ) return true ;
92
+ if (BeginOffset > RHS.BeginOffset ) return false ;
93
+ if (EndOffset > RHS.EndOffset ) return true ;
94
+ return false ;
95
+ }
106
96
107
- // / \brief Support comparison with a single offset to allow binary searches.
108
- friend bool operator <(const ByteRange &LHS, uint64_t RHSOffset) {
109
- return LHS.BeginOffset < RHSOffset;
110
- }
97
+ // / \brief Support comparison with a single offset to allow binary searches.
98
+ friend bool operator <(const ByteRange &LHS, uint64_t RHSOffset) {
99
+ return LHS.BeginOffset < RHSOffset;
100
+ }
111
101
112
- friend LLVM_ATTRIBUTE_UNUSED bool operator <(uint64_t LHSOffset,
113
- const ByteRange &RHS) {
114
- return LHSOffset < RHS.BeginOffset ;
115
- }
102
+ friend LLVM_ATTRIBUTE_UNUSED bool operator <(uint64_t LHSOffset,
103
+ const ByteRange &RHS) {
104
+ return LHSOffset < RHS.BeginOffset ;
105
+ }
116
106
117
- bool operator ==(const ByteRange &RHS) const {
118
- return BeginOffset == RHS.BeginOffset && EndOffset == RHS.EndOffset ;
119
- }
120
- bool operator !=(const ByteRange &RHS) const { return !operator ==(RHS); }
121
- };
107
+ bool operator ==(const ByteRange &RHS) const {
108
+ return BeginOffset == RHS.BeginOffset && EndOffset == RHS.EndOffset ;
109
+ }
110
+ bool operator !=(const ByteRange &RHS) const { return !operator ==(RHS); }
111
+ };
122
112
123
- // / \brief A partition of an alloca.
113
+ // / \brief A partition of an alloca.
114
+ // /
115
+ // / This structure represents a contiguous partition of the alloca. These are
116
+ // / formed by examining the uses of the alloca. During formation, they may
117
+ // / overlap but once an AllocaPartitioning is built, the Partitions within it
118
+ // / are all disjoint.
119
+ struct Partition : public ByteRange {
120
+ // / \brief Whether this partition is splittable into smaller partitions.
124
121
// /
125
- // / This structure represents a contiguous partition of the alloca. These are
126
- // / formed by examining the uses of the alloca. During formation, they may
127
- // / overlap but once an AllocaPartitioning is built, the Partitions within it
128
- // / are all disjoint.
129
- struct Partition : public ByteRange {
130
- // / \brief Whether this partition is splittable into smaller partitions.
131
- // /
132
- // / We flag partitions as splittable when they are formed entirely due to
133
- // / accesses by trivially splittable operations such as memset and memcpy.
134
- bool IsSplittable;
135
-
136
- // / \brief Test whether a partition has been marked as dead.
137
- bool isDead () const {
138
- if (BeginOffset == UINT64_MAX) {
139
- assert (EndOffset == UINT64_MAX);
140
- return true ;
141
- }
142
- return false ;
122
+ // / We flag partitions as splittable when they are formed entirely due to
123
+ // / accesses by trivially splittable operations such as memset and memcpy.
124
+ bool IsSplittable;
125
+
126
+ // / \brief Test whether a partition has been marked as dead.
127
+ bool isDead () const {
128
+ if (BeginOffset == UINT64_MAX) {
129
+ assert (EndOffset == UINT64_MAX);
130
+ return true ;
143
131
}
132
+ return false ;
133
+ }
144
134
145
- // / \brief Kill a partition.
146
- // / This is accomplished by setting both its beginning and end offset to
147
- // / the maximum possible value.
148
- void kill () {
149
- assert (!isDead () && " He's Dead, Jim!" );
150
- BeginOffset = EndOffset = UINT64_MAX;
151
- }
135
+ // / \brief Kill a partition.
136
+ // / This is accomplished by setting both its beginning and end offset to
137
+ // / the maximum possible value.
138
+ void kill () {
139
+ assert (!isDead () && " He's Dead, Jim!" );
140
+ BeginOffset = EndOffset = UINT64_MAX;
141
+ }
152
142
153
- Partition () : ByteRange(), IsSplittable() {}
154
- Partition (uint64_t BeginOffset, uint64_t EndOffset, bool IsSplittable)
155
- : ByteRange(BeginOffset, EndOffset), IsSplittable(IsSplittable) {}
156
- };
143
+ Partition () : ByteRange(), IsSplittable() {}
144
+ Partition (uint64_t BeginOffset, uint64_t EndOffset, bool IsSplittable)
145
+ : ByteRange(BeginOffset, EndOffset), IsSplittable(IsSplittable) {}
146
+ };
157
147
158
- // / \brief A particular use of a partition of the alloca.
159
- // /
160
- // / This structure is used to associate uses of a partition with it. They
161
- // / mark the range of bytes which are referenced by a particular instruction,
162
- // / and includes a handle to the user itself and the pointer value in use.
163
- // / The bounds of these uses are determined by intersecting the bounds of the
164
- // / memory use itself with a particular partition. As a consequence there is
165
- // / intentionally overlap between various uses of the same partition.
166
- class PartitionUse : public ByteRange {
167
- // / \brief Combined storage for both the Use* and split state.
168
- PointerIntPair<Use*, 1 , bool > UsePtrAndIsSplit;
148
+ // / \brief A particular use of a partition of the alloca.
149
+ // /
150
+ // / This structure is used to associate uses of a partition with it. They
151
+ // / mark the range of bytes which are referenced by a particular instruction,
152
+ // / and includes a handle to the user itself and the pointer value in use.
153
+ // / The bounds of these uses are determined by intersecting the bounds of the
154
+ // / memory use itself with a particular partition. As a consequence there is
155
+ // / intentionally overlap between various uses of the same partition.
156
+ class PartitionUse : public ByteRange {
157
+ // / \brief Combined storage for both the Use* and split state.
158
+ PointerIntPair<Use*, 1 , bool > UsePtrAndIsSplit;
169
159
170
- public:
171
- PartitionUse () : ByteRange(), UsePtrAndIsSplit() {}
172
- PartitionUse (uint64_t BeginOffset, uint64_t EndOffset, Use *U,
173
- bool IsSplit)
174
- : ByteRange(BeginOffset, EndOffset), UsePtrAndIsSplit(U, IsSplit) {}
160
+ public:
161
+ PartitionUse () : ByteRange(), UsePtrAndIsSplit() {}
162
+ PartitionUse (uint64_t BeginOffset, uint64_t EndOffset, Use *U,
163
+ bool IsSplit)
164
+ : ByteRange(BeginOffset, EndOffset), UsePtrAndIsSplit(U, IsSplit) {}
175
165
176
- // / \brief The use in question. Provides access to both user and used value.
177
- // /
178
- // / Note that this may be null if the partition use is *dead*, that is, it
179
- // / should be ignored.
180
- Use *getUse () const { return UsePtrAndIsSplit.getPointer (); }
166
+ // / \brief The use in question. Provides access to both user and used value.
167
+ // /
168
+ // / Note that this may be null if the partition use is *dead*, that is, it
169
+ // / should be ignored.
170
+ Use *getUse () const { return UsePtrAndIsSplit.getPointer (); }
181
171
182
- // / \brief Set the use for this partition use range.
183
- void setUse (Use *U) { UsePtrAndIsSplit.setPointer (U); }
172
+ // / \brief Set the use for this partition use range.
173
+ void setUse (Use *U) { UsePtrAndIsSplit.setPointer (U); }
184
174
185
- // / \brief Whether this use is split across multiple partitions.
186
- bool isSplit () const { return UsePtrAndIsSplit.getInt (); }
187
- };
175
+ // / \brief Whether this use is split across multiple partitions.
176
+ bool isSplit () const { return UsePtrAndIsSplit.getInt (); }
177
+ };
178
+ }
179
+
180
+ namespace llvm {
181
+ template <> struct isPodLike <Partition> : llvm::true_type {};
182
+ template <> struct isPodLike <PartitionUse> : llvm::true_type {};
183
+ }
188
184
185
+ namespace {
186
+ // / \brief Alloca partitioning representation.
187
+ // /
188
+ // / This class represents a partitioning of an alloca into slices, and
189
+ // / information about the nature of uses of each slice of the alloca. The goal
190
+ // / is that this information is sufficient to decide if and how to split the
191
+ // / alloca apart and replace slices with scalars. It is also intended that this
192
+ // / structure can capture the relevant information needed both to decide about
193
+ // / and to enact these transformations.
194
+ class AllocaPartitioning {
195
+ public:
189
196
// / \brief Construct a partitioning of a particular alloca.
190
197
// /
191
198
// / Construction does most of the work for partitioning the alloca. This
@@ -1389,7 +1396,7 @@ class PHIOrSelectSpeculator : public InstVisitor<PHIOrSelectSpeculator> {
1389
1396
// may be grown during speculation. However, we never need to re-visit the
1390
1397
// new uses, and so we can use the initial size bound.
1391
1398
for (unsigned Idx = 0 , Size = P.use_size (PI); Idx != Size; ++Idx) {
1392
- const AllocaPartitioning:: PartitionUse &PU = P.getUse (PI, Idx);
1399
+ const PartitionUse &PU = P.getUse (PI, Idx);
1393
1400
if (!PU.getUse ())
1394
1401
continue ; // Skip dead use.
1395
1402
@@ -1594,7 +1601,7 @@ class PHIOrSelectSpeculator : public InstVisitor<PHIOrSelectSpeculator> {
1594
1601
IRBuilder<> IRB (&SI);
1595
1602
Use *Ops[2 ] = { &SI.getOperandUse (1 ), &SI.getOperandUse (2 ) };
1596
1603
AllocaPartitioning::iterator PIs[2 ];
1597
- AllocaPartitioning:: PartitionUse PUs[2 ];
1604
+ PartitionUse PUs[2 ];
1598
1605
for (unsigned i = 0 , e = 2 ; i != e; ++i) {
1599
1606
PIs[i] = P.findPartitionForPHIOrSelectOperand (Ops[i]);
1600
1607
if (PIs[i] != P.end ()) {
0 commit comments