LLVM: lib/Transforms/IPO/GlobalOpt.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

67#include

68#include

69#include

70#include

71#include

72

73using namespace llvm;

74

75#define DEBUG_TYPE "globalopt"

76

77STATISTIC(NumMarked , "Number of globals marked constant");

78STATISTIC(NumUnnamed , "Number of globals marked unnamed_addr");

79STATISTIC(NumSRA , "Number of aggregate globals broken into scalars");

80STATISTIC(NumSubstitute,"Number of globals with initializers stored into them");

81STATISTIC(NumDeleted , "Number of globals deleted");

82STATISTIC(NumGlobUses , "Number of global uses devirtualized");

83STATISTIC(NumLocalized , "Number of globals localized");

84STATISTIC(NumShrunkToBool , "Number of global vars shrunk to booleans");

85STATISTIC(NumFastCallFns , "Number of functions converted to fastcc");

86STATISTIC(NumCtorsEvaluated, "Number of static ctors evaluated");

87STATISTIC(NumNestRemoved , "Number of nest attributes removed");

88STATISTIC(NumAliasesResolved, "Number of global aliases resolved");

89STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated");

90STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed");

91STATISTIC(NumAtExitRemoved, "Number of atexit handlers removed");

92STATISTIC(NumInternalFunc, "Number of internal functions");

93STATISTIC(NumColdCC, "Number of functions marked coldcc");

94STATISTIC(NumIFuncsResolved, "Number of statically resolved IFuncs");

95STATISTIC(NumIFuncsDeleted, "Number of IFuncs removed");

96

99 cl::desc("Statically resolve calls to versioned "

100 "functions from non-versioned callers."),

102

105 cl::desc("Maximum number of caller/callee versions that is allowed for "

106 "using the expensive (cubic) static resolution algorithm."));

107

110 cl::desc("Enable stress test of coldcc by adding "

111 "calling conv to all internal functions."),

113

117 "Maximum block frequency, expressed as a percentage of caller's "

118 "entry frequency, for a call site to be considered cold for enabling "

119 "coldcc"));

120

121

122

124

125

126

127

128

129

130

131

133 return false;

134

137

138 unsigned Limit = 20;

139 do {

140 Type *Ty = Types.pop_back_val();

141 switch (Ty->getTypeID()) {

142 default: break;

144 return true;

148 return true;

149 break;

152 break;

155 if (STy->isOpaque()) return true;

160 Types.push_back(InnerTy);

161 }

162 break;

163 }

164 }

165 if (--Limit == 0) return true;

166 } while (!Types.empty());

167 return false;

168}

169

170

171

172

175 do {

177 return true;

178 if (!V->hasOneUse())

179 return false;

182 return false;

184 return true;

185

187 if (I->mayHaveSideEffects())

188 return false;

190 if (GEP->hasAllConstantIndices())

191 return false;

192 } else if (I->getNumOperands() != 1) {

193 return false;

194 }

195

196 V = I->getOperand(0);

197 } while (true);

198}

199

200

201

202

203static bool

206

207

208

209

210

211

212

213

214

216

217

218

220

222

223 while (!Worklist.empty()) {

226 Value *V = SI->getValueOperand();

229 SI->eraseFromParent();

231 if (I->hasOneUse())

232 Dead.push_back(std::make_pair(I, SI));

233 }

237 MSI->eraseFromParent();

239 if (I->hasOneUse())

240 Dead.push_back(std::make_pair(I, MSI));

241 }

244 if (MemSrc && MemSrc->isConstant()) {

246 MTI->eraseFromParent();

248 if (I->hasOneUse())

249 Dead.push_back(std::make_pair(I, MTI));

250 }

254 }

255 }

256

257 for (const auto &[Inst, Store] : Dead) {

259 Store->eraseFromParent();

261 do {

263 break;

265 if (!J)

266 break;

267 I->eraseFromParent();

268 I = J;

269 } while (true);

270 I->eraseFromParent();

272 }

273 }

274

277}

278

279

280

281

288

291 for (Value *Op : I->operands())

294 I->eraseFromParent();

296 };

297 while (!WorkList.empty()) {

299 if (!Visited.insert(U).second)

300 continue;

301

309

310

311 Type *Ty = LI->getType();

313 LI->replaceAllUsesWith(Res);

314 EraseFromParent(LI);

315 continue;

316 }

317

318 Value *PtrOp = LI->getPointerOperand();

321 DL, Offset, true);

323 if (II->getIntrinsicID() == Intrinsic::threadlocal_address)

324 PtrOp = II->getArgOperand(0);

325 }

326 if (PtrOp == GV) {

328 LI->replaceAllUsesWith(Value);

329 EraseFromParent(LI);

330 }

331 }

333

334 EraseFromParent(SI);

337 EraseFromParent(MI);

339 if (II->getIntrinsicID() == Intrinsic::threadlocal_address)

341 }

342 }

343

348}

349

350

351

358

359

360

365 auto AppendUses = [&](Value *V) {

367 if (Visited.insert(&U).second)

369 };

370 AppendUses(GV);

371 while (!Worklist.empty()) {

373 User *V = U->getUser();

374

377 (GEP && GEP->hasAllConstantIndices())) {

378 AppendUses(V);

379 continue;

380 }

381

383

384

386 return false;

387

388 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);

389 Ptr = Ptr->stripAndAccumulateConstantOffsets(DL, Offset,

390 true);

391 if (Ptr != GV || Offset.getActiveBits() >= 64)

392 return false;

393

394

395

397 const auto &[It, Inserted] =

399 if (Ty != It->second.Ty)

400 return false;

401

402 if (Inserted) {

403 It->second.Initializer =

405 if (!It->second.Initializer) {

406 LLVM_DEBUG(dbgs() << "Global SRA: Failed to evaluate initializer of "

407 << *GV << " with type " << *Ty << " at offset "

408 << Offset.getZExtValue());

409 return false;

410 }

411 }

412

413

414 if (Ty->isScalableTy())

415 return false;

416

417 auto IsStored = [](Value *V, Constant *Initializer) {

419 if (SI)

420 return false;

421

423 if (!StoredConst)

424 return true;

425

426

427 return Initializer != StoredConst;

428 };

429

431 It->second.IsStored |= IsStored(V, It->second.Initializer);

432 continue;

433 }

434

435

438 return false;

439 continue;

