LLVM  16.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/InstIterator.h"
22 #include "llvm/Transforms/Utils.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "inject-tli-mappings"
28 
29 STATISTIC(NumCallInjected,
30  "Number of calls in which the mappings have been injected.");
31 
32 STATISTIC(NumVFDeclAdded,
33  "Number of function declarations that have been added.");
34 STATISTIC(NumCompUsedAdded,
35  "Number of `@llvm.compiler.used` operands that have been added.");
36 
37 /// A helper function that adds the vector function declaration that
38 /// vectorizes the CallInst CI with a vectorization factor of VF
39 /// lanes. The TLI assumes that all parameters and the return type of
40 /// CI (other than void) need to be widened to a VectorType of VF
41 /// lanes.
42 static void addVariantDeclaration(CallInst &CI, const ElementCount &VF,
43  const StringRef VFName) {
44  Module *M = CI.getModule();
45 
46  // Add function declaration.
47  Type *RetTy = ToVectorTy(CI.getType(), VF);
49  for (Value *ArgOperand : CI.args())
50  Tys.push_back(ToVectorTy(ArgOperand->getType(), VF));
51  assert(!CI.getFunctionType()->isVarArg() &&
52  "VarArg functions are not supported.");
53  FunctionType *FTy = FunctionType::get(RetTy, Tys, /*isVarArg=*/false);
54  Function *VectorF =
57  ++NumVFDeclAdded;
58  LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added to the module: `" << VFName
59  << "` of type " << *(VectorF->getType()) << "\n");
60 
61  // Make function declaration (without a body) "sticky" in the IR by
62  // listing it in the @llvm.compiler.used intrinsic.
63  assert(!VectorF->size() && "VFABI attribute requires `@llvm.compiler.used` "
64  "only on declarations.");
65  appendToCompilerUsed(*M, {VectorF});
66  LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << VFName
67  << "` to `@llvm.compiler.used`.\n");
68  ++NumCompUsedAdded;
69 }
70 
71 static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
72  // This is needed to make sure we don't query the TLI for calls to
73  // bitcast of function pointers, like `%call = call i32 (i32*, ...)
74  // bitcast (i32 (...)* @goo to i32 (i32*, ...)*)(i32* nonnull %i)`,
75  // as such calls make the `isFunctionVectorizable` raise an
76  // exception.
77  if (CI.isNoBuiltin() || !CI.getCalledFunction())
78  return;
79 
80  StringRef ScalarName = CI.getCalledFunction()->getName();
81 
82  // Nothing to be done if the TLI thinks the function is not
83  // vectorizable.
84  if (!TLI.isFunctionVectorizable(ScalarName))
85  return;
88  Module *M = CI.getModule();
89  const SetVector<StringRef> OriginalSetOfMappings(Mappings.begin(),
90  Mappings.end());
91 
92  auto AddVariantDecl = [&](const ElementCount &VF) {
93  const std::string TLIName =
94  std::string(TLI.getVectorizedFunction(ScalarName, VF));
95  if (!TLIName.empty()) {
96  std::string MangledName =
97  VFABI::mangleTLIVectorName(TLIName, ScalarName, CI.arg_size(), VF);
98  if (!OriginalSetOfMappings.count(MangledName)) {
99  Mappings.push_back(MangledName);
100  ++NumCallInjected;
101  }
102  Function *VariantF = M->getFunction(TLIName);
103  if (!VariantF)
104  addVariantDeclaration(CI, VF, TLIName);
105  }
106  };
107 
108  // All VFs in the TLI are powers of 2.
109  ElementCount WidestFixedVF, WidestScalableVF;
110  TLI.getWidestVF(ScalarName, WidestFixedVF, WidestScalableVF);
111 
113  ElementCount::isKnownLE(VF, WidestFixedVF); VF *= 2)
114  AddVariantDecl(VF);
115 
116  // TODO: Add scalable variants once we're able to test them.
117  assert(WidestScalableVF.isZero() &&
118  "Scalable vector mappings not yet supported");
119 
121 }
122 
123 static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
124  for (auto &I : instructions(F))
125  if (auto CI = dyn_cast<CallInst>(&I))
126  addMappingsFromTLI(TLI, *CI);
127  // Even if the pass adds IR attributes, the analyses are preserved.
128  return false;
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 // New pass manager implementation.
133 ////////////////////////////////////////////////////////////////////////////////
137  runImpl(TLI, F);
138  // Even if the pass adds IR attributes, the analyses are preserved.
139  return PreservedAnalyses::all();
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 // Legacy PM Implementation.
144 ////////////////////////////////////////////////////////////////////////////////
146  const TargetLibraryInfo &TLI =
147  getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
148  return runImpl(TLI, F);
149 }
150 
152  AU.setPreservesCFG();
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 // Legacy Pass manager initialization
165 ////////////////////////////////////////////////////////////////////////////////
167 
169  "Inject TLI Mappings", false, false)
173 
175  return new InjectTLIMappingsLegacy();
176 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::LoopAccessLegacyAnalysis
This analysis provides dependence information for the memory accesses of a loop.
Definition: LoopAccessAnalysis.h:796
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::CallBase::isNoBuiltin
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
Definition: InstrTypes.h:1840
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:69
llvm::ElementCount
Definition: TypeSize.h:404
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:774
InstIterator.h
llvm::Function
Definition: Function.h:60
llvm::LinearPolySize< ElementCount >::isKnownLE
static bool isKnownLE(const LinearPolySize &LHS, const LinearPolySize &RHS)
Definition: TypeSize.h:340
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
Statistic.h
llvm::VFABI::getVectorVariantNames
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...
Definition: VectorUtils.cpp:1534
llvm::TargetLibraryInfo::isFunctionVectorizable
bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const
Definition: TargetLibraryInfo.h:335
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
OptimizationRemarkEmitter.h
GlobalsModRef.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
InjectTLIMappings.h
llvm::CallBase::getFunctionType
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1255
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::FunctionType::isVarArg
bool isVarArg() const
Definition: DerivedTypes.h:123
llvm::InjectTLIMappingsLegacy
Definition: InjectTLIMappings.h:28
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Mappings
Inject TLI Mappings
Definition: InjectTLIMappings.cpp:171
llvm::VFABI::mangleTLIVectorName
std::string mangleTLIVectorName(StringRef VectorName, StringRef ScalarName, unsigned numArgs, ElementCount VF)
This routine mangles the given VectorName according to the LangRef specification for vector-function-...
Definition: VectorUtils.cpp:1518
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1397
llvm::ToVectorTy
Type * ToVectorTy(Type *Scalar, ElementCount EC)
A helper function for converting Scalar types to vector types.
Definition: VectorUtils.h:299
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TargetLibraryInfo.h
false
Definition: StackSlotColoring.cpp:141
DEBUG_TYPE
#define DEBUG_TYPE
Definition: InjectTLIMappings.cpp:27
llvm::appendToCompilerUsed
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
Definition: ModuleUtils.cpp:111
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::Function::copyAttributesFrom
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:715
llvm::ScalarEvolutionWrapperPass
Definition: ScalarEvolution.h:2188
Utils.h
llvm::createInjectTLIMappingsLegacyPass
FunctionPass * createInjectTLIMappingsLegacyPass()
Definition: InjectTLIMappings.cpp:174
llvm::LinearPolySize< ElementCount >::getFixed
static ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:283
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
VectorUtils.h
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:475
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(InjectTLIMappingsLegacy, DEBUG_TYPE, "Inject TLI Mappings", false, false) INITIALIZE_PASS_END(InjectTLIMappingsLegacy
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
I
#define I(x, y, z)
Definition: MD5.cpp:58
addVariantDeclaration
static void addVariantDeclaration(CallInst &CI, const ElementCount &VF, const StringRef VFName)
A helper function that adds the vector function declaration that vectorizes the CallInst CI with a ve...
Definition: InjectTLIMappings.cpp:42
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
addMappingsFromTLI
static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI)
Definition: InjectTLIMappings.cpp:71
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:265
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
DemandedBits.h
llvm::InjectTLIMappingsLegacy::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: InjectTLIMappings.cpp:151
llvm::OptimizationRemarkEmitterWrapperPass
OptimizationRemarkEmitter legacy analysis pass.
Definition: OptimizationRemarkEmitter.h:146
llvm::DemandedBitsWrapperPass
Definition: DemandedBits.h:103
llvm::InjectTLIMappings::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: InjectTLIMappings.cpp:134
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::CallBase::arg_size
unsigned arg_size() const
Definition: InstrTypes.h:1340
runImpl
static bool runImpl(const TargetLibraryInfo &TLI, Function &F)
Definition: InjectTLIMappings.cpp:123
llvm::VFABI::setVectorVariantNames
void setVectorVariantNames(CallInst *CI, ArrayRef< std::string > VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.
Definition: ModuleUtils.cpp:242
llvm::SetVector::count
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:215
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:226
llvm::UnivariateLinearPolyBase::isZero
bool isZero() const
Definition: TypeSize.h:229
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
ModuleUtils.h
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition: AliasAnalysis.h:924
llvm::GlobalsAAWrapperPass
Legacy wrapper pass to provide the GlobalsAAResult object.
Definition: GlobalsModRef.h:142
llvm::InjectTLIMappingsLegacy::runOnFunction
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Definition: InjectTLIMappings.cpp:145
llvm::TargetLibraryInfo::getWidestVF
void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, ElementCount &ScalableVF) const
Returns the largest vectorization factor used in the list of vector functions.
Definition: TargetLibraryInfo.h:435
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:290
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::SetVector
A vector that has set insertion semantics.
Definition: SetVector.h:40
llvm::InjectTLIMappingsLegacy::ID
static char ID
Definition: InjectTLIMappings.h:30
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:450
llvm::CallBase::args
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1333
llvm::TargetLibraryInfo::getVectorizedFunction
StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const
Definition: TargetLibraryInfo.h:341
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Function::size
size_t size() const
Definition: Function.h:712