LLVM  13.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/IR/IntrinsicInst.h"
23 #include "llvm/Transforms/Utils.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "inject-tli-mappings"
29 
30 STATISTIC(NumCallInjected,
31  "Number of calls in which the mappings have been injected.");
32 
33 STATISTIC(NumVFDeclAdded,
34  "Number of function declarations that have been added.");
35 STATISTIC(NumCompUsedAdded,
36  "Number of `@llvm.compiler.used` operands that have been added.");
37 
38 /// A helper function that adds the vector function declaration that
39 /// vectorizes the CallInst CI with a vectorization factor of VF
40 /// lanes. The TLI assumes that all parameters and the return type of
41 /// CI (other than void) need to be widened to a VectorType of VF
42 /// lanes.
43 static void addVariantDeclaration(CallInst &CI, const ElementCount &VF,
44  const StringRef VFName) {
45  Module *M = CI.getModule();
46 
47  // Add function declaration.
48  Type *RetTy = ToVectorTy(CI.getType(), VF);
50  for (Value *ArgOperand : CI.arg_operands())
51  Tys.push_back(ToVectorTy(ArgOperand->getType(), VF));
52  assert(!CI.getFunctionType()->isVarArg() &&
53  "VarArg functions are not supported.");
54  FunctionType *FTy = FunctionType::get(RetTy, Tys, /*isVarArg=*/false);
55  Function *VectorF =
58  ++NumVFDeclAdded;
59  LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added to the module: `" << VFName
60  << "` of type " << *(VectorF->getType()) << "\n");
61 
62  // Make function declaration (without a body) "sticky" in the IR by
63  // listing it in the @llvm.compiler.used intrinsic.
64  assert(!VectorF->size() && "VFABI attribute requires `@llvm.compiler.used` "
65  "only on declarations.");
66  appendToCompilerUsed(*M, {VectorF});
67  LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << VFName
68  << "` to `@llvm.compiler.used`.\n");
69  ++NumCompUsedAdded;
70 }
71 
72 static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
73  // This is needed to make sure we don't query the TLI for calls to
74  // bitcast of function pointers, like `%call = call i32 (i32*, ...)
75  // bitcast (i32 (...)* @goo to i32 (i32*, ...)*)(i32* nonnull %i)`,
76  // as such calls make the `isFunctionVectorizable` raise an
77  // exception.
78  if (CI.isNoBuiltin() || !CI.getCalledFunction())
79  return;
80 
81  StringRef ScalarName = CI.getCalledFunction()->getName();
82 
83  // Nothing to be done if the TLI thinks the function is not
84  // vectorizable.
85  if (!TLI.isFunctionVectorizable(ScalarName))
86  return;
89  Module *M = CI.getModule();
90  const SetVector<StringRef> OriginalSetOfMappings(Mappings.begin(),
91  Mappings.end());
92 
93  auto AddVariantDecl = [&](const ElementCount &VF) {
94  const std::string TLIName =
95  std::string(TLI.getVectorizedFunction(ScalarName, VF));
96  if (!TLIName.empty()) {
97  std::string MangledName = VFABI::mangleTLIVectorName(
98  TLIName, ScalarName, CI.getNumArgOperands(), VF);
99  if (!OriginalSetOfMappings.count(MangledName)) {
100  Mappings.push_back(MangledName);
101  ++NumCallInjected;
102  }
103  Function *VariantF = M->getFunction(TLIName);
104  if (!VariantF)
105  addVariantDeclaration(CI, VF, TLIName);
106  }
107  };
108 
109  // All VFs in the TLI are powers of 2.
110  ElementCount WidestFixedVF, WidestScalableVF;
111  TLI.getWidestVF(ScalarName, WidestFixedVF, WidestScalableVF);
112 
114  ElementCount::isKnownLE(VF, WidestFixedVF); VF *= 2)
115  AddVariantDecl(VF);
116 
117  // TODO: Add scalable variants once we're able to test them.
118  assert(WidestScalableVF.isZero() &&
119  "Scalable vector mappings not yet supported");
120 
122 }
123 
124 static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
125  for (auto &I : instructions(F))
126  if (auto CI = dyn_cast<CallInst>(&I))
127  addMappingsFromTLI(TLI, *CI);
128  // Even if the pass adds IR attributes, the analyses are preserved.
129  return false;
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 // New pass manager implementation.
134 ////////////////////////////////////////////////////////////////////////////////
138  runImpl(TLI, F);
139  // Even if the pass adds IR attributes, the analyses are preserved.
140  return PreservedAnalyses::all();
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 // Legacy PM Implementation.
145 ////////////////////////////////////////////////////////////////////////////////
147  const TargetLibraryInfo &TLI =
148  getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
149  return runImpl(TLI, F);
150 }
151 
153  AU.setPreservesCFG();
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 // Legacy Pass manager initialization
166 ////////////////////////////////////////////////////////////////////////////////
168 
170  "Inject TLI Mappings", false, false)
174 
176  return new InjectTLIMappingsLegacy();
177 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm::LoopAccessLegacyAnalysis
This analysis provides dependence information for the memory accesses of a loop.
Definition: LoopAccessAnalysis.h:717
llvm
Definition: AllocatorList.h:23
llvm::CallBase::isNoBuiltin
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
Definition: InstrTypes.h:1769
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:66
llvm::VFABI::setVectorVariantNames
void setVectorVariantNames(CallInst *CI, const SmallVector< std::string, 8 > &VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.
Definition: ModuleUtils.cpp:296
IntrinsicInst.h
llvm::ElementCount
Definition: TypeSize.h:386
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:769
InstIterator.h
llvm::Function
Definition: Function.h:61
llvm::LinearPolySize< ElementCount >::isKnownLE
static bool isKnownLE(const LinearPolySize &LHS, const LinearPolySize &RHS)
Definition: TypeSize.h:341
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1167
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:1317
llvm::TargetLibraryInfo::isFunctionVectorizable
bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const
Definition: TargetLibraryInfo.h:326
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:321
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:46
InjectTLIMappings.h
llvm::CallBase::getFunctionType
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1244
llvm::CallBase::getNumArgOperands
unsigned getNumArgOperands() const
Definition: InstrTypes.h:1339
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::FunctionType::isVarArg
bool isVarArg() const
Definition: DerivedTypes.h:122
llvm::InjectTLIMappingsLegacy
Definition: InjectTLIMappings.h:26
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Mappings
Inject TLI Mappings
Definition: InjectTLIMappings.cpp:172
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:1301
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1396
llvm::ToVectorTy
Type * ToVectorTy(Type *Scalar, ElementCount EC)
A helper function for converting Scalar types to vector types.
Definition: VectorUtils.h:301
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TargetLibraryInfo.h
false
Definition: StackSlotColoring.cpp:142
DEBUG_TYPE
#define DEBUG_TYPE
Definition: InjectTLIMappings.cpp:28
llvm::appendToCompilerUsed
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
Definition: ModuleUtils.cpp:110
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:681
llvm::ScalarEvolutionWrapperPass
Definition: ScalarEvolution.h:2135
Utils.h
llvm::createInjectTLIMappingsLegacyPass
FunctionPass * createInjectTLIMappingsLegacyPass()
Definition: InjectTLIMappings.cpp:175
llvm::LinearPolySize< ElementCount >::getFixed
static ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:284
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:463
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:59
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:43
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:67
addMappingsFromTLI
static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI)
Definition: InjectTLIMappings.cpp:72
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
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:294
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:152
llvm::OptimizationRemarkEmitterWrapperPass
OptimizationRemarkEmitter legacy analysis pass.
Definition: OptimizationRemarkEmitter.h:146
llvm::DemandedBitsWrapperPass
Definition: DemandedBits.h:102
llvm::InjectTLIMappings::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: InjectTLIMappings.cpp:135
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
runImpl
static bool runImpl(const TargetLibraryInfo &TLI, Function &F)
Definition: InjectTLIMappings.cpp:124
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:219
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:1281
llvm::GlobalsAAWrapperPass
Legacy wrapper pass to provide the GlobalsAAResult object.
Definition: GlobalsModRef.h:143
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:146
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:423
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:271
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1478
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::SetVector
A vector that has set insertion semantics.
Definition: SetVector.h:40
llvm::CallBase::arg_operands
iterator_range< User::op_iterator > arg_operands()
Definition: InstrTypes.h:1333
llvm::InjectTLIMappingsLegacy::ID
static char ID
Definition: InjectTLIMappings.h:28
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:438
llvm::TargetLibraryInfo::getVectorizedFunction
StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const
Definition: TargetLibraryInfo.h:332
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:102
llvm::Function::size
size_t size() const
Definition: Function.h:783