440 }

441

442

443 return false;

444 }

445

446 return true;

447}

448

449

451 uint64_t FragmentOffsetInBits,

456 for (auto *GVE : GVs) {

457 DIVariable *Var = GVE->getVariable();

459 int64_t CurVarOffsetInBytes = 0;

460 uint64_t CurVarOffsetInBits = 0;

461 uint64_t FragmentEndInBits = FragmentOffsetInBits + FragmentSizeInBits;

462

463

465 continue;

466

467

468 if (CurVarOffsetInBytes < 0)

469 continue;

470

471

472 CurVarOffsetInBits = CHAR_BIT * (uint64_t)CurVarOffsetInBytes;

473

474

475 if (CurVarOffsetInBits >= FragmentEndInBits)

476 continue;

477

479 uint64_t CurVarEndInBits = CurVarOffsetInBits + CurVarSize;

480

481 if (CurVarSize != 0 &&

482 CurVarEndInBits <= FragmentOffsetInBits)

483 continue;

484

485

486

487 if (CurVarSize != 0 &&

488 CurVarOffsetInBits >= FragmentOffsetInBits &&

489 CurVarEndInBits <= FragmentEndInBits) {

490 uint64_t CurVarOffsetInFragment =

491 (CurVarOffsetInBits - FragmentOffsetInBits) / 8;

492 if (CurVarOffsetInFragment != 0)

494 CurVarOffsetInFragment});

495 else

497 auto *NGVE =

500 continue;

501 }

502

503

504 if (FragmentSizeInBits < VarSize) {

505 if (CurVarOffsetInBits > FragmentOffsetInBits)

506 continue;

507 uint64_t CurVarFragmentOffsetInBits =

508 FragmentOffsetInBits - CurVarOffsetInBits;

509 uint64_t CurVarFragmentSizeInBits = FragmentSizeInBits;

510 if (CurVarSize != 0 && CurVarEndInBits < FragmentEndInBits)

511 CurVarFragmentSizeInBits -= (FragmentEndInBits - CurVarEndInBits);

512 if (CurVarOffsetInBits)

515 Expr, CurVarFragmentOffsetInBits, CurVarFragmentSizeInBits))

516 Expr = *E;

517 else

518 continue;

519 }

522 }

523}

524

525

526

527

528

529

532

533

536 return nullptr;

537

538

540 return nullptr;

541

542

543

544

545 unsigned NumParts = count_if(Parts, [](const auto &Pair) {

546 return Pair.second.IsLoaded && Pair.second.IsStored;

547 });

548 if (NumParts > 16)

549 return nullptr;

550

551

553 for (const auto &Pair : Parts) {

555 {Pair.first, Pair.second.Ty, Pair.second.Initializer});

556 }

558

559

561 for (const auto &[OffsetForTy, Ty, _] : TypesVector) {

562

563 if (OffsetForTy < Offset)

564 return nullptr;

565

566 Offset = OffsetForTy + DL.getTypeAllocSize(Ty);

567 }

568

569

571 return nullptr;

572

573 LLVM_DEBUG(dbgs() << "PERFORMING GLOBAL SRA ON: " << *GV << "\n");

574

575

576 Align StartAlignment =

579

580

582 unsigned NameSuffix = 0;

583 for (auto &[OffsetForTy, Ty, Initializer] : TypesVector) {

586 Initializer, GV->getName() + "." + Twine(NameSuffix++), GV,

588

590 NewGlobals.insert({OffsetForTy, NGV});

591

592

593

594

595

598

599

601 DL.getTypeAllocSizeInBits(Ty), VarSize);

602 }

603

604

608 auto AppendUsers = [&](Value *V) {

610 if (Visited.insert(U).second)

612 };

613 AppendUsers(GV);

614 while (!Worklist.empty()) {

618 AppendUsers(V);

621 continue;

622 }

623

625 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);

626 Ptr = Ptr->stripAndAccumulateConstantOffsets(DL, Offset,

627 true);

628 assert(Ptr == GV && "Load/store must be from/to global");

630 assert(NGV && "Must have replacement global for this offset");

631

632

636

638 LI->setOperand(0, NGV);

639 LI->setAlignment(NewAlign);

640 } else {

642 SI->setOperand(1, NGV);

643 SI->setAlignment(NewAlign);

644 }

645 continue;

646 }

647

649 "Other users can only be dead constants");

650 }

651

652

656 ++NumSRA;

657

659 return NewGlobals.begin()->second;

660}

661

662

663

664

667 for (const User *U : V->users()) {

669

670

672 return false;

673 }

675

677 if (SI->getOperand(0) == V) {

678 return false;

679 }

681 if (CI->getCalledOperand() != V) {

682 return false;

683 }

685 if (II->getCalledOperand() != V) {

686 return false;

687 }

690 return false;

694

695

697 return false;

703 ->getPointerOperand()

704 ->stripPointerCasts()) &&

705 "Should be GlobalVariable");

706

707

708

709 } else {

710 return false;

711 }

712 }

713 return true;

714}

715

716

717

718

722 while (!Worklist.empty()) {

724 for (const auto *U : P->users()) {

726 if (!LI->isSimple())

727 return false;

730 return false;

732 if (SI->isSimple())

733 return false;

734

735 if (SI->getPointerOperand() != P)

736 return false;

738 if (CE->stripPointerCasts() != GV)

739 return false;

740

742 } else {

743

744 return false;

745 }

746 }

747 }

748

749 return true;

750}

751

752

757 while (!Worklist.empty()) {

759 for (auto *U : P->users()) {

762 continue;

763 }

764

766 "Expect only load or store instructions");

767 Uses.push_back(U);

768 }

769 }

770}

771

774 for (auto UI = V->user_begin(), E = V->user_end(); UI != E; ) {

776

777

779 return false;

781 LI->setOperand(0, NewV);

784 if (SI->getOperand(1) == V) {

785 SI->setOperand(1, NewV);

787 }

791

792

795 bool PassedAsArg = false;

796 for (unsigned i = 0, e = CB->arg_size(); i != e; ++i)

798 PassedAsArg = true;

800 }

801

802 if (PassedAsArg) {

803

804 UI = V->user_begin();

805 }

806 }

810 if (CI->use_empty()) {

812 CI->eraseFromParent();

813 }

815

817 Idxs.reserve(GEPI->getNumOperands()-1);

