diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index c5f23339205ad031b42d81ae6e0bdee4e98e5e8e..267e17d28089fa904af1a7536f02115363fea070 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -2480,8 +2480,10 @@ BaseNode *CGLowerer::LowerExpr(BaseNode &parent, BaseNode &expr, BlockNode &blkN case OP_select: if (IsComplexSelect(static_cast(expr))) { return LowerComplexSelect(static_cast(expr), parent, blkNode); - } else { + } else if (mirModule.GetFlavor() != kFlavorLmbc) { return SplitTernaryNodeResult(static_cast(expr), parent, blkNode); + } else { + return &expr; } case OP_sizeoftype: { diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index e14704bbc73667d01aa63fe936f8876713e8660e..454a3aa0e780be588dd883bd743de3f795e09c63 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3210,6 +3210,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; +// icall and icallproto class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) @@ -3285,7 +3286,7 @@ class IcallNode : public NaryStmtNode { } private: - TyIdx retTyIdx; // return type for callee + TyIdx retTyIdx; // for icall: return type for callee; for icallproto: the prototye // the 0th operand is the function pointer CallReturnVector returnValues; }; diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 249b619b075d5958d068a0737b1dad6e4cf79a30..d05c844f310ba34bfb2ff7db1a80642ba41fa20b 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -125,9 +125,10 @@ class MIRParser { PUIdx EnterUndeclaredFunction(bool isMcount = false); // for -pg in order to add "void _mcount()" bool ParseStmtCall(StmtNodePtr&); bool ParseStmtCallMcount(StmtNodePtr&); // for -pg in order to add "void _mcount()" to all the functions - bool ParseStmtIcall(StmtNodePtr&, bool isAssigned); + bool ParseStmtIcall(StmtNodePtr&, Opcode op); bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); + bool ParseStmtIcallproto(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index d1265eda42823ac0ed96f73921da6a9110acec57..34cfb51c8d11308ece1fbdf08f0616a76146e3ae 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -220,3 +220,4 @@ OPCODE(dassignoff, DassignoffNode, (OPCODEISSTMT | OPCODEHASSSADEF), 8) OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) + OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 843a7693ca10c4a9880c104416ff5f9de85a0402..5117ed8ed0fe8f6a5bc5512b01ccc2d9efa7f0f9 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -493,6 +493,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); OutputTypeViaTypeName(icallnode->GetRetTyIdx()); diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index f956ed2070a404e47e371d22e1d7120782bbb9c0..d18aac9f58351ce2a9b13d6f7ee857492fe0fd04 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -632,6 +632,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallproto: case OP_icall: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 9d09296ea119f807521cd45e0af46b8196816aae..08d2ff06a56304b30f74c12922c6b8fe3c092260 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -817,7 +817,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { type.GetParamAttrsList().push_back(ImportTypeAttrs()); } GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - CHECK_FATAL(type.GetRetTyIdx() != TyIdx(0), "ImportTypeNonJava: retTyIdx cannot be 0"); return tyIdxUsed; } case kBinKindTypeParam: { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index b20e80f88970ff4727ef8396cdbd35df32a67a80..4611246c1b2c0f68e433138ea7c958650fcb8e22 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1128,7 +1128,12 @@ void CallNode::Dump(int32 indent, bool newline) const { } MIRType *IcallNode::GetCallReturnType() { - return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); + if (op == OP_icall || op == OP_icallassigned) { + return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); + } + // icallproto + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); + return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); } const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { @@ -1150,6 +1155,10 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); + if (op == OP_icallproto) { + LogInfo::MapleLogger() << " "; + GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); + } NaryOpnds::Dump(indent); if (kOpcodeInfo.IsCallAssigned(GetOpCode())) { DumpCallReturns(*theMIRModule, this->returnValues, indent); diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 37daecc54a7d7dc088c4dafaac0df74774c966fb..6d4c28b105bf4a67d04588679fc39c8bf5d4c2f4 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -922,22 +922,31 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { return true; } -bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, bool isAssigned) { +bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // syntax: icall (, , ..., ) // icallassigned (, ..., ) { // dassign // dassign // . . . // dassign } - auto *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, !isAssigned ? OP_icall : OP_icallassigned); + // icallproto (, , ..., ) + IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); + if (op == OP_icallproto) { + TyIdx tyIdx(0); + if (!ParseDerivedType(tyIdx)) { + Error("error parsing type in ParseStmtIcall for icallproto at "); + return false; + } + iCallStmt->SetRetTyIdx(tyIdx); + } MapleVector opndsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseExprNaryOperand(opndsVec)) { return false; } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (isAssigned) { + if (op == OP_icallassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -950,11 +959,15 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, bool isAssigned) { } bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt) { - return ParseStmtIcall(stmt, false); + return ParseStmtIcall(stmt, OP_icall); } bool MIRParser::ParseStmtIcallassigned(StmtNodePtr &stmt) { - return ParseStmtIcall(stmt, true); + return ParseStmtIcall(stmt, OP_icallassigned); +} + +bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallproto); } bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { @@ -3399,6 +3412,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_interfacecallinstantassigned] = &MIRParser::ParseStmtCall; funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; + funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 90f056cfcbfe50c78c43d3b234d46bbad2aab835..a49aca1ce2a88be7902e78aae1d0785f87475a8f 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -47,6 +47,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); void LoadFormalsAssignedToPregs(); diff --git a/src/mapleall/maple_me/include/me_function.h b/src/mapleall/maple_me/include/me_function.h index 024d6e40b7db612f3cfad39ff992643b06c36287..3929edf4312e613e8c8fe7eeed173d0edebf5ded 100644 --- a/src/mapleall/maple_me/include/me_function.h +++ b/src/mapleall/maple_me/include/me_function.h @@ -402,6 +402,7 @@ class MeFunction : public FuncEmit { uint32 hdseRuns = 0; // number of times hdse phase has been run uint32 hpropRuns = 0; // number of times hprop phase has been run uint32 vrpRuns = 0; // number of times vrp phase has been run + bool genLMBC = false; // whether outputing lmbc (low maple bytecode) }; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_FUNCTION_H diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index 746fbeabc94e6d23440a5018f3ffb2470e74dd49..5660778bbc3fbadd6160840c492dc1c8f39dbee9 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -333,6 +333,101 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } +MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = dynamic_cast(static_cast(mirType)->GetPointedType()); + } else { + res = dynamic_cast(mirType); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = dynamic_cast(static_cast(mirType)->GetPointedType()); + } else { + res = dynamic_cast(mirType); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = dynamic_cast(mirType); + CHECK_FATAL(structty, "LMBCLowerer::FuncTypeFromFuncPtrExpr: non-zero fieldID for non-structure"); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = dynamic_cast(static_cast(mirType)->GetPointedType()); + } else { + res = dynamic_cast(mirType); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = dynamic_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypePointer) { + res = dynamic_cast(static_cast(mirType)->GetPointedType()); + } else { + res = dynamic_cast(mirType); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = dynamic_cast(static_cast(mirType)->GetPointedType()); + } else { + res = dynamic_cast(mirType); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { // go through each parameter uint32 i = 0; @@ -394,7 +489,13 @@ void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { opnd0 = naryStmt->Opnd(0); naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->GetNopnd().push_back(opnd0); + // convert to OP_icallproto by finding the function prototype and record in stmt + naryStmt->SetOpCode(OP_icallproto); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); + CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); + static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); + // add back the function pointer operand + naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); naryStmt->SetNumOpnds(1); } else { naryStmt->GetNopnd().clear(); // remove the call operands diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 9194d9232535a5ea12fc276582316d1798f7cc4d..0177039ff3fd3a710050dfc3f22b310c237a2f01 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -100,6 +100,9 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { auto meFuncStackMP = std::make_unique(memPoolCtrler, ""); MemPool *versMP = new ThreadLocalMemPool(memPoolCtrler, "first verst mempool"); MeFunction &meFunc = *(meFuncMP->New(&m, func, meFuncMP.get(), *meFuncStackMP, versMP, meInput)); + if (genLMBC) { + meFunc.genLMBC = true; + } func->SetMeFunc(&meFunc); meFunc.PartialInit(); #if DEBUG diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index d43864ea983af1568f34df15365d9349f1548940..1fa9b83126eb9d733d783f98513c6f4991670706 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -375,6 +375,9 @@ void MeSSALPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, if (!MeOption::lpre4Address) { break; } + if (func->genLMBC) { + break; + } CreateRealOcc(meStmt, seqStmt, meExpr, false); break; } diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index 307b93af10ff640c65c713a82e773abd6d5ef0c8..010399bc958d44235e6e6ec93fd9fc84d3317d67 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -642,6 +642,12 @@ MeExpr &Prop::PropVar(VarMeExpr &varMeExpr, bool atParm, bool checkPhi) { propsPerformed >= propLimit) { return varMeExpr; } + if (st->GetType() && st->GetType()->GetKind() == kTypePointer) { + MIRPtrType *ptrType = static_cast(st->GetType()); + if (ptrType->GetPointedType()->GetKind() == kTypeFunction) { + return varMeExpr; + } + } if (varMeExpr.GetDefBy() == kDefByStmt) { DassignMeStmt *defStmt = static_cast(varMeExpr.GetDefStmt()); diff --git a/src/mapleall/maple_me/src/ssa_epre.cpp b/src/mapleall/maple_me/src/ssa_epre.cpp index 34e1f1812a40c49774855907a87ccb1b9ca71e9f..9ddf02c99ae5254ea919045eb9f196c5dc2bbad5 100644 --- a/src/mapleall/maple_me/src/ssa_epre.cpp +++ b/src/mapleall/maple_me/src/ssa_epre.cpp @@ -368,7 +368,8 @@ void SSAEPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, b if (!epreIncludeRef && meOpExpr->GetPrimType() == PTY_ref) { break; } - if (meOpExpr->GetOp() == OP_gcmallocjarray || meOpExpr->GetOp() == OP_gcmalloc) { + if (meOpExpr->GetOp() == OP_gcmallocjarray || meOpExpr->GetOp() == OP_gcmalloc || + meOpExpr->GetOp() == OP_retype) { break; } if (isRebuild && !hasTempVarAs1Opnd) {