Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Analysis/CaptureTracking.cpp
Show All 20 Lines | |||||
#include "llvm/ADT/Statistic.h" | #include "llvm/ADT/Statistic.h" | ||||
#include "llvm/Analysis/AliasAnalysis.h" | #include "llvm/Analysis/AliasAnalysis.h" | ||||
#include "llvm/Analysis/CFG.h" | #include "llvm/Analysis/CFG.h" | ||||
#include "llvm/Analysis/ValueTracking.h" | #include "llvm/Analysis/ValueTracking.h" | ||||
#include "llvm/IR/Constants.h" | #include "llvm/IR/Constants.h" | ||||
#include "llvm/IR/Dominators.h" | #include "llvm/IR/Dominators.h" | ||||
#include "llvm/IR/Instructions.h" | #include "llvm/IR/Instructions.h" | ||||
#include "llvm/IR/IntrinsicInst.h" | #include "llvm/IR/IntrinsicInst.h" | ||||
#include "llvm/IR/Intrinsics.h" | |||||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | ||||
using namespace llvm; | using namespace llvm; | ||||
#define DEBUG_TYPE "capture-tracking" | #define DEBUG_TYPE "capture-tracking" | ||||
STATISTIC(NumCaptured, "Number of pointers maybe captured"); | STATISTIC(NumCaptured, "Number of pointers maybe captured"); | ||||
STATISTIC(NumNotCaptured, "Number of pointers not captured"); | STATISTIC(NumNotCaptured, "Number of pointers not captured"); | ||||
▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Lines | void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, | ||||
while (!Worklist.empty()) { | while (!Worklist.empty()) { | ||||
const Use *U = Worklist.pop_back_val(); | const Use *U = Worklist.pop_back_val(); | ||||
Instruction *I = cast<Instruction>(U->getUser()); | Instruction *I = cast<Instruction>(U->getUser()); | ||||
switch (I->getOpcode()) { | switch (I->getOpcode()) { | ||||
case Instruction::Call: | case Instruction::Call: | ||||
case Instruction::Invoke: { | case Instruction::Invoke: { | ||||
if (auto *II = dyn_cast<IntrinsicInst>(I)) | |||||
if (II->getIntrinsicID() == Intrinsic::noalias || | |||||
II->getIntrinsicID() == Intrinsic::provenance_noalias || | |||||
II->getIntrinsicID() == Intrinsic::noalias_arg_guard || | |||||
II->getIntrinsicID() == Intrinsic::noalias_copy_guard) { | |||||
AddUses(I); | |||||
break; | |||||
} | |||||
auto *Call = cast<CallBase>(I); | auto *Call = cast<CallBase>(I); | ||||
// Not captured if the callee is readonly, doesn't return a copy through | // Not captured if the callee is readonly, doesn't return a copy through | ||||
// its return value and doesn't unwind (a readonly function can leak bits | // its return value and doesn't unwind (a readonly function can leak bits | ||||
// by throwing an exception or not depending on the input value). | // by throwing an exception or not depending on the input value). | ||||
if (Call->onlyReadsMemory() && Call->doesNotThrow() && | if (Call->onlyReadsMemory() && Call->doesNotThrow() && | ||||
Call->getType()->isVoidTy()) | Call->getType()->isVoidTy()) | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 152 Lines • Show Last 20 Lines |