LLVM  6.0.0svn
AMDGPULowerIntrinsics.cpp
Go to the documentation of this file.
1 //===-- AMDGPULowerIntrinsics.cpp -----------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "AMDGPU.h"
11 #include "AMDGPUSubtarget.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/IntrinsicInst.h"
17 #include "llvm/IR/Module.h"
19 
20 #define DEBUG_TYPE "amdgpu-lower-intrinsics"
21 
22 using namespace llvm;
23 
24 namespace {
25 
26 const unsigned MaxStaticSize = 1024;
27 
28 class AMDGPULowerIntrinsics : public ModulePass {
29 private:
30  bool makeLIDRangeMetadata(Function &F) const;
31 
32 public:
33  static char ID;
34 
35  AMDGPULowerIntrinsics() : ModulePass(ID) {}
36 
37  bool runOnModule(Module &M) override;
38  bool expandMemIntrinsicUses(Function &F);
39  StringRef getPassName() const override {
40  return "AMDGPU Lower Intrinsics";
41  }
42 
43  void getAnalysisUsage(AnalysisUsage &AU) const override {
45  }
46 };
47 
48 }
49 
51 
53 
54 INITIALIZE_PASS(AMDGPULowerIntrinsics, DEBUG_TYPE, "Lower intrinsics", false,
55  false)
56 
57 // TODO: Should refine based on estimated number of accesses (e.g. does it
58 // require splitting based on alignment)
59 static bool shouldExpandOperationWithSize(Value *Size) {
61  return !CI || (CI->getZExtValue() > MaxStaticSize);
62 }
63 
64 bool AMDGPULowerIntrinsics::expandMemIntrinsicUses(Function &F) {
66  bool Changed = false;
67 
68  for (auto I = F.user_begin(), E = F.user_end(); I != E;) {
69  Instruction *Inst = cast<Instruction>(*I);
70  ++I;
71 
72  switch (ID) {
73  case Intrinsic::memcpy: {
74  auto *Memcpy = cast<MemCpyInst>(Inst);
75  if (shouldExpandOperationWithSize(Memcpy->getLength())) {
76  Function *ParentFunc = Memcpy->getParent()->getParent();
77  const TargetTransformInfo &TTI =
78  getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*ParentFunc);
79  expandMemCpyAsLoop(Memcpy, TTI);
80  Changed = true;
81  Memcpy->eraseFromParent();
82  }
83 
84  break;
85  }
86  case Intrinsic::memmove: {
87  auto *Memmove = cast<MemMoveInst>(Inst);
88  if (shouldExpandOperationWithSize(Memmove->getLength())) {
89  expandMemMoveAsLoop(Memmove);
90  Changed = true;
91  Memmove->eraseFromParent();
92  }
93 
94  break;
95  }
96  case Intrinsic::memset: {
97  auto *Memset = cast<MemSetInst>(Inst);
98  if (shouldExpandOperationWithSize(Memset->getLength())) {
99  expandMemSetAsLoop(Memset);
100  Changed = true;
101  Memset->eraseFromParent();
102  }
103 
104  break;
105  }
106  default:
107  break;
108  }
109  }
110 
111  return Changed;
112 }
113 
114 bool AMDGPULowerIntrinsics::makeLIDRangeMetadata(Function &F) const {
115  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
116  if (!TPC)
117  return false;
118 
119  const TargetMachine &TM = TPC->getTM<TargetMachine>();
121  bool Changed = false;
122 
123  for (auto *U : F.users()) {
124  auto *CI = dyn_cast<CallInst>(U);
125  if (!CI)
126  continue;
127 
128  Changed |= ST.makeLIDRangeMetadata(CI);
129  }
130  return Changed;
131 }
132 
133 bool AMDGPULowerIntrinsics::runOnModule(Module &M) {
134  bool Changed = false;
135 
136  for (Function &F : M) {
137  if (!F.isDeclaration())
138  continue;
139 
140  switch (F.getIntrinsicID()) {
141  case Intrinsic::memcpy:
142  case Intrinsic::memmove:
143  case Intrinsic::memset:
144  if (expandMemIntrinsicUses(F))
145  Changed = true;
146  break;
147 
148  case Intrinsic::amdgcn_workitem_id_x:
149  case Intrinsic::r600_read_tidig_x:
150  case Intrinsic::amdgcn_workitem_id_y:
151  case Intrinsic::r600_read_tidig_y:
152  case Intrinsic::amdgcn_workitem_id_z:
153  case Intrinsic::r600_read_tidig_z:
154  case Intrinsic::r600_read_local_size_x:
155  case Intrinsic::r600_read_local_size_y:
156  case Intrinsic::r600_read_local_size_z:
157  Changed |= makeLIDRangeMetadata(F);
158  break;
159 
160  default:
161  break;
162  }
163  }
164 
165  return Changed;
166 }
167 
169  return new AMDGPULowerIntrinsics();
170 }
AMDGPU specific subclass of TargetSubtarget.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void expandMemMoveAsLoop(MemMoveInst *MemMove)
Expand MemMove as a loop. MemMove is not deleted.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
INITIALIZE_PASS(AMDGPULowerIntrinsics, DEBUG_TYPE, "Lower intrinsics", false, false) static bool shouldExpandOperationWithSize(Value *Size)
This class represents a function call, abstracting a target machine&#39;s calling convention.
F(f)
void expandMemSetAsLoop(MemSetInst *MemSet)
Expand MemSet as a loop. MemSet is not deleted.
AnalysisUsage & addRequired()
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:149
Wrapper pass for TargetTransformInfo.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Represent the analysis usage information of a pass.
ModulePass * createAMDGPULowerIntrinsicsPass()
#define DEBUG_TYPE
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Module.h This file contains the declarations for the Module class.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:175
iterator_range< user_iterator > users()
Definition: Value.h:401
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
char & AMDGPULowerIntrinsicsID
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:201
user_iterator user_begin()
Definition: Value.h:377
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:556
LLVM Value Representation.
Definition: Value.h:73
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:57
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
This pass exposes codegen information to IR-level passes.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI)
Expand MemCpy as a loop. MemCpy is not deleted.
user_iterator user_end()
Definition: Value.h:385