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 19 namespace llvm { 20 21 template <typename T> class SmallVectorImpl; 22 class CallBase; 23 class CallInst; 24 class Constant; 25 class Function; 26 class DominatorTree; 27 class Instruction; 28 class Module; 29 30 /// The type of CFI jumptable needed for a function. 31 enum CfiFunctionLinkage { 32 CFL_Definition = 0, 33 CFL_Declaration = 1, 34 CFL_WeakDeclaration = 2 35 }; 36 37 /// A call site that could be devirtualized. 38 struct DevirtCallSite { 39 /// The offset from the address point to the virtual function. 40 uint64_t Offset; 41 /// The call site itself. 42 CallBase &CB; 43 }; 44 45 /// Given a call to the intrinsic \@llvm.type.test, find all devirtualizable 46 /// call sites based on the call and return them in DevirtCalls. 47 void findDevirtualizableCallsForTypeTest( 48 SmallVectorImpl<DevirtCallSite> &DevirtCalls, 49 SmallVectorImpl<CallInst *> &Assumes, const CallInst *CI, 50 DominatorTree &DT); 51 52 /// Given a call to the intrinsic \@llvm.type.checked.load, find all 53 /// devirtualizable call sites based on the call and return them in DevirtCalls. 54 void findDevirtualizableCallsForTypeCheckedLoad( 55 SmallVectorImpl<DevirtCallSite> &DevirtCalls, 56 SmallVectorImpl<Instruction *> &LoadedPtrs, 57 SmallVectorImpl<Instruction *> &Preds, bool &HasNonCallUses, 58 const CallInst *CI, DominatorTree &DT); 59 60 /// Processes a Constant recursively looking into elements of arrays, structs 61 /// and expressions to find a trivial pointer element that is located at the 62 /// given offset (relative to the beginning of the whole outer Constant). 63 /// 64 /// Used for example from GlobalDCE to find an entry in a C++ vtable that 65 /// matches a vcall offset. 66 /// 67 /// To support Swift vtables, getPointerAtOffset can see through "relative 68 /// pointers", i.e. (sub-)expressions of the form of: 69 /// 70 /// @symbol = ... { 71 /// i32 trunc (i64 sub ( 72 /// i64 ptrtoint (<type> @target to i64), i64 ptrtoint (... @symbol to i64) 73 /// ) to i32) 74 /// } 75 /// 76 /// For such (sub-)expressions, getPointerAtOffset returns the @target pointer. 77 Constant *getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, 78 Constant *TopLevelGlobal = nullptr); 79 80 /// Finds the same "relative pointer" pattern as described above, where the 81 /// target is `F`, and replaces the entire pattern with a constant zero. 82 void replaceRelativePointerUsersWithZero(Function *F); 83 84 } // namespace llvm 85 86 #endif 87