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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

50#include

51#include

52#include

53

54using namespace llvm;

55

56#define DEBUG_TYPE "deadargelim"

57

58STATISTIC(NumArgumentsEliminated, "Number of unread args removed");

59STATISTIC(NumRetValsEliminated, "Number of unused return values removed");

61 "Number of unread args replaced with poison");

62

63namespace {

64

65

67protected:

68

70

71public:

72 static char ID;

73

76 }

77

80 return false;

85 }

86

87 virtual bool shouldHackArguments() const { return false; }

88};

89

90bool isMustTailCalleeAnalyzable(const CallBase &CB) {

93}

94

95}

96

97char DAE::ID = 0;

98

99INITIALIZE_PASS(DAE, "deadargelim", "Dead Argument Elimination", false, false)

100

101namespace {

102

103

104

105struct DAH : public DAE {

106 static char ID;

107

108 DAH() : DAE(ID) {}

109

110 bool shouldHackArguments() const override { return true; }

111};

112

113}

114

115char DAH::ID = 0;

116

118 "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)", false,

119 false)

120

121

122

124

126

127

128

129bool DeadArgumentEliminationPass::deleteDeadVarargs(Function &F) {

130 assert(F.getFunctionType()->isVarArg() && "Function isn't varargs!");

131 if (F.isDeclaration() || F.hasLocalLinkage())

132 return false;

133

134

135 if (F.hasAddressTaken())

136 return false;

137

138

139

140

141 if (F.hasFnAttribute(Attribute::Naked)) {

142 return false;

143 }

144

145

146

149 CallInst *CI = dyn_cast(&I);

150 if (!CI)

151 continue;

153 return false;

155 if (II->getIntrinsicID() == Intrinsic::vastart)

156 return false;

157 }

158 }

159 }

160

161

162

163

164

165

167

168 std::vector<Type *> Params(FTy->param_begin(), FTy->param_end());

170 unsigned NumArgs = Params.size();

171

172

176 F.getParent()->getFunctionList().insert(F.getIterator(), NF);

179

180

181

182

183 std::vector<Value *> Args;

185 CallBase *CB = dyn_cast(U);

186 if (!CB)

187 continue;

188

189

191

192

196 for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo)

200 }

201

204

206 if (InvokeInst *II = dyn_cast(CB)) {

209 } else {

211 cast(NewCB)->setTailCallKind(

212 cast(CB)->getTailCallKind());

213 }

216 NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});

217

218 Args.clear();

219

222

224

225

226

228 }

229

230

231

232

234

235

236

237

240 I != E; ++I, ++I2) {

241

242 I->replaceAllUsesWith(&*I2);

243 I2->takeName(&*I);

244 }

245

246

248 F.getAllMetadata(MDs);

249 for (auto [KindID, Node] : MDs)

251

252

253 F.replaceAllUsesWith(NF);

254

255

257

258 F.eraseFromParent();

259 return true;

260}

261

262

263

264bool DeadArgumentEliminationPass::removeDeadArgumentsFromCallers(Function &F) {

265

266

267

268

269

270

271

272

273

274

275

276 if (F.hasExactDefinition())

277 return false;

278

279

280

281

282

284 F.getFunctionType()->isVarArg())

285 return false;

286

287

288

289

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

291 return false;

292

293 if (F.use_empty())

294 return false;

295

297 bool Changed = false;

298

302 if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&

303 !Arg.hasPassPointeeByValueCopyAttr()) {

304 if (Arg.isUsedByMetadata()) {

306 Changed = true;

307 }

308 UnusedArgs.push_back(Arg.getArgNo());

309 F.removeParamAttrs(Arg.getArgNo(), UBImplyingAttributes);

310 }

311 }

312

313 if (UnusedArgs.empty())

314 return false;

315

316 for (Use &U : F.uses()) {

317 CallBase *CB = dyn_cast(U.getUser());

318 if (!CB || !CB->isCallee(&U) ||

320 continue;

321

322

323 for (unsigned ArgNo : UnusedArgs) {

327

328 ++NumArgumentsReplacedWithPoison;

329 Changed = true;

330 }

331 }

332

333 return Changed;

334}

335

336

337

338

341 if (RetTy->isVoidTy())

342 return 0;

344 return STy->getNumElements();

346 return ATy->getNumElements();

347 return 1;

348}

349

350

351

