xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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