1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2020-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef VISA_PASSES_MERGESCALAR_HPP
10 #define VISA_PASSES_MERGESCALAR_HPP
11 
12 #include "../G4_IR.hpp"
13 #include "../BuildIR.h"
14 #include "../FlowGraph.h"
15 
16 namespace vISA {
17 
18 // use by mergeScalar
19 #define OPND_PATTERN_ENUM(DO) \
20     DO(UNKNOWN) \
21     DO(IDENTICAL) \
22     DO(CONTIGUOUS) \
23     DO(DISJOINT)
24 
25 enum OPND_PATTERN
26 {
27     OPND_PATTERN_ENUM(MAKE_ENUM)
28 };
29 
30 static const char* patternNames[] =
31 {
32     OPND_PATTERN_ENUM(STRINGIFY)
33 };
34 
35 struct BUNDLE_INFO
36 {
37     static constexpr int maxBundleSize = 16;
38     static constexpr int maxNumSrc = 3;
39     int size;
40     int sizeLimit;
41     G4_BB* bb;
42     INST_LIST_ITER startIter;
43     G4_INST* inst[maxBundleSize];
44     OPND_PATTERN dstPattern;
45     OPND_PATTERN srcPattern[maxNumSrc];
46 
BUNDLE_INFOvISA::BUNDLE_INFO47     BUNDLE_INFO(G4_BB* instBB, INST_LIST_ITER& instPos, int limit) : sizeLimit(limit), bb(instBB)
48     {
49 
50         inst[0] = *instPos;
51         startIter = instPos;
52         dstPattern = OPND_PATTERN::UNKNOWN;
53         for (int i = 0; i < maxNumSrc; i++)
54         {
55             srcPattern[i] = OPND_PATTERN::UNKNOWN;
56         }
57         size = 1;
58     }
59 
operator newvISA::BUNDLE_INFO60     void* operator new(size_t sz, Mem_Manager& m) { return m.alloc(sz); }
61 
appendInstvISA::BUNDLE_INFO62     void appendInst(G4_INST* lastInst)
63     {
64         MUST_BE_TRUE(size < maxBundleSize, "max bundle size exceeded");
65         inst[size++] = lastInst;
66     }
67 
deleteLastInstvISA::BUNDLE_INFO68     void deleteLastInst()
69     {
70         assert(size > 0 && "empty bundle");
71         inst[--size] = nullptr;
72     }
73 
74     bool canMergeDst(G4_DstRegRegion* dst);
75     bool canMergeSource(G4_Operand* src, int srcPos);
76     bool canMerge(G4_INST* inst);
77 
78     bool doMerge(IR_Builder& builder,
79         std::unordered_set<G4_Declare*>& modifiedDcl,
80         std::vector<G4_Declare*>& newInputs);
81 
printvISA::BUNDLE_INFO82     void print(std::ostream& output) const
83     {
84         output << "Bundle:\n";
85         output << "Dst pattern:\t" << patternNames[dstPattern] << "\n";
86         output << "Src Pattern:\t";
87         for (int i = 0; i < inst[0]->getNumSrc(); ++i)
88         {
89             output << patternNames[srcPattern[i]] << " ";
90         }
91         output << "\n";
92         for (int i = 0; i < size; ++i)
93         {
94             inst[i]->emit(output);
95             output << "\n";
96         }
97     }
98 
dumpvISA::BUNDLE_INFO99     void dump() const
100     {
101         print(std::cerr);
102     }
103 
104     void findInstructionToMerge(INST_LIST_ITER& iter, const IR_Builder& builder);
105 
106     static bool isMergeCandidate(G4_INST* inst, const IR_Builder& builder, bool isInSimdFlow);
107 }; // BUNDLE_INFO
108 } // vISA::
109 
110 #endif // _MERGESCALAR_H
111