352

355 assert(RetTy->isVoidTy() && "void type has no subtype");

356

358 return STy->getElementType(Idx);

360 return ATy->getElementType();

362}

363

364

365

367DeadArgumentEliminationPass::markIfNotLive(RetOrArg Use,

368 UseVector &MaybeLiveUses) {

369

370 if (isLive(Use))

372

373

374

375 MaybeLiveUses.push_back(Use);

377}

378

379

380

381

382

383

384

385

387DeadArgumentEliminationPass::surveyUse(const Use *U, UseVector &MaybeLiveUses,

388 unsigned RetValNum) {

389 const User *V = U->getUser();

390 if (const ReturnInst *RI = dyn_cast(V)) {

391

392

393

394

395 const Function *F = RI->getParent()->getParent();

396 if (RetValNum != -1U) {

398

399 return markIfNotLive(Use, MaybeLiveUses);

400 }

401

403 for (unsigned Ri = 0; Ri < numRetVals(F); ++Ri) {

405

406

407

409 markIfNotLive(Use, MaybeLiveUses);

410 if (Result != Live)

411 Result = SubResult;

412 }

413 return Result;

414 }

415

418 IV->hasIndices())

419

420

421

422 RetValNum = *IV->idx_begin();

423

424

425

426

428 for (const Use &UU : IV->uses()) {

429 Result = surveyUse(&UU, MaybeLiveUses, RetValNum);

430 if (Result == Live)

431 break;

432 }

433 return Result;

434 }

435

436 if (const auto *CB = dyn_cast(V)) {

438 if (F) {

439

440

441

444

445

446

447

448

450

451 if (ArgNo >= F->getFunctionType()->getNumParams())

452

454

456 "Argument is not where we expected it");

457

458

459

461 return markIfNotLive(Use, MaybeLiveUses);

462 }

463 }

464

466}

467

468

469

470

471

472

473

475DeadArgumentEliminationPass::surveyUses(const Value *V,

476 UseVector &MaybeLiveUses) {

477

479

480 for (const Use &U : V->uses()) {

481 Result = surveyUse(&U, MaybeLiveUses);

482 if (Result == Live)

483 break;

484 }

485 return Result;

486}

487

488

489

490

491

492

493

494void DeadArgumentEliminationPass::surveyFunction(const Function &F) {

495

496

497 if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||

498 F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {

499 markLive(F);

500 return;

501 }

502

503

504

505

506 if (F.hasFnAttribute(Attribute::Naked)) {

507 markLive(F);

508 return;

509 }

510

512

513

515

516 RetVals RetValLiveness(RetCount, MaybeLive);

517

519

520

521

522

523 RetUses MaybeLiveRetUses(RetCount);

524

525 bool HasMustTailCalls = false;

527

528

529 if (const auto *TC = BB.getTerminatingMustTailCall()) {

530 HasMustTailCalls = true;

531

532

533

534 if (!isMustTailCalleeAnalyzable(*TC)) {

535 markLive(F);

536 return;

537 }

538 }

539 }

540

541 if (HasMustTailCalls) {

542 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - " << F.getName()

543 << " has musttail calls\n");

544 }

545

547 markLive(F);

548 return;

549 }

550

552 dbgs() << "DeadArgumentEliminationPass - Inspecting callers for fn: "

553 << F.getName() << "\n");

554

555

556 unsigned NumLiveRetVals = 0;

557

558 bool HasMustTailCallers = false;

559

560

561 for (const Use &U : F.uses()) {

562

563

564 const auto *CB = dyn_cast(U.getUser());

565 if (!CB || !CB->isCallee(&U) ||

567 markLive(F);

568 return;

569 }

570

571

572

574 HasMustTailCallers = true;

575

576

577

578

579

580 if (NumLiveRetVals == RetCount)

581 continue;

582

583

584 for (const Use &UU : CB->uses()) {

585 if (ExtractValueInst *Ext = dyn_cast(UU.getUser())) {

586

587

588 unsigned Idx = *Ext->idx_begin();

589 if (RetValLiveness[Idx] != Live) {

590 RetValLiveness[Idx] = surveyUses(Ext, MaybeLiveRetUses[Idx]);

591 if (RetValLiveness[Idx] == Live)

592 NumLiveRetVals++;

593 }

594 } else {

595

596

597 UseVector MaybeLiveAggregateUses;

598 if (surveyUse(&UU, MaybeLiveAggregateUses) == Live) {

599 NumLiveRetVals = RetCount;

600 RetValLiveness.assign(RetCount, Live);

601 break;

602 }

603

604 for (unsigned Ri = 0; Ri != RetCount; ++Ri) {

605 if (RetValLiveness[Ri] != Live)

606 MaybeLiveRetUses[Ri].append(MaybeLiveAggregateUses.begin(),

607 MaybeLiveAggregateUses.end());

608 }

609 }

610 }

611 }

