LLVM: lib/CodeGen/SafeStack.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

67#include

68#include

69#include

70#include

71#include

72#include

73

74using namespace llvm;

76

77#define DEBUG_TYPE "safe-stack"

78

79namespace llvm {

80

81STATISTIC(NumFunctions, "Total number of functions");

82STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack");

83STATISTIC(NumUnsafeStackRestorePointsFunctions,

84 "Number of functions that use setjmp or exceptions");

85

86STATISTIC(NumAllocas, "Total number of allocas");

87STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas");

88STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas");

89STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments");

90STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads");

91

92}

93

94

95

99

101 cl::desc("enable safe stack coloring"),

103

104namespace {

105

106

107

108

109

110

111class SafeStack {

117

118 Type *StackPtrTy;

119 Type *IntPtrTy;

120 Type *Int32Ty;

121

122 Value *UnsafeStackPtr = nullptr;

123

124

125

126

127

128

129

130 static constexpr Align StackAlignment = Align::Constant<16>();

131

132

134

135

138

139

140

141

147

148

149

151

152

153

154

155

156

162

163

164

165

166

167

171 Value *StaticTop, bool NeedDynamicTop);

172

173

174

175

176 void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr,

179

180 bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize);

181

186

187 bool ShouldInlinePointerAddress(CallInst &CI);

188 void TryInlinePointerAddress();

189

190public:

193 : F(F), TL(TL), DL(DL), DTU(DTU), SE(SE),

194 StackPtrTy(DL.getAllocaPtrType(F.getContext())),

195 IntPtrTy(DL.getIntPtrType(F.getContext())),

196 Int32Ty(Type::getInt32Ty(F.getContext())) {}

197

198

199

200 bool run();

201};

202

203constexpr Align SafeStack::StackAlignment;

204

205uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {

208 auto C = dyn_cast(AI->getArraySize());

209 if (C)

210 return 0;

211 Size *= C->getZExtValue();

212 }

214}

215

218 const SCEV *AddrExpr = SE.getSCEV(Addr);

219 const auto *Base = dyn_cast(SE.getPointerBase(AddrExpr));

220 if (Base || Base->getValue() != AllocaPtr) {

222 dbgs() << "[SafeStack] "

223 << (isa(AllocaPtr) ? "Alloca " : "ByValArgument ")

224 << *AllocaPtr << "\n"

225 << "SCEV " << *AddrExpr << " not directly based on alloca\n");

226 return false;

227 }

228

229 const SCEV *Expr = SE.removePointerBase(AddrExpr);

231 ConstantRange AccessStartRange = SE.getUnsignedRange(Expr);

237 bool Safe = AllocaRange.contains(AccessRange);

238

240 dbgs() << "[SafeStack] "

241 << (isa(AllocaPtr) ? "Alloca " : "ByValArgument ")

242 << *AllocaPtr << "\n"

243 << " Access " << *Addr << "\n"

244 << " SCEV " << *Expr

245 << " U: " << SE.getUnsignedRange(Expr)

246 << ", S: " << SE.getSignedRange(Expr) << "\n"

247 << " Range " << AccessRange << "\n"

248 << " AllocaRange " << AllocaRange << "\n"

249 << " " << (Safe ? "safe" : "unsafe") << "\n");

250

251 return Safe;

252}

253

254bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,

255 const Value *AllocaPtr,

257 if (auto MTI = dyn_cast(MI)) {

258 if (MTI->getRawSource() != U && MTI->getRawDest() != U)

259 return true;

260 } else {

261 if (MI->getRawDest() != U)

262 return true;

263 }

264

265 const auto *Len = dyn_cast(MI->getLength());

266

267 if (!Len) return false;

268 return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize);

269}

270

271

272

273

274bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {

275

276

277

281

282

283 while (!WorkList.empty()) {

285 for (const Use &UI : V->uses()) {

286 auto I = cast(UI.getUser());

287 assert(V == UI.get());

288

289 switch (I->getOpcode()) {

290 case Instruction::Load:

291 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getType()), AllocaPtr,

292 AllocaSize))

293 return false;

294 break;

295

296 case Instruction::VAArg:

297

298 break;

299 case Instruction::Store:

300 if (V == I->getOperand(0)) {

301

303 << "[SafeStack] Unsafe alloca: " << *AllocaPtr

304 << "\n store of address: " << *I << "\n");

305 return false;

306 }

307

308 if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getOperand(0)->getType()),

309 AllocaPtr, AllocaSize))

310 return false;

311 break;

312

313 case Instruction::Ret:

314

315 return false;

316

317 case Instruction::Call:

318 case Instruction::Invoke: {

319 const CallBase &CS = *cast(I);

320

321 if (I->isLifetimeStartOrEnd())

322 continue;

323

324 if (const MemIntrinsic *MI = dyn_cast(I)) {

325 if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) {

327 << "[SafeStack] Unsafe alloca: " << *AllocaPtr

328 << "\n unsafe memintrinsic: " << *I << "\n");

329 return false;

330 }

331 continue;

332 }

333

334

335

336

337

338

339

340

342 for (const auto *A = B; A != E; ++A)

343 if (A->get() == V)

346 LLVM_DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr

347 << "\n unsafe call: " << *I << "\n");

348 return false;

349 }

350 continue;

351 }

352

353 default:

354 if (Visited.insert(I).second)

355 WorkList.push_back(cast(I));

356 }

357 }

358 }

359

360

361 return true;

362}

363

365 Value *StackGuardVar = TL.getIRStackGuard(IRB);

367

368 if (!StackGuardVar) {

369 TL.insertSSPDeclarations(*M);

370 return IRB.CreateIntrinsic(Intrinsic::stackguard, {}, {});

371 }

372

373 return IRB.CreateLoad(StackPtrTy, StackGuardVar, "StackGuard");

374}

375

376void SafeStack::findInsts(Function &F,

383 if (auto AI = dyn_cast(&I)) {

384 ++NumAllocas;

385

386 uint64_t Size = getStaticAllocaAllocationSize(AI);

387 if (IsSafeStackAlloca(AI, Size))

388 continue;

389

391 ++NumUnsafeStaticAllocas;

393 } else {

394 ++NumUnsafeDynamicAllocas;

396 }

397 } else if (auto RI = dyn_cast(&I)) {

398 if (CallInst *CI = I.getParent()->getTerminatingMustTailCall())

400 else

402 } else if (auto CI = dyn_cast(&I)) {

403

404 if (CI->getCalledFunction() && CI->canReturnTwice())

405 StackRestorePoints.push_back(CI);

406 } else if (auto LP = dyn_cast(&I)) {

407

408 StackRestorePoints.push_back(LP);

409 } else if (auto II = dyn_cast(&I)) {

410 if (II->getIntrinsicID() == Intrinsic::gcroot)

412 "gcroot intrinsic not compatible with safestack attribute");

413 }

414 }

416 if (!Arg.hasByValAttr())

417 continue;

418 uint64_t Size = DL.getTypeStoreSize(Arg.getParamByValType());

419 if (IsSafeStackAlloca(&Arg, Size))

420 continue;

421

422 ++NumUnsafeByValArguments;

424 }

425}

426

430 Value *StaticTop, bool NeedDynamicTop) {

431 assert(StaticTop && "The stack top isn't set.");

432

433 if (StackRestorePoints.empty())

434 return nullptr;

435

436

437

438

439

440

441

443 if (NeedDynamicTop) {

444

445

446 DynamicTop = IRB.CreateAlloca(StackPtrTy, nullptr,

447 "unsafe_stack_dynamic_ptr");

449 }

450

451

453 ++NumUnsafeStackRestorePoints;

454

456 Value *CurrentTop =

457 DynamicTop ? IRB.CreateLoad(StackPtrTy, DynamicTop) : StaticTop;

458 IRB.CreateStore(CurrentTop, UnsafeStackPtr);

459 }

