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

74 DAE() : ModulePass(ID) {

76 }

77

78 bool runOnModule(Module &M) override {

79 if (skipModule(M))

80 return false;

81 DeadArgumentEliminationPass DAEP(shouldHackArguments());

83 PreservedAnalyses PA = DAEP.run(M, DummyMAM);

85 }

86

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

88};

89

90}

91

92char DAE::ID = 0;

93

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

95

96namespace {

97

98

99

100struct DAH : public DAE {

101 static char ID;

102

103 DAH() : DAE(ID) {}

104

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

106};

107

108}

109

110char DAH::ID = 0;

111

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

114 false)

115

116

117

119

121

122

123

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

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

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

127 return false;

128

129

130 if (F.hasAddressTaken())

131 return false;

132

133

134

135

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

137 return false;

138 }

139

140

141

142 for (BasicBlock &BB : F) {

143 for (Instruction &I : BB) {

145 if (!CI)

146 continue;

148 return false;

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

151 return false;

152 }

153 }

154 }

155

156

157

158

159

160

161 FunctionType *FTy = F.getFunctionType();

162

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

164 FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);

165 unsigned NumArgs = Params.size();

166

167

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

173

174

175

176

177 std::vector<Value *> Args;

180 if (!CB)

181 continue;

182

183

185

186

188 if (!PAL.isEmpty()) {

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

191 ArgAttrs.push_back(PAL.getParamAttrs(ArgNo));

192 PAL = AttributeList::get(F.getContext(), PAL.getFnAttrs(),

193 PAL.getRetAttrs(), ArgAttrs);

194 }

195

198

199 CallBase *NewCB = nullptr;

203 } else {

207 }

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

211

212 Args.clear();

213

216

218

219

220

222 }

223

224

225

226

228

229

230

231

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

235

236 I->replaceAllUsesWith(&*I2);

237 I2->takeName(&*I);

238 }

239

240

242 F.getAllMetadata(MDs);

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

245

246

247 F.replaceAllUsesWith(NF);

248

249

251

252 F.eraseFromParent();

253 return true;

254}

255

256

257

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

259

260

261

262

263

264

265

266

267

268

269

270 if (F.hasExactDefinition())

271 return false;

272

273

274

275

276

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

279 return false;

280

281

282

283

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

285 return false;

286

287 if (F.use_empty())

288 return false;

289

290 SmallVector<unsigned, 8> UnusedArgs;

292

293 AttributeMask UBImplyingAttributes =

294 AttributeFuncs::getUBImplyingAttributes();

295 for (Argument &Arg : F.args()) {

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

297 !Arg.hasPassPointeeByValueCopyAttr()) {

298 if (Arg.isUsedByMetadata()) {

301 }

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

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

304 }

305 }

306

307 if (UnusedArgs.empty())

308 return false;

309

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

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

314 continue;

315

316

317 for (unsigned ArgNo : UnusedArgs) {

321

322 ++NumArgumentsReplacedWithPoison;

324 }

325 }

326

328}

329

330

331

332

334 Type *RetTy = F->getReturnType();

336 return 0;

338 return STy->getNumElements();

340 return ATy->getNumElements();

341 return 1;

342}

343

344

345

346

348 Type *RetTy = F->getReturnType();

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

350

352 return STy->getElementType(Idx);

354 return ATy->getElementType();

355 return RetTy;

356}

357

358

359

361DeadArgumentEliminationPass::markIfNotLive(RetOrArg Use,

362 UseVector &MaybeLiveUses) {

363

364 if (isLive(Use))

366

367

368

369 MaybeLiveUses.push_back(Use);

371}

372

373

374

375

376

377

378

379

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

382 unsigned RetValNum) {

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

385

386

387

388

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

390 if (RetValNum != -1U) {

392

393 return markIfNotLive(Use, MaybeLiveUses);

394 }

395

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

399

400

401

403 markIfNotLive(Use, MaybeLiveUses);

404 if (Result != Live)

406 }

