LLVM  15.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 (BasicBlock &BB : F) {
61  for (Instruction &Instr : BB) {
62  if (CallInst *CI = dyn_cast<CallInst>(&Instr)) {
63  Function *CalledF = CI->getCalledFunction();
64  if (CalledF && CalledF->isIntrinsic()) {
65  // This is an intrinsic function call, check if its an istypep
66  switch (CalledF->getIntrinsicID()) {
67  default: break;
68  case Intrinsic::nvvm_istypep_sampler:
69  Changed |= replaceIsTypePSampler(Instr);
70  break;
71  case Intrinsic::nvvm_istypep_surface:
72  Changed |= replaceIsTypePSurface(Instr);
73  break;
74  case Intrinsic::nvvm_istypep_texture:
75  Changed |= replaceIsTypePTexture(Instr);
76  break;
77  }
78  }
79  }
80  }
81  }
82 
83  // Delete any istypep instances we replaced in the IR
84  for (Instruction *I : InstrToDelete)
85  I->eraseFromParent();
86 
87  return Changed;
88 }
89 
90 bool NVPTXImageOptimizer::replaceIsTypePSampler(Instruction &I) {
91  Value *TexHandle = cleanupValue(I.getOperand(0));
92  if (isSampler(*TexHandle)) {
93  // This is an OpenCL sampler, so it must be a samplerref
94  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
95  return true;
96  } else if (isImage(*TexHandle)) {
97  // This is an OpenCL image, so it cannot be a samplerref
98  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
99  return true;
100  } else {
101  // The image type is unknown, so we cannot eliminate the intrinsic
102  return false;
103  }
104 }
105 
106 bool NVPTXImageOptimizer::replaceIsTypePSurface(Instruction &I) {
107  Value *TexHandle = cleanupValue(I.getOperand(0));
108  if (isImageReadWrite(*TexHandle) ||
109  isImageWriteOnly(*TexHandle)) {
110  // This is an OpenCL read-only/read-write image, so it must be a surfref
111  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
112  return true;
113  } else if (isImageReadOnly(*TexHandle) ||
114  isSampler(*TexHandle)) {
115  // This is an OpenCL read-only/ imageor sampler, so it cannot be
116  // a surfref
117  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
118  return true;
119  } else {
120  // The image type is unknown, so we cannot eliminate the intrinsic
121  return false;
122  }
123 }
124 
125 bool NVPTXImageOptimizer::replaceIsTypePTexture(Instruction &I) {
126  Value *TexHandle = cleanupValue(I.getOperand(0));
127  if (isImageReadOnly(*TexHandle)) {
128  // This is an OpenCL read-only image, so it must be a texref
129  replaceWith(&I, ConstantInt::getTrue(I.getContext()));
130  return true;
131  } else if (isImageWriteOnly(*TexHandle) ||
132  isImageReadWrite(*TexHandle) ||
133  isSampler(*TexHandle)) {
134  // This is an OpenCL read-write/write-only image or a sampler, so it
135  // cannot be a texref
136  replaceWith(&I, ConstantInt::getFalse(I.getContext()));
137  return true;
138  } else {
139  // The image type is unknown, so we cannot eliminate the intrinsic
140  return false;
141  }
142 }
143 
144 void NVPTXImageOptimizer::replaceWith(Instruction *From, ConstantInt *To) {
145  // We implement "poor man's DCE" here to make sure any code that is no longer
146  // live is actually unreachable and can be trivially eliminated by the
147  // unreachable block elimination pass.
148  for (Use &U : From->uses()) {
149  if (BranchInst *BI = dyn_cast<BranchInst>(U)) {
150  if (BI->isUnconditional()) continue;
151  BasicBlock *Dest;
152  if (To->isZero())
153  // Get false block
154  Dest = BI->getSuccessor(1);
155  else
156  // Get true block
157  Dest = BI->getSuccessor(0);
158  BranchInst::Create(Dest, BI);
159  InstrToDelete.push_back(BI);
160  }
161  }
162  From->replaceAllUsesWith(To);
163  InstrToDelete.push_back(From);
164 }
165 
166 Value *NVPTXImageOptimizer::cleanupValue(Value *V) {
167  if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(V)) {
168  return cleanupValue(EVI->getAggregateOperand());
169  }
170  return V;
171 }
172 
174  return new NVPTXImageOptimizer();
175 }
llvm::Function::isIntrinsic
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition: Function.h:210
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::Function
Definition: Function.h:60
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:1185
Module.h
llvm::isImage
bool isImage(const Value &val)
Definition: NVPTXUtilities.cpp:212
ConstantFolding.h
F
#define F(x, y, z)
Definition: MD5.cpp:55
NVPTX.h
llvm::isSampler
bool isSampler(const Value &val)
Definition: NVPTXUtilities.cpp:155
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
NVPTXUtilities.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
Intrinsics.h
llvm::Instruction
Definition: Instruction.h:42
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::isImageReadOnly
bool isImageReadOnly(const Value &val)
Definition: NVPTXUtilities.cpp:176
I
#define I(x, y, z)
Definition: MD5.cpp:58
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:121
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:194
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:2398
llvm::createNVPTXImageOptimizerPass
FunctionPass * createNVPTXImageOptimizerPass()
Definition: NVPTXImageOptimizer.cpp:173
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:308
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1461
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
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::BranchInst
Conditional or Unconditional Branch instruction.
Definition: Instructions.h:3086
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38