818 for (User::op_iterator i = GEPI->op_begin() + 1, e = GEPI->op_end();

819 i != e; ++i)

822 else

823 break;

824 if (Idxs.size() == GEPI->getNumOperands()-1)

827 NewV, Idxs));

828 if (GEPI->use_empty()) {

830 GEPI->eraseFromParent();

831 }

832 }

833 }

834

836}

837

838

839

840

841

846

847

848

849 bool AllNonStoreUsesGone = true;

850

851

855

856 if (LI->use_empty()) {

857 LI->eraseFromParent();

859 } else {

860 AllNonStoreUsesGone = false;

861 }

863

864 assert(GlobalUser->getOperand(1) == GV &&

865 "Must be storing *to* the global");

866 } else {

867 AllNonStoreUsesGone = false;

868

869

870

876 "Only expect load and stores!");

877 }

878 }

879

881 LLVM_DEBUG(dbgs() << "OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV

882 << "\n");

883 ++NumGlobUses;

884 }

885

886

887

888 if (AllNonStoreUsesGone) {

891 } else {

894 }

899 ++NumDeleted;

900 }

901 }

903}

904

905

906

912 I->replaceAllUsesWith(NewC);

913

914

915

916 while (UI != E && *UI == I)

917 ++UI;

919 I->eraseFromParent();

920 }

921}

922

923

924

925

926

927

933 LLVM_DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI

934 << '\n');

935

936

938 AllocSize);

939

940

941

946

947

948

949

950

951

954

955 Builder.CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);

956 }

957

958

960

961

962

967 bool InitBoolUsed = false;

968

969

972 for (auto *U : Guses) {

974

975

978 SI->getValueOperand())),

979 InitBool, false, Align(1), SI->getOrdering(), SI->getSyncScopeID(),

980 SI->getIterator());

981 NewSI->setDebugLoc(SI->getDebugLoc());

982 SI->eraseFromParent();

983 continue;

984 }

985

990 if (!ICI) {

991 LoadUse.set(NewGV);

992 continue;

993 }

994

995

997 InitBool->getName() + ".val", false, Align(1),

1000

1001

1002

1003

1005 InitBoolUsed = true;

1010 break;

1013 break;

1018 break;

1021 break;

1022 }

1025 }

1027 }

1028

1029

1030 if (!InitBoolUsed) {

1031 while (!InitBool->use_empty())

1033 delete InitBool;

1034 } else

1036

1037

1040

1041

1042

1043

1045

1046 return NewGV;

1047}

1048

1049

1050

1051

1052static bool

1058

1059 while (!Worklist.empty()) {

1061 if (!Visited.insert(V).second)

1062 continue;

1063

1064 for (const Use &VUse : V->uses()) {

1065 const User *U = VUse.getUser();

1067 continue;

1068

1070 if (SI->getValueOperand() == V &&

1071 SI->getPointerOperand()->stripPointerCasts() != GV)

1072 return false;

1073 continue;

1074 }

1075

1078 continue;

1079 }

1080

1081 return false;

1082 }

1083 }

1084

1085 return true;

1086}

1087

1088

1089

1090

1091

1097

1098 return false;

1099

1102 if (!InitVal)

1103

1104 return false;

1105

1108 return false;

1109

1110

1111

1112

1113 if (AllocSize >= 2048)

1114 return false;

1115

1116

1117

1118

1119

1120

1121

1123 return false;

1124

1125

1126

1127

1128

1130 return false;

1131

1133 return true;

1134}

1135

1136

1137

1138static bool

1142

1143

1144

1145

1150 nullptr ,

1153

1155 return true;

1158 auto *TLI = &GetTLI(*CI->getFunction());

1160 return true;

1161 }

1162 }

1163 }

1164

1165 return false;

1166}

1167

1168

1169

1170

1171

1174

1175

1176

1177

1178

1179

1183 return false;

1184

1185

1186

1189 return false;

1191 return false;

1192 }

1193

1194 LLVM_DEBUG(dbgs() << " *** SHRINKING TO BOOL: " << *GV << "\n");

1195

1196

1198 false,

1206

1209 "No reason to shrink to bool!");

1210

1213

1214

1215

1216 bool IsOneZero = false;

1217 bool EmitOneOrZero = true;

1219 if (CI && CI->getValue().getActiveBits() <= 64) {

1220 IsOneZero = InitVal->isNullValue() && CI->isOne();

1221

1223 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {

1224 uint64_t ValInit = CIInit->getZExtValue();

1225 uint64_t ValOther = CI->getZExtValue();

1226 uint64_t ValMinus = ValOther - ValInit;

1227

1228 for(auto *GVe : GVs){

1232 unsigned SizeInOctets =

1233 DL.getTypeAllocSizeInBits(NewGV->getValueType()) / 8;

1234

1235

1236

1237

1238

1239

1240

1241

1242

1244 dwarf::DW_OP_deref_size, SizeInOctets,

1245 dwarf::DW_OP_constu, ValMinus,

1246 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,

1247 dwarf::DW_OP_plus};

1248 bool WithStackValue = true;

1253 }

1254 EmitOneOrZero = false;

1255 }

1256 }

1257

1258 if (EmitOneOrZero) {

1259

1260

1261 for(auto *GV : GVs)

1263 }

1264

1268

1269 bool StoringOther = SI->getOperand(0) == OtherVal;

1270

1271 Value *StoreVal;

1272 if (StoringOther || SI->getOperand(0) == InitVal) {

1274 StoringOther);

1275 } else {

1276

1277

1278

1280

1281

1282

1283

1285 assert(LI->getOperand(0) == GV && "Not a copy!");

1286

1287 StoreVal =

1289 false, Align(1), LI->getOrdering(),

1290 LI->getSyncScopeID(), LI->getIterator());

1291 cast(StoreVal)->setDebugLoc(LI->getDebugLoc());

1292 } else {

1294 "This is not a form that we understand!");

1295 StoreVal = StoredVal->getOperand(0);

1297 }

1298 }

1300 new StoreInst(StoreVal, NewGV, false, Align(1), SI->getOrdering(),

1301 SI->getSyncScopeID(), SI->getIterator());

1303 } else {

1304

1310 if (IsOneZero)

1312 else {

1315 }

1317

1318

1322 }

1324 }

1325

1326

1327

1330 return true;

1331}

1332

1333static bool

1338

1340 return false;

