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