003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/NVPTX
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
NVPTX
/
📁
..
📁
MCTargetDesc
📄
ManagedStringPool.h
(1.41 KB)
📄
NVPTX.h
(3.22 KB)
📄
NVPTX.td
(4.99 KB)
📄
NVPTXAllocaHoisting.cpp
(2.12 KB)
📄
NVPTXAllocaHoisting.h
(755 B)
📄
NVPTXAsmPrinter.cpp
(71.02 KB)
📄
NVPTXAsmPrinter.h
(11.23 KB)
📄
NVPTXAssignValidGlobalNames.cpp
(2.74 KB)
📄
NVPTXFrameLowering.cpp
(3.41 KB)
📄
NVPTXFrameLowering.h
(1.34 KB)
📄
NVPTXGenericToNVVM.cpp
(11.59 KB)
📄
NVPTXISelDAGToDAG.cpp
(134.03 KB)
📄
NVPTXISelDAGToDAG.h
(3.54 KB)
📄
NVPTXISelLowering.cpp
(198.59 KB)
📄
NVPTXISelLowering.h
(15.65 KB)
📄
NVPTXImageOptimizer.cpp
(5.64 KB)
📄
NVPTXInstrFormats.td
(1.72 KB)
📄
NVPTXInstrInfo.cpp
(7.88 KB)
📄
NVPTXInstrInfo.h
(2.87 KB)
📄
NVPTXInstrInfo.td
(133.35 KB)
📄
NVPTXIntrinsics.td
(329.76 KB)
📄
NVPTXLowerAggrCopies.cpp
(4.85 KB)
📄
NVPTXLowerAggrCopies.h
(744 B)
📄
NVPTXLowerAlloca.cpp
(4.27 KB)
📄
NVPTXLowerArgs.cpp
(9.16 KB)
📄
NVPTXMCExpr.cpp
(2.04 KB)
📄
NVPTXMCExpr.h
(3.92 KB)
📄
NVPTXMachineFunctionInfo.h
(1.71 KB)
📄
NVPTXPeephole.cpp
(4.92 KB)
📄
NVPTXPrologEpilogPass.cpp
(8.91 KB)
📄
NVPTXProxyRegErasure.cpp
(3.81 KB)
📄
NVPTXRegisterInfo.cpp
(4.41 KB)
📄
NVPTXRegisterInfo.h
(2.04 KB)
📄
NVPTXRegisterInfo.td
(3.12 KB)
📄
NVPTXReplaceImageHandles.cpp
(6.27 KB)
📄
NVPTXSubtarget.cpp
(2.15 KB)
📄
NVPTXSubtarget.h
(3.02 KB)
📄
NVPTXTargetMachine.cpp
(14.25 KB)
📄
NVPTXTargetMachine.h
(3.33 KB)
📄
NVPTXTargetObjectFile.h
(1.53 KB)
📄
NVPTXTargetTransformInfo.cpp
(6.18 KB)
📄
NVPTXTargetTransformInfo.h
(4.7 KB)
📄
NVPTXUtilities.cpp
(9.37 KB)
📄
NVPTXUtilities.h
(2.03 KB)
📄
NVVMIntrRange.cpp
(4.88 KB)
📄
NVVMReflect.cpp
(6.8 KB)
📁
TargetInfo
📄
cl_common_defines.h
(3.94 KB)
Editing: NVPTXImageOptimizer.cpp
//===-- NVPTXImageOptimizer.cpp - Image optimization pass -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This pass implements IR-level optimizations of image access code, // including: // // 1. Eliminate istypep intrinsics when image access qualifier is known // //===----------------------------------------------------------------------===// #include "NVPTX.h" #include "NVPTXUtilities.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" using namespace llvm; namespace { class NVPTXImageOptimizer : public FunctionPass { private: static char ID; SmallVector<Instruction*, 4> InstrToDelete; public: NVPTXImageOptimizer(); bool runOnFunction(Function &F) override; private: bool replaceIsTypePSampler(Instruction &I); bool replaceIsTypePSurface(Instruction &I); bool replaceIsTypePTexture(Instruction &I); Value *cleanupValue(Value *V); void replaceWith(Instruction *From, ConstantInt *To); }; } char NVPTXImageOptimizer::ID = 0; NVPTXImageOptimizer::NVPTXImageOptimizer() : FunctionPass(ID) {} bool NVPTXImageOptimizer::runOnFunction(Function &F) { if (skipFunction(F)) return false; bool Changed = false; InstrToDelete.clear(); // Look for call instructions in the function for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { for (BasicBlock::iterator I = (*BI).begin(), E = (*BI).end(); I != E; ++I) { Instruction &Instr = *I; if (CallInst *CI = dyn_cast<CallInst>(I)) { Function *CalledF = CI->getCalledFunction(); if (CalledF && CalledF->isIntrinsic()) { // This is an intrinsic function call, check if its an istypep switch (CalledF->getIntrinsicID()) { default: break; case Intrinsic::nvvm_istypep_sampler: Changed |= replaceIsTypePSampler(Instr); break; case Intrinsic::nvvm_istypep_surface: Changed |= replaceIsTypePSurface(Instr); break; case Intrinsic::nvvm_istypep_texture: Changed |= replaceIsTypePTexture(Instr); break; } } } } } // Delete any istypep instances we replaced in the IR for (unsigned i = 0, e = InstrToDelete.size(); i != e; ++i) InstrToDelete[i]->eraseFromParent(); return Changed; } bool NVPTXImageOptimizer::replaceIsTypePSampler(Instruction &I) { Value *TexHandle = cleanupValue(I.getOperand(0)); if (isSampler(*TexHandle)) { // This is an OpenCL sampler, so it must be a samplerref replaceWith(&I, ConstantInt::getTrue(I.getContext())); return true; } else if (isImage(*TexHandle)) { // This is an OpenCL image, so it cannot be a samplerref replaceWith(&I, ConstantInt::getFalse(I.getContext())); return true; } else { // The image type is unknown, so we cannot eliminate the intrinsic return false; } } bool NVPTXImageOptimizer::replaceIsTypePSurface(Instruction &I) { Value *TexHandle = cleanupValue(I.getOperand(0)); if (isImageReadWrite(*TexHandle) || isImageWriteOnly(*TexHandle)) { // This is an OpenCL read-only/read-write image, so it must be a surfref replaceWith(&I, ConstantInt::getTrue(I.getContext())); return true; } else if (isImageReadOnly(*TexHandle) || isSampler(*TexHandle)) { // This is an OpenCL read-only/ imageor sampler, so it cannot be // a surfref replaceWith(&I, ConstantInt::getFalse(I.getContext())); return true; } else { // The image type is unknown, so we cannot eliminate the intrinsic return false; } } bool NVPTXImageOptimizer::replaceIsTypePTexture(Instruction &I) { Value *TexHandle = cleanupValue(I.getOperand(0)); if (isImageReadOnly(*TexHandle)) { // This is an OpenCL read-only image, so it must be a texref replaceWith(&I, ConstantInt::getTrue(I.getContext())); return true; } else if (isImageWriteOnly(*TexHandle) || isImageReadWrite(*TexHandle) || isSampler(*TexHandle)) { // This is an OpenCL read-write/write-only image or a sampler, so it // cannot be a texref replaceWith(&I, ConstantInt::getFalse(I.getContext())); return true; } else { // The image type is unknown, so we cannot eliminate the intrinsic return false; } } void NVPTXImageOptimizer::replaceWith(Instruction *From, ConstantInt *To) { // We implement "poor man's DCE" here to make sure any code that is no longer // live is actually unreachable and can be trivially eliminated by the // unreachable block elimination pass. for (CallInst::use_iterator UI = From->use_begin(), UE = From->use_end(); UI != UE; ++UI) { if (BranchInst *BI = dyn_cast<BranchInst>(*UI)) { if (BI->isUnconditional()) continue; BasicBlock *Dest; if (To->isZero()) // Get false block Dest = BI->getSuccessor(1); else // Get true block Dest = BI->getSuccessor(0); BranchInst::Create(Dest, BI); InstrToDelete.push_back(BI); } } From->replaceAllUsesWith(To); InstrToDelete.push_back(From); } Value *NVPTXImageOptimizer::cleanupValue(Value *V) { if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(V)) { return cleanupValue(EVI->getAggregateOperand()); } return V; } FunctionPass *llvm::createNVPTXImageOptimizerPass() { return new NVPTXImageOptimizer(); }
Upload File
Create Folder