LLVM  16.0.0git
AMDGPURewriteOutArguments.cpp
Go to the documentation of this file.
1 //===- AMDGPURewriteOutArgumentsPass.cpp - Create struct returns ----------===//
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 /// \file This pass attempts to replace out argument usage with a return of a
10 /// struct.
11 ///
12 /// We can support returning a lot of values directly in registers, but
13 /// idiomatic C code frequently uses a pointer argument to return a second value
14 /// rather than returning a struct by value. GPU stack access is also quite
15 /// painful, so we want to avoid that if possible. Passing a stack object
16 /// pointer to a function also requires an additional address expansion code
17 /// sequence to convert the pointer to be relative to the kernel's scratch wave
18 /// offset register since the callee doesn't know what stack frame the incoming
19 /// pointer is relative to.
20 ///
21 /// The goal is to try rewriting code that looks like this:
22 ///
23 /// int foo(int a, int b, int* out) {
24 /// *out = bar();
25 /// return a + b;
26 /// }
27 ///
28 /// into something like this:
29 ///
30 /// std::pair<int, int> foo(int a, int b) {
31 /// return std::make_pair(a + b, bar());
32 /// }
33 ///
34 /// Typically the incoming pointer is a simple alloca for a temporary variable
35 /// to use the API, which if replaced with a struct return will be easily SROA'd
36 /// out when the stub function we create is inlined
37 ///
38 /// This pass introduces the struct return, but leaves the unused pointer
39 /// arguments and introduces a new stub function calling the struct returning
40 /// body. DeadArgumentElimination should be run after this to clean these up.
41 //
42 //===----------------------------------------------------------------------===//
43 
44 #include "AMDGPU.h"
45 #include "Utils/AMDGPUBaseInfo.h"
46 #include "llvm/ADT/SmallSet.h"
47 #include "llvm/ADT/Statistic.h"
49 #include "llvm/IR/IRBuilder.h"
50 #include "llvm/IR/Instructions.h"
51 #include "llvm/InitializePasses.h"
52 #include "llvm/Pass.h"
54 #include "llvm/Support/Debug.h"
56 
57 #define DEBUG_TYPE "amdgpu-rewrite-out-arguments"
58 
59 using namespace llvm;
60 
62  "amdgpu-any-address-space-out-arguments",
63  cl::desc("Replace pointer out arguments with "
64  "struct returns for non-private address space"),
65  cl::Hidden,
66  cl::init(false));
67 
69  "amdgpu-max-return-arg-num-regs",
70  cl::desc("Approximately limit number of return registers for replacing out arguments"),
71  cl::Hidden,
72  cl::init(16));
73 
74 STATISTIC(NumOutArgumentsReplaced,
75  "Number out arguments moved to struct return values");
76 STATISTIC(NumOutArgumentFunctionsReplaced,
77  "Number of functions with out arguments moved to struct return values");
78 
79 namespace {
80 
81 class AMDGPURewriteOutArguments : public FunctionPass {
82 private:
83  const DataLayout *DL = nullptr;
84  MemoryDependenceResults *MDA = nullptr;
85 
86  Type *getStoredType(Value &Arg) const;
87  Type *getOutArgumentType(Argument &Arg) const;
88 
89 public:
90  static char ID;
91 
92  AMDGPURewriteOutArguments() : FunctionPass(ID) {}
93 
94  void getAnalysisUsage(AnalysisUsage &AU) const override {
97  }
98 
99  bool doInitialization(Module &M) override;
100  bool runOnFunction(Function &F) override;
101 };
102 
103 } // end anonymous namespace
104 
105 INITIALIZE_PASS_BEGIN(AMDGPURewriteOutArguments, DEBUG_TYPE,
106  "AMDGPU Rewrite Out Arguments", false, false)
108 INITIALIZE_PASS_END(AMDGPURewriteOutArguments, DEBUG_TYPE,
109  "AMDGPU Rewrite Out Arguments", false, false)
110 
111 char AMDGPURewriteOutArguments::ID = 0;
112 
113 Type *AMDGPURewriteOutArguments::getStoredType(Value &Arg) const {
114  const int MaxUses = 10;
115  int UseCount = 0;
116 
117  SmallVector<Use *> Worklist;
118  for (Use &U : Arg.uses())
119  Worklist.push_back(&U);
120 
121  Type *StoredType = nullptr;
122  while (!Worklist.empty()) {
123  Use *U = Worklist.pop_back_val();
124 
125  if (auto *BCI = dyn_cast<BitCastInst>(U->getUser())) {
126  for (Use &U : BCI->uses())
127  Worklist.push_back(&U);
128  continue;
129  }
130 
131  if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {
132  if (UseCount++ > MaxUses)
133  return nullptr;
134 
135  if (!SI->isSimple() ||
136  U->getOperandNo() != StoreInst::getPointerOperandIndex())
137  return nullptr;
138 
139  if (StoredType && StoredType != SI->getValueOperand()->getType())
140  return nullptr; // More than one type.
141  StoredType = SI->getValueOperand()->getType();
142  continue;
143  }
144 
145  // Unsupported user.
146  return nullptr;
147  }
148 
149  return StoredType;
150 }
151 
152 Type *AMDGPURewriteOutArguments::getOutArgumentType(Argument &Arg) const {
153  const unsigned MaxOutArgSizeBytes = 4 * MaxNumRetRegs;
154  PointerType *ArgTy = dyn_cast<PointerType>(Arg.getType());
155 
156  // TODO: It might be useful for any out arguments, not just privates.
157  if (!ArgTy || (ArgTy->getAddressSpace() != DL->getAllocaAddrSpace() &&
158  !AnyAddressSpace) ||
159  Arg.hasByValAttr() || Arg.hasStructRetAttr()) {
160  return nullptr;
161  }
162 
163  Type *StoredType = getStoredType(Arg);
164  if (!StoredType || DL->getTypeStoreSize(StoredType) > MaxOutArgSizeBytes)
165  return nullptr;
166 
167  return StoredType;
168 }
169 
170 bool AMDGPURewriteOutArguments::doInitialization(Module &M) {
171  DL = &M.getDataLayout();
172  return false;
173 }
174 
176  if (skipFunction(F))
177  return false;
178 
179  // TODO: Could probably handle variadic functions.
180  if (F.isVarArg() || F.hasStructRetAttr() ||
181  AMDGPU::isEntryFunctionCC(F.getCallingConv()))
182  return false;
183 
184  MDA = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
185 
186  unsigned ReturnNumRegs = 0;
187  SmallDenseMap<int, Type *, 4> OutArgIndexes;
188  SmallVector<Type *, 4> ReturnTypes;
189  Type *RetTy = F.getReturnType();
190  if (!RetTy->isVoidTy()) {
191  ReturnNumRegs = DL->getTypeStoreSize(RetTy) / 4;
192 
193  if (ReturnNumRegs >= MaxNumRetRegs)
194  return false;
195 
196  ReturnTypes.push_back(RetTy);
197  }
198 
200  for (Argument &Arg : F.args()) {
201  if (Type *Ty = getOutArgumentType(Arg)) {
202  LLVM_DEBUG(dbgs() << "Found possible out argument " << Arg
203  << " in function " << F.getName() << '\n');
204  OutArgs.push_back({&Arg, Ty});
205  }
206  }
207 
208  if (OutArgs.empty())
209  return false;
210 
211  using ReplacementVec = SmallVector<std::pair<Argument *, Value *>, 4>;
212 
214 
216  for (BasicBlock &BB : F) {
217  if (ReturnInst *RI = dyn_cast<ReturnInst>(&BB.back()))
218  Returns.push_back(RI);
219  }
220 
221  if (Returns.empty())
222  return false;
223 
224  bool Changing;
225 
226  do {
227  Changing = false;
228 
229  // Keep retrying if we are able to successfully eliminate an argument. This
230  // helps with cases with multiple arguments which may alias, such as in a
231  // sincos implementation. If we have 2 stores to arguments, on the first
232  // attempt the MDA query will succeed for the second store but not the
233  // first. On the second iteration we've removed that out clobbering argument
234  // (by effectively moving it into another function) and will find the second
235  // argument is OK to move.
236  for (const auto &Pair : OutArgs) {
237  bool ThisReplaceable = true;
239 
240  Argument *OutArg = Pair.first;
241  Type *ArgTy = Pair.second;
242 
243  // Skip this argument if converting it will push us over the register
244  // count to return limit.
245 
246  // TODO: This is an approximation. When legalized this could be more. We
247  // can ask TLI for exactly how many.
248  unsigned ArgNumRegs = DL->getTypeStoreSize(ArgTy) / 4;
249  if (ArgNumRegs + ReturnNumRegs > MaxNumRetRegs)
250  continue;
251 
252  // An argument is convertible only if all exit blocks are able to replace
253  // it.
254  for (ReturnInst *RI : Returns) {
255  BasicBlock *BB = RI->getParent();
256 
257  MemDepResult Q = MDA->getPointerDependencyFrom(
258  MemoryLocation::getBeforeOrAfter(OutArg), true, BB->end(), BB, RI);
259  StoreInst *SI = nullptr;
260  if (Q.isDef())
261  SI = dyn_cast<StoreInst>(Q.getInst());
262 
263  if (SI) {
264  LLVM_DEBUG(dbgs() << "Found out argument store: " << *SI << '\n');
265  ReplaceableStores.emplace_back(RI, SI);
266  } else {
267  ThisReplaceable = false;
268  break;
269  }
270  }
271 
272  if (!ThisReplaceable)
273  continue; // Try the next argument candidate.
274 
275  for (std::pair<ReturnInst *, StoreInst *> Store : ReplaceableStores) {
276  Value *ReplVal = Store.second->getValueOperand();
277 
278  auto &ValVec = Replacements[Store.first];
279  if (llvm::any_of(ValVec,
280  [OutArg](const std::pair<Argument *, Value *> &Entry) {
281  return Entry.first == OutArg;
282  })) {
283  LLVM_DEBUG(dbgs()
284  << "Saw multiple out arg stores" << *OutArg << '\n');
285  // It is possible to see stores to the same argument multiple times,
286  // but we expect these would have been optimized out already.
287  ThisReplaceable = false;
288  break;
289  }
290 
291  ValVec.emplace_back(OutArg, ReplVal);
292  Store.second->eraseFromParent();
293  }
294 
295  if (ThisReplaceable) {
296  ReturnTypes.push_back(ArgTy);
297  OutArgIndexes.insert({OutArg->getArgNo(), ArgTy});
298  ++NumOutArgumentsReplaced;
299  Changing = true;
300  }
301  }
302  } while (Changing);
303 
304  if (Replacements.empty())
305  return false;
306 
307  LLVMContext &Ctx = F.getParent()->getContext();
308  StructType *NewRetTy = StructType::create(Ctx, ReturnTypes, F.getName());
309 
310  FunctionType *NewFuncTy = FunctionType::get(NewRetTy,
311  F.getFunctionType()->params(),
312  F.isVarArg());
313 
314  LLVM_DEBUG(dbgs() << "Computed new return type: " << *NewRetTy << '\n');
315 
316  Function *NewFunc = Function::Create(NewFuncTy, Function::PrivateLinkage,
317  F.getName() + ".body");
318  F.getParent()->getFunctionList().insert(F.getIterator(), NewFunc);
319  NewFunc->copyAttributesFrom(&F);
320  NewFunc->setComdat(F.getComdat());
321 
322  // We want to preserve the function and param attributes, but need to strip
323  // off any return attributes, e.g. zeroext doesn't make sense with a struct.
324  NewFunc->stealArgumentListFrom(F);
325 
326  AttributeMask RetAttrs;
327  RetAttrs.addAttribute(Attribute::SExt);
328  RetAttrs.addAttribute(Attribute::ZExt);
329  RetAttrs.addAttribute(Attribute::NoAlias);
330  NewFunc->removeRetAttrs(RetAttrs);
331  // TODO: How to preserve metadata?
332 
333  // Move the body of the function into the new rewritten function, and replace
334  // this function with a stub.
335  NewFunc->getBasicBlockList().splice(NewFunc->begin(), F.getBasicBlockList());
336 
337  for (std::pair<ReturnInst *, ReplacementVec> &Replacement : Replacements) {
338  ReturnInst *RI = Replacement.first;
339  IRBuilder<> B(RI);
340  B.SetCurrentDebugLocation(RI->getDebugLoc());
341 
342  int RetIdx = 0;
343  Value *NewRetVal = PoisonValue::get(NewRetTy);
344 
345  Value *RetVal = RI->getReturnValue();
346  if (RetVal)
347  NewRetVal = B.CreateInsertValue(NewRetVal, RetVal, RetIdx++);
348 
349  for (std::pair<Argument *, Value *> ReturnPoint : Replacement.second)
350  NewRetVal = B.CreateInsertValue(NewRetVal, ReturnPoint.second, RetIdx++);
351 
352  if (RetVal)
353  RI->setOperand(0, NewRetVal);
354  else {
355  B.CreateRet(NewRetVal);
356  RI->eraseFromParent();
357  }
358  }
359 
360  SmallVector<Value *, 16> StubCallArgs;
361  for (Argument &Arg : F.args()) {
362  if (OutArgIndexes.count(Arg.getArgNo())) {
363  // It's easier to preserve the type of the argument list. We rely on
364  // DeadArgumentElimination to take care of these.
365  StubCallArgs.push_back(PoisonValue::get(Arg.getType()));
366  } else {
367  StubCallArgs.push_back(&Arg);
368  }
369  }
370 
371  BasicBlock *StubBB = BasicBlock::Create(Ctx, "", &F);
372  IRBuilder<> B(StubBB);
373  CallInst *StubCall = B.CreateCall(NewFunc, StubCallArgs);
374 
375  int RetIdx = RetTy->isVoidTy() ? 0 : 1;
376  for (Argument &Arg : F.args()) {
377  if (!OutArgIndexes.count(Arg.getArgNo()))
378  continue;
379 
380  PointerType *ArgType = cast<PointerType>(Arg.getType());
381 
382  Type *EltTy = OutArgIndexes[Arg.getArgNo()];
383  const auto Align =
384  DL->getValueOrABITypeAlignment(Arg.getParamAlign(), EltTy);
385 
386  Value *Val = B.CreateExtractValue(StubCall, RetIdx++);
387  Type *PtrTy = Val->getType()->getPointerTo(ArgType->getAddressSpace());
388 
389  // We can peek through bitcasts, so the type may not match.
390  Value *PtrVal = B.CreateBitCast(&Arg, PtrTy);
391 
392  B.CreateAlignedStore(Val, PtrVal, Align);
393  }
394 
395  if (!RetTy->isVoidTy()) {
396  B.CreateRet(B.CreateExtractValue(StubCall, 0));
397  } else {
398  B.CreateRetVoid();
399  }
400 
401  // The function is now a stub we want to inline.
402  F.addFnAttr(Attribute::AlwaysInline);
403 
404  ++NumOutArgumentFunctionsReplaced;
405  return true;
406 }
407 
409  return new AMDGPURewriteOutArguments();
410 }
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm::GlobalObject::setComdat
void setComdat(Comdat *C)
Definition: Globals.cpp:189
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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::ReturnInst
Return a value (possibly void), from a function.
Definition: Instructions.h:3050
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::Function::getBasicBlockList
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
Definition: Function.h:684
llvm::Function
Definition: Function.h:60
Pass.h
llvm::ReturnInst::getReturnValue
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
Definition: Instructions.h:3095
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::IRBuilder<>
llvm::PointerType::getAddressSpace
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:682
llvm::SmallDenseMap
Definition: DenseMap.h:880
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
DEBUG_TYPE
#define DEBUG_TYPE
Definition: AMDGPURewriteOutArguments.cpp:57
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::AttributeMask
Definition: Attributes.h:978
llvm::Argument::getArgNo
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition: Argument.h:46
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
llvm::MemDepResult
A memory dependence query can return one of three different answers.
Definition: MemoryDependenceAnalysis.h:39
MemoryDependenceAnalysis.h
llvm::StructType::create
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:513
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
CommandLine.h
llvm::Function::stealArgumentListFrom
void stealArgumentListFrom(Function &Src)
Steal arguments from another function.
Definition: Function.cpp:468
SI
@ SI
Definition: SIInstrInfo.cpp:7966
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::Function::removeRetAttrs
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
Definition: Function.cpp:607
llvm::Value::uses
iterator_range< use_iterator > uses()
Definition: Value.h:376
false
Definition: StackSlotColoring.cpp:141
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AMDGPU
Definition: AMDGPUReplaceLDSUseWithPointer.cpp:114
MaxNumRetRegs
static cl::opt< unsigned > MaxNumRetRegs("amdgpu-max-return-arg-num-regs", cl::desc("Approximately limit number of return registers for replacing out arguments"), cl::Hidden, cl::init(16))
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::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::AMDGPU::isEntryFunctionCC
bool isEntryFunctionCC(CallingConv::ID CC)
Definition: AMDGPUBaseInfo.cpp:1831
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::cl::opt< bool >
llvm::MemDepResult::getInst
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
Definition: MemoryDependenceAnalysis.h:167
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:298
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:81
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
llvm::DenseMap
Definition: DenseMap.h:714
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
IRBuilder.h
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:66
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::empty
bool empty() const
Definition: DenseMap.h:98
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(AMDGPURewriteOutArguments, DEBUG_TYPE, "AMDGPU Rewrite Out Arguments", false, false) INITIALIZE_PASS_END(AMDGPURewriteOutArguments
llvm::User::setOperand
void setOperand(unsigned i, Value *Val)
Definition: User.h:174
llvm::createAMDGPURewriteOutArgumentsPass
FunctionPass * createAMDGPURewriteOutArgumentsPass()
Definition: AMDGPURewriteOutArguments.cpp:408
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1741
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
AMDGPU.h
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::Function::begin
iterator begin()
Definition: Function.h:707
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:85
llvm::MemoryDependenceResults
Provides a lazy, caching interface for making common memory aliasing information queries,...
Definition: MemoryDependenceAnalysis.h:266
llvm::MemoryDependenceWrapperPass
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
Definition: MemoryDependenceAnalysis.h:527
llvm::Type::getPointerTo
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:774
llvm::GlobalValue::PrivateLinkage
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
Instructions.h
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:359
llvm::SmallVectorImpl::pop_back_val
T pop_back_val()
Definition: SmallVector.h:677
AnyAddressSpace
static cl::opt< bool > AnyAddressSpace("amdgpu-any-address-space-out-arguments", cl::desc("Replace pointer out arguments with " "struct returns for non-private address space"), cl::Hidden, cl::init(false))
llvm::MemoryLocation::getBeforeOrAfter
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
Definition: MemoryLocation.h:279
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
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
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::cl::desc
Definition: CommandLine.h:413
llvm::AttributeMask::addAttribute
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: Attributes.h:993
raw_ostream.h
llvm::StoreInst::getPointerOperandIndex
static unsigned getPointerOperandIndex()
Definition: Instructions.h:392
Arguments
AMDGPU Rewrite Out Arguments
Definition: AMDGPURewriteOutArguments.cpp:109
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Debug.h
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
AMDGPUBaseInfo.h
SmallSet.h
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1732
llvm::MemDepResult::isDef
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
Definition: MemoryDependenceAnalysis.h:145