612

613 if (HasMustTailCallers) {

614 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - " << F.getName()

615 << " has musttail callers\n");

616 }

617

618

619 for (unsigned Ri = 0; Ri != RetCount; ++Ri)

620 markValue(createRet(&F, Ri), RetValLiveness[Ri], MaybeLiveRetUses[Ri]);

621

622 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Inspecting args for fn: "

623 << F.getName() << "\n");

624

625

626 unsigned ArgI = 0;

629 AI != E; ++AI, ++ArgI) {

631 if (F.getFunctionType()->isVarArg() || HasMustTailCallers ||

632 HasMustTailCalls) {

633

634

635

636

637

638

639

640

641

642

643

644 Result = Live;

645 } else {

646

647

648 Result = surveyUses(&*AI, MaybeLiveArgUses);

649 }

650

651

652 markValue(createArg(&F, ArgI), Result, MaybeLiveArgUses);

653

654 MaybeLiveArgUses.clear();

655 }

656}

657

658

659

660

661void DeadArgumentEliminationPass::markValue(const RetOrArg &RA, Liveness L,

662 const UseVector &MaybeLiveUses) {

663 switch (L) {

665 markLive(RA);

666 break;

668 assert(!isLive(RA) && "Use is already live!");

669 for (const auto &MaybeLiveUse : MaybeLiveUses) {

670 if (isLive(MaybeLiveUse)) {

671

672 markLive(RA);

673 break;

674 }

675

676

677 Uses.emplace(MaybeLiveUse, RA);

678 }

679 break;

680 }

681}

682

683

684

685

686void DeadArgumentEliminationPass::markLive(const Function &F) {

687 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Intrinsically live fn: "

688 << F.getName() << "\n");

689

691

692 for (unsigned ArgI = 0, E = F.arg_size(); ArgI != E; ++ArgI)

693 propagateLiveness(createArg(&F, ArgI));

694

695 for (unsigned Ri = 0, E = numRetVals(&F); Ri != E; ++Ri)

696 propagateLiveness(createRet(&F, Ri));

697}

698

699

700

701void DeadArgumentEliminationPass::markLive(const RetOrArg &RA) {

702 if (isLive(RA))

703 return;

704

706

707 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Marking "

708 << RA.getDescription() << " live\n");

709 propagateLiveness(RA);

710}

711

712bool DeadArgumentEliminationPass::isLive(const RetOrArg &RA) {

714}

715

716

717

718void DeadArgumentEliminationPass::propagateLiveness(const RetOrArg &RA) {

719

720

721

722 UseMap::iterator Begin = Uses.lower_bound(RA);

723 UseMap::iterator E = Uses.end();

724 UseMap::iterator I;

725 for (I = Begin; I != E && I->first == RA; ++I)

726 markLive(I->second);

727

728

729

730 Uses.erase(Begin, I);

731}

732

733

734

735

736bool DeadArgumentEliminationPass::removeDeadStuffFromFunction(Function *F) {

737

739 return false;

740

741

742

744 std::vector<Type *> Params;

745

746

747 bool HasLiveReturnedArg = false;

748

749

753

754

756

757

758

759 unsigned ArgI = 0;

761 ++I, ++ArgI) {

764 Params.push_back(I->getType());

765 ArgAlive[ArgI] = true;

767 HasLiveReturnedArg |= PAL.hasParamAttr(ArgI, Attribute::Returned);

768 } else {

769 ++NumArgumentsEliminated;

770

771 ORE.emit([&]() {

773 << "eliminating argument " << ore::NV("ArgName", I->getName())

774 << "(" << ore::NV("ArgIndex", ArgI) << ")";

775 });

776 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Removing argument "

777 << ArgI << " (" << I->getName() << ") from "

778 << F->getName() << "\n");

779 }

780 }

781

