@@ -100,6 +100,26 @@ static const User *isGEP(const Value *V) {
100
100
return 0 ;
101
101
}
102
102
103
+ static const Value *GetGEPOperands (const Value *V, std::vector<Value*> &GEPOps){
104
+ assert (GEPOps.empty () && " Expect empty list to populate!" );
105
+ GEPOps.insert (GEPOps.end (), cast<User>(V)->op_begin ()+1 ,
106
+ cast<User>(V)->op_end ());
107
+
108
+ // Accumulate all of the chained indexes into the operand array
109
+ V = cast<User>(V)->getOperand (0 );
110
+
111
+ while (const User *G = isGEP (V)) {
112
+ if (!isa<Constant>(GEPOps[0 ]) ||
113
+ !cast<Constant>(GEPOps[0 ])->isNullValue ())
114
+ break ; // Don't handle folding arbitrary pointer offsets yet...
115
+ GEPOps.erase (GEPOps.begin ()); // Drop the zero index
116
+ GEPOps.insert (GEPOps.begin (), G->op_begin ()+1 , G->op_end ());
117
+ V = G->getOperand (0 );
118
+ }
119
+ return V;
120
+ }
121
+
122
+
103
123
// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
104
124
// as array references. Note that this function is heavily tail recursive.
105
125
// Hopefully we have a smart C++ compiler. :)
@@ -192,31 +212,10 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
192
212
// non-aliasing.
193
213
194
214
// Collect all of the chained GEP operands together into one simple place
195
- std::vector<Value*> GEP1Ops (cast<User>(V1)->op_begin ()+1 ,
196
- cast<User>(V1)->op_end ());
197
- std::vector<Value*> GEP2Ops (cast<User>(V2)->op_begin ()+1 ,
198
- cast<User>(V2)->op_end ());
199
-
200
- // Accumulate all of the chained indexes into the operand arrays
201
- BasePtr1 = cast<User>(V1)->getOperand (0 );
202
- BasePtr2 = cast<User>(V2)->getOperand (0 );
203
- while (const User *G = isGEP (BasePtr1)) {
204
- if (!isa<Constant>(GEP1Ops[0 ]) ||
205
- !cast<Constant>(GEP1Ops[0 ])->isNullValue ())
206
- break ; // Don't handle folding arbitrary pointer offsets yet...
207
- GEP1Ops.erase (GEP1Ops.begin ());
208
- GEP1Ops.insert (GEP1Ops.begin (), G->op_begin ()+1 , G->op_end ());
209
- BasePtr1 = G->getOperand (0 );
210
- }
211
- while (const User *G = isGEP (BasePtr2)) {
212
- if (!isa<Constant>(GEP2Ops[0 ]) ||
213
- !cast<Constant>(GEP2Ops[0 ])->isNullValue ())
214
- break ; // Don't handle folding arbitrary pointer offsets yet...
215
- GEP2Ops.erase (GEP2Ops.begin ());
216
- GEP2Ops.insert (GEP2Ops.begin (), G->op_begin ()+1 , G->op_end ());
217
- BasePtr2 = G->getOperand (0 );
218
- }
219
-
215
+ std::vector<Value*> GEP1Ops, GEP2Ops;
216
+ BasePtr1 = GetGEPOperands (V1, GEP1Ops);
217
+ BasePtr2 = GetGEPOperands (V2, GEP2Ops);
218
+
220
219
AliasResult GAlias =
221
220
CheckGEPInstructions (BasePtr1->getType (), GEP1Ops, V1Size,
222
221
BasePtr2->getType (), GEP2Ops, V2Size);
@@ -229,21 +228,24 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
229
228
// instruction. If one pointer is a GEP with a non-zero index of the other
230
229
// pointer, we know they cannot alias.
231
230
//
232
- if (isa<GetElementPtrInst> (V2)) {
231
+ if (isGEP (V2)) {
233
232
std::swap (V1, V2);
234
233
std::swap (V1Size, V2Size);
235
234
}
236
235
237
236
if (V1Size != ~0U && V2Size != ~0U )
238
- if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V1)) {
239
- AliasResult R = alias (GEP->getOperand (0 ), V1Size, V2, V2Size);
237
+ if (const User *GEP = isGEP (V1)) {
238
+ std::vector<Value*> GEPOperands;
239
+ const Value *BasePtr = GetGEPOperands (V1, GEPOperands);
240
+
241
+ AliasResult R = alias (BasePtr, V1Size, V2, V2Size);
240
242
if (R == MustAlias) {
241
243
// If there is at least one non-zero constant index, we know they cannot
242
244
// alias.
243
245
bool ConstantFound = false ;
244
246
bool AllZerosFound = true ;
245
- for (unsigned i = 1 , e = GEP-> getNumOperands (); i != e; ++i)
246
- if (const Constant *C = dyn_cast<Constant>(GEP-> getOperand (i) )) {
247
+ for (unsigned i = 0 , e = GEPOperands. size (); i != e; ++i)
248
+ if (const Constant *C = dyn_cast<Constant>(GEPOperands[i] )) {
247
249
if (!C->isNullValue ()) {
248
250
ConstantFound = true ;
249
251
AllZerosFound = false ;
@@ -266,17 +268,13 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
266
268
// the size of the argument... build an index vector that is equal to
267
269
// the arguments provided, except substitute 0's for any variable
268
270
// indexes we find...
269
-
270
- std::vector<Value*> Indices;
271
- Indices.reserve (GEP->getNumOperands ()-1 );
272
- for (unsigned i = 1 ; i != GEP->getNumOperands (); ++i)
273
- if (const Constant *C = dyn_cast<Constant>(GEP->getOperand (i)))
274
- Indices.push_back ((Value*)C);
275
- else
276
- Indices.push_back (Constant::getNullValue (Type::LongTy));
277
- const Type *Ty = GEP->getOperand (0 )->getType ();
278
- int Offset = getTargetData ().getIndexedOffset (Ty, Indices);
279
- if (Offset >= (int )V2Size || Offset <= -(int )V1Size)
271
+ for (unsigned i = 0 ; i != GEPOperands.size (); ++i)
272
+ if (!isa<Constant>(GEPOperands[i]) ||
273
+ isa<ConstantExpr>(GEPOperands[i]))
274
+ GEPOperands[i] =Constant::getNullValue (GEPOperands[i]->getType ());
275
+ int64_t Offset = getTargetData ().getIndexedOffset (BasePtr->getType (),
276
+ GEPOperands);
277
+ if (Offset >= (int64_t )V2Size || Offset <= -(int64_t )V1Size)
280
278
return NoAlias;
281
279
}
282
280
}
@@ -326,7 +324,7 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops,
326
324
// If we have seen all constant operands, and run out of indexes on one of the
327
325
// getelementptrs, check to see if the tail of the leftover one is all zeros.
328
326
// If so, return mustalias.
329
- if (UnequalOper == MinOperands && MinOperands != MaxOperands ) {
327
+ if (UnequalOper == MinOperands) {
330
328
if (GEP1Ops.size () < GEP2Ops.size ()) std::swap (GEP1Ops, GEP2Ops);
331
329
332
330
bool AllAreZeros = true ;
@@ -432,7 +430,6 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops,
432
430
}
433
431
434
432
// We know that GEP1Ops[FirstConstantOper] & GEP2Ops[FirstConstantOper] are ok
435
-
436
433
437
434
// Loop over the rest of the operands...
438
435
for (unsigned i = FirstConstantOper+1 ; i != MaxOperands; ++i) {
0 commit comments