mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!8982 refactor overflow to delete use of struct
Merge pull request !8982 from huangyan/delete_struct_hy
This commit is contained in:
commit
65f7c113f0
@ -776,6 +776,11 @@ void LiteCGIRBuilder::SaveGate2Expr(GateRef gate, Expr expr, bool isGlueAdd)
|
||||
gate2Expr_[gate] = {LiteCGValueKind::kConstKind, static_cast<maple::ConstvalNode*>(newNode)->GetConstVal()};
|
||||
}
|
||||
|
||||
void LiteCGIRBuilder::SaveGate2Expr(GateRef gate, PregIdx pregIdx1, PregIdx pregIdx2)
|
||||
{
|
||||
gate2Expr_[gate] = {LiteCGValueKind::kPregPairKind, std::make_pair(pregIdx1, pregIdx2)};
|
||||
}
|
||||
|
||||
Expr LiteCGIRBuilder::GetConstant(GateRef gate)
|
||||
{
|
||||
std::bitset<64> value = acc_.GetConstantValue(gate); // 64 for bit width
|
||||
@ -835,6 +840,18 @@ Expr LiteCGIRBuilder::GetExprFromGate(GateRef gate)
|
||||
return lmirBuilder_->Regread(std::get<PregIdx>(value.data));
|
||||
}
|
||||
|
||||
Expr LiteCGIRBuilder::GetExprFromGate(GateRef gate, uint32_t index)
|
||||
{
|
||||
LiteCGValue value = gate2Expr_[gate];
|
||||
ASSERT(value.kind == LiteCGValueKind::kPregPairKind);
|
||||
ASSERT(index == 0 || index == 1);
|
||||
std::pair<PregIdx, PregIdx> pair = std::get<std::pair<PregIdx, PregIdx>>(value.data);
|
||||
if (index == 0) {
|
||||
return lmirBuilder_->Regread(pair.first);
|
||||
}
|
||||
return lmirBuilder_->Regread(pair.second);
|
||||
}
|
||||
|
||||
void LiteCGIRBuilder::InitializeHandlers()
|
||||
{
|
||||
illegalOpHandlers_ = {OpCode::NOP,
|
||||
@ -2065,25 +2082,7 @@ void LiteCGIRBuilder::HandleAddWithOverflow(GateRef gate)
|
||||
|
||||
void LiteCGIRBuilder::VisitAddWithOverflow(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
// need use different symbol name?
|
||||
// get return type {i32 res, u1 carry}
|
||||
auto *retType = lmirBuilder_->GetStructType("overflow_internal@i32");
|
||||
retType = retType ? retType
|
||||
: lmirBuilder_->CreateStructType("overflow_internal@i32")
|
||||
.Field("res", lmirBuilder_->i32Type)
|
||||
.Field("carry", lmirBuilder_->u1Type)
|
||||
.Done();
|
||||
static uint32_t val = 0;
|
||||
std::string retVarName = "add_overflow_ret@i32" + std::to_string(val++);
|
||||
Var &retVar = lmirBuilder_->CreateLocalVar(retType, retVarName);
|
||||
|
||||
// generate function call
|
||||
Expr e1Value = GetExprFromGate(e1);
|
||||
Expr e2Value = GetExprFromGate(e2);
|
||||
std::vector<Expr> args = {e1Value, e2Value};
|
||||
auto &call = lmirBuilder_->IntrinsicCall(IntrinsicId::INTRN_ADD_WITH_OVERFLOW, args, &retVar);
|
||||
SaveGate2Expr(gate, lmirBuilder_->Dread(retVar));
|
||||
lmirBuilder_->AppendStmt(GetOrCreateBB(instID2bbID_[acc_.GetId(gate)]), call);
|
||||
VisitBinaryOpWithOverflow(gate, e1, e2, IntrinsicId::INTRN_ADD_WITH_OVERFLOW);
|
||||
}
|
||||
|
||||
void LiteCGIRBuilder::HandleSubWithOverflow(GateRef gate)
|
||||
@ -2097,25 +2096,7 @@ void LiteCGIRBuilder::HandleSubWithOverflow(GateRef gate)
|
||||
|
||||
void LiteCGIRBuilder::VisitSubWithOverflow(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
// need use different symbol name?
|
||||
// get return type {i32 res, u1 carry}
|
||||
auto *retType = lmirBuilder_->GetStructType("overflow_internal@i32");
|
||||
retType = retType ? retType
|
||||
: lmirBuilder_->CreateStructType("overflow_internal@i32")
|
||||
.Field("res", lmirBuilder_->i32Type)
|
||||
.Field("carry", lmirBuilder_->u1Type)
|
||||
.Done();
|
||||
static uint32_t val = 0;
|
||||
std::string retVarName = "sub_overflow_ret@i32" + std::to_string(val++);
|
||||
Var &retVar = lmirBuilder_->CreateLocalVar(retType, retVarName);
|
||||
|
||||
// generate function call
|
||||
Expr e1Value = GetExprFromGate(e1);
|
||||
Expr e2Value = GetExprFromGate(e2);
|
||||
std::vector<Expr> args = {e1Value, e2Value};
|
||||
auto &call = lmirBuilder_->IntrinsicCall(IntrinsicId::INTRN_SUB_WITH_OVERFLOW, args, &retVar);
|
||||
SaveGate2Expr(gate, lmirBuilder_->Dread(retVar));
|
||||
lmirBuilder_->AppendStmt(GetOrCreateBB(instID2bbID_[acc_.GetId(gate)]), call);
|
||||
VisitBinaryOpWithOverflow(gate, e1, e2, IntrinsicId::INTRN_SUB_WITH_OVERFLOW);
|
||||
}
|
||||
|
||||
void LiteCGIRBuilder::HandleMulWithOverflow(GateRef gate)
|
||||
@ -2129,24 +2110,20 @@ void LiteCGIRBuilder::HandleMulWithOverflow(GateRef gate)
|
||||
|
||||
void LiteCGIRBuilder::VisitMulWithOverflow(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
// need use different symbol name?
|
||||
// get return type {i32 res, u1 carry}
|
||||
auto *retType = lmirBuilder_->GetStructType("overflow_internal@i32");
|
||||
retType = retType ? retType
|
||||
: lmirBuilder_->CreateStructType("overflow_internal@i32")
|
||||
.Field("res", lmirBuilder_->i32Type)
|
||||
.Field("carry", lmirBuilder_->u1Type)
|
||||
.Done();
|
||||
static uint32_t val = 0;
|
||||
std::string retVarName = "mul_overflow_ret@i32" + std::to_string(val++);
|
||||
Var &retVar = lmirBuilder_->CreateLocalVar(retType, retVarName);
|
||||
VisitBinaryOpWithOverflow(gate, e1, e2, IntrinsicId::INTRN_MUL_WITH_OVERFLOW);
|
||||
}
|
||||
|
||||
void LiteCGIRBuilder::VisitBinaryOpWithOverflow(GateRef gate, GateRef e1, GateRef e2, IntrinsicId intrinsicId)
|
||||
{
|
||||
PregIdx preg1 = lmirBuilder_->CreatePreg(lmirBuilder_->i32Type);
|
||||
PregIdx preg2 = lmirBuilder_->CreatePreg(lmirBuilder_->u1Type);
|
||||
|
||||
// generate function call
|
||||
Expr e1Value = GetExprFromGate(e1);
|
||||
Expr e2Value = GetExprFromGate(e2);
|
||||
std::vector<Expr> args = {e1Value, e2Value};
|
||||
auto &call = lmirBuilder_->IntrinsicCall(IntrinsicId::INTRN_MUL_WITH_OVERFLOW, args, &retVar);
|
||||
SaveGate2Expr(gate, lmirBuilder_->Dread(retVar));
|
||||
auto &call = lmirBuilder_->IntrinsicCall(intrinsicId, args, preg1, preg2);
|
||||
SaveGate2Expr(gate, preg1, preg2);
|
||||
lmirBuilder_->AppendStmt(GetOrCreateBB(instID2bbID_[acc_.GetId(gate)]), call);
|
||||
}
|
||||
|
||||
@ -2513,15 +2490,10 @@ void LiteCGIRBuilder::HandleExtractValue(GateRef gate)
|
||||
|
||||
void LiteCGIRBuilder::VisitExtractValue(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
Expr e1Value = GetExprFromGate(e1);
|
||||
ASSERT((acc_.GetOpCode(e2) == OpCode::CONSTANT) && acc_.GetMachineType(e2) == MachineType::I32);
|
||||
uint32_t index = static_cast<uint32_t>(acc_.GetConstantValue(e2));
|
||||
Var *baseVar = lmirBuilder_->GetLocalVarFromExpr(e1Value);
|
||||
ASSERT(baseVar != nullptr);
|
||||
// in maple type system, field 0 means the agg itself and field index start from 1
|
||||
Expr rhs = lmirBuilder_->DreadWithField(*baseVar, index + 1);
|
||||
PregIdx pregIdx = lmirBuilder_->CreatePreg(rhs.GetType());
|
||||
lmirBuilder_->AppendStmt(GetOrCreateBB(instID2bbID_[acc_.GetId(gate)]), lmirBuilder_->Regassign(rhs, pregIdx));
|
||||
Expr expr = GetExprFromGate(e1, index);
|
||||
PregIdx pregIdx = lmirBuilder_->GetPregIdxFromExpr(expr);
|
||||
SaveGate2Expr(gate, lmirBuilder_->Regread(pregIdx));
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,9 @@ private:
|
||||
}
|
||||
}
|
||||
void SaveGate2Expr(GateRef gate, maple::litecg::Expr expr, bool isGlueAdd = false);
|
||||
void SaveGate2Expr(GateRef gate, maple::litecg::PregIdx pregIdx1, maple::litecg::PregIdx pregIdx2);
|
||||
maple::litecg::Expr GetExprFromGate(GateRef gate);
|
||||
maple::litecg::Expr GetExprFromGate(GateRef gate, uint32_t index);
|
||||
maple::litecg::Expr GetConstant(GateRef gate);
|
||||
void BuildInstID2BBIDMap();
|
||||
maple::litecg::BB &GetOrCreateBB(int bbID);
|
||||
@ -216,6 +218,7 @@ private:
|
||||
{
|
||||
return enableLog_;
|
||||
}
|
||||
void VisitBinaryOpWithOverflow(GateRef gate, GateRef e1, GateRef e2, maple::litecg::IntrinsicId intrinsicId);
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_LITECG_IR_BUILDER_H
|
||||
|
@ -163,9 +163,6 @@ public:
|
||||
|
||||
void LowerAsmStmt(AsmNode *asmNode, BlockNode *blk);
|
||||
|
||||
/* Lower pointer/reference types if found in pseudo registers. */
|
||||
void LowerPseudoRegs(const MIRFunction &func) const;
|
||||
|
||||
/* A pseudo register refers to a symbol when DreadNode is converted to RegreadNode. */
|
||||
StIdx GetSymbolReferredToByPseudoRegister(PregIdx regNO) const
|
||||
{
|
||||
|
@ -38,7 +38,6 @@ public:
|
||||
hashLabelOpndTable(mallocator.Adapter()),
|
||||
hashOfstOpndTable(mallocator.Adapter()),
|
||||
hashMemOpndTable(mallocator.Adapter()),
|
||||
stIdx2OverflowResult(mallocator.Adapter()),
|
||||
memOpndsRequiringOffsetAdjustment(mallocator.Adapter()),
|
||||
memOpndsForStkPassedArguments(mallocator.Adapter()),
|
||||
immOpndsRequiringOffsetAdjustment(mallocator.Adapter()),
|
||||
@ -533,7 +532,6 @@ private:
|
||||
MapleUnorderedMap<LabelIdx, LabelOperand *> hashLabelOpndTable;
|
||||
MapleUnorderedMap<OfstRegIdx, OfstOperand *> hashOfstOpndTable;
|
||||
MapleUnorderedMap<MemOperand, MemOperand *> hashMemOpndTable;
|
||||
MapleUnorderedMap<StIdx, std::pair<RegOperand *, RegOperand *>> stIdx2OverflowResult;
|
||||
/*
|
||||
* Local variables, formal parameters that are passed via registers
|
||||
* need offset adjustment after callee-saved registers are known.
|
||||
|
@ -136,11 +136,12 @@ enum LiteCGValueKind {
|
||||
kSymbolKind,
|
||||
kConstKind,
|
||||
kGlueAdd,
|
||||
kPregPairKind,
|
||||
};
|
||||
|
||||
struct LiteCGValue {
|
||||
LiteCGValueKind kind;
|
||||
std::variant<PregIdx, MIRSymbol*, MIRConst*> data;
|
||||
std::variant<PregIdx, MIRSymbol*, MIRConst*, std::pair<PregIdx, PregIdx>> data;
|
||||
};
|
||||
|
||||
using Args = std::vector<Expr>;
|
||||
@ -405,6 +406,8 @@ public:
|
||||
// when result is nullptr, don't need the result (or no result)
|
||||
Stmt &IntrinsicCall(IntrinsicId func, Args &valueArgs, Var *result = nullptr);
|
||||
|
||||
Stmt &IntrinsicCall(IntrinsicId func, Args &valueArgs, PregIdx retPregIdx1, PregIdx retPregIdx2);
|
||||
|
||||
Stmt &Return(Expr returnVal);
|
||||
|
||||
// debug info
|
||||
|
@ -1265,17 +1265,6 @@ void CGLowerer::LowerEntry(MIRFunction &func)
|
||||
}
|
||||
}
|
||||
|
||||
void CGLowerer::LowerPseudoRegs(const MIRFunction &func) const
|
||||
{
|
||||
for (uint32 i = 1; i < func.GetPregTab()->Size(); ++i) {
|
||||
MIRPreg *ipr = func.GetPregTab()->PregFromPregIdx(i);
|
||||
PrimType primType = ipr->GetPrimType();
|
||||
if (primType == PTY_u1) {
|
||||
ipr->SetPrimType(PTY_u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGLowerer::CleanupBranches(MIRFunction &func) const
|
||||
{
|
||||
BlockNode *block = func.GetBody();
|
||||
@ -1751,7 +1740,6 @@ void CGLowerer::LowerFunc(MIRFunction &func)
|
||||
labelIdx = 0;
|
||||
SetCurrentFunc(&func);
|
||||
LowerEntry(func);
|
||||
LowerPseudoRegs(func);
|
||||
BlockNode *origBody = func.GetBody();
|
||||
CHECK_FATAL(origBody != nullptr, "origBody should not be nullptr");
|
||||
|
||||
|
@ -937,22 +937,6 @@ void AArch64CGFunc::SelectIassign(IassignNode &stmt)
|
||||
Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr)
|
||||
{
|
||||
MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx());
|
||||
auto itr = stIdx2OverflowResult.find(expr.GetStIdx());
|
||||
if (itr != stIdx2OverflowResult.end()) {
|
||||
/* add_with_overflow / sub_with_overflow:
|
||||
* reg1: param1
|
||||
* reg2: param2
|
||||
* adds/subs reg3, reg1, reg2
|
||||
* cset reg4, vs
|
||||
* result is saved in std::pair<RegOperand*, RegOperand*>(reg3, reg4)
|
||||
*/
|
||||
if (expr.GetFieldID() == 1) {
|
||||
return itr->second.first;
|
||||
} else {
|
||||
DEBUG_ASSERT(expr.GetFieldID() == 2, "only has 2 fileds for intrinsic overflow call result");
|
||||
return itr->second.second;
|
||||
}
|
||||
}
|
||||
|
||||
PrimType symType = symbol->GetType()->GetPrimType();
|
||||
uint32 offset = 0;
|
||||
@ -4771,8 +4755,12 @@ void AArch64CGFunc::SelectOverFlowCall(const IntrinsiccallNode &intrnNode)
|
||||
intrnNode.Opnd(0)->GetPrimType()); /* first argument of intrinsic */
|
||||
RegOperand &opnd1 = LoadIntoRegister(*HandleExpr(intrnNode, *intrnNode.Opnd(1)),
|
||||
intrnNode.Opnd(1)->GetPrimType()); /* first argument of intrinsic */
|
||||
RegOperand &resReg = CreateRegisterOperandOfType(type);
|
||||
RegOperand &resReg2 = CreateRegisterOperandOfType(PTY_u8);
|
||||
auto *retVals = &intrnNode.GetReturnVec();
|
||||
CHECK_FATAL(retVals->size() == k2ByteSize, "there must be two return values");
|
||||
PregIdx pregIdx = (*retVals)[0].second.GetPregIdx();
|
||||
PregIdx pregIdx2 = (*retVals)[1].second.GetPregIdx();
|
||||
RegOperand &resReg = GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx));
|
||||
RegOperand &resReg2 = GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx2));
|
||||
Operand &rflag = GetOrCreateRflag();
|
||||
// arith operation with set flag
|
||||
if (intrinsic == INTRN_ADD_WITH_OVERFLOW) {
|
||||
@ -4791,11 +4779,6 @@ void AArch64CGFunc::SelectOverFlowCall(const IntrinsiccallNode &intrnNode)
|
||||
} else {
|
||||
CHECK_FATAL(false, "niy");
|
||||
}
|
||||
// store back
|
||||
auto *retVals = &intrnNode.GetReturnVec();
|
||||
auto &pair = retVals->at(0);
|
||||
stIdx2OverflowResult[pair.first] = std::pair<RegOperand *, RegOperand *>(&resReg, &resReg2);
|
||||
return;
|
||||
}
|
||||
|
||||
void AArch64CGFunc::SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode)
|
||||
|
@ -416,17 +416,21 @@ void X64MPIsel::SelectOverFlowCall(const IntrinsiccallNode &intrnNode)
|
||||
|
||||
// store
|
||||
auto *p2nrets = &intrnNode.GetReturnVec();
|
||||
if (p2nrets->size() == k1ByteSize) {
|
||||
StIdx stIdx = (*p2nrets)[0].first;
|
||||
if (p2nrets->size() == k2ByteSize) {
|
||||
CHECK_NULL_FATAL(cgFunc->GetBecommon().GetMIRModule().CurFunction());
|
||||
MIRSymbol *sym =
|
||||
cgFunc->GetBecommon().GetMIRModule().CurFunction()->GetSymTab()->GetSymbolFromStIdx(stIdx.Idx());
|
||||
DEBUG_ASSERT(sym != nullptr, "nullptr check");
|
||||
MemOperand &memOperand = GetOrCreateMemOpndFromSymbol(*sym, 1);
|
||||
MemOperand &memOperand2 = GetOrCreateMemOpndFromSymbol(*sym, 2);
|
||||
SelectCopy(memOperand, resReg, type);
|
||||
Insn &insn = cgFunc->GetInsnBuilder()->BuildInsn(MOP_seto_m, X64CG::kMd[MOP_seto_m]);
|
||||
insn.AddOpndChain(memOperand2);
|
||||
PregIdx pregIdx = (*p2nrets)[0].second.GetPregIdx();
|
||||
MIRPreg *mirPreg = cgFunc->GetFunction().GetPregTab()->PregFromPregIdx(pregIdx);
|
||||
PrimType regType = mirPreg->GetPrimType();
|
||||
RegOperand &retReg = cgFunc->GetOpndBuilder()->CreateVReg(cgFunc->GetVirtualRegNOFromPseudoRegIdx(pregIdx),
|
||||
GetPrimTypeBitSize(regType), cgFunc->GetRegTyFromPrimTy(regType));
|
||||
SelectCopy(retReg, resReg, type);
|
||||
PregIdx pregIdx2 = (*p2nrets)[1].second.GetPregIdx();
|
||||
MIRPreg *mirPreg2 = cgFunc->GetFunction().GetPregTab()->PregFromPregIdx(pregIdx2);
|
||||
PrimType regType2 = mirPreg2->GetPrimType();
|
||||
RegOperand &retReg2 = cgFunc->GetOpndBuilder()->CreateVReg(cgFunc->GetVirtualRegNOFromPseudoRegIdx(pregIdx2),
|
||||
GetPrimTypeBitSize(regType2), cgFunc->GetRegTyFromPrimTy(regType2));
|
||||
Insn &insn = cgFunc->GetInsnBuilder()->BuildInsn(MOP_seto_r, X64CG::kMd[MOP_seto_r]);
|
||||
insn.AddOpndChain(retReg2);
|
||||
cgFunc->GetCurBB()->AppendInsn(insn);
|
||||
} else {
|
||||
CHECK_FATAL(false, "should not happen");
|
||||
|
@ -562,6 +562,18 @@ Stmt &LMIRBuilder::IntrinsicCall(IntrinsicId func_, Args &args_, Var *result)
|
||||
}
|
||||
}
|
||||
|
||||
Stmt &LMIRBuilder::IntrinsicCall(IntrinsicId func_, Args &args_, PregIdx retPregIdx1, PregIdx retPregIdx2)
|
||||
{
|
||||
MapleVector<BaseNode *> args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter());
|
||||
for (const auto &arg : args_) {
|
||||
args.emplace_back(arg.GetNode());
|
||||
}
|
||||
|
||||
// need to fix the type for IntrinsicId
|
||||
auto func = static_cast<MIRIntrinsicID>(func_);
|
||||
return *mirBuilder.CreateStmtIntrinsicCallAssigned(func, args, retPregIdx1, retPregIdx2);
|
||||
}
|
||||
|
||||
Stmt &LMIRBuilder::Return(Expr returnVal)
|
||||
{
|
||||
return *mirBuilder.CreateStmtReturn(returnVal.GetNode());
|
||||
|
@ -303,6 +303,8 @@ public:
|
||||
CallNode *CreateStmtCallRegassigned(PUIdx, const MapleVector<BaseNode *> &, PregIdx, Opcode);
|
||||
IntrinsiccallNode *CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
|
||||
PregIdx retPregIdx);
|
||||
IntrinsiccallNode *CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
|
||||
PregIdx retPregIdx1, PregIdx retPregIdx2);
|
||||
IntrinsiccallNode *CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
|
||||
const MIRSymbol *ret, TyIdx tyIdx = TyIdx());
|
||||
IntrinsiccallNode *CreateStmtXintrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
|
||||
|
@ -1089,6 +1089,22 @@ IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID id
|
||||
return stmt;
|
||||
}
|
||||
|
||||
IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
|
||||
PregIdx retPregIdx1, PregIdx retPregIdx2)
|
||||
{
|
||||
auto *stmt =
|
||||
NewNode<IntrinsiccallNode>(*GetCurrentFuncCodeMpAllocator(), OP_intrinsiccallassigned, idx);
|
||||
DEBUG_ASSERT(stmt != nullptr, "stmt is null");
|
||||
stmt->SetOpnds(args);
|
||||
if (retPregIdx1 > 0) {
|
||||
stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, retPregIdx1)));
|
||||
}
|
||||
if (retPregIdx2 > 0) {
|
||||
stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, retPregIdx2)));
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
|
||||
IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
|
||||
const MIRSymbol *ret, TyIdx tyIdx)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user