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