1 //===- TypeMetadataUtils.h - Utilities related to type metadata --*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains functions that make it easier to manipulate type metadata 10 // for devirtualization. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ANALYSIS_TYPEMETADATAUTILS_H 15 #define LLVM_ANALYSIS_TYPEMETADATAUTILS_H 16 17 #include <cstdint> 18 #include <utility> 19 20 namespace llvm { 21 22 template <typename T> class SmallVectorImpl; 23 class CallBase; 24 class CallInst; 25 class Constant; 26 class Function; 27 class DominatorTree; 28 class GlobalVariable; 29 class Instruction; 30 class Module; 31 32 /// The type of CFI jumptable needed for a function. 33 enum CfiFunctionLinkage { 34 CFL_Definition = 0, 35 CFL_Declaration = 1, 36 CFL_WeakDeclaration = 2 37 }; 38 39 /// A call site that could be devirtualized. 40 struct DevirtCallSite { 41 /// The offset from the address point to the virtual function. 42 uint64_t Offset; 43 /// The call site itself. 44 CallBase &CB; 45 }; 46 47 /// Given a call to the intrinsic \@llvm.type.test, find all devirtualizable 48 /// call sites based on the call and return them in DevirtCalls. 49 void findDevirtualizableCallsForTypeTest( 50 SmallVectorImpl<DevirtCallSite> &DevirtCalls, 51 SmallVectorImpl<CallInst *> &Assumes, const CallInst *CI, 52 DominatorTree &DT); 53 54 /// Given a call to the intrinsic \@llvm.type.checked.load, find all 55 /// devirtualizable call sites based on the call and return them in DevirtCalls. 56 void findDevirtualizableCallsForTypeCheckedLoad( 57 SmallVectorImpl<DevirtCallSite> &DevirtCalls, 58 SmallVectorImpl<Instruction *> &LoadedPtrs, 59 SmallVectorImpl<Instruction *> &Preds, bool &HasNonCallUses, 60 const CallInst *CI, DominatorTree &DT); 61 62 /// Processes a Constant recursively looking into elements of arrays, structs 63 /// and expressions to find a trivial pointer element that is located at the 64 /// given offset (relative to the beginning of the whole outer Constant). 65 /// 66 /// Used for example from GlobalDCE to find an entry in a C++ vtable that 67 /// matches a vcall offset. 68 /// 69 /// To support relative vtables, getPointerAtOffset can see through "relative 70 /// pointers", i.e. (sub-)expressions of the form of: 71 /// 72 /// @symbol = ... { 73 /// i32 trunc (i64 sub ( 74 /// i64 ptrtoint (<type> @target to i64), i64 ptrtoint (... @symbol to i64) 75 /// ) to i32) 76 /// } 77 /// 78 /// For such (sub-)expressions, getPointerAtOffset returns the @target pointer. 79 Constant *getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, 80 Constant *TopLevelGlobal = nullptr); 81 82 /// Given a vtable and a specified offset, returns the function and the trivial 83 /// pointer at the specified offset in pair iff the pointer at the specified 84 /// offset is a function or an alias to a function. Returns a pair of nullptr 85 /// otherwise. 86 std::pair<Function *, Constant *> 87 getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M); 88 89 /// Finds the same "relative pointer" pattern as described above, where the 90 /// target is `C`, and replaces the entire pattern with a constant zero. 91 void replaceRelativePointerUsersWithZero(Constant *C); 92 93 } // namespace llvm 94 95 #endif 96