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