1341

1344 return false;

1345

1346 bool Dead;

1348 Dead = (F->isDeclaration() && F->use_empty()) || F->isDefTriviallyDead();

1349 else

1351 if (!Dead)

1352 return false;

1353

1354 LLVM_DEBUG(dbgs() << "GLOBAL DEAD: " << GV << "\n");

1356 if (DeleteFnCallback)

1357 DeleteFnCallback(*F);

1358 }

1361 ++NumDeleted;

1362 return true;

1363}

1364

1368

1369

1370

1371

1372

1373

1374

1375

1376

1377

1381 for (auto *U : GV->users()) {

1383 if (I)

1384 return false;

1385 assert(I->getParent()->getParent() == F);

1386

1391 else

1392 return false;

1393 }

1394

1395

1396

1397

1398

1399 auto &DT = LookupDomTree(*const_cast<Function *>(F));

1400

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410 const unsigned Threshold = 100;

1411 if (Loads.size() * Stores.size() > Threshold)

1412 return false;

1413

1414 for (auto *L : Loads) {

1415 auto *LTy = L->getType();

1418

1419

1420

1421 return DT.dominates(S, L) &&

1422 DL.getTypeStoreSize(LTy).getFixedValue() <=

1423 DL.getTypeStoreSize(STy).getFixedValue();

1424 }))

1425 return false;

1426 }

1427

1428 return true;

1429}

1430

1431

1432

1433

1438

1439

1440

1442 return false;

1447 if (LI->getFunction() == F &&

1448 LI->getType() == StoredOnceValue->getType() && LI->isSimple())

1450 }

1451 }

1452

1453 bool MadeChange = false;

1454 if (!Loads.empty()) {

1455 auto &DT = LookupDomTree(*const_cast<Function *>(F));

1456 for (auto *LI : Loads) {

1457 if (DT.dominates(StoredOnceStore, LI)) {

1458 LI->replaceAllUsesWith(const_cast<Value *>(StoredOnceValue));

1459 LI->eraseFromParent();

1460 MadeChange = true;

1461 }

1462 }

1463 }

1464 return MadeChange;

1465}

1466

1467

1468

1469static bool

1475

1476

1477

1478

1479

1480

1481

1482

1483 if (!GS.HasMultipleAccessingFunctions &&

1484 GS.AccessingFunction &&

1488 GS.AccessingFunction->doesNotRecurse() &&

1490 LookupDomTree)) {

1492

1493 LLVM_DEBUG(dbgs() << "LOCALIZING GLOBAL: " << *GV << "\n");

1495 GS.AccessingFunction->getEntryBlock().begin().getNonConst();

1497

1499 nullptr, GV->getName(), FirstI);

1503

1504

1505

1507 }

1508

1511 ++NumLocalized;

1512 return true;

1513 }

1514

1516

1517

1518

1519 if (!GS.IsLoaded) {

1520 LLVM_DEBUG(dbgs() << "GLOBAL NEVER LOADED: " << *GV << "\n");

1521

1523

1525 } else {

1526

1527

1529 }

1530

1531

1534 ++NumDeleted;

1536 }

1538

1539 }

1541 LLVM_DEBUG(dbgs() << "MARKING CONSTANT: " << *GV << "\n");

1542

1543

1544

1545

1547 assert(!GV->isConstant() && "Expected a non-constant global");

1550 }

1551

1552

1554

1555

1557 LLVM_DEBUG(dbgs() << " *** Marking constant allowed us to simplify "

1558 << "all users and delete global!\n");

1560 ++NumDeleted;

1561 return true;

1562 }

1563

1564

1565 ++NumMarked;

1566 }

1570 return true;

1571 }

1572 Value *StoredOnceValue = GS.getStoredOnceValue();

1575 const_cast<Function &>(*GS.StoredOnceStore->getFunction());

1576 bool CanHaveNonUndefGlobalInitializer =

1577 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(

1579

1580

1581

1582

1583

1584

1585

1588 DL.getTypeAllocSize(SOVConstant->getType()) ==

1590 CanHaveNonUndefGlobalInitializer) {

1591 if (SOVConstant->getType() == GV->getValueType()) {

1592

1594 } else {

1595

1600 NGV->takeName(GV);

1601 NGV->copyAttributesFrom(GV);

1604 GV = NGV;

1605 }

1606

1607

1609

1611 LLVM_DEBUG(dbgs() << " *** Substituting initializer allowed us to "

1612 << "simplify all users and delete global!\n");

1614 ++NumDeleted;

1615 }

1616 ++NumSubstitute;

1617 return true;

1618 }

1619

1620

1621

1623 return true;

1624

1625

1626

1627 if (GS.NumStores == 1)

1629 return true;

1630

1631

1632

1635 CanHaveNonUndefGlobalInitializer)) {

1637 ++NumShrunkToBool;

1638 return true;

1639 }

1640 }

1641 }

1642

1644}

1645

1646

1647

1648static bool

1654 return false;

1655

1657

1659 return false;

1660

1667 NumUnnamed++;

1669 }

1670 }

1671

1672

1675

1677 if (!GVar)

1679

1680 if (GVar->isConstant() || !GVar->hasInitializer())

1682

1685}

1686

1687

1688

1690 for (User *U : F->users())

1692 if (Call->getCalledOperand() == F)

1694}

1695

1698 unsigned AttrIndex;

1699 if (Attrs.hasAttrSomewhere(A, &AttrIndex))

1700 return Attrs.removeAttributeAtIndex(C, AttrIndex, A);

1701 return Attrs;

1702}

1703

1705 F->setAttributes(StripAttr(F->getContext(), F->getAttributes(), A));

1706 for (User *U : F->users()) {

1709 }

1710}

1711

1712

1713

1714

1715

1718

1719

1721 return false;

1722

1723 if (F->isVarArg())

1724 return false;

1725

1726

1727

1728

1729

1730 for (User *U : F->users()) {

1732 if (!CI)

1733 continue;

1734

1736 return false;

1737 }

1738

1740 if (BB.getTerminatingMustTailCall())

1741 return false;

1742

1743 return F->hasAddressTaken();

1744}

1745

1749 auto Res = ChangeableCCCache.try_emplace(F, false);

1750 if (Res.second)

1752 return Res.first->second;

1753}

1754

1755

1756

1759 auto *CallSiteBB = CB.getParent();

