From 885bc5edab35ed5551f32150c926b82331535270 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 14 Nov 2022 19:25:42 -0800 Subject: [PATCH 1/3] Added back the missing maple IR verifier (mplverf) from incubator Also strengthened some checks that have been relaxed. Put back the commented rules in mir_nodes.cpp. --- BUILD.gn | 4 + Makefile | 6 +- src/mapleall/BUILD.gn | 4 + src/mapleall/maple_ir/BUILD.gn | 14 +++ src/mapleall/maple_ir/CMakeLists.txt | 11 ++ src/mapleall/maple_ir/src/mir_nodes.cpp | 116 ++++++++++++++++++-- src/mapleall/maple_ir/src/mpl_verify.cpp | 133 +++++++++++++++++++++++ 7 files changed, 279 insertions(+), 9 deletions(-) create mode 100644 src/mapleall/maple_ir/src/mpl_verify.cpp diff --git a/BUILD.gn b/BUILD.gn index 40e691379f..50821caea1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -20,6 +20,10 @@ group("irbuild") { deps = [ "${MAPLEALL_ROOT}:irbuild" ] } +group("mplverf") { + deps = [ "${MAPLEALL_ROOT}:mplverf" ] +} + group("hir2mpl") { deps = [ "${HIR2MPL_ROOT}:hir2mpl" ] } diff --git a/Makefile b/Makefile index e3a7e3bc88..f74a3cde86 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,10 @@ irbuild: install_patch mpldbg: $(call build_gn, $(GN_OPTIONS), mpldbg) +.PHONY: mplverf +mplverf: install_patch + $(call build_gn, $(GN_OPTIONS), mplverf) + .PHONY: ast2mpl ast2mpl: $(call build_gn, $(GN_OPTIONS), ast2mpl) @@ -137,7 +141,7 @@ java-core-def: install $(MAKE) gen-def OPT=$(OPT) DEBUG=$(DEBUG) .PHONY: install -install: maple dex2mpl_install irbuild hir2mpl +install: maple dex2mpl_install irbuild hir2mpl mplverf $(shell mkdir -p $(INSTALL_DIR)/ops/linker/; \ rsync -a -L $(MRT_ROOT)/maplert/linker/maplelld.so.lds $(INSTALL_DIR)/ops/linker/; \ rsync -a -L $(MAPLE_ROOT)/build/java2d8 $(INSTALL_DIR)/bin; \ diff --git a/src/mapleall/BUILD.gn b/src/mapleall/BUILD.gn index 73605d9877..dee5464472 100644 --- a/src/mapleall/BUILD.gn +++ b/src/mapleall/BUILD.gn @@ -121,3 +121,7 @@ group("irbuild") { group("maplegen") { deps = [ "${MAPLEALL_ROOT}/maple_be:maplegen" ] } + +group("mplverf") { + deps = [ "${MAPLEALL_ROOT}/maple_ir:mplverf" ] +} diff --git a/src/mapleall/maple_ir/BUILD.gn b/src/mapleall/maple_ir/BUILD.gn index 79155184d4..0b797ce04c 100755 --- a/src/mapleall/maple_ir/BUILD.gn +++ b/src/mapleall/maple_ir/BUILD.gn @@ -107,3 +107,17 @@ executable("mpldbg") { "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", ] } + +src_mplverf = [ "src/mpl_verify.cpp" ] + +executable("mplverf") { + sources = src_mplverf + include_dirs = include_directories + deps = [ + ":libmplir", + "${MAPLEALL_ROOT}/mempool:libmempool", + "${MAPLEALL_ROOT}/mpl2mpl:libmpl2mpl", + "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", + "${MAPLEALL_ROOT}/maple_driver:libmaple_driver", + ] +} diff --git a/src/mapleall/maple_ir/CMakeLists.txt b/src/mapleall/maple_ir/CMakeLists.txt index 24d556a4e6..8da1c6037e 100755 --- a/src/mapleall/maple_ir/CMakeLists.txt +++ b/src/mapleall/maple_ir/CMakeLists.txt @@ -65,6 +65,8 @@ set(src_irbuild "src/driver.cpp") set(src_mpldbg "src/mpl_dbg.cpp") +set(src_mplverf "src/mpl_verify.cpp") + set(deps_libmplir libdriver_option libmplphase @@ -113,3 +115,12 @@ set_target_properties(mpldbg PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MAPLE_BUILD_OUTPUT}/bin" ) +#mplverf +add_executable(mplverf "${src_mplverf}") +set_target_properties(mplverf PROPERTIES + COMPILE_FLAGS "" + INCLUDE_DIRECTORIES "${inc_libmplir}" + LINK_LIBRARIES "${deps_irbuild}" + RUNTIME_OUTPUT_DIRECTORY "${MAPLE_BUILD_OUTPUT}/bin" +) + diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 7a03023d85..e3be06406b 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1612,6 +1612,100 @@ void AsmNode::Dump(int32 indent) const { LogInfo::MapleLogger() << " }\n"; } +// Start of type verification for Maple IR nodes. +// +// General rules: +// +// 1. For binary operations, the types of the two operands must be compatible. +// +// 2. In checking type compatibility, other than identical types, the types in +// each of the following group are compatible with each other: +// [i32, u32, ptr, ref, a32] +// [i64, u64, ptr, ref, a64] +// +// 3. dynany is compatiable with any dyn* type. +// +// 4. u1, i8, u8, i16, u16 must not be types of arithmetic operations, because +// many machines do not provide instructions for such types as they lack such +// register sizes. Similarly, these types must not be used as result types for +// any read instructions: dread/iread/regread/ireadoff/ireadfpoff. +// +// 5. When an opcode only specifies one type (which is called the result type), +// it expects both operands and results to be of this same type. Thus, the +// types among the operands and this result type must be compatible. +// +// 6. When an opcode specifies two types, the additional (second) type is +// the operand type. The types of the operands and the operand type must be +// compatible. +// +// 7. The opcodes addrof, addroflabel, addroffunc and iaddrof form addresses. +// Thus, their result type must be in [ptr,ref,a32,a64]. +// +// 8. The opcodes bnot, extractbits, sext, zext, lnot must have result type in +// [i32, u32, i64, u64]. +// +// 9. The opcodes abs, neg must have result type in +// [i32, u32, i64, u64, f32, f64]. +// +// 10. The opcodes recip, sqrt must have result type in [f32, f64]. +// +// 11. The opcodes ceil, floor, round, trunc must have result-type in +// [i32, u32, i64, u64] and operand-type in [f32, f64]. +// +// 12. The opcodes add, div, sub, mpy, max, min must have result-type in +// [i32, u32, i64, u64, f32, f64]. +// +// 13. The opcodes eq, ge, gt, le, lt, ne must have result-type in +// any signed or unsigned integer type; they also specifies operand-type, and +// this operand-type and the types of their two operands must be compatible. +// +// 14. The opcodes ashr, band, bior, bxor, depositbits, land, lior, lshr, shl, +// rem must have result-type in [i32, u32, i64, u64]. +// +// 15. select's result-type and the types of its second and third operands must +// be compatible; its first operand must be of integer type. +// +// 16. array's result-type must be in [ptr,ref,a32,a64]; the type of must +// also be in [ptr,ref,a32,a64]; the types of the rest of the operands must be in +// [i32, u32, i64, u64]. +// +// 17. The operand of brfalse, trfalse must be of integer type. +// +// 18. The operand of switch, rangegoto must be in [i32, u32, i64, u64]. + +inline bool ExcludeSmallIntTypeVerify(const BaseNode &opnd) { + switch (opnd.GetPrimType()) { + case PTY_u1: + case PTY_i8: + case PTY_u8: + case PTY_i16: + case PTY_u16: + return false; + default: + break; + } + return true; +} + +inline bool ArithTypeVerify(const BaseNode &opnd) { + bool verifyResult = ExcludeSmallIntTypeVerify(opnd); + if (!verifyResult) { + LogInfo::MapleLogger() << "\n#Error:u1,i8,u8,i16,u16 should not be used as types of arithmetic operations\n"; + opnd.Dump(); + } + return verifyResult; +} + +inline bool ReadTypeVerify(const BaseNode &opnd) { + bool verifyResult = ExcludeSmallIntTypeVerify(opnd); + if (!verifyResult) { + LogInfo::MapleLogger() + << "\n#Error:u1,i8,u8,i16,u16 should not be used as result types for dread/iread/regread/ireadoff/ireadfpoff\n"; + opnd.Dump(); + } + return verifyResult; +} + inline bool IntTypeVerify(PrimType pTyp) { return pTyp == PTY_i32 || pTyp == PTY_u32 || pTyp == PTY_i64 || pTyp == PTY_u64; } @@ -1670,7 +1764,7 @@ inline bool BinaryTypeVerify(PrimType pType) { } inline bool BinaryGenericVerify(const BaseNode &bOpnd0, const BaseNode &bOpnd1) { - return bOpnd0.Verify() && bOpnd1.Verify(); + return bOpnd0.Verify() && bOpnd1.Verify() && ArithTypeVerify(bOpnd0) && ArithTypeVerify(bOpnd1); } inline bool CompareTypeVerify(PrimType pType) { @@ -1870,7 +1964,10 @@ bool UnaryNode::Verify() const { } else if (GetOpCode() == OP_recip || GetOpCode() == OP_sqrt) { resTypeVerf = UnaryTypeVerify2(GetPrimType()); } - + bool opndTypeVerf = true; + if (op != OP_lnot) { + opndTypeVerf = ArithTypeVerify(*uOpnd); + } // When an opcode only specifies one type, check for compatibility // between the operands and the result-type. bool compVerf = true; @@ -1879,7 +1976,7 @@ bool UnaryNode::Verify() const { compVerf = CompatibleTypeVerify(*uOpnd, *this); } bool opndExprVerf = uOpnd->Verify(); - return resTypeVerf && compVerf && opndExprVerf; + return resTypeVerf && opndTypeVerf && compVerf && opndExprVerf; } bool TypeCvtNode::Verify() const { @@ -2130,7 +2227,7 @@ bool IntrinsicopNode::VerifyJArrayLength(VerifyResult &verifyResult) const { bool IreadNode::Verify() const { bool addrExprVerf = Opnd(0)->Verify(); - bool pTypeVerf = true; + bool pTypeVerf = ReadTypeVerify(*this); bool structVerf = true; if (GetTypeKind(tyIdx) != kTypePointer) { LogInfo::MapleLogger() << "\n#Error: must be a pointer type\n"; @@ -2171,7 +2268,7 @@ bool IreadNode::Verify() const { } bool RegreadNode::Verify() const { - return true; + return ReadTypeVerify(*this); } bool IreadoffNode::Verify() const { @@ -2184,6 +2281,7 @@ bool IreadFPoffNode::Verify() const { bool ExtractbitsNode::Verify() const { bool opndExprVerf = Opnd(0)->Verify(); + bool opndTypeVerf = ArithTypeVerify(*Opnd(0)); bool compVerf = CompatibleTypeVerify(*Opnd(0), *this); bool resTypeVerf = UnaryTypeVerify0(GetPrimType()); constexpr int numBitsInByte = 8; @@ -2192,7 +2290,7 @@ bool ExtractbitsNode::Verify() const { LogInfo::MapleLogger() << "\n#Error: The operand of extractbits must be large enough to contain the specified bitfield\n"; } - return opndExprVerf && compVerf && resTypeVerf && opnd0SizeVerf; + return opndExprVerf && opndTypeVerf && compVerf && resTypeVerf && opnd0SizeVerf; } bool BinaryNode::Verify() const { @@ -2317,6 +2415,7 @@ bool AddrofNode::Verify() const { bool pTypeVerf = true; bool structVerf = IsStructureVerify(fieldID, GetStIdx()); if (GetOpCode() == OP_dread) { + pTypeVerf = ReadTypeVerify(*this); if (fieldID == 0 && IsStructureTypeKind(GetTypeKind(GetStIdx()))) { if (GetPrimType() != PTY_agg) { pTypeVerf = false; @@ -2433,12 +2532,13 @@ bool RangeGotoNode::Verify() const { } bool BlockNode::Verify() const { + bool passing = true; for (auto &stmt : GetStmtNodes()) { if (!stmt.Verify()) { - return false; + passing = false; } } - return true; + return passing; } bool BlockNode::Verify(VerifyResult &verifyResult) const { diff --git a/src/mapleall/maple_ir/src/mpl_verify.cpp b/src/mapleall/maple_ir/src/mpl_verify.cpp new file mode 100644 index 0000000000..d0f640e685 --- /dev/null +++ b/src/mapleall/maple_ir/src/mpl_verify.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) [2020-2022] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include +#include + +#include "bin_mplt.h" +#include "mir_function.h" +#include "mir_parser.h" +#include "opcode_info.h" +#include "triple.h" + +using namespace maple; + +namespace maple { +enum TargetIdEnum { kArm32, kAarch64, kX86, kAmd64, kVm, kRiscV64, kLastTargetId }; + +typedef struct { + const char *name; + int len; + TargetIdEnum id; +} target_descr_t; + +target_descr_t targetDescrs[kLastTargetId] = { + { "aarch64", 7, kAarch64 }, { "arm", 3, kArm32 }, { "vm", 2, kVm }, { "x86_64", 6, kAmd64 }, { "x86", 3, kX86 }, + {"riscv64", 7, kRiscV64 }, +}; + +TargetIdEnum target; + +MIRModule *theModule = nullptr; +bool dumpit; + +bool VerifyModule(MIRModule *module) { + bool res = true; + MapleList &funcList = module->GetFunctionList(); + for (MapleList::iterator it = funcList.begin(); it != funcList.end(); it++) { + MIRFunction *curfun = *it; + BlockNode *block = curfun->GetBody(); + module->SetCurFunction(curfun); + if (dumpit) { + curfun->Dump(false); + } + if (!block) { + continue; + } + if (!block->Verify()) { + res = false; + } + } + return res; +} + +} // namespace maple + +static void usage(const char *pgm) { + INFO(kLncInfo, "usage: %s [--dump] [--target=]\n", pgm); + exit(1); +} + +int main(int argc, const char *argv[]) { + if (argc < 2) { + usage(argv[0]); + } + + target = kAarch64; // default + + const char *mirInfile = nullptr; + for (int i = 1; i < argc; ++i) { + if (!strncmp(argv[i], "--dump", 6)) { + dumpit = true; + } else if (!strncmp(argv[i], "--target=", 9)) { + target = kLastTargetId; + for (int j = 0; j < kLastTargetId; ++j) { + target_descr_t &jt = targetDescrs[j]; + if (!strncmp(argv[i] + 9, jt.name, jt.len)) { + target = jt.id; + break; + } + } + if (target == kLastTargetId) { + usage(argv[0]); + } + } else if (argv[i][0] != '-') { + mirInfile = argv[i]; + } + } + + if (!mirInfile) { + usage(argv[0]); + } + if (strlen(mirInfile) > PATH_MAX) { + CHECK_FATAL(false, "invalid arg "); + } + Triple::GetTriple().Init(); + std::string filename(mirInfile); + std::string::size_type lastdot = filename.find_last_of("."); + bool isbpl = filename.compare(lastdot, 5, ".bpl\0") == 0; + + theModule = new MIRModule(mirInfile); + theMIRModule = theModule; + if (!isbpl) { + maple::MIRParser theparser(*theModule); + if (!theparser.ParseMIR()) { + theparser.EmitError(filename); + return 1; + } + } + else { + BinaryMplImport binMplt(*theModule); + binMplt.SetImported(false); + if (!binMplt.Import(filename, true)) { + FATAL(kLncFatal, "cannot open .bpl file: %s", mirInfile); + return 1; + } + } + if (!VerifyModule(theModule)) { + exit(1); + } + return 0; +} -- Gitee From 76bf88cce3d6a2fd5da7ffc4b245f116c4263803 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 15 Nov 2022 15:44:05 -0800 Subject: [PATCH 2/3] Some additional editing --- src/mapleall/maple_ir/src/mir_nodes.cpp | 6 +++--- src/mapleall/maple_ir/src/mpl_verify.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index e3be06406b..0568ddd9ae 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1612,7 +1612,7 @@ void AsmNode::Dump(int32 indent) const { LogInfo::MapleLogger() << " }\n"; } -// Start of type verification for Maple IR nodes. +// Start of primtype verification for Maple IR nodes. // // General rules: // @@ -1628,7 +1628,7 @@ void AsmNode::Dump(int32 indent) const { // 4. u1, i8, u8, i16, u16 must not be types of arithmetic operations, because // many machines do not provide instructions for such types as they lack such // register sizes. Similarly, these types must not be used as result types for -// any read instructions: dread/iread/regread/ireadoff/ireadfpoff. +// any read instructions: dread/iread/regread. // // 5. When an opcode only specifies one type (which is called the result type), // it expects both operands and results to be of this same type. Thus, the @@ -1660,7 +1660,7 @@ void AsmNode::Dump(int32 indent) const { // this operand-type and the types of their two operands must be compatible. // // 14. The opcodes ashr, band, bior, bxor, depositbits, land, lior, lshr, shl, -// rem must have result-type in [i32, u32, i64, u64]. +// rem must have result-type in [i32, u32, i64, u64]. // // 15. select's result-type and the types of its second and third operands must // be compatible; its first operand must be of integer type. diff --git a/src/mapleall/maple_ir/src/mpl_verify.cpp b/src/mapleall/maple_ir/src/mpl_verify.cpp index d0f640e685..8e16d6ebfd 100644 --- a/src/mapleall/maple_ir/src/mpl_verify.cpp +++ b/src/mapleall/maple_ir/src/mpl_verify.cpp @@ -24,7 +24,6 @@ using namespace maple; -namespace maple { enum TargetIdEnum { kArm32, kAarch64, kX86, kAmd64, kVm, kRiscV64, kLastTargetId }; typedef struct { @@ -34,16 +33,19 @@ typedef struct { } target_descr_t; target_descr_t targetDescrs[kLastTargetId] = { - { "aarch64", 7, kAarch64 }, { "arm", 3, kArm32 }, { "vm", 2, kVm }, { "x86_64", 6, kAmd64 }, { "x86", 3, kX86 }, + { "aarch64", 7, kAarch64 }, + { "arm", 3, kArm32 }, + { "vm", 2, kVm }, + { "x86_64", 6, kAmd64 }, + { "x86", 3, kX86 }, {"riscv64", 7, kRiscV64 }, }; TargetIdEnum target; - MIRModule *theModule = nullptr; bool dumpit; -bool VerifyModule(MIRModule *module) { +static bool VerifyModule(MIRModule *module) { bool res = true; MapleList &funcList = module->GetFunctionList(); for (MapleList::iterator it = funcList.begin(); it != funcList.end(); it++) { @@ -63,8 +65,6 @@ bool VerifyModule(MIRModule *module) { return res; } -} // namespace maple - static void usage(const char *pgm) { INFO(kLncInfo, "usage: %s [--dump] [--target=]\n", pgm); exit(1); -- Gitee From c7c9dedc09094b2375c7ae8cd65fbb523f3508cc Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Wed, 16 Nov 2022 21:17:53 -0800 Subject: [PATCH 3/3] adjust code to eliminate warnings from code scanner --- src/mapleall/maple_ir/src/mir_nodes.cpp | 121 ++++++++++++----------- src/mapleall/maple_ir/src/mpl_verify.cpp | 65 +++--------- 2 files changed, 75 insertions(+), 111 deletions(-) diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 0568ddd9ae..12d5128afd 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1612,66 +1612,67 @@ void AsmNode::Dump(int32 indent) const { LogInfo::MapleLogger() << " }\n"; } -// Start of primtype verification for Maple IR nodes. -// -// General rules: -// -// 1. For binary operations, the types of the two operands must be compatible. -// -// 2. In checking type compatibility, other than identical types, the types in -// each of the following group are compatible with each other: -// [i32, u32, ptr, ref, a32] -// [i64, u64, ptr, ref, a64] -// -// 3. dynany is compatiable with any dyn* type. -// -// 4. u1, i8, u8, i16, u16 must not be types of arithmetic operations, because -// many machines do not provide instructions for such types as they lack such -// register sizes. Similarly, these types must not be used as result types for -// any read instructions: dread/iread/regread. -// -// 5. When an opcode only specifies one type (which is called the result type), -// it expects both operands and results to be of this same type. Thus, the -// types among the operands and this result type must be compatible. -// -// 6. When an opcode specifies two types, the additional (second) type is -// the operand type. The types of the operands and the operand type must be -// compatible. -// -// 7. The opcodes addrof, addroflabel, addroffunc and iaddrof form addresses. -// Thus, their result type must be in [ptr,ref,a32,a64]. -// -// 8. The opcodes bnot, extractbits, sext, zext, lnot must have result type in -// [i32, u32, i64, u64]. -// -// 9. The opcodes abs, neg must have result type in -// [i32, u32, i64, u64, f32, f64]. -// -// 10. The opcodes recip, sqrt must have result type in [f32, f64]. -// -// 11. The opcodes ceil, floor, round, trunc must have result-type in -// [i32, u32, i64, u64] and operand-type in [f32, f64]. -// -// 12. The opcodes add, div, sub, mpy, max, min must have result-type in -// [i32, u32, i64, u64, f32, f64]. -// -// 13. The opcodes eq, ge, gt, le, lt, ne must have result-type in -// any signed or unsigned integer type; they also specifies operand-type, and -// this operand-type and the types of their two operands must be compatible. -// -// 14. The opcodes ashr, band, bior, bxor, depositbits, land, lior, lshr, shl, -// rem must have result-type in [i32, u32, i64, u64]. -// -// 15. select's result-type and the types of its second and third operands must -// be compatible; its first operand must be of integer type. -// -// 16. array's result-type must be in [ptr,ref,a32,a64]; the type of must -// also be in [ptr,ref,a32,a64]; the types of the rest of the operands must be in -// [i32, u32, i64, u64]. -// -// 17. The operand of brfalse, trfalse must be of integer type. -// -// 18. The operand of switch, rangegoto must be in [i32, u32, i64, u64]. +/* Start of primtype verification for Maple IR nodes. + + General rules: + + 1. For binary operations, the types of the two operands must be compatible. + + 2. In checking type compatibility, other than identical types, the types in + each of the following group are compatible with each other: + [i32, u32, ptr, ref, a32] + [i64, u64, ptr, ref, a64] + + 3. dynany is compatiable with any dyn* type. + + 4. u1, i8, u8, i16, u16 must not be types of arithmetic operations, because + many machines do not provide instructions for such types as they lack such + register sizes. Similarly, these types must not be used as result types for + any read instructions: dread/iread/regread. + + 5. When an opcode only specifies one type (which is called the result type), + it expects both operands and results to be of this same type. Thus, the + types among the operands and this result type must be compatible. + + 6. When an opcode specifies two types, the additional (second) type is + the operand type. The types of the operands and the operand type must be + compatible. + + 7. The opcodes addrof, addroflabel, addroffunc and iaddrof form addresses. + Thus, their result type must be in [ptr,ref,a32,a64]. + + 8. The opcodes bnot, extractbits, sext, zext, lnot must have result type in + [i32, u32, i64, u64]. + + 9. The opcodes abs, neg must have result type in + [i32, u32, i64, u64, f32, f64]. + + 10. The opcodes recip, sqrt must have result type in [f32, f64]. + + 11. The opcodes ceil, floor, round, trunc must have result-type in + [i32, u32, i64, u64] and operand-type in [f32, f64]. + + 12. The opcodes add, div, sub, mpy, max, min must have result-type in + [i32, u32, i64, u64, f32, f64]. + + 13. The opcodes eq, ge, gt, le, lt, ne must have result-type in + any signed or unsigned integer type; they also specifies operand-type, and + this operand-type and the types of their two operands must be compatible. + + 14. The opcodes ashr, band, bior, bxor, depositbits, land, lior, lshr, shl, + rem must have result-type in [i32, u32, i64, u64]. + + 15. select's result-type and the types of its second and third operands must + be compatible; its first operand must be of integer type. + + 16. array's result-type must be in [ptr,ref,a32,a64]; the type of must + also be in [ptr,ref,a32,a64]; the types of the rest of the operands must be in + [i32, u32, i64, u64]. + + 17. The operand of brfalse, trfalse must be of integer type. + + 18. The operand of switch, rangegoto must be in [i32, u32, i64, u64]. +*/ inline bool ExcludeSmallIntTypeVerify(const BaseNode &opnd) { switch (opnd.GetPrimType()) { diff --git a/src/mapleall/maple_ir/src/mpl_verify.cpp b/src/mapleall/maple_ir/src/mpl_verify.cpp index 8e16d6ebfd..58444df623 100644 --- a/src/mapleall/maple_ir/src/mpl_verify.cpp +++ b/src/mapleall/maple_ir/src/mpl_verify.cpp @@ -24,36 +24,15 @@ using namespace maple; -enum TargetIdEnum { kArm32, kAarch64, kX86, kAmd64, kVm, kRiscV64, kLastTargetId }; - -typedef struct { - const char *name; - int len; - TargetIdEnum id; -} target_descr_t; - -target_descr_t targetDescrs[kLastTargetId] = { - { "aarch64", 7, kAarch64 }, - { "arm", 3, kArm32 }, - { "vm", 2, kVm }, - { "x86_64", 6, kAmd64 }, - { "x86", 3, kX86 }, - {"riscv64", 7, kRiscV64 }, -}; - -TargetIdEnum target; -MIRModule *theModule = nullptr; -bool dumpit; +static bool dumpit; static bool VerifyModule(MIRModule *module) { bool res = true; - MapleList &funcList = module->GetFunctionList(); - for (MapleList::iterator it = funcList.begin(); it != funcList.end(); it++) { - MIRFunction *curfun = *it; - BlockNode *block = curfun->GetBody(); - module->SetCurFunction(curfun); + for (MIRFunction *curfunc : module->GetFunctionList()) { + BlockNode *block = curfunc->GetBody(); + module->SetCurFunction(curfunc); if (dumpit) { - curfun->Dump(false); + curfunc->Dump(false); } if (!block) { continue; @@ -65,51 +44,35 @@ static bool VerifyModule(MIRModule *module) { return res; } -static void usage(const char *pgm) { - INFO(kLncInfo, "usage: %s [--dump] [--target=]\n", pgm); - exit(1); +static void Usage(const char *pgm) { + INFO(kLncInfo, "usage: %s [--dump]\n", pgm); } int main(int argc, const char *argv[]) { if (argc < 2) { - usage(argv[0]); + Usage(argv[0]); + return 1; } - target = kAarch64; // default - const char *mirInfile = nullptr; for (int i = 1; i < argc; ++i) { if (!strncmp(argv[i], "--dump", 6)) { dumpit = true; - } else if (!strncmp(argv[i], "--target=", 9)) { - target = kLastTargetId; - for (int j = 0; j < kLastTargetId; ++j) { - target_descr_t &jt = targetDescrs[j]; - if (!strncmp(argv[i] + 9, jt.name, jt.len)) { - target = jt.id; - break; - } - } - if (target == kLastTargetId) { - usage(argv[0]); - } } else if (argv[i][0] != '-') { mirInfile = argv[i]; } } if (!mirInfile) { - usage(argv[0]); - } - if (strlen(mirInfile) > PATH_MAX) { - CHECK_FATAL(false, "invalid arg "); + Usage(argv[0]); + return 1; } Triple::GetTriple().Init(); std::string filename(mirInfile); std::string::size_type lastdot = filename.find_last_of("."); - bool isbpl = filename.compare(lastdot, 5, ".bpl\0") == 0; + bool isbpl = filename.compare(lastdot, std::string::npos, ".bpl") == 0; - theModule = new MIRModule(mirInfile); + MIRModule *theModule = new MIRModule(mirInfile); theMIRModule = theModule; if (!isbpl) { maple::MIRParser theparser(*theModule); @@ -127,7 +90,7 @@ int main(int argc, const char *argv[]) { } } if (!VerifyModule(theModule)) { - exit(1); + return 1; } return 0; } -- Gitee