Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 "ccu_rep.h"
12 : #include "ccu_rep_reference_manager.h"
13 :
14 : #include "string_util.h"
15 : #include "exception_util.h"
16 : #include "ccu_api_exception.h"
17 :
18 : namespace Hccl {
19 : namespace CcuRep {
20 :
21 2 : CcuRepFuncCall::CcuRepFuncCall(const std::string& label) : label(label) { type = CcuRepType::FUNC_CALL; }
22 :
23 6 : CcuRepFuncCall::CcuRepFuncCall(const Variable& funcAddrVar) : label(""), funcAddrVar(funcAddrVar)
24 : {
25 2 : type = CcuRepType::FUNC_CALL;
26 2 : }
27 :
28 4 : const std::string& CcuRepFuncCall::GetLabel() const { return label; }
29 :
30 2 : void CcuRepFuncCall::Reference(std::shared_ptr<CcuRepFuncBlock> refRep) { funcBlock = refRep; }
31 :
32 4 : void CcuRepFuncCall::SetFuncManager(CcuRepReferenceManager* funcManager) { this->funcManager = funcManager; }
33 :
34 66 : void CcuRepFuncCall::SetInArg(const Variable& var)
35 : {
36 66 : inArgCount++;
37 66 : if (inArgCount > FUNC_IN_MAX) {
38 0 : HCCL_ERROR("[%s]CcuFunc Max ArgCount = %u, Current ArgCount = %u", __func__, FUNC_IN_MAX, inArgCount);
39 0 : THROW<CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_IN_MAX);
40 : }
41 66 : inArgs.push_back(CcuRepArg(var));
42 198 : HCCL_INFO("[%s]Define Input Arg: Index[%u], Type[Variable] Id[%u]", __func__, inArgs.size(), var.Id());
43 66 : }
44 :
45 2 : void CcuRepFuncCall::SetOutArg(const Variable& var)
46 : {
47 2 : outArgCount++;
48 2 : if (outArgCount > FUNC_OUT_MAX) {
49 0 : THROW<CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_OUT_MAX);
50 : }
51 2 : outArgs.push_back(CcuRepArg(var));
52 2 : }
53 :
54 0 : void CcuRepFuncCall::SetInArg(const std::vector<Variable>& varList)
55 : {
56 0 : inArgCount += varList.size();
57 0 : if (inArgCount > FUNC_IN_MAX) {
58 0 : HCCL_ERROR("[%s]CcuFunc Max ArgCount = %u, Current ArgCount = %u", __func__, FUNC_IN_MAX, inArgCount);
59 0 : THROW<CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_IN_MAX);
60 : }
61 0 : inArgs.push_back(CcuRepArg(varList));
62 0 : HCCL_INFO("[%s]Define Input Arg: Index[%u], Type[Variable List]: ", __func__, inArgs.size());
63 0 : }
64 :
65 0 : void CcuRepFuncCall::SetOutArg(const std::vector<Variable>& varList)
66 : {
67 0 : outArgCount += varList.size();
68 0 : if (outArgCount > FUNC_OUT_MAX) {
69 0 : THROW<CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_OUT_MAX);
70 : }
71 0 : outArgs.push_back(CcuRepArg(varList));
72 0 : }
73 :
74 12 : uint16_t CcuRepFuncCall::InstrCount()
75 : {
76 12 : instrCount = inArgCount + outArgCount + 4; // funcCall除去入参和出参的处理外,需要额外4条指令
77 12 : return instrCount;
78 : }
79 :
80 4 : bool CcuRepFuncCall::Translate(CcuInstr*& instr, uint16_t& instrId, const TransDep& dep)
81 : {
82 4 : if (funcManager == nullptr) {
83 0 : THROW<CcuApiException>("funcManager is nullptr");
84 : }
85 : // 未实现, FuncCall和FuncBlock中的args个数校验
86 4 : uint32_t extraInstrNum = 4; // funcCall除去入参和出参的处理外,需要额外4条指令
87 4 : if (this->instr == nullptr) {
88 4 : this->instrId = instrId;
89 4 : this->instr = instr;
90 4 : instr += InstrCount();
91 4 : instrId += InstrCount();
92 : }
93 :
94 4 : if (funcBlock != nullptr && !funcBlock->Translated()) {
95 0 : return translated;
96 : }
97 :
98 4 : translated = true;
99 :
100 4 : uint32_t iInArg = 0;
101 70 : for (uint32_t i = 0; i < inArgs.size(); i++) {
102 66 : if (inArgs[i].type == CcuArgType::VARIABLE) {
103 198 : LoadXXInstr(
104 66 : this->instr + iInArg, funcManager->GetFuncIn()[iInArg].Id(), inArgs[i].var.Id(), dep.reserveXnId);
105 66 : iInArg++;
106 0 : } else if (inArgs[i].type == CcuArgType::VARIABLE_LIST) {
107 0 : for (uint32_t j = 0; j < inArgs[i].varList.size(); j++) {
108 0 : LoadXXInstr(
109 0 : this->instr + iInArg, funcManager->GetFuncIn()[iInArg].Id(), inArgs[i].varList[j].Id(),
110 0 : dep.reserveXnId);
111 0 : iInArg++;
112 : }
113 : }
114 : }
115 :
116 4 : uint32_t locId = 0;
117 4 : if (funcBlock != nullptr) {
118 4 : LoadImdToXnInstr(
119 2 : this->instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), funcBlock->StartInstrId());
120 : } else {
121 6 : LoadXXInstr(
122 2 : this->instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), funcAddrVar.Id(), dep.reserveXnId);
123 : }
124 :
125 8 : LoadImdToXnInstr(
126 4 : this->instr + inArgCount + locId++, funcManager->GetFuncRet(GetCallLayer()).Id(),
127 4 : this->instrId + inArgCount + 3); // 需要指向函数返回位置,为输入指令Id + 3
128 4 : JumpInstr(this->instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), dep.reserveXnId, 1);
129 4 : LoadImdToXnInstr(this->instr + inArgCount + locId++, dep.reserveXnId, 0);
130 :
131 4 : uint32_t iOutArg = 0;
132 6 : for (uint32_t i = 0; i < outArgs.size(); i++) {
133 2 : if (outArgs[i].type == CcuArgType::VARIABLE) {
134 6 : LoadXXInstr(
135 2 : this->instr + inArgCount + extraInstrNum + iOutArg, outArgs[i].var.Id(),
136 2 : funcManager->GetFuncOut()[iOutArg].Id(), dep.reserveXnId);
137 2 : iOutArg++;
138 0 : } else if (outArgs[i].type == CcuArgType::VARIABLE_LIST) {
139 0 : for (uint32_t j = 0; j < outArgs[i].varList.size(); j++) {
140 0 : LoadXXInstr(
141 0 : this->instr + inArgCount + extraInstrNum + iOutArg, outArgs[i].varList[j].Id(),
142 0 : funcManager->GetFuncOut()[iOutArg].Id(), dep.reserveXnId);
143 0 : iOutArg++;
144 : }
145 : }
146 : }
147 :
148 4 : return translated;
149 : }
150 :
151 4 : std::string CcuRepFuncCall::Describe() { return StringFormat("FuncCall[%s]", label.c_str()); }
152 :
153 4 : int32_t CcuRepFuncCall::GetCallLayer() { return funcBlock == nullptr ? FUNC_NEST_MAX : funcBlock->GetCallLayer(); }
154 :
155 : }; // namespace CcuRep
156 : }; // namespace Hccl
|