@@ -130,8 +130,8 @@ namespace {
130
130
void ConvertUsesToScalar (Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
131
131
Value *ConvertUsesOfLoadToScalar (LoadInst *LI, AllocaInst *NewAI,
132
132
uint64_t Offset);
133
- Value *ConvertUsesOfStoreToScalar (StoreInst *SI , AllocaInst *NewAI,
134
- uint64_t Offset);
133
+ Value *ConvertUsesOfStoreToScalar (Value *StoredVal , AllocaInst *NewAI,
134
+ uint64_t Offset, Instruction *InsertPt );
135
135
static Instruction *isOnlyCopiedFromConstantGlobal (AllocationInst *AI);
136
136
};
137
137
}
@@ -1274,6 +1274,18 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
1274
1274
continue ;
1275
1275
}
1276
1276
1277
+ // If this is a constant sized memset of a constant value (e.g. 0) we can
1278
+ // handle it.
1279
+ if (isa<MemSetInst>(User) &&
1280
+ // Store of constant value.
1281
+ isa<ConstantInt>(User->getOperand (2 )) &&
1282
+ // Store with constant size.
1283
+ isa<ConstantInt>(User->getOperand (3 ))) {
1284
+ VecTy = Type::VoidTy;
1285
+ IsNotTrivial = true ;
1286
+ continue ;
1287
+ }
1288
+
1277
1289
// Otherwise, we cannot handle this!
1278
1290
return false ;
1279
1291
}
@@ -1301,7 +1313,8 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
1301
1313
1302
1314
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
1303
1315
assert (SI->getOperand (0 ) != Ptr && " Consistency error!" );
1304
- new StoreInst (ConvertUsesOfStoreToScalar (SI, NewAI, Offset), NewAI, SI);
1316
+ new StoreInst (ConvertUsesOfStoreToScalar (SI->getOperand (0 ), NewAI,
1317
+ Offset, SI), NewAI, SI);
1305
1318
SI->eraseFromParent ();
1306
1319
continue ;
1307
1320
}
@@ -1321,6 +1334,29 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
1321
1334
GEP->eraseFromParent ();
1322
1335
continue ;
1323
1336
}
1337
+
1338
+ // If this is a constant sized memset of a constant value (e.g. 0) we can
1339
+ // transform it into a store of the expanded constant value.
1340
+ if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
1341
+ assert (MSI->getRawDest () == Ptr && " Consistency error!" );
1342
+ unsigned NumBytes = cast<ConstantInt>(MSI->getLength ())->getZExtValue ();
1343
+ unsigned Val = cast<ConstantInt>(MSI->getValue ())->getZExtValue ();
1344
+
1345
+ // Compute the value replicated the right number of times.
1346
+ APInt APVal (NumBytes*8 , Val);
1347
+
1348
+ // Splat the value if non-zero.
1349
+ if (Val)
1350
+ for (unsigned i = 1 ; i != NumBytes; ++i)
1351
+ APVal |= APVal << 8 ;
1352
+
1353
+ new StoreInst (ConvertUsesOfStoreToScalar (ConstantInt::get (APVal), NewAI,
1354
+ Offset, MSI), NewAI, MSI);
1355
+ MSI->eraseFromParent ();
1356
+ continue ;
1357
+ }
1358
+
1359
+
1324
1360
assert (0 && " Unsupported operation!" );
1325
1361
abort ();
1326
1362
}
@@ -1422,40 +1458,38 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
1422
1458
// /
1423
1459
// / Offset is an offset from the original alloca, in bits that need to be
1424
1460
// / shifted to the right. By the end of this, there should be no uses of Ptr.
1425
- Value *SROA::ConvertUsesOfStoreToScalar (StoreInst *SI , AllocaInst *NewAI,
1426
- uint64_t Offset) {
1461
+ Value *SROA::ConvertUsesOfStoreToScalar (Value *SV , AllocaInst *NewAI,
1462
+ uint64_t Offset, Instruction *IP ) {
1427
1463
1428
1464
// Convert the stored type to the actual type, shift it left to insert
1429
1465
// then 'or' into place.
1430
- Value *SV = SI->getOperand (0 );
1431
1466
const Type *AllocaType = NewAI->getType ()->getElementType ();
1432
- if (SV->getType () == AllocaType && Offset == 0 ) {
1467
+ if (SV->getType () == AllocaType && Offset == 0 )
1433
1468
return SV;
1434
- }
1435
1469
1436
1470
if (const VectorType *VTy = dyn_cast<VectorType>(AllocaType)) {
1437
- Value *Old = new LoadInst (NewAI, NewAI->getName ()+" .in" , SI );
1471
+ Value *Old = new LoadInst (NewAI, NewAI->getName ()+" .in" , IP );
1438
1472
1439
1473
// If the result alloca is a vector type, this is either an element
1440
1474
// access or a bitcast to another vector type.
1441
1475
if (isa<VectorType>(SV->getType ())) {
1442
- SV = new BitCastInst (SV, AllocaType, SV->getName (), SI );
1476
+ SV = new BitCastInst (SV, AllocaType, SV->getName (), IP );
1443
1477
} else {
1444
1478
// Must be an element insertion.
1445
1479
unsigned Elt = Offset/TD->getTypePaddedSizeInBits (VTy->getElementType ());
1446
1480
1447
1481
if (SV->getType () != VTy->getElementType ())
1448
- SV = new BitCastInst (SV, VTy->getElementType (), " tmp" , SI );
1482
+ SV = new BitCastInst (SV, VTy->getElementType (), " tmp" , IP );
1449
1483
1450
1484
SV = InsertElementInst::Create (Old, SV,
1451
1485
ConstantInt::get (Type::Int32Ty, Elt),
1452
- " tmp" , SI );
1486
+ " tmp" , IP );
1453
1487
}
1454
1488
return SV;
1455
1489
}
1456
1490
1457
1491
1458
- Value *Old = new LoadInst (NewAI, NewAI->getName ()+" .in" , SI );
1492
+ Value *Old = new LoadInst (NewAI, NewAI->getName ()+" .in" , IP );
1459
1493
1460
1494
// If SV is a float, convert it to the appropriate integer type.
1461
1495
// If it is a pointer, do the same, and also handle ptr->ptr casts
@@ -1465,19 +1499,19 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI,
1465
1499
unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits (SV->getType ());
1466
1500
unsigned DestStoreWidth = TD->getTypeStoreSizeInBits (AllocaType);
1467
1501
if (SV->getType ()->isFloatingPoint () || isa<VectorType>(SV->getType ()))
1468
- SV = new BitCastInst (SV, IntegerType::get (SrcWidth), SV->getName (), SI );
1502
+ SV = new BitCastInst (SV, IntegerType::get (SrcWidth), SV->getName (), IP );
1469
1503
else if (isa<PointerType>(SV->getType ()))
1470
- SV = new PtrToIntInst (SV, TD->getIntPtrType (), SV->getName (), SI );
1504
+ SV = new PtrToIntInst (SV, TD->getIntPtrType (), SV->getName (), IP );
1471
1505
1472
1506
// Zero extend or truncate the value if needed.
1473
1507
if (SV->getType () != AllocaType) {
1474
1508
if (SV->getType ()->getPrimitiveSizeInBits () <
1475
1509
AllocaType->getPrimitiveSizeInBits ())
1476
- SV = new ZExtInst (SV, AllocaType, SV->getName (), SI );
1510
+ SV = new ZExtInst (SV, AllocaType, SV->getName (), IP );
1477
1511
else {
1478
1512
// Truncation may be needed if storing more than the alloca can hold
1479
1513
// (undefined behavior).
1480
- SV = new TruncInst (SV, AllocaType, SV->getName (), SI );
1514
+ SV = new TruncInst (SV, AllocaType, SV->getName (), IP );
1481
1515
SrcWidth = DestWidth;
1482
1516
SrcStoreWidth = DestStoreWidth;
1483
1517
}
@@ -1502,12 +1536,12 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI,
1502
1536
if (ShAmt > 0 && (unsigned )ShAmt < DestWidth) {
1503
1537
SV = BinaryOperator::CreateShl (SV,
1504
1538
ConstantInt::get (SV->getType (), ShAmt),
1505
- SV->getName (), SI );
1539
+ SV->getName (), IP );
1506
1540
Mask <<= ShAmt;
1507
1541
} else if (ShAmt < 0 && (unsigned )-ShAmt < DestWidth) {
1508
1542
SV = BinaryOperator::CreateLShr (SV,
1509
1543
ConstantInt::get (SV->getType (), -ShAmt),
1510
- SV->getName (), SI );
1544
+ SV->getName (), IP );
1511
1545
Mask = Mask.lshr (-ShAmt);
1512
1546
}
1513
1547
@@ -1516,8 +1550,8 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI,
1516
1550
if (SrcWidth != DestWidth) {
1517
1551
assert (DestWidth > SrcWidth);
1518
1552
Old = BinaryOperator::CreateAnd (Old, ConstantInt::get (~Mask),
1519
- Old->getName ()+" .mask" , SI );
1520
- SV = BinaryOperator::CreateOr (Old, SV, SV->getName ()+" .ins" , SI );
1553
+ Old->getName ()+" .mask" , IP );
1554
+ SV = BinaryOperator::CreateOr (Old, SV, SV->getName ()+" .ins" , IP );
1521
1555
}
1522
1556
return SV;
1523
1557
}
0 commit comments