1760 auto CallSiteFreq = CallerBFI.getBlockFreq(CallSiteBB);

1761 auto CallerEntryFreq =

1763 return CallSiteFreq < CallerEntryFreq * ColdProb;

1764}

1765

1766

1767

1768

1769

1770static bool

1773 const std::vector<Function *> &AllCallsCold) {

1774

1775 if (F.user_empty())

1776 return false;

1777

1778 for (User *U : F.users()) {

1781 continue;

1785 return false;

1787 return false;

1788 }

1789 return true;

1790}

1791

1793 for (User *U : F->users())

1795 if (Call->getCalledOperand() == F)

1797}

1798

1799

1800

1801

1802static bool

1809

1810 if (CI->isInlineAsm())

1811 continue;

1812 Function *CalledFn = CI->getCalledFunction();

1813 if (!CalledFn)

1814 return false;

1815

1816

1817

1818

1820 continue;

1822 return false;

1823

1825 return false;

1828 return false;

1829 }

1830 }

1831 }

1832 return true;

1833}

1834

1836 for (User *U : F->users()) {

1839 return true;

1840 }

1841 return false;

1842}

1843

1845 for (User *U : F->users())

1847 return true;

1848 return false;

1849}

1850

1853

1854 auto *M = F->getParent();

1855

1857

1858

1860 for (User *U : PreallocatedCalls) {

1862 if (!CB)

1863 continue;

1864

1867 "Shouldn't call RemotePreallocated() on a musttail preallocated call");

1868

1871 CallBase *PreallocatedSetup = nullptr;

1872 for (auto *It = OpBundles.begin(); It != OpBundles.end(); ++It) {

1873 if (It->getTag() == "preallocated") {

1874 PreallocatedSetup = cast(*It->input_begin());

1875 OpBundles.erase(It);

1876 break;

1877 }

1878 }

1879 assert(PreallocatedSetup && "Did not find preallocated bundle");

1882

1884 "Unknown indirect call type");

1889

1890 Builder.SetInsertPoint(PreallocatedSetup);

1891 auto *StackSave = Builder.CreateStackSave();

1892 Builder.SetInsertPoint(NewCB->getNextNode());

1893 Builder.CreateStackRestore(StackSave);

1894

1895

1896

1897

1898

1899

1900

1901

1904 for (auto *User : PreallocatedArgs) {

1906 assert(UseCall->getCalledFunction()->getIntrinsicID() ==

1907 Intrinsic::call_preallocated_arg &&

1908 "preallocated token use was not a llvm.call.preallocated.arg");

1911 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];

1912 if (!AllocaReplacement) {

1913 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();

1914 auto *ArgType =

1915 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();

1916 auto *InsertBefore = PreallocatedSetup->getNextNode();

1917 Builder.SetInsertPoint(InsertBefore);

1918 auto *Alloca =

1919 Builder.CreateAlloca(ArgType, AddressSpace, nullptr, "paarg");

1920 ArgAllocas[AllocArgIndex] = Alloca;

1921 AllocaReplacement = Alloca;

1922 }

1923

1924 UseCall->replaceAllUsesWith(AllocaReplacement);

1925 UseCall->eraseFromParent();

1926 }

1927

1929 }

1930}

1931

1932static bool

1941

1943

1945 std::vector<Function *> AllCallsCold;

1948 AllCallsCold.push_back(&F);

1949

1950

1952

1953

1954 if (F.hasFnAttribute(Attribute::Naked))

1955 continue;

1956

1957

1958 if (F.hasName() && F.isDeclaration() && F.hasLocalLinkage())

1960

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

1963 continue;

1964 }

1965

1966

1967

1968

1969

1970

1971

1972

1973

1974

1975 if (F.isDeclaration()) {

1978 ChangedCFGCallback(F);

1979 }

1980 }

1981

1983

1984 if (F.hasLocalLinkage())

1985 continue;

1986

1987

1988

1989

1990

1991

1992 if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&

1996 }

1997

1998

1999

2000 if (F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {

2005 }

2006 continue;

2007 }

2008

2010 NumInternalFunc++;

2012

2013

2014

2015

2017 (TTI.useColdCCForColdCall(F) &&

2019 ChangeableCCCache.erase(&F);

2023 NumColdCC++;

2024 }

2025 }

2026

2028

2029

2030

2032 if (TTI.useFastCCForInternalCall(F)) {

2035 ++NumFastCallFns;

2037 }

2038 }

2039

2040 if (F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&

2041 F.hasAddressTaken()) {

2042

2043

2045 ++NumNestRemoved;

2047 }

2048 }

2050}

2051

2052static bool

2059

2061

2064

2065 if (GV.hasInitializer())

2067 auto &DL = M.getDataLayout();

2068

2069

2070

2072 if (New != C)

2073 GV.setInitializer(New);

2074 }

2075

2076 if (deleteIfDead(GV, NotDiscardableComdats)) {

2078 continue;

2079 }

2080

2082 }

2084}

2085

2086

2087

2090

2091 if (F->isDeclaration())

2092 return false;

2093

2098

2099 if (EvalSuccess) {

2100 ++NumCtorsEvaluated;

2101

2102

2104 LLVM_DEBUG(dbgs() << "FULLY EVALUATED GLOBAL CTOR FUNCTION '"

2105 << F->getName() << "' to " << NewInitializers.size()

2106 << " stores.\n");

2107 for (const auto &Pair : NewInitializers)

2108 Pair.first->setInitializer(Pair.second);

2110 GV->setConstant(true);

2111 }

2112

2113 return EvalSuccess;

2114}

2115

2121

2124 if (Init.empty()) {

2125 V.eraseFromParent();

2126 return;

2127 }

2128

2129

2130 const Type *UsedArrayType = V.getValueType();

2132 const auto *VEPT = cast(VAT->getArrayElementType());

2133

2134

2137

2142 }

2143

2144

2147

2148 Module *M = V.getParent();

2149 V.removeFromParent();

2154 NV->takeName(&V);

2155 NV->setSection("llvm.metadata");

2156 delete &V;

2157}

2158

