LLVM  8.0.1
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>();
120  bool Changed = false;
121 
122  for (auto *U : F.users()) {
123  auto *CI = dyn_cast<CallInst>(U);
124  if (!CI)
125  continue;
126 
127  Changed |= AMDGPUSubtarget::get(TM, F).makeLIDRangeMetadata(CI);
128  }
129  return Changed;
130 }
131 
132 bool AMDGPULowerIntrinsics::runOnModule(Module &M) {
133  bool Changed = false;
134 
135  for (Function &F : M) {
136  if (!F.isDeclaration())
137  continue;
138 
139  switch (F.getIntrinsicID()) {
140  case Intrinsic::memcpy:
141  case Intrinsic::memmove:
142  case Intrinsic::memset:
143  if (expandMemIntrinsicUses(F))
144  Changed = true;
145  break;
146 
156  Changed |= makeLIDRangeMetadata(F);
157  break;
158 
159  default:
160  break;
161  }
162  }
163 
164  return Changed;
165 }
166 
168  return new AMDGPULowerIntrinsics();
169 }
bool makeLIDRangeMetadata(Instruction *I) const
Creates value range metadata on an workitemid.* inrinsic call or load.
AMDGPU specific subclass of TargetSubtarget.
This class represents lattice values for constants.
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:65
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.
static const AMDGPUSubtarget & get(const MachineFunction &MF)
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:194
iterator_range< user_iterator > users()
Definition: Value.h:400
#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
uint32_t Size
Definition: Profile.cpp:47
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:206
user_iterator user_begin()
Definition: Value.h:376
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:566
LLVM Value Representation.
Definition: Value.h:73
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
This pass exposes codegen information to IR-level passes.
void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI)
Expand MemCpy as a loop. MemCpy is not deleted.
user_iterator user_end()
Definition: Value.h:384