782

783 Type *RetTy = FTy->getReturnType();

784 Type *NRetTy = nullptr;

786

787

789 std::vector<Type *> RetTypes;

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810 if (RetTy->isVoidTy() || HasLiveReturnedArg) {

812 } else {

813

814 for (unsigned Ri = 0; Ri != RetCount; ++Ri) {

817 RetTypes.push_back(getRetComponentType(F, Ri));

818 NewRetIdxs[Ri] = RetTypes.size() - 1;

819 } else {

820 ++NumRetValsEliminated;

821

822 ORE.emit([&]() {

824 << "removing return value " << std::to_string(Ri);

825 });

827 dbgs() << "DeadArgumentEliminationPass - Removing return value "

828 << Ri << " from " << F->getName() << "\n");

829 }

830 }

831 if (RetTypes.size() > 1) {

832

834

835

836 NRetTy = StructType::get(STy->getContext(), RetTypes, STy->isPacked());

837 } else {

838 assert(isa(RetTy) && "unexpected multi-value return");

839 NRetTy = ArrayType::get(RetTypes[0], RetTypes.size());

840 }

841 } else if (RetTypes.size() == 1)

842

843

844 NRetTy = RetTypes.front();

845 else if (RetTypes.empty())

846

848 }

849

850 assert(NRetTy && "No new return type found?");

851

852

854

855

856

857

858

861 else

862 assert(!RAttrs.overlaps(

864 "Return attributes no longer compatible?");

865

867

868

871

872

873 assert(ArgAttrVec.size() == Params.size());

876

877

879

880

881 if (NFTy == FTy)

882 return false;

883

884

889

890

891 F->getParent()->getFunctionList().insert(F->getIterator(), NF);

894

895

896

897 std::vector<Value *> Args;

898 while (F->use_empty()) {

899 CallBase &CB = cast(*F->user_back());

900

901 ArgAttrVec.clear();

903

904

905

907 RAttrs.remove(

910

911

912

914 unsigned Pi = 0;

915

916

917 for (unsigned E = FTy->getNumParams(); Pi != E; ++I, ++Pi)

918 if (ArgAlive[Pi]) {

919 Args.push_back(*I);

920

922 if (NRetTy != RetTy && Attrs.hasAttribute(Attribute::Returned)) {

923

924

925

926

927

929 F->getContext(), AttrBuilder(F->getContext(), Attrs)

931 } else {

932

934 }

935 }

936

937

938 for (auto *E = CB.arg_end(); I != E; ++I, ++Pi) {

939 Args.push_back(*I);

941 }

942

943

945

946

947

949 F->getContext(), Attribute::AllocSize);

950

953

956

958 if (InvokeInst *II = dyn_cast(&CB)) {

960 Args, OpBundles, "", CB.getParent());

961 } else {

963 cast(NewCB)->setTailCallKind(

964 cast(&CB)->getTailCallKind());

965 }

968 NewCB->copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});

969 Args.clear();

970 ArgAttrVec.clear();

971

974

978

979

981 } else {

983 "Return type changed, but not into a void. The old return type"

984 " must have been a struct or an array!");

986 if (InvokeInst *II = dyn_cast(&CB)) {

990 }

991

992

993

994

995

996

998 for (unsigned Ri = 0; Ri != RetCount; ++Ri)

999 if (NewRetIdxs[Ri] != -1) {

1002 if (RetTypes.size() > 1)

1003

1004

1005 V = IRB.CreateExtractValue(NewCB, NewRetIdxs[Ri], "newret");

1006 else

1007

1008 V = NewCB;

1009

1010 RetVal = IRB.CreateInsertValue(RetVal, V, Ri, "oldret");

1011 }

1012

1013

1016 }

1017 }

1018

1019

1020

1022 }

1023

1024

1025

1026

1028

1029

1030

1031 ArgI = 0;

1034 I != E; ++I, ++ArgI)

1035 if (ArgAlive[ArgI]) {

1036

1037

1038 I->replaceAllUsesWith(&*I2);

1039 I2->takeName(&*I);

1040 ++I2;

1041 } else {

1042

1043

1045 }

1046

1047

1048