408 }

409

412 IV->hasIndices())

413

414

415

416 RetValNum = *IV->idx_begin();

417

418

419

420

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

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

424 if (Result == Live)

425 break;

426 }

428 }

429

432 if (F) {

433

434

435

438

439

440

441

442

444

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

446

448

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

451

452

453

455 return markIfNotLive(Use, MaybeLiveUses);

456 }

457 }

458

460}

461

462

463

464

465

466

467

469DeadArgumentEliminationPass::surveyUses(const Value *V,

470 UseVector &MaybeLiveUses) {

471

473

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

475 Result = surveyUse(&U, MaybeLiveUses);

476 if (Result == Live)

477 break;

478 }

480}

481

482

483

484

485

486

487

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

489

490

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

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

493 markFrozen(F);

494 return;

495 }

496

497

498

499

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

501 markFrozen(F);

502 return;

503 }

504

506

507

509

510 RetVals RetValLiveness(RetCount, MaybeLive);

511

513

514

515

516

517 RetUses MaybeLiveRetUses(RetCount);

518

519 for (const BasicBlock &BB : F) {

520 if (BB.getTerminatingMustTailCall()) {

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

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

523 if (markFnOrRetTyFrozenOnMusttail(F))

524 return;

525 }

526 }

527

529 markFrozen(F);

530 return;

531 }

532

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

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

536

537

538 unsigned NumLiveRetVals = 0;

539

540

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

542

543

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

547 markFrozen(F);

548 return;

549 }

550

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

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

554 if (markFnOrRetTyFrozenOnMusttail(F))

555 return;

556 }

557

558

559

560

561

562 if (NumLiveRetVals == RetCount)

563 continue;

564

565

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

568

569

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

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

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

573 if (RetValLiveness[Idx] == Live)

574 NumLiveRetVals++;

575 }

576 } else {

577

578

579 UseVector MaybeLiveAggregateUses;

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

581 NumLiveRetVals = RetCount;

582 RetValLiveness.assign(RetCount, Live);

583 break;

584 }

585

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

587 if (RetValLiveness[Ri] != Live)

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

589 MaybeLiveAggregateUses.end());

590 }

591 }

592 }

593 }

594

595

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

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

598

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

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

601

602

603 unsigned ArgI = 0;

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

608 if (F.getFunctionType()->isVarArg()) {

609

610

611

612

613

615 } else {

616

617

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

619 }

620

621

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

623

624 MaybeLiveArgUses.clear();

625 }

626}

627

628

629

630

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

632 const UseVector &MaybeLiveUses) {

633 switch (L) {

635 markLive(RA);

636 break;

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

639 for (const auto &MaybeLiveUse : MaybeLiveUses) {

640 if (isLive(MaybeLiveUse)) {

641

642 markLive(RA);

643 break;

644 }

645

646

647 Uses.emplace(MaybeLiveUse, RA);

648 }

649 break;

650 }

651}

652

653

654

655

656

657bool DeadArgumentEliminationPass::markFnOrRetTyFrozenOnMusttail(

661 markFrozen(F);

662 return true;

663 } else {

664 markRetTyFrozen(F);

665 return false;

666 }

667}

668

669

670

671

672void DeadArgumentEliminationPass::markFrozen(const Function &F) {

673 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - frozen fn: "

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

675

677

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

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

680

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

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

683}

684

685void DeadArgumentEliminationPass::markRetTyFrozen(const Function &F) {

686 LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - frozen return type fn: "

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

689}

690

691

692

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

694 if (isLive(RA))

695 return;

696

698

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

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

701 propagateLiveness(RA);

702}

703

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

706}

707

708

709

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

711

712

713

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

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

716 UseMap::iterator I;

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

718 markLive(I->second);

719

720

721

722 Uses.erase(Begin, I);

723}

724

725

726

727

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

729

731 return false;

732

733

734

