xref: /llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h (revision 73c3b7337b0a3a8cb447f9801341d5648aebe9b2)
1 //===- CallPromotionUtils.h - Utilities for call promotion ------*- 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 declares utilities useful for promoting indirect call sites to
10 // direct call sites.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
15 #define LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
16 
17 #include "llvm/Analysis/CtxProfAnalysis.h"
18 namespace llvm {
19 template <typename T> class ArrayRef;
20 class Constant;
21 class CallBase;
22 class CastInst;
23 class Function;
24 class Instruction;
25 class MDNode;
26 class Value;
27 
28 /// Return true if the given indirect call site can be made to call \p Callee.
29 ///
30 /// This function ensures that the number and type of the call site's arguments
31 /// and return value match those of the given function. If the types do not
32 /// match exactly, they must at least be bitcast compatible. If \p FailureReason
33 /// is non-null and the indirect call cannot be promoted, the failure reason
34 /// will be stored in it.
35 bool isLegalToPromote(const CallBase &CB, Function *Callee,
36                       const char **FailureReason = nullptr);
37 
38 /// Promote the given indirect call site to unconditionally call \p Callee.
39 ///
40 /// This function promotes the given call site, returning the direct call or
41 /// invoke instruction. If the function type of the call site doesn't match that
42 /// of the callee, bitcast instructions are inserted where appropriate. If \p
43 /// RetBitCast is non-null, it will be used to store the return value bitcast,
44 /// if created.
45 CallBase &promoteCall(CallBase &CB, Function *Callee,
46                       CastInst **RetBitCast = nullptr);
47 
48 /// Promote the given indirect call site to conditionally call \p Callee. The
49 /// promoted direct call instruction is predicated on `CB.getCalledOperand() ==
50 /// Callee`.
51 ///
52 /// This function creates an if-then-else structure at the location of the call
53 /// site. The original call site is moved into the "else" block. A clone of the
54 /// indirect call site is promoted, placed in the "then" block, and returned. If
55 /// \p BranchWeights is non-null, it will be used to set !prof metadata on the
56 /// new conditional branch.
57 CallBase &promoteCallWithIfThenElse(CallBase &CB, Function *Callee,
58                                     MDNode *BranchWeights = nullptr);
59 
60 CallBase *promoteCallWithIfThenElse(CallBase &CB, Function &Callee,
61                                     PGOContextualProfile &CtxProf);
62 
63 /// This is similar to `promoteCallWithIfThenElse` except that the condition to
64 /// promote a virtual call is that \p VPtr is the same as any of \p
65 /// AddressPoints.
66 ///
67 /// This function is expected to be used on virtual calls (a subset of indirect
68 /// calls). \p VPtr is the virtual table address stored in the objects, and
69 /// \p AddressPoints contains vtable address points. A vtable address point is
70 /// a location inside the vtable that's referenced by vpointer in C++ objects.
71 ///
72 /// TODO: sink the address-calculation instructions of indirect callee to the
73 /// indirect call fallback after transformation.
74 CallBase &promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr,
75                                    Function *Callee,
76                                    ArrayRef<Constant *> AddressPoints,
77                                    MDNode *BranchWeights);
78 
79 /// Try to promote (devirtualize) a virtual call on an Alloca. Return true on
80 /// success.
81 ///
82 /// Look for a pattern like:
83 ///
84 ///  %o = alloca %class.Impl
85 ///  %1 = getelementptr %class.Impl, %class.Impl* %o, i64 0, i32 0, i32 0
86 ///  store i32 (...)** bitcast (i8** getelementptr inbounds
87 ///      ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV4Impl, i64 0, inrange i32 0, i64 2)
88 ///      to i32 (...)**), i32 (...)*** %1
89 ///  %2 = getelementptr inbounds %class.Impl, %class.Impl* %o, i64 0, i32 0
90 ///  %3 = bitcast %class.Interface* %2 to void (%class.Interface*)***
91 ///  %vtable.i = load void (%class.Interface*)**, void (%class.Interface*)*** %3
92 ///  %4 = load void (%class.Interface*)*, void (%class.Interface*)** %vtable.i
93 ///  call void %4(%class.Interface* nonnull %2)
94 ///
95 /// @_ZTV4Impl = linkonce_odr dso_local unnamed_addr constant { [3 x i8*] }
96 ///     { [3 x i8*]
97 ///     [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI4Impl to i8*),
98 ///     i8* bitcast (void (%class.Impl*)* @_ZN4Impl3RunEv to i8*)] }
99 ///
100 bool tryPromoteCall(CallBase &CB);
101 
102 /// Predicate and clone the given call site.
103 ///
104 /// This function creates an if-then-else structure at the location of the
105 /// call site. The "if" condition compares the call site's called value to
106 /// the given callee. The original call site is moved into the "else" block,
107 /// and a clone of the call site is placed in the "then" block. The cloned
108 /// instruction is returned.
109 CallBase &versionCallSite(CallBase &CB, Value *Callee, MDNode *BranchWeights);
110 
111 } // end namespace llvm
112 
113 #endif // LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
114