23
23
#include " llvm/Analysis/GlobalsModRef.h"
24
24
#include " llvm/Analysis/MemoryDependenceAnalysis.h"
25
25
#include " llvm/Analysis/MemoryLocation.h"
26
+ #include " llvm/Analysis/MemorySSA.h"
27
+ #include " llvm/Analysis/MemorySSAUpdater.h"
26
28
#include " llvm/Analysis/TargetLibraryInfo.h"
27
29
#include " llvm/Analysis/ValueTracking.h"
28
30
#include " llvm/IR/Argument.h"
@@ -278,6 +280,7 @@ class MemCpyOptLegacyPass : public FunctionPass {
278
280
AU.addPreserved <MemoryDependenceWrapperPass>();
279
281
AU.addRequired <AAResultsWrapperPass>();
280
282
AU.addPreserved <AAResultsWrapperPass>();
283
+ AU.addPreserved <MemorySSAWrapperPass>();
281
284
}
282
285
};
283
286
@@ -315,7 +318,27 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
315
318
MemsetRanges Ranges (DL);
316
319
317
320
BasicBlock::iterator BI (StartInst);
321
+
322
+ // Keeps track of the last memory use or def before the insertion point for
323
+ // the new memset. The new MemoryDef for the inserted memsets will be inserted
324
+ // after MemInsertPoint. It points to either LastMemDef or to the last user
325
+ // before the insertion point of the memset, if there are any such users.
326
+ MemoryUseOrDef *MemInsertPoint = nullptr ;
327
+ // Keeps track of the last MemoryDef between StartInst and the insertion point
328
+ // for the new memset. This will become the defining access of the inserted
329
+ // memsets.
330
+ MemoryDef *LastMemDef = nullptr ;
318
331
for (++BI; !BI->isTerminator (); ++BI) {
332
+ if (MSSAU) {
333
+ auto *CurrentAcc = cast_or_null<MemoryUseOrDef>(
334
+ MSSAU->getMemorySSA ()->getMemoryAccess (&*BI));
335
+ if (CurrentAcc) {
336
+ MemInsertPoint = CurrentAcc;
337
+ if (auto *CurrentDef = dyn_cast<MemoryDef>(CurrentAcc))
338
+ LastMemDef = CurrentDef;
339
+ }
340
+ }
341
+
319
342
if (!isa<StoreInst>(BI) && !isa<MemSetInst>(BI)) {
320
343
// If the instruction is readnone, ignore it, otherwise bail out. We
321
344
// don't even allow readonly here because we don't want something like:
@@ -394,15 +417,27 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
394
417
: Range.TheStores ) dbgs ()
395
418
<< *SI << ' \n ' ;
396
419
dbgs () << " With: " << *AMemSet << ' \n ' );
397
-
398
420
if (!Range.TheStores .empty ())
399
421
AMemSet->setDebugLoc (Range.TheStores [0 ]->getDebugLoc ());
400
422
423
+ if (MSSAU) {
424
+ assert (LastMemDef && MemInsertPoint &&
425
+ " Both LastMemDef and MemInsertPoint need to be set" );
426
+ auto *NewDef = cast<MemoryDef>(
427
+ MSSAU->createMemoryAccessAfter (AMemSet, LastMemDef, MemInsertPoint));
428
+ MSSAU->insertDef (NewDef, /* RenameUses=*/ true );
429
+ LastMemDef = NewDef;
430
+ MemInsertPoint = NewDef;
431
+ }
432
+
401
433
// Zap all the stores.
402
434
for (Instruction *SI : Range.TheStores ) {
435
+ if (MSSAU)
436
+ MSSAU->removeMemoryAccess (SI);
403
437
MD->removeInstruction (SI);
404
438
SI->eraseFromParent ();
405
439
}
440
+
406
441
++NumMemSetInfer;
407
442
}
408
443
@@ -573,6 +608,17 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
573
608
LLVM_DEBUG (dbgs () << " Promoting " << *LI << " to " << *SI << " => "
574
609
<< *M << " \n " );
575
610
611
+ if (MSSAU) {
612
+ assert (isa<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (P)));
613
+ auto *LastDef =
614
+ cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (P));
615
+ auto *NewAccess =
616
+ MSSAU->createMemoryAccessAfter (M, LastDef, LastDef);
617
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
618
+ MSSAU->removeMemoryAccess (SI);
619
+ MSSAU->removeMemoryAccess (LI);
620
+ }
621
+
576
622
MD->removeInstruction (SI);
577
623
SI->eraseFromParent ();
578
624
MD->removeInstruction (LI);
@@ -621,6 +667,11 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
621
667
DL.getTypeStoreSize (SI->getOperand (0 )->getType ()),
622
668
commonAlignment (SI->getAlign (), LI->getAlign ()), C);
623
669
if (changed) {
670
+ if (MSSAU) {
671
+ MSSAU->removeMemoryAccess (SI);
672
+ MSSAU->removeMemoryAccess (LI);
673
+ }
674
+
624
675
MD->removeInstruction (SI);
625
676
SI->eraseFromParent ();
626
677
MD->removeInstruction (LI);
@@ -658,6 +709,15 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
658
709
659
710
LLVM_DEBUG (dbgs () << " Promoting " << *SI << " to " << *M << " \n " );
660
711
712
+ if (MSSAU) {
713
+ assert (isa<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (SI)));
714
+ auto *LastDef =
715
+ cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (SI));
716
+ auto *NewAccess = MSSAU->createMemoryAccessAfter (M, LastDef, LastDef);
717
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
718
+ MSSAU->removeMemoryAccess (SI);
719
+ }
720
+
661
721
MD->removeInstruction (SI);
662
722
SI->eraseFromParent ();
663
723
NumMemSetInfer++;
@@ -939,14 +999,23 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,
939
999
// TODO: Is this worth it if we're creating a less aligned memcpy? For
940
1000
// example we could be moving from movaps -> movq on x86.
941
1001
IRBuilder<> Builder (M);
1002
+ Instruction *NewM;
942
1003
if (UseMemMove)
943
- Builder.CreateMemMove (M->getRawDest (), M->getDestAlign (),
944
- MDep->getRawSource (), MDep->getSourceAlign (),
945
- M->getLength (), M->isVolatile ());
1004
+ NewM = Builder.CreateMemMove (M->getRawDest (), M->getDestAlign (),
1005
+ MDep->getRawSource (), MDep->getSourceAlign (),
1006
+ M->getLength (), M->isVolatile ());
946
1007
else
947
- Builder.CreateMemCpy (M->getRawDest (), M->getDestAlign (),
948
- MDep->getRawSource (), MDep->getSourceAlign (),
949
- M->getLength (), M->isVolatile ());
1008
+ NewM = Builder.CreateMemCpy (M->getRawDest (), M->getDestAlign (),
1009
+ MDep->getRawSource (), MDep->getSourceAlign (),
1010
+ M->getLength (), M->isVolatile ());
1011
+
1012
+ if (MSSAU) {
1013
+ assert (isa<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (M)));
1014
+ auto *LastDef = cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (M));
1015
+ auto *NewAccess = MSSAU->createMemoryAccessAfter (NewM, LastDef, LastDef);
1016
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
1017
+ MSSAU->removeMemoryAccess (M);
1018
+ }
950
1019
951
1020
// Remove the instruction we're replacing.
952
1021
MD->removeInstruction (M);
@@ -1012,11 +1081,25 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
1012
1081
Value *SizeDiff = Builder.CreateSub (DestSize, SrcSize);
1013
1082
Value *MemsetLen = Builder.CreateSelect (
1014
1083
Ule, ConstantInt::getNullValue (DestSize->getType ()), SizeDiff);
1015
- Builder.CreateMemSet (
1084
+ Instruction *NewMemSet = Builder.CreateMemSet (
1016
1085
Builder.CreateGEP (Dest->getType ()->getPointerElementType (), Dest,
1017
1086
SrcSize),
1018
1087
MemSet->getOperand (1 ), MemsetLen, MaybeAlign (Align));
1019
1088
1089
+ if (MSSAU) {
1090
+ assert (isa<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (MemCpy)) &&
1091
+ " MemCpy must be a MemoryDef" );
1092
+ // The new memset is inserted after the memcpy, but it is known that its
1093
+ // defining access is the memset about to be removed which immediately
1094
+ // precedes the memcpy.
1095
+ auto *LastDef =
1096
+ cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (MemCpy));
1097
+ auto *NewAccess = MSSAU->createMemoryAccessBefore (
1098
+ NewMemSet, LastDef->getDefiningAccess (), LastDef);
1099
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
1100
+ MSSAU->removeMemoryAccess (MemSet);
1101
+ }
1102
+
1020
1103
MD->removeInstruction (MemSet);
1021
1104
MemSet->eraseFromParent ();
1022
1105
return true ;
@@ -1081,8 +1164,16 @@ bool MemCpyOptPass::performMemCpyToMemSetOptzn(MemCpyInst *MemCpy,
1081
1164
}
1082
1165
1083
1166
IRBuilder<> Builder (MemCpy);
1084
- Builder.CreateMemSet (MemCpy->getRawDest (), MemSet->getOperand (1 ), CopySize,
1085
- MaybeAlign (MemCpy->getDestAlignment ()));
1167
+ Instruction *NewM =
1168
+ Builder.CreateMemSet (MemCpy->getRawDest (), MemSet->getOperand (1 ),
1169
+ CopySize, MaybeAlign (MemCpy->getDestAlignment ()));
1170
+ if (MSSAU) {
1171
+ auto *LastDef =
1172
+ cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (MemCpy));
1173
+ auto *NewAccess = MSSAU->createMemoryAccessAfter (NewM, LastDef, LastDef);
1174
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
1175
+ }
1176
+
1086
1177
return true ;
1087
1178
}
1088
1179
@@ -1098,6 +1189,9 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1098
1189
// If the source and destination of the memcpy are the same, then zap it.
1099
1190
if (M->getSource () == M->getDest ()) {
1100
1191
++BBI;
1192
+ if (MSSAU)
1193
+ MSSAU->removeMemoryAccess (M);
1194
+
1101
1195
MD->removeInstruction (M);
1102
1196
M->eraseFromParent ();
1103
1197
return true ;
@@ -1109,8 +1203,18 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1109
1203
if (Value *ByteVal = isBytewiseValue (GV->getInitializer (),
1110
1204
M->getModule ()->getDataLayout ())) {
1111
1205
IRBuilder<> Builder (M);
1112
- Builder.CreateMemSet (M->getRawDest (), ByteVal, M->getLength (),
1113
- MaybeAlign (M->getDestAlignment ()), false );
1206
+ Instruction *NewM =
1207
+ Builder.CreateMemSet (M->getRawDest (), ByteVal, M->getLength (),
1208
+ MaybeAlign (M->getDestAlignment ()), false );
1209
+ if (MSSAU) {
1210
+ auto *LastDef =
1211
+ cast<MemoryDef>(MSSAU->getMemorySSA ()->getMemoryAccess (M));
1212
+ auto *NewAccess =
1213
+ MSSAU->createMemoryAccessAfter (NewM, LastDef, LastDef);
1214
+ MSSAU->insertDef (cast<MemoryDef>(NewAccess), /* RenameUses=*/ true );
1215
+ MSSAU->removeMemoryAccess (M);
1216
+ }
1217
+
1114
1218
MD->removeInstruction (M);
1115
1219
M->eraseFromParent ();
1116
1220
++NumCpyToSet;
@@ -1145,6 +1249,9 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1145
1249
M->getSourceAlign ().valueOrOne ());
1146
1250
if (performCallSlotOptzn (M, M->getDest (), M->getSource (),
1147
1251
CopySize->getZExtValue (), Alignment, C)) {
1252
+ if (MSSAU)
1253
+ MSSAU->removeMemoryAccess (M);
1254
+
1148
1255
MD->removeInstruction (M);
1149
1256
M->eraseFromParent ();
1150
1257
return true ;
@@ -1161,6 +1268,9 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1161
1268
return processMemCpyMemCpyDependence (M, MDep);
1162
1269
} else if (SrcDepInfo.isDef ()) {
1163
1270
if (hasUndefContents (SrcDepInfo.getInst (), CopySize)) {
1271
+ if (MSSAU)
1272
+ MSSAU->removeMemoryAccess (M);
1273
+
1164
1274
MD->removeInstruction (M);
1165
1275
M->eraseFromParent ();
1166
1276
++NumMemCpyInstr;
@@ -1171,6 +1281,8 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
1171
1281
if (SrcDepInfo.isClobber ())
1172
1282
if (MemSetInst *MDep = dyn_cast<MemSetInst>(SrcDepInfo.getInst ()))
1173
1283
if (performMemCpyToMemSetOptzn (M, MDep)) {
1284
+ if (MSSAU)
1285
+ MSSAU->removeMemoryAccess (M);
1174
1286
MD->removeInstruction (M);
1175
1287
M->eraseFromParent ();
1176
1288
++NumCpyToSet;
@@ -1201,6 +1313,9 @@ bool MemCpyOptPass::processMemMove(MemMoveInst *M) {
1201
1313
M->setCalledFunction (Intrinsic::getDeclaration (M->getModule (),
1202
1314
Intrinsic::memcpy, ArgTys));
1203
1315
1316
+ // For MemorySSA nothing really changes (except that memcpy may imply stricter
1317
+ // aliasing guarantees).
1318
+
1204
1319
// MemDep may have over conservative information about this instruction, just
1205
1320
// conservatively flush it from the cache.
1206
1321
MD->removeInstruction (M);
@@ -1338,27 +1453,34 @@ PreservedAnalyses MemCpyOptPass::run(Function &F, FunctionAnalysisManager &AM) {
1338
1453
auto *AA = &AM.getResult <AAManager>(F);
1339
1454
auto *AC = &AM.getResult <AssumptionAnalysis>(F);
1340
1455
auto *DT = &AM.getResult <DominatorTreeAnalysis>(F);
1456
+ auto *MSSA = AM.getCachedResult <MemorySSAAnalysis>(F);
1341
1457
1342
- bool MadeChange = runImpl (F, &MD, &TLI, AA, AC, DT);
1458
+ bool MadeChange =
1459
+ runImpl (F, &MD, &TLI, AA, AC, DT, MSSA ? &MSSA->getMSSA () : nullptr );
1343
1460
if (!MadeChange)
1344
1461
return PreservedAnalyses::all ();
1345
1462
1346
1463
PreservedAnalyses PA;
1347
1464
PA.preserveSet <CFGAnalyses>();
1348
1465
PA.preserve <GlobalsAA>();
1349
1466
PA.preserve <MemoryDependenceAnalysis>();
1467
+ if (MSSA)
1468
+ PA.preserve <MemorySSAAnalysis>();
1350
1469
return PA;
1351
1470
}
1352
1471
1353
1472
bool MemCpyOptPass::runImpl (Function &F, MemoryDependenceResults *MD_,
1354
1473
TargetLibraryInfo *TLI_, AliasAnalysis *AA_,
1355
- AssumptionCache *AC_, DominatorTree *DT_) {
1474
+ AssumptionCache *AC_, DominatorTree *DT_,
1475
+ MemorySSA *MSSA_) {
1356
1476
bool MadeChange = false ;
1357
1477
MD = MD_;
1358
1478
TLI = TLI_;
1359
1479
AA = AA_;
1360
1480
AC = AC_;
1361
1481
DT = DT_;
1482
+ MemorySSAUpdater MSSAU_ (MSSA_);
1483
+ MSSAU = MSSA_ ? &MSSAU_ : nullptr ;
1362
1484
// If we don't have at least memset and memcpy, there is little point of doing
1363
1485
// anything here. These are required by a freestanding implementation, so if
1364
1486
// even they are disabled, there is no point in trying hard.
@@ -1371,6 +1493,9 @@ bool MemCpyOptPass::runImpl(Function &F, MemoryDependenceResults *MD_,
1371
1493
MadeChange = true ;
1372
1494
}
1373
1495
1496
+ if (MSSA_ && VerifyMemorySSA)
1497
+ MSSA_->verifyMemorySSA ();
1498
+
1374
1499
MD = nullptr ;
1375
1500
return MadeChange;
1376
1501
}
@@ -1385,6 +1510,8 @@ bool MemCpyOptLegacyPass::runOnFunction(Function &F) {
1385
1510
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
1386
1511
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache (F);
1387
1512
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
1513
+ auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
1388
1514
1389
- return Impl.runImpl (F, MD, TLI, AA, AC, DT);
1515
+ return Impl.runImpl (F, MD, TLI, AA, AC, DT,
1516
+ MSSAWP ? &MSSAWP->getMSSA () : nullptr );
1390
1517
}
0 commit comments