735 FunctionType *FTy = F->getFunctionType();

736 std::vector<Type *> Params;

737

738

739 bool HasLiveReturnedArg = false;

740

741

743 const AttributeList &PAL = F->getAttributes();

744 OptimizationRemarkEmitter ORE(F);

745

746

748

749

750

751 unsigned ArgI = 0;

753 ++I, ++ArgI) {

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

757 ArgAlive[ArgI] = true;

758 ArgAttrVec.push_back(PAL.getParamAttrs(ArgI));

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

760 } else {

761 ++NumArgumentsEliminated;

762

763 ORE.emit([&]() {

764 return OptimizationRemark(DEBUG_TYPE, "ArgumentRemoved", F)

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

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

767 });

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

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

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

771 }

772 }

773

774

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

776 Type *NRetTy = nullptr;

778

779

781 std::vector<Type *> RetTypes;

782

783

784

785

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802 if (RetTy->isVoidTy() || HasLiveReturnedArg ||

804 NRetTy = RetTy;

805 } else {

806

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

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

812 } else {

813 ++NumRetValsEliminated;

814

815 ORE.emit([&]() {

816 return OptimizationRemark(DEBUG_TYPE, "ReturnValueRemoved", F)

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

818 });

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

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

822 }

823 }

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

825

827

828

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

830 } else {

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

833 }

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

835

836

837 NRetTy = RetTypes.front();

838 else if (RetTypes.empty())

839

841 }

842

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

844

845

846 AttrBuilder RAttrs(F->getContext(), PAL.getRetAttrs());

847

848

849

850

851

853 RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy, PAL.getRetAttrs()));

854 else

855 assert(!RAttrs.overlaps(

856 AttributeFuncs::typeIncompatible(NRetTy, PAL.getRetAttrs())) &&

857 "Return attributes no longer compatible?");

858

860

861

862 AttributeSet FnAttrs =

863 PAL.getFnAttrs().removeAttribute(F->getContext(), Attribute::AllocSize);

864

865

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

867 AttributeList NewPAL =

868 AttributeList::get(F->getContext(), FnAttrs, RetAttrs, ArgAttrVec);

869

870

871 FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg());

872

873

874 if (NFTy == FTy)

875 return false;

876

877

882

883

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

886

887

888

889 std::vector<Value *> Args;

890 while (F->use_empty()) {

892

893 ArgAttrVec.clear();

894 const AttributeList &CallPAL = CB.getAttributes();

895

896

897

898 AttrBuilder RAttrs(F->getContext(), CallPAL.getRetAttrs());

899 RAttrs.remove(

900 AttributeFuncs::typeIncompatible(NRetTy, CallPAL.getRetAttrs()));

902

903

904

906 unsigned Pi = 0;

907

908

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

910 if (ArgAlive[Pi]) {

911 Args.push_back(*I);

912

913 AttributeSet Attrs = CallPAL.getParamAttrs(Pi);

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

915

916

917

918

919

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

922 .removeAttribute(Attribute::Returned)));

923 } else {

924

926 }

927 }

928

929

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

931 Args.push_back(*I);

932 ArgAttrVec.push_back(CallPAL.getParamAttrs(Pi));

933 }

934

935

937

938

939

940 AttributeSet FnAttrs = CallPAL.getFnAttrs().removeAttribute(

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

942

943 AttributeList NewCallPAL =

944 AttributeList::get(F->getContext(), FnAttrs, RetAttrs, ArgAttrVec);

945

948

949 CallBase *NewCB = nullptr;

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

953 } else {

957 }

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

961 Args.clear();

962 ArgAttrVec.clear();

963

966

970

971

973 } else {

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

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

982 }

983

984

985

986

987

988

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

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

994 if (RetTypes.size() > 1)

995

996

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

998 else

999

1000 V = NewCB;

1001

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

1003 }

1004

1005

1008 }

1009 }

1010

1011

1012

1014 }

1015

1016

1017

1018