460

461 return DynamicTop;

462}

463

468

473 FailureProb.getNumerator());

477

479 F.getParent()->getOrInsertFunction("__stack_chk_fail", IRB.getVoidTy());

480 IRBFail.CreateCall(StackChkFail, {});

481}

482

483

484

485

486Value *SafeStack::moveStaticAllocasToUnsafeStack(

490 if (StaticAllocas.empty() && ByValArguments.empty())

491 return BasePointer;

492

494

495 StackLifetime SSC(F, StaticAllocas, StackLifetime::LivenessType::May);

498 SSC.run();

499

500 for (const auto *I : SSC.getMarkers()) {

501 auto *Op = dyn_cast(I->getOperand(1));

503

504 if (Op && Op->use_empty())

505 Op->eraseFromParent();

506 }

507

508

510 if (StackGuardSlot) {

513 SSL.addObject(StackGuardSlot, getStaticAllocaAllocationSize(StackGuardSlot),

514 Align, SSC.getFullLiveRange());

515 }

516

517 for (Argument *Arg : ByValArguments) {

518 Type *Ty = Arg->getParamByValType();

520 if (Size == 0)

521 Size = 1;

522

523

525 if (auto A = Arg->getParamAlign())

527 SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange());

528 }

529

530 for (AllocaInst *AI : StaticAllocas) {

532 uint64_t Size = getStaticAllocaAllocationSize(AI);

533 if (Size == 0)

534 Size = 1;

535

536

538

540 ClColoring ? SSC.getLiveRange(AI) : NoColoringRange);

541 }

542

543 SSL.computeLayout();

544 Align FrameAlignment = SSL.getFrameAlignment();

545

546

547

548 if (FrameAlignment > StackAlignment) {

549

554 ConstantInt::get(IntPtrTy, ~(FrameAlignment.value() - 1))),

555 StackPtrTy));

556 }

557

559

560 if (StackGuardSlot) {

561 unsigned Offset = SSL.getObjectOffset(StackGuardSlot);

566

567

570 }

571

572 for (Argument *Arg : ByValArguments) {

573 unsigned Offset = SSL.getObjectOffset(Arg);

575 Type *Ty = Arg->getParamByValType();

576

578 if (Size == 0)

579 Size = 1;

580

584 Arg->getName() + ".unsafe-byval");

585

586

589 Arg->replaceAllUsesWith(NewArg);

592 }

593

594

595 for (AllocaInst *AI : StaticAllocas) {

597 unsigned Offset = SSL.getObjectOffset(AI);

598

601

602

603

604 std::string Name = std::string(AI->getName()) + ".unsafe";

608

610 if (auto *PHI = dyn_cast(User))

611 InsertBefore = PHI->getIncomingBlock(U)->getTerminator();

612 else

613 InsertBefore = User;

614

617 IRBUser.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -Offset));

618 Value *Replacement =

619 IRBUser.CreateAddrSpaceCast(Off, AI->getType(), Name);

620

621 if (auto *PHI = dyn_cast(User))

622

623

624 PHI->setIncomingValueForBlock(PHI->getIncomingBlock(U), Replacement);

625 else

626 U.set(Replacement);

627 }

628

630 }

631

632

633

634

635 unsigned FrameSize = alignTo(SSL.getFrameSize(), StackAlignment);

636

639 Data.push_back(MDB.createString("unsafe-stack-size"));

640 Data.push_back(MDB.createConstant(ConstantInt::get(Int32Ty, FrameSize)));

642 F.setMetadata(LLVMContext::MD_annotation, MD);

643

644

646

647 Value *StaticTop =

648 IRB.CreatePtrAdd(BasePointer, ConstantInt::get(Int32Ty, -FrameSize),

649 "unsafe_stack_static_top");

650 IRB.CreateStore(StaticTop, UnsafeStackPtr);