1051 if (ReturnInst *RI = dyn_cast(BB.getTerminator())) {

1053 Value *RetVal = nullptr;

1054

1055 if (!NFTy->getReturnType()->isVoidTy()) {

1057

1058

1059

1060

1061

1062 Value *OldRet = RI->getOperand(0);

1063

1065 for (unsigned RetI = 0; RetI != RetCount; ++RetI)

1066 if (NewRetIdxs[RetI] != -1) {

1067 Value *EV = IRB.CreateExtractValue(OldRet, RetI, "oldret");

1068

1069 if (RetTypes.size() > 1) {

1070

1071

1072

1073 RetVal = IRB.CreateInsertValue(RetVal, EV, NewRetIdxs[RetI],

1074 "newret");

1075 } else {

1076

1077

1078 RetVal = EV;

1079 }

1080 }

1081 }

1082

1083

1084 auto *NewRet =

1086 NewRet->setDebugLoc(RI->getDebugLoc());

1087 RI->eraseFromParent();

1088 }

1089

1090

1092 F->getAllMetadata(MDs);

1093 for (auto [KindID, Node] : MDs)

1094 NF->addMetadata(KindID, *Node);

1095

1096

1097

1098

1099

1100 if (NFTy != FTy && NF->getSubprogram()) {

1102 auto Temp = SP->getType()->cloneWithCC(llvm::dwarf::DW_CC_nocall);

1104 }

1105

1106

1107 F->eraseFromParent();

1108

1109 return true;

1110}

1111

1112void DeadArgumentEliminationPass::propagateVirtMustcallLiveness(

1114

1115

1117 while (!NewLiveFuncs.empty()) {

1119 for (const auto *F : NewLiveFuncs)

1120 for (const auto *U : F->users())

1121 if (const auto *CB = dyn_cast(U))

1124 Temp.insert(CB->getParent()->getParent());

1125 NewLiveFuncs.clear();

1126 NewLiveFuncs.insert(Temp.begin(), Temp.end());

1127 for (const auto *F : Temp)

1128 markLive(*F);

1129 }

1130}

1131

1134 bool Changed = false;

1135

1136

1137

1138

1139

1140 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Deleting dead varargs\n");

1142 if (F.getFunctionType()->isVarArg())

1143 Changed |= deleteDeadVarargs(F);

1144

1145

1146

1147

1148 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Determining liveness\n");

1149 for (auto &F : M)

1150 surveyFunction(F);

1151

1152 propagateVirtMustcallLiveness(M);

1153

1154

1155

1156

1158 Changed |= removeDeadStuffFromFunction(&F);

1159

1160

1161

1162 for (auto &F : M)

1163 Changed |= removeDeadArgumentsFromCallers(F);

1164

1165 if (!Changed)

1168}

This file contains the simple types necessary to represent the attributes associated with functions a...

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

assert(!RetTy->isVoidTy() &&"void type has no subtype")

Convenience function that returns the number of return values It returns for void functions and for functions not returning a struct It returns the number of struct elements for functions returning a struct static unsigned numRetVals(const Function *F)

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

This defines the Use class.

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

SI optimize exec mask operations pre RA

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)

static const uint32_t IV[8]

A container for analyses that lazily runs them and caches their results.

This class represents an incoming formal argument to a Function.

static ArrayType * get(Type *ElementType, uint64_t NumElements)

This static method is the primary way to construct an ArrayType.

AttrBuilder & removeAttribute(Attribute::AttrKind Val)

Remove an attribute from the builder.

AttributeSet getFnAttrs() const

The function attributes are returned.

static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)

Create an AttributeList with the specified parameters in it.

bool isEmpty() const

Return true if there are no attributes.

AttributeSet getRetAttrs() const

The attributes for the ret value are returned.

bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const

Return true if the attribute exists for the given argument.

AttributeSet getParamAttrs(unsigned ArgNo) const

The attributes for the argument or parameter at the given index are returned.

AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const

Remove the specified attribute from this set.

static AttributeSet get(LLVMContext &C, const AttrBuilder &B)

LLVM Basic Block Representation.

const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

void setCallingConv(CallingConv::ID CC)

void removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)

Removes the attributes from the given argument.

void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const

Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

CallingConv::ID getCallingConv() const

User::op_iterator arg_begin()

Return the iterator pointing to the beginning of the argument list.

bool isMustTailCall() const

Tests if this call site must be tail call optimized.

bool isCallee(Value::const_user_iterator UI) const

Determine whether the passed iterator points to the callee operand's Use.

