LLVM 24.0.0git
InjectTLIMappings.cpp
Go to the documentation of this file.
1//===- InjectTLIMAppings.cpp - TLI to VFABI attribute injection ----------===//
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// Populates the VFABI attribute with the scalar-to-vector mappings
10// from the TargetLibraryInfo.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/SetVector.h"
16#include "llvm/ADT/Statistic.h"
22#include "llvm/IR/Attributes.h"
26
27using namespace llvm;
28
29#define DEBUG_TYPE "inject-tli-mappings"
30
31STATISTIC(NumCallInjected,
32 "Number of calls in which the mappings have been injected.");
33
34STATISTIC(NumVFDeclAdded,
35 "Number of function declarations that have been added.");
36STATISTIC(NumCompUsedAdded,
37 "Number of `@llvm.compiler.used` operands that have been added.");
38
39/// A helper function that adds the vector variant declaration for vectorizing
40/// the CallInst \p CI with a vectorization factor of \p VF lanes. For each
41/// mapping, TLI provides a VABI prefix, which contains all information required
42/// to create vector function declaration.
43static void addVariantDeclaration(CallInst &CI, const ElementCount &VF,
44 const VecDesc *VD) {
45 Module *M = CI.getModule();
46 FunctionType *ScalarFTy = CI.getFunctionType();
47
48 assert(!ScalarFTy->isVarArg() && "VarArg functions are not supported.");
49
50 const std::optional<VFInfo> Info = VFABI::tryDemangleForVFABI(
51 VD->getVectorFunctionABIVariantString(), ScalarFTy);
52
53 assert(Info && "Failed to demangle vector variant");
54 assert(Info->Shape.VF == VF && "Mangled name does not match VF");
55
56 const StringRef VFName = VD->getVectorFnName();
57 FunctionType *VectorFTy = VFABI::createFunctionType(*Info, ScalarFTy);
58 Function *VecFunc =
59 Function::Create(VectorFTy, Function::ExternalLinkage, VFName, M);
61
62 // When mapping scalar functions to vector functions, some attributes
63 // (e.g. signext) are not valid on vector types. Remove attributes that are
64 // incompatible with the vectorized return type and arguments.
65 VecFunc->removeRetAttrs(AttributeFuncs::typeIncompatible(
66 VecFunc->getReturnType(), VecFunc->getAttributes().getRetAttrs()));
67 for (auto &Arg : VecFunc->args())
68 Arg.removeAttrs(
69 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));
70
71 if (auto CC = VD->getCallingConv())
72 VecFunc->setCallingConv(*CC);
73 ++NumVFDeclAdded;
74 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added to the module: `" << VFName
75 << "` of type " << *VectorFTy << "\n");
76
77 // Make function declaration (without a body) "sticky" in the IR by
78 // listing it in the @llvm.compiler.used intrinsic.
79 assert(!VecFunc->size() && "VFABI attribute requires `@llvm.compiler.used` "
80 "only on declarations.");
81 appendToCompilerUsed(*M, {VecFunc});
82 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << VFName
83 << "` to `@llvm.compiler.used`.\n");
84 ++NumCompUsedAdded;
85}
86
87static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
88 // This is needed to make sure we don't query the TLI for calls to
89 // bitcast of function pointers, like `%call = call i32 (i32*, ...)
90 // bitcast (i32 (...)* @goo to i32 (i32*, ...)*)(i32* nonnull %i)`,
91 // as such calls make the `isFunctionVectorizable` raise an
92 // exception.
93 if (CI.isNoBuiltin() || !CI.getCalledFunction())
94 return;
95
96 // Skip variadic function calls as they are not supported (like 'int pow();')
97 if (CI.getFunctionType()->isVarArg())
98 return;
99
100 StringRef ScalarName = CI.getCalledFunction()->getName();
101
102 // Nothing to be done if the TLI thinks the function is not
103 // vectorizable.
104 if (!TLI.isFunctionVectorizable(ScalarName))
105 return;
107 VFABI::getVectorVariantNames(CI, Mappings);
108 Module *M = CI.getModule();
109 const SetVector<StringRef> OriginalSetOfMappings(llvm::from_range, Mappings);
110
111 auto AddVariantDecl = [&](const ElementCount &VF, bool Predicate) {
112 const VecDesc *VD = TLI.getVectorMappingInfo(ScalarName, VF, Predicate);
113 if (VD && !VD->getVectorFnName().empty()) {
114 std::string MangledName = VD->getVectorFunctionABIVariantString();
115 if (!OriginalSetOfMappings.count(MangledName)) {
116 Mappings.push_back(MangledName);
117 ++NumCallInjected;
118 }
119 Function *VariantF = M->getFunction(VD->getVectorFnName());
120 if (!VariantF)
121 addVariantDeclaration(CI, VF, VD);
122 }
123 };
124
125 // All VFs in the TLI are powers of 2.
126 ElementCount WidestFixedVF, WidestScalableVF;
127 TLI.getWidestVF(ScalarName, WidestFixedVF, WidestScalableVF);
128
129 for (bool Predicated : {false, true}) {
131 ElementCount::isKnownLE(VF, WidestFixedVF); VF *= 2)
132 AddVariantDecl(VF, Predicated);
133
135 ElementCount::isKnownLE(VF, WidestScalableVF); VF *= 2)
136 AddVariantDecl(VF, Predicated);
137 }
138
139 VFABI::setVectorVariantNames(&CI, Mappings);
140}
141
142static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
143 for (auto &I : instructions(F))
144 if (auto CI = dyn_cast<CallInst>(&I))
145 addMappingsFromTLI(TLI, *CI);
146 // Even if the pass adds IR attributes, the analyses are preserved.
147 return false;
148}
149
150////////////////////////////////////////////////////////////////////////////////
151// New pass manager implementation.
152////////////////////////////////////////////////////////////////////////////////
156 runImpl(TLI, F);
157 // Even if the pass adds IR attributes, the analyses are preserved.
158 return PreservedAnalyses::all();
159}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool runImpl(MachineFunction &MF)
Definition CFIFixup.cpp:304
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI)
static void addVariantDeclaration(CallInst &CI, const ElementCount &VF, const VecDesc *VD)
A helper function that adds the vector variant declaration for vectorizing the CallInst CI with a vec...
static bool runImpl(const TargetLibraryInfo &TLI, Function &F)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
FunctionType * getFunctionType() const
This class represents a function call, abstracting a target machine's calling convention.
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:309
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
bool isVarArg() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
iterator_range< arg_iterator > args()
Definition Function.h:877
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
const Function & getFunction() const
Definition Function.h:167
size_t size() const
Definition Function.h:843
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
Definition Function.cpp:709
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:217
void setCallingConv(CallingConv::ID CC)
Definition Function.h:277
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:846
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
Definition SetVector.h:268
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, ElementCount &ScalableVF) const
Returns the largest vectorization factor used in the list of vector functions.
const VecDesc * getVectorMappingInfo(StringRef F, const ElementCount &VF, bool Masked) const
bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
Provides info so a possible vectorization of a function can be computed.
std::optional< CallingConv::ID > getCallingConv() const
LLVM_ABI std::string getVectorFunctionABIVariantString() const
Returns a vector function ABI variant string on the form: ZGV<isa><mask><vlen><vparams><scalarname>(<...
StringRef getVectorFnName() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:231
LLVM_ABI std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
LLVM_ABI FunctionType * createFunctionType(const VFInfo &Info, const FunctionType *ScalarFTy)
Constructs a FunctionType by applying vector function information to the type of a matching scalar fu...
LLVM_ABI void getVectorVariantNames(const CallInst &CI, SmallVectorImpl< std::string > &VariantMappings)
Populates a set of strings representing the Vector Function ABI variants associated to the CallInst C...
LLVM_ABI void setVectorVariantNames(CallInst *CI, ArrayRef< std::string > VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr from_range_t from_range
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.