LLVM 23.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/Statistic.h"
21#include "llvm/IR/Attributes.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "inject-tli-mappings"
29
30STATISTIC(NumCallInjected,
31 "Number of calls in which the mappings have been injected.");
32
33STATISTIC(NumVFDeclAdded,
34 "Number of function declarations that have been added.");
35STATISTIC(NumCompUsedAdded,
36 "Number of `@llvm.compiler.used` operands that have been added.");
37
38/// A helper function that adds the vector variant declaration for vectorizing
39/// the CallInst \p CI with a vectorization factor of \p VF lanes. For each
40/// mapping, TLI provides a VABI prefix, which contains all information required
41/// to create vector function declaration.
42static void addVariantDeclaration(CallInst &CI, const ElementCount &VF,
43 const VecDesc *VD) {
44 Module *M = CI.getModule();
45 FunctionType *ScalarFTy = CI.getFunctionType();
46
47 assert(!ScalarFTy->isVarArg() && "VarArg functions are not supported.");
48
49 const std::optional<VFInfo> Info = VFABI::tryDemangleForVFABI(
50 VD->getVectorFunctionABIVariantString(), ScalarFTy);
51
52 assert(Info && "Failed to demangle vector variant");
53 assert(Info->Shape.VF == VF && "Mangled name does not match VF");
54
55 const StringRef VFName = VD->getVectorFnName();
56 FunctionType *VectorFTy = VFABI::createFunctionType(*Info, ScalarFTy);
57 Function *VecFunc =
58 Function::Create(VectorFTy, Function::ExternalLinkage, VFName, M);
60
61 // When mapping scalar functions to vector functions, some attributes
62 // (e.g. signext) are not valid on vector types. Remove attributes that are
63 // incompatible with the vectorized return type and arguments.
64 VecFunc->removeRetAttrs(AttributeFuncs::typeIncompatible(
65 VecFunc->getReturnType(), VecFunc->getAttributes().getRetAttrs()));
66 for (auto &Arg : VecFunc->args())
67 Arg.removeAttrs(
68 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));
69
70 if (auto CC = VD->getCallingConv())
71 VecFunc->setCallingConv(*CC);
72 ++NumVFDeclAdded;
73 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added to the module: `" << VFName
74 << "` of type " << *VectorFTy << "\n");
75
76 // Make function declaration (without a body) "sticky" in the IR by
77 // listing it in the @llvm.compiler.used intrinsic.
78 assert(!VecFunc->size() && "VFABI attribute requires `@llvm.compiler.used` "
79 "only on declarations.");
80 appendToCompilerUsed(*M, {VecFunc});
81 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << VFName
82 << "` to `@llvm.compiler.used`.\n");
83 ++NumCompUsedAdded;
84}
85
86static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
87 // This is needed to make sure we don't query the TLI for calls to
88 // bitcast of function pointers, like `%call = call i32 (i32*, ...)
89 // bitcast (i32 (...)* @goo to i32 (i32*, ...)*)(i32* nonnull %i)`,
90 // as such calls make the `isFunctionVectorizable` raise an
91 // exception.
92 if (CI.isNoBuiltin() || !CI.getCalledFunction())
93 return;
94
95 StringRef ScalarName = CI.getCalledFunction()->getName();
96
97 // Nothing to be done if the TLI thinks the function is not
98 // vectorizable.
99 if (!TLI.isFunctionVectorizable(ScalarName))
100 return;
102 VFABI::getVectorVariantNames(CI, Mappings);
103 Module *M = CI.getModule();
104 const SetVector<StringRef> OriginalSetOfMappings(llvm::from_range, Mappings);
105
106 auto AddVariantDecl = [&](const ElementCount &VF, bool Predicate) {
107 const VecDesc *VD = TLI.getVectorMappingInfo(ScalarName, VF, Predicate);
108 if (VD && !VD->getVectorFnName().empty()) {
109 std::string MangledName = VD->getVectorFunctionABIVariantString();
110 if (!OriginalSetOfMappings.count(MangledName)) {
111 Mappings.push_back(MangledName);
112 ++NumCallInjected;
113 }
114 Function *VariantF = M->getFunction(VD->getVectorFnName());
115 if (!VariantF)
116 addVariantDeclaration(CI, VF, VD);
117 }
118 };
119
120 // All VFs in the TLI are powers of 2.
121 ElementCount WidestFixedVF, WidestScalableVF;
122 TLI.getWidestVF(ScalarName, WidestFixedVF, WidestScalableVF);
123
124 for (bool Predicated : {false, true}) {
126 ElementCount::isKnownLE(VF, WidestFixedVF); VF *= 2)
127 AddVariantDecl(VF, Predicated);
128
130 ElementCount::isKnownLE(VF, WidestScalableVF); VF *= 2)
131 AddVariantDecl(VF, Predicated);
132 }
133
134 VFABI::setVectorVariantNames(&CI, Mappings);
135}
136
137static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
138 for (auto &I : instructions(F))
139 if (auto CI = dyn_cast<CallInst>(&I))
140 addMappingsFromTLI(TLI, *CI);
141 // Even if the pass adds IR attributes, the analyses are preserved.
142 return false;
143}
144
145////////////////////////////////////////////////////////////////////////////////
146// New pass manager implementation.
147////////////////////////////////////////////////////////////////////////////////
151 runImpl(TLI, F);
152 // Even if the pass adds IR attributes, the analyses are preserved.
153 return PreservedAnalyses::all();
154}
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(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
#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 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:114
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:312
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:166
iterator_range< arg_iterator > args()
Definition Function.h:896
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:352
const Function & getFunction() const
Definition Function.h:164
size_t size() const
Definition Function.h:862
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
Definition Function.cpp:707
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:214
void setCallingConv(CallingConv::ID CC)
Definition Function.h:274
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:858
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
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:67
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:262
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
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:322
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:230
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.
Definition Types.h:26
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:207
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.