15 #ifndef LLVM_ANALYSIS_CFLGRAPH_H
16 #define LLVM_ANALYSIS_CFLGRAPH_H
54 std::vector<NodeInfo> Levels;
58 auto NumLevels = Levels.size();
59 if (NumLevels > Level)
61 Levels.resize(Level + 1);
66 assert(Level < Levels.size());
70 assert(Level < Levels.size());
81 NodeInfo *getNode(
Node N) {
82 auto Itr = ValueImpls.
find(N.Val);
83 if (Itr == ValueImpls.
end() || Itr->second.getNumLevels() <= N.DerefLevel)
85 return &Itr->second.getNodeInfoAtLevel(N.DerefLevel);
93 auto &ValInfo = ValueImpls[N.
Val];
94 auto Changed = ValInfo.addNodeToLevel(N.
DerefLevel);
95 ValInfo.getNodeInfoAtLevel(N.
DerefLevel).Attr |= Attr;
100 auto *Info = getNode(N);
106 auto *FromInfo = getNode(From);
107 assert(FromInfo !=
nullptr);
108 auto *ToInfo = getNode(To);
109 assert(ToInfo !=
nullptr);
112 ToInfo->ReverseEdges.push_back(
Edge{From,
Offset});
116 auto Itr = ValueImpls.
find(N.
Val);
117 if (Itr == ValueImpls.
end() || Itr->second.getNumLevels() <= N.
DerefLevel)
119 return &Itr->second.getNodeInfoAtLevel(N.
DerefLevel);
123 auto *Info = getNode(N);
129 return make_range<const_value_iterator>(ValueImpls.
begin(),
153 class GetEdgesVisitor :
public InstVisitor<GetEdgesVisitor, void> {
165 return CE->
getOpcode() != Instruction::ICmp &&
171 static bool getPossibleTargets(
CallSite CS,
186 if (
auto GVal = dyn_cast<GlobalValue>(Val)) {
190 }
else if (
auto CExpr = dyn_cast<ConstantExpr>(Val)) {
191 if (hasUsefulEdges(CExpr)) {
193 visitConstantExpr(CExpr);
200 assert(From !=
nullptr && To !=
nullptr);
211 void addDerefEdge(Value *From, Value *To,
bool IsRead) {
212 assert(From !=
nullptr && To !=
nullptr);
213 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
218 Graph.addNode(InstantiatedValue{From, 1});
219 Graph.addEdge(InstantiatedValue{From, 1}, InstantiatedValue{To, 0});
221 Graph.addNode(InstantiatedValue{To, 1});
222 Graph.addEdge(InstantiatedValue{From, 0}, InstantiatedValue{To, 1});
226 void addLoadEdge(Value *From, Value *To) { addDerefEdge(From, To,
true); }
227 void addStoreEdge(Value *From, Value *To) { addDerefEdge(From, To,
false); }
230 GetEdgesVisitor(CFLGraphBuilder &Builder,
const DataLayout &DL)
231 : AA(Builder.
Analysis), DL(DL), TLI(Builder.TLI), Graph(Builder.Graph),
232 ReturnValues(Builder.ReturnedValues) {}
234 void visitInstruction(Instruction &) {
238 void visitReturnInst(ReturnInst &Inst) {
239 if (
auto RetVal = Inst.getReturnValue()) {
240 if (RetVal->getType()->isPointerTy()) {
242 ReturnValues.push_back(RetVal);
247 void visitPtrToIntInst(PtrToIntInst &Inst) {
248 auto *
Ptr = Inst.getOperand(0);
252 void visitIntToPtrInst(IntToPtrInst &Inst) {
257 void visitCastInst(CastInst &Inst) {
258 auto *Src = Inst.getOperand(0);
259 addAssignEdge(Src, &Inst);
262 void visitBinaryOperator(BinaryOperator &Inst) {
263 auto *Op1 = Inst.getOperand(0);
264 auto *Op2 = Inst.getOperand(1);
265 addAssignEdge(Op1, &Inst);
266 addAssignEdge(Op2, &Inst);
269 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
270 auto *
Ptr = Inst.getPointerOperand();
271 auto *Val = Inst.getNewValOperand();
272 addStoreEdge(Val,
Ptr);
275 void visitAtomicRMWInst(AtomicRMWInst &Inst) {
276 auto *
Ptr = Inst.getPointerOperand();
277 auto *Val = Inst.getValOperand();
278 addStoreEdge(Val,
Ptr);
281 void visitPHINode(PHINode &Inst) {
282 for (Value *Val : Inst.incoming_values())
283 addAssignEdge(Val, &Inst);
286 void visitGEP(GEPOperator &GEPOp) {
288 APInt APOffset(
DL.getPointerSizeInBits(GEPOp.getPointerAddressSpace()),
290 if (GEPOp.accumulateConstantOffset(DL, APOffset))
291 Offset = APOffset.getSExtValue();
293 auto *
Op = GEPOp.getPointerOperand();
294 addAssignEdge(
Op, &GEPOp, Offset);
297 void visitGetElementPtrInst(GetElementPtrInst &Inst) {
298 auto *GEPOp = cast<GEPOperator>(&Inst);
302 void visitSelectInst(SelectInst &Inst) {
308 auto *TrueVal = Inst.getTrueValue();
309 auto *FalseVal = Inst.getFalseValue();
310 addAssignEdge(TrueVal, &Inst);
311 addAssignEdge(FalseVal, &Inst);
314 void visitAllocaInst(AllocaInst &Inst) { addNode(&Inst); }
316 void visitLoadInst(LoadInst &Inst) {
317 auto *
Ptr = Inst.getPointerOperand();
319 addLoadEdge(
Ptr, Val);
322 void visitStoreInst(StoreInst &Inst) {
323 auto *
Ptr = Inst.getPointerOperand();
324 auto *Val = Inst.getValueOperand();
325 addStoreEdge(Val,
Ptr);
328 void visitVAArgInst(VAArgInst &Inst) {
337 if (Inst.getType()->isPointerTy())
341 static bool isFunctionExternal(Function *Fn) {
342 return !Fn->hasExactDefinition();
345 bool tryInterproceduralAnalysis(CallSite CS,
346 const SmallVectorImpl<Function *> &Fns) {
353 for (
auto *Fn : Fns) {
354 if (isFunctionExternal(Fn) || Fn->isVarArg())
357 assert(Fn->arg_size() <= CS.arg_size());
358 if (!AA.getAliasSummary(*Fn))
362 for (
auto *Fn : Fns) {
363 auto Summary = AA.getAliasSummary(*Fn);
364 assert(Summary !=
nullptr);
366 auto &RetParamRelations = Summary->RetParamRelations;
367 for (
auto &Relation : RetParamRelations) {
369 if (IRelation.hasValue()) {
370 Graph.addNode(IRelation->From);
371 Graph.addNode(IRelation->To);
372 Graph.addEdge(IRelation->From, IRelation->To);
376 auto &RetParamAttributes = Summary->RetParamAttributes;
377 for (
auto &
Attribute : RetParamAttributes) {
379 if (IAttr.hasValue())
380 Graph.addNode(IAttr->IValue, IAttr->Attr);
387 void visitCallSite(CallSite CS) {
388 auto Inst = CS.getInstruction();
391 for (Value *V : CS.args())
392 if (V->getType()->isPointerTy())
394 if (Inst->getType()->isPointerTy())
410 SmallVector<Function *, 4> Targets;
411 if (getPossibleTargets(CS, Targets))
412 if (tryInterproceduralAnalysis(CS, Targets))
419 if (!CS.onlyReadsMemory())
420 for (Value *V : CS.args()) {
421 if (V->getType()->isPointerTy()) {
431 if (Inst->getType()->isPointerTy()) {
432 auto *Fn = CS.getCalledFunction();
433 if (Fn ==
nullptr || !Fn->doesNotAlias(0))
444 void visitExtractElementInst(ExtractElementInst &Inst) {
445 auto *
Ptr = Inst.getVectorOperand();
447 addLoadEdge(
Ptr, Val);
450 void visitInsertElementInst(InsertElementInst &Inst) {
451 auto *Vec = Inst.getOperand(0);
452 auto *Val = Inst.getOperand(1);
453 addAssignEdge(Vec, &Inst);
454 addStoreEdge(Val, &Inst);
457 void visitLandingPadInst(LandingPadInst &Inst) {
461 if (Inst.getType()->isPointerTy())
465 void visitInsertValueInst(InsertValueInst &Inst) {
466 auto *Agg = Inst.getOperand(0);
467 auto *Val = Inst.getOperand(1);
468 addAssignEdge(Agg, &Inst);
469 addStoreEdge(Val, &Inst);
472 void visitExtractValueInst(ExtractValueInst &Inst) {
473 auto *
Ptr = Inst.getAggregateOperand();
474 addLoadEdge(
Ptr, &Inst);
477 void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
478 auto *From1 = Inst.getOperand(0);
479 auto *From2 = Inst.getOperand(1);
480 addAssignEdge(From1, &Inst);
481 addAssignEdge(From2, &Inst);
484 void visitConstantExpr(ConstantExpr *CE) {
485 switch (CE->getOpcode()) {
486 case Instruction::GetElementPtr: {
487 auto GEPOp = cast<GEPOperator>(CE);
491 case Instruction::PtrToInt: {
492 auto *
Ptr = CE->getOperand(0);
496 case Instruction::IntToPtr: {
500 case Instruction::BitCast:
501 case Instruction::AddrSpaceCast:
502 case Instruction::Trunc:
503 case Instruction::ZExt:
504 case Instruction::SExt:
505 case Instruction::FPExt:
506 case Instruction::FPTrunc:
507 case Instruction::UIToFP:
508 case Instruction::SIToFP:
509 case Instruction::FPToUI:
510 case Instruction::FPToSI: {
511 auto *Src = CE->getOperand(0);
512 addAssignEdge(Src, CE);
516 auto *TrueVal = CE->getOperand(0);
517 auto *FalseVal = CE->getOperand(1);
518 addAssignEdge(TrueVal, CE);
519 addAssignEdge(FalseVal, CE);
522 case Instruction::InsertElement: {
523 auto *Vec = CE->getOperand(0);
524 auto *Val = CE->getOperand(1);
525 addAssignEdge(Vec, CE);
526 addStoreEdge(Val, CE);
529 case Instruction::ExtractElement: {
530 auto *
Ptr = CE->getOperand(0);
531 addLoadEdge(
Ptr, CE);
534 case Instruction::InsertValue: {
535 auto *Agg = CE->getOperand(0);
536 auto *Val = CE->getOperand(1);
537 addAssignEdge(Agg, CE);
538 addStoreEdge(Val, CE);
541 case Instruction::ExtractValue: {
542 auto *
Ptr = CE->getOperand(0);
543 addLoadEdge(
Ptr, CE);
545 case Instruction::ShuffleVector: {
546 auto *From1 = CE->getOperand(0);
547 auto *From2 = CE->getOperand(1);
548 addAssignEdge(From1, CE);
549 addAssignEdge(From2, CE);
553 case Instruction::Sub:
554 case Instruction::FSub:
555 case Instruction::Mul:
556 case Instruction::FMul:
557 case Instruction::UDiv:
558 case Instruction::SDiv:
559 case Instruction::FDiv:
560 case Instruction::URem:
561 case Instruction::SRem:
562 case Instruction::FRem:
566 case Instruction::Shl:
567 case Instruction::LShr:
568 case Instruction::AShr:
569 case Instruction::ICmp:
570 case Instruction::FCmp: {
571 addAssignEdge(CE->getOperand(0), CE);
572 addAssignEdge(CE->getOperand(1), CE);
585 static bool hasUsefulEdges(Instruction *Inst) {
586 bool IsNonInvokeRetTerminator = isa<TerminatorInst>(Inst) &&
587 !isa<InvokeInst>(Inst) &&
588 !isa<ReturnInst>(Inst);
589 return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
590 !IsNonInvokeRetTerminator;
593 void addArgumentToGraph(Argument &Arg) {
594 if (Arg.getType()->isPointerTy()) {
595 Graph.addNode(InstantiatedValue{&Arg, 0},
608 void addInstructionToGraph(GetEdgesVisitor &Visitor, Instruction &Inst) {
609 if (!hasUsefulEdges(&Inst))
617 void buildGraphFrom(Function &Fn) {
618 GetEdgesVisitor Visitor(*
this, Fn.getParent()->getDataLayout());
620 for (
auto &Bb : Fn.getBasicBlockList())
621 for (
auto &Inst : Bb.getInstList())
622 addInstructionToGraph(Visitor, Inst);
624 for (
auto &Arg : Fn.args())
625 addArgumentToGraph(Arg);
630 : Analysis(Analysis), TLI(TLI) {
636 return ReturnedValues;
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
Base class for instruction visitors.
AliasAttrs attrFor(Node N) const
This is the result of instantiating InterfaceValue at a particular callsite.
The Program Expression Graph (PEG) of CFL analysis CFLGraph is auxiliary data structure used by CFL-b...
bool addNodeToLevel(unsigned Level)
iterator_range< const_value_iterator > value_mappings() const
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
const SmallVector< Value *, 4 > & getReturnValues() const
A constant value that is initialized with an expression using other constant values.
void addAttr(Node N, AliasAttrs Attr)
const NodeInfo & getNodeInfoAtLevel(unsigned Level) const
CFLGraphBuilder(CFLAA &Analysis, const TargetLibraryInfo &TLI, Function &Fn)
bool addNode(Node N, AliasAttrs Attr=AliasAttrs())
AliasAttrs getAttrEscaped()
AttrEscaped represent whether the said pointer comes from a known source but escapes to the unknown w...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
Optional< InstantiatedAttr > instantiateExternalAttribute(ExternalAttribute EAttr, CallSite CS)
const NodeInfo * getNode(Node N) const
bool isPointerTy() const
True if this is an instance of PointerType.
AliasAttrs getAttrUnknown()
AttrUnknown represent whether the said pointer comes from a source not known to alias analyses (such ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A builder class used to create CFLGraph instance from a given function The CFL-AA that uses this buil...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
void addEdge(Node From, Node To, int64_t Offset=0)
This file defines various utility types and functions useful to summary-based alias analysis...
A range adaptor for a pair of iterators.
ValueMap::const_iterator const_value_iterator
NodeInfo & getNodeInfoAtLevel(unsigned Level)
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates uninitialized memory (such ...
const CFLGraph & getCFLGraph() const
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
block Block Frequency Analysis
unsigned getNumLevels() const
static const int64_t UnknownOffset
AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val)
AttrGlobal represent whether the said pointer is a global value.
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates zero-filled memory (such as...
iterator find(const KeyT &Val)
std::bitset< NumAliasAttrs > AliasAttrs
These are attributes that an alias analysis can use to mark certain special properties of a given poi...
AliasAttrs getAttrCaller()
AttrCaller represent whether the said pointer comes from a source not known to the current function b...
std::vector< Edge > EdgeList
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
LLVM Value Representation.
Optional< InstantiatedRelation > instantiateExternalRelation(ExternalRelation ERelation, CallSite CS)
static const unsigned MaxSupportedArgsInSummary
The maximum number of arguments we can put into a summary.