2159namespace {

2160

2161

2162class LLVMUsed {

2163 SmallPtrSet<GlobalValue *, 4> Used;

2164 SmallPtrSet<GlobalValue *, 4> CompilerUsed;

2165 GlobalVariable *UsedV;

2166 GlobalVariable *CompilerUsedV;

2167

2168public:

2169 LLVMUsed(Module &M) {

2176 }

2177

2178 using iterator = SmallPtrSet<GlobalValue *, 4>::iterator;

2179 using used_iterator_range = iterator_range;

2180

2181 iterator usedBegin() { return Used.begin(); }

2182 iterator usedEnd() { return Used.end(); }

2183

2184 used_iterator_range used() {

2185 return used_iterator_range(usedBegin(), usedEnd());

2186 }

2187

2188 iterator compilerUsedBegin() { return CompilerUsed.begin(); }

2189 iterator compilerUsedEnd() { return CompilerUsed.end(); }

2190

2191 used_iterator_range compilerUsed() {

2192 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());

2193 }

2194

2195 bool usedCount(GlobalValue *GV) const { return Used.count(GV); }

2196

2197 bool compilerUsedCount(GlobalValue *GV) const {

2198 return CompilerUsed.count(GV);

2199 }

2200

2201 bool usedErase(GlobalValue *GV) { return Used.erase(GV); }

2202 bool compilerUsedErase(GlobalValue *GV) { return CompilerUsed.erase(GV); }

2203 bool usedInsert(GlobalValue *GV) { return Used.insert(GV).second; }

2204

2205 bool compilerUsedInsert(GlobalValue *GV) {

2206 return CompilerUsed.insert(GV).second;

2207 }

2208

2209 void syncVariablesAndSets() {

2210 if (UsedV)

2212 if (CompilerUsedV)

2214 }

2215};

2216

2217}

2218

2220 if (GA.use_empty())

2221 return false;

2222

2223 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&

2224 "We should have removed the duplicated "

2225 "element from llvm.compiler.used");

2227

2228

2229 return true;

2230

2231

2232 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);

2233}

2234

2237 return true;

2238

2239 return U.usedCount(&GV) || U.compilerUsedCount(&GV);

2240}

2241

2243 bool &RenameTarget) {

2245 return false;

2246

2247 RenameTarget = false;

2248 bool Ret = false;

2250 Ret = true;

2251

2252

2254 return Ret;

2255

2256

2257

2258

2259

2260

2261

2262

2266 return Ret;

2267

2268 RenameTarget = true;

2269 return true;

2270}

2271

2272static bool

2276 LLVMUsed Used(M);

2277

2279 Used.compilerUsedErase(GV);

2280

2281

2282

2283 auto IsModuleLocal = [](GlobalValue &GV) {

2286 };

2287

2289

2290 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())

2292

2293 if (deleteIfDead(J, NotDiscardableComdats)) {

2295 continue;

2296 }

2297

2298

2299 if (!IsModuleLocal(J))

2300 continue;

2301

2302 Constant *Aliasee = J.getAliasee();

2304

2305

2306

2307

2308

2309

2311 continue;

2312

2313 Target->removeDeadConstantUsers();

2314

2315

2316 bool RenameTarget;

2318 continue;

2319

2320 J.replaceAllUsesWith(Aliasee);

2321 ++NumAliasesResolved;

2323

2324 if (RenameTarget) {

2325

2326 Target->takeName(&J);

2327 Target->setLinkage(J.getLinkage());

2328 Target->setDSOLocal(J.isDSOLocal());

2329 Target->setVisibility(J.getVisibility());

2330 Target->setDLLStorageClass(J.getDLLStorageClass());

2331

2332 if (Used.usedErase(&J))

2333 Used.usedInsert(Target);

2334

2335 if (Used.compilerUsedErase(&J))

2336 Used.compilerUsedInsert(Target);

2338 continue;

2339

2340

2341 M.eraseAlias(&J);

2342 ++NumAliasesRemoved;

2344 }

2345

2346 Used.syncVariablesAndSets();

2347

2349}

2350

2354 LibFunc Func) {

2355

2356 auto FuncIter = M.begin();

2357 if (FuncIter == M.end())

2358 return nullptr;

2359 auto *TLI = &GetTLI(*FuncIter);

2360

2361 if (!TLI->has(Func))

2362 return nullptr;

2363

2365 if (!Fn)

2366 return nullptr;

2367

2368

2369 TLI = &GetTLI(*Fn);

2370

2371

2372 LibFunc F;

2373 if (!TLI->getLibFunc(*Fn, F) || F != Func)

2374 return nullptr;

2375

2376 return Fn;

2377}

2378

2379

2380

2381

2382

2384

2385

2387 return false;

2388

2390 if (I.isDebugOrPseudoInst())

2391 continue;

2393 return true;

2394 break;

2395 }

2396 return false;

2397}

2398

2400

2401

2402

2403

2404

2405

2406

2407

2408

2409

2410

2411

2412

2413

2415

2417

2418

2419

2421 if (!CI)

2422 continue;

2423

2427 continue;

2428

2429

2432

2433 if (isCXX)

2434 ++NumCXXDtorsRemoved;

2435 else

2436 ++NumAtExitRemoved;

2437

2439 }

2440

2442}

2443

2446 return nullptr;

2447

2450 return nullptr;

2451

2452 if (Resolver->isInterposable())

2453 return nullptr;

2454

2455

2456 auto It = Resolver->begin();

2457 if (++It != Resolver->end())

2458 return nullptr;

2459

2461

2463 return nullptr;

2464

2466 if (!Ret)

2467 return nullptr;

2468

2470}

2471

2472

2473

2478 if (!IF.use_empty() &&

2479 (!Callee->isDeclaration() ||

2480 none_of(IF.users(), [](User *U) { return isa(U); }))) {

2481 IF.replaceAllUsesWith(Callee);

2482 NumIFuncsResolved++;

2484 }

2486}

2487

2488static bool

2493 if (deleteIfDead(IF, NotDiscardableComdats)) {

2494 NumIFuncsDeleted++;

2496 }

2498}

2499

2500

2501

2502

2503static bool

2507 if (!GetTTI(*F).isMultiversionedFunction(*F))

2508 return false;

2511 if (collectVersions(Sel->getTrueValue(), Versions, GetTTI))

2512 return false;

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

2514 return false;

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

2517 if (collectVersions(Phi->getIncomingValue(I), Versions, GetTTI))

2518 return false;

2519 } else {

2520

2521 return false;

2522 }

2523 return true;

2524}

2525

2526

2527

2528

2529

2530

2531

2532

2533

2534

2535

2536

