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 (GEP->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();

320 DL, Offset, true);

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 (SI)

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 (SI->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 (I)

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 F->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 (F.hasName() && F.isDeclaration() && F.hasLocalLinkage())

1957

1958 if (deleteIfDead(F, NotDiscardableComdats, DeleteFnCallback)) {

1960 continue;

1961 }

1962

1963

1964

1965

1966

1967

1968

1969

1970

1971

1972 if (F.isDeclaration()) {

1975 ChangedCFGCallback(F);

1976 }

1977 }

1978

1980

1981 if (F.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 F.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 (collectVersions(Sel->getTrueValue(), Versions, GetTTI))

2508 return false;

2509 if (collectVersions(Sel->getFalseValue(), Versions, GetTTI))

2510 return false;

2512 for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I)

2513 if (collectVersions(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 (collectVersions(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 (F.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::...