LLVM  6.0.0svn
TypeMetadataUtils.cpp
Go to the documentation of this file.
1 //===- TypeMetadataUtils.cpp - Utilities related to type metadata ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains functions that make it easier to manipulate type metadata
11 // for devirtualization.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Intrinsics.h"
18 #include "llvm/IR/Module.h"
19 
20 using namespace llvm;
21 
22 // Search for virtual calls that call FPtr and add them to DevirtCalls.
23 static void
25  bool *HasNonCallUses, Value *FPtr, uint64_t Offset) {
26  for (const Use &U : FPtr->uses()) {
27  Value *User = U.getUser();
28  if (isa<BitCastInst>(User)) {
29  findCallsAtConstantOffset(DevirtCalls, HasNonCallUses, User, Offset);
30  } else if (auto CI = dyn_cast<CallInst>(User)) {
31  DevirtCalls.push_back({Offset, CI});
32  } else if (auto II = dyn_cast<InvokeInst>(User)) {
33  DevirtCalls.push_back({Offset, II});
34  } else if (HasNonCallUses) {
35  *HasNonCallUses = true;
36  }
37  }
38 }
39 
40 // Search for virtual calls that load from VPtr and add them to DevirtCalls.
41 static void
44  Value *VPtr, int64_t Offset) {
45  for (const Use &U : VPtr->uses()) {
46  Value *User = U.getUser();
47  if (isa<BitCastInst>(User)) {
48  findLoadCallsAtConstantOffset(M, DevirtCalls, User, Offset);
49  } else if (isa<LoadInst>(User)) {
50  findCallsAtConstantOffset(DevirtCalls, nullptr, User, Offset);
51  } else if (auto GEP = dyn_cast<GetElementPtrInst>(User)) {
52  // Take into account the GEP offset.
53  if (VPtr == GEP->getPointerOperand() && GEP->hasAllConstantIndices()) {
54  SmallVector<Value *, 8> Indices(GEP->op_begin() + 1, GEP->op_end());
55  int64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType(
56  GEP->getSourceElementType(), Indices);
57  findLoadCallsAtConstantOffset(M, DevirtCalls, User, Offset + GEPOffset);
58  }
59  }
60  }
61 }
62 
65  SmallVectorImpl<CallInst *> &Assumes, const CallInst *CI) {
66  assert(CI->getCalledFunction()->getIntrinsicID() == Intrinsic::type_test);
67 
68  const Module *M = CI->getParent()->getParent()->getParent();
69 
70  // Find llvm.assume intrinsics for this llvm.type.test call.
71  for (const Use &CIU : CI->uses()) {
72  if (auto *AssumeCI = dyn_cast<CallInst>(CIU.getUser())) {
73  Function *F = AssumeCI->getCalledFunction();
74  if (F && F->getIntrinsicID() == Intrinsic::assume)
75  Assumes.push_back(AssumeCI);
76  }
77  }
78 
79  // If we found any, search for virtual calls based on %p and add them to
80  // DevirtCalls.
81  if (!Assumes.empty())
82  findLoadCallsAtConstantOffset(M, DevirtCalls,
83  CI->getArgOperand(0)->stripPointerCasts(), 0);
84 }
85 
89  SmallVectorImpl<Instruction *> &Preds, bool &HasNonCallUses,
90  const CallInst *CI) {
92  Intrinsic::type_checked_load);
93 
94  auto *Offset = dyn_cast<ConstantInt>(CI->getArgOperand(1));
95  if (!Offset) {
96  HasNonCallUses = true;
97  return;
98  }
99 
100  for (const Use &U : CI->uses()) {
101  auto CIU = U.getUser();
102  if (auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
103  if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
104  LoadedPtrs.push_back(EVI);
105  continue;
106  }
107  if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
108  Preds.push_back(EVI);
109  continue;
110  }
111  }
112  HasNonCallUses = true;
113  }
114 
115  for (Value *LoadedPtr : LoadedPtrs)
116  findCallsAtConstantOffset(DevirtCalls, &HasNonCallUses, LoadedPtr,
117  Offset->getZExtValue());
118 }
iterator_range< use_iterator > uses()
Definition: Value.h:356
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
static void findLoadCallsAtConstantOffset(const Module *M, SmallVectorImpl< DevirtCallSite > &DevirtCalls, Value *VPtr, int64_t Offset)
This class represents a function call, abstracting a target machine&#39;s calling convention.
F(f)
Hexagon Common GEP
void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst *> &Assumes, const CallInst *CI)
Given a call to the intrinsic .type.test, find all devirtualizable call sites based on the call and r...
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:361
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
static void findCallsAtConstantOffset(SmallVectorImpl< DevirtCallSite > &DevirtCalls, bool *HasNonCallUses, Value *FPtr, uint64_t Offset)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
Definition: Value.cpp:558
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
void findDevirtualizableCallsForTypeCheckedLoad(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< Instruction *> &LoadedPtrs, SmallVectorImpl< Instruction *> &Preds, bool &HasNonCallUses, const CallInst *CI)
Given a call to the intrinsic .type.checked.load, find all devirtualizable call sites based on the ca...
Module.h This file contains the declarations for the Module class.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:175
Function * getCalledFunction() const
Return the function called, or null if this is an indirect function invocation.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:108
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:556
LLVM Value Representation.
Definition: Value.h:73
int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef< Value *> Indices) const
Returns the offset from the beginning of the type for the specified indices.
Definition: DataLayout.cpp:729
const BasicBlock * getParent() const
Definition: Instruction.h:66