2537

2538

2539

2540

2541

2542

2543

2544

2545

2546

2550

2551

2553

2555

2557

2559

2561

2563 LLVM_DEBUG(dbgs() << "Examining IFUNC " << IF.getName() << "\n");

2564

2565 if (IF.isInterposable())

2566 continue;

2567

2570 continue;

2571

2572 if (Resolver->isInterposable())

2573 continue;

2574

2576

2579 if (collectVersions(Ret->getReturnValue(), Versions, GetTTI))

2580 return true;

2581 return false;

2582 }))

2583 continue;

2584

2585 if (Versions.empty())

2586 continue;

2587

2588 for (Function *V : Versions) {

2589 VersionOf.insert({V, &IF});

2590 auto [FeatIt, FeatInserted] = FeatureMask.try_emplace(V);

2591 if (FeatInserted)

2592 FeatIt->second = GetTTI(*V).getFeatureMask(*V);

2593 auto [PriorIt, PriorInserted] = PriorityMask.try_emplace(V);

2594 if (PriorInserted)

2595 PriorIt->second = GetTTI(*V).getPriorityMask(*V);

2596 }

2597

2598

2599 sort(Versions, [&](auto *LHS, auto *RHS) {

2600 return PriorityMask[LHS].ugt(PriorityMask[RHS]);

2601 });

2602

2604 VersionedFuncs.try_emplace(&IF, std::move(Versions));

2605 }

2606

2611

2612

2613 for (User *U : CalleeIF->users()) {

2615 if (CB->getCalledOperand() == CalleeIF) {

2616 Function *Caller = CB->getFunction();

2619 bool CallerIsFMV = TTI.isMultiversionedFunction(*Caller);

2620

2621 if (auto It = VersionOf.find(Caller); It != VersionOf.end())

2622 CallerIF = It->second;

2624

2625 auto [It, Inserted] = FeatureMask.try_emplace(Caller);

2626 if (Inserted)

2627 It->second = TTI.getFeatureMask(*Caller);

2628 } else

2629

2630 continue;

2631 auto [It, Inserted] = CallSites.try_emplace(Caller);

2632 if (Inserted) {

2633 if (CallerIsFMV)

2634 CallerIFuncs.insert(CallerIF);

2635 else

2636 NonFMVCallers.push_back(Caller);

2637 }

2638 It->second.push_back(CB);

2639 }

2640 }

2641 }

2642

2643 if (CallSites.empty())

2644 continue;

2645

2646 LLVM_DEBUG(dbgs() << "Statically resolving calls to function "

2647 << CalleeIF->getResolverFunction()->getName() << "\n");

2648

2649

2650

2651

2654 bool CallerIsFMV) {

2655 bool AllowExpensiveChecks = CallerIsFMV &&

2658

2659 unsigned J = 0;

2660

2661 for (unsigned I = 0, E = Callers.size(); I < E; ++I) {

2662

2663 if (J == Callees.size())

2664 break;

2665

2667 APInt CallerBits = FeatureMask[Caller];

2668

2669

2670

2671

2672

2673

2674 auto eliminateAvailableFeatures = [&](unsigned BestCandidate) {

2675 unsigned K = 0;

2676 while (K < I && BestCandidate < Callees.size()) {

2677 APInt MissingBits = FeatureMask[Callers[K]] & ~CallerBits;

2678 if (MissingBits.isSubsetOf(FeatureMask[Callees[BestCandidate]])) {

2679 ++BestCandidate;

2680

2681 K = 0;

2682 } else

2683 ++K;

2684 }

2685 return BestCandidate;

2686 };

2687

2688 unsigned BestCandidate =

2689 AllowExpensiveChecks ? eliminateAvailableFeatures(J) : J;

2690

2691 if (BestCandidate == Callees.size())

2692 continue;

2693

2695 << (CallerIsFMV ? "FMV" : "regular") << " caller "

2696 << Caller->getName() << "\n");

2697

2698 Function *Callee = Callees[BestCandidate];

2699 APInt CalleeBits = FeatureMask[Callee];

2700

2701

2702

2703

2704 if (CalleeBits.isSubsetOf(CallerBits)) {

2705

2706 if (auto It = CallSites.find(Caller); It != CallSites.end()) {

2707 for (CallBase *CS : It->second) {

2708 LLVM_DEBUG(dbgs() << " Redirecting call " << Caller->getName()

2709 << " -> " << Callee->getName() << "\n");

2711 }

2713 }

2714 }

2715

2716

2717 if (!CallerIsFMV)

2718 continue;

2719

2720

2721

2722

2723

2724 while (CallerBits.isSubsetOf(FeatureMask[Callees[J]]) &&

2725 ++J < Callees.size())

2726 ;

2727 }

2728 };

2729

2730 auto &Callees = VersionedFuncs[CalleeIF];

2731

2732

2734 staticallyResolveCalls(NonFMVCallers, Callees, false);

2735

2736

2737 for (GlobalIFunc *CallerIF : CallerIFuncs) {

2738 auto &Callers = VersionedFuncs[CallerIF];

2739 staticallyResolveCalls(Callers, Callees, true);

2740 }

2741

2742 if (CalleeIF->use_empty() ||

2743 all_of(CalleeIF->users(), [](User *U) { return isa(U); }))

2744 NumIFuncsResolved++;

2745 }

2747}

2748

2749static bool

2759 bool LocalChange = true;

2760 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;

2761

2762 while (LocalChange) {

2763 LocalChange = false;

2764

2765 NotDiscardableComdats.clear();

2769 NotDiscardableComdats.insert(C);

2771 if (const Comdat *C = F.getComdat())

2772 if (F.isDefTriviallyDead())

2773 NotDiscardableComdats.insert(C);

2775 if (const Comdat *C = GA.getComdat())

2776 if (!GA.isDiscardableIfUnused() || !GA.use_empty())

2777 NotDiscardableComdats.insert(C);

2778

2779

2780 LocalChange |= OptimizeFunctions(M, GetTLI, GetTTI, GetBFI, LookupDomTree,

2781 NotDiscardableComdats, ChangedCFGCallback,

2782 DeleteFnCallback);

2783

2784

2785 LocalChange |=

2787 if (FirstNotFullyEvaluatedPriority &&

2788 *FirstNotFullyEvaluatedPriority != Priority)

2789 return false;

2791 if (!Evaluated)

2792 FirstNotFullyEvaluatedPriority = Priority;

2793 return Evaluated;

2794 });

