diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2016-05-10 18:07:21 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-05-10 18:07:21 +0000 |
commit | ccdc225c27f2534d2f204c303421c7e68ab8de70 (patch) | |
tree | fc83513389a65e3ec3a37e28d596dcdd69343732 /llvm/lib/Analysis | |
parent | b68f16e007b1b29ed1b9afc18f5ff645b2232174 (diff) | |
download | bcm5719-llvm-ccdc225c27f2534d2f204c303421c7e68ab8de70.tar.gz bcm5719-llvm-ccdc225c27f2534d2f204c303421c7e68ab8de70.zip |
Re-apply r269081 and r269082 with a fix for MSVC.
llvm-svn: 269094
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/BitSetUtils.cpp | 82 | ||||
-rw-r--r-- | llvm/lib/Analysis/CMakeLists.txt | 1 |
2 files changed, 83 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/BitSetUtils.cpp b/llvm/lib/Analysis/BitSetUtils.cpp new file mode 100644 index 00000000000..d83dca60cce --- /dev/null +++ b/llvm/lib/Analysis/BitSetUtils.cpp @@ -0,0 +1,82 @@ +//===- BitSetUtils.cpp - Utilities related to pointer bitsets -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains functions that make it easier to manipulate bitsets for +// devirtualization. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/BitSetUtils.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" + +using namespace llvm; + +// Search for virtual calls that call FPtr and add them to DevirtCalls. +static void +findCallsAtConstantOffset(SmallVectorImpl<DevirtCallSite> &DevirtCalls, + Value *FPtr, uint64_t Offset) { + for (const Use &U : FPtr->uses()) { + Value *User = U.getUser(); + if (isa<BitCastInst>(User)) { + findCallsAtConstantOffset(DevirtCalls, User, Offset); + } else if (auto CI = dyn_cast<CallInst>(User)) { + DevirtCalls.push_back({Offset, CI}); + } else if (auto II = dyn_cast<InvokeInst>(User)) { + DevirtCalls.push_back({Offset, II}); + } + } +} + +// Search for virtual calls that load from VPtr and add them to DevirtCalls. +static void +findLoadCallsAtConstantOffset(Module *M, + SmallVectorImpl<DevirtCallSite> &DevirtCalls, + Value *VPtr, uint64_t Offset) { + for (const Use &U : VPtr->uses()) { + Value *User = U.getUser(); + if (isa<BitCastInst>(User)) { + findLoadCallsAtConstantOffset(M, DevirtCalls, User, Offset); + } else if (isa<LoadInst>(User)) { + findCallsAtConstantOffset(DevirtCalls, User, Offset); + } else if (auto GEP = dyn_cast<GetElementPtrInst>(User)) { + // Take into account the GEP offset. + if (VPtr == GEP->getPointerOperand() && GEP->hasAllConstantIndices()) { + SmallVector<Value *, 8> Indices(GEP->op_begin() + 1, GEP->op_end()); + uint64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType( + GEP->getSourceElementType(), Indices); + findLoadCallsAtConstantOffset(M, DevirtCalls, User, Offset + GEPOffset); + } + } + } +} + +void llvm::findDevirtualizableCalls( + SmallVectorImpl<DevirtCallSite> &DevirtCalls, + SmallVectorImpl<CallInst *> &Assumes, CallInst *CI) { + assert(CI->getCalledFunction()->getIntrinsicID() == Intrinsic::bitset_test); + + Module *M = CI->getParent()->getParent()->getParent(); + + // Find llvm.assume intrinsics for this llvm.bitset.test call. + for (const Use &CIU : CI->uses()) { + auto AssumeCI = dyn_cast<CallInst>(CIU.getUser()); + if (AssumeCI) { + Function *F = AssumeCI->getCalledFunction(); + if (F && F->getIntrinsicID() == Intrinsic::assume) + Assumes.push_back(AssumeCI); + } + } + + // If we found any, search for virtual calls based on %p and add them to + // DevirtCalls. + if (!Assumes.empty()) + findLoadCallsAtConstantOffset(M, DevirtCalls, + CI->getArgOperand(0)->stripPointerCasts(), 0); +} diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt index 0ec27443d8a..c598d9e4971 100644 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -5,6 +5,7 @@ add_llvm_library(LLVMAnalysis Analysis.cpp AssumptionCache.cpp BasicAliasAnalysis.cpp + BitSetUtils.cpp BlockFrequencyInfo.cpp BlockFrequencyInfoImpl.cpp BranchProbabilityInfo.cpp |