1020

1021

1022

1023 ArgI = 0;

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

1027 if (ArgAlive[ArgI]) {

1028

1029

1030 I->replaceAllUsesWith(&*I2);

1031 I2->takeName(&*I);

1032 ++I2;

1033 } else {

1034

1035

1037 }

1038

1039

1040

1042 for (BasicBlock &BB : *NF)

1045 Value *RetVal = nullptr;

1046

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

1049

1050

1051

1052

1053

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

1055

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

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

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

1060

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

1062

1063

1064

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

1066 "newret");

1067 } else {

1068

1069

1070 RetVal = EV;

1071 }

1072 }

1073 }

1074

1075

1076 auto *NewRet =

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

1079 RI->eraseFromParent();

1080 }

1081

1082

1084 F->getAllMetadata(MDs);

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

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

1087

1088

1089

1090

1091

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

1093 DISubprogram *SP = NF->getSubprogram();

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

1096 }

1097

1098

1099 F->eraseFromParent();

1100

1101 return true;

1102}

1103

1107

1108

1109

1110

1111

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

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

1115 Changed |= deleteDeadVarargs(F);

1116

1117

1118

1119

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

1121 for (auto &F : M)

1122 surveyFunction(F);

1123

1124

1125

1126

1128 Changed |= removeDeadStuffFromFunction(&F);

1129

1130

1131

1132 for (auto &F : M)

1133 Changed |= removeDeadArgumentsFromCallers(F);

1134

1138}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

static Type * getRetComponentType(const Function *F, unsigned Idx)

Returns the sub-type a function will return at a given Idx.

Definition DeadArgumentElimination.cpp:347

static unsigned numRetVals(const Function *F)

Convenience function that returns the number of return values.

Definition DeadArgumentElimination.cpp:333

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.

Machine Check Debug Module

uint64_t IntrinsicInst * II

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

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]

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

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

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

LLVM_ABI const_iterator getFirstInsertionPt() const

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

void setCallingConv(CallingConv::ID CC)

void removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)

Removes the attributes from the given argument.

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

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

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

bool isMustTailCall() const

LLVM_ABI void removeDeadConstantUsers() const

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

SmallVector< RetOrArg, 5 > UseVector

PreservedAnalyses run(Module &M, ModuleAnalysisManager &)

Definition DeadArgumentElimination.cpp:1104

FuncSet FrozenRetTyFunctions

This set contains all functions that cannot change return type;.

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.

FuncSet FrozenFunctions

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

bool ShouldHackArguments

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

UseMap Uses

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

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

void setAttributes(AttributeList Attrs)

Set the attribute list for this Function.

Type * getReturnType() const

Returns the type of the ret val.

const Argument * const_arg_iterator

void copyAttributesFrom(const Function *Src)

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

LLVM_ABI void setComdat(Comdat *C)

LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)

Add a metadata attachment.

static unsigned getAggregateOperandIndex()

LLVM_ABI InstListType::iterator eraseFromParent()

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

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

Copy metadata from SrcInst to this instruction.

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

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

static LLVM_ABI PassRegistry * getPassRegistry()

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

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

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

void push_back(const T &Elt)

Class to represent struct types.

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

bool isArrayTy() const

True if this is an instance of ArrayType.

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

bool isStructTy() const

True if this is an instance of StructType.

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.

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

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

unsigned ID

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

@ Tail

Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...

@ SwiftTail

This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...

@ BasicBlock

Various leaf nodes.

@ User

could "use" a pointer

DiagnosticInfoOptimizationBase::Argument NV

NodeAddr< UseNode * > Use

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

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

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI void initializeDAEPass(PassRegistry &)

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

IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >

LLVM_ABI ModulePass * createDeadArgEliminationPass()

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

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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

LLVM_ABI ModulePass * createDeadArgHackingPass()

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

Definition DeadArgumentElimination.cpp:120

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

Struct that represents (part of) either a return value or a function argument.