2795

2796

2798 NotDiscardableComdats);

2799

2800

2802

2803

2804

2808

2811

2812

2814

2815

2817

2818

2820

2822 }

2823

2824

2825

2826

2828}

2829

2831 auto &DL = M.getDataLayout();

2832 auto &FAM =

2836 };

2839 };

2842 };

2843

2846 };

2847 auto ChangedCFGCallback = [&FAM](Function &F) {

2849 };

2850 auto DeleteFnCallback = [&FAM](Function &F) { FAM.clear(F, F.getName()); };

2851

2853 ChangedCFGCallback, DeleteFnCallback))

2855

2857

2859

2860

2861

2863 return PA;

2864}

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:173

static Function * FindAtExitLibFunc(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI, LibFunc Func)

Definition GlobalOpt.cpp:2352

static bool optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)

Definition GlobalOpt.cpp:1139

static Function * hasSideeffectFreeStaticResolution(GlobalIFunc &IF)

Definition GlobalOpt.cpp:2444

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:1092

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:907

static bool OptimizeStaticIFuncs(Module &M)

Find IFuncs that have resolvers that always point at the same statically known callee,...

Definition GlobalOpt.cpp:2474

static bool hasOnlyColdCalls(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, ChangeableCCCacheTy &ChangeableCCCache)

Definition GlobalOpt.cpp:1803

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:719

static bool hasChangeableCCImpl(Function *F)

Return true if this is a calling convention that we'd like to change.

Definition GlobalOpt.cpp:1716

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:665

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:929

static bool collectVersions(Value *V, SmallVectorImpl< Function * > &Versions, function_ref< TargetTransformInfo &(Function &)> GetTTI)

Definition GlobalOpt.cpp:2504

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:2383

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:361

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:1053

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:1933

static bool DeleteDeadIFuncs(Module &M, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)

Definition GlobalOpt.cpp:2489

static void RemoveAttribute(Function *F, Attribute::AttrKind A)

Definition GlobalOpt.cpp:1704

static bool hasChangeableCC(Function *F, ChangeableCCCacheTy &ChangeableCCCache)

Definition GlobalOpt.cpp:1747

static bool deleteIfDead(GlobalValue &GV, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats, function_ref< void(Function &)> DeleteFnCallback=nullptr)

Definition GlobalOpt.cpp:1334

static void RemovePreallocated(Function *F)

Definition GlobalOpt.cpp:1851

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:1649

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:1757

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:450

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:2273

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:1172

static void ChangeCalleesToFastCall(Function *F)

Walk all of the direct calls of the specified function, changing them to FastCC.

Definition GlobalOpt.cpp:1689

static bool hasMustTailCallers(Function *F)

Definition GlobalOpt.cpp:1835

static bool OptimizeNonTrivialIFuncs(Module &M, function_ref< TargetTransformInfo &(Function &)> GetTTI)

Definition GlobalOpt.cpp:2547

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:2053

static void allUsesOfLoadAndStores(GlobalVariable *GV, SmallVector< Value *, 4 > &Uses)

Get all the loads/store uses for global variable GV.

Definition GlobalOpt.cpp:753

static bool OptimizeEmptyGlobalAtExitDtors(Function *CXAAtExitFn, bool isCXX)

Definition GlobalOpt.cpp:2399

static bool mayHaveOtherReferences(GlobalValue &GV, const LLVMUsed &U)

Definition GlobalOpt.cpp:2235

static void changeCallSitesToColdCC(Function *F)

Definition GlobalOpt.cpp:1792

static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs, Attribute::AttrKind A)

Definition GlobalOpt.cpp:1696

static bool hasInvokeCallers(Function *F)

Definition GlobalOpt.cpp:1844

static void setUsedInitializer(GlobalVariable &V, const SmallPtrSetImpl< GlobalValue * > &Init)

Definition GlobalOpt.cpp:2122

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:842

static bool isValidCandidateForColdCC(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, const std::vector< Function * > &AllCallsCold)

Definition GlobalOpt.cpp:1771

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:2750

static bool EvaluateStaticConstructor(Function *F, const DataLayout &DL, TargetLibraryInfo *TLI)

Evaluate static constructors in the function, if we can.

Definition GlobalOpt.cpp:2088

static bool CleanupConstantGlobalUsers(GlobalVariable *GV, const DataLayout &DL)

We just marked GV constant.

Definition GlobalOpt.cpp:282

SmallDenseMap< Function *, bool, 8 > ChangeableCCCacheTy

Definition GlobalOpt.cpp:1746

static bool isLeakCheckerRoot(GlobalVariable *GV)

Is this global variable possibly used by a leak checker as a root?

Definition GlobalOpt.cpp:123

static bool forwardStoredOnceStore(GlobalVariable *GV, const StoreInst *StoredOnceStore, function_ref< DominatorTree &(Function &)> LookupDomTree)

Definition GlobalOpt.cpp:1434

static int compareNames(Constant *const *A, Constant *const *B)

Definition GlobalOpt.cpp:2116

static bool CleanupPointerRootUsers(GlobalVariable *GV, function_ref< TargetLibraryInfo &(Function &)> GetTLI)

This GV is a pointer root.

Definition GlobalOpt.cpp:204

static bool isPointerValueDeadOnEntryToFunction(const Function *F, GlobalValue *GV, function_ref< DominatorTree &(Function &)> LookupDomTree)

Definition GlobalOpt.cpp:1365

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:1470

static bool hasUsesToReplace(GlobalAlias &GA, const LLVMUsed &U, bool &RenameTarget)

Definition GlobalOpt.cpp:2242

static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV)

Definition GlobalOpt.cpp:772

static GlobalVariable * SRAGlobal(GlobalVariable *GV, const DataLayout &DL)

Perform scalar replacement of aggregates on the specified global variable.

Definition GlobalOpt.cpp:530

static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U)

Definition GlobalOpt.cpp:2219

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

This file contains the declarations for profiling metadata utility functions.

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:2830

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.

LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)

Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...

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:352

bool IsStored

Definition GlobalOpt.cpp:356

Constant * Initializer

Definition GlobalOpt.cpp:354

bool IsLoaded

Definition GlobalOpt.cpp:355

Type * Ty

Definition GlobalOpt.cpp:353

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::...