1 /* 2 * Copyright (c) 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_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H 17 #define COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H 18 19 #include "codegen.h" 20 21 namespace ark::compiler { 22 23 class Encoder; 24 class CodeBuilder; 25 class OsrEntryStub; 26 27 class EncodeVisitor : public GraphVisitor { 28 using EntrypointId = RuntimeInterface::EntrypointId; 29 30 public: EncodeVisitor(Codegen * cg)31 explicit EncodeVisitor(Codegen *cg) : cg_(cg), arch_(cg->GetArch()) {} 32 33 EncodeVisitor() = delete; 34 GetBlocksToVisit()35 const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override 36 { 37 return cg_->GetGraph()->GetBlocksRPO(); 38 } GetCodegen()39 Codegen *GetCodegen() const 40 { 41 return cg_; 42 } GetEncoder()43 Encoder *GetEncoder() 44 { 45 return cg_->GetEncoder(); 46 } GetArch()47 Arch GetArch() const 48 { 49 return arch_; 50 } GetCallingConvention()51 CallingConvention *GetCallingConvention() 52 { 53 return cg_->GetCallingConvention(); 54 } 55 GetRegfile()56 RegistersDescription *GetRegfile() 57 { 58 return cg_->GetRegfile(); 59 } 60 GetResult()61 bool GetResult() 62 { 63 return success_ && cg_->GetEncoder()->GetResult(); 64 } 65 66 // For each group of SpillFillData representing spill or fill operations and 67 // sharing the same source and destination types order by stack slot number in descending order. 68 static void SortSpillFillData(ArenaVector<SpillFillData> *spillFills); 69 // Checks if two spill-fill operations could be coalesced into single operation over pair of arguments. 70 static bool CanCombineSpillFills(SpillFillData pred, SpillFillData succ, const CFrameLayout &fl, 71 const Graph *graph); 72 73 protected: 74 // UnaryOperation 75 static void VisitMov(GraphVisitor *visitor, Inst *inst); 76 static void VisitNeg(GraphVisitor *visitor, Inst *inst); 77 static void VisitAbs(GraphVisitor *visitor, Inst *inst); 78 static void VisitNot(GraphVisitor *visitor, Inst *inst); 79 static void VisitSqrt(GraphVisitor *visitor, Inst *inst); 80 81 // BinaryOperation 82 static void VisitAdd(GraphVisitor *visitor, Inst *inst); 83 static void VisitSub(GraphVisitor *visitor, Inst *inst); 84 static void VisitMul(GraphVisitor *visitor, Inst *inst); 85 static void VisitShl(GraphVisitor *visitor, Inst *inst); 86 static void VisitAShr(GraphVisitor *visitor, Inst *inst); 87 static void VisitAnd(GraphVisitor *visitor, Inst *inst); 88 static void VisitOr(GraphVisitor *visitor, Inst *inst); 89 static void VisitXor(GraphVisitor *visitor, Inst *inst); 90 91 // Binary Overflow Operation 92 static void VisitAddOverflow(GraphVisitor *visitor, Inst *inst); 93 static void VisitAddOverflowCheck(GraphVisitor *visitor, Inst *inst); 94 static void VisitSubOverflow(GraphVisitor *visitor, Inst *inst); 95 static void VisitSubOverflowCheck(GraphVisitor *visitor, Inst *inst); 96 static void VisitNegOverflowAndZeroCheck(GraphVisitor *visitor, Inst *inst); 97 98 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 99 #define BINARY_IMM_OPERATION(opc) static void Visit##opc##I(GraphVisitor *visitor, Inst *inst) 100 101 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 102 #define BINARY_IMM_OPS(DEF) \ 103 DEF(Add); \ 104 DEF(Sub); \ 105 DEF(Shl); \ 106 DEF(AShr); \ 107 DEF(And); \ 108 DEF(Or); \ 109 DEF(Xor); \ 110 DEF(Div); \ 111 DEF(Mod) 112 113 BINARY_IMM_OPS(BINARY_IMM_OPERATION); 114 115 #undef BINARY_IMM_OPS 116 #undef BINARY_IMM_OPERATION 117 118 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 119 #define BINARY_SIGN_UNSIGN_OPERATION(opc) static void Visit##opc(GraphVisitor *visitor, Inst *inst) 120 121 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 122 #define SIGN_UNSIGN_OPS(DEF) \ 123 DEF(Div); \ 124 DEF(Mod); \ 125 DEF(Min); \ 126 DEF(Max); \ 127 DEF(Shr) 128 129 SIGN_UNSIGN_OPS(BINARY_SIGN_UNSIGN_OPERATION); 130 131 #undef SIGN_UNSIGN_OPS 132 #undef BINARY_SIGN_UNSIGN_OPERATION 133 134 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 135 #define BINARY_SHIFTED_REGISTER_OPERATION_DEF(opc, ignored) \ 136 static void Visit##opc##SR(GraphVisitor *visitor, Inst *inst); 137 138 ENCODE_INST_WITH_SHIFTED_OPERAND(BINARY_SHIFTED_REGISTER_OPERATION_DEF) 139 140 #undef BINARY_SHIFTED_REGISTER_OPERATION_DEF 141 142 static void VisitShrI(GraphVisitor *visitor, Inst *inst); 143 144 static void VisitCast(GraphVisitor *visitor, Inst *inst); 145 146 static void VisitBitcast(GraphVisitor *visitor, Inst *inst); 147 148 static void VisitPhi([[maybe_unused]] GraphVisitor *visitor, [[maybe_unused]] Inst *inst); 149 150 static void VisitConstant(GraphVisitor *visitor, Inst *inst); 151 152 static void VisitNullPtr(GraphVisitor *visitor, Inst *inst); 153 154 static void VisitLoadUndefined(GraphVisitor *visitor, Inst *inst); 155 156 static void VisitIf(GraphVisitor *visitor, Inst *inst); 157 158 static void VisitIfImm(GraphVisitor *visitor, Inst *inst); 159 160 static void VisitCompare(GraphVisitor *visitor, Inst *inst); 161 162 static void VisitCmp(GraphVisitor *visitor, Inst *inst); 163 164 // All next visitors use execution model for implementation 165 static void VisitReturnVoid(GraphVisitor *visitor, Inst * /* unused */); 166 167 static void VisitReturn(GraphVisitor *visitor, Inst *inst); 168 169 static void VisitReturnI(GraphVisitor *visitor, Inst *inst); 170 171 static void VisitReturnInlined(GraphVisitor *visitor, Inst * /* unused */); 172 173 static void VisitNewArray(GraphVisitor *visitor, Inst *inst); 174 175 static void VisitLoadConstArray(GraphVisitor *visitor, Inst *inst); 176 177 static void VisitFillConstArray(GraphVisitor *visitor, Inst *inst); 178 179 static void VisitParameter(GraphVisitor *visitor, Inst *inst); 180 181 static void VisitStoreArray(GraphVisitor *visitor, Inst *inst); 182 183 static void VisitSpillFill(GraphVisitor *visitor, Inst *inst); 184 185 static void VisitSaveState(GraphVisitor *visitor, Inst *inst); 186 187 static void VisitSaveStateDeoptimize(GraphVisitor *visitor, Inst *inst); 188 189 static void VisitSaveStateOsr(GraphVisitor *visitor, Inst *inst); 190 191 static void VisitLoadArray(GraphVisitor *visitor, Inst *inst); 192 193 static void VisitLoadCompressedStringChar(GraphVisitor *visitor, Inst *inst); 194 195 static void VisitLenArray(GraphVisitor *visitor, Inst *inst); 196 197 static void VisitNullCheck(GraphVisitor *visitor, Inst *inst); 198 199 static void VisitBoundsCheck(GraphVisitor *visitor, Inst *inst); 200 201 static void VisitZeroCheck(GraphVisitor *visitor, Inst *inst); 202 203 static void VisitRefTypeCheck(GraphVisitor *visitor, Inst *inst); 204 205 static void VisitNegativeCheck(GraphVisitor *visitor, Inst *inst); 206 207 static void VisitNotPositiveCheck(GraphVisitor *visitor, Inst *inst); 208 209 static void VisitLoadString(GraphVisitor *visitor, Inst *inst); 210 211 static void VisitResolveObjectField(GraphVisitor *visitor, Inst *inst); 212 213 static void VisitLoadResolvedObjectField(GraphVisitor *visitor, Inst *inst); 214 215 static void VisitLoadObject(GraphVisitor *visitor, Inst *inst); 216 217 static void VisitLoad(GraphVisitor *visitor, Inst *inst); 218 219 static void VisitStoreObject(GraphVisitor *visitor, Inst *inst); 220 221 static void VisitStoreResolvedObjectField(GraphVisitor *visitor, Inst *inst); 222 223 static void VisitStore(GraphVisitor *visitor, Inst *inst); 224 225 static void VisitLoadStatic(GraphVisitor *visitor, Inst *inst); 226 227 static void VisitResolveObjectFieldStatic(GraphVisitor *visitor, Inst *inst); 228 229 static void VisitLoadResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst); 230 231 static void VisitStoreStatic(GraphVisitor *visitor, Inst *inst); 232 233 static void VisitUnresolvedStoreStatic(GraphVisitor *visitor, Inst *inst); 234 235 static void VisitStoreResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst); 236 237 static void VisitNewObject(GraphVisitor *visitor, Inst *inst); 238 239 static void VisitLoadRuntimeClass(GraphVisitor *visitor, Inst *inst); 240 241 static void VisitLoadClass(GraphVisitor *visitor, Inst *inst); 242 243 static void VisitLoadAndInitClass(GraphVisitor *visitor, Inst *inst); 244 245 static void VisitGetGlobalVarAddress(GraphVisitor *visitor, Inst *inst); 246 247 static void VisitUnresolvedLoadAndInitClass(GraphVisitor *visitor, Inst *inst); 248 249 static void VisitInitClass(GraphVisitor *visitor, Inst *inst); 250 251 static void VisitUnresolvedInitClass(GraphVisitor *visitor, Inst *inst); 252 253 static void VisitLoadType(GraphVisitor *visitor, Inst *inst); 254 255 static void VisitUnresolvedLoadType(GraphVisitor *visitor, Inst *inst); 256 257 static void VisitCheckCast(GraphVisitor *visitor, Inst *inst); 258 259 static void VisitIsInstance(GraphVisitor *visitor, Inst *inst); 260 261 static void VisitMonitor(GraphVisitor *visitor, Inst *inst); 262 263 static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst); 264 265 static void VisitBuiltin(GraphVisitor *visitor, Inst *inst); 266 267 static void VisitBoundsCheckI(GraphVisitor *visitor, Inst *inst); 268 269 static void VisitStoreArrayI(GraphVisitor *visitor, Inst *inst); 270 271 static void VisitLoadArrayI(GraphVisitor *visitor, Inst *inst); 272 273 static void VisitLoadCompressedStringCharI(GraphVisitor *visitor, Inst *inst); 274 275 static void VisitLoadI(GraphVisitor *visitor, Inst *inst); 276 277 static void VisitStoreI(GraphVisitor *visitor, Inst *inst); 278 279 static void VisitMultiArray(GraphVisitor *visitor, Inst *inst); 280 static void VisitInitEmptyString(GraphVisitor *visitor, Inst *inst); 281 static void VisitInitString(GraphVisitor *visitor, Inst *inst); 282 283 static void VisitCallStatic(GraphVisitor *visitor, Inst *inst); 284 285 static void VisitResolveStatic(GraphVisitor *visitor, Inst *inst); 286 static void VisitCallResolvedStatic(GraphVisitor *visitor, Inst *inst); 287 288 static void VisitCallVirtual(GraphVisitor *visitor, Inst *inst); 289 290 static void VisitResolveVirtual(GraphVisitor *visitor, Inst *inst); 291 static void VisitCallResolvedVirtual(GraphVisitor *visitor, Inst *inst); 292 293 static void VisitCallLaunchStatic(GraphVisitor *visitor, Inst *inst); 294 static void VisitCallResolvedLaunchStatic(GraphVisitor *visitor, Inst *inst); 295 296 static void VisitCallLaunchVirtual(GraphVisitor *visitor, Inst *inst); 297 static void VisitCallResolvedLaunchVirtual(GraphVisitor *visitor, Inst *inst); 298 299 static void VisitCallDynamic(GraphVisitor *visitor, Inst *inst); 300 301 static void VisitLoadConstantPool(GraphVisitor *visitor, Inst *inst); 302 static void VisitLoadLexicalEnv(GraphVisitor *visitor, Inst *inst); 303 304 static void VisitLoadFromConstantPool(GraphVisitor *visitor, Inst *inst); 305 306 static void VisitSafePoint(GraphVisitor *visitor, Inst *inst); 307 308 static void VisitSelect(GraphVisitor *visitor, Inst *inst); 309 310 static void VisitSelectImm(GraphVisitor *visitor, Inst *inst); 311 312 static void VisitLoadArrayPair(GraphVisitor *visitor, Inst *inst); 313 314 static void VisitLoadArrayPairI(GraphVisitor *visitor, Inst *inst); 315 316 static void VisitLoadPairPart(GraphVisitor *visitor, Inst *inst); 317 318 static void VisitLoadObjectPair(GraphVisitor *visitor, Inst *inst); 319 320 static void VisitStoreArrayPair(GraphVisitor *visitor, Inst *inst); 321 322 static void VisitStoreArrayPairI(GraphVisitor *visitor, Inst *inst); 323 324 static void VisitStoreObjectPair(GraphVisitor *visitor, Inst *inst); 325 326 static void VisitLoadExclusive(GraphVisitor *visitor, Inst *inst); 327 328 static void VisitStoreExclusive(GraphVisitor *visitor, Inst *inst); 329 330 static void VisitNOP(GraphVisitor *visitor, Inst *inst); 331 332 static void VisitThrow(GraphVisitor *visitor, Inst *inst); 333 334 static void VisitDeoptimizeIf(GraphVisitor *visitor, Inst *inst); 335 336 static void VisitDeoptimizeCompare(GraphVisitor *visitor, Inst *inst); 337 338 static void VisitDeoptimizeCompareImm(GraphVisitor *visitor, Inst *inst); 339 340 static void VisitDeoptimize(GraphVisitor *visitor, Inst *inst); 341 342 static void VisitIsMustDeoptimize(GraphVisitor *visitor, Inst *inst); 343 344 static void VisitMAdd(GraphVisitor *visitor, Inst *inst); 345 static void VisitMSub(GraphVisitor *visitor, Inst *inst); 346 static void VisitMNeg(GraphVisitor *visitor, Inst *inst); 347 static void VisitOrNot(GraphVisitor *visitor, Inst *inst); 348 static void VisitAndNot(GraphVisitor *visitor, Inst *inst); 349 static void VisitXorNot(GraphVisitor *visitor, Inst *inst); 350 static void VisitNegSR(GraphVisitor *visitor, Inst *inst); 351 352 static void VisitGetInstanceClass(GraphVisitor *visitor, Inst *inst); 353 static void VisitGetManagedClassObject(GraphVisitor *visito, Inst *inst); 354 static void VisitLoadImmediate(GraphVisitor *visitor, Inst *inst); 355 static void VisitFunctionImmediate(GraphVisitor *visitor, Inst *inst); 356 static void VisitLoadObjFromConst(GraphVisitor *visitor, Inst *inst); 357 static void VisitRegDef(GraphVisitor *visitor, Inst *inst); 358 static void VisitLiveIn(GraphVisitor *visitor, Inst *inst); 359 static void VisitLiveOut(GraphVisitor *visitor, Inst *inst); 360 static void VisitCallIndirect(GraphVisitor *visitor, Inst *inst); 361 static void VisitCall(GraphVisitor *visitor, Inst *inst); 362 363 // Dyn inst. 364 static void VisitCompareAnyType(GraphVisitor *visitor, Inst *inst); 365 static void VisitGetAnyTypeName(GraphVisitor *visitor, Inst *inst); 366 static void VisitCastAnyTypeValue(GraphVisitor *visitor, Inst *inst); 367 static void VisitCastValueToAnyType(GraphVisitor *visitor, Inst *inst); 368 static void VisitAnyTypeCheck(GraphVisitor *visitor, Inst *inst); 369 static void VisitHclassCheck(GraphVisitor *visitor, Inst *inst); 370 static void VisitObjByIndexCheck(GraphVisitor *visitor, Inst *inst); 371 372 static void VisitLoadObjectDynamic(GraphVisitor *visitor, Inst *inst); 373 static void VisitStoreObjectDynamic(GraphVisitor *visitor, Inst *inst); 374 VisitDefault(Inst * inst)375 void VisitDefault([[maybe_unused]] Inst *inst) override 376 { 377 #ifndef NDEBUG 378 COMPILER_LOG(DEBUG, CODEGEN) << "Can't encode instruction " << GetOpcodeString(inst->GetOpcode()) 379 << " with type " << DataType::ToString(inst->GetType()); 380 #endif 381 success_ = false; 382 } 383 384 // Helper functions 385 static void FillUnresolvedClass(GraphVisitor *visitor, Inst *inst); 386 static void FillObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel); 387 static void FillOtherClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel); 388 static void FillArrayObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel); 389 static void FillArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel); 390 static void FillInterfaceClass(GraphVisitor *visitor, Inst *inst); 391 392 static void FillLoadClassUnresolved(GraphVisitor *visitor, Inst *inst); 393 394 static void FillCheckCast(GraphVisitor *visitor, Inst *inst, Reg src, LabelHolder::LabelId endLabel, 395 compiler::ClassType klassType); 396 397 static void FillIsInstanceUnresolved(GraphVisitor *visitor, Inst *inst); 398 399 static void FillIsInstanceCaseObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg); 400 401 static void FillIsInstanceCaseOther(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel); 402 403 static void FillIsInstanceCaseArrayObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg, 404 LabelHolder::LabelId endLabel); 405 406 static void FillIsInstanceCaseArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, 407 LabelHolder::LabelId endLabel); 408 409 static void FillIsInstanceCaseInterface(GraphVisitor *visitor, Inst *inst); 410 411 static void FillIsInstance(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel); 412 413 #include "optimizer/ir/visitor.inc" 414 415 private: 416 Codegen *cg_; 417 Arch arch_; 418 bool success_ {true}; 419 }; // EncodeVisitor 420 421 } // namespace ark::compiler 422 423 #endif // COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H 424