• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 "unit_test.h"
20 
21 namespace panda::compiler {
22 class GraphCreator {
23 public:
24     GraphCreator() = delete;
GraphCreator(ArenaAllocator & allocator,ArenaAllocator & local_allocator)25     explicit GraphCreator(ArenaAllocator &allocator, ArenaAllocator &local_allocator)
26         : allocator_(allocator), local_allocator_(local_allocator)
27     {
28     }
29 
30     Graph *GenerateGraph(Inst *inst);
31 
SetRuntimeTargetArch(Arch arch)32     void SetRuntimeTargetArch(Arch arch)
33     {
34         arch_ = arch;
35     }
36 
GetRuntime()37     RuntimeInterface *GetRuntime()
38     {
39         return &runtime_;
40     }
41 
GetAllocator()42     ArenaAllocator *GetAllocator() const
43     {
44         return &allocator_;
45     }
46 
GetLocalAllocator()47     ArenaAllocator *GetLocalAllocator() const
48     {
49         return &local_allocator_;
50     }
51 
SetNumVRegsArgs(size_t regs,size_t args)52     void SetNumVRegsArgs(size_t regs, size_t args)
53     {
54         runtime_.vregs_count = regs;
55         runtime_.args_count = args;
56     }
57 
58 private:
59     Graph *CreateGraph();
60     Graph *GenerateOperation(Inst *inst, int32_t n);
61     Graph *GenerateCheckOperation(Inst *inst);
62     Graph *GenerateSSOperation(Inst *inst);
63     Graph *GenerateBoundaryCheckOperation(Inst *inst);
64     Graph *GenerateThrowOperation(Inst *inst);
65     Graph *GenerateMultiArrayOperation(Inst *inst);
66     Graph *GeneratePhiOperation(Inst *inst);
67 
68     Graph *CreateGraphWithOneBasicBlock();
69     Graph *CreateGraphWithTwoBasicBlock();
70     Graph *CreateGraphWithThreeBasicBlock();
71     Graph *CreateGraphWithFourBasicBlock();
72     ParameterInst *CreateParamInst(Graph *graph, DataType::Type type, uint8_t slot);
73 
74     // need to create graphs
75     ArenaAllocator &allocator_;
76     ArenaAllocator &local_allocator_;
77     RuntimeInterfaceMock runtime_;
78     Arch arch_ {Arch::AARCH64};
79 #include "generate_operations_intrinsic_graph.inl"
80 };
81 
82 class InstGenerator {
83 public:
84     InstGenerator() = delete;
InstGenerator(ArenaAllocator & allocator)85     explicit InstGenerator(ArenaAllocator &allocator) : allocator_(allocator) {}
86 
87     std::vector<Inst *> &Generate(Opcode OpCode);
88 
GetAllPossibleInstToGenerateNumber()89     int GetAllPossibleInstToGenerateNumber()
90     {
91         int result = 0;
92         for (auto &it : opcode_x_possible_types_) {
93             result += it.second.size();
94         }
95         return result;
96     }
97 
GetPossibleInstToGenerateNumber(Opcode OpCode)98     int GetPossibleInstToGenerateNumber(Opcode OpCode)
99     {
100         return opcode_x_possible_types_[OpCode].size();
101     }
102 
GetMap()103     std::map<Opcode, std::vector<DataType::Type>> &GetMap()
104     {
105         return opcode_x_possible_types_;
106     }
107 
GetAllocator()108     ArenaAllocator *GetAllocator()
109     {
110         return &allocator_;
111     }
112 
113 private:
114     template <class T>
115     std::vector<Inst *> &GenerateOperations(Opcode OpCode);
116 
117     template <class T>
118     std::vector<Inst *> &GenerateOperationsImm(Opcode OpCode);
119 
120     template <class T>
121     std::vector<Inst *> &GenerateOperationsShiftedRegister(Opcode OpCode);
122 
GenerateIntrinsic(DataType::Type Type,RuntimeInterface::IntrinsicId intrinsic_id)123     void GenerateIntrinsic(DataType::Type Type, RuntimeInterface::IntrinsicId intrinsic_id)
124     {
125         auto inst = Inst::New<IntrinsicInst>(&allocator_, Opcode::Intrinsic);
126         inst->SetType(Type);
127         inst->SetIntrinsicId(intrinsic_id);
128         insts_.push_back(inst);
129     }
130 
131     std::vector<DataType::Type> integer_types_ {DataType::UINT8,  DataType::INT8,  DataType::UINT16, DataType::INT16,
132                                                 DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64};
133 
134     std::vector<DataType::Type> numeric_types_ {DataType::BOOL,  DataType::UINT8,   DataType::INT8,   DataType::UINT16,
135                                                 DataType::INT16, DataType::UINT32,  DataType::INT32,  DataType::UINT64,
136                                                 DataType::INT64, DataType::FLOAT32, DataType::FLOAT64};
137 
138     std::vector<DataType::Type> ref_num_types_ {
139         DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,  DataType::INT8,  DataType::UINT16,  DataType::INT16,
140         DataType::UINT32,    DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64};
141 
142     std::vector<DataType::Type> ref_int_types_ {DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,  DataType::INT8,
143                                                 DataType::UINT16,    DataType::INT16, DataType::UINT32, DataType::INT32,
144                                                 DataType::UINT64,    DataType::INT64};
145 
146     std::vector<DataType::Type> all_types_ {DataType::REFERENCE, DataType::BOOL,  DataType::UINT8,   DataType::INT8,
147                                             DataType::UINT16,    DataType::INT16, DataType::UINT32,  DataType::INT32,
148                                             DataType::UINT64,    DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
149                                             DataType::VOID};
150 
151     std::vector<DataType::Type> floats_types_ {DataType::FLOAT32, DataType::FLOAT64};
152 
153     std::map<Opcode, std::vector<DataType::Type>> opcode_x_possible_types_ = {
154         {Opcode::Neg, numeric_types_},
155         {Opcode::Abs, numeric_types_},
156         {Opcode::Not, integer_types_},
157         {Opcode::Add, numeric_types_},
158         {Opcode::Sub, numeric_types_},
159         {Opcode::Mul, numeric_types_},
160         {Opcode::Div, numeric_types_},
161         {Opcode::Min, numeric_types_},
162         {Opcode::Max, numeric_types_},
163         {Opcode::Shl, integer_types_},
164         {Opcode::Shr, integer_types_},
165         {Opcode::AShr, integer_types_},
166         {Opcode::Mod, numeric_types_},
167         {Opcode::And, integer_types_},
168         {Opcode::Or, integer_types_},
169         {Opcode::Xor, integer_types_},
170         {Opcode::Compare, ref_num_types_},
171         {Opcode::If, ref_int_types_},
172         {Opcode::Cmp, {DataType::INT32}},
173         {Opcode::Constant, {DataType::INT64, DataType::FLOAT32, DataType::FLOAT64}},
174         {Opcode::Phi, ref_num_types_},
175         {Opcode::IfImm, ref_int_types_},
176         {Opcode::Cast, numeric_types_},
177         {Opcode::Parameter, ref_num_types_},
178         {Opcode::IsInstance, {DataType::BOOL}},
179         {Opcode::LenArray, {DataType::INT32}},
180         {Opcode::LoadArray, ref_num_types_},
181         {Opcode::StoreArray, ref_num_types_},
182         {Opcode::LoadArrayI, ref_num_types_},
183         {Opcode::StoreArrayI, ref_num_types_},
184         {Opcode::CheckCast, {DataType::NO_TYPE}},
185         {Opcode::NullCheck, {DataType::NO_TYPE}},
186         {Opcode::ZeroCheck, {DataType::NO_TYPE}},
187         {Opcode::NegativeCheck, {DataType::NO_TYPE}},
188         {Opcode::BoundsCheck, {DataType::NO_TYPE}},
189         {Opcode::BoundsCheckI, {DataType::NO_TYPE}},
190         {Opcode::SaveState, {DataType::NO_TYPE}},
191         {Opcode::ReturnVoid, {DataType::NO_TYPE}},
192         {Opcode::Throw, {DataType::NO_TYPE}},
193         {Opcode::NewArray, {DataType::REFERENCE}},
194         {Opcode::Return, ref_num_types_},
195         {Opcode::ReturnI, numeric_types_},
196         {Opcode::CallStatic, all_types_},
197         {Opcode::CallVirtual, all_types_},
198         {Opcode::AddI, integer_types_},
199         {Opcode::SubI, integer_types_},
200         {Opcode::AndI, integer_types_},
201         {Opcode::OrI, integer_types_},
202         {Opcode::XorI, integer_types_},
203         {Opcode::ShrI, integer_types_},
204         {Opcode::ShlI, integer_types_},
205         {Opcode::AShrI, integer_types_},
206         {Opcode::SpillFill, {DataType::NO_TYPE}},
207         {Opcode::NewObject, {DataType::REFERENCE}},
208         {Opcode::LoadObject, ref_num_types_},
209         {Opcode::LoadStatic, ref_num_types_},
210         {Opcode::StoreObject, ref_num_types_},
211         {Opcode::StoreStatic, ref_num_types_},
212         {Opcode::LoadString, {DataType::REFERENCE}},
213         {Opcode::LoadType, {DataType::REFERENCE}},
214         {Opcode::SafePoint, {DataType::NO_TYPE}},
215         {Opcode::ReturnInlined, {DataType::NO_TYPE}},
216         {Opcode::Monitor, {DataType::VOID}},
217         {Opcode::Intrinsic, {}},
218         {Opcode::Select, ref_int_types_},
219         {Opcode::SelectImm, ref_int_types_},
220         {Opcode::NullPtr, {DataType::REFERENCE}},
221         {Opcode::LoadArrayPair,
222          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
223           DataType::REFERENCE}},
224         {Opcode::LoadArrayPairI,
225          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
226           DataType::REFERENCE}},
227         {Opcode::StoreArrayPair,
228          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
229           DataType::REFERENCE}},
230         {Opcode::StoreArrayPairI,
231          {DataType::UINT32, DataType::INT32, DataType::UINT64, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64,
232           DataType::REFERENCE}},
233         {Opcode::AndNot, integer_types_},
234         {Opcode::OrNot, integer_types_},
235         {Opcode::XorNot, integer_types_},
236         {Opcode::MNeg, numeric_types_},
237         {Opcode::MAdd, numeric_types_},
238         {Opcode::MSub, numeric_types_},
239         {Opcode::AddSR, integer_types_},
240         {Opcode::SubSR, integer_types_},
241         {Opcode::AndSR, integer_types_},
242         {Opcode::OrSR, integer_types_},
243         {Opcode::XorSR, integer_types_},
244         {Opcode::AndNotSR, integer_types_},
245         {Opcode::OrNotSR, integer_types_},
246         {Opcode::XorNotSR, integer_types_},
247         {Opcode::NegSR, integer_types_},
248     };
249 
250     std::vector<ShiftType> only_shifts_ = {ShiftType::LSL, ShiftType::LSR, ShiftType::ASR};
251     std::vector<ShiftType> shifts_and_rotation_ = {ShiftType::LSL, ShiftType::LSR, ShiftType::ASR, ShiftType::ROR};
252     std::map<Opcode, std::vector<ShiftType>> opcode_x_possible_shift_types_ = {{Opcode::AddSR, only_shifts_},
253                                                                                {Opcode::SubSR, only_shifts_},
254                                                                                {Opcode::AndSR, shifts_and_rotation_},
255                                                                                {Opcode::OrSR, shifts_and_rotation_},
256                                                                                {Opcode::XorSR, shifts_and_rotation_},
257                                                                                {Opcode::AndNotSR, shifts_and_rotation_},
258                                                                                {Opcode::OrNotSR, shifts_and_rotation_},
259                                                                                {Opcode::XorNotSR, shifts_and_rotation_},
260                                                                                {Opcode::NegSR, only_shifts_}};
261     std::vector<Inst *> insts_;
262 
263     // need to create graphs
264     ArenaAllocator &allocator_;
265 };
266 
267 class StatisticGenerator {
268 public:
StatisticGenerator(InstGenerator & inst_generator,GraphCreator & graph_creator)269     StatisticGenerator(InstGenerator &inst_generator, GraphCreator &graph_creator)
270         : inst_generator_(inst_generator), graph_creator_(graph_creator)
271     {
272     }
273 
274     virtual ~StatisticGenerator() = default;
275 
276     typedef std::map<DataType::Type, int8_t> FULL_INST_STAT;
277     typedef std::map<RuntimeInterface::IntrinsicId, bool> FULL_INTRINSIC_STAT;
278     typedef std::pair<std::map<Opcode, FULL_INST_STAT>, FULL_INTRINSIC_STAT> FULL_STAT;
279 
280     virtual void Generate() = 0;
281 
GetStatistic()282     FULL_STAT &GetStatistic()
283     {
284         return statistic_;
285     }
286 
287     void GenerateHTMLPage(std::string file_name);
288 
289 protected:
290     InstGenerator &inst_generator_;
291     GraphCreator &graph_creator_;
292 
293     int all_inst_number_ = 0;
294     int positive_inst_number = 0;
295 
296     int all_opcode_number_ = 0;
297     int implemented_opcode_number_ = 0;
298 
299     FULL_STAT statistic_;
300 
301     FULL_INST_STAT tmplt_ = {
302         {DataType::NO_TYPE, -1}, {DataType::REFERENCE, -1}, {DataType::BOOL, -1},  {DataType::UINT8, -1},
303         {DataType::INT8, -1},    {DataType::UINT16, -1},    {DataType::INT16, -1}, {DataType::UINT32, -1},
304         {DataType::INT32, -1},   {DataType::UINT64, -1},    {DataType::INT64, -1}, {DataType::FLOAT32, -1},
305         {DataType::FLOAT64, -1}, {DataType::ANY, -1},       {DataType::VOID, -1},
306     };
307 };
308 }  // namespace panda::compiler
309 
310 #endif  // COMPILER_TESTS_INST_GENERATOR_H
311