• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 MAPLE_IR_INCLUDE_OPCODE_INFO_H
17 #define MAPLE_IR_INCLUDE_OPCODE_INFO_H
18 #include "types_def.h"
19 #include "opcodes.h"
20 #include "mpl_logging.h"
21 
22 namespace maple {
23 enum OpcodeProp {
24     kOpcodePropNone,
25     kOpcodePropIsStmt,          // The instruction is a stmt, so has 2 stmt pointers
26     kOpcodePropIsVarSize,       // The instruction size is not fixed
27     kOpcodePropNotMMPL,         // The instruction is not allowed in Machine Maple IR
28     kOpcodePropIsCompare,       // The instruction is one of the 6 comparison ops
29     kOpcodePropIsTypeCvt,       // The instruction is a type conversion op
30     kOpcodePropHasSSAUse,       // The instruction may incur a use in SSA form
31     kOpcodePropHasSSADef,       // The instruction may incur a def in SSA form
32     kOpcodePropIsCall,          // The instruction is among the call instructions
33     kOpcodePropIsCallAssigned,  // The instruction is among the call instructions with implicit assignments of the
34     // returned values
35     kOpcodePropNotPure,  // The operation does not return same result with idential operands
36     kOpcodePropMayThrowException,
37     kOpcodePropIsAssertUpperBoundary,  // The operation check upper boundary
38     kOpcodePropIsAssertLowerBoundary,  // The operation check lower boundary
39 };
40 
41 constexpr unsigned long OPCODEISSTMT = 1ULL << kOpcodePropIsStmt;
42 constexpr unsigned long OPCODEISVARSIZE = 1ULL << kOpcodePropIsVarSize;
43 constexpr unsigned long OPCODENOTMMPL = 1ULL << kOpcodePropNotMMPL;
44 constexpr unsigned long OPCODEISCOMPARE = 1ULL << kOpcodePropIsCompare;
45 constexpr unsigned long OPCODEISTYPECVT = 1ULL << kOpcodePropIsTypeCvt;
46 constexpr unsigned long OPCODEHASSSAUSE = 1ULL << kOpcodePropHasSSAUse;
47 constexpr unsigned long OPCODEHASSSADEF = 1ULL << kOpcodePropHasSSADef;
48 constexpr unsigned long OPCODEISCALL = 1ULL << kOpcodePropIsCall;
49 constexpr unsigned long OPCODEISCALLASSIGNED = 1ULL << kOpcodePropIsCallAssigned;
50 constexpr unsigned long OPCODENOTPURE = 1ULL << kOpcodePropNotPure;
51 constexpr unsigned long OPCODEMAYTHROWEXCEPTION = 1ULL << kOpcodePropMayThrowException;
52 constexpr unsigned long OPCODEASSERTUPPERBOUNDARY = 1ULL << kOpcodePropIsAssertUpperBoundary;
53 constexpr unsigned long OPCODEASSERTLOWERBOUNDARY = 1ULL << kOpcodePropIsAssertLowerBoundary;
54 
55 struct OpcodeDesc {
56     uint8 instrucSize;  // size of instruction in bytes
57     uint16 flag;        // stores the opcode property flags
58     std::string name;
59 };
60 
61 class OpcodeTable {
62 public:
63     OpcodeTable();
64     ~OpcodeTable() = default;
65 
GetTableItemAt(Opcode o)66     OpcodeDesc GetTableItemAt(Opcode o) const
67     {
68         DEBUG_ASSERT(o < OP_last, "invalid opcode");
69         return table[o];
70     }
71 
IsStmt(Opcode o)72     bool IsStmt(Opcode o) const
73     {
74         DEBUG_ASSERT(o < OP_last, "invalid opcode");
75         return table[o].flag & OPCODEISSTMT;
76     }
77 
IsVarSize(Opcode o)78     bool IsVarSize(Opcode o) const
79     {
80         DEBUG_ASSERT(o < OP_last, "invalid opcode");
81         return table[o].flag & OPCODEISVARSIZE;
82     }
83 
NotMMPL(Opcode o)84     bool NotMMPL(Opcode o) const
85     {
86         DEBUG_ASSERT(o < OP_last, "invalid opcode");
87         return table[o].flag & OPCODENOTMMPL;
88     }
89 
IsCompare(Opcode o)90     bool IsCompare(Opcode o) const
91     {
92         DEBUG_ASSERT(o < OP_last, "invalid opcode");
93         return table[o].flag & OPCODEISCOMPARE;
94     }
95 
IsTypeCvt(Opcode o)96     bool IsTypeCvt(Opcode o) const
97     {
98         DEBUG_ASSERT(o < OP_last, "invalid opcode");
99         return table[o].flag & OPCODEISTYPECVT;
100     }
101 
HasSSAUse(Opcode o)102     bool HasSSAUse(Opcode o) const
103     {
104         DEBUG_ASSERT(o < OP_last, "invalid opcode");
105         return table[o].flag & OPCODEHASSSAUSE;
106     }
107 
HasSSADef(Opcode o)108     bool HasSSADef(Opcode o) const
109     {
110         DEBUG_ASSERT(o < OP_last, "invalid opcode");
111         return table[o].flag & OPCODEHASSSADEF;
112     }
113 
IsCall(Opcode o)114     bool IsCall(Opcode o) const
115     {
116         DEBUG_ASSERT(o < OP_last, "invalid opcode");
117         return table[o].flag & OPCODEISCALL;
118     }
119 
IsCallAssigned(Opcode o)120     bool IsCallAssigned(Opcode o) const
121     {
122         DEBUG_ASSERT(o < OP_last, "invalid opcode");
123         return table[o].flag & OPCODEISCALLASSIGNED;
124     }
125 
IsICall(Opcode o)126     bool IsICall(Opcode o) const
127     {
128         DEBUG_ASSERT(o < OP_last, "invalid opcode");
129         return o == OP_icall || o == OP_icallassigned || o == OP_icallproto || o == OP_icallprotoassigned;
130     }
131 
NotPure(Opcode o)132     bool NotPure(Opcode o) const
133     {
134         DEBUG_ASSERT(o < OP_last, "invalid opcode");
135         return table[o].flag & OPCODENOTPURE;
136     }
137 
MayThrowException(Opcode o)138     bool MayThrowException(Opcode o) const
139     {
140         DEBUG_ASSERT(o < OP_last, "invalid opcode");
141         return table[o].flag & OPCODEMAYTHROWEXCEPTION;
142     }
143 
HasSideEffect(Opcode o)144     bool HasSideEffect(Opcode o) const
145     {
146         DEBUG_ASSERT(o < OP_last, "invalid opcode");
147         return MayThrowException(o);
148     }
149 
GetName(Opcode o)150     const std::string &GetName(Opcode o) const
151     {
152         DEBUG_ASSERT(o < OP_last, "invalid opcode");
153         return table[o].name;
154     }
155 
IsCondBr(Opcode o)156     bool IsCondBr(Opcode o) const
157     {
158         DEBUG_ASSERT(o < OP_last, "invalid opcode");
159         return o == OP_brtrue || o == OP_brfalse;
160     }
161 
AssignActualVar(Opcode o)162     bool AssignActualVar(Opcode o) const
163     {
164         DEBUG_ASSERT(o < OP_last, "invalid opcode");
165         return o == OP_dassign || o == OP_regassign;
166     }
167 
IsAssertBoundary(Opcode o)168     bool IsAssertBoundary(Opcode o) const
169     {
170         DEBUG_ASSERT(o < OP_last, "invalid opcode");
171         return table[o].flag & (OPCODEASSERTUPPERBOUNDARY | OPCODEASSERTLOWERBOUNDARY);
172     }
173 
IsAssertUpperBoundary(Opcode o)174     bool IsAssertUpperBoundary(Opcode o) const
175     {
176         DEBUG_ASSERT(o < OP_last, "invalid opcode");
177         return table[o].flag & OPCODEASSERTUPPERBOUNDARY;
178     }
179 
IsAssertLowerBoundary(Opcode o)180     bool IsAssertLowerBoundary(Opcode o) const
181     {
182         DEBUG_ASSERT(o < OP_last, "invalid opcode");
183         return table[o].flag & OPCODEASSERTLOWERBOUNDARY;
184     }
185 
186 private:
187     OpcodeDesc table[OP_last];
188 };
189 extern const OpcodeTable kOpcodeInfo;
190 }  // namespace maple
191 #endif  // MAPLE_IR_INCLUDE_OPCODE_INFO_H
192