LLVM: lib/Transforms/IPO/GlobalOpt.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
66#include
67#include
68#include
69#include
70#include
71
72using namespace llvm;
73
74#define DEBUG_TYPE "globalopt"
75
76STATISTIC(NumMarked , "Number of globals marked constant");
77STATISTIC(NumUnnamed , "Number of globals marked unnamed_addr");
78STATISTIC(NumSRA , "Number of aggregate globals broken into scalars");
79STATISTIC(NumSubstitute,"Number of globals with initializers stored into them");
80STATISTIC(NumDeleted , "Number of globals deleted");
81STATISTIC(NumGlobUses , "Number of global uses devirtualized");
82STATISTIC(NumLocalized , "Number of globals localized");
83STATISTIC(NumShrunkToBool , "Number of global vars shrunk to booleans");
84STATISTIC(NumFastCallFns , "Number of functions converted to fastcc");
85STATISTIC(NumCtorsEvaluated, "Number of static ctors evaluated");
86STATISTIC(NumNestRemoved , "Number of nest attributes removed");
87STATISTIC(NumAliasesResolved, "Number of global aliases resolved");
88STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated");
89STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed");
90STATISTIC(NumAtExitRemoved, "Number of atexit handlers removed");
91STATISTIC(NumInternalFunc, "Number of internal functions");
92STATISTIC(NumColdCC, "Number of functions marked coldcc");
93STATISTIC(NumIFuncsResolved, "Number of statically resolved IFuncs");
94STATISTIC(NumIFuncsDeleted, "Number of IFuncs removed");
95
98 cl::desc("Statically resolve calls to versioned "
99 "functions from non-versioned callers."),
101
104 cl::desc("Maximum number of caller/callee versions that is allowed for "
105 "using the expensive (cubic) static resolution algorithm."));
106
109 cl::desc("Enable stress test of coldcc by adding "
110 "calling conv to all internal functions."),
112
116 "Maximum block frequency, expressed as a percentage of caller's "
117 "entry frequency, for a call site to be considered cold for enabling "
118 "coldcc"));
119
120
121
123
124
125
126
127
128
129
130
132 return false;
133
136
137 unsigned Limit = 20;
138 do {
139 Type *Ty = Types.pop_back_val();
140 switch (Ty->getTypeID()) {
141 default: break;
143 return true;
147 return true;
148 break;
151 break;
154 if (STy->isOpaque()) return true;
159 Types.push_back(InnerTy);
160 }
161 break;
162 }
163 }
164 if (--Limit == 0) return true;
165 } while (!Types.empty());
166 return false;
167}
168
169
170
171
174 do {
176 return true;
177 if (!V->hasOneUse())
178 return false;
181 return false;
183 return true;
184
186 if (I->mayHaveSideEffects())
187 return false;
189 if (->hasAllConstantIndices())
190 return false;
191 } else if (I->getNumOperands() != 1) {
192 return false;
193 }
194
195 V = I->getOperand(0);
196 } while (true);
197}
198
199
200
201
202static bool
205
206
207
208
209
210
211
212
213
215
216
217
219
221
222 while (!Worklist.empty()) {
225 Value *V = SI->getValueOperand();
228 SI->eraseFromParent();
230 if (I->hasOneUse())
231 Dead.push_back(std::make_pair(I, SI));
232 }
236 MSI->eraseFromParent();
238 if (I->hasOneUse())
239 Dead.push_back(std::make_pair(I, MSI));
240 }
243 if (MemSrc && MemSrc->isConstant()) {
245 MTI->eraseFromParent();
247 if (I->hasOneUse())
248 Dead.push_back(std::make_pair(I, MTI));
249 }
253 }
254 }
255
256 for (const auto &[Inst, Store] : Dead) {
258 Store->eraseFromParent();
260 do {
262 break;
264 if (!J)
265 break;
266 I->eraseFromParent();
267 I = J;
268 } while (true);
269 I->eraseFromParent();
271 }
272 }
273
276}
277
278
279
280
287
290 for (Value *Op : I->operands())
293 I->eraseFromParent();
295 };
296 while (!WorkList.empty()) {
298 if (!Visited.insert(U).second)
299 continue;
300
308
309
310 Type *Ty = LI->getType();
312 LI->replaceAllUsesWith(Res);
313 EraseFromParent(LI);
314 continue;
315 }
316
317 Value *PtrOp = LI->getPointerOperand();
322 if (II->getIntrinsicID() == Intrinsic::threadlocal_address)
323 PtrOp = II->getArgOperand(0);
324 }
325 if (PtrOp == GV) {
327 LI->replaceAllUsesWith(Value);
328 EraseFromParent(LI);
329 }
330 }
332
333 EraseFromParent(SI);
336 EraseFromParent(MI);
338 if (II->getIntrinsicID() == Intrinsic::threadlocal_address)
340 }
341 }
342
347}
348
349
350
357
358
359
364 auto AppendUses = [&](Value *V) {
366 if (Visited.insert(&U).second)
368 };
369 AppendUses(GV);
370 while (!Worklist.empty()) {
372 User *V = U->getUser();
373
376 (GEP && GEP->hasAllConstantIndices())) {
377 AppendUses(V);
378 continue;
379 }
380
382
383
385 return false;
386
387 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
388 Ptr = Ptr->stripAndAccumulateConstantOffsets(DL, Offset,
389 true);
390 if (Ptr != GV || Offset.getActiveBits() >= 64)
391 return false;
392
393
394
396 const auto &[It, Inserted] =
398 if (Ty != It->second.Ty)
399 return false;
400
401 if (Inserted) {
402 It->second.Initializer =
404 if (!It->second.Initializer) {
405 LLVM_DEBUG(dbgs() << "Global SRA: Failed to evaluate initializer of "
406 << *GV << " with type " << *Ty << " at offset "
407 << Offset.getZExtValue());
408 return false;
409 }
410 }
411
412
413 if (Ty->isScalableTy())
414 return false;
415
416 auto IsStored = [](Value *V, Constant *Initializer) {
418 if ()
419 return false;
420
422 if (!StoredConst)
423 return true;
424
425
426 return Initializer != StoredConst;
427 };
428
430 It->second.IsStored |= IsStored(V, It->second.Initializer);
431 continue;
432 }
433
434
437 return false;
438 continue;
439 }
440
441
442 return false;
443 }
444
445 return true;
446}
447
448
450 uint64_t FragmentOffsetInBits,
455 for (auto *GVE : GVs) {
456 DIVariable *Var = GVE->getVariable();
458 int64_t CurVarOffsetInBytes = 0;
459 uint64_t CurVarOffsetInBits = 0;
460 uint64_t FragmentEndInBits = FragmentOffsetInBits + FragmentSizeInBits;
461
462
464 continue;
465
466
467 if (CurVarOffsetInBytes < 0)
468 continue;
469
470
471 CurVarOffsetInBits = CHAR_BIT * (uint64_t)CurVarOffsetInBytes;
472
473
474 if (CurVarOffsetInBits >= FragmentEndInBits)
475 continue;
476
478 uint64_t CurVarEndInBits = CurVarOffsetInBits + CurVarSize;
479
480 if (CurVarSize != 0 &&
481 CurVarEndInBits <= FragmentOffsetInBits)
482 continue;
483
484
485
486 if (CurVarSize != 0 &&
487 CurVarOffsetInBits >= FragmentOffsetInBits &&
488 CurVarEndInBits <= FragmentEndInBits) {
489 uint64_t CurVarOffsetInFragment =
490 (CurVarOffsetInBits - FragmentOffsetInBits) / 8;
491 if (CurVarOffsetInFragment != 0)
493 CurVarOffsetInFragment});
494 else
496 auto *NGVE =
499 continue;
500 }
501
502
503 if (FragmentSizeInBits < VarSize) {
504 if (CurVarOffsetInBits > FragmentOffsetInBits)
505 continue;
506 uint64_t CurVarFragmentOffsetInBits =
507 FragmentOffsetInBits - CurVarOffsetInBits;
508 uint64_t CurVarFragmentSizeInBits = FragmentSizeInBits;
509 if (CurVarSize != 0 && CurVarEndInBits < FragmentEndInBits)
510 CurVarFragmentSizeInBits -= (FragmentEndInBits - CurVarEndInBits);
511 if (CurVarOffsetInBits)
514 Expr, CurVarFragmentOffsetInBits, CurVarFragmentSizeInBits))
515 Expr = *E;
516 else
517 continue;
518 }
521 }
522}
523
524
525
526
527
528
531
532
535 return nullptr;
536
537
539 return nullptr;
540
541
542
543
544 unsigned NumParts = count_if(Parts, [](const auto &Pair) {
545 return Pair.second.IsLoaded && Pair.second.IsStored;
546 });
547 if (NumParts > 16)
548 return nullptr;
549
550
552 for (const auto &Pair : Parts) {
554 {Pair.first, Pair.second.Ty, Pair.second.Initializer});
555 }
557
558
560 for (const auto &[OffsetForTy, Ty, _] : TypesVector) {
561
562 if (OffsetForTy < Offset)
563 return nullptr;
564
565 Offset = OffsetForTy + DL.getTypeAllocSize(Ty);
566 }
567
568
570 return nullptr;
571
572 LLVM_DEBUG(dbgs() << "PERFORMING GLOBAL SRA ON: " << *GV << "\n");
573
574
575 Align StartAlignment =
578
579
581 unsigned NameSuffix = 0;
582 for (auto &[OffsetForTy, Ty, Initializer] : TypesVector) {
585 Initializer, GV->getName() + "." + Twine(NameSuffix++), GV,
587
589 NewGlobals.insert({OffsetForTy, NGV});
590
591
592
593
594
597
598
600 DL.getTypeAllocSizeInBits(Ty), VarSize);
601 }
602
603
607 auto AppendUsers = [&](Value *V) {
609 if (Visited.insert(U).second)
611 };
612 AppendUsers(GV);
613 while (!Worklist.empty()) {
617 AppendUsers(V);
620 continue;
621 }
622
624 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
625 Ptr = Ptr->stripAndAccumulateConstantOffsets(DL, Offset,
626 true);
627 assert(Ptr == GV && "Load/store must be from/to global");
629 assert(NGV && "Must have replacement global for this offset");
630
631
635
637 LI->setOperand(0, NGV);
638 LI->setAlignment(NewAlign);
639 } else {
641 SI->setOperand(1, NGV);
642 SI->setAlignment(NewAlign);
643 }
644 continue;
645 }
646
648 "Other users can only be dead constants");
649 }
650
651
655 ++NumSRA;
656
658 return NewGlobals.begin()->second;
659}
660
661
662
663
666 for (const User *U : V->users()) {
668
669
671 return false;
672 }
674
676 if (SI->getOperand(0) == V) {
677 return false;
678 }
680 if (CI->getCalledOperand() != V) {
681 return false;
682 }
684 if (II->getCalledOperand() != V) {
685 return false;
686 }
689 return false;
693
694
696 return false;
702 ->getPointerOperand()
703 ->stripPointerCasts()) &&
704 "Should be GlobalVariable");
705
706
707
708 } else {
709 return false;
710 }
711 }
712 return true;
713}
714
715
716
717
721 while (!Worklist.empty()) {
723 for (const auto *U : P->users()) {
725 if (!LI->isSimple())
726 return false;
729 return false;
731 if (->isSimple())
732 return false;
733
734 if (SI->getPointerOperand() != P)
735 return false;
737 if (CE->stripPointerCasts() != GV)
738 return false;
739
741 } else {
742
743 return false;
744 }
745 }
746 }
747
748 return true;
749}
750
751
756 while (!Worklist.empty()) {
758 for (auto *U : P->users()) {
761 continue;
762 }
763
765 "Expect only load or store instructions");
766 Uses.push_back(U);
767 }
768 }
769}
770
773 for (auto UI = V->user_begin(), E = V->user_end(); UI != E; ) {
775
776
778 return false;
780 LI->setOperand(0, NewV);
783 if (SI->getOperand(1) == V) {
784 SI->setOperand(1, NewV);
786 }
790
791
794 bool PassedAsArg = false;
795 for (unsigned i = 0, e = CB->arg_size(); i != e; ++i)
797 PassedAsArg = true;
799 }
800
801 if (PassedAsArg) {
802
803 UI = V->user_begin();
804 }
805 }
809 if (CI->use_empty()) {
811 CI->eraseFromParent();
812 }
814
816 Idxs.reserve(GEPI->getNumOperands()-1);
817 for (User::op_iterator i = GEPI->op_begin() + 1, e = GEPI->op_end();
818 i != e; ++i)
821 else
822 break;
823 if (Idxs.size() == GEPI->getNumOperands()-1)
826 NewV, Idxs));
827 if (GEPI->use_empty()) {
829 GEPI->eraseFromParent();
830 }
831 }
832 }
833
835}
836
837
838
839
840
845
846
847
848 bool AllNonStoreUsesGone = true;
849
850
854
855 if (LI->use_empty()) {
856 LI->eraseFromParent();
858 } else {
859 AllNonStoreUsesGone = false;
860 }
862
863 assert(GlobalUser->getOperand(1) == GV &&
864 "Must be storing *to* the global");
865 } else {
866 AllNonStoreUsesGone = false;
867
868
869
875 "Only expect load and stores!");
876 }
877 }
878
880 LLVM_DEBUG(dbgs() << "OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV
881 << "\n");
882 ++NumGlobUses;
883 }
884
885
886
887 if (AllNonStoreUsesGone) {
890 } else {
893 }
898 ++NumDeleted;
899 }
900 }
902}
903
904
905
911 I->replaceAllUsesWith(NewC);
912
913
914
915 while (UI != E && *UI == I)
916 ++UI;
918 I->eraseFromParent();
919 }
920}
921
922
923
924
925
926
932 LLVM_DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI
933 << '\n');
934
935
937 AllocSize);
938
939
940
945
946
947
948
949
950
953
954 Builder.CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);
955 }
956
957
959
960
961
966 bool InitBoolUsed = false;
967
968
971 for (auto *U : Guses) {
973
974
977 SI->getValueOperand())),
978 InitBool, false, Align(1), SI->getOrdering(), SI->getSyncScopeID(),
979 SI->getIterator());
980 NewSI->setDebugLoc(SI->getDebugLoc());
981 SI->eraseFromParent();
982 continue;
983 }
984
989 if (!ICI) {
990 LoadUse.set(NewGV);
991 continue;
992 }
993
994
996 InitBool->getName() + ".val", false, Align(1),
999
1000
1001
1002
1004 InitBoolUsed = true;
1009 break;
1012 break;
1017 break;
1020 break;
1021 }
1024 }
1026 }
1027
1028
1029 if (!InitBoolUsed) {
1030 while (!InitBool->use_empty())
1032 delete InitBool;
1033 } else
1035
1036
1039
1040
1041
1042
1044
1045 return NewGV;
1046}
1047
1048
1049
1050
1051static bool
1057
1058 while (!Worklist.empty()) {
1060 if (!Visited.insert(V).second)
1061 continue;
1062
1063 for (const Use &VUse : V->uses()) {
1064 const User *U = VUse.getUser();
1066 continue;
1067
1069 if (SI->getValueOperand() == V &&
1070 SI->getPointerOperand()->stripPointerCasts() != GV)
1071 return false;
1072 continue;
1073 }
1074
1077 continue;
1078 }
1079
1080 return false;
1081 }
1082 }
1083
1084 return true;
1085}
1086
1087
1088
1089
1090
1096
1097 return false;
1098
1101 if (!InitVal)
1102
1103 return false;
1104
1107 return false;
1108
1109
1110
1111
1112 if (AllocSize >= 2048)
1113 return false;
1114
1115
1116
1117
1118
1119
1120
1122 return false;
1123
1124
1125
1126
1127
1129 return false;
1130
1132 return true;
1133}
1134
1135
1136
1137static bool
1141
1142
1143
1144
1149 nullptr ,
1152
1154 return true;
1157 auto *TLI = &GetTLI(*CI->getFunction());
1159 return true;
1160 }
1161 }
1162 }
1163
1164 return false;
1165}
1166
1167
1168
1169
1170
1173
1174
1175
1176
1177
1178
1182 return false;
1183
1184
1185
1188 return false;
1190 return false;
1191 }
1192
1193 LLVM_DEBUG(dbgs() << " *** SHRINKING TO BOOL: " << *GV << "\n");
1194
1195
1197 false,
1205
1208 "No reason to shrink to bool!");
1209
1212
1213
1214
1215 bool IsOneZero = false;
1216 bool EmitOneOrZero = true;
1218 if (CI && CI->getValue().getActiveBits() <= 64) {
1219 IsOneZero = InitVal->isNullValue() && CI->isOne();
1220
1222 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {
1223 uint64_t ValInit = CIInit->getZExtValue();
1224 uint64_t ValOther = CI->getZExtValue();
1225 uint64_t ValMinus = ValOther - ValInit;
1226
1227 for(auto *GVe : GVs){
1231 unsigned SizeInOctets =
1232 DL.getTypeAllocSizeInBits(NewGV->getValueType()) / 8;
1233
1234
1235
1236
1237
1238
1239
1240
1241
1243 dwarf::DW_OP_deref_size, SizeInOctets,
1244 dwarf::DW_OP_constu, ValMinus,
1245 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
1246 dwarf::DW_OP_plus};
1247 bool WithStackValue = true;
1252 }
1253 EmitOneOrZero = false;
1254 }
1255 }
1256
1257 if (EmitOneOrZero) {
1258
1259
1260 for(auto *GV : GVs)
1262 }
1263
1267
1268 bool StoringOther = SI->getOperand(0) == OtherVal;
1269
1270 Value *StoreVal;
1271 if (StoringOther || SI->getOperand(0) == InitVal) {
1273 StoringOther);
1274 } else {
1275
1276
1277
1279
1280
1281
1282
1284 assert(LI->getOperand(0) == GV && "Not a copy!");
1285
1286 StoreVal =
1288 false, Align(1), LI->getOrdering(),
1289 LI->getSyncScopeID(), LI->getIterator());
1290 cast(StoreVal)->setDebugLoc(LI->getDebugLoc());
1291 } else {
1293 "This is not a form that we understand!");
1294 StoreVal = StoredVal->getOperand(0);
1296 }
1297 }
1299 new StoreInst(StoreVal, NewGV, false, Align(1), SI->getOrdering(),
1300 SI->getSyncScopeID(), SI->getIterator());
1302 } else {
1303
1309 if (IsOneZero)
1311 else
1314
1315
1319 }
1321 }
1322
1323
1324
1327 return true;
1328}
1329
1330static bool
1335
1337 return false;
1338
1341 return false;
1342
1343 bool Dead;
1345 Dead = (F->isDeclaration() && F->use_empty()) || F->isDefTriviallyDead();
1346 else
1348 if (!Dead)
1349 return false;
1350
1351 LLVM_DEBUG(dbgs() << "GLOBAL DEAD: " << GV << "\n");
1353 if (DeleteFnCallback)
1354 DeleteFnCallback(*F);
1355 }
1358 ++NumDeleted;
1359 return true;
1360}
1361
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1378 for (auto *U : GV->users()) {
1380 if ()
1381 return false;
1382 assert(I->getParent()->getParent() == F);
1383
1388 else
1389 return false;
1390 }
1391
1392
1393
1394
1395
1396 auto &DT = LookupDomTree(*const_cast<Function *>(F));
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407 const unsigned Threshold = 100;
1408 if (Loads.size() * Stores.size() > Threshold)
1409 return false;
1410
1411 for (auto *L : Loads) {
1412 auto *LTy = L->getType();
1415
1416
1417
1418 return DT.dominates(S, L) &&
1419 DL.getTypeStoreSize(LTy).getFixedValue() <=
1420 DL.getTypeStoreSize(STy).getFixedValue();
1421 }))
1422 return false;
1423 }
1424
1425 return true;
1426}
1427
1428
1429
1430
1435
1436
1437
1439 return false;
1444 if (LI->getFunction() == F &&
1445 LI->getType() == StoredOnceValue->getType() && LI->isSimple())
1447 }
1448 }
1449
1450 bool MadeChange = false;
1451 if (!Loads.empty()) {
1452 auto &DT = LookupDomTree(*const_cast<Function *>(F));
1453 for (auto *LI : Loads) {
1454 if (DT.dominates(StoredOnceStore, LI)) {
1455 LI->replaceAllUsesWith(const_cast<Value *>(StoredOnceValue));
1456 LI->eraseFromParent();
1457 MadeChange = true;
1458 }
1459 }
1460 }
1461 return MadeChange;
1462}
1463
1464
1465
1466static bool
1472
1473
1474
1475
1476
1477
1478
1479
1480 if (!GS.HasMultipleAccessingFunctions &&
1481 GS.AccessingFunction &&
1485 GS.AccessingFunction->doesNotRecurse() &&
1487 LookupDomTree)) {
1489
1490 LLVM_DEBUG(dbgs() << "LOCALIZING GLOBAL: " << *GV << "\n");
1492 GS.AccessingFunction->getEntryBlock().begin().getNonConst();
1494
1496 nullptr, GV->getName(), FirstI);
1500
1501
1502
1504 }
1505
1508 ++NumLocalized;
1509 return true;
1510 }
1511
1513
1514
1515
1516 if (!GS.IsLoaded) {
1517 LLVM_DEBUG(dbgs() << "GLOBAL NEVER LOADED: " << *GV << "\n");
1518
1520
1522 } else {
1523
1524
1526 }
1527
1528
1531 ++NumDeleted;
1533 }
1535
1536 }
1538 LLVM_DEBUG(dbgs() << "MARKING CONSTANT: " << *GV << "\n");
1539
1540
1541
1542
1544 assert(!GV->isConstant() && "Expected a non-constant global");
1547 }
1548
1549
1551
1552
1554 LLVM_DEBUG(dbgs() << " *** Marking constant allowed us to simplify "
1555 << "all users and delete global!\n");
1557 ++NumDeleted;
1558 return true;
1559 }
1560
1561
1562 ++NumMarked;
1563 }
1567 return true;
1568 }
1569 Value *StoredOnceValue = GS.getStoredOnceValue();
1572 const_cast<Function &>(*GS.StoredOnceStore->getFunction());
1573 bool CanHaveNonUndefGlobalInitializer =
1574 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
1576
1577
1578
1579
1580
1581
1582
1585 DL.getTypeAllocSize(SOVConstant->getType()) ==
1587 CanHaveNonUndefGlobalInitializer) {
1588 if (SOVConstant->getType() == GV->getValueType()) {
1589
1591 } else {
1592
1597 NGV->takeName(GV);
1598 NGV->copyAttributesFrom(GV);
1601 GV = NGV;
1602 }
1603
1604
1606
1608 LLVM_DEBUG(dbgs() << " *** Substituting initializer allowed us to "
1609 << "simplify all users and delete global!\n");
1611 ++NumDeleted;
1612 }
1613 ++NumSubstitute;
1614 return true;
1615 }
1616
1617
1618
1620 return true;
1621
1622
1623
1624 if (GS.NumStores == 1)
1626 return true;
1627
1628
1629
1632 CanHaveNonUndefGlobalInitializer)) {
1634 ++NumShrunkToBool;
1635 return true;
1636 }
1637 }
1638 }
1639
1641}
1642
1643
1644
1645static bool
1651 return false;
1652
1654
1656 return false;
1657
1664 NumUnnamed++;
1666 }
1667 }
1668
1669
1672
1674 if (!GVar)
1676
1677 if (GVar->isConstant() || !GVar->hasInitializer())
1679
1682}
1683
1684
1685
1687 for (User *U : F->users())
1689 if (Call->getCalledOperand() == F)
1691}
1692
1695 unsigned AttrIndex;
1696 if (Attrs.hasAttrSomewhere(A, &AttrIndex))
1697 return Attrs.removeAttributeAtIndex(C, AttrIndex, A);
1698 return Attrs;
1699}
1700
1702 F->setAttributes(StripAttr(F->getContext(), F->getAttributes(), A));
1703 for (User *U : F->users()) {
1706 }
1707}
1708
1709
1710
1711
1712
1715
1716
1718 return false;
1719
1720 if (F->isVarArg())
1721 return false;
1722
1723
1724
1725
1726
1727 for (User *U : F->users()) {
1729 if (!CI)
1730 continue;
1731
1733 return false;
1734 }
1735
1737 if (BB.getTerminatingMustTailCall())
1738 return false;
1739
1740 return ->hasAddressTaken();
1741}
1742
1746 auto Res = ChangeableCCCache.try_emplace(F, false);
1747 if (Res.second)
1749 return Res.first->second;
1750}
1751
1752
1753
1756 auto *CallSiteBB = CB.getParent();
1757 auto CallSiteFreq = CallerBFI.getBlockFreq(CallSiteBB);
1758 auto CallerEntryFreq =
1760 return CallSiteFreq < CallerEntryFreq * ColdProb;
1761}
1762
1763
1764
1765
1766
1767static bool
1770 const std::vector<Function *> &AllCallsCold) {
1771
1772 if (F.user_empty())
1773 return false;
1774
1775 for (User *U : F.users()) {
1778 continue;
1782 return false;
1784 return false;
1785 }
1786 return true;
1787}
1788
1790 for (User *U : F->users())
1792 if (Call->getCalledOperand() == F)
1794}
1795
1796
1797
1798
1799static bool
1806
1807 if (CI->isInlineAsm())
1808 continue;
1809 Function *CalledFn = CI->getCalledFunction();
1810 if (!CalledFn)
1811 return false;
1812
1813
1814
1815
1817 continue;
1819 return false;
1820
1822 return false;
1825 return false;
1826 }
1827 }
1828 }
1829 return true;
1830}
1831
1833 for (User *U : F->users()) {
1836 return true;
1837 }
1838 return false;
1839}
1840
1842 for (User *U : F->users())
1844 return true;
1845 return false;
1846}
1847
1850
1851 auto *M = F->getParent();
1852
1854
1855
1857 for (User *U : PreallocatedCalls) {
1859 if (!CB)
1860 continue;
1861
1864 "Shouldn't call RemotePreallocated() on a musttail preallocated call");
1865
1868 CallBase *PreallocatedSetup = nullptr;
1869 for (auto *It = OpBundles.begin(); It != OpBundles.end(); ++It) {
1870 if (It->getTag() == "preallocated") {
1871 PreallocatedSetup = cast(*It->input_begin());
1872 OpBundles.erase(It);
1873 break;
1874 }
1875 }
1876 assert(PreallocatedSetup && "Did not find preallocated bundle");
1879
1881 "Unknown indirect call type");
1886
1887 Builder.SetInsertPoint(PreallocatedSetup);
1888 auto *StackSave = Builder.CreateStackSave();
1889 Builder.SetInsertPoint(NewCB->getNextNode());
1890 Builder.CreateStackRestore(StackSave);
1891
1892
1893
1894
1895
1896
1897
1898
1901 for (auto *User : PreallocatedArgs) {
1903 assert(UseCall->getCalledFunction()->getIntrinsicID() ==
1904 Intrinsic::call_preallocated_arg &&
1905 "preallocated token use was not a llvm.call.preallocated.arg");
1908 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
1909 if (!AllocaReplacement) {
1910 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
1911 auto *ArgType =
1912 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
1913 auto *InsertBefore = PreallocatedSetup->getNextNode();
1914 Builder.SetInsertPoint(InsertBefore);
1915 auto *Alloca =
1916 Builder.CreateAlloca(ArgType, AddressSpace, nullptr, "paarg");
1917 ArgAllocas[AllocArgIndex] = Alloca;
1918 AllocaReplacement = Alloca;
1919 }
1920
1921 UseCall->replaceAllUsesWith(AllocaReplacement);
1922 UseCall->eraseFromParent();
1923 }
1924
1926 }
1927}
1928
1929static bool
1938
1940
1942 std::vector<Function *> AllCallsCold;
1945 AllCallsCold.push_back(&F);
1946
1947
1949
1950
1951 if (F.hasFnAttribute(Attribute::Naked))
1952 continue;
1953
1954
1955 if (.hasName() &&
.isDeclaration() &&
.hasLocalLinkage())
1957
1958 if (deleteIfDead(F, NotDiscardableComdats, DeleteFnCallback)) {
1960 continue;
1961 }
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972 if (.isDeclaration()) {
1975 ChangedCFGCallback(F);
1976 }
1977 }
1978
1980
1981 if (.hasLocalLinkage())
1982 continue;
1983
1984
1985
1986
1987
1988
1989 if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
1993 }
1994
1995
1996
1997 if (F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
2002 }
2003 continue;
2004 }
2005
2007 NumInternalFunc++;
2009
2010
2011
2012
2014 (TTI.useColdCCForColdCall(F) &&
2016 ChangeableCCCache.erase(&F);
2020 NumColdCC++;
2021 }
2022 }
2023
2025
2026
2027
2029 if (TTI.useFastCCForInternalCall(F)) {
2032 ++NumFastCallFns;
2034 }
2035 }
2036
2037 if (F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
2038 .hasAddressTaken()) {
2039
2040
2042 ++NumNestRemoved;
2044 }
2045 }
2047}
2048
2049static bool
2056
2058
2061
2062 if (GV.hasInitializer())
2064 auto &DL = M.getDataLayout();
2065
2066
2067
2069 if (New != C)
2070 GV.setInitializer(New);
2071 }
2072
2073 if (deleteIfDead(GV, NotDiscardableComdats)) {
2075 continue;
2076 }
2077
2079 }
2081}
2082
2083
2084
2087
2088 if (F->isDeclaration())
2089 return false;
2090
2095
2096 if (EvalSuccess) {
2097 ++NumCtorsEvaluated;
2098
2099
2101 LLVM_DEBUG(dbgs() << "FULLY EVALUATED GLOBAL CTOR FUNCTION '"
2102 << F->getName() << "' to " << NewInitializers.size()
2103 << " stores.\n");
2104 for (const auto &Pair : NewInitializers)
2105 Pair.first->setInitializer(Pair.second);
2107 GV->setConstant(true);
2108 }
2109
2110 return EvalSuccess;
2111}
2112
2118
2121 if (Init.empty()) {
2122 V.eraseFromParent();
2123 return;
2124 }
2125
2126
2127 const Type *UsedArrayType = V.getValueType();
2129 const auto *VEPT = cast(VAT->getArrayElementType());
2130
2131
2134
2139 }
2140
2141
2144
2145 Module *M = V.getParent();
2146 V.removeFromParent();
2150 NV->takeName(&V);
2151 NV->setSection("llvm.metadata");
2152 delete &V;
2153}
2154
2155namespace {
2156
2157
2158class LLVMUsed {
2159 SmallPtrSet<GlobalValue *, 4> Used;
2160 SmallPtrSet<GlobalValue *, 4> CompilerUsed;
2161 GlobalVariable *UsedV;
2162 GlobalVariable *CompilerUsedV;
2163
2164public:
2165 LLVMUsed(Module &M) {
2172 }
2173
2174 using iterator = SmallPtrSet<GlobalValue *, 4>::iterator;
2175 using used_iterator_range = iterator_range;
2176
2177 iterator usedBegin() { return Used.begin(); }
2178 iterator usedEnd() { return Used.end(); }
2179
2180 used_iterator_range used() {
2181 return used_iterator_range(usedBegin(), usedEnd());
2182 }
2183
2184 iterator compilerUsedBegin() { return CompilerUsed.begin(); }
2185 iterator compilerUsedEnd() { return CompilerUsed.end(); }
2186
2187 used_iterator_range compilerUsed() {
2188 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());
2189 }
2190
2191 bool usedCount(GlobalValue *GV) const { return Used.count(GV); }
2192
2193 bool compilerUsedCount(GlobalValue *GV) const {
2194 return CompilerUsed.count(GV);
2195 }
2196
2197 bool usedErase(GlobalValue *GV) { return Used.erase(GV); }
2198 bool compilerUsedErase(GlobalValue *GV) { return CompilerUsed.erase(GV); }
2199 bool usedInsert(GlobalValue *GV) { return Used.insert(GV).second; }
2200
2201 bool compilerUsedInsert(GlobalValue *GV) {
2202 return CompilerUsed.insert(GV).second;
2203 }
2204
2205 void syncVariablesAndSets() {
2206 if (UsedV)
2208 if (CompilerUsedV)
2210 }
2211};
2212
2213}
2214
2216 if (GA.use_empty())
2217 return false;
2218
2219 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&
2220 "We should have removed the duplicated "
2221 "element from llvm.compiler.used");
2223
2224
2225 return true;
2226
2227
2228 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
2229}
2230
2233 return true;
2234
2235 return U.usedCount(&GV) || U.compilerUsedCount(&GV);
2236}
2237
2239 bool &RenameTarget) {
2241 return false;
2242
2243 RenameTarget = false;
2244 bool Ret = false;
2246 Ret = true;
2247
2248
2250 return Ret;
2251
2252
2253
2254
2255
2256
2257
2258
2262 return Ret;
2263
2264 RenameTarget = true;
2265 return true;
2266}
2267
2268static bool
2272 LLVMUsed Used(M);
2273
2275 Used.compilerUsedErase(GV);
2276
2277
2278
2279 auto IsModuleLocal = [](GlobalValue &GV) {
2282 };
2283
2285
2286 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
2288
2289 if (deleteIfDead(J, NotDiscardableComdats)) {
2291 continue;
2292 }
2293
2294
2295 if (!IsModuleLocal(J))
2296 continue;
2297
2298 Constant *Aliasee = J.getAliasee();
2300
2301
2302
2303
2304
2305
2307 continue;
2308
2309 Target->removeDeadConstantUsers();
2310
2311
2312 bool RenameTarget;
2314 continue;
2315
2316 J.replaceAllUsesWith(Aliasee);
2317 ++NumAliasesResolved;
2319
2320 if (RenameTarget) {
2321
2322 Target->takeName(&J);
2323 Target->setLinkage(J.getLinkage());
2324 Target->setDSOLocal(J.isDSOLocal());
2325 Target->setVisibility(J.getVisibility());
2326 Target->setDLLStorageClass(J.getDLLStorageClass());
2327
2328 if (Used.usedErase(&J))
2329 Used.usedInsert(Target);
2330
2331 if (Used.compilerUsedErase(&J))
2332 Used.compilerUsedInsert(Target);
2334 continue;
2335
2336
2337 M.eraseAlias(&J);
2338 ++NumAliasesRemoved;
2340 }
2341
2342 Used.syncVariablesAndSets();
2343
2345}
2346
2350 LibFunc Func) {
2351
2352 auto FuncIter = M.begin();
2353 if (FuncIter == M.end())
2354 return nullptr;
2355 auto *TLI = &GetTLI(*FuncIter);
2356
2357 if (!TLI->has(Func))
2358 return nullptr;
2359
2361 if (!Fn)
2362 return nullptr;
2363
2364
2365 TLI = &GetTLI(*Fn);
2366
2367
2368 LibFunc F;
2369 if (!TLI->getLibFunc(*Fn, F) || F != Func)
2370 return nullptr;
2371
2372 return Fn;
2373}
2374
2375
2376
2377
2378
2380
2381
2383 return false;
2384
2386 if (I.isDebugOrPseudoInst())
2387 continue;
2389 return true;
2390 break;
2391 }
2392 return false;
2393}
2394
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2411
2413
2414
2415
2417 if (!CI)
2418 continue;
2419
2423 continue;
2424
2425
2428
2429 if (isCXX)
2430 ++NumCXXDtorsRemoved;
2431 else
2432 ++NumAtExitRemoved;
2433
2435 }
2436
2438}
2439
2442 return nullptr;
2443
2446 return nullptr;
2447
2448 if (Resolver->isInterposable())
2449 return nullptr;
2450
2451
2452 auto It = Resolver->begin();
2453 if (++It != Resolver->end())
2454 return nullptr;
2455
2457
2459 return nullptr;
2460
2462 if (!Ret)
2463 return nullptr;
2464
2466}
2467
2468
2469
2474 if (!IF.use_empty() &&
2475 (!Callee->isDeclaration() ||
2476 none_of(IF.users(), [](User *U) { return isa(U); }))) {
2477 IF.replaceAllUsesWith(Callee);
2478 NumIFuncsResolved++;
2480 }
2482}
2483
2484static bool
2489 if (deleteIfDead(IF, NotDiscardableComdats)) {
2490 NumIFuncsDeleted++;
2492 }
2494}
2495
2496
2497
2498
2499static bool
2503 if (!GetTTI(*F).isMultiversionedFunction(*F))
2504 return false;
2507 if ((Sel->getTrueValue(), Versions, GetTTI))
2508 return false;
2509 if ((Sel->getFalseValue(), Versions, GetTTI))
2510 return false;
2512 for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I)
2513 if ((Phi->getIncomingValue(I), Versions, GetTTI))
2514 return false;
2515 } else {
2516
2517 return false;
2518 }
2519 return true;
2520}
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2546
2547
2549
2551
2553
2555
2557 LLVM_DEBUG(dbgs() << "Examining IFUNC " << IF.getName() << "\n");
2558
2559 if (IF.isInterposable())
2560 continue;
2561
2564 continue;
2565
2566 if (Resolver->isInterposable())
2567 continue;
2568
2570
2573 if ((Ret->getReturnValue(), Versions, GetTTI))
2574 return true;
2575 return false;
2576 }))
2577 continue;
2578
2579 if (Versions.empty())
2580 continue;
2581
2582 for (Function *V : Versions) {
2583 VersionOf.insert({V, &IF});
2584 auto [It, Inserted] = FeatureMask.try_emplace(V);
2585 if (Inserted)
2586 It->second = GetTTI(*V).getFeatureMask(*V);
2587 }
2588
2589
2590 sort(Versions, [&](auto *LHS, auto *RHS) {
2591 return FeatureMask[LHS].ugt(FeatureMask[RHS]);
2592 });
2593
2595 VersionedFuncs.try_emplace(&IF, std::move(Versions));
2596 }
2597
2602
2603
2604 for (User *U : CalleeIF->users()) {
2606 if (CB->getCalledOperand() == CalleeIF) {
2607 Function *Caller = CB->getFunction();
2610 bool CallerIsFMV = TTI.isMultiversionedFunction(*Caller);
2611
2612 if (auto It = VersionOf.find(Caller); It != VersionOf.end())
2613 CallerIF = It->second;
2615
2616 auto [It, Inserted] = FeatureMask.try_emplace(Caller);
2617 if (Inserted)
2618 It->second = TTI.getFeatureMask(*Caller);
2619 } else
2620
2621 continue;
2622 auto [It, Inserted] = CallSites.try_emplace(Caller);
2623 if (Inserted) {
2624 if (CallerIsFMV)
2625 CallerIFuncs.insert(CallerIF);
2626 else
2627 NonFMVCallers.push_back(Caller);
2628 }
2629 It->second.push_back(CB);
2630 }
2631 }
2632 }
2633
2634 if (CallSites.empty())
2635 continue;
2636
2637 LLVM_DEBUG(dbgs() << "Statically resolving calls to function "
2638 << CalleeIF->getResolverFunction()->getName() << "\n");
2639
2640
2641
2642
2645 bool CallerIsFMV) {
2646 bool AllowExpensiveChecks = CallerIsFMV &&
2649
2650 unsigned J = 0;
2651
2652 for (unsigned I = 0, E = Callers.size(); I < E; ++I) {
2653
2654 if (J == Callees.size())
2655 break;
2656
2658 APInt CallerBits = FeatureMask[Caller];
2659
2660
2661
2662
2663
2664
2665 auto eliminateAvailableFeatures = [&](unsigned BestCandidate) {
2666 unsigned K = 0;
2667 while (K < I && BestCandidate < Callees.size()) {
2668 APInt MissingBits = FeatureMask[Callers[K]] & ~CallerBits;
2669 if (MissingBits.isSubsetOf(FeatureMask[Callees[BestCandidate]])) {
2670 ++BestCandidate;
2671
2672 K = 0;
2673 } else
2674 ++K;
2675 }
2676 return BestCandidate;
2677 };
2678
2679 unsigned BestCandidate =
2680 AllowExpensiveChecks ? eliminateAvailableFeatures(J) : J;
2681
2682 if (BestCandidate == Callees.size())
2683 continue;
2684
2686 << (CallerIsFMV ? "FMV" : "regular") << " caller "
2687 << Caller->getName() << "\n");
2688
2689 Function *Callee = Callees[BestCandidate];
2690 APInt CalleeBits = FeatureMask[Callee];
2691
2692
2693
2694
2695 if (CalleeBits.isSubsetOf(CallerBits)) {
2696
2697 if (auto It = CallSites.find(Caller); It != CallSites.end()) {
2698 for (CallBase *CS : It->second) {
2699 LLVM_DEBUG(dbgs() << " Redirecting call " << Caller->getName()
2700 << " -> " << Callee->getName() << "\n");
2702 }
2704 }
2705 }
2706
2707
2708 if (!CallerIsFMV)
2709 continue;
2710
2711
2712
2713
2714
2715 while (CallerBits.isSubsetOf(FeatureMask[Callees[J]]) &&
2716 ++J < Callees.size())
2717 ;
2718 }
2719 };
2720
2721 auto &Callees = VersionedFuncs[CalleeIF];
2722
2723
2725 staticallyResolveCalls(NonFMVCallers, Callees, false);
2726
2727
2728 for (GlobalIFunc *CallerIF : CallerIFuncs) {
2729 auto &Callers = VersionedFuncs[CallerIF];
2730 staticallyResolveCalls(Callers, Callees, true);
2731 }
2732
2733 if (CalleeIF->use_empty() ||
2734 all_of(CalleeIF->users(), [](User *U) { return isa(U); }))
2735 NumIFuncsResolved++;
2736 }
2738}
2739
2740static bool
2750 bool LocalChange = true;
2751 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;
2752
2753 while (LocalChange) {
2754 LocalChange = false;
2755
2756 NotDiscardableComdats.clear();
2760 NotDiscardableComdats.insert(C);
2762 if (const Comdat *C = F.getComdat())
2763 if (.isDefTriviallyDead())
2764 NotDiscardableComdats.insert(C);
2766 if (const Comdat *C = GA.getComdat())
2767 if (!GA.isDiscardableIfUnused() || !GA.use_empty())
2768 NotDiscardableComdats.insert(C);
2769
2770
2771 LocalChange |= OptimizeFunctions(M, GetTLI, GetTTI, GetBFI, LookupDomTree,
2772 NotDiscardableComdats, ChangedCFGCallback,
2773 DeleteFnCallback);
2774
2775
2776 LocalChange |=
2778 if (FirstNotFullyEvaluatedPriority &&
2779 *FirstNotFullyEvaluatedPriority != Priority)
2780 return false;
2782 if (!Evaluated)
2783 FirstNotFullyEvaluatedPriority = Priority;
2784 return Evaluated;
2785 });
2786
2787
2789 NotDiscardableComdats);
2790
2791
2793
2794
2795
2799
2802
2803
2805
2806
2808
2809
2811
2813 }
2814
2815
2816
2817
2819}
2820
2822 auto &DL = M.getDataLayout();
2823 auto &FAM =
2827 };
2830 };
2833 };
2834
2837 };
2838 auto ChangedCFGCallback = [&FAM](Function &F) {
2840 };
2841 auto DeleteFnCallback = [&FAM](Function &F) { FAM.clear(F, F.getName()); };
2842
2844 ChangedCFGCallback, DeleteFnCallback))
2846
2848
2850
2851
2852
2854 return PA;
2855}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static bool IsSafeComputationToRemove(Value *V, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
Given a value that is stored to a global but never read, determine whether it's safe to remove the st...
Definition GlobalOpt.cpp:172
static Function * FindAtExitLibFunc(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI, LibFunc Func)
Definition GlobalOpt.cpp:2348
static bool optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
Definition GlobalOpt.cpp:1138
static Function * hasSideeffectFreeStaticResolution(GlobalIFunc &IF)
Definition GlobalOpt.cpp:2440
static bool tryToOptimizeStoreOfAllocationToGlobal(GlobalVariable *GV, CallInst *CI, const DataLayout &DL, TargetLibraryInfo *TLI)
If we have a global that is only initialized with a fixed size allocation try to transform the progra...
Definition GlobalOpt.cpp:1091
static void ConstantPropUsersOf(Value *V, const DataLayout &DL, TargetLibraryInfo *TLI)
Walk the use list of V, constant folding all of the instructions that are foldable.
Definition GlobalOpt.cpp:906
static bool OptimizeStaticIFuncs(Module &M)
Find IFuncs that have resolvers that always point at the same statically known callee,...
Definition GlobalOpt.cpp:2470
static bool hasOnlyColdCalls(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, ChangeableCCCacheTy &ChangeableCCCache)
Definition GlobalOpt.cpp:1800
static bool allUsesOfLoadedValueWillTrapIfNull(const GlobalVariable *GV)
Return true if all uses of any loads from GV will trap if the loaded value is null.
Definition GlobalOpt.cpp:718
static bool hasChangeableCCImpl(Function *F)
Return true if this is a calling convention that we'd like to change.
Definition GlobalOpt.cpp:1713
static bool AllUsesOfValueWillTrapIfNull(const Value *V, SmallPtrSetImpl< const PHINode * > &PHIs)
Return true if all users of the specified value will trap if the value is dynamically null.
Definition GlobalOpt.cpp:664
static GlobalVariable * OptimizeGlobalAddressOfAllocation(GlobalVariable *GV, CallInst *CI, uint64_t AllocSize, Constant *InitVal, const DataLayout &DL, TargetLibraryInfo *TLI)
This function takes the specified global variable, and transforms the program as if it always contain...
Definition GlobalOpt.cpp:928
static bool collectVersions(Value *V, SmallVectorImpl< Function * > &Versions, function_ref< TargetTransformInfo &(Function &)> GetTTI)
Definition GlobalOpt.cpp:2500
static bool IsEmptyAtExitFunction(const Function &Fn)
Returns whether the given function is an empty C++ destructor or atexit handler and can therefore be ...
Definition GlobalOpt.cpp:2379
static bool collectSRATypes(DenseMap< uint64_t, GlobalPart > &Parts, GlobalVariable *GV, const DataLayout &DL)
Look at all uses of the global and determine which (offset, type) pairs it can be split into.
Definition GlobalOpt.cpp:360
static bool valueIsOnlyUsedLocallyOrStoredToOneGlobal(const CallInst *CI, const GlobalVariable *GV)
Scan the use-list of GV checking to make sure that there are no complex uses of GV.
Definition GlobalOpt.cpp:1052
static bool OptimizeFunctions(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, function_ref< DominatorTree &(Function &)> LookupDomTree, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats, function_ref< void(Function &F)> ChangedCFGCallback, function_ref< void(Function &F)> DeleteFnCallback)
Definition GlobalOpt.cpp:1930
static bool DeleteDeadIFuncs(Module &M, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
Definition GlobalOpt.cpp:2485
static void RemoveAttribute(Function *F, Attribute::AttrKind A)
Definition GlobalOpt.cpp:1701
static bool hasChangeableCC(Function *F, ChangeableCCCacheTy &ChangeableCCCache)
Definition GlobalOpt.cpp:1744
static bool deleteIfDead(GlobalValue &GV, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats, function_ref< void(Function &)> DeleteFnCallback=nullptr)
Definition GlobalOpt.cpp:1331
static void RemovePreallocated(Function *F)
Definition GlobalOpt.cpp:1848
static cl::opt< bool > OptimizeNonFMVCallers("optimize-non-fmv-callers", cl::desc("Statically resolve calls to versioned " "functions from non-versioned callers."), cl::init(true), cl::Hidden)
static bool processGlobal(GlobalValue &GV, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree)
Analyze the specified global variable and optimize it if possible.
Definition GlobalOpt.cpp:1646
static bool isColdCallSite(CallBase &CB, BlockFrequencyInfo &CallerBFI)
Return true if the block containing the call site has a BlockFrequency of less than ColdCCRelFreq% of...
Definition GlobalOpt.cpp:1754
static void transferSRADebugInfo(GlobalVariable *GV, GlobalVariable *NGV, uint64_t FragmentOffsetInBits, uint64_t FragmentSizeInBits, uint64_t VarSize)
Copy over the debug info for a variable to its SRA replacements.
Definition GlobalOpt.cpp:449
static cl::opt< bool > EnableColdCCStressTest("enable-coldcc-stress-test", cl::desc("Enable stress test of coldcc by adding " "calling conv to all internal functions."), cl::init(false), cl::Hidden)
static bool OptimizeGlobalAliases(Module &M, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
Definition GlobalOpt.cpp:2269
static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal)
At this point, we have learned that the only two values ever stored into GV are its initializer and O...
Definition GlobalOpt.cpp:1171
static void ChangeCalleesToFastCall(Function *F)
Walk all of the direct calls of the specified function, changing them to FastCC.
Definition GlobalOpt.cpp:1686
static bool hasMustTailCallers(Function *F)
Definition GlobalOpt.cpp:1832
static bool OptimizeNonTrivialIFuncs(Module &M, function_ref< TargetTransformInfo &(Function &)> GetTTI)
Definition GlobalOpt.cpp:2543
static bool OptimizeGlobalVars(Module &M, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
Definition GlobalOpt.cpp:2050
static void allUsesOfLoadAndStores(GlobalVariable *GV, SmallVector< Value *, 4 > &Uses)
Get all the loads/store uses for global variable GV.
Definition GlobalOpt.cpp:752
static bool OptimizeEmptyGlobalAtExitDtors(Function *CXAAtExitFn, bool isCXX)
Definition GlobalOpt.cpp:2395
static bool mayHaveOtherReferences(GlobalValue &GV, const LLVMUsed &U)
Definition GlobalOpt.cpp:2231
static void changeCallSitesToColdCC(Function *F)
Definition GlobalOpt.cpp:1789
static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs, Attribute::AttrKind A)
Definition GlobalOpt.cpp:1693
static bool hasInvokeCallers(Function *F)
Definition GlobalOpt.cpp:1841
static void setUsedInitializer(GlobalVariable &V, const SmallPtrSetImpl< GlobalValue * > &Init)
Definition GlobalOpt.cpp:2119
static cl::opt< unsigned > MaxIFuncVersions("max-ifunc-versions", cl::Hidden, cl::init(5), cl::desc("Maximum number of caller/callee versions that is allowed for " "using the expensive (cubic) static resolution algorithm."))
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
The specified global has only one non-null value stored into it.
Definition GlobalOpt.cpp:841
static bool isValidCandidateForColdCC(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, const std::vector< Function * > &AllCallsCold)
Definition GlobalOpt.cpp:1768
static cl::opt< int > ColdCCRelFreq("coldcc-rel-freq", cl::Hidden, cl::init(2), cl::desc("Maximum block frequency, expressed as a percentage of caller's " "entry frequency, for a call site to be considered cold for enabling " "coldcc"))
static bool optimizeGlobalsInModule(Module &M, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, function_ref< DominatorTree &(Function &)> LookupDomTree, function_ref< void(Function &F)> ChangedCFGCallback, function_ref< void(Function &F)> DeleteFnCallback)
Definition GlobalOpt.cpp:2741
static bool EvaluateStaticConstructor(Function *F, const DataLayout &DL, TargetLibraryInfo *TLI)
Evaluate static constructors in the function, if we can.
Definition GlobalOpt.cpp:2085
static bool CleanupConstantGlobalUsers(GlobalVariable *GV, const DataLayout &DL)
We just marked GV constant.
Definition GlobalOpt.cpp:281
SmallDenseMap< Function *, bool, 8 > ChangeableCCCacheTy
Definition GlobalOpt.cpp:1743
static bool isLeakCheckerRoot(GlobalVariable *GV)
Is this global variable possibly used by a leak checker as a root?
Definition GlobalOpt.cpp:122
static bool forwardStoredOnceStore(GlobalVariable *GV, const StoreInst *StoredOnceStore, function_ref< DominatorTree &(Function &)> LookupDomTree)
Definition GlobalOpt.cpp:1431
static int compareNames(Constant *const *A, Constant *const *B)
Definition GlobalOpt.cpp:2113
static bool CleanupPointerRootUsers(GlobalVariable *GV, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
This GV is a pointer root.
Definition GlobalOpt.cpp:203
static bool isPointerValueDeadOnEntryToFunction(const Function *F, GlobalValue *GV, function_ref< DominatorTree &(Function &)> LookupDomTree)
Definition GlobalOpt.cpp:1362
static bool processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree)
Analyze the specified global variable and optimize it if possible.
Definition GlobalOpt.cpp:1467
static bool hasUsesToReplace(GlobalAlias &GA, const LLVMUsed &U, bool &RenameTarget)
Definition GlobalOpt.cpp:2238
static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV)
Definition GlobalOpt.cpp:771
static GlobalVariable * SRAGlobal(GlobalVariable *GV, const DataLayout &DL)
Perform scalar replacement of aggregates on the specified global variable.
Definition GlobalOpt.cpp:529
static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U)
Definition GlobalOpt.cpp:2215
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
Remove Loads Into Fake Uses
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This pass exposes codegen information to IR-level passes.
Class for arbitrary precision integers.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
static LLVM_ABI CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, InsertPosition InsertPt=nullptr)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
void setCalledOperand(Value *V)
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
bool isMustTailCall() const
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static LLVM_ABI Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static LLVM_ABI std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static LLVM_ABI DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
A pair of DIGlobalVariable and DIExpression.
uint64_t getSizeInBits() const
Base class for variables.
A parsed version of the target data layout string in and methods for querying it.
static DebugLoc getCompilerGenerated()
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
DenseMap< GlobalVariable *, Constant * > getMutatedInitializers() const
bool EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl< Constant * > &ActualArgs)
Evaluate a call to function F, returning true if successful, false if we can't evaluate it.
const SmallPtrSetImpl< GlobalVariable * > & getInvariants() const
const BasicBlock & getEntryBlock() const
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
const Constant * getAliasee() const
LLVM_ABI const Function * getResolverFunction() const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition GlobalOpt.cpp:2821
bool isImplicitDSOLocal() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
LLVM_ABI const Comdat * getComdat() const
ThreadLocalMode getThreadLocalMode() const
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
PointerType * getType() const
Global values are always pointers.
LLVM_ABI bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
bool hasGlobalUnnamedAddr() const
UnnamedAddr getUnnamedAddr() const
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
static bool isDiscardableIfUnused(LinkageTypes Linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AppendingLinkage
Special purpose, only applies to global arrays.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
bool isExternallyInitialized() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
void setConstant(bool Val)
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
LLVM_ABI void getDebugInfo(SmallVectorImpl< DIGlobalVariableExpression * > &GVs) const
Fill the vector with all debug info attachements.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
LLVM_ABI void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVMContext & getContext() const
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
void insertGlobalVariable(GlobalVariable *GV)
Insert global variable GV at the end of the global variable list and take ownership.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Value * getValueOperand()
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
Class to represent struct types.
ArrayRef< Type * > elements() const
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FixedVectorTyID
Fixed width SIMD vector type.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM_ABI void set(Value *Val)
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
This class represents zero extension of integer types.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ X86_ThisCall
Similar to X86_StdCall.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI Constant * ConstantFoldInstruction(const Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
LLVM_ABI Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty, const DataLayout &DL)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
LLVM_ABI Align getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to ensure that the alignment of V is at least PrefAlign bytes.
bool optimizeGlobalCtorsList(Module &M, function_ref< bool(uint32_t, Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it retur...
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isPointerTy(const Type *T)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...
Part of the global at a specific offset, which is only accessed through loads and stores with the giv...
Definition GlobalOpt.cpp:351
bool IsStored
Definition GlobalOpt.cpp:355
Constant * Initializer
Definition GlobalOpt.cpp:353
bool IsLoaded
Definition GlobalOpt.cpp:354
Type * Ty
Definition GlobalOpt.cpp:352
This struct is a compact representation of a valid (non-zero power of two) alignment.
As we analyze each global or thread-local variable, keep track of some information about it.
@ InitializerStored
This global is stored to, but the only thing stored is the constant it was initialized with.
@ StoredOnce
This global is stored to, but only its initializer and one other value is ever stored to it.
static bool analyzeGlobal(const Value *V, GlobalStatus &GS)
Look at all uses of the global and fill in the GlobalStatus structure.
Various options to control the behavior of getObjectSize.
Function object to check whether the first component of a container supported by std::get (like std::...