1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #pragma once 10 #include "Compiler/CodeGenContextWrapper.hpp" 11 #include "Compiler/MetaDataUtilsWrapper.h" 12 #include "common/MDFrameWork.h" 13 #include "common/LLVMWarningsPush.hpp" 14 #include "llvm/Config/llvm-config.h" 15 #include "llvm/Pass.h" 16 #include "llvm/IR/InstVisitor.h" 17 #include "llvm/Analysis/TargetLibraryInfo.h" 18 #include "llvm/Analysis/LoopPass.h" 19 #include "llvm/IR/Instructions.h" 20 #include "llvm/IR/ConstantFolder.h" 21 #include "common/LLVMWarningsPop.hpp" 22 23 namespace llvm 24 { 25 // Forward declare: 26 class SampleIntrinsic; 27 class SamplerLoadIntrinsic; 28 } 29 30 namespace IGC 31 { 32 class CustomSafeOptPass : public llvm::FunctionPass, public llvm::InstVisitor<CustomSafeOptPass> 33 { 34 public: 35 static char ID; 36 37 CustomSafeOptPass(); 38 ~CustomSafeOptPass()39 ~CustomSafeOptPass() {} 40 getAnalysisUsage(llvm::AnalysisUsage & AU) const41 virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const override 42 { 43 AU.addRequired<CodeGenContextWrapper>(); 44 AU.setPreservesCFG(); 45 } 46 47 virtual bool runOnFunction(llvm::Function& F) override; 48 getPassName() const49 virtual llvm::StringRef getPassName() const override 50 { 51 return "Custom Pass Optimization"; 52 } 53 54 void visitInstruction(llvm::Instruction& I); 55 void visitUDiv(llvm::BinaryOperator& I); 56 void visitAllocaInst(llvm::AllocaInst& I); 57 void visitCallInst(llvm::CallInst& C); 58 void removeHftoFCast(llvm::Instruction& I); 59 void visitBinaryOperator(llvm::BinaryOperator& I); 60 bool isEmulatedAdd(llvm::BinaryOperator& I); 61 void visitBfi(llvm::CallInst* inst); 62 void visitf32tof16(llvm::CallInst* inst); 63 void visitSampleBptr(llvm::SampleIntrinsic* inst); 64 void visitMulH(llvm::CallInst* inst, bool isSigned); 65 void visitFPToUIInst(llvm::FPToUIInst& FPUII); 66 void visitFPTruncInst(llvm::FPTruncInst& I); 67 void visitExtractElementInst(llvm::ExtractElementInst& I); 68 void visitLdptr(llvm::SamplerLoadIntrinsic* inst); 69 void visitLdRawVec(llvm::CallInst* inst); 70 void visitLoadInst(llvm::LoadInst& I); 71 void dp4WithIdentityMatrix(llvm::ExtractElementInst& I); 72 bool isIdentityMatrix(llvm::ExtractElementInst& I); 73 void visitAnd(llvm::BinaryOperator& I); 74 void visitXor(llvm::Instruction& XorInstr); 75 76 // 77 // IEEE Floating point arithmetic is not associative. Any pattern 78 // match that changes the order or paramters is unsafe. 79 // 80 81 // 82 // Removing sources is also unsafe. 83 // X * 1 => X : Unsafe 84 // X + 0 => X : Unsafe 85 // X - X => X : Unsafe 86 // 87 88 // When in doubt assume a floating point optimization is unsafe! 89 90 void visitBinaryOperatorTwoConstants(llvm::BinaryOperator& I); 91 void visitBinaryOperatorPropNegate(llvm::BinaryOperator& I); 92 void visitBitCast(llvm::BitCastInst& BC); 93 94 void matchDp4a(llvm::BinaryOperator& I); 95 96 template <typename MaskType> void matchReverse(llvm::BinaryOperator& I); 97 private: 98 bool psHasSideEffect; 99 }; 100 101 #if LLVM_VERSION_MAJOR >= 7 102 class TrivialLocalMemoryOpsElimination : public llvm::FunctionPass, public llvm::InstVisitor<TrivialLocalMemoryOpsElimination> 103 { 104 public: 105 static char ID; 106 107 TrivialLocalMemoryOpsElimination(); 108 ~TrivialLocalMemoryOpsElimination()109 ~TrivialLocalMemoryOpsElimination() {} 110 getAnalysisUsage(llvm::AnalysisUsage & AU) const111 virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const override 112 { 113 AU.addRequired<CodeGenContextWrapper>(); 114 AU.addRequired<MetaDataUtilsWrapper>(); 115 AU.setPreservesCFG(); 116 } 117 118 virtual bool runOnFunction(llvm::Function& F) override; 119 getPassName() const120 virtual llvm::StringRef getPassName() const override 121 { 122 return "TrivialLocalMemoryOpsElimination"; 123 } 124 125 void visitLoadInst(llvm::LoadInst& I); 126 void visitStoreInst(llvm::StoreInst& I); 127 void visitCallInst(llvm::CallInst& I); 128 bool isLocalBarrier(llvm::CallInst& I); 129 void findNextThreadGroupBarrierInst(llvm::Instruction& I); 130 void anyCallInstUseLocalMemory(llvm::CallInst& I); 131 132 private: 133 llvm::SmallVector<llvm::LoadInst*, 16> m_LocalLoadsToRemove; 134 llvm::SmallVector<llvm::StoreInst*, 16> m_LocalStoresToRemove; 135 llvm::SmallVector<llvm::CallInst*, 16> m_LocalFencesBariersToRemove; 136 137 bool abortPass = false; 138 const std::vector<bool> m_argumentsOfLocalMemoryBarrier{ true, false, false, false, false, false, true }; 139 }; 140 #endif 141 142 class GenSpecificPattern : public llvm::FunctionPass, public llvm::InstVisitor<GenSpecificPattern> 143 { 144 public: 145 static char ID; 146 147 GenSpecificPattern(); 148 ~GenSpecificPattern()149 ~GenSpecificPattern() {} 150 getAnalysisUsage(llvm::AnalysisUsage & AU) const151 virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const override 152 { 153 AU.setPreservesCFG(); 154 AU.addRequired<CodeGenContextWrapper>(); 155 } 156 157 virtual bool runOnFunction(llvm::Function& F) override; 158 getPassName() const159 virtual llvm::StringRef getPassName() const override 160 { 161 return "GenSpecificPattern"; 162 } 163 164 void visitBinaryOperator(llvm::BinaryOperator& I); 165 void visitSelectInst(llvm::SelectInst& I); 166 void visitCmpInst(llvm::CmpInst& I); 167 void visitZExtInst(llvm::ZExtInst& I); 168 void visitCastInst(llvm::CastInst& I); 169 void visitIntToPtr(llvm::IntToPtrInst& I); 170 void visitSDiv(llvm::BinaryOperator& I); 171 void visitTruncInst(llvm::TruncInst& I); 172 void visitBitCastInst(llvm::BitCastInst& I); 173 void visitLoadInst(llvm::LoadInst& I); 174 #if LLVM_VERSION_MAJOR >= 10 175 void visitFNeg(llvm::UnaryOperator& I); 176 #endif 177 178 void createBitcastExtractInsertPattern(llvm::BinaryOperator& I, 179 llvm::Value* Op1, llvm::Value* Op2, unsigned extractNum1, unsigned extractNum2); 180 }; 181 182 class FCmpPaternMatch : public llvm::FunctionPass, public llvm::InstVisitor<FCmpPaternMatch> 183 { 184 public: 185 static char ID; 186 187 FCmpPaternMatch(); 188 ~FCmpPaternMatch()189 ~FCmpPaternMatch() {} 190 191 virtual bool runOnFunction(llvm::Function& F) override; 192 getPassName() const193 virtual llvm::StringRef getPassName() const override 194 { 195 return "FCmpPaternMatch"; 196 } 197 198 void visitSelectInst(llvm::SelectInst& I); 199 }; 200 201 class IGCConstProp : public llvm::FunctionPass 202 { 203 public: 204 static char ID; 205 206 IGCConstProp(bool enableSimplifyGEP = false); 207 ~IGCConstProp()208 ~IGCConstProp() {} 209 getAnalysisUsage(llvm::AnalysisUsage & AU) const210 virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const override 211 { 212 AU.addRequired<llvm::TargetLibraryInfoWrapperPass>(); 213 AU.addRequired<CodeGenContextWrapper>(); 214 AU.setPreservesCFG(); 215 } 216 217 virtual bool runOnFunction(llvm::Function& F) override; 218 getPassName() const219 virtual llvm::StringRef getPassName() const override 220 { 221 // specialized const-prop with shader-const replacement 222 return "const-prop with shader-const replacement"; 223 } 224 225 private: 226 llvm::Module* module; 227 llvm::Constant* replaceShaderConstant(llvm::Instruction* inst); 228 llvm::Constant* ConstantFoldCmpInst(llvm::CmpInst* inst); 229 llvm::Constant* ConstantFoldExtractElement(llvm::ExtractElementInst* inst); 230 llvm::Constant* ConstantFoldCallInstruction(llvm::CallInst* inst); 231 bool simplifyAdd(llvm::BinaryOperator* BO); 232 bool simplifyGEP(llvm::GetElementPtrInst* GEP); 233 bool m_enableMathConstProp; 234 bool m_enableSimplifyGEP; 235 const llvm::DataLayout* m_TD; 236 llvm::TargetLibraryInfo* m_TLI; 237 }; 238 239 llvm::FunctionPass* createVectorBitCastOptPass(); 240 llvm::FunctionPass* createGenStrengthReductionPass(); 241 llvm::FunctionPass* createNanHandlingPass(); 242 llvm::FunctionPass* createFlattenSmallSwitchPass(); 243 llvm::FunctionPass* createSplitIndirectEEtoSelPass(); 244 llvm::FunctionPass* createIGCIndirectICBPropagaionPass(); 245 llvm::FunctionPass* createBlendToDiscardPass(); 246 llvm::FunctionPass* createMarkReadOnlyLoadPass(); 247 llvm::FunctionPass* createLogicalAndToBranchPass(); 248 llvm::FunctionPass* createCleanPHINodePass(); 249 250 } // namespace IGC 251