@@ -174,6 +174,34 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) {
174
174
return false ;
175
175
}
176
176
177
+ // / Apply 'Func' to Ptr. If this returns nullptr, introspect the pointer's
178
+ // / type and walk down through the initial elements to obtain additional
179
+ // / pointers to try. Returns the first non-null return value from Func, or
180
+ // / nullptr if the type can't be introspected further.
181
+ static Constant *
182
+ evaluateBitcastFromPtr (Constant *Ptr, const DataLayout &DL,
183
+ const TargetLibraryInfo *TLI,
184
+ std::function<Constant *(Constant *)> Func) {
185
+ Constant *Val;
186
+ while (!(Val = Func (Ptr))) {
187
+ // If Ty is a struct, we can convert the pointer to the struct
188
+ // into a pointer to its first member.
189
+ // FIXME: This could be extended to support arrays as well.
190
+ Type *Ty = cast<PointerType>(Ptr->getType ())->getElementType ();
191
+ if (!isa<StructType>(Ty))
192
+ break ;
193
+
194
+ IntegerType *IdxTy = IntegerType::get (Ty->getContext (), 32 );
195
+ Constant *IdxZero = ConstantInt::get (IdxTy, 0 , false );
196
+ Constant *const IdxList[] = {IdxZero, IdxZero};
197
+
198
+ Ptr = ConstantExpr::getGetElementPtr (Ty, Ptr, IdxList);
199
+ if (auto *FoldedPtr = ConstantFoldConstant (Ptr, DL, TLI))
200
+ Ptr = FoldedPtr;
201
+ }
202
+ return Val;
203
+ }
204
+
177
205
static Constant *getInitializer (Constant *C) {
178
206
auto *GV = dyn_cast<GlobalVariable>(C);
179
207
return GV && GV->hasDefinitiveInitializer () ? GV->getInitializer () : nullptr ;
@@ -184,8 +212,14 @@ static Constant *getInitializer(Constant *C) {
184
212
Constant *Evaluator::ComputeLoadResult (Constant *P) {
185
213
// If this memory location has been recently stored, use the stored value: it
186
214
// is the most up-to-date.
187
- DenseMap<Constant*, Constant*>::const_iterator I = MutatedMemory.find (P);
188
- if (I != MutatedMemory.end ()) return I->second ;
215
+ auto findMemLoc = [this ](Constant *Ptr) {
216
+ DenseMap<Constant *, Constant *>::const_iterator I =
217
+ MutatedMemory.find (Ptr);
218
+ return I != MutatedMemory.end () ? I->second : nullptr ;
219
+ };
220
+
221
+ if (Constant *Val = findMemLoc (P))
222
+ return Val;
189
223
190
224
// Access it.
191
225
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P)) {
@@ -203,13 +237,17 @@ Constant *Evaluator::ComputeLoadResult(Constant *P) {
203
237
break ;
204
238
// Handle a constantexpr bitcast.
205
239
case Instruction::BitCast:
206
- Constant *Val = getVal (CE->getOperand (0 ));
207
- auto MM = MutatedMemory.find (Val);
208
- auto *I = (MM != MutatedMemory.end ()) ? MM->second
209
- : getInitializer (CE->getOperand (0 ));
210
- if (I)
240
+ // We're evaluating a load through a pointer that was bitcast to a
241
+ // different type. See if the "from" pointer has recently been stored.
242
+ // If it hasn't, we may still be able to find a stored pointer by
243
+ // introspecting the type.
244
+ Constant *Val =
245
+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, findMemLoc);
246
+ if (!Val)
247
+ Val = getInitializer (CE->getOperand (0 ));
248
+ if (Val)
211
249
return ConstantFoldLoadThroughBitcast (
212
- I , P->getType ()->getPointerElementType (), DL);
250
+ Val , P->getType ()->getPointerElementType (), DL);
213
251
break ;
214
252
}
215
253
}
@@ -329,37 +367,26 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
329
367
<< " Attempting to resolve bitcast on constant ptr.\n " );
330
368
// If we're evaluating a store through a bitcast, then we need
331
369
// to pull the bitcast off the pointer type and push it onto the
332
- // stored value.
333
- Ptr = CE->getOperand (0 );
334
-
335
- Type *NewTy = cast<PointerType>(Ptr->getType ())->getElementType ();
336
-
337
- // In order to push the bitcast onto the stored value, a bitcast
338
- // from NewTy to Val's type must be legal. If it's not, we can try
339
- // introspecting NewTy to find a legal conversion.
340
- Constant *NewVal;
341
- while (!(NewVal = ConstantFoldLoadThroughBitcast (Val, NewTy, DL))) {
342
- // If NewTy is a struct, we can convert the pointer to the struct
343
- // into a pointer to its first member.
344
- // FIXME: This could be extended to support arrays as well.
345
- if (StructType *STy = dyn_cast<StructType>(NewTy)) {
346
-
347
- IntegerType *IdxTy = IntegerType::get (NewTy->getContext (), 32 );
348
- Constant *IdxZero = ConstantInt::get (IdxTy, 0 , false );
349
- Constant * const IdxList[] = {IdxZero, IdxZero};
350
-
351
- Ptr = ConstantExpr::getGetElementPtr (NewTy, Ptr, IdxList);
352
- if (auto *FoldedPtr = ConstantFoldConstant (Ptr, DL, TLI))
353
- Ptr = FoldedPtr;
354
- NewTy = STy->getTypeAtIndex (0U );
355
-
356
- // If we can't improve the situation by introspecting NewTy,
357
- // we have to give up.
358
- } else {
359
- LLVM_DEBUG (dbgs () << " Failed to bitcast constant ptr, can not "
360
- " evaluate.\n " );
361
- return false ;
370
+ // stored value. In order to push the bitcast onto the stored value,
371
+ // a bitcast from the pointer's element type to Val's type must be
372
+ // legal. If it's not, we can try introspecting the type to find a
373
+ // legal conversion.
374
+
375
+ auto castValTy = [&](Constant *P) -> Constant * {
376
+ Type *Ty = cast<PointerType>(P->getType ())->getElementType ();
377
+ if (Constant *FV = ConstantFoldLoadThroughBitcast (Val, Ty, DL)) {
378
+ Ptr = P;
379
+ return FV;
362
380
}
381
+ return nullptr ;
382
+ };
383
+
384
+ Constant *NewVal =
385
+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, castValTy);
386
+ if (!NewVal) {
387
+ LLVM_DEBUG (dbgs () << " Failed to bitcast constant ptr, can not "
388
+ " evaluate.\n " );
389
+ return false ;
363
390
}
364
391
365
392
Val = NewVal;
0 commit comments