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
20namespace llvm {
21
22template <typename T> class SmallVectorImpl;
23class CallBase;
24class CallInst;
25class Constant;
26class Function;
27class DominatorTree;
28class GlobalVariable;
29class Instruction;
30class Module;
31
32/// The type of CFI jumptable needed for a function.
33enum CfiFunctionLinkage {
34 CFL_Definition = 0,
35 CFL_Declaration = 1,
36 CFL_WeakDeclaration = 2
37};
38
39/// A call site that could be devirtualized.
40struct 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.
49void 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.
56void 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 Swift 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.
79Constant *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.
86std::pair<Function *, Constant *>
87getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M);
88
89/// Finds the same "relative pointer" pattern as described above, where the
90/// target is `F`, and replaces the entire pattern with a constant zero.
91void replaceRelativePointerUsersWithZero(Function *F);
92
93} // namespace llvm
94
95#endif
96

source code of llvm/include/llvm/Analysis/TypeMetadataUtils.h