651 return StaticTop;

652}

653

654void SafeStack::moveDynamicAllocasToUnsafeStack(

658

659 for (AllocaInst *AI : DynamicAllocas) {

661

662

664 if (ArraySize->getType() != IntPtrTy)

665 ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false);

666

668 uint64_t TySize = DL.getTypeAllocSize(Ty);

669 Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize));

670

672 IntPtrTy);

674

675

676 auto Align = std::max(std::max(DL.getPrefTypeAlign(Ty), AI->getAlign()),

677 StackAlignment);

678

682 StackPtrTy);

683

684

686 if (DynamicTop)

688

690 if (AI->hasName() && isa(NewAI))

692

696 }

697

698 if (!DynamicAllocas.empty()) {

699

701 auto *II = dyn_cast(&I);

702 if (II)

703 continue;

704

705 if (II->getIntrinsicID() == Intrinsic::stacksave) {

709 II->replaceAllUsesWith(LI);

710 II->eraseFromParent();

711 } else if (II->getIntrinsicID() == Intrinsic::stackrestore) {

714 SI->takeName(II);

716 II->eraseFromParent();

717 }

718 }

719 }

720}

721

722bool SafeStack::ShouldInlinePointerAddress(CallInst &CI) {

724 if (CI.hasFnAttr(Attribute::AlwaysInline) &&

726 return true;

727 if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) ||

729 return false;

730 return true;

731}

732

733void SafeStack::TryInlinePointerAddress() {

734 auto *CI = dyn_cast(UnsafeStackPtr);

735 if (!CI)

736 return;

737

738 if(F.hasOptNone())

739 return;

740

742 if (!Callee || Callee->isDeclaration())

743 return;

744

745 if (!ShouldInlinePointerAddress(*CI))

746 return;

747

750}

751

752bool SafeStack::run() {

753 assert(F.hasFnAttribute(Attribute::SafeStack) &&

754 "Can't run SafeStack on a function without the attribute");

755 assert(F.isDeclaration() && "Can't run SafeStack on a function declaration");

756

757 ++NumFunctions;

758

763

764

765

766

767

768

770

771

772

773 findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns,

774 StackRestorePoints);

775

776 if (StaticAllocas.empty() && DynamicAllocas.empty() &&

777 ByValArguments.empty() && StackRestorePoints.empty())

778 return false;

779

780 if (!StaticAllocas.empty() || !DynamicAllocas.empty() ||

781 !ByValArguments.empty())

782 ++NumUnsafeStackFunctions;

783

784 if (!StackRestorePoints.empty())

785 ++NumUnsafeStackRestorePointsFunctions;

786

787 IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());

788

789

792 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));

795 "__safestack_pointer_address", IRB.getPtrTy(0));

797 } else {

798 UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB);

799 }

800

801

802

804 IRB.CreateLoad(StackPtrTy, UnsafeStackPtr, false, "unsafe_stack_ptr");

806

807 AllocaInst *StackGuardSlot = nullptr;

808

809 if (F.hasFnAttribute(Attribute::StackProtect) ||

810 F.hasFnAttribute(Attribute::StackProtectStrong) ||

811 F.hasFnAttribute(Attribute::StackProtectReq)) {

813 StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr);

814 IRB.CreateStore(StackGuard, StackGuardSlot);

815

818 checkStackGuard(IRBRet, F, *RI, StackGuardSlot, StackGuard);

819 }

820 }

821

822

823

824 Value *StaticTop = moveStaticAllocasToUnsafeStack(

825 IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot);

826

827

828

829

830

831

832

833 AllocaInst *DynamicTop = createStackRestorePoints(

834 IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());

835

836

837 moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop,

838 DynamicAllocas);

839

840

843 IRB.CreateStore(BasePointer, UnsafeStackPtr);

844 }

845

846 TryInlinePointerAddress();

847

848 LLVM_DEBUG(dbgs() << "[SafeStack] safestack applied\n");

849 return true;

850}

851

852class SafeStackLegacyPass : public FunctionPass {

854

855public:

856 static char ID;

857

860 }

861

867 }

868

870 LLVM_DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");

871

872 if (F.hasFnAttribute(Attribute::SafeStack)) {

873 LLVM_DEBUG(dbgs() << "[SafeStack] safestack is not requested"

874 " for this function\n");

875 return false;

876 }

877

878 if (F.isDeclaration()) {

879 LLVM_DEBUG(dbgs() << "[SafeStack] function definition"

880 " is not available\n");

881 return false;

882 }

883

884 TM = &getAnalysis().getTM<TargetMachine>();

885 auto *TL = TM->getSubtargetImpl(F)->getTargetLowering();

886 if (!TL)

888

889 auto *DL = &F.getDataLayout();

890 auto &TLI = getAnalysis().getTLI(F);

891 auto &ACT = getAnalysis().getAssumptionCache(F);

892

893

894

895

896

898 bool ShouldPreserveDominatorTree;

899 std::optional LazilyComputedDomTree;

900

901

902

903

904 if (auto *DTWP = getAnalysisIfAvailable()) {

905 DT = &DTWP->getDomTree();

906 ShouldPreserveDominatorTree = true;

907 } else {

908

909 LazilyComputedDomTree.emplace(F);

910 DT = &*LazilyComputedDomTree;

911 ShouldPreserveDominatorTree = false;

912 }

913

914

916

917 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);

918

920

921 return SafeStack(F, *TL, *DL, ShouldPreserveDominatorTree ? &DTU : nullptr,

922 SE)

923 .run();

924 }

925};

926

927}

928

931 LLVM_DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");

932

933 if (F.hasFnAttribute(Attribute::SafeStack)) {

934 LLVM_DEBUG(dbgs() << "[SafeStack] safestack is not requested"

935 " for this function\n");

937 }

938

939 if (F.isDeclaration()) {

940 LLVM_DEBUG(dbgs() << "[SafeStack] function definition"

941 " is not available\n");

943 }

944

945 auto *TL = TM->getSubtargetImpl(F)->getTargetLowering();

946 if (!TL)

948

949 auto &DL = F.getDataLayout();

950

951

954 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);

955

956 bool Changed = SafeStack(F, *TL, DL, &DTU, SE).run();

957

958 if (!Changed)

962 return PA;

963}

964

965char SafeStackLegacyPass::ID = 0;

966

968 "Safe Stack instrumentation pass", false, false)

973

This file implements a class to represent arbitrary precision integral constant values and operations...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

VarLocInsertPt getNextNode(const DbgRecord *DVR)

Expand Atomic instructions

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

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

global merge Global merge function pass

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

This defines the Use class.

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

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

static cl::opt< bool > SafeStackUsePointerAddress("safestack-use-pointer-address", cl::init(false), cl::Hidden)

Use __safestack_pointer_address even if the platform has a faster way of access safe stack pointer.

static cl::opt< bool > ClColoring("safe-stack-coloring", cl::desc("enable safe stack coloring"), cl::Hidden, cl::init(true))

This file defines the SmallPtrSet class.

This file defines the SmallVector class.

static Value * getStackGuard(const TargetLoweringBase *TLI, Module *M, IRBuilder<> &B, bool *SupportsSelectionDAGSP=nullptr)

Create a stack guard loading and populate whether SelectionDAG SSP is supported.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

This file describes how to lower LLVM code to machine code.

Target-Independent Code Generator Pass Configuration Options pass.

Class for arbitrary precision integers.

an instruction to allocate memory on the stack

bool isStaticAlloca() const

Return true if this alloca is in the entry block of the function and is a constant size.

Align getAlign() const

Return the alignment of the memory that is being allocated by the instruction.

PointerType * getType() const

Overload to return most specific pointer type.

Type * getAllocatedType() const

Return the type that is being allocated by the instruction.

bool isArrayAllocation() const

Return true if there is an allocation size parameter to the allocation instruction that is not 1.

const Value * getArraySize() const

Get the number of elements allocated.

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

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

This class represents an incoming formal argument to a Function.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool empty() const

empty - Check if the array is empty.

An immutable pass that tracks lazily created AssumptionCache objects.

static BranchProbability getBranchProbStackProtector(bool IsLikely)

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

bool doesNotCapture(unsigned OpNo) const

Determine whether this data operand is not captured.

Function * getCalledFunction() const

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

bool doesNotAccessMemory(unsigned OpNo) const

bool hasFnAttr(Attribute::AttrKind Kind) const

Determine whether this call has the given attribute.

User::op_iterator arg_begin()

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

bool isNoInline() const

Return true if the call should not be inlined.

User::op_iterator arg_end()

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

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

This class represents a range of values.

ConstantRange add(const ConstantRange &Other) const

Return a new range representing the possible values resulting from an addition of a value in this ran...

bool contains(const APInt &Val) const

Return true if the specified value is in the set.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

Analysis pass which computes a DominatorTree.

Legacy analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...

FunctionPass class - This class is used to implement most global optimizations.

virtual bool runOnFunction(Function &F)=0

runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.

AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")

Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")

Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")

Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())

void SetCurrentDebugLocation(DebugLoc L)

Set location information used by debugging information.

Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")

CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with Args, mangled using Types.

Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")

LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)

Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...

Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")

StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)

Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")

CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)

PointerType * getPtrTy(unsigned AddrSpace=0)

Fetch the type representing a pointer.

Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

Type * getVoidTy()

Fetch the type representing void.

CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)

Create and insert a memcpy between the specified pointers.

Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

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

This class captures the data input to the InlineFunction call, and records the auxiliary results prod...

InstListType::iterator eraseFromParent()

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

A wrapper class for inspecting calls to intrinsic functions.

MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)

Return metadata containing two branch weights.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

This is the common base class for memset/memcpy/memmove.

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

virtual void getAnalysisUsage(AnalysisUsage &) const

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

void preserve()

Mark an analysis as preserved.

This class represents an analyzed expression in the program.

Type * getType() const

Return the LLVM type of this SCEV expression.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)

Analysis pass that exposes the ScalarEvolution for a function.

The main scalar evolution driver.

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 push_back(const T &Elt)

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

This class represents a set of interesting instructions where an alloca is live.

Compute live ranges of allocas.

This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...

Primary interface to the complete machine description for the target machine.

Target-Independent Code Generator Pass Configuration Options.

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

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

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.

LLVMContext & getContext() const

All values hold a context through their type.

StringRef getName() const

Return a constant reference to the value's name.

void takeName(Value *V)

Transfer the name from V to this value.

NodeTy * getNextNode()

Get the next node, or nullptr for the list tail.

Compute the layout of an unsafe stack frame.

@ C

The default llvm calling convention, compatible with C.

unsigned ID

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

initializer< Ty > init(const Ty &Val)

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

This is an optimization pass for GlobalISel generic memory operations.

FunctionPass * createSafeStackPass()

This pass splits the stack into a safe stack and an unsafe stack to protect against stack-based overf...

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

InlineResult isInlineViable(Function &Callee)

Minimal filter to detect invalid constructs for inlining.

raw_ostream & dbgs()

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

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

void initializeSafeStackLegacyPassPass(PassRegistry &)

InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, bool MergeAttributes=false, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, Function *ForwardVarArgsTo=nullptr)

This function inlines the called function into the basic block of the caller.

void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, int Offset=0)

Replaces multiple llvm.dbg.value instructions when the alloca it describes is replaced with a new val...

constexpr unsigned BitWidth

Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)

Split the containing block at the specified instruction - everything before SplitBefore stays in the ...

bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset)

Replaces llvm.dbg.declare instruction when the address it describes is replaced with a new value.

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t value() const

This is a hole in the type system and should not be abused.

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.