LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_microcode_opt - extract_operands.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.7 % 195 136
Test Date: 2026-08-25 19:18:03 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "extract_operands.h"
      12              : 
      13              : #include "config/barrier_config.h"
      14              : 
      15              : namespace hcomm {
      16              : namespace CcuOpt {
      17              : 
      18              :     namespace {
      19              : 
      20              :         // reduce.count 字段以 "实际 ms 数 - 2" 编码, 且仅占低 3 位:
      21              :         // 实际 ms 数 = (count_field & 0x7) + 2.
      22              :         constexpr uint16_t CCU_REDUCE_COUNT_MASK = 0x7;
      23              :         constexpr uint16_t CCU_REDUCE_COUNT_BIAS = 2;
      24              :         // operate.parMode == 1: 第二操作数为寄存器 (Xd = Xn @ Xm); == 0 时为 imm16.
      25              :         constexpr uint16_t PARMODE_REGISTER_PAIR = 1;
      26              :         // set/clearCKE.clearType == 1: 命中后自动清零 waitCKEId, 该 CKE 位既读又写.
      27              :         constexpr uint16_t CLEARTYPE_AUTO = 1;
      28              : 
      29          558 :         inline void AddRead(std::vector<RegOperand>& out, RegType type, uint16_t regId)
      30              :         {
      31          558 :             if (regId == 0 && type == RegType::CKE) {
      32           25 :                 return;
      33              :             }
      34          533 :             out.push_back(RegOperand{type, regId, /*isDef=*/false});
      35              :         }
      36              : 
      37          495 :         inline void AddWrite(std::vector<RegOperand>& out, RegType type, uint16_t regId)
      38              :         {
      39          495 :             if (regId == 0 && type == RegType::CKE) {
      40           25 :                 return;
      41              :             }
      42          470 :             out.push_back(RegOperand{type, regId, /*isDef=*/true});
      43              :         }
      44              : 
      45              :         // Load 类中的访存 / 清零指令 (非算子). 返回 true 表示已处理该 code.
      46          645 :         bool ExtractLoadMemOps(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
      47              :         {
      48              :             using namespace InstrCodeV2;
      49          645 :             switch (instr.header.code) {
      50           15 :                 case LOADSQEARGSTOX_CODE:
      51           15 :                     AddWrite(out, RegType::XN, instr.v2.loadSqeArgsToX.xnId);
      52           15 :                     return true;
      53          269 :                 case LOADIMDTOX_CODE:
      54          269 :                     AddWrite(out, RegType::XN, instr.v2.loadImdToX.xnId);
      55          269 :                     return true;
      56            0 :                 case LOADSTOREX_CODE:
      57              :                     // Xd = *Xs, *Xdo = Xso (读改写形式), 保守全部当作读写.
      58            0 :                     AddRead(out, RegType::XN, instr.v2.loadStoreX.xsId);
      59            0 :                     AddRead(out, RegType::XN, instr.v2.loadStoreX.xsoId);
      60            0 :                     AddRead(out, RegType::XN, instr.v2.loadStoreX.xdoId);
      61            0 :                     AddWrite(out, RegType::XN, instr.v2.loadStoreX.xdId);
      62            0 :                     return true;
      63            0 :                 case CLEARX_CODE:
      64              :                     // ClearX 语义为把指定 Xn / Xm 清零, 两者都是 def.
      65            0 :                     AddWrite(out, RegType::XN, instr.v2.clearX.xnId);
      66            0 :                     AddWrite(out, RegType::XN, instr.v2.clearX.xmId);
      67            0 :                     return true;
      68          202 :                 case NOP_CODE:
      69              :                     // 无寄存器操作数.
      70          202 :                     return true;
      71            0 :                 case LOAD_CODE:
      72            0 :                     AddRead(out, RegType::XN, instr.v2.load.xsId);
      73            0 :                     AddRead(out, RegType::XN, instr.v2.load.xstId);
      74            0 :                     AddRead(out, RegType::XN, instr.v2.load.xlId);
      75            0 :                     AddWrite(out, RegType::XN, instr.v2.load.xdId);
      76            0 :                     return true;
      77            0 :                 case STORE_CODE:
      78            0 :                     AddRead(out, RegType::XN, instr.v2.store.xdId);
      79            0 :                     AddRead(out, RegType::XN, instr.v2.store.xdtId);
      80            0 :                     AddRead(out, RegType::XN, instr.v2.store.xsId);
      81            0 :                     AddRead(out, RegType::XN, instr.v2.store.xlId);
      82            0 :                     AddRead(out, RegType::XN, instr.v2.store.xhId);
      83            0 :                     return true;
      84          159 :                 default:
      85          159 :                     return false;
      86              :             }
      87              :         }
      88              : 
      89              :         // Load 类中的算子指令 (Add / Sub / Mul / And / Or / Xor / Shl / Shr / Popcnt / Not).
      90              :         // Xd = Xn @ Xm (parMode == 1) 或 Xd = Xn @ imm16 (parMode == 0); Not / Popcnt 仅使用 Xn.
      91          159 :         void ExtractLoadOperator(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
      92              :         {
      93              :             using namespace InstrCodeV2;
      94          159 :             switch (instr.header.code) {
      95          158 :                 case ADD_CODE:
      96              :                 case SUB_CODE:
      97              :                 case MUL_CODE:
      98              :                 case AND_CODE:
      99              :                 case OR_CODE:
     100              :                 case XOR_CODE:
     101              :                 case SHL_CODE:
     102              :                 case SHR_CODE:
     103              :                 case POPCNT_CODE:
     104          158 :                     AddWrite(out, RegType::XN, instr.v2.operate.xdId);
     105          158 :                     AddRead(out, RegType::XN, instr.v2.operate.xnId);
     106          158 :                     if (instr.v2.operate.parMode == PARMODE_REGISTER_PAIR) {
     107           80 :                         AddRead(out, RegType::XN, instr.v2.operate.xmId);
     108              :                     }
     109          158 :                     break;
     110            1 :                 case NOT_CODE:
     111            1 :                     AddWrite(out, RegType::XN, instr.v2.operate.xdId);
     112            1 :                     AddRead(out, RegType::XN, instr.v2.operate.xnId);
     113            1 :                     break;
     114            0 :                 default:
     115            0 :                     break;
     116              :             }
     117          159 :         }
     118              : 
     119          645 :         void ExtractLoadType(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     120              :         {
     121          645 :             if (!ExtractLoadMemOps(out, instr)) {
     122          159 :                 ExtractLoadOperator(out, instr);
     123              :             }
     124              :             // setCKEId 不作为 CKE def, 不提取 (见文件顶部 set 语义说明).
     125          645 :         }
     126              : 
     127          117 :         void ExtractCtrlType(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     128              :         {
     129              :             using namespace InstrCodeV2;
     130          117 :             switch (instr.header.code) {
     131           20 :                 case LOOP_CODE:
     132              :                     // xmId = IterNum, xnId = Offset, xpId = ContextId; 三者都是 Xn 寄存器.
     133           20 :                     AddRead(out, RegType::XN, instr.v2.loop.xmId);
     134           20 :                     AddRead(out, RegType::XN, instr.v2.loop.xnId);
     135           20 :                     AddRead(out, RegType::XN, instr.v2.loop.xpId);
     136           20 :                     break;
     137           10 :                 case LOOPGROUP_CODE:
     138           10 :                     AddRead(out, RegType::XN, instr.v2.loopGroup.xnId);
     139           10 :                     AddRead(out, RegType::XN, instr.v2.loopGroup.xmId);
     140           10 :                     AddRead(out, RegType::XN, instr.v2.loopGroup.xpId);
     141           10 :                     break;
     142           32 :                 case SETCKBIT_CODE:
     143           32 :                     AddRead(out, RegType::CKE, instr.v2.setCKE.waitCKEId);
     144           32 :                     if (instr.v2.setCKE.clearType == CLEARTYPE_AUTO) {
     145           32 :                         AddWrite(out, RegType::CKE, instr.v2.setCKE.waitCKEId);
     146              :                     }
     147           32 :                     break;
     148           15 :                 case CLEARCKBIT_CODE:
     149              :                     // 与 setcke 对称: 只有 clearType=1 自动清零的 waitCKEId 才是 CKE 写者 (read + def);
     150              :                     // clearCKEId 只是主动清某位, 同样不作为触发写后读的 def.
     151           15 :                     AddRead(out, RegType::CKE, instr.v2.clearCKE.waitCKEId);
     152           15 :                     if (instr.v2.clearCKE.clearType == CLEARTYPE_AUTO) {
     153           14 :                         AddWrite(out, RegType::CKE, instr.v2.clearCKE.waitCKEId);
     154              :                     }
     155           15 :                     break;
     156           40 :                 case JMP_CODE:
     157           40 :                     AddRead(out, RegType::XN, instr.v2.jmp.relTarInstrXnId);
     158           40 :                     AddRead(out, RegType::XN, instr.v2.jmp.conditionXnId);
     159           40 :                     AddRead(out, RegType::XN, instr.v2.jmp.expectedXnId);
     160           40 :                     break;
     161            0 :                 case WAIT_CODE:
     162            0 :                     AddRead(out, RegType::XN, instr.v2.wait.conditionXnId);
     163            0 :                     AddRead(out, RegType::XN, instr.v2.wait.expectedXnId);
     164            0 :                     break;
     165            0 :                 case FENCE_CODE:
     166            0 :                     break;
     167            0 :                 default:
     168            0 :                     break;
     169              :             }
     170          117 :         }
     171              : 
     172              :         // Trans 类中的纯搬运指令 (Mem<->MS / Mem<->Mem / TransMem). 返回 true 表示已处理该 code.
     173           11 :         bool ExtractTransMoveOps(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     174              :         {
     175              :             using namespace InstrCodeV2;
     176           11 :             switch (instr.header.code) {
     177            4 :                 case TRANSLOCMEMTOLOCMS_CODE:
     178            4 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMS.xsId);
     179            4 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMS.xstId);
     180            4 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMS.xlId);
     181            4 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMS.xoId);
     182            4 :                     AddWrite(out, RegType::MS, instr.v2.transLocMemToLocMS.msId);
     183            4 :                     return true;
     184            2 :                 case TRANSLOCMSTOLOCMEM_CODE:
     185            2 :                     AddRead(out, RegType::MS, instr.v2.transLocMSToLocMem.msId);
     186            2 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMem.xdId);
     187            2 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMem.xdtId);
     188            2 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMem.xlId);
     189            2 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMem.xoId);
     190            2 :                     return true;
     191            0 :                 case TRANSLOCMSTOLOCMS_CODE:
     192            0 :                     AddRead(out, RegType::MS, instr.v2.transLocMSToLocMS.mssId);
     193            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMS.xlId);
     194            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMSToLocMS.xoId);
     195            0 :                     AddWrite(out, RegType::MS, instr.v2.transLocMSToLocMS.msdId);
     196            0 :                     return true;
     197            0 :                 case TRANSLOCMEMTOLOCMEM_CODE:
     198            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMem.xdId);
     199            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMem.xdtId);
     200            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMem.xsId);
     201            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMem.xstId);
     202            0 :                     AddRead(out, RegType::XN, instr.v2.transLocMemToLocMem.xlId);
     203              :                     // usedMSId / msNum 描述临时 MS 区段, 保守视作 read.
     204            0 :                     AddRead(out, RegType::MS, instr.v2.transLocMemToLocMem.usedMSId);
     205            0 :                     return true;
     206            1 :                 case TRANSMEM_CODE:
     207            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xdId);
     208            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xdtId);
     209            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xsId);
     210            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xstId);
     211            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xlId);
     212            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xcId);
     213            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xnId);
     214            1 :                     AddRead(out, RegType::XN, instr.v2.transMem.xntId);
     215            1 :                     return true;
     216            4 :                 default:
     217            4 :                     return false;
     218              :             }
     219              :         }
     220              : 
     221              :         // Trans 类中的同步指令 (SyncWtX / SyncAtX).
     222            4 :         void ExtractTransSyncOps(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     223              :         {
     224              :             using namespace InstrCodeV2;
     225            4 :             switch (instr.header.code) {
     226            4 :                 case SYNCWTX_CODE:
     227            4 :                     AddRead(out, RegType::XN, instr.v2.syncWtX.xdId);
     228            4 :                     AddRead(out, RegType::XN, instr.v2.syncWtX.xdtId);
     229            4 :                     AddRead(out, RegType::XN, instr.v2.syncWtX.xsId);
     230            4 :                     AddRead(out, RegType::XN, instr.v2.syncWtX.xcId);
     231            4 :                     if (instr.v2.syncWtX.notifyValid != 0) {
     232            3 :                         AddRead(out, RegType::XN, instr.v2.syncWtX.xnId);
     233            3 :                         AddRead(out, RegType::XN, instr.v2.syncWtX.xntId);
     234              :                     }
     235            4 :                     break;
     236            0 :                 case SYNCATX_CODE:
     237            0 :                     AddRead(out, RegType::XN, instr.v2.syncAtX.xdId);
     238            0 :                     AddRead(out, RegType::XN, instr.v2.syncAtX.xdtId);
     239            0 :                     AddRead(out, RegType::XN, instr.v2.syncAtX.xsId);
     240            0 :                     AddRead(out, RegType::XN, instr.v2.syncAtX.xcId);
     241            0 :                     break;
     242            0 :                 default:
     243            0 :                     break;
     244              :             }
     245            4 :         }
     246              : 
     247           11 :         void ExtractTransType(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     248              :         {
     249           11 :             if (!ExtractTransMoveOps(out, instr)) {
     250            4 :                 ExtractTransSyncOps(out, instr);
     251              :             }
     252              :             // setCKEId 不作为 CKE def, 不提取 (见文件顶部 set 语义说明).
     253           11 :         }
     254              : 
     255            2 :         void ExtractReduceType(std::vector<RegOperand>& out, const CcuRep::CcuInstr& instr)
     256              :         {
     257              :             // ReduceAdd / ReduceMax / ReduceMin: MSA~MSH reduce to MSA, msId[0] 既读又写.
     258            2 :             uint16_t countInInstr = instr.v2.reduce.count;
     259              :             // countInInstr 是 "count - 2" 后存进去的, 实际 ms 数 = count_field + 2.
     260            2 :             uint16_t realCount = (countInInstr & CCU_REDUCE_COUNT_MASK) + CCU_REDUCE_COUNT_BIAS;
     261            2 :             if (realCount > CcuRep::CCU_REDUCE_MAX_MS) {
     262            0 :                 realCount = CcuRep::CCU_REDUCE_MAX_MS;
     263              :             }
     264              : 
     265            2 :             AddRead(out, RegType::MS, instr.v2.reduce.msId[0]);
     266            2 :             AddWrite(out, RegType::MS, instr.v2.reduce.msId[0]);
     267            4 :             for (uint16_t i = 1; i < realCount; ++i) {
     268            2 :                 AddRead(out, RegType::MS, instr.v2.reduce.msId[i]);
     269              :             }
     270            2 :             AddRead(out, RegType::XN, instr.v2.reduce.XnIdLength);
     271              :             // setCKEId 不作为 CKE def, 不提取 (见文件顶部 set 语义说明).
     272            2 :         }
     273              : 
     274              :     } // namespace
     275              : 
     276          775 :     std::vector<RegOperand> ExtractOperandsV2(const CcuRep::CcuInstr& instr)
     277              :     {
     278              :         using namespace InstrCodeV2;
     279          775 :         std::vector<RegOperand> out;
     280          775 :         out.reserve(8);
     281          775 :         switch (instr.header.type) {
     282          645 :             case LOAD_TYPE:
     283          645 :                 ExtractLoadType(out, instr);
     284          645 :                 break;
     285          117 :             case CTRL_TYPE:
     286          117 :                 ExtractCtrlType(out, instr);
     287          117 :                 break;
     288           11 :             case TRANS_TYPE:
     289           11 :                 ExtractTransType(out, instr);
     290           11 :                 break;
     291            2 :             case REDUCE_TYPE:
     292            2 :                 ExtractReduceType(out, instr);
     293            2 :                 break;
     294            0 :             default:
     295            0 :                 break;
     296              :         }
     297          775 :         return out;
     298            0 :     }
     299              : 
     300              : } // namespace CcuOpt
     301              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1