LLVM: lib/Transforms/Utils/GuardUtils.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

21

22using namespace llvm;

24

27 cl::desc("The probability of a guard failing is assumed to be the "

28 "reciprocal of this value (default = 1 << 20)"));

29

31 CallInst *Guard, bool UseWC) {

34

35 auto *CheckBB = Guard->getParent();

36 auto *DeoptBlockTerm =

38

39 auto *CheckBI = cast(CheckBB->getTerminator());

40

41

42

43 CheckBI->swapSuccessors();

44

45 CheckBI->getSuccessor(0)->setName("guarded");

46 CheckBI->getSuccessor(1)->setName("deopt");

47

48 if (auto *MD = Guard->getMetadata(LLVMContext::MD_make_implicit))

49 CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD);

50

52 CheckBI->setMetadata(LLVMContext::MD_prof,

54

56 auto *DeoptCall = B.CreateCall(DeoptIntrinsic, Args, {DeoptOB}, "");

57

59 B.CreateRetVoid();

60 } else {

61 DeoptCall->setName("deoptcall");

62 B.CreateRet(DeoptCall);

63 }

64

66 DeoptBlockTerm->eraseFromParent();

67

68 if (UseWC) {

69

70

71

73 auto *WC = B.CreateIntrinsic(Intrinsic::experimental_widenable_condition,

74 {}, {}, nullptr, "widenable_cond");

75 CheckBI->setCondition(B.CreateAnd(CheckBI->getCondition(), WC,

76 "exiplicit_guard_cond"));

78 }

79}

80

81

84

85

86

87

88

89

93 if (C) {

94

96 WidenableBR->setCondition(B.CreateAnd(NewCond, WC->get()));

97 } else {

98

100 C->set(B.CreateAnd(NewCond, C->get()));

102

104 }

106}

107

110

114 if (C) {

115

117 WidenableBR->setCondition(B.CreateAnd(NewCond, WC->get()));

118 } else {

119

121

123 C->set(NewCond);

124 }

126}

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

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

static cl::opt< uint32_t > PredicatePassBranchWeight("guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1<< 20), cl::desc("The probability of a guard failing is assumed to be the " "reciprocal of this value (default = 1 << 20)"))

LLVM Basic Block Representation.

Conditional or Unconditional Branch instruction.

void setCondition(Value *V)

Value * getCondition() const

std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const

Return an operand bundle by name, if present.

CallingConv::ID getCallingConv() const

Value * getArgOperand(unsigned i) const

iterator_range< User::op_iterator > args()

Iteration adapter for range-for loops.

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

Type * getReturnType() const

Returns the type of the ret val.

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

MDNode * getMetadata(unsigned KindID) const

Get the metadata of given kind attached to this Instruction.

void moveBefore(Instruction *MovePos)

Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...

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

Return metadata containing two branch weights.

A container for an operand bundle being viewed as a set of values rather than a set of uses.

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

bool isVoidTy() const

Return true if this is 'void'.

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

LLVM Value Representation.

LLVMContext & getContext() const

All values hold a context through their type.

const ParentTy * getParent() const

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

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

void makeGuardControlFlowExplicit(Function *DeoptIntrinsic, CallInst *Guard, bool UseWC)

Splits control flow at point of Guard, replacing it with explicit branch by the condition of guard's ...

void widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond)

Given a branch we know is widenable (defined per Analysis/GuardUtils.h), widen it such that condition...

void setWidenableBranchCond(BranchInst *WidenableBR, Value *Cond)

Given a branch we know is widenable (defined per Analysis/GuardUtils.h), set it's condition such that...

bool parseWidenableBranch(const User *U, Value *&Condition, Value *&WidenableCondition, BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB)

If U is widenable branch looking like: cond = ... wc = call i1 @llvm.experimental....

bool isWidenableBranch(const User *U)

Returns true iff U is a widenable branch (that is, extractWidenableCondition returns widenable condit...

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