void setAttributes(AttributeList A)

Set the attributes for this call.

Value * getArgOperand(unsigned i) const

void setArgOperand(unsigned i, Value *v)

User::op_iterator arg_end()

Return the iterator pointing to the end of the argument list.

bool isBundleOperand(unsigned Idx) const

Return true if the operand at index Idx is a bundle operand.

FunctionType * getFunctionType() const

unsigned getArgOperandNo(const Use *U) const

Given a use for a arg operand, get the arg operand number that corresponds to it.

AttributeList getAttributes() const

Return the attributes for this call.

This class represents a function call, abstracting a target machine's calling convention.

static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

bool isMustTailCall() const

void removeDeadConstantUsers() const

If there are any dead constant users dangling off of this constant, remove them.

DISubprogram * getSubprogram() const

Get the subprogram for this scope.

Eliminate dead arguments (and return values) from functions.

SmallVector< RetOrArg, 5 > UseVector

std::set< const Function * > LiveFuncSet

PreservedAnalyses run(Module &M, ModuleAnalysisManager &)

Liveness

During our initial pass over the program, we determine that things are either alive or maybe alive.

LiveSet LiveValues

This set contains all values that have been determined to be live.

RetOrArg createRet(const Function *F, unsigned Idx)

Convenience wrapper.

RetOrArg createArg(const Function *F, unsigned Idx)

Convenience wrapper.

bool ShouldHackArguments

This allows this pass to do double-duty as the dead arg hacking pass (used only by bugpoint).

LiveFuncSet LiveFunctions

This set contains all values that are cannot be changed in any way.

UseMap Uses

This maps a return value or argument to any MaybeLive return values or arguments it uses.

static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)

void splice(Function::iterator ToIt, Function *FromF)

Transfer all blocks from FromF to this function at ToIt.

bool IsNewDbgInfoFormat

Is this function using intrinsics to record the position of debugging information,...

void setAttributes(AttributeList Attrs)

Set the attribute list for this Function.

Type * getReturnType() const

Returns the type of the ret val.

void copyAttributesFrom(const Function *Src)

copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...

void setComdat(Comdat *C)

void addMetadata(unsigned KindID, MDNode &MD)

Add a metadata attachment.

bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

This instruction inserts a struct field of array element value into an aggregate value.

static unsigned getAggregateOperandIndex()

InstListType::iterator eraseFromParent()

This method unlinks 'this' from the containing basic block and deletes it.

void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())

Copy metadata from SrcInst to this instruction.

A wrapper class for inspecting calls to intrinsic functions.

static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)

static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithPermanent(std::unique_ptr< T, TempMDNodeDeleter > N)

Replace a temporary node with a permanent one.

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

bool skipModule(Module &M) const

Optional passes call this function to check whether the pass should be skipped.

virtual bool runOnModule(Module &M)=0

runOnModule - Virtual method overriden by subclasses to process the module being operated on.

A Module instance is used to store all the information related to an LLVM module.

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

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.

bool areAllPreserved() const

Test whether all analyses are preserved (and none are abandoned).

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Return a value (possibly void), from a function.

static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Class to represent struct types.

static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

The instances of the Type class are immutable: once they are created, they are never changed.

static Type * getVoidTy(LLVMContext &C)

bool isVoidTy() const

Return true if this is 'void'.

A Use represents the edge between a Value definition and its users.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

bool isUsedByMetadata() const

Return true if there is metadata referencing this value.

iterator_range< use_iterator > uses()

void takeName(Value *V)

Transfer the name from V to this value.

const ParentTy * getParent() const

self_iterator getIterator()

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

constexpr char Attrs[]

Key for Kernel::Metadata::mAttrs.

AttributeMask getUBImplyingAttributes()

Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.

AttributeMask typeIncompatible(Type *Ty, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)

Which attributes cannot be applied to a type.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

DiagnosticInfoOptimizationBase::Argument NV

This is an optimization pass for GlobalISel generic memory operations.

ModulePass * createDeadArgEliminationPass()

createDeadArgEliminationPass - This pass removes arguments from functions which are not used by the b...

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

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

void initializeDAEPass(PassRegistry &)

BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")

Split the edge connecting the specified blocks, and return the newly created basic block between From...

ModulePass * createDeadArgHackingPass()

DeadArgHacking pass - Same as DAE, but delete arguments of external functions as well.