• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMPILER_TESTS_INST_GENERATOR_H
17 #define COMPILER_TESTS_INST_GENERATOR_H
18 
19 #include "macros.h"
20 #include "unit_test.h"
21 
22 namespace ark::compiler {
23 class GraphCreator {
24 public:
25     GraphCreator() = delete;
GraphCreator(ArenaAllocator & allocator,ArenaAllocator & localAllocator)26     explicit GraphCreator(ArenaAllocator &allocator, ArenaAllocator &localAllocator)
27         : allocator_(allocator), localAllocator_(localAllocator)
28     {
29     }
30 
31     Graph *GenerateGraph(Inst *inst);
32 
SetRuntimeTargetArch(Arch arch)33     void SetRuntimeTargetArch(Arch arch)
34     {
35         arch_ = arch;
36     }
37 
GetRuntimeTargetArch()38     Arch GetRuntimeTargetArch() const
39     {
40         return arch_;
41     }
42 
GetRuntime()43     RuntimeInterface *GetRuntime()
44     {
45         return &runtime_;
46     }
47 
GetAllocator()48     ArenaAllocator *GetAllocator() const
49     {
50         return &allocator_;
51     }
52 
GetLocalAllocator()53     ArenaAllocator *GetLocalAllocator() const
54     {
55         return &localAllocator_;
56     }
57 
58 private:
59     Graph *CreateGraph();
60 
61     Inst *PopulateLoadArrayPair(Graph *graph, BasicBlock *block, Inst *inst, Opcode opc);
62     void PopulateStoreArrayPair(Graph *graph, Inst *inst, Opcode opc);
63     void PopulateReturnInlined(Graph *graph, BasicBlock *block, Inst *inst, int32_t n);
64     void PopulateCall(Graph *graph, BasicBlock *block, Inst *inst, DataType::Type type, int32_t n);
65     void PopulateLoadStoreArray(Graph *graph, Inst *inst, DataType::Type type, int32_t n);
66     void PopulateLoadStoreArrayI(Graph *graph, Inst *inst, DataType::Type type, int32_t n);
67     void PopulateSelect(Graph *graph, Inst *inst, DataType::Type type, int32_t n);
68     void PopulateSelectI(Graph *graph, Inst *inst, DataType::Type type, int32_t n);
69     void PopulateStoreStatic(Graph *graph, BasicBlock *block, Inst *inst, DataType::Type type);
70     void PopulateLoadStatic(Graph *graph, BasicBlock *block, Inst *inst);
71     void PopulateMonitor(Graph *graph, BasicBlock *block, Inst *inst);
72     void PopulateLoadType(Graph *graph, BasicBlock *block, Inst *inst);
73     void PopulateIsInstance(Graph *graph, BasicBlock *block, Inst *inst);
74     void PopulateNewArray(Graph *graph, BasicBlock *block, Inst *inst, int32_t n);
75     void PopulateNewObject(Graph *graph, BasicBlock *block, Inst *inst, int32_t n);
76     void PopulateDefault(Graph *graph, Inst *inst, DataType::Type type, int32_t n);
77     void PopulateGraph(Graph *graph, Inst *inst, int32_t n);
78     void Finalize(Graph *graph, BasicBlock *block, Inst *inst);
79 
80     Graph *GenerateOperation(Inst *inst, int32_t n);
81     Graph *GenerateCheckOperation(Inst *inst);
82     Graph *GenerateSSOperation(Inst *inst);
83     Graph *GenerateBoundaryCheckOperation(Inst *inst);
84     Graph *GenerateThrowOperation(Inst *inst);
85     Graph *GenerateMultiArrayOperation(Inst *inst);
86     Graph *GeneratePhiOperation(Inst *inst);
87 
88 #include "generate_operations_intrinsic_graph.inl"
89 
90     Graph *CreateGraphWithOneBasicBlock();
91     Graph *CreateGraphWithTwoBasicBlock();
92     Graph *CreateGraphWithThreeBasicBlock();
93     Graph *CreateGraphWithFourBasicBlock();
94     ParameterInst *CreateParamInst(Graph *graph, DataType::Type type, uint8_t slot);
95 
96     struct PackArgsForCkeckInst {
97         Opcode opcode;
98         DataType::Type type;
99         Inst *inst;
100         ParameterInst *param1;
101         ParameterInst *param2;
102 
103         SaveStateInst *saveState;
104         BasicBlock *block;
105         Graph *graph;
106     };
107 
108     Inst *CreateCheckInstByPackArgs(const PackArgsForCkeckInst &pack);
109 
110 private:
111     // need to create graphs
112     ArenaAllocator &allocator_;
113     ArenaAllocator &localAllocator_;
114     RuntimeInterfaceMock runtime_;
115     Arch arch_ {Arch::AARCH64};
116 
117 public:
SetNumVRegsArgs(size_t regs,size_t args)118     void SetNumVRegsArgs(size_t regs, size_t args)
119     {
120         runtime_.vregsCount_ = regs;
121         runtime_.argsCount_ = args;
122     }
123 };
124 
125 class InstGenerator {
126 public:
127     InstGenerator() = delete;
InstGenerator(ArenaAllocator & allocator)128     explicit InstGenerator(ArenaAllocator &allocator) : allocator_(allocator) {}
129 
130     std::vector<Inst *> &Generate(Opcode opCode);
131 
GetAllPossibleInstToGenerateNumber()132     int GetAllPossibleInstToGenerateNumber()
133     {
134         int result = 0;
135         for (auto &it : opcodeXPossibleTypes_) {
136             result += it.second.size();
137         }
138         return result;
139     }
140 
GetPossibleInstToGenerateNumber(Opcode opCode)141     int GetPossibleInstToGenerateNumber(Opcode opCode)
142     {
143         return opcodeXPossibleTypes_[opCode].size();
144     }
145 
GetMap()146     std::map<Opcode, std::vector<DataType::Type>> &GetMap()
147     {
148         return opcodeXPossibleTypes_;
149     }
150 
GetAllocator()151     ArenaAllocator *GetAllocator()
152     {
153         return &allocator_;
154     }
155 
156 private:
157     template <class T>
158     std::vector<Inst *> &GenerateOperations(Opcode opCode);
159 
160     template <class T>
161     std::vector<Inst *> &GenerateOperationsImm(Opcode opCode);
162 
163     template <class T>
164     std::vector<Inst *> &GenerateOperationsShiftedRegister(Opcode opCode);
165 
GenerateIntrinsic(DataType::Type type,RuntimeInterface::IntrinsicId intrinsicId)166     void GenerateIntrinsic(DataType::Type type, RuntimeInterface::IntrinsicId intrinsicId)
167     {
168         auto inst = Inst::New<IntrinsicInst>(&allocator_, Opcode::Intrinsic);
169         inst->SetType(type);
170         inst->SetIntrinsicId(intrinsicId);
171         insts_.push_back(inst);
172     }
173 
174     void SetFlagsNoCseNoHoistIfReference(Inst *inst, DataType::Type dstType);
175 
176     std::vector<DataType::Type> integerTypes_ {DataType::UINT8,  DataType::INT8,  DataType::UINT16, DataType::INT16,
177                                                DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64};
178 
179     std::vector<DataType::Type> numericTypes_ {DataType::BOOL,  DataType::UINT8,   DataType::INT8,   DataType::UINT16,
180                                                DataType::INT16, DataType::UINT32,  DataType::INT32,  DataType::UINT64,
181                                                DataType::INT64, DataType::FLOAT32, DataType::FLOAT64};
182 
183     std::vector<DataType::Type> refNumTypes_ {
184         DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,  DataType::INT8,  DataType::UINT16,  DataType::INT16,
185         DataType::UINT32,    DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64};
186 
187     std::vector<DataType::Type> refIntTypes_ {DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,  DataType::INT8,
188                                               DataType::UINT16,    DataType::INT16, DataType::UINT32, DataType::INT32,
189                                               DataType::UINT64,    DataType::INT64};
190 
191     std::vector<DataType::Type> allTypes_ {DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,   DataType::INT8,
192                                            DataType::UINT16,    DataType::INT16, DataType::UINT32,  DataType::INT32,
193                                            DataType::UINT64,    DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
194                                            DataType::VOID};
195 
196     std::vector<DataType::Type> floatsTypes_ {DataType::FLOAT32, DataType::FLOAT64};
197 
198     std::map<Opcode, std::vector<DataType::Type>> opcodeXPossibleTypes_ = {
199         {Opcode::Neg, numericTypes_},
200         {Opcode::Abs, numericTypes_},
201         {Opcode::Not, integerTypes_},
202         {Opcode::Add, numericTypes_},
203         {Opcode::Sub, numericTypes_},
204         {Opcode::Mul, numericTypes_},
205         {Opcode::Div, numericTypes_},
206         {Opcode::Min, numericTypes_},
207         {Opcode::Max, numericTypes_},
208         {Opcode::Shl, integerTypes_},
209         {Opcode::Shr, integerTypes_},
210         {Opcode::AShr, integerTypes_},
211         {Opcode::Mod, numericTypes_},
212         {Opcode::And, integerTypes_},
213         {Opcode::Or, integerTypes_},
214         {Opcode::Xor, integerTypes_},
215         {Opcode::Compare, refNumTypes_},
216         {Opcode::If, refIntTypes_},
217         {Opcode::Cmp, {DataType::INT32}},
218         {Opcode::Constant, {DataType::INT64, DataType::FLOAT32, DataType::FLOAT64}},
219         {Opcode::Phi, refNumTypes_},
220         {Opcode::IfImm, refIntTypes_},
221         {Opcode::Cast, numericTypes_},
222         {Opcode::Parameter, refNumTypes_},
223         {Opcode::IsInstance, {DataType::BOOL}},
224         {Opcode::LenArray, {DataType::INT32}},
225         {Opcode::LoadArray, refNumTypes_},
226         {Opcode::StoreArray, refNumTypes_},
227         {Opcode::LoadArrayI, refNumTypes_},
228         {Opcode::StoreArrayI, refNumTypes_},
229         {Opcode::CheckCast, {DataType::NO_TYPE}},
230         {Opcode::NullCheck, {DataType::NO_TYPE}},
231         {Opcode::ZeroCheck, {DataType::NO_TYPE}},
232         {Opcode::NegativeCheck, {DataType::NO_TYPE}},
233         {Opcode::BoundsCheck, {DataType::NO_TYPE}},
234         {Opcode::BoundsCheckI, {DataType::NO_TYPE}},
235         {Opcode::SaveState, {DataType::NO_TYPE}},
236         {Opcode::ReturnVoid, {DataType::NO_TYPE}},
237         {Opcode::Throw, {DataType::NO_TYPE}},
238         {Opcode::NewArray, {DataType::REFERENCE}},
239         {Opcode::Return, refNumTypes_},
240         {Opcode::ReturnI, numericTypes_},
241         {Opcode::CallStatic, allTypes_},
242         {Opcode::CallVirtual, allTypes_},
243         {Opcode::AddI, integerTypes_},
244         {Opcode::SubI, integerTypes_},
245         {Opcode::AndI, integerTypes_},
246         {Opcode::OrI, integerTypes_},
247         {Opcode::XorI, integerTypes_},
248         {Opcode::ShrI, integerTypes_},
249         {Opcode::ShlI, integerTypes_},
250         {Opcode::AShrI, integerTypes_},
251         {Opcode::SpillFill, {DataType::NO_TYPE}},
252         {Opcode::NewObject, {DataType::REFERENCE}},
253         {Opcode::LoadObject, refNumTypes_},
254         {Opcode::LoadStatic, refNumTypes_},
255         {Opcode::StoreObject, refNumTypes_},
256         {Opcode::StoreStatic, refNumTypes_},
257         {Opcode::LoadString, {DataType::REFERENCE}},
258         {Opcode::LoadType, {DataType::REFERENCE}},
259         {Opcode::SafePoint, {DataType::NO_TYPE}},
260         {Opcode::ReturnInlined, {DataType::NO_TYPE}},
261         {Opcode::Monitor, {DataType::VOID}},
262         {Opcode::Intrinsic, {}},
263         {Opcode::Select, refIntTypes_},
264         {Opcode::SelectImm, refIntTypes_},
265         {Opcode::NullPtr, {DataType::REFERENCE}},
266         {Opcode::LoadArrayPair,
267          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
268           DataType::REFERENCE}},
269         {Opcode::LoadArrayPairI,
270          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
271           DataType::REFERENCE}},
272         {Opcode::StoreArrayPair,
273          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
274           DataType::REFERENCE}},
275         {Opcode::StoreArrayPairI,
276          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
277           DataType::REFERENCE}},
278         {Opcode::AndNot, integerTypes_},
279         {Opcode::OrNot, integerTypes_},
280         {Opcode::XorNot, integerTypes_},
281         {Opcode::MNeg, numericTypes_},
282         {Opcode::MAdd, numericTypes_},
283         {Opcode::MSub, numericTypes_},
284         {Opcode::AddSR, integerTypes_},
285         {Opcode::SubSR, integerTypes_},
286         {Opcode::AndSR, integerTypes_},
287         {Opcode::OrSR, integerTypes_},
288         {Opcode::XorSR, integerTypes_},
289         {Opcode::AndNotSR, integerTypes_},
290         {Opcode::OrNotSR, integerTypes_},
291         {Opcode::XorNotSR, integerTypes_},
292         {Opcode::NegSR, integerTypes_},
293     };
294 
295     std::vector<ShiftType> onlyShifts_ = {ShiftType::LSL, ShiftType::LSR, ShiftType::ASR};
296     std::vector<ShiftType> shiftsAndRotation_ = {ShiftType::LSL, ShiftType::LSR, ShiftType::ASR, ShiftType::ROR};
297     std::map<Opcode, std::vector<ShiftType>> opcodeXPossibleShiftTypes_ = {
298         {Opcode::AddSR, onlyShifts_},          {Opcode::SubSR, onlyShifts_},
299         {Opcode::AndSR, shiftsAndRotation_},   {Opcode::OrSR, shiftsAndRotation_},
300         {Opcode::XorSR, shiftsAndRotation_},   {Opcode::AndNotSR, shiftsAndRotation_},
301         {Opcode::OrNotSR, shiftsAndRotation_}, {Opcode::XorNotSR, shiftsAndRotation_},
302         {Opcode::NegSR, onlyShifts_}};
303     std::vector<Inst *> insts_;
304 
305     // need to create graphs
306     ArenaAllocator &allocator_;
307 };
308 
309 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
310 class StatisticGenerator {
311 public:
StatisticGenerator(InstGenerator & instGenerator,GraphCreator & graphCreator)312     StatisticGenerator(InstGenerator &instGenerator, GraphCreator &graphCreator)
313         : instGenerator_(instGenerator), graphCreator_(graphCreator)
314     {
315     }
316 
317     virtual ~StatisticGenerator() = default;
318 
319     NO_COPY_SEMANTIC(StatisticGenerator);
320     NO_MOVE_SEMANTIC(StatisticGenerator);
321 
322     using FullInstStat = std::map<DataType::Type, int8_t>;
323     using FullIntrinsicStat = std::map<RuntimeInterface::IntrinsicId, bool>;
324     using FullStat = std::pair<std::map<Opcode, FullInstStat>, FullIntrinsicStat>;
325 
326     virtual void Generate() = 0;
327 
GetStatistic()328     FullStat &GetStatistic()
329     {
330         return statistic_;
331     }
332 
333     void GenerateHTMLPage(const std::string &fileName);
334 
335 private:
336     void FillHTMLPageHeadPart(std::ofstream &htmlPage);
337     void FillHTMLPageOpcodeStatistic(std::ofstream &htmlPage, Opcode opc);
338 
339 protected:
340     InstGenerator &instGenerator_;
341     GraphCreator &graphCreator_;
342 
343     int allInstNumber_ = 0;
344     int positiveInstNumber_ = 0;
345 
346     int allOpcodeNumber_ = 0;
347     int implementedOpcodeNumber_ = 0;
348 
349     FullStat statistic_;
350 
351     FullInstStat tmplt_ = {
352         {DataType::NO_TYPE, -1}, {DataType::REFERENCE, -1}, {DataType::BOOL, -1},  {DataType::UINT8, -1},
353         {DataType::INT8, -1},    {DataType::UINT16, -1},    {DataType::INT16, -1}, {DataType::UINT32, -1},
354         {DataType::INT32, -1},   {DataType::UINT64, -1},    {DataType::INT64, -1}, {DataType::FLOAT32, -1},
355         {DataType::FLOAT64, -1}, {DataType::ANY, -1},       {DataType::VOID, -1},
356     };
357 };
358 // NOLINTEND(misc-non-private-member-variables-in-classes)
359 
360 }  // namespace ark::compiler
361 
362 #endif  // COMPILER_TESTS_INST_GENERATOR_H
363