LLVM  10.0.0svn
NVPTXImageOptimizer.cpp
Go to the documentation of this file.
1 //===-- NVPTXImageOptimizer.cpp - Image optimization pass -----------------===//
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 // This pass implements IR-level optimizations of image access code,
10 // including:
11 //
12 // 1. Eliminate istypep intrinsics when image access qualifier is known
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "NVPTX.h"
17 #include "NVPTXUtilities.h"
19 #include "llvm/IR/Instructions.h"
20 #include "llvm/IR/Intrinsics.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Pass.h"
23 
24 using namespace llvm;
25 
26 namespace {
27 class NVPTXImageOptimizer : public FunctionPass {
28 private:
29  static char ID;
30  SmallVector<Instruction*, 4> InstrToDelete;
31 
32 public:
33  NVPTXImageOptimizer();
34 
35  bool runOnFunction(Function &F) override;
36 
37 private:
38  bool replaceIsTypePSampler(Instruction &I);
39  bool replaceIsTypePSurface(Instruction &I);
40  bool replaceIsTypePTexture(Instruction &I);
41  Value *cleanupValue(Value *V);
42  void replaceWith(Instruction *From, ConstantInt *To);
43 };
44 }
45 
47 
48 NVPTXImageOptimizer::NVPTXImageOptimizer()
49  : FunctionPass(ID) {}
50 
52  if (skipFunction(F))
53  return false;
54 
55  bool Changed = false;
56  InstrToDelete.clear();
57 
58  // Look for call instructions in the function
59  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE;
60  ++BI) {
61  for (BasicBlock::iterator I = (*BI).begin(), E = (*BI).end();
62  I != E; ++I) {
63  Instruction &Instr = *I;
64  if (CallInst *CI = dyn_cast<CallInst>(I)) {
65  Function *CalledF = CI->getCalledFunction();
66  if (CalledF && CalledF->isIntrinsic()) {
67  // This is an intrinsic function call, check if its an istypep
68  switch (CalledF->getIntrinsicID()) {
69  default: break;
70  case Intrinsic::nvvm_istypep_sampler:
71  Changed |= replaceIsTypePSampler(Instr);
72  break;
73  case Intrinsic::nvvm_istypep_surface:
74  Changed |= replaceIsTypePSurface(Instr);
75  break;
76  case Intrinsic::nvvm_istypep_texture:
77  Changed |= replaceIsTypePTexture(Instr);
78  break;
79  }
80  }
81  }
82  }
83  }
84 
85  // Delete any istypep instances we replaced in the IR
86  for (unsigned i = 0, e = InstrToDelete.size(); i != e; ++i)
87  InstrToDelete[i]->eraseFromParent();
88 
89  return Changed;
90 }
91 
92 bool NVPTXImageOptimizer::replaceIsTypePSampler(Instruction &I) {
93  Value *TexHandle = cleanupValue(I.getOperand(0));
94  if (isSampler(*TexHandle)) {
95  // This is an OpenCL sampler, so it must be a samplerref
96  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
97  return true;
98  } else if (isImage(*TexHandle)) {
99  // This is an OpenCL image, so it cannot be a samplerref
100  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
101  return true;
102  } else {
103  // The image type is unknown, so we cannot eliminate the intrinsic
104  return false;
105  }
106 }
107 
108 bool NVPTXImageOptimizer::replaceIsTypePSurface(Instruction &I) {
109  Value *TexHandle = cleanupValue(I.getOperand(0));
110  if (isImageReadWrite(*TexHandle) ||
111  isImageWriteOnly(*TexHandle)) {
112  // This is an OpenCL read-only/read-write image, so it must be a surfref
113  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
114  return true;
115  } else if (isImageReadOnly(*TexHandle) ||
116  isSampler(*TexHandle)) {
117  // This is an OpenCL read-only/ imageor sampler, so it cannot be
118  // a surfref
119  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
120  return true;
121  } else {
122  // The image type is unknown, so we cannot eliminate the intrinsic
123  return false;
124  }
125 }
126 
127 bool NVPTXImageOptimizer::replaceIsTypePTexture(Instruction &I) {
128  Value *TexHandle = cleanupValue(I.getOperand(0));
129  if (isImageReadOnly(*TexHandle)) {
130  // This is an OpenCL read-only image, so it must be a texref
131  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
132  return true;
133  } else if (isImageWriteOnly(*TexHandle) ||
134  isImageReadWrite(*TexHandle) ||
135  isSampler(*TexHandle)) {
136  // This is an OpenCL read-write/write-only image or a sampler, so it
137  // cannot be a texref
138  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
139  return true;
140  } else {
141  // The image type is unknown, so we cannot eliminate the intrinsic
142  return false;
143  }
144 }
145 
146 void NVPTXImageOptimizer::replaceWith(Instruction *From, ConstantInt *To) {
147  // We implement "poor man's DCE" here to make sure any code that is no longer
148  // live is actually unreachable and can be trivially eliminated by the
149  // unreachable block elimination pass.
150  for (CallInst::use_iterator UI = From->use_begin(), UE = From->use_end();
151  UI != UE; ++UI) {
152  if (BranchInst *BI = dyn_cast<BranchInst>(*UI)) {
153  if (BI->isUnconditional()) continue;
154  BasicBlock *Dest;
155  if (To->isZero())
156  // Get false block
157  Dest = BI->getSuccessor(1);
158  else
159  // Get true block
160  Dest = BI->getSuccessor(0);
161  BranchInst::Create(Dest, BI);
162  InstrToDelete.push_back(BI);
163  }
164  }
165  From->replaceAllUsesWith(To);
166  InstrToDelete.push_back(From);
167 }
168 
169 Value *NVPTXImageOptimizer::cleanupValue(Value *V) {
170  if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(V)) {
171  return cleanupValue(EVI->getAggregateOperand());
172  }
173  return V;
174 }
175 
177  return new NVPTXImageOptimizer();
178 }
bool isIntrinsic() const
isIntrinsic - Returns true if the function&#39;s name starts with "llvm.".
Definition: Function.h:198
use_iterator use_end()
Definition: Value.h:366
This instruction extracts a struct member or array element value from an aggregate value...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
iterator end()
Definition: Function.h:682
This class represents a function call, abstracting a target machine&#39;s calling convention.
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:733
F(f)
static Constant * getTrue(Type *Ty)
For a boolean type or a vector of boolean type, return true or a vector with every element true...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:429
FunctionPass * createNVPTXImageOptimizerPass()
iterator begin()
Definition: Function.h:680
bool isSampler(const Value &val)
Value * getOperand(unsigned i) const
Definition: User.h:169
static bool runOnFunction(Function &F, bool PostInlining)
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
Conditional or Unconditional Branch instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
bool isImage(const Value &val)
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
BlockVerifier::State From
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Module.h This file contains the declarations for the Module class.
bool isImageReadWrite(const Value &val)
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:193
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false...
use_iterator use_begin()
Definition: Value.h:358
bool isImageReadOnly(const Value &val)
#define I(x, y, z)
Definition: MD5.cpp:58
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:192
LLVM Value Representation.
Definition: Value.h:73
bool isImageWriteOnly(const Value &val)