diff --git a/doc/en/TargetConstants.md b/doc/en/TargetConstants.md new file mode 100644 index 0000000000000000000000000000000000000000..4be1770113c4d96ab7d45d7cfd760b8b9abe2c07 --- /dev/null +++ b/doc/en/TargetConstants.md @@ -0,0 +1,136 @@ +### Introduction +This document describes the way to work with target constants in maple IR. +It's very important to distinguish `host` constants from the `target` ones. +`Host` constants represent values on the machine where the compiler runs. +`Target` constants represent values that will be present in the target code generated by the compiler. +So, in the common case there is no one-to-one mapping between `host` constants and `target` ones. +For example, a host machine has `one's complement` representation for integers, but the `target` machine +has `two's complement` integers representation. Or more realistic case when the target machine supports `int128_t` and can +hold 128-bit constants directly, but the `host` machine does not. +So, we need to find a safe and convenient way how to represent and operate on the `target` constants in maple IR +while compiling a user program. + +### Working with constants in maple IR +Let's show how to work with constants on `Constant Folding` optimization as an example. +Consider the following Maple IR: +``` +func &foo static used () i8 { + return (add i8 (constval i8 1, constval i8 2)) +} +``` +we want to fold this `add` to perform calculation at compile time. +We could do something like this: +```c++ +MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, + const MIRIntConst *intConst0, + const MIRIntConst *intConst1) const { + int64 intValueOfConst0 = intConst0->GetValue(); + int64 intValueOfConst1 = intConst1->GetValue(); + + uint64 result64 = 0; + uint32 result32 = 0; + uint16 result16 = 0; + uint8 result8 = 0; + + bool useResult64 = (GetPrimTypeSize(resultType) == 8); + bool useResult32 = (GetPrimTypeSize(resultType) == 4); + bool useResult16 = (GetPrimTypeSize(resultType) == 2); + bool useResult8 = (GetPrimTypeSize(resultType) == 1); + + switch (opcode) { + case OP_add: { + if (useResult64) { + result64 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); + } else if (useResult32) { + result32 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); + } else if (useResult16) { + result16 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); + } else if (useResult8) { + result8 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); + } + break; + } + ... +``` +As can be seen, there is a lot of boilerplate code depending on the type size of the result of operation. +In a more general case, the sign of the result type is also has to be taken into account, doubling the code size (e.g. div) +Also, if we manipulate with 128-bit types it's possible that there is no `int128_t` type on the host machine and in this +case we need to perform such calculation manually. For example, we need to hold the value in two `int64_t` variables. +So, we need to be able to work with target constants in a safe and convenient way. To achieve this goal we can use +a special class that's called `IntVal`. It provides a convenient interface for manipulation with target constants. +For example, the above case can be managed as follows: +```c++ +MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, + const MIRIntConst *intConst0, + const MIRIntConst *intConst1) const { + IntVal intVal0 = intConst0->GetValue(); + IntVal intVal1 = intConst1->GetValue(); + + IntVal result(0, resultType); + + switch (opcode) { + case OP_add: { + result = intVal0.Add(intVal1, resultType); + // or + // result = intVal0 + intVal1; + // if resultType is equal to type of operands + break; + } + ... +``` +Let's take a look at `IntVal` class in more detail. + +##### The IntVal class +This class represents a target integer constant in `two's complement` representation. +It's able to hold signed and unsigned integers with arbitrary bit-width (currently, no more than 64 bits. 128-bit support is in progress) +that can be created using the following constructors: +```c++ +/// Creates IntVal object from uint64 value with bit-width defined by bitWidth parameter +/// and interpreted as signed value if isSigned parameter is true +IntVal(uint64 val, uint8 bitWidth, bool isSigned); + +/// The same as above, but bit-width and signedness are obtained from the given PrimType +IntVal(uint64 val, PrimType type); +``` +Also, this class provides an interface to perform arithmetic, bitwise, comparison and other operations on the target constants. +For example: +```c++ +/// perform an addition: *this + val. Bit-width and signedness of values must be the same +IntVal operator+(const IntVal &val) const; + +/// the same as above, but performs '+' in terms of the given integer PrimType +IntVal Add(const IntVal &val, PrimType pType) const; + +/// perform a binary 'and': *this & val. Bit-width and signedness of values must be the same +IntVal operator&(const IntVal &val) const; + +/// the same as above, but performs '&' in terms of the given integer PrimType +IntVal And(const IntVal &val, PrimType pType) const; + +/// perform a comparison: *this < val. Bit-width and signedness of values must be the same +bool operator<(const IntVal &rhs) const; + +/// the same as above, but performs '<' in terms of the given integer PrimType +bool Less(const IntVal &rhs, PrimType pType) const; +``` + +There are `Extend`, `Trunc` and `TruncOrExtend` functions that allow truncating or extending (zero or sign extension) +depending on the given integer PrimType. These functions return new `IntVal` object that has bit-width and sign obtained +from the given PrimType and has a value obtained from the original value by truncation or extension (zero of sign). +```c++ +IntVal TruncOrExtend(PrimType newType) cosnt; +IntVal Extend(PrimType newType) cosnt; +IntVal Trunc(PrimType newType) cosnt; +``` +It's possible to get a host constant from the target one (in case the value can fit into the host constant) using the following +interfaces: +```c++ +/// perform zero extension of the value +uint64 GetZXTValue(uint8 size = 0) const; + +/// perform sign extension of the value +int64 GetSXTValue(uint8 size = 0) const; + +/// perform sign or zero extension of the value depending on its sign +int64 GetExtValue(uint8 size = 0) const; +``` diff --git a/src/hir2mpl/ast_input/clang/src/ast_expr.cpp b/src/hir2mpl/ast_input/clang/src/ast_expr.cpp index 2420e329df6333d290422bc39472f4df3b58383b..3993cb7ce2fc239750dfbe03d316bf8820a545ba 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_expr.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_expr.cpp @@ -27,8 +27,105 @@ #include "ror.h" #include "conditional_operator.h" +#include + namespace maple { + +namespace { + const uint32 kOneByte = 8; + +template +std::optional GenerateConstCommon(Opcode op, T p0, T p1) { + switch (op) { + case OP_add: { + return p0 + p1; + } + case OP_sub: { + return p0 - p1; + } + case OP_mul: { + return p0 * p1; + } + case OP_div: { + return p0 / p1; + } + default: { + return std::nullopt; + } + } +} + +template , bool> = true> +T GenerateConst(Opcode op, T p0, T p1) { + auto res = GenerateConstCommon(op, p0, p1); + ASSERT(res, "invalid operations for floating point values"); + return *res; +} + +IntVal GenerateConst(Opcode op, const IntVal &p0, const IntVal &p1) { + ASSERT(p0.GetBitWidth() == p1.GetBitWidth() && p0.IsSigned() == p1.IsSigned(), "width and sign must be the same"); + + if (auto res = GenerateConstCommon(op, p0, p1)) { + return *res; + } + + switch (op) { + case OP_rem: { + return p0 % p1; + } + case OP_shl: { + return p0 << p1; + } + case OP_lshr: + case OP_ashr: { + return p0 >> p1; + } + case OP_bior: { + return p0 | p1; + } + case OP_band: { + return p0 & p1; + } + case OP_bxor: { + return p0 ^ p1; + } + case OP_land: + case OP_cand: { + return IntVal(p0.GetExtValue() && p1.GetExtValue(), p0.GetBitWidth(), p0.IsSigned()); + } + case OP_lior: + case OP_cior: { + return IntVal(p0.GetExtValue() || p1.GetExtValue(), p0.GetBitWidth(), p0.IsSigned()); + } + default: + CHECK_FATAL(false, "unsupported operation"); + } +} + +MIRConst *MIRConstGenerator(MemPool *mp, MIRConst *konst0, MIRConst *konst1, Opcode op) { +#define RET_VALUE_IF_CONST_TYPE_IS(TYPE) \ + { \ + auto *c0 = safe_cast(konst0); \ + if (c0) { \ + auto *c1 = safe_cast(konst1); \ + ASSERT(c1, "invalid const type"); \ + ASSERT(c0->GetType().GetPrimType() == c1->GetType().GetPrimType(), "types are not equal"); \ + return mp->New(GenerateConst(op, c0->GetValue(), c1->GetValue()), c0->GetType()); \ + } \ + } + + RET_VALUE_IF_CONST_TYPE_IS(MIRIntConst) + RET_VALUE_IF_CONST_TYPE_IS(MIRFloatConst) + RET_VALUE_IF_CONST_TYPE_IS(MIRDoubleConst) + +#undef RET_VALUE_IF_CONST_TYPE_IS + + CHECK_FATAL(false, "unreachable code"); +} + +} // anonymous namespace + // ---------- ASTValue ---------- MIRConst *ASTValue::Translate2MIRConst() const { switch (pty) { @@ -356,7 +453,7 @@ MIRConst *ASTCastExpr::GenerateMIRDoubleConst() const { } case kConstInt: { return FEManager::GetModule().GetMemPool()->New( - static_cast(static_cast(childConst)->GetValue()), + static_cast(static_cast(childConst)->GetExtValue()), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); } case kConstDoubleConst: { @@ -384,7 +481,7 @@ MIRConst *ASTCastExpr::GenerateMIRFloatConst() const { } case kConstInt: { return FEManager::GetModule().GetMemPool()->New( - static_cast(static_cast(childConst)->GetValue()), + static_cast(static_cast(childConst)->GetExtValue()), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); } default: { @@ -402,9 +499,9 @@ MIRConst *ASTCastExpr::GenerateMIRIntConst() const { switch (childConst->GetKind()) { case kConstDoubleConst: case kConstInt: { - int64 val = childConst->GetKind() == kConstDoubleConst ? - static_cast(static_cast(childConst)->GetValue()) : - static_cast(childConst)->GetValue(); + int64 val = childConst->GetKind() == kConstDoubleConst + ? static_cast(static_cast(childConst)->GetValue()) + : static_cast(childConst)->GetExtValue(); PrimType destPrimType = mirType->GetPrimType(); switch (destPrimType) { @@ -1971,7 +2068,7 @@ MIRConst *ASTBinaryOperatorExpr::GenerateMIRConstImpl() const { } else { CHECK_FATAL(false, "Unsupported yet"); } - int64 value = constInt->GetValue(); + int64 value = constInt->GetExtValue(); if (baseConst->GetKind() == kConstStrConst) { std::string str = GlobalTables::GetUStrTable().GetStringFromStrIdx(static_cast(baseConst)->GetValue()); @@ -1997,7 +2094,7 @@ MIRConst *ASTBinaryOperatorExpr::GenerateMIRConstImpl() const { auto id = konst->GetFieldID(); auto ty = konst->GetType(); auto offset = konst->GetOffset(); - int64 value = static_cast(rightConst)->GetValue(); + int64 value = static_cast(rightConst)->GetExtValue(); return FEManager::GetModule().GetMemPool()->New(idx, id, ty, offset - value); } else { CHECK_FATAL(false, "NIY"); diff --git a/src/hir2mpl/ast_input/clang/src/ast_parser.cpp b/src/hir2mpl/ast_input/clang/src/ast_parser.cpp index 31a7550d022f0338ab946fd5efc93f6d80d0633c..e1bd2405f538c8e1cf99b0290138f493d9c182c5 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_parser.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_parser.cpp @@ -1607,6 +1607,7 @@ ASTExpr *ASTParser::BuildExprToComputeSizeFromVLA(MapleAllocator &allocator, con astBOExpr->SetOpcode(OP_mul); astBOExpr->SetLeftExpr(lhs); astBOExpr->SetRightExpr(rhs); + return astBOExpr; } uint32 size = GetSizeFromQualType(qualType); diff --git a/src/hir2mpl/common/include/fe_utils_ast.h b/src/hir2mpl/common/include/fe_utils_ast.h index 8591fb5a7a0317c3ae40cb8ed53480643106f2db..de8f150703860dee209e9fd2f0d3becab472ed87 100644 --- a/src/hir2mpl/common/include/fe_utils_ast.h +++ b/src/hir2mpl/common/include/fe_utils_ast.h @@ -32,124 +32,5 @@ class FEUtilAST { FEUtilAST() = default; ~FEUtilAST() = default; }; - -template -std::function OpGenerator(Opcode op, T p0, T p1, bool isSigned) { - switch (op) { - case OP_add: { - return [p0, p1]() { return p0 + p1; }; - } - case OP_sub: { - return [p0, p1]() { return p0 - p1; }; - } - case OP_mul: { - return [p0, p1]() { return p0 * p1; }; - } - case OP_div: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) / static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) / static_cast(p1); }; - } - } - case OP_rem: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) % static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) % static_cast(p1); }; - } - } - case OP_shl: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) << static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) << static_cast(p1); }; - } - } - case OP_lshr: - case OP_ashr: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) >> static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) >> static_cast(p1); }; - } - } - case OP_bior: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) | static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) | static_cast(p1); }; - } - } - case OP_band: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) & static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) & static_cast(p1); }; - } - } - case OP_bxor: { - if (isSigned) { - return [p0, p1]() { return static_cast(p0) ^ static_cast(p1); }; - } else { - return [p0, p1]() { return static_cast(p0) ^ static_cast(p1); }; - } - } - case OP_land: { - return [p0, p1]() { - if (!p0) { - return static_cast(0); - } else if (!p1) { - return static_cast(0); - } else { - return static_cast(1); - } - }; - } - case OP_lior: { - return [p0, p1]() { - if (p0) { - return static_cast(1); - } else if (p1) { - return static_cast(1); - } else { - return static_cast(0); - } - }; - } - case OP_cand: { - return [p0, p1]() { - if (!p0) { - return static_cast(0); - } else if (!p1) { - return static_cast(0); - } else { - return static_cast(1); - } - }; - } - case OP_cior: { - return [p0, p1]() { - if (p0) { - return static_cast(1); - } else if (p1) { - return static_cast(1); - } else { - return static_cast(0); - } - }; - } - default: { - return nullptr; - } - } - return nullptr; -} - -template -T *MIRConstGenerator(MemPool *mp, T *konst0, T *konst1, Opcode op) { - bool isSigned = IsSignedInteger(konst0->GetType().GetPrimType()) && IsSignedInteger(konst1->GetType().GetPrimType()); - return mp->New(OpGenerator(op, konst0->GetValue(), konst1->GetValue(), isSigned)(), konst0->GetType()); -} } // namespace maple #endif // HIR2MPL_INCLUDE_FE_UTILS_AST_H diff --git a/src/mapleall/maple_be/include/cg/emit.h b/src/mapleall/maple_be/include/cg/emit.h index b3dc187ccf97c1ca61af6781bf4c2d44b83c6e8e..e816682eaecb049bc7decebb5bd551c4a7c0d6dc 100644 --- a/src/mapleall/maple_be/include/cg/emit.h +++ b/src/mapleall/maple_be/include/cg/emit.h @@ -220,6 +220,11 @@ class Emitter { return *this; } + Emitter &Emit(const IntVal& val) { + outStream << val.GetExtValue(); + return *this; + } + Emitter &Emit(const MapleString &str) { ASSERT(str.c_str() != nullptr, "nullptr check"); outStream << str; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index ed42d07408916b1c53f1ee8f67afd163175f133f..e89616f2899c74168244bc01d2dde13c7b244874 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -410,8 +410,8 @@ BaseNode *CGLowerer::LowerFarray(ArrayNode &array) { const ConstvalNode *constvalNode = static_cast(array.GetIndex(0)); if (constvalNode->GetConstVal()->GetKind() == kConstInt) { const MIRIntConst *pIntConst = static_cast(constvalNode->GetConstVal()); - CHECK_FATAL(JAVALANG || pIntConst->GetValue() >= 0, "Array index should >= 0."); - int64 eleOffset = pIntConst->GetValue() * eSize; + CHECK_FATAL(JAVALANG || !pIntConst->IsNegative(), "Array index should >= 0."); + uint64 eleOffset = pIntConst->GetExtValue() * eSize; if (farrayType->GetKind() == kTypeJArray) { eleOffset += RTSupport::GetRTSupportInstance().GetArrayContentOffset(); @@ -440,9 +440,8 @@ BaseNode *CGLowerer::LowerFarray(ArrayNode &array) { if ((farrayType->GetKind() == kTypeJArray) && (resNode->GetOpCode() == OP_constval)) { ConstvalNode *idxNode = static_cast(resNode); - int64 idx = safe_cast(idxNode->GetConstVal())->GetValue(); - MIRIntConst *eConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - idx * static_cast(eSize), arrayType); + uint64 idx = safe_cast(idxNode->GetConstVal())->GetExtValue(); + MIRIntConst *eConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(idx * eSize, arrayType); rMul = mirModule.CurFuncCodeMemPool()->New(eConst); rMul->SetPrimType(array.GetPrimType()); } else { @@ -559,9 +558,8 @@ BaseNode *CGLowerer::LowerArray(ArrayNode &array, const BaseNode &parent) { if (resNode->GetOpCode() == OP_constval) { /* index is a constant, we can calculate the offset now */ ConstvalNode *idxNode = static_cast(resNode); - int64 idx = safe_cast(idxNode->GetConstVal())->GetValue(); - MIRIntConst *eConst = - GlobalTables::GetIntConstTable().GetOrCreateIntConst(idx * static_cast(eSize), arrayTypes); + uint64 idx = safe_cast(idxNode->GetConstVal())->GetExtValue(); + MIRIntConst *eConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(idx * eSize, arrayTypes); rMul = mirModule.CurFuncCodeMemPool()->New(eConst); rMul->SetPrimType(array.GetPrimType()); if (dim == 1) { @@ -650,14 +648,13 @@ BaseNode *CGLowerer::LowerCArray(ArrayNode &array) { BaseNode *index = static_cast(array.GetIndex(static_cast(i))); bool isConst = false; - int64 indexVal = 0; + uint64 indexVal = 0; if (index->op == OP_constval) { ConstvalNode *constNode = static_cast(index); - indexVal = (static_cast(constNode->GetConstVal()))->GetValue(); + indexVal = (static_cast(constNode->GetConstVal()))->GetExtValue(); isConst = true; MIRIntConst *newConstNode = mirModule.GetMemPool()->New( - indexVal * static_cast(mpyDim), - *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + indexVal * mpyDim, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); BaseNode *newValNode = mirModule.CurFuncCodeMemPool()->New(newConstNode); newValNode->SetPrimType(array.GetPrimType()); if (i == 0) { @@ -674,8 +671,7 @@ BaseNode *CGLowerer::LowerCArray(ArrayNode &array) { BaseNode *mpyNode; if (isConst) { MIRIntConst *mulConst = mirModule.GetMemPool()->New( - static_cast(mpyDim) * indexVal, - *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + mpyDim * indexVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); BaseNode *mulSize = mirModule.CurFuncCodeMemPool()->New(mulConst); mulSize->SetPrimType(array.GetPrimType()); mpyNode = mulSize; @@ -717,9 +713,9 @@ BaseNode *CGLowerer::LowerCArray(ArrayNode &array) { if (resNode->op == OP_constval) { // index is a constant, we can calculate the offset now ConstvalNode *idxNode = static_cast(resNode); - int64 idx = static_cast(idxNode->GetConstVal())->GetValue(); + uint64 idx = static_cast(idxNode->GetConstVal())->GetExtValue(); MIRIntConst *econst = mirModule.GetMemPool()->New( - idx * static_cast(esize), *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + idx * esize, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); rMul = mirModule.CurFuncCodeMemPool()->New(econst); rMul->SetPrimType(array.GetPrimType()); if (dim == 1 && array.GetBase()->op == OP_addrof && static_cast(array.GetBase())->GetFieldID() == 0) { @@ -3670,7 +3666,7 @@ StmtNode *CGLowerer::LowerSyncEnterSyncExit(StmtNode &stmt) { CHECK_FATAL(nStmt.Opnd(1)->GetOpCode() == OP_constval, "wrong 2nd arg type for syncenter"); ConstvalNode *cst = static_cast(nStmt.GetNopndAt(1)); MIRIntConst *intConst = safe_cast(cst->GetConstVal()); - switch (static_cast(intConst->GetValue())) { + switch (intConst->GetExtValue()) { case kMCCSyncEnterFast0: id = INTRN_FIRST_SYNC_ENTER; break; @@ -4017,7 +4013,7 @@ void CGLowerer::InitArrayClassCacheTableIndex() { MIRSymbol *strTab = nullptr; for (size_t i = 0; i < aggConst.GetConstVec().size(); ++i) { MIRConst *elemConst = aggConst.GetConstVecItem(i); - uint32 intValue = static_cast(((safe_cast(elemConst))->GetValue()) & 0xFFFFFFFF); + uint32 intValue = static_cast(((safe_cast(elemConst))->GetExtValue()) & 0xFFFFFFFF); bool isHotReflectStr = (intValue & 0x00000003) != 0; /* use the last two bits of intValue in this expression */ if (isHotReflectStr) { uint32 tag = (intValue & 0x00000003) - kCStringShift; /* use the last two bits of intValue in this expression */ @@ -4037,7 +4033,7 @@ void CGLowerer::InitArrayClassCacheTableIndex() { for (auto start = (intValue >> 2); start < strAgg->GetConstVec().size(); ++start) { /* the last two bits is flag */ MIRIntConst *oneChar = static_cast(strAgg->GetConstVecItem(start)); if ((oneChar != nullptr) && !oneChar->IsZero()) { - arrayClassName += static_cast(oneChar->GetValue()); + arrayClassName += static_cast(oneChar->GetExtValue()); } else { break; } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index e26ccfa0e05ef90dee8d242ebe5e3235b3b870ed..64c7c261f83742eacb1f5f9e1633e5c14aa725d7 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1239,7 +1239,7 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { CHECK_FATAL(constNode.GetConstVal()->GetKind() == kConstInt, "expect MIRIntConst does not support float yet"); MIRIntConst *mirIntConst = safe_cast(constNode.GetConstVal()); CHECK_FATAL(mirIntConst != nullptr, "just checking"); - int64 scale = mirIntConst->GetValue(); + int64 scale = mirIntConst->GetExtValue(); if (str.find("r") != std::string::npos) { bool isSigned = scale < 0; ImmOperand &immOpnd = CreateImmOperand(scale, k64BitSize, isSigned); @@ -3431,7 +3431,7 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr, } Operand *AArch64CGFunc::SelectIntConst(MIRIntConst &intConst) { - return &CreateImmOperand(intConst.GetValue(), GetPrimTypeSize(intConst.GetType().GetPrimType()) * kBitsPerByte, + return &CreateImmOperand(intConst.GetExtValue(), GetPrimTypeSize(intConst.GetType().GetPrimType()) * kBitsPerByte, false); } @@ -4052,7 +4052,7 @@ Operand &AArch64CGFunc::SelectCGArrayElemAdd(BinaryNode &node, const BaseNode &p ConstvalNode *constvalNode = static_cast(opnd1); MIRConst *mirConst = constvalNode->GetConstVal(); MIRIntConst *mirIntConst = static_cast(mirConst); - SelectAddrof(result, CreateStImmOperand(symbol, mirIntConst->GetValue(), 0)); + SelectAddrof(result, CreateStImmOperand(symbol, mirIntConst->GetExtValue(), 0)); return result; } @@ -9292,11 +9292,11 @@ MemOperand *AArch64CGFunc::CheckAndCreateExtendMemOpnd(PrimType ptype, const Bas ASSERT(constOfstNode->GetConstVal()->GetKind() == kConstInt, "expect MIRIntConst"); MIRIntConst *intOfst = safe_cast(constOfstNode->GetConstVal()); CHECK_FATAL(intOfst != nullptr, "just checking"); - /* discard large offset and negative offset */ - if (intOfst->GetValue() > INT32_MAX || intOfst->GetValue() < 0) { + /* discard large offset and negative offset */ + if (intOfst->GetExtValue() > INT32_MAX || intOfst->IsNegative()) { return nullptr; } - uint32 scale = static_cast(intOfst->GetValue()); + uint32 scale = static_cast(intOfst->GetExtValue()); OfstOperand &ofstOpnd = GetOrCreateOfstOpnd(scale, k32BitSize); uint32 dsize = GetPrimTypeBitSize(ptype); MemOperand *memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, GetPrimTypeBitSize(ptype), @@ -9344,7 +9344,7 @@ MemOperand *AArch64CGFunc::CheckAndCreateExtendMemOpnd(PrimType ptype, const Bas CHECK_FATAL(constValNode->GetConstVal()->GetKind() == kConstInt, "expect MIRIntConst"); MIRIntConst *mirIntConst = safe_cast(constValNode->GetConstVal()); CHECK_FATAL(mirIntConst != nullptr, "just checking"); - int32 scale = mirIntConst->GetValue(); + int32 scale = mirIntConst->GetExtValue(); if (scale < 0) { return nullptr; } @@ -9387,7 +9387,7 @@ MemOperand &AArch64CGFunc::CreateNonExtendMemOpnd(PrimType ptype, const BaseNode ASSERT(constOfstNode->GetConstVal()->GetKind() == kConstInt, "expect MIRIntConst"); MIRIntConst *intOfst = safe_cast(constOfstNode->GetConstVal()); CHECK_FATAL(intOfst != nullptr, "just checking"); - offset = (addrExpr.GetOpCode() == OP_add) ? offset + intOfst->GetSXTValue() : offset - intOfst->GetSXTValue(); + offset = (addrExpr.GetOpCode() == OP_add) ? offset + intOfst->GetExtValue() : offset - intOfst->GetExtValue(); } else { addrOpnd = HandleExpr(parent, addrExpr); } @@ -10060,7 +10060,7 @@ void AArch64CGFunc::SelectMPLProfCounterInc(const IntrinsiccallNode &intrnNode) ASSERT(mirConst != nullptr, "nullptr check"); CHECK_FATAL(mirConst->GetKind() == kConstInt, "expect MIRIntConst type"); MIRIntConst *mirIntConst = safe_cast(mirConst); - int64 offset = GetPrimTypeSize(PTY_u64) * mirIntConst->GetValue(); + int64 offset = GetPrimTypeSize(PTY_u64) * mirIntConst->GetExtValue(); if (!GetCG()->IsQuiet()) { maple::LogInfo::MapleLogger(kLlInfo) << "At counter table offset: " << offset << std::endl; @@ -10093,7 +10093,7 @@ void AArch64CGFunc::SelectMPLProfCounterInc(const IntrinsiccallNode &intrnNode) ASSERT(mirConst != nullptr, "nullptr check"); CHECK_FATAL(mirConst->GetKind() == kConstInt, "expect MIRIntConst type"); MIRIntConst *mirIntConst = safe_cast(mirConst); - int64 idx = GetPrimTypeSize(PTY_u32) * mirIntConst->GetValue(); + int64 idx = GetPrimTypeSize(PTY_u32) * mirIntConst->GetExtValue(); if (!GetCG()->IsQuiet()) { maple::LogInfo::MapleLogger(kLlErr) << "Id index " << idx << std::endl; } @@ -10137,7 +10137,7 @@ void AArch64CGFunc::SelectMPLClinitCheck(const IntrinsiccallNode &intrnNode) { ASSERT(mirConst != nullptr, "nullptr check"); CHECK_FATAL(mirConst->GetKind() == kConstInt, "expect MIRIntConst type"); MIRIntConst *mirIntConst = safe_cast(mirConst); - stOpnd = &CreateStImmOperand(*symbol, mirIntConst->GetValue(), 0); + stOpnd = &CreateStImmOperand(*symbol, mirIntConst->GetExtValue(), 0); } regno_t vRegNO2 = NewVReg(GetRegTyFromPrimTy(PTY_a64), GetPrimTypeSize(PTY_a64)); @@ -10288,7 +10288,7 @@ void AArch64CGFunc::SelectCAtomicStoreN(const IntrinsiccallNode &intrinsiccallNo auto *value = HandleExpr(intrinsiccallNode, *intrinsiccallNode.Opnd(1)); auto *memOrderOpnd = intrinsiccallNode.Opnd(kInsnThirdOpnd); auto *memOrderConst = static_cast(static_cast(memOrderOpnd)->GetConstVal()); - auto memOrder = static_cast(memOrderConst->GetValue()); + auto memOrder = static_cast(memOrderConst->GetExtValue()); SelectAtomicStore(*value, *addr, primType, PickMemOrder(memOrder, false)); } @@ -10857,7 +10857,7 @@ Operand *AArch64CGFunc::SelectCAtomicLoadN(IntrinsicopNode &intrinsicopNode) { auto *memOrderOpnd = intrinsicopNode.Opnd(1); auto primType = intrinsicopNode.GetPrimType(); auto *memOrderConst = static_cast(static_cast(memOrderOpnd)->GetConstVal()); - auto memOrder = static_cast(memOrderConst->GetValue()); + auto memOrder = static_cast(memOrderConst->GetExtValue()); return SelectAtomicLoad(*addrOpnd, primType, PickMemOrder(memOrder, true)); } @@ -10879,7 +10879,7 @@ Operand *AArch64CGFunc::SelectCAtomicExchangeN(IntrinsicopNode &intrinsicopNode) auto *valueOpnd = HandleExpr(intrinsicopNode, *intrinsicopNode.Opnd(1)); auto *memOrderOpnd = intrinsicopNode.Opnd(kInsnThirdOpnd); auto *memOrderConst = static_cast(static_cast(memOrderOpnd)->GetConstVal()); - auto memOrder = static_cast(memOrderConst->GetValue()); + auto memOrder = static_cast(memOrderConst->GetExtValue()); auto *result = SelectAtomicLoad(*addrOpnd, primType, PickMemOrder(memOrder, true)); SelectAtomicStore(*valueOpnd, *addrOpnd, primType, PickMemOrder(memOrder, false)); return result; @@ -10908,7 +10908,7 @@ Operand *AArch64CGFunc::SelectCReturnAddress(IntrinsicopNode &intrinopNode) { ASSERT(constNode.GetConstVal()->GetKind() == kConstInt, "expect MIRIntConst does not support float yet"); MIRIntConst *mirIntConst = safe_cast(constNode.GetConstVal()); ASSERT(mirIntConst != nullptr, "nullptr checking"); - int64 scale = mirIntConst->GetValue(); + int64 scale = mirIntConst->GetExtValue(); /* * Do not support getting return address with a nonzero argument * inline / tail call opt will destory this behavior diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index ed07979f97ac3f6c4f9ab9451779f4269acfc8aa..3533eea0b3eedf15d07f2722fce245cfe7bd65c3 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -91,7 +91,7 @@ bool LiveRange::IsRematerializable(AArch64CGFunc &cgFunc, uint8 rematLev) const return false; } const MIRIntConst *intConst = static_cast(rematInfo.mirConst); - int64 val = intConst->GetValue(); + int64 val = intConst->GetExtValue(); if (val >= -kMax16UnsignedImm && val <= kMax16UnsignedImm) { return true; } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp index 6369b50146452de28d41dbf25318c2ea7836c418..8b7287546602e6418995e6b971b60a6c8cf5cda3 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_emitter.cpp @@ -590,7 +590,7 @@ void AArch64AsmEmitter::Run(FuncEmitInfo &funcEmitInfo) { switch (st->GetKonst()->GetType().GetPrimType()) { case PTY_u32: { MIRIntConst *intConst = safe_cast(st->GetKonst()); - (void)emitter.Emit("\t.long ").Emit(static_cast(intConst->GetValue())).Emit("\n"); + (void)emitter.Emit("\t.long ").Emit(static_cast(intConst->GetExtValue())).Emit("\n"); emitter.IncreaseJavaInsnCount(); break; } diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index b3ff957c14c94a09ebf05cb00416cc702ebedc47..2a9176e37332bf91ee0cacfb485f3eec8261c936 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -417,7 +417,7 @@ Operand *HandleVectorMerge(const IntrinsicopNode &intrnNode, CGFunc &cgFunc) { int32 iNum = 0; if (index->GetOpCode() == OP_constval) { MIRConst *mirConst = static_cast(index)->GetConstVal(); - iNum = static_cast(safe_cast(mirConst)->GetValue()); + iNum = static_cast(safe_cast(mirConst)->GetExtValue()); PrimType ty = intrnNode.Opnd(0)->GetPrimType(); if (!IsPrimitiveVector(ty)) { iNum = 0; @@ -449,7 +449,7 @@ Operand *HandleVectorGetElement(const IntrinsicopNode &intrnNode, CGFunc &cgFunc int32 laneNum = -1; if (opndLane->IsConstImmediate()) { MIRConst *mirConst = static_cast(intrnNode.Opnd(1))->GetConstVal(); - laneNum = static_cast(safe_cast(mirConst)->GetValue()); + laneNum = static_cast(safe_cast(mirConst)->GetExtValue()); } else { CHECK_FATAL(0, "VectorGetElement does not have lane const"); } @@ -484,7 +484,7 @@ Operand *HandleVectorSetElement(const IntrinsicopNode &intrnNode, CGFunc &cgFunc int32 laneNum = -1; if (opnd2->IsConstImmediate()) { MIRConst *mirConst = static_cast(arg2)->GetConstVal(); - laneNum = static_cast(safe_cast(mirConst)->GetValue()); + laneNum = static_cast(safe_cast(mirConst)->GetExtValue()); } else { CHECK_FATAL(0, "VectorSetElement does not have lane const"); } @@ -581,7 +581,7 @@ Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) auto constNode = static_cast(intrinsicopNode.Opnd(1)); CHECK_FATAL(constNode != nullptr, "null ptr check"); auto mirIntConst = static_cast(constNode->GetConstVal()); - return cgFunc.SelectLazyLoadStatic(*st, mirIntConst->GetValue(), intrinsicopNode.GetPrimType()); + return cgFunc.SelectLazyLoadStatic(*st, mirIntConst->GetExtValue(), intrinsicopNode.GetPrimType()); } case INTRN_MPL_READ_ARRAYCLASS_CACHE_ENTRY: { auto addrOfNode = static_cast(intrinsicopNode.Opnd(0)); @@ -589,7 +589,7 @@ Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) auto constNode = static_cast(intrinsicopNode.Opnd(1)); CHECK_FATAL(constNode != nullptr, "null ptr check"); auto mirIntConst = static_cast(constNode->GetConstVal()); - return cgFunc.SelectLoadArrayClassCache(*st, mirIntConst->GetValue(), intrinsicopNode.GetPrimType()); + return cgFunc.SelectLoadArrayClassCache(*st, mirIntConst->GetExtValue(), intrinsicopNode.GetPrimType()); } // double case INTRN_C_sin: diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index f3639db01ac490b08bd1ba8521e1425faa3d5b79..368d88480802edf70c1eea8d1d5defb83cbe4941 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -547,7 +547,7 @@ void Emitter::EmitBitFieldConstant(StructEmitInfo &structEmitInfo, MIRConst &mir uint32 fieldSize = static_cast(mirType).GetFieldSize(); MIRIntConst &fieldValue = static_cast(mirConst); /* Truncate the size of FieldValue to the bit field size. */ - if (fieldSize < fieldValue.GetBitWidth()) { + if (fieldSize < fieldValue.GetActualBitWidth()) { fieldValue.Trunc(fieldSize); } /* Clear higher Bits for signed value */ @@ -556,16 +556,15 @@ void Emitter::EmitBitFieldConstant(StructEmitInfo &structEmitInfo, MIRConst &mir structEmitInfo.GetCombineBitFieldValue()); } if (CGOptions::IsBigEndian()) { - uint64 beValue = static_cast(fieldValue.GetValue()); - if (fieldValue.GetValue() < 0) { + uint64 beValue = fieldValue.GetExtValue(); + if (fieldValue.IsNegative()) { beValue = beValue - ((beValue >> fieldSize) << fieldSize); } structEmitInfo.SetCombineBitFieldValue( (structEmitInfo.GetCombineBitFieldValue() << fieldSize) + beValue); } else { - structEmitInfo.SetCombineBitFieldValue( - (static_cast(fieldValue.GetValue()) << structEmitInfo.GetCombineBitFieldWidth()) + - structEmitInfo.GetCombineBitFieldValue()); + structEmitInfo.SetCombineBitFieldValue((fieldValue.GetExtValue() << structEmitInfo.GetCombineBitFieldWidth()) + + structEmitInfo.GetCombineBitFieldValue()); } structEmitInfo.IncreaseCombineBitFieldWidth(fieldSize); structEmitInfo.IncreaseNextFieldOffset(fieldSize); @@ -696,7 +695,7 @@ void Emitter::EmitScalarConstant(MIRConst &mirConst, bool newLine, bool flag32, case kConstInt: { MIRIntConst &intCt = static_cast(mirConst); uint32 sizeInBits = GetPrimTypeBitSize(mirType.GetPrimType()); - if (intCt.GetBitWidth() > sizeInBits) { + if (intCt.GetActualBitWidth() > sizeInBits) { intCt.Trunc(sizeInBits); } if (flag32) { @@ -1228,7 +1227,7 @@ MIRAddroffuncConst *Emitter::GetAddroffuncConst(const MIRSymbol &mirSymbol, MIRA GlobalTables::GetStrTable().GetStrIdxFromName(funcDefTabName)); MIRAggConst &funDefTabAggConst = static_cast(*funDefTabSy->GetKonst()); MIRIntConst *funcAddrIndexConst = safe_cast(funcAddrConst); - int64 indexDefTab = funcAddrIndexConst->GetValue(); + uint64 indexDefTab = funcAddrIndexConst->GetExtValue(); MIRAggConst *defTabAggConst = safe_cast(funDefTabAggConst.GetConstVecItem(indexDefTab)); MIRConst *funcConst = defTabAggConst->GetConstVecItem(0); if (funcConst->GetKind() == kConstAddrofFunc) { @@ -1243,9 +1242,9 @@ MIRAddroffuncConst *Emitter::GetAddroffuncConst(const MIRSymbol &mirSymbol, MIRA int64 Emitter::GetFieldOffsetValue(const std::string &className, const MIRIntConst &intConst, const std::map &strIdx2Type) { - int64 idx = intConst.GetValue(); - bool isDefTabIndex = static_cast(idx) & 0x1; - int64 fieldIdx = static_cast(idx) >> 1; + uint64 idx = intConst.GetExtValue(); + bool isDefTabIndex = idx & 0x1; + int64 fieldIdx = idx >> 1; if (isDefTabIndex) { /* it's def table index. */ return fieldIdx; @@ -1338,7 +1337,7 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui if (isClassInfo || isMethodsInfo || isFieldsInfo || mirSymbol.IsRegJNITab() || isInOffsetTab || isStaticStr || isConflictPerfix || isArrayClassCacheName || isMethodSignature) { /* compare with all 1s */ - uint32 index = static_cast((safe_cast(elemConst))->GetValue()) & 0xFFFFFFFF; + uint32 index = static_cast((safe_cast(elemConst))->GetExtValue()) & 0xFFFFFFFF; bool isHotReflectStr = (index & 0x00000003) != 0; /* use the last two bits of index in this expression */ std::string hotStr; if (isHotReflectStr) { @@ -1427,7 +1426,7 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui Emit("\t.quad\t"); const int width = 8; #endif /* USE_32BIT_REF */ - uint32 muidDataTabAddr = static_cast((safe_cast(elemConst))->GetValue()); + uint32 muidDataTabAddr = static_cast((safe_cast(elemConst))->GetExtValue()); if (muidDataTabAddr != 0) { bool isDefTabIndex = (muidDataTabAddr & kFromDefIndexMask32Mod) == kFromDefIndexMask32Mod; std::string muidDataTabPrefix = isDefTabIndex ? kMuidDataDefTabPrefixStr : kMuidDataUndefTabPrefixStr; @@ -1450,13 +1449,13 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui Emit("+" + strTabName + "\n"); #endif } else if (mirSymbol.IsReflectionMethodAddrData()) { - int64 defTabIndex = intConst->GetValue(); #ifdef USE_32BIT_REF Emit("\t.long\t"); #else Emit("\t.quad\t"); #endif /* USE_32BIT_REF */ - Emit(std::to_string(defTabIndex) + "\n"); + Emit(intConst->GetValue()); + Emit("\n"); } else if (mirSymbol.IsReflectionFieldOffsetData()) { /* Figure out instance field offset now. */ size_t prefixStrLen = strlen(kFieldOffsetDataPrefixStr); @@ -1468,14 +1467,14 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui std::string widthFlag = ".quad"; #endif /* USE_32BIT_REF */ int64 fieldOffset = GetFieldOffsetValue(typeName, *intConst, strIdx2Type); - int64 fieldIdx = intConst->GetValue(); - bool isDefTabIndex = static_cast(fieldIdx) & 0x1; + uint64 fieldIdx = intConst->GetExtValue(); + bool isDefTabIndex = fieldIdx & 0x1; if (isDefTabIndex) { /* it's def table index. */ Emit("\t// " + typeName + " static field, data def table index " + std::to_string(fieldOffset) + "\n"); } else { /* really offset. */ - fieldIdx = static_cast(fieldIdx) >> 1; + fieldIdx >>= 1; Emit("\t// " + typeName + "\t field" + std::to_string(fieldIdx) + "\n"); } Emit("\t" + widthFlag + "\t" + std::to_string(fieldOffset) + "\n"); @@ -1501,7 +1500,7 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui typeName = stName.substr(prefixStrLen); widthFlag = ".long"; } - int64 fieldIdx = intConst->GetValue(); + int64 fieldIdx = intConst->GetExtValue(); MIRSymbol *pOffsetData = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( GlobalTables::GetStrTable().GetStrIdxFromName(kFieldOffsetDataPrefixStr + typeName)); if (pOffsetData != nullptr) { @@ -1553,7 +1552,7 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui Emit("\t.short\t" + std::to_string(objSize) + comments + "\n"); } else if (mirSymbol.IsMuidRangeTab()) { MIRIntConst *subIntCt = safe_cast(elemConst); - int flag = subIntCt->GetValue(); + int flag = subIntCt->GetExtValue(); InitRangeIdx2PerfixStr(); if (rangeIdx2PrefixStr.find(flag) == rangeIdx2PrefixStr.end()) { EmitScalarConstant(*elemConst, false); @@ -1597,7 +1596,7 @@ void Emitter::EmitConstantTable(const MIRSymbol &mirSymbol, MIRConst &mirConst, #ifdef USE_32BIT_REF itabConflictIndex = static_cast((safe_cast(elemConst))->GetValue()) & 0xffff; #else - itabConflictIndex = static_cast((safe_cast(elemConst))->GetValue()) & 0xffffffff; + itabConflictIndex = safe_cast(elemConst)->GetExtValue() & 0xffffffff; #endif } if (IsPrimitiveScalar(elemConst->GetType().GetPrimType())) { @@ -2058,8 +2057,8 @@ void Emitter::MarkVtabOrItabEndFlag(const std::vector &mirSymbolVec) static_cast(tabConst->GetValue()) | 0X40000000, tabConst->GetType()); #else /* #define COLD VTAB ITAB END FLAG 0X4000000000000000 */ - tabConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(static_cast(tabConst->GetValue()) | 0X4000000000000000), tabConst->GetType()); + tabConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(tabConst->GetExtValue() | 0X4000000000000000, + tabConst->GetType()); #endif aggConst->SetItem(static_cast(size) - 1, tabConst, aggConst->GetFieldIdItem(size - 1)); } diff --git a/src/mapleall/maple_be/src/cg/isel.cpp b/src/mapleall/maple_be/src/cg/isel.cpp index 9b5537c74482023c32cab9962f1aa2ad8e57b227..46b84ace34b68b23ded9b1166ec9231d9fa80d82 100644 --- a/src/mapleall/maple_be/src/cg/isel.cpp +++ b/src/mapleall/maple_be/src/cg/isel.cpp @@ -611,7 +611,7 @@ void MPISel::SelectIassignoff(const IassignoffNode &stmt) { CGImmOperand *MPISel::SelectIntConst(MIRIntConst &intConst) { uint32 opndSz = GetPrimTypeSize(intConst.GetType().GetPrimType()) * kBitsPerByte; - return &cgFunc->GetOpndBuilder()->CreateImm(opndSz, intConst.GetValue()); + return &cgFunc->GetOpndBuilder()->CreateImm(opndSz, intConst.GetExtValue()); } Operand *MPISel::SelectShift(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) { diff --git a/src/mapleall/maple_ipa/include/ipa_clone.h b/src/mapleall/maple_ipa/include/ipa_clone.h index 2aa2b9c62afcfab09b39ba92ee0671221b92f93d..d1c1174139935982fccb1aef454122d26ffdd581 100644 --- a/src/mapleall/maple_ipa/include/ipa_clone.h +++ b/src/mapleall/maple_ipa/include/ipa_clone.h @@ -52,8 +52,7 @@ class IpaClone : public AnalysisResult { std::map> &summary, uint32 index); void EvalImportantExpression(MIRFunction *func, std::vector &result); bool CheckCostModel(MIRFunction *newFunc, uint32 paramIndex, std::vector &calleeValue, uint32 impSize); - template - void ComupteValue(dataT value, dataT paramValue, CompareNode *cond, uint64_t &bitRes); + void ComupteValue(const IntVal& value, const IntVal& paramValue, CompareNode *cond, uint64_t &bitRes); void CloneNoImportantExpressFunction(MIRFunction *func, uint32 paramIndex); void ModifyParameterSideEffect(MIRFunction *newFunc, uint32 paramIndex); diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index c69dedcc977eadad3f699286d64b2e461fa00d0e..b8dbf3bcc627911bb704bf64cb149d53014312ca 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -368,8 +368,7 @@ void IpaClone::DecideCloneFunction(std::vector &result, uint32 paramInd } } -template -void IpaClone::ComupteValue(dataT value, dataT paramValue, CompareNode *cond, uint64_t &bitRes) { +void IpaClone::ComupteValue(const IntVal& value, const IntVal& paramValue, CompareNode *cond, uint64_t &bitRes) { if (cond->GetOpCode() == OP_gt) { bitRes = (value > paramValue) | (bitRes << 1); } else if (cond->GetOpCode() == OP_eq) { @@ -388,7 +387,7 @@ void IpaClone::ComupteValue(dataT value, dataT paramValue, CompareNode *cond, ui void IpaClone::EvalCompareResult(std::vector &result, std::map > &evalMap, std::map> &summary, uint32 index) { for (auto &it: summary) { - int64_t value = it.first; + int64 value = it.first; uint64_t bitRes = 0; bool runFlag = false; for (auto &expr : result) { @@ -406,27 +405,16 @@ void IpaClone::EvalCompareResult(std::vector &result, std::mapGetOpndType(); BaseNode *opnd1 = cond->Opnd(1); ConstvalNode *constNode = static_cast(opnd1); - int64_t paramValue = static_cast(constNode->GetConstVal())->GetValue(); - if (primType == PTY_i64) { - ComupteValue(value, paramValue, cond, bitRes); - } else if (primType == PTY_u64) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_u32) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_i32) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_u16) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_i16) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_u8) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else if (primType == PTY_i8) { - ComupteValue(static_cast(value), static_cast(paramValue), cond, bitRes); - } else { + MIRIntConst *constVal = safe_cast(constNode->GetConstVal()); + ASSERT(constVal, "invalid const type"); + if (primType != PTY_i64 && primType != PTY_u64 && primType != PTY_i32 && primType != PTY_u32 && + primType != PTY_i16 && primType != PTY_u16 && primType != PTY_i8 && primType != PTY_u8) { runFlag = false; break; } + IntVal paramValue = { constVal->GetValue(), primType }; + IntVal newValue = { static_cast(value), primType }; + ComupteValue(newValue, paramValue, cond, bitRes); } if (runFlag) { evalMap[bitRes].emplace_back(value); diff --git a/src/mapleall/maple_ipa/src/ipa_collect.cpp b/src/mapleall/maple_ipa/src/ipa_collect.cpp index 8006e3dffe5c61010fafef25739cbd22e0bca3f4..074fcc9b24b48e428378091d481cfeea9339aa8c 100644 --- a/src/mapleall/maple_ipa/src/ipa_collect.cpp +++ b/src/mapleall/maple_ipa/src/ipa_collect.cpp @@ -131,25 +131,8 @@ void CollectIpaInfo::TraversalMeStmt(MeStmt &meStmt) { if (IsPrimitiveInteger(formalSt->GetType()->GetPrimType())) { CallerSummary summary(curFunc->GetPuidx(), callMeStmt->GetMeStmtId()); auto *intConst = safe_cast(constExpr->GetConstVal()); - PrimType type = formalSt->GetType()->GetPrimType(); - int64_t value = intConst->GetValue(); - if (type == PTY_i8 || type == PTY_u8) { - int32 temp = static_cast(value); - if (temp < 0) { - value = static_cast(temp); - } - } else if (type == PTY_i16 || type == PTY_u16) { - int32 temp = static_cast(value); - if (temp < 0) { - value = static_cast(temp); - } - } else if (type == PTY_i32 || type == PTY_u32) { - int32 temp = static_cast(value); - if (temp < 0) { - value = static_cast(temp); - } - } - UpdateCaleeParaAboutInt(meStmt, value, i, summary); + IntVal value = { intConst->GetValue(), formalSt->GetType()->GetPrimType() }; + UpdateCaleeParaAboutInt(meStmt, value.GetExtValue(), i, summary); } } else if (constExpr->GetConstVal()->GetKind() == kConstFloatConst) { if (IsPrimitiveFloat(formalSt->GetType()->GetPrimType())) { diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index 6d2681c89b331ba36a408eec2b653fe35c659d4b..c7eb2a9b4fddb4fc42f91466a108a817a24c40cc 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -630,7 +630,7 @@ class IntConstTable { IntConstTable &operator=(const IntConstTable &p) = delete; ~IntConstTable(); - MIRIntConst *GetOrCreateIntConst(int64 val, MIRType &type); + MIRIntConst *GetOrCreateIntConst(uint64 val, MIRType &type); static std::unique_ptr Create() { auto p = std::unique_ptr(new IntConstTable()); @@ -639,8 +639,8 @@ class IntConstTable { private: IntConstTable() = default; - MIRIntConst *DoGetOrCreateIntConst(int64 val, MIRType &type); - MIRIntConst *DoGetOrCreateIntConstTreadSafe(int64 val, MIRType &type); + MIRIntConst *DoGetOrCreateIntConst(uint64 val, MIRType &type); + MIRIntConst *DoGetOrCreateIntConstTreadSafe(uint64 val, MIRType &type); std::shared_timed_mutex mtx; std::unordered_map intConstTable; }; diff --git a/src/mapleall/maple_ir/include/lexer.h b/src/mapleall/maple_ir/include/lexer.h index 8c6d148f8c9289b8c7ac43e2126412d9c0a74c76..71c0bbfd67e0e922e029eaed0751d18ed16b5172 100644 --- a/src/mapleall/maple_ir/include/lexer.h +++ b/src/mapleall/maple_ir/include/lexer.h @@ -56,7 +56,7 @@ class MIRLexer { return name; } - int64 GetTheIntVal() const { + uint64 GetTheIntVal() const { return theIntVal; } @@ -73,7 +73,7 @@ class MIRLexer { private: MIRModule &module; // for storing the different types of constant values - int64 theIntVal = 0; // also indicates preg number under TK_preg + uint64 theIntVal = 0; // also indicates preg number under TK_preg float theFloatVal = 0.0; double theDoubleVal = 0.0; MapleVector seenComments; diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index b7d42cb431866004559833c8d025db42f96a426c..27710a4e4d93c387875b8fff4298c977676f2d58 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -150,7 +150,7 @@ class MIRBuilder { MIRSymbol *GetOrCreateDeclInFunc(const std::string &str, const MIRType &type, MIRFunction &func); // for creating Expression ConstvalNode *CreateConstval(MIRConst *constVal); - ConstvalNode *CreateIntConst(int64, PrimType); + ConstvalNode *CreateIntConst(uint64, PrimType); ConstvalNode *CreateFloatConst(float val); ConstvalNode *CreateDoubleConst(double val); ConstvalNode *CreateFloat128Const(const uint64 *val); diff --git a/src/mapleall/maple_ir/include/mir_const.h b/src/mapleall/maple_ir/include/mir_const.h index a4608bfb22e3a1c98a1451c98f63b675cc125f70..bd0f17661b81b251ef816a0fd8beb84b8218cf8f 100644 --- a/src/mapleall/maple_ir/include/mir_const.h +++ b/src/mapleall/maple_ir/include/mir_const.h @@ -16,6 +16,7 @@ #define MAPLE_IR_INCLUDE_MIR_CONST_H #include #include "mir_type.h" +#include "mpl_int_val.h" namespace maple { class MIRConst; // circular dependency exists, no other choice @@ -92,56 +93,58 @@ class MIRConst { class MIRIntConst : public MIRConst { public: - using value_type = int64; - MIRIntConst(int64 val, MIRType &type) : MIRConst(type, kConstInt), value(val) { - if (!IsPrimitiveDynType(type.GetPrimType())) { - if (type.GetPrimType() == PTY_u128 || type.GetPrimType() == PTY_i128) { - Trunc(64u); - } else { - Trunc(GetPrimTypeBitSize(type.GetPrimType())); - } - } + MIRIntConst(uint64 val, MIRType &type) + : MIRConst(type, kConstInt), value(val, type.GetPrimType()) {} + + MIRIntConst(const IntVal &val, MIRType &type) : MIRConst(type, kConstInt), value(val) { + [[maybe_unused]] PrimType pType = type.GetPrimType(); + ASSERT(IsPrimitiveInteger(pType) && GetPrimTypeActualBitSize(pType) <= value.GetBitWidth(), + "Constant is tried to be constructed with non-integral type or bit-width is not appropriate for it"); } - ~MIRIntConst() = default; + /// @return number of used bits in the value + uint8 GetActualBitWidth() const; - uint8 GetBitWidth() const; + void Trunc(uint8 width) { + value.TruncInPlace(width); + } - void Trunc(uint8 width); + void Dump(const MIRSymbolTable *localSymTab) const override; - int64 GetValueUnderType() const; + bool IsNegative() const { + return value.IsSigned() && value.GetSignBit(); + } - void Dump(const MIRSymbolTable *localSymTab) const override; - bool IsZero() const override { - return value == 0 && IsPrimitiveInteger(GetType().GetPrimType()); + bool IsPositive() const { + return !IsNegative() && value != 0; } - bool IsGeZero() { - return value >= 0 && IsPrimitiveInteger(GetType().GetPrimType()); + bool IsZero() const override { + return value == 0; } bool IsOne() const override { - return value == 1 && IsPrimitiveInteger(GetType().GetPrimType()); - }; - bool IsMagicNum() const override { - // use INIT_INST_TABLE defined 50 OPs for inst_processor_table - constexpr int64 kMagicNum = 51; - return value == kMagicNum && IsPrimitiveInteger(GetType().GetPrimType()); - }; - bool IsAllBitsOne() const { - return value == -1 && IsPrimitiveInteger(GetType().GetPrimType()); - }; + return value == 1; + } + void Neg() override { - CHECK_FATAL(false, "Can't Use This Interface in This Object"); + value = -value; } - int64 GetValue() const { + const IntVal &GetValue() const { return value; } - int64 GetSXTValue() const { - uint32 width = GetPrimTypeBitSize(GetType().GetPrimType()); - return static_cast(value << (64 - width)) >> (64 - width); + int64 GetExtValue(uint8 size = 0) const { + return value.GetExtValue(size); + } + + int64 GetSXTValue(uint8 size = 0) const { + return value.GetSXTValue(size); + } + + uint64 GetZXTValue(uint8 size = 0) const { + return value.GetZXTValue(size); } void SetValue(int64 val) const { @@ -153,12 +156,10 @@ class MIRIntConst : public MIRConst { MIRIntConst *Clone(MemPool &memPool) const override { CHECK_FATAL(false, "Can't Use This Interface in This Object"); - (void)memPool; - return nullptr; } private: - int64 value; + IntVal value; }; class MIRAddrofConst : public MIRConst { @@ -606,6 +607,9 @@ class MIRStConst : public MIRConst { MapleVector stOffsetVec; // symbols offset }; #endif // MIR_FEATURE_FULL + +bool IsDivSafe(const MIRIntConst& dividend, const MIRIntConst& divisor, PrimType pType); + } // namespace maple #define LOAD_SAFE_CAST_FOR_MIR_CONST diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index bccf0a65dd9de04e5d6f85af3f18919fcb8f599b..aa17570f673b56f38e1cc1eb45cfa9c268efcaef 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -39,7 +39,7 @@ using OutputTypeFactory = FunctionFactory(constVal).GetValue()); + mplExport.WriteNum(static_cast(constVal).GetExtValue()); } void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index 631288a2ea6c111c47f36a0fca08d8b79fb7b322..f65057327f34dd77aba9d39367c78176f270b2e9 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -296,14 +296,14 @@ void FPConstTable::PostInit() { minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble); } -MIRIntConst *IntConstTable::GetOrCreateIntConst(int64 val, MIRType &type) { +MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type) { if (ThreadEnv::IsMeParallel()) { return DoGetOrCreateIntConstTreadSafe(val, type); } return DoGetOrCreateIntConst(val, type); } -MIRIntConst *IntConstTable::DoGetOrCreateIntConst(int64 val, MIRType &type) { +MIRIntConst *IntConstTable::DoGetOrCreateIntConst(uint64 val, MIRType &type) { IntConstKey key(val, type.GetTypeIndex()); if (intConstTable.find(key) != intConstTable.end()) { return intConstTable[key]; @@ -312,7 +312,7 @@ MIRIntConst *IntConstTable::DoGetOrCreateIntConst(int64 val, MIRType &type) { return intConstTable[key]; } -MIRIntConst *IntConstTable::DoGetOrCreateIntConstTreadSafe(int64 val, MIRType &type) { +MIRIntConst *IntConstTable::DoGetOrCreateIntConstTreadSafe(uint64 val, MIRType &type) { IntConstKey key(val, type.GetTypeIndex()); { std::shared_lock lock(mtx); diff --git a/src/mapleall/maple_ir/src/lexer.cpp b/src/mapleall/maple_ir/src/lexer.cpp index 1d91fbb23839e1c6f9e68456bdd85374fa51f714..11185dee92d9bab0e4d3597d204485098a126254 100644 --- a/src/mapleall/maple_ir/src/lexer.cpp +++ b/src/mapleall/maple_ir/src/lexer.cpp @@ -204,49 +204,49 @@ TokenKind MIRLexer::GetHexConst(uint32 valStart, bool negative) { } TokenKind MIRLexer::GetIntConst(uint32 valStart, bool negative) { - char c = GetCharAtWithUpperCheck(curIdx); - theIntVal = HexCharToDigit(c); - c = GetNextCurrentCharWithUpperCheck(); - uint8 hexValue = 10; - if (theIntVal == 0) { - // octal - hexValue = 8; - } - if (negative) { - theIntVal = -theIntVal; - } - while (isdigit(c)) { - int32 val = HexCharToDigit(c); - if (negative) { - val = -val; - } - theIntVal = (theIntVal * hexValue) + val; - if (val < 0) { - ASSERT(theIntVal < 0, "int value overflow"); - } else if (val > 0) { - ASSERT(theIntVal > 0, "int value overflow"); - } - c = GetNextCurrentCharWithUpperCheck(); + auto negOrSelf = [negative](uint64 val) { return negative ? ~val + 1 : val; }; + + theIntVal = HexCharToDigit(GetCharAtWithUpperCheck(curIdx)); + + uint64 radix = theIntVal == 0 ? 8 : 10; + + char c = GetNextCurrentCharWithUpperCheck(); + + for (theIntVal = negOrSelf(theIntVal); isdigit(c); c = GetNextCurrentCharWithUpperCheck()) { + theIntVal = (theIntVal * radix) + negOrSelf(HexCharToDigit(c)); } + if (c == 'u' || c == 'U') { // skip 'u' or 'U' c = GetNextCurrentCharWithUpperCheck(); + if (c == 'l' || c == 'L') { c = GetNextCurrentCharWithUpperCheck(); } } + if (c == 'l' || c == 'L') { c = GetNextCurrentCharWithUpperCheck(); + if (c == 'l' || c == 'L' || c == 'u' || c == 'U') { ++curIdx; } } + name = line.substr(valStart, curIdx - valStart); - theFloatVal = static_cast(theIntVal); - theDoubleVal = static_cast(theIntVal); - if (negative && theIntVal == 0) { - theFloatVal = -theFloatVal; - theDoubleVal = -theDoubleVal; + + if (negative) { + theFloatVal = static_cast(static_cast(theIntVal)); + theDoubleVal = static_cast(static_cast(theIntVal)); + + if (theIntVal == 0) { + theFloatVal = -theFloatVal; + theDoubleVal = -theDoubleVal; + } + } else { + theFloatVal = static_cast(theIntVal); + theDoubleVal = static_cast(theIntVal); } + return TK_intconst; } diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 965b2a83c6d29db6c4c7fcb1fef93128f510cd05..af670f0196c3cc7403ccb2e8321fb3e13f61dcfb 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -498,7 +498,7 @@ ConstvalNode *MIRBuilder::CreateConstval(MIRConst *mirConst) { return GetCurrentFuncCodeMp()->New(mirConst->GetType().GetPrimType(), mirConst); } -ConstvalNode *MIRBuilder::CreateIntConst(int64 val, PrimType pty) { +ConstvalNode *MIRBuilder::CreateIntConst(uint64 val, PrimType pty) { auto *mirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(val, *GlobalTables::GetTypeTable().GetPrimType(pty)); return GetCurrentFuncCodeMp()->New(pty, mirConst); diff --git a/src/mapleall/maple_ir/src/mir_const.cpp b/src/mapleall/maple_ir/src/mir_const.cpp index 4b78e1a432dec22b85906ddbe06c386acf80c821..4c6e1ef551352a5c84a17f7a4b3c97c7b777ec81 100644 --- a/src/mapleall/maple_ir/src/mir_const.cpp +++ b/src/mapleall/maple_ir/src/mir_const.cpp @@ -20,12 +20,7 @@ namespace maple { void MIRIntConst::Dump(const MIRSymbolTable*) const { - constexpr int64 valThreshold = 1024; - if (value <= valThreshold) { - LogInfo::MapleLogger() << value; - } else { - LogInfo::MapleLogger() << std::hex << "0x" << value << std::dec; - } + LogInfo::MapleLogger() << value; } bool MIRIntConst::operator==(const MIRConst &rhs) const { @@ -39,46 +34,21 @@ bool MIRIntConst::operator==(const MIRConst &rhs) const { return ((&intConst.GetType() == &GetType()) && (intConst.value == value)); } -uint8 MIRIntConst::GetBitWidth() const { +uint8 MIRIntConst::GetActualBitWidth() const { if (value == 0) { return 1; } + + int64 val = GetExtValue(); + uint64 tmp = val < 0 ? -(val + 1) : val; + uint8 width = 0; - uint64 tmp = value < 0 ? -(value + 1) : value; while (tmp != 0) { ++width; tmp = tmp >> 1u; } - return width; -} - -void MIRIntConst::Trunc(uint8 width) { - const int32 shiftBitNum = static_cast(64u - width); - if (shiftBitNum < 0) { - CHECK_FATAL(false, "shiftBitNum should not be less than zero"); - } - auto unsignShiftBitNum = static_cast(shiftBitNum); - if (IsSignedInteger(GetType().GetPrimType())) { - value = (value << unsignShiftBitNum) >> unsignShiftBitNum; - } else { - value = ((static_cast(value)) << unsignShiftBitNum) >> unsignShiftBitNum; - } -} -int64 MIRIntConst::GetValueUnderType() const { - uint32 bitSize = GetPrimTypeBitSize(GetNonDynType(GetType().GetPrimType())); - if (GetNonDynType(GetType().GetPrimType()) == PTY_u128 || GetNonDynType(GetType().GetPrimType()) == PTY_i128) { - bitSize = 64u; - } - const int32 shiftBitNum = static_cast(64u - bitSize); - if (shiftBitNum < 0) { - CHECK_FATAL(false, "shiftBitNum should not be less than zero"); - } - if (IsSignedInteger(GetType().GetPrimType())) { - return static_cast(((value) << shiftBitNum) >> shiftBitNum); - } - auto unsignedVal = static_cast(value); - return static_cast((unsignedVal << shiftBitNum) >> shiftBitNum); + return width; } void MIRAddrofConst::Dump(const MIRSymbolTable *localSymTab) const { @@ -294,5 +264,14 @@ bool MIRStr16Const::operator==(const MIRConst &rhs) const { const auto &rhsCs = static_cast(rhs); return (&GetType() == &rhs.GetType()) && (value == rhsCs.value); } + +bool IsDivSafe(const MIRIntConst ÷nd, const MIRIntConst &divisor, PrimType pType) { + if (IsUnsignedInteger(pType)) { + return divisor.GetValue() != 0; + } + + return divisor.GetValue() != 0 && (!dividend.GetValue().IsMinValue() || !divisor.GetValue().AreAllBitsOne()); +} + } // namespace maple #endif // MIR_FEATURE_FULL diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index f4324cdb81d055293268b3c04229ba8cf4502e3e..ce085e6d1a928404aaa0b5245a4ef4bd864a1629 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -690,8 +690,8 @@ BaseNode *MIRLower::LowerFarray(ArrayNode *array) { const ConstvalNode *constvalNode = static_cast(array->GetIndex(0)); if (constvalNode->GetConstVal()->GetKind() == kConstInt) { const MIRIntConst *pIntConst = static_cast(constvalNode->GetConstVal()); - CHECK_FATAL(mirModule.IsJavaModule() || pIntConst->GetValue() >= 0, "Array index should >= 0."); - int64 eleOffset = pIntConst->GetValue() * static_cast(eSize); + CHECK_FATAL(mirModule.IsJavaModule() || !pIntConst->IsNegative(), "Array index should >= 0."); + int64 eleOffset = pIntConst->GetExtValue() * eSize; BaseNode *baseNode = array->GetBase(); if (eleOffset == 0) { @@ -786,14 +786,13 @@ BaseNode *MIRLower::LowerCArray(ArrayNode *array) { BaseNode *index = static_cast(array->GetIndex(i)); bool isConst = false; - int64 indexVal = 0; + uint64 indexVal = 0; if (index->op == OP_constval) { ConstvalNode *constNode = static_cast(index); - indexVal = (static_cast(constNode->GetConstVal()))->GetValue(); + indexVal = (static_cast(constNode->GetConstVal()))->GetExtValue(); isConst = true; MIRIntConst *newConstNode = mirModule.GetMemPool()->New( - indexVal * static_cast(mpyDim), - *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); + indexVal * mpyDim, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); BaseNode *newValNode = mirModule.CurFuncCodeMemPool()->New(newConstNode); newValNode->SetPrimType(array->GetPrimType()); if (i == 0) { diff --git a/src/mapleall/maple_me/include/irmap.h b/src/mapleall/maple_me/include/irmap.h index f3a5152506c9e4d32c1bc6da41611449ef0c7661..7a0c7536a46828c293cb88e9409e5e486d5711a6 100644 --- a/src/mapleall/maple_me/include/irmap.h +++ b/src/mapleall/maple_me/include/irmap.h @@ -115,6 +115,7 @@ class IRMap : public AnalysisResult { virtual void Dump() = 0; virtual void SetCurFunction(const BB&) {} + MeExpr *CreateIntConstMeExpr(const IntVal &value, PrimType pType); MeExpr *CreateIntConstMeExpr(int64, PrimType); MeExpr *CreateConstMeExpr(PrimType, MIRConst&); MeExpr *CreateMeExprUnary(Opcode, PrimType, MeExpr&); diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 0474bcfde35f5d8b63abebada6eb230b89dad3e4..d41d2de94ad32aeb8c64a9bb240437fab937de77 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -537,7 +537,14 @@ class ConstMeExpr : public MeExpr { bool IsZero() const override; bool IsIntZero() const override; bool IsOne() const; - int64 GetIntValue() const; + // Get int value represented by IntVal class + IntVal GetIntValue() const; + // Get value extended by its sign + int64 GetExtIntValue() const; + // Get zero extended value + uint64 GetZXTIntValue() const; + // Get sign extended value + int64 GetSXTIntValue() const; MIRConst *GetConstVal() { return constVal; @@ -554,7 +561,7 @@ class ConstMeExpr : public MeExpr { if (constVal->GetKind() == kConstInt) { auto *intConst = safe_cast(constVal); CHECK_NULL_FATAL(intConst); - return intConst->GetValue(); + return intConst->GetExtValue(); } if (constVal->GetKind() == kConstFloatConst) { auto *floatConst = safe_cast(constVal); diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 70706b225d7fbf1b981cee4efb52021d201944eb..c2f0995f039bef1483b9f2819460e32ac6c1668f 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -194,7 +194,7 @@ OffsetType AliasClass::OffsetInBitOfArrayElement(const ArrayNode *arrayNode) { } auto mirConst = static_cast(opnd)->GetConstVal(); ASSERT(mirConst->GetKind() == kConstInt, "array index must be integer"); - auto index = static_cast(mirConst)->GetValue(); + int64 index = static_cast(mirConst)->GetExtValue(); arrayIndexVector[opndId - 1] = index; } @@ -373,7 +373,7 @@ AliasInfo AliasClass::CreateAliasInfoExpr(BaseNode &expr) { } auto mirConst = static_cast(opnd)->GetConstVal(); CHECK_FATAL(mirConst->GetKind() == kConstInt, "array index must be integer"); - int64 constVal = static_cast(mirConst)->GetValue(); + int64 constVal = static_cast(mirConst)->GetExtValue(); if (expr.GetOpCode() == OP_sub) { constVal = -constVal; } else { diff --git a/src/mapleall/maple_me/src/copy_prop.cpp b/src/mapleall/maple_me/src/copy_prop.cpp index be20d47278b0a33b0f1004257194a9e8a9c98abd..8b27e908d76c424bfe9563d88b4c75b5dcbbbecc 100644 --- a/src/mapleall/maple_me/src/copy_prop.cpp +++ b/src/mapleall/maple_me/src/copy_prop.cpp @@ -61,7 +61,7 @@ static bool PropagatableBaseOfIvar(const IvarMeExpr *ivar, const MeExpr *newExpr if (constVal->GetKind() != kConstInt) { return false; } - int64 val = static_cast(constVal)->GetValue(); + int64 val = static_cast(constVal)->GetExtValue(); if (val == 0 || val == GetPrimTypeSize(PTY_ptr)) { return true; } diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index ba545a59910fa77f3d31bd6e91fcd8e5f26e9237..11f5c766a64ca2c4375daccd0bb96f2cde8e5720 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -255,7 +255,7 @@ PEGBuilder::PtrValueRecorder PEGBuilder::BuildPEGNodeOfAdd(const BinaryNode *bin auto *constVal = static_cast(binaryNode->Opnd(1))->GetConstVal(); ASSERT(constVal->GetKind() == kConstInt, "pointer cannot add/sub a non-integer value"); - int64 offsetInByte = static_cast(static_cast(constVal)->GetValue()); + int64 offsetInByte = static_cast(constVal)->GetExtValue(); int64 offsetInBit = kOffsetUnknown; if (offsetInByte < kOffsetMax && offsetInByte > kOffsetMin) { constexpr int kBitNumInOneByte = 8; diff --git a/src/mapleall/maple_me/src/irmap.cpp b/src/mapleall/maple_me/src/irmap.cpp index c652e9a09dad06eaca9153ba68589d0a25c6f1d1..9587b27a327428bfaa111aecc446f05426203f8f 100644 --- a/src/mapleall/maple_me/src/irmap.cpp +++ b/src/mapleall/maple_me/src/irmap.cpp @@ -302,7 +302,7 @@ MeExpr* IRMap::SimplifyIvarWithConstOffset(IvarMeExpr *ivar, bool lhsIvar) { // get offset value auto *mirConst = static_cast(offsetNode)->GetConstVal(); CHECK_FATAL(mirConst->GetKind() == kConstInt, "must be integer const"); - auto offsetInByte = static_cast(mirConst)->GetValue(); + auto offsetInByte = static_cast(mirConst)->GetExtValue(); OffsetType offset(ivar->GetOffset()); offset += (base->GetOp() == OP_add ? offsetInByte : -offsetInByte); if (offset.IsInvalid()) { @@ -814,6 +814,10 @@ MeExpr *IRMap::CreateConstMeExpr(PrimType pType, MIRConst &mirConst) { return HashMeExpr(constMeExpr); } +MeExpr *IRMap::CreateIntConstMeExpr(const IntVal &value, PrimType pType) { + return CreateIntConstMeExpr(value.GetExtValue(), pType); +} + MeExpr *IRMap::CreateIntConstMeExpr(int64 value, PrimType pType) { auto *intConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(value, *GlobalTables::GetTypeTable().GetPrimType(pType)); @@ -1098,12 +1102,8 @@ MeExpr *IRMap::FoldConstExpr(PrimType primType, Opcode op, ConstMeExpr *opndA, C maple::ConstantFold cf(mirModule); auto *constA = static_cast(opndA->GetConstVal()); auto *constB = static_cast(opndB->GetConstVal()); - if ((op == OP_div || op == OP_rem)) { - if (constB->GetValue() == 0 || - (constB->GetValue() == -1 && ((primType == PTY_i32 && constA->GetValue() == INT32_MIN) || - (primType == PTY_i64 && constA->GetValue() == INT64_MIN)))) { - return nullptr; - } + if ((op == OP_div || op == OP_rem) && !IsDivSafe(*constA, *constB, primType)) { + return nullptr; } MIRConst *resconst = cf.FoldIntConstBinaryMIRConst(op, primType, constA, constB); return CreateConstMeExpr(primType, *resconst); @@ -1128,7 +1128,7 @@ MeExpr *IRMap::SimplifyLshrExpr(const OpMeExpr *shrExpr) { auto trySimplifyToExtractbits = [this, shrExpr, countr_one](MeExpr *band, ConstMeExpr *shrConst)->MeExpr* { auto *opnd0 = band->GetOpnd(0); auto *opnd1 = band->GetOpnd(1); - auto shrOffset = static_cast(shrConst)->GetIntValue(); + auto shrOffset = static_cast(shrConst)->GetExtIntValue(); if (opnd0->GetMeOp() != kMeOpConst && opnd1->GetMeOp() != kMeOpConst) { return nullptr; } @@ -1136,7 +1136,7 @@ MeExpr *IRMap::SimplifyLshrExpr(const OpMeExpr *shrExpr) { opnd0 = opnd1; opnd1 = band->GetOpnd(0); } - int64 const0 = static_cast(opnd0)->GetIntValue(); + int64 const0 = static_cast(opnd0)->GetExtIntValue(); if (GetPrimTypeSize(opnd0->GetPrimType()) < GetPrimTypeSize(PTY_u64)) { const0 = static_cast(static_cast(const0)); } @@ -1386,8 +1386,8 @@ MeExpr *IRMap::SimplifyAddExpr(const OpMeExpr *addExpr) { } // (constA - a) + constB --> (constA + constB) - a if (opnd1->GetMeOp() == kMeOpConst) { - auto constA = static_cast(opndA)->GetIntValue(); - auto constB = static_cast(opnd1)->GetIntValue(); + auto constA = static_cast(opndA)->GetExtIntValue(); + auto constB = static_cast(opnd1)->GetExtIntValue(); if (ConstantFold::IntegerOpIsOverflow(OP_add, opndA->GetPrimType(), constA, constB)) { return nullptr; } @@ -1410,11 +1410,11 @@ MeExpr *IRMap::SimplifyAddExpr(const OpMeExpr *addExpr) { return retOpMeExpr; } - if (opndB->GetMeOp() == kMeOpConst && static_cast(opndB)->GetIntValue() != INT_MIN) { + if (opndB->GetMeOp() == kMeOpConst && static_cast(opndB)->GetExtIntValue() != INT_MIN) { // (a - constA) + constB --> a + (constB - constA) if (opnd1->GetMeOp() == kMeOpConst) { - auto constA = static_cast(opnd1)->GetIntValue(); - auto constB = static_cast(opndB)->GetIntValue(); + auto constA = static_cast(opnd1)->GetExtIntValue(); + auto constB = static_cast(opndB)->GetExtIntValue(); if (ConstantFold::IntegerOpIsOverflow(OP_sub, opndA->GetPrimType(), constA, constB)) { return nullptr; } @@ -1810,13 +1810,13 @@ MeExpr *IRMap::SimplifyCmpExpr(OpMeExpr *cmpExpr) { // we prefer ne/eq in following optimizations if (opnd0->GetMeOp() == kMeOpConst && static_cast(opnd0)->GetConstVal()->IsZero()) { auto *newcmp = CreateMeExprCompare(cmpop == OP_ge ? OP_eq : OP_ne, PTY_u1, cmpExpr->GetOpndType(), - *opnd1, *CreateIntConstMeExpr(0, cmpExpr->GetPrimType())); + *opnd1, *CreateIntConstMeExpr(0, cmpExpr->GetOpndType())); auto *simplified = SimplifyCmpExpr(static_cast(newcmp)); return simplified == nullptr ? newcmp : simplified; } if (opnd1->GetMeOp() == kMeOpConst && static_cast(opnd1)->GetConstVal()->IsOne()) { auto *newcmp = CreateMeExprCompare(cmpop == OP_ge ? OP_ne : OP_eq, PTY_u1, cmpExpr->GetOpndType(), - *opnd0, *CreateIntConstMeExpr(0, cmpExpr->GetPrimType())); + *opnd0, *CreateIntConstMeExpr(0, cmpExpr->GetOpndType())); auto *simplified = SimplifyCmpExpr(static_cast(newcmp)); return simplified == nullptr ? newcmp : simplified; } @@ -1836,13 +1836,13 @@ MeExpr *IRMap::SimplifyCmpExpr(OpMeExpr *cmpExpr) { // we prefer ne/eq in following optimizations if (opnd1->GetMeOp() == kMeOpConst && static_cast(opnd1)->GetConstVal()->IsZero()) { auto *newcmp = CreateMeExprCompare(cmpop == OP_gt ? OP_ne : OP_eq, PTY_u1, cmpExpr->GetOpndType(), - *opnd0, *CreateIntConstMeExpr(0, cmpExpr->GetPrimType())); + *opnd0, *CreateIntConstMeExpr(0, cmpExpr->GetOpndType())); auto *simplified = SimplifyCmpExpr(static_cast(newcmp)); return simplified == nullptr ? newcmp : simplified; } if (opnd0->GetMeOp() == kMeOpConst && static_cast(opnd0)->GetConstVal()->IsOne()) { auto *newcmp = CreateMeExprCompare(cmpop == OP_gt ? OP_eq : OP_ne, PTY_u1, cmpExpr->GetOpndType(), - *opnd1, *CreateIntConstMeExpr(0, cmpExpr->GetPrimType())); + *opnd1, *CreateIntConstMeExpr(0, cmpExpr->GetOpndType())); auto *simplified = SimplifyCmpExpr(static_cast(newcmp)); return simplified == nullptr ? newcmp : simplified; } @@ -1950,7 +1950,7 @@ std::optional &CollectBitparts(MeExpr *expr, std::mapGetOpnd(1)->GetMeOp() == kMeOpConst) { - auto andMask = static_cast(expr->GetOpnd(1))->GetIntValue(); + auto andMask = static_cast(expr->GetOpnd(1))->GetExtIntValue(); if (__builtin_popcountll(andMask) % 8 != 0) { return result; } @@ -1975,7 +1975,7 @@ std::optional &CollectBitparts(MeExpr *expr, std::mapGetOpnd(1)->GetMeOp() == kMeOpConst) { - auto bitShift = static_cast(expr->GetOpnd(1))->GetIntValue(); + auto bitShift = static_cast(expr->GetOpnd(1))->GetExtIntValue(); if (bitShift < 0 || bitShift > bitwidth) { return result; } @@ -2145,7 +2145,7 @@ static bool IsSignBitZero(MeExpr *opnd, uint64 signBit, uint64 shiftAmt) { if (opnd1->GetMeOp() != kMeOpConst) { return false; } - auto andValue = static_cast(opnd1)->GetIntValue(); + auto andValue = static_cast(opnd1)->GetExtIntValue(); knownZeroBits |= ~andValue; break; } @@ -2169,7 +2169,7 @@ MeExpr *IRMap::SimplifyAshrMeExpr(OpMeExpr *opmeexpr) { if (opnd1->GetMeOp() != kMeOpConst) { return nullptr; } - auto shiftAmt = static_cast(opnd1)->GetIntValue(); + auto shiftAmt = static_cast(opnd1)->GetExtIntValue(); auto bitWidth = GetPrimTypeBitSize(opmeexpr->GetPrimType()); if (shiftAmt >= bitWidth) { @@ -2342,15 +2342,8 @@ MeExpr *IRMap::SimplifyOpMeExpr(OpMeExpr *opmeexpr) { maple::ConstantFold cf(mirModule); MIRIntConst *opnd0const = static_cast(static_cast(opnd0)->GetConstVal()); MIRIntConst *opnd1const = static_cast(static_cast(opnd1)->GetConstVal()); - if ((opop == OP_div || opop == OP_rem)) { - int64 opnd0constValue = opnd0const->GetValue(); - int64 opnd1constValue = opnd1const->GetValue(); - PrimType resPtyp = opmeexpr->GetPrimType(); - if (opnd1constValue == 0 || - (opnd1constValue == -1 && ((resPtyp == PTY_i32 && opnd0constValue == INT32_MIN) || - (resPtyp == PTY_i64 && opnd0constValue == INT64_MIN)))) { + if ((opop == OP_div || opop == OP_rem) && !IsDivSafe(*opnd0const, *opnd1const, opmeexpr->GetPrimType())) { return nullptr; - } } MIRConst *resconst = cf.FoldIntConstBinaryMIRConst(opmeexpr->GetOp(), opmeexpr->GetPrimType(), opnd0const, opnd1const); @@ -2376,9 +2369,11 @@ MeExpr *IRMap::SimplifyOpMeExpr(OpMeExpr *opmeexpr) { } MeExpr *opnd0 = opmeexpr->GetOpnd(0); MeExpr *opnd1 = opmeexpr->GetOpnd(1); + if (opnd0->GetMeOp() == kMeOpConst && opnd1->GetMeOp() == kMeOpConst) { return foldConst(opnd0, opnd1, opmeexpr->GetOp(), opmeexpr->GetPrimType()); } + return SimplifyLshrExpr(opmeexpr); } case OP_band: { @@ -2406,7 +2401,7 @@ MeExpr *IRMap::SimplifyOpMeExpr(OpMeExpr *opmeexpr) { auto *opnd = opmeexpr->GetOpnd(0); if (opnd->GetMeOp() == kMeOpConst && IsPrimitiveInteger(opnd->GetPrimType()) && IsPrimitiveInteger(opmeexpr->GetPrimType())) { - return CreateIntConstMeExpr(-static_cast(opnd)->GetIntValue(), opmeexpr->GetPrimType()); + return CreateIntConstMeExpr(-static_cast(opnd)->GetExtIntValue(), opmeexpr->GetPrimType()); } return nullptr; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 9acc290d375d3842b6b780a9b2ae74ce60f1eb06..eca0a9f4105c70e0f5c9caaea123ddbfe098bec3 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -622,7 +622,7 @@ static bool IncDecAmountIsSmallInteger(MeExpr *x) { } ConstMeExpr *cMeExpr = static_cast(x); MIRIntConst *cnode = dynamic_cast(cMeExpr->GetConstVal()); - return cnode != nullptr && cnode->GetValue() < 0x1000; + return cnode != nullptr && cnode->GetExtValue() < 0x1000; } MeStmt *IRMapBuild::BuildDassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index ea13d7b91befc059bb0f912edf74be81c04279e8..9cab595c5d0dee9f19b475781d3e71cd674c2683 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -56,7 +56,7 @@ BaseNode &ConstMeExpr::EmitExpr(SSATab &ssaTab) { // if int const has been promoted from dyn int const, remove the type tag if (IsPrimitiveInteger(exprConst->GetPrimType())) { auto *intConst = safe_cast(exprConst->GetConstVal()); - MIRIntConst *newIntConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(intConst->GetValueUnderType(), + MIRIntConst *newIntConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(intConst->GetExtValue(), intConst->GetType()); exprConst->SetConstVal(newIntConst); } @@ -302,7 +302,7 @@ StmtNode &DassignMeStmt::EmitStmt(SSATab &ssaTab) { StIdx lhsStIdx = lhsMirSt->GetStIdx(); int32 offset = (GetVarLHS()->GetOst()->GetOffset().val) / 8; PrimType rhsType = GetRHS()->GetPrimType(); - int64 val = static_cast(GetRHS())->GetIntValue(); + int64 val = static_cast(GetRHS())->GetExtIntValue(); ConstvalNode *rhsNode = ssaTab.GetModule().GetMIRBuilder()->CreateIntConst(val, rhsType); MemPool *codeMemPool = ssaTab.GetModule().CurFunction()->GetCodeMempool(); DassignoffNode *dassignoffNode = codeMemPool->New(lhsStIdx, offset, rhsType, rhsNode); @@ -379,7 +379,7 @@ StmtNode &IassignMeStmt::EmitStmt(SSATab &ssaTab) { addrNode = codeMemPool->New(OP_add, lhsVar->GetBase()->GetPrimType(), &(lhsVar->GetBase()->EmitExpr(ssaTab)), offsetNode); } - int64 val = static_cast(GetOpnd(1))->GetIntValue(); + int64 val = static_cast(GetOpnd(1))->GetExtIntValue(); ConstvalNode *rhsNode = ssaTab.GetModule().GetMIRBuilder()->CreateIntConst(val, rhsType); MemPool *codeMemPool = ssaTab.GetModule().CurFunction()->GetCodeMempool(); IassignoffNode *iassignoffNode = codeMemPool->New(rhsType, offset, addrNode, rhsNode); diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 33f19ee45247877e4abbbd43900b4973f49115a1..6ede310138b951bba04059748e3957de3d8013b5 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -232,7 +232,7 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { if (opnd1->op == OP_constval) { MIRConst *mirconst = static_cast(opnd1)->GetConstVal(); if (mirconst->GetKind() == kConstInt) { - subsDesc->additiveConst = static_cast(mirconst)->GetValue(); + subsDesc->additiveConst = static_cast(mirconst)->GetExtValue(); if (op == OP_sub) { subsDesc->additiveConst = - subsDesc->additiveConst; } @@ -278,7 +278,7 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { subsDesc->tooMessy = true; return subsDesc; } - subsDesc->coeff = static_cast(mirconst)->GetValue(); + subsDesc->coeff = static_cast(mirconst)->GetExtValue(); } // process varNode if (varNode->GetOpCode() == OP_cvt) { diff --git a/src/mapleall/maple_me/src/lfo_iv_canon.cpp b/src/mapleall/maple_me/src/lfo_iv_canon.cpp index 49c6d2c402162fc9c0b2bc4fa7ef6e7166c2fabe..a1ee9193f02582f54cd8b74a702bd8f6409db0a7 100644 --- a/src/mapleall/maple_me/src/lfo_iv_canon.cpp +++ b/src/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -72,7 +72,7 @@ int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *phiLHS, int32 *appearance MIRConst *konst = static_cast(x)->GetConstVal(); CHECK_FATAL(konst->GetKind() == kConstInt, "ComputeIncrAmt: must be integer constant"); MIRIntConst *intConst = static_cast(konst); - return static_cast(intConst->GetValue()); + return static_cast(intConst->GetExtValue()); } case kMeOpVar: case kMeOpReg:{ @@ -484,7 +484,7 @@ void IVCanon::ComputeTripCount() { if (tripCount->GetOp() == maple::OP_constval) { MIRConst *con = static_cast(tripCount)->GetConstVal(); MIRIntConst *countval = static_cast(con); - if (static_cast(countval->GetValue()) < 0) { + if (countval->IsNegative()) { MIRIntConst *zeroConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, con->GetType()); tripCount = irMap->CreateConstMeExpr(tripCount->GetPrimType(), *zeroConst); } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 01b96e0eae89ab85328eb80d15df5b1987a50b42..7284f2059a514c56d995ba138f5f724dffa2a0f1 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -110,27 +110,28 @@ void LoopTransPlan::GenerateBoundInfo(const DoloopNode *doloop, const DoloopInfo BaseNode *upNode = condNode->Opnd(1); MIRIntConst *newIncr = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - vecFactor * incrConst->GetValue(), *typeInt); + vecFactor * incrConst->GetExtValue(), *typeInt); ConstvalNode *newIncrNode = codeMP->New(PTY_i32, newIncr); PrimType newOpndtype = (static_cast(condNode))->GetOpndType() == PTY_ptr ? PTY_i64 : PTY_i32; if (initNode->IsConstval()) { ConstvalNode *lcn = static_cast(initNode); MIRIntConst *lowConst = static_cast(lcn->GetConstVal()); - int64 lowvalue = lowConst->GetValue(); + int64 lowvalue = lowConst->GetExtValue(); // upNode is constant if (upNode->IsConstval()) { ConstvalNode *ucn = static_cast(upNode); MIRIntConst *upConst = static_cast(ucn->GetConstVal()); - int64 upvalue = upConst->GetValue(); + int64 upvalue = upConst->GetExtValue(); if (condOpHasEqual) { upvalue += 1; } - if (((upvalue - lowvalue) % (newIncr->GetValue())) == 0) { + int64 newIncrVal = newIncr->GetExtValue(); + if (((upvalue - lowvalue) % newIncrVal) == 0) { // early return, change vbound->stride only vBound = localMP->New(nullptr, nullptr, newIncrNode); } else { // trip count is not vector lane aligned - int64 newupval = (upvalue - lowvalue) / (newIncr->GetValue()) * (newIncr->GetValue()) + lowvalue; + int64 newupval = (upvalue - lowvalue) / newIncrVal * newIncrVal + lowvalue; MIRIntConst *newUpConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(newupval, *typeInt); ConstvalNode *newUpNode = codeMP->New(PTY_i32, newUpConst); vBound = localMP->New(nullptr, newUpNode, newIncrNode); @@ -234,16 +235,16 @@ bool LoopTransPlan::Generate(const DoloopNode *doloop, const DoloopInfo* li, boo if (initNode->IsConstval() && upNode->IsConstval() && incrNode->IsConstval()) { ConstvalNode *lcn = static_cast(initNode); MIRIntConst *lowConst = static_cast(lcn->GetConstVal()); - int64 lowvalue = lowConst->GetValue(); + int64 lowvalue = lowConst->GetExtValue(); ConstvalNode *ucn = static_cast(upNode); MIRIntConst *upConst = static_cast(ucn->GetConstVal()); - int64 upvalue = upConst->GetValue(); + int64 upvalue = upConst->GetExtValue(); ConstvalNode *icn = static_cast(incrNode); MIRIntConst *incrConst = static_cast(icn->GetConstVal()); if (condOpHasEqual) { upvalue += 1; } - int64 tripCount = (upvalue - lowvalue) / (incrConst->GetValue()); + int64 tripCount = (upvalue - lowvalue) / (incrConst->GetExtValue()); if (static_cast(tripCount) < vecLanes) { tripCount = (tripCount / 4 * 4); // get closest 2^n if (tripCount * vecInfo->smallestTypeSize < 64) { @@ -1685,7 +1686,8 @@ void LoopVectorization::VectorizeDoLoop(DoloopNode *doloop, LoopTransPlan *tp) { if (GetPrimTypeSize(incrNode->GetPrimType()) != GetPrimTypeSize(elemType->GetPrimType())) { ConstvalNode *constnode = static_cast(incrNode); MIRIntConst *incrconst = static_cast(constnode->GetConstVal()); - MIRIntConst *newConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(incrconst->GetValue(), *elemType); + MIRIntConst *newConst = + GlobalTables::GetIntConstTable().GetOrCreateIntConst(incrconst->GetExtValue(), *elemType); incrNode = codeMP->New(elemType->GetPrimType(), newConst); } BaseNode *incrhs = codeMP->New(OP_add, vecType->GetPrimType(), regreadNode, incrNode); @@ -1954,7 +1956,7 @@ bool LoopVectorization::CanConvert(uint32_t lshtypeSize, uint32_t rhstypeSize) c bool LoopVectorization::CanAdjustRhsConstType(PrimType targetType, ConstvalNode *rhs) { MIRIntConst *intConst = static_cast(rhs->GetConstVal()); - int64 v = intConst->GetValue(); + int64 v = intConst->GetExtValue(); bool res = false; switch (targetType) { case PTY_i32: { diff --git a/src/mapleall/maple_me/src/lfo_unroll.cpp b/src/mapleall/maple_me/src/lfo_unroll.cpp index b92852ca14730af239136ff83ea93d4857fbe136..5373294f55d64cc4722dcfa6474a59b79ea6afff 100644 --- a/src/mapleall/maple_me/src/lfo_unroll.cpp +++ b/src/mapleall/maple_me/src/lfo_unroll.cpp @@ -206,8 +206,8 @@ BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { } // update incrExpr ConstvalNode *stepNode = static_cast(unrolledDoloop->GetIncrExpr()); - int64 origIncr = static_cast(stepNode->GetConstVal())->GetValue(); - unrolledDoloop->SetIncrExpr(mirBuilder->CreateIntConst(origIncr * static_cast(times), ivPrimType)); + uint64 origIncr = static_cast(stepNode->GetConstVal())->GetExtValue(); + unrolledDoloop->SetIncrExpr(mirBuilder->CreateIntConst(origIncr * times, ivPrimType)); unrolledBlk->AddStatement(unrolledDoloop); return unrolledBlk; } @@ -272,7 +272,7 @@ void LfoUnrollOneLoop::Process() { } ConstvalNode *stepNode = static_cast(doloop->GetIncrExpr()); MIRIntConst *stepConst = static_cast(stepNode->GetConstVal()); - stepAmount = stepConst->GetValue(); + stepAmount = stepConst->GetExtValue(); size_t tripCount = 0; // 0 if not constant trip count if (doloop->GetStartExpr()->IsConstval() && endExpr->IsConstval()) { @@ -280,7 +280,7 @@ void LfoUnrollOneLoop::Process() { MIRIntConst *startConst = static_cast(startNode->GetConstVal()); ConstvalNode *endNode = static_cast(endExpr); MIRIntConst *endConst = static_cast(endNode->GetConstVal()); - tripCount = static_cast((endConst->GetValue() - startConst->GetValue()) / stepAmount); + tripCount = static_cast((endConst->GetExtValue() - startConst->GetExtValue()) / stepAmount); if (condExpr->GetOpCode() == OP_ge || condExpr->GetOpCode() == OP_le) { tripCount++; } diff --git a/src/mapleall/maple_me/src/me_abco.cpp b/src/mapleall/maple_me/src/me_abco.cpp index 3b973bfb02d880a6e276d4d0e3ddd23098ba349b..179f67b057bba90c1a1724ac2ac80b83b8ad64dc 100644 --- a/src/mapleall/maple_me/src/me_abco.cpp +++ b/src/mapleall/maple_me/src/me_abco.cpp @@ -223,16 +223,16 @@ bool MeABC::BuildBrMeStmtInGraph(MeStmt &meStmt) { AddUseDef(*opOpnd1); AddUseDef(*opOpnd2); } else if (opOpnd1->GetMeOp() == kMeOpConst) { - brTargetOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetIntValue()); + brTargetOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetExtIntValue()); brTargetOpnd2 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[0]->GetLHS()); - brFallThruOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetIntValue()); + brFallThruOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetExtIntValue()); brFallThruOpnd2 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(0)->GetLHS()); AddUseDef(*opOpnd2); } else if (opOpnd2->GetMeOp() == kMeOpConst) { brTargetOpnd1 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[0]->GetLHS()); - brTargetOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetIntValue()); + brTargetOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetExtIntValue()); brFallThruOpnd1 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(0)->GetLHS()); - brFallThruOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetIntValue()); + brFallThruOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetExtIntValue()); AddUseDef(*opOpnd1); } else { CHECK_FATAL(false, "impossible"); @@ -365,7 +365,7 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { if (varExpr != nullptr) { CHECK_FATAL(varExpr->GetMeOp() == kMeOpConst, "must be"); ESSAConstNode *constNode = inequalityGraph->GetOrCreateConstNode( - static_cast(varExpr)->GetIntValue()); + static_cast(varExpr)->GetExtIntValue()); AddEdgePair(*arrLength, *constNode, 0, EdgeType::kNone); } else { AddEdgePair(*arrLength, *rhsNode, 0, EdgeType::kNone); @@ -373,7 +373,7 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { } else { CHECK_FATAL(opMeExpr->GetOpnd(0)->GetMeOp() == kMeOpConst, "must be"); rhsNode = inequalityGraph->GetOrCreateConstNode( - static_cast(opMeExpr->GetOpnd(0))->GetIntValue()); + static_cast(opMeExpr->GetOpnd(0))->GetExtIntValue()); AddEdgePair(*arrLength, *rhsNode, 0, EdgeType::kNone); } return true; @@ -400,9 +400,9 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); AddUseDef(*opnd1); AddEdgePair(*rhsNode, *lhsNode, - -static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + -static_cast(opnd2)->GetExtIntValue(), EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, - static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + static_cast(opnd2)->GetExtIntValue(), EdgeType::kLower); return true; }else { // support this pattern later @@ -422,9 +422,9 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); AddUseDef(*opnd1); AddEdgePair(*rhsNode, *lhsNode, - -static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + -static_cast(opnd2)->GetExtIntValue(), EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, - static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + static_cast(opnd2)->GetExtIntValue(), EdgeType::kLower); return true; } else { // support this pattern later @@ -457,9 +457,9 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { AddUseDef(*opnd1); ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); AddEdgePair(*rhsNode, *lhsNode, - static_cast(tmpVar)->GetIntValue(), EdgeType::kUpper); + static_cast(tmpVar)->GetExtIntValue(), EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, - -static_cast(tmpVar)->GetIntValue(), EdgeType::kLower); + -static_cast(tmpVar)->GetExtIntValue(), EdgeType::kLower); return true; } visited.clear(); @@ -486,9 +486,9 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); AddUseDef(*opnd1); AddEdgePair(*rhsNode, *lhsNode, - static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + static_cast(opnd2)->GetExtIntValue(), EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, - -static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + -static_cast(opnd2)->GetExtIntValue(), EdgeType::kLower); return true; } else { visited.clear(); @@ -498,9 +498,9 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd2); AddUseDef(*opnd2); AddEdgePair(*rhsNode, *lhsNode, - static_cast(opnd1)->GetIntValue(), EdgeType::kUpper); + static_cast(opnd1)->GetExtIntValue(), EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, - -static_cast(opnd1)->GetIntValue(), EdgeType::kLower); + -static_cast(opnd1)->GetExtIntValue(), EdgeType::kLower); return true; } CHECK_FATAL(false, "impossible"); @@ -518,14 +518,14 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { if (IsUnsignedInteger(opnd1->GetPrimType())) { AddUseDef(*opnd1); rhsNode1 = GetOrCreateRHSNode(*opnd1); - } else if (opnd1->GetMeOp() == kMeOpConst && static_cast(opnd1)->GetIntValue() >= 0) { - rhsNode1 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd1)->GetIntValue()); + } else if (opnd1->GetMeOp() == kMeOpConst && static_cast(opnd1)->GetExtIntValue() >= 0) { + rhsNode1 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd1)->GetExtIntValue()); } if (IsUnsignedInteger(opnd2->GetPrimType())) { AddUseDef(*opnd2); rhsNode2 = GetOrCreateRHSNode(*opnd2); - } else if (opnd2->GetMeOp() == kMeOpConst && static_cast(opnd2)->GetIntValue() >= 0) { - rhsNode2 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd2)->GetIntValue()); + } else if (opnd2->GetMeOp() == kMeOpConst && static_cast(opnd2)->GetExtIntValue() >= 0) { + rhsNode2 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd2)->GetExtIntValue()); } if (rhsNode1 == nullptr && rhsNode2 == nullptr) { return false; @@ -550,7 +550,7 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { return false; } if (opnd2->GetMeOp() == kMeOpConst) { - if (static_cast(opnd2)->GetIntValue() > 0) { + if (static_cast(opnd2)->GetExtIntValue() > 0) { visited.clear(); if (HasRelativeWithLength(*opnd1)) { unresolveEdge[std::make_pair(lhs, nullptr)] = opnd2; @@ -563,7 +563,7 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { varExpr = TryToResolveVar(*varExpr, true); if (varExpr != nullptr) { CHECK_FATAL(varExpr->GetMeOp() == kMeOpConst, "must be"); - if (static_cast(varExpr)->GetIntValue() > 0) { + if (static_cast(varExpr)->GetExtIntValue() > 0) { visited.clear(); if (HasRelativeWithLength(*opnd1)) { unresolveEdge[std::make_pair(lhs, nullptr)] = opnd2; @@ -613,7 +613,7 @@ bool MeABC::BuildAssignInGraph(const MeStmt &meStmt) { AddEdgePair(*rhsNode, *lhsNode, 0, EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, 0, EdgeType::kLower); } else { - ESSAConstNode *rhsNode = inequalityGraph->GetOrCreateConstNode(static_cast(rhs)->GetIntValue()); + ESSAConstNode *rhsNode = inequalityGraph->GetOrCreateConstNode(static_cast(rhs)->GetExtIntValue()); AddEdgePair(*rhsNode, *lhsNode, 0, EdgeType::kUpper); AddEdgePair(*lhsNode, *rhsNode, 0, EdgeType::kLower); } @@ -964,7 +964,7 @@ void MeABC::InitNewStartPoint(MeStmt &meStmt, MeExpr &opnd1, MeExpr &opnd2, bool AddUseDef(opnd2); } else { CHECK_FATAL(opnd2.GetMeOp() == kMeOpConst, "must be"); - (void)inequalityGraph->GetOrCreateConstNode(static_cast(&opnd2)->GetIntValue()); + (void)inequalityGraph->GetOrCreateConstNode(static_cast(&opnd2)->GetExtIntValue()); } BB *curBB = meStmt.GetBB(); if (curBB->GetPiList().size()) { diff --git a/src/mapleall/maple_me/src/me_inequality_graph.cpp b/src/mapleall/maple_me/src/me_inequality_graph.cpp index aa6a8d31bb38e5f45ab76f2264e4627ae0534696..4daa1700af878198b61b5077fd2801f32fa8bdb8 100644 --- a/src/mapleall/maple_me/src/me_inequality_graph.cpp +++ b/src/mapleall/maple_me/src/me_inequality_graph.cpp @@ -336,7 +336,7 @@ bool ABCD::IsLessOrEqual(const MeExpr &arrayNode, const MeExpr &idx) { idxNode = &(inequalityGraph->GetNode(idx)); } else { CHECK_FATAL(idx.GetMeOp() == kMeOpConst, "must be"); - idxNode = &(inequalityGraph->GetNode(static_cast(idx).GetIntValue())); + idxNode = &(inequalityGraph->GetNode(static_cast(idx).GetExtIntValue())); } std::unique_ptr e = std::make_unique(kLowerBound, kUpper); active.clear(); @@ -351,7 +351,7 @@ bool ABCD::DemandProve(const MeExpr &arrayNode, const MeExpr &idx) { idxNode = &(inequalityGraph->GetNode(idx)); } else { CHECK_FATAL(idx.GetMeOp() == kMeOpConst, "must be"); - idxNode = &(inequalityGraph->GetNode(static_cast(idx).GetIntValue())); + idxNode = &(inequalityGraph->GetNode(static_cast(idx).GetExtIntValue())); } ESSABaseNode &zNode = inequalityGraph->GetNode(0); bool upperResult = ABCD::DemandProve(aNode, *idxNode, kUpper); diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index 4206d9ac8e2161f0accc9672abb8fee133629a25..1930c6a907997821497e288aea95c4e11e240c95 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -652,7 +652,7 @@ bool OpMeExpr::StrengthReducible() { if (GetOpnd(1)->GetOp() == OP_constval) { ConstMeExpr *cMeExpr = static_cast(GetOpnd(1)); MIRIntConst *cnode = static_cast(cMeExpr->GetConstVal()); - return cnode->GetValue() < 0x1000; + return cnode->GetExtValue() < 0x1000; } return false; } @@ -683,7 +683,7 @@ int64 OpMeExpr::SRMultiplier(OriginalSt *ost) { case OP_mul: { MIRConst *constVal = static_cast(GetOpnd(1))->GetConstVal(); ASSERT(constVal->GetKind() == kConstInt, "OpMeExpr::SRMultiplier: multiplier not an integer constant"); - return static_cast(constVal)->GetValueUnderType(); + return static_cast(constVal)->GetExtValue(); } default: CHECK_FATAL(false, "SRMultiplier: unexpected strength reduction opcode"); @@ -693,7 +693,7 @@ int64 OpMeExpr::SRMultiplier(OriginalSt *ost) { // first, make sure it's int const and return true if the int const great or eq 0 bool ConstMeExpr::GeZero() const { - return (GetIntValue() >= 0); + return (GetExtIntValue() >= 0); } bool ConstMeExpr::GtZero() const { @@ -701,7 +701,7 @@ bool ConstMeExpr::GtZero() const { if (constVal->GetKind() != kConstInt) { return false; } - return (safe_cast(constVal)->GetValue() > 0); + return (safe_cast(constVal)->IsPositive()); } bool ConstMeExpr::IsZero() const { @@ -735,15 +735,33 @@ bool ConstMeExpr::IsOne() const { if (constVal->GetKind() != kConstInt) { return false; } - return (safe_cast(constVal)->GetValue() == 1); + return safe_cast(constVal)->IsOne(); } -int64 ConstMeExpr::GetIntValue() const { +IntVal ConstMeExpr::GetIntValue() const { CHECK_FATAL(constVal != nullptr, "constVal is null"); CHECK_FATAL(constVal->GetKind() == kConstInt, "expect int const"); return safe_cast(constVal)->GetValue(); } +int64 ConstMeExpr::GetExtIntValue() const { + CHECK_FATAL(constVal != nullptr, "constVal is null"); + CHECK_FATAL(constVal->GetKind() == kConstInt, "expect int const"); + return safe_cast(constVal)->GetExtValue(); +} + +uint64 ConstMeExpr::GetZXTIntValue() const { + CHECK_FATAL(constVal != nullptr, "constVal is null"); + CHECK_FATAL(constVal->GetKind() == kConstInt, "expect int const"); + return safe_cast(constVal)->GetZXTValue(); +} + +int64 ConstMeExpr::GetSXTIntValue() const { + CHECK_FATAL(constVal != nullptr, "constVal is null"); + CHECK_FATAL(constVal->GetKind() == kConstInt, "expect int const"); + return safe_cast(constVal)->GetSXTValue(); +} + MeExpr *ConstMeExpr::GetIdenticalExpr(MeExpr &expr, bool isConstructor) const { (void)isConstructor; auto *constExpr = static_cast(&expr); diff --git a/src/mapleall/maple_me/src/me_ivopts.cpp b/src/mapleall/maple_me/src/me_ivopts.cpp index 03d97ebf5778b7e89baa8c8e6297714eec277624..1f36a6c78e2e313643bb800584e9ff28b2e6262e 100644 --- a/src/mapleall/maple_me/src/me_ivopts.cpp +++ b/src/mapleall/maple_me/src/me_ivopts.cpp @@ -786,7 +786,7 @@ OpMeExpr *IVOptimizer::TryCvtCmp(OpMeExpr &op, MeStmt &stmt) { if (opnd->GetMeOp() != kMeOpConst) { return &op; } - int64 cmpConst = static_cast(opnd)->GetIntValue(); + int64 cmpConst = static_cast(opnd)->GetExtIntValue(); if (GetPrimTypeSize(opnd->GetPrimType()) < kEightByte) { cmpConst = static_cast(static_cast(cmpConst)); } @@ -799,11 +799,11 @@ OpMeExpr *IVOptimizer::TryCvtCmp(OpMeExpr &op, MeStmt &stmt) { bb->SetSucc(1, tmp); } - int64 baseConst = static_cast(iv->base)->GetIntValue(); + int64 baseConst = static_cast(iv->base)->GetExtIntValue(); if (GetPrimTypeSize(iv->base->GetPrimType()) < kEightByte) { baseConst = static_cast(static_cast(baseConst)); } - int64 stepConst = static_cast(iv->step)->GetIntValue(); + int64 stepConst = static_cast(iv->step)->GetExtIntValue(); if (GetPrimTypeSize(iv->step->GetPrimType()) < kEightByte) { stepConst = static_cast(static_cast(stepConst)); } @@ -1227,7 +1227,7 @@ MeExpr *IVOptimizer::StripConstantPart(MeExpr &expr, int64 &offset) { return nullptr; } case OP_constval: { - offset = static_cast(expr).GetIntValue(); + offset = static_cast(expr).GetExtIntValue(); return nullptr; } default: { @@ -1453,7 +1453,7 @@ static void FindScalarFactor(MeExpr &expr, std::unordered_map(expr).GetIntValue(); + int64 constVal = static_cast(expr).GetExtIntValue(); auto it = record.find(kInvalidExprID); if (it == record.end()) { record.emplace(kInvalidExprID, std::make_pair(nullptr, multiplier * constVal)); @@ -1488,9 +1488,9 @@ static void FindScalarFactor(MeExpr &expr, std::unordered_mapGetMeOp() == kMeOpConst) { - FindScalarFactor(*op.GetOpnd(1), record, multiplier * static_cast(opnd0)->GetIntValue()); + FindScalarFactor(*op.GetOpnd(1), record, multiplier * static_cast(opnd0)->GetExtIntValue()); } else { - FindScalarFactor(*op.GetOpnd(0), record, multiplier * static_cast(opnd1)->GetIntValue()); + FindScalarFactor(*op.GetOpnd(0), record, multiplier * static_cast(opnd1)->GetExtIntValue()); } } else if (op.GetOp() == OP_cvt) { FindScalarFactor(*op.GetOpnd(0), record, multiplier); @@ -1508,8 +1508,8 @@ int64 IVOptimizer::ComputeRatioOfStep(MeExpr &candStep, MeExpr &groupStep) { // can not compute return 0; } - int64 candConst = static_cast(candStep).GetIntValue(); - int64 groupConst = static_cast(groupStep).GetIntValue(); + int64 candConst = static_cast(candStep).GetExtIntValue(); + int64 groupConst = static_cast(groupStep).GetExtIntValue(); if (candStep.GetPrimType() == PTY_u32 || groupStep.GetPrimType() == PTY_u32) { candConst = static_cast(static_cast(candConst)); groupConst = static_cast(static_cast(groupConst)); @@ -1652,8 +1652,8 @@ static bool CheckOverflow(const MeExpr *opnd0, const MeExpr *opnd1, Opcode op, P if (opnd0->GetMeOp() != kMeOpConst || opnd1->GetMeOp() != kMeOpConst) { return true; } - int64 const0 = static_cast(opnd0)->GetIntValue(); - int64 const1 = static_cast(opnd1)->GetIntValue(); + int64 const0 = static_cast(opnd0)->GetExtIntValue(); + int64 const1 = static_cast(opnd1)->GetExtIntValue(); if (op == OP_add) { int64 res = static_cast(static_cast(const0) + static_cast(const1)); if (IsUnsignedInteger(ptyp)) { diff --git a/src/mapleall/maple_me/src/me_merge_stmts.cpp b/src/mapleall/maple_me/src/me_merge_stmts.cpp index 6383c948b20e59b5f955ec53d0fb1d5776c3ca3b..d8e1b59a53e9d354f2a5d10754ecc6aca00517f5 100644 --- a/src/mapleall/maple_me/src/me_merge_stmts.cpp +++ b/src/mapleall/maple_me/src/me_merge_stmts.cpp @@ -115,7 +115,7 @@ void MergeStmts::mergeIassigns(vOffsetStmt& iassignCandidates) { } IassignMeStmt *lastIassignMeStmt = static_cast(iassignCandidates[firstIdx].second); ConstMeExpr *rhsLastIassignMeStmt = static_cast(lastIassignMeStmt->GetOpnd(1)); - uint64 fieldVal = static_cast(rhsLastIassignMeStmt->GetIntValue()); + uint64 fieldVal = static_cast(rhsLastIassignMeStmt->GetExtIntValue()); uint64 combinedVal = (fieldVal << (64 - fieldBitSize)) >> (64 - fieldBitSize); auto combineValue = [&](int stmtIdx) { @@ -127,7 +127,7 @@ void MergeStmts::mergeIassigns(vOffsetStmt& iassignCandidates) { fieldBitSize = GetStructFieldBitSize(lhsStructType, fieldID); } fieldVal = static_cast(static_cast( - static_cast(iassignCandidates[stmtIdx].second)->GetOpnd(1))->GetIntValue()); + static_cast(iassignCandidates[stmtIdx].second)->GetOpnd(1))->GetExtIntValue()); fieldVal = (fieldVal << (64 - fieldBitSize)) >> (64 - fieldBitSize); combinedVal = combinedVal << fieldBitSize | fieldVal; }; @@ -226,7 +226,7 @@ void MergeStmts::mergeDassigns(vOffsetStmt& dassignCandidates) { int32 fieldBitSizeEndIdx = GetStructFieldBitSize(lhsStructTypeStart, fieldIDEndIdx); uint64 fieldValIdx = static_cast(static_cast(static_cast( - dassignCandidates[firstIdx].second)->GetRHS())->GetIntValue()); + dassignCandidates[firstIdx].second)->GetRHS())->GetExtIntValue()); uint64 combinedVal = (fieldValIdx << (64 - fieldBitSizeEndIdx)) >> (64 - fieldBitSizeEndIdx); @@ -235,7 +235,7 @@ void MergeStmts::mergeDassigns(vOffsetStmt& dassignCandidates) { FieldID fieldIDStmtIdx = lhsOrigStStmtIdx->GetFieldID(); int32 fieldBitSizeStmtIdx = GetStructFieldBitSize(lhsStructTypeStart, fieldIDStmtIdx); uint64 fieldValStmtIdx = static_cast(static_cast( - static_cast(dassignCandidates[stmtIdx].second)->GetRHS())->GetIntValue()); + static_cast(dassignCandidates[stmtIdx].second)->GetRHS())->GetExtIntValue()); fieldValStmtIdx = (fieldValStmtIdx << (64 - fieldBitSizeStmtIdx)) >> (64 - fieldBitSizeStmtIdx); combinedVal = (combinedVal << fieldBitSizeStmtIdx) | fieldValStmtIdx; }; @@ -317,7 +317,7 @@ void MergeStmts::simdMemcpy(IntrinsiccallMeStmt* memcpyCallStmt) { lengthExpr->GetConstVal()->GetKind() != kConstInt) { return; } - int32 copyLength = static_cast(lengthExpr->GetIntValue()); + int32 copyLength = static_cast(lengthExpr->GetExtIntValue()); if (copyLength <= 0 || copyLength > simdThreshold || copyLength % 8 != 0) { return; } @@ -395,7 +395,7 @@ void MergeStmts::simdMemset(IntrinsiccallMeStmt* memsetCallStmt) { numExpr->GetConstVal()->GetKind() != kConstInt) { return; } - int32 setLength = static_cast(numExpr->GetIntValue()); + int32 setLength = static_cast(numExpr->GetExtIntValue()); // It seems unlikely that setLength is just a few bytes long if (setLength <= 0 || setLength > simdThreshold) { return; diff --git a/src/mapleall/maple_me/src/me_predict.cpp b/src/mapleall/maple_me/src/me_predict.cpp index 471b9070c3122739e623779180ff5d0cd053eed2..3a48d2d17ac85e4d74bc4a8f5d178a43c162686d 100644 --- a/src/mapleall/maple_me/src/me_predict.cpp +++ b/src/mapleall/maple_me/src/me_predict.cpp @@ -112,7 +112,7 @@ Predictor MePrediction::ReturnPrediction(const MeExpr *val, Prediction &predicti return kPredNullReturn; } else if (IsPrimitiveInteger(retType)) { // Negative return values are often used to indicate errors. - if (constExpr->GetIntValue() < 0) { + if (constExpr->GetExtIntValue() < 0) { prediction = kNotTaken; return kPredNegativeReturn; } diff --git a/src/mapleall/maple_me/src/me_scalar_analysis.cpp b/src/mapleall/maple_me/src/me_scalar_analysis.cpp index c2e90bed7432eb9d67fe6c321998da1fea8e781b..20e729e21e7a51aa33d5bf7d39e564fa5814d6d8 100644 --- a/src/mapleall/maple_me/src/me_scalar_analysis.cpp +++ b/src/mapleall/maple_me/src/me_scalar_analysis.cpp @@ -422,7 +422,7 @@ CRNode *LoopScalarAnalysisResult::GetOrCreateCRVarNode(MeExpr &expr) { CRNode *LoopScalarAnalysisResult::GetOrCreateLoopInvariantCR(MeExpr &expr) { if (expr.GetMeOp() == kMeOpConst && static_cast(expr).GetConstVal()->GetKind() == kConstInt) { - return GetOrCreateCRConstNode(&expr, static_cast(expr).GetIntValue()); + return GetOrCreateCRConstNode(&expr, static_cast(expr).GetExtIntValue()); } if (expr.GetMeOp() == kMeOpVar || expr.GetMeOp() == kMeOpReg) { // Try to resolve Var is assigned from Const @@ -432,7 +432,7 @@ CRNode *LoopScalarAnalysisResult::GetOrCreateLoopInvariantCR(MeExpr &expr) { scalar = TryToResolveScalar(*scalar, visitedPhi, dummyExpr); if (scalar != nullptr && scalar != &dummyExpr) { CHECK_FATAL(scalar->GetMeOp() == kMeOpConst, "must be"); - return GetOrCreateCRConstNode(&expr, static_cast(scalar)->GetIntValue()); + return GetOrCreateCRConstNode(&expr, static_cast(scalar)->GetExtIntValue()); } return GetOrCreateCRVarNode(expr); } @@ -901,7 +901,7 @@ CRNode *LoopScalarAnalysisResult::CreateSimpleCRForPhi(MePhiNode &phiNode, if (rhs->GetMeOp() == kMeOpConst && startExpr.GetDefBy() == kDefByStmt) { MeExpr *rhs2 = startExpr.GetDefStmt()->GetRHS(); if (rhs2->GetMeOp() == kMeOpConst && - (static_cast(rhs)->GetIntValue() == static_cast(rhs2)->GetIntValue())) { + (static_cast(rhs)->GetExtIntValue() == static_cast(rhs2)->GetExtIntValue())) { return GetOrCreateLoopInvariantCR(*rhs); } } diff --git a/src/mapleall/maple_me/src/me_slp.cpp b/src/mapleall/maple_me/src/me_slp.cpp index 2b86a64bd2ecbd762b9fae2764957223aa1346b3..97445515791c95ebad7a2b26820ad3747db22670 100644 --- a/src/mapleall/maple_me/src/me_slp.cpp +++ b/src/mapleall/maple_me/src/me_slp.cpp @@ -146,7 +146,7 @@ void MemoryHelper::ExtractAddendOffset(const MeExpr &expr, bool isNeg, MemLoc &m break; } case OP_constval: { - auto val = static_cast(expr).GetIntValue(); + auto val = static_cast(expr).GetExtIntValue(); memLoc.offset += (isNeg ? -val : val); break; } @@ -1250,7 +1250,7 @@ static bool IsConstvalInRangeOfInsnImm(ConstMeExpr *constExpr, Opcode op, uint32 if (constExpr->GetConstVal()->GetKind() != kConstInt) { return false; } - auto val = constExpr->GetIntValue(); + auto val = constExpr->GetExtIntValue(); switch (op) { case OP_add: case OP_sub: @@ -2760,7 +2760,7 @@ bool SLPVectorizer::DoVectTreeNodeConstval(TreeNode *treeNode) { lhsReg = irMap.CreateRegMeExpr(*vecType); std::vector constants(treeNode->GetExprs().size()); std::transform(treeNode->GetExprs().begin(), treeNode->GetExprs().end(), constants.begin(), [](MeExpr *expr) { - return static_cast(expr)->GetIntValue(); + return static_cast(expr)->GetExtIntValue(); }); uint64 mergeConstval = ConstructConstants(constants, GetPrimTypeBitSize(elemType)); rhs = irMap.CreateIntConstMeExpr(mergeConstval, vecType->GetPrimType()); diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index 099a38a88a1ad26b6fc817dea5c512b2b6381331..1ee85ce4f1e88c239c56e85c4780b3aba2706ba4 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -400,7 +400,7 @@ void MeSSALPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, if (intConst == nullptr) { break; } - if ((static_cast(intConst->GetValue()) >> 12) == 0) { + if ((intConst->GetExtValue() >> 12) == 0) { break; // not promoting if value fits in 12 bits } if (!meStmt.GetBB()->GetAttributes(kBBAttrIsInLoop)) { diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 2d5fab20a88db6489ed0fdeff4bed500568f64fa..0142154820760d80e45fdebf27f71185baef45c9 100755 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -715,7 +715,7 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, bool updateCaches) { if (boundOpnd.GetMeOp() == kMeOpConst && static_cast(boundOpnd).GetConstVal()->GetKind() == kConstInt && - static_cast(static_cast(boundOpnd).GetIntValue()) == kInvaliedBound) { + static_cast(static_cast(boundOpnd).GetExtIntValue()) == kInvaliedBound) { if (updateCaches) { Insert2AnalysisedArrayChecks(bb.GetBBId(), *meStmt->GetOpnd(1), *meStmt->GetOpnd(0), meStmt->GetOp()); } @@ -1352,7 +1352,7 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & case kMeOpConst: { if (static_cast(meExpr).GetConstVal()->GetKind() == kConstInt) { (void)Insert2Caches(bb.GetBBId(), meExpr.GetExprID(), std::make_unique( - Bound(nullptr, static_cast(meExpr).GetIntValue(), meExpr.GetPrimType()), kEqual)); + Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); } break; } @@ -1747,7 +1747,7 @@ bool ValueRangePropagation::CreateNewBoundWhenAddOrSub(Opcode op, Bound bound, i // Judge whether the value is constant. bool ValueRangePropagation::IsConstant(const BB &bb, MeExpr &expr, int64 &value, bool canNotBeNotEqual) { if (expr.GetMeOp() == kMeOpConst && static_cast(expr).GetConstVal()->GetKind() == kConstInt) { - value = static_cast(expr).GetIntValue(); + value = static_cast(expr).GetExtIntValue(); return true; } auto *valueRange = FindValueRange(bb, expr); @@ -1756,7 +1756,7 @@ bool ValueRangePropagation::IsConstant(const BB &bb, MeExpr &expr, int64 &value, static_cast(expr).GetDefStmt()->GetRHS()->GetMeOp() == kMeOpConst && static_cast(static_cast(expr).GetDefStmt()->GetRHS())->GetConstVal()->GetKind() == kConstInt) { - value = static_cast(static_cast(expr).GetDefStmt()->GetRHS())->GetIntValue(); + value = static_cast(static_cast(expr).GetDefStmt()->GetRHS())->GetExtIntValue(); (void)Insert2Caches(static_cast(expr).GetDefStmt()->GetBB()->GetBBId(), expr.GetExprID(), std::make_unique(Bound(value, expr.GetPrimType()), kEqual)); return true; @@ -2155,7 +2155,7 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { resVR = DealWithMeOp(bb, stmt); } else if (rhs->GetMeOp() == kMeOpConst && static_cast(rhs)->GetConstVal()->GetKind() == kConstInt) { resVR = std::make_unique( - Bound(static_cast(rhs)->GetIntValue(), rhs->GetPrimType()), kEqual); + Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), kEqual); } if (resVR != nullptr) { auto pTypeOfLHS = lhs->GetPrimType(); @@ -2196,7 +2196,7 @@ bool ValueRangePropagation::CanComputeLoopIndVar(const MeExpr &phiLHS, MeExpr &e static_cast(opMeExpr.GetOpnd(1))->GetConstVal()->GetKind() == kConstInt) { ConstMeExpr *rhsExpr = static_cast(opMeExpr.GetOpnd(1)); int64 res = 0; - auto rhsConst = rhsExpr->GetIntValue(); + auto rhsConst = rhsExpr->GetExtIntValue(); if (rhsExpr->GetPrimType() == PTY_u64 && static_cast(rhsConst) > GetMaxNumber(PTY_i64)) { return false; } @@ -4337,7 +4337,7 @@ bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr & valueRange = FindValueRange(bb, opnd); if (valueRange == nullptr) { if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { - rightRangePtr = std::make_unique(Bound(static_cast(opnd).GetIntValue(), + rightRangePtr = std::make_unique(Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); valueRange = rightRangePtr.get(); if (!Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr))) { @@ -4363,7 +4363,7 @@ bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr & RangeType lhsRangeType = valueRangeOfLHS->GetRangeType(); Bound lhsBound = valueRangeOfLHS->GetBound(); PrimType rhsPrimType = rhs->GetPrimType(); - Bound rhsBound = Bound(static_cast(rhs)->GetIntValue(), rhsPrimType); + Bound rhsBound = Bound(static_cast(rhs)->GetExtIntValue(), rhsPrimType); // If the type of operands is OpMeExpr, need compute the valueRange of operand: // Example: if ((a != c) < b), // a: ValueRange(5, kEqual) @@ -4577,8 +4577,8 @@ void ValueRangePropagation::DealWithBrStmtWithOneOpnd(BB &bb, const CondGotoMeSt std::unique_ptr rightRangePtr = std::make_unique( Bound(nullptr, 0, opnd.GetPrimType()), kEqual); if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { - std::unique_ptr leftRangePtr = - std::make_unique(Bound(static_cast(opnd).GetIntValue(), opnd.GetPrimType()), kEqual); + std::unique_ptr leftRangePtr = std::make_unique( + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); DealWithCondGoto(bb, op, leftRangePtr.get(), *rightRangePtr.get(), stmt); } else { ValueRange *leftRange = FindValueRange(bb, opnd); diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index 98e4ca8d8e24a0674fcea07856f6e473d486dd86..f465b7888d4d6e568b674f001533a30703027945 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -135,7 +135,7 @@ bool IsSimpleImm(uint64 imm) { // if non-simple imm exist, return it, otherwise return 0 int64 GetNonSimpleImm(MeExpr *expr) { if (expr->GetMeOp() == kMeOpConst && IsPrimitiveInteger(expr->GetPrimType())) { - int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetValue(); + int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); if (!IsSimpleImm(static_cast(imm))) { return imm; } @@ -322,7 +322,7 @@ std::unique_ptr GetVRForSimpleCmpExpr(const MeExpr &expr) { if (constVal->GetKind() != kConstInt) { return nullptr; } - int64 val = static_cast(constVal)->GetValue(); + int64 val = static_cast(constVal)->GetExtValue(); opnd1Bound.SetConstant(val); } else if (expr.GetOpnd(1)->IsScalar()) { opnd1Bound.SetVar(expr.GetOpnd(1)); @@ -1503,7 +1503,7 @@ bool IsExprSameLexicalally(MeExpr *expr1, MeExpr *expr2) { MIRConst *const1 = static_cast(expr1)->GetConstVal(); MIRConst *const2 = static_cast(expr2)->GetConstVal(); if (const1->GetKind() == kConstInt) { - return static_cast(const1)->GetValue() == static_cast(const2)->GetValue(); + return static_cast(const1)->GetExtValue() == static_cast(const2)->GetExtValue(); } else if (const1->GetKind() == kConstFloatConst) { return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), static_cast(const2)->GetValue()); @@ -2084,7 +2084,7 @@ bool OptimizeBB::OptimizeSwitchBB() { auto *swConstExpr = static_cast(swStmt->GetOpnd()); MIRConst *swConstVal = swConstExpr->GetConstVal(); ASSERT(swConstVal->GetKind() == kConstInt, "[FUNC: %s]switch is only legal for integer val", funcName); - int64 val = static_cast(swConstVal)->GetValue(); + int64 val = static_cast(swConstVal)->GetExtValue(); BB *survivor = currBB->GetSucc(0); // init as default BB for (size_t i = 0; i < swStmt->GetSwitchTable().size(); ++i) { int64 caseVal = swStmt->GetSwitchTable().at(i).first; @@ -2146,8 +2146,8 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { lePtyp != gePtyp || !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around return nullptr; } - int64 leVal = static_cast(static_cast(leConst)->GetConstVal())->GetValue(); - int64 geVal = static_cast(static_cast(geConst)->GetConstVal())->GetValue(); + int64 leVal = static_cast(static_cast(leConst)->GetConstVal())->GetExtValue(); + int64 geVal = static_cast(static_cast(geConst)->GetConstVal())->GetExtValue(); if (leOp == OP_le) { // (x <= val1) <==> (x < val1 + 1) // if we still use (x <= val1) here, (x - val1) <= 0 may not overflow (if x == val1) diff --git a/src/mapleall/maple_me/src/seqvec.cpp b/src/mapleall/maple_me/src/seqvec.cpp index 65ba57e69f7e264f8f1a0c6513f82c277efa1a20..b02890c0eea712fae2737e162be167f7aea2c3e7 100644 --- a/src/mapleall/maple_me/src/seqvec.cpp +++ b/src/mapleall/maple_me/src/seqvec.cpp @@ -227,7 +227,7 @@ MIRType* SeqVectorize::GenVecType(PrimType sPrimType, uint8 lanes) const { bool SeqVectorize::CanAdjustRhsType(PrimType targetType, ConstvalNode *rhs) { MIRIntConst *intConst = static_cast(rhs->GetConstVal()); - int64 v = intConst->GetValue(); + int64 v = intConst->GetExtValue(); bool res = false; switch (targetType) { case PTY_i32: { @@ -324,7 +324,7 @@ bool SeqVectorize::SameIntConstValue(MeExpr *e1, MeExpr *e2) { MIRIntConst *intc1 = static_cast(const1); MIRConst *const2 = (static_cast(e2))->GetConstVal(); MIRIntConst *intc2 = static_cast(const2); - return (intc1->GetValue() == intc2->GetValue()); + return (intc1->GetExtValue() == intc2->GetExtValue()); } return false; } @@ -376,7 +376,7 @@ bool SeqVectorize::IsOpExprConsecutiveMem(MeExpr *off1, MeExpr *off2, int32_t di MIRIntConst *intoff1 = static_cast(constoff1); MIRConst *constoff2 = static_cast(off2->GetOpnd(1))->GetConstVal(); MIRIntConst *intoff2 = static_cast(constoff2); - if (intoff2->GetValue() - intoff1->GetValue() == diff) { + if (intoff2->GetExtValue() - intoff1->GetExtValue() == diff) { return true; } } @@ -393,7 +393,7 @@ bool SeqVectorize::IsOpExprConsecutiveMem(MeExpr *off1, MeExpr *off2, int32_t di MIRIntConst *intc1 = static_cast(const1); MIRConst *const2 = static_cast(off2)->GetConstVal(); MIRIntConst *intc2 = static_cast(const2); - if (intc2->GetValue() - intc1->GetValue() == diff) { + if (intc2->GetExtValue() - intc1->GetExtValue() == diff) { return true; } } diff --git a/src/mapleall/maple_me/src/ssa_epre_for_lftr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_lftr.cpp index 27f8ba4c68b31c2d44d783c4ae6cfff0107f0873..a368e104889f67cdb8662226f55b61f603cecb33 100644 --- a/src/mapleall/maple_me/src/ssa_epre_for_lftr.cpp +++ b/src/mapleall/maple_me/src/ssa_epre_for_lftr.cpp @@ -159,7 +159,7 @@ static bool IsLargeInteger(ConstMeExpr *constOpnd) { if (intconst == nullptr) { return false; } - return ((uint64) intconst->GetValue()) > 0x8000000; + return intconst->GetExtValue() > 0x8000000; } void SSAEPre::CreateCompOcc(MeStmt *meStmt, int seqStmt, OpMeExpr *compare, bool isRebuilt) { diff --git a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp index fcbfda16cc8bd36e4ab2ba2303171266f670a7c1..b976011bd4eecff89941bda4161f5a70393b17a9 100644 --- a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp +++ b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -107,7 +107,7 @@ static int64 GetIncreAmtAndRhsScalar(MeExpr *x, ScalarMeExpr *&rhsScalar) { "GetIncreAmtAndRhsScalar: cannot find constant inc/dec amount"); MIRConst *constVal = static_cast(opexpr->GetOpnd(1))->GetConstVal(); CHECK_FATAL(constVal->GetKind() == kConstInt, "GetIncreAmtAndRhsScalar: unexpected constant type"); - int64 amt = static_cast(constVal)->GetValueUnderType(); + int64 amt = static_cast(constVal)->GetExtValue(); return (opexpr->GetOp() == OP_sub) ? -amt : amt; } diff --git a/src/mapleall/maple_util/BUILD.gn b/src/mapleall/maple_util/BUILD.gn index 081e8a64a06e32d1aea97c4776a30f8f5e3fde0a..a7341eae06d6a71b33cac4bd135be3378bfd37a6 100755 --- a/src/mapleall/maple_util/BUILD.gn +++ b/src/mapleall/maple_util/BUILD.gn @@ -26,6 +26,7 @@ src_libmplutil = [ "src/string_utils.cpp", "src/error_code.cpp", "src/thread_env.cpp", + "src/mpl_int_val.cpp", ] src_libcommandline = [ diff --git a/src/mapleall/maple_util/include/mpl_int_val.h b/src/mapleall/maple_util/include/mpl_int_val.h new file mode 100644 index 0000000000000000000000000000000000000000..da76b5db97a0e3d7e1aea11656281ab0fd633e3d --- /dev/null +++ b/src/mapleall/maple_util/include/mpl_int_val.h @@ -0,0 +1,490 @@ +/* + * Copyright (c) [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. + */ +#ifndef MAPLE_UTIL_INCLUDE_MPL_INT_VAL_H +#define MAPLE_UTIL_INCLUDE_MPL_INT_VAL_H + +#include "mir_type.h" + +namespace maple { + +/// @brief this class provides different operations on signed and unsigned integers with arbitrary bit-width +class IntVal { + public: + /// @brief create zero value with zero bit-width + IntVal() : value(0), width(0), sign(false) {} + + IntVal(uint64 val, uint8 bitWidth, bool isSigned) : value(val), width(bitWidth), sign(isSigned) { + ASSERT(width <= valBitSize && width != 0, "bit-width is too wide"); + TruncInPlace(); + } + + IntVal(uint64 val, PrimType type) : IntVal(val, GetPrimTypeActualBitSize(type), IsSignedInteger(type)) { + ASSERT(IsPrimitiveInteger(type), "Type must be integral"); + } + + IntVal(const IntVal &val, PrimType type) : IntVal(val.value, type) {} + + IntVal(const IntVal &val, uint8 bitWidth, bool isSigned) : IntVal(val.value, bitWidth, isSigned) {} + + IntVal(const IntVal &val, bool isSigned) : IntVal(val.value, val.width, isSigned) {} + + IntVal &operator=(const IntVal &other) { + if (width == 0) { + // Allow 'this' to be assigned with new bit-width and sign iff + // its original bit-width is zero (i.e. the value was created by the default ctor) + Assign(other); + } else { + // Otherwise, assign only new value, but sign and width must be the same + ASSERT(width == other.width && sign == other.sign, "different bit-width or sign"); + value = other.value; + } + + return *this; + } + + IntVal &operator=(uint64 other) { + value = other; + return *this; + } + + void Assign(const IntVal &other) { + value = other.value; + width = other.width; + sign = other.sign; + } + + /// @return bit-width of the value + uint8 GetBitWidth() const { + return width; + } + + /// @return true if the value is signed + bool IsSigned() const { + return sign; + } + + /// @return sign or zero extended value depending on its signedness + int64 GetExtValue(uint8 size = 0) const { + return sign ? GetSXTValue(size) : GetZXTValue(size); + } + + /// @return zero extended value + uint64 GetZXTValue(uint8 size = 0) const { + // if size == 0, just return the value itself because it's already truncated for an appropriate width + return size ? (value << (valBitSize - size)) >> (valBitSize - size) : value; + } + + /// @return sign extended value + int64 GetSXTValue(uint8 size = 0) const { + uint8 bitWidth = size ? size : width; + return static_cast(value << (valBitSize - bitWidth)) >> (valBitSize - bitWidth); + } + + /// @return true if the (most significant bit) MSB is set + bool GetSignBit() const { + return GetBit(width - 1); + } + + /// @return true if all bits are 1 + bool AreAllBitsOne() const { + return value == (allOnes >> (valBitSize - width)); + } + + /// @return true if the value is maximum considering its signedness + bool IsMaxValue() const { + return sign ? value == ((uint64(1) << (width - 1)) - 1) : AreAllBitsOne(); + } + + /// @return true if the value is minimum considering its signedness + bool IsMinValue() const { + return sign ? value == (uint64(1) << (width - 1)) : value == 0; + } + + // + // Comparison operators that manipulate on values with the same sign and bit-width + // + bool operator==(const IntVal &rhs) const { + ASSERT(width == rhs.width && sign == rhs.sign, "bit-width and sign must be the same"); + return value == rhs.value; + } + + bool operator!=(const IntVal &rhs) const { + return !(*this == rhs); + } + + bool operator<(const IntVal &rhs) const { + ASSERT(width == rhs.width && sign == rhs.sign, "bit-width and sign must be the same"); + return sign ? GetSXTValue() < rhs.GetSXTValue() : value < rhs.value; + } + + bool operator>(const IntVal &rhs) const { + ASSERT(width == rhs.width && sign == rhs.sign, "bit-width and sign must be the same"); + return sign ? GetSXTValue() > rhs.GetSXTValue() : value > rhs.value; + } + + bool operator<=(const IntVal &rhs) const { + return !(*this > rhs); + } + + bool operator>=(const IntVal &rhs) const { + return !(*this < rhs); + } + + // + // Arithmetic and bitwise operators that manipulate on values with the same sign and bit-width + // + IntVal operator+(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value + val.value, width, sign); + } + + IntVal operator-(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value - val.value, width, sign); + } + + IntVal operator*(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value * val.value, width, sign); + } + + IntVal operator/(const IntVal &divisor) const; + + IntVal operator%(const IntVal &divisor) const; + + IntVal operator&(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value & val.value, width, sign); + } + + IntVal operator|(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value | val.value, width, sign); + } + + IntVal operator^(const IntVal &val) const { + ASSERT(width == val.width && sign == val.sign, "bit-width and sign must be the same"); + return IntVal(value ^ val.value, width, sign); + } + + /// @brief shift-left operator + IntVal operator<<(uint64 bits) const { + ASSERT(bits <= width, "invalid shift value"); + return IntVal(value << bits, width, sign); + } + + IntVal operator<<(const IntVal &bits) const { + return *this << bits.value; + } + + /// @brief shift-right operator + /// @note if value is signed this operator works as arithmetic shift-right operator, + /// otherwise it's logical shift-right operator + IntVal operator>>(uint64 bits) const { + ASSERT(bits <= width, "invalid shift value"); + return IntVal(sign ? GetSXTValue() >> bits : value >> bits, width, sign); + } + + IntVal operator>>(const IntVal &bits) const { + return *this >> bits.value; + } + + // + // Comparison operators that compare values obtained from primitive type. + // + /// @note Note that these functions work as follows: + /// 1) sign or zero extend both values (*this and/or rhs) to the new bit-width + /// obtained from pType depending on their original signedness; + /// or truncate the values if their original bit-width is greater than new one + /// 2) then perform the operation itself on new given values that have the same bit-width and sign + /// + /// @warning it's better to avoid using these function in favor of operator==, operator< etc + /// + bool Equal(const IntVal &rhs, PrimType pType) const { + return TruncOrExtend(pType) == rhs.TruncOrExtend(pType); + } + + bool Less(const IntVal &rhs, PrimType pType) const { + return TruncOrExtend(pType) < rhs.TruncOrExtend(pType); + } + + bool Greater(const IntVal &rhs, PrimType pType) const { + return TruncOrExtend(pType) > rhs.TruncOrExtend(pType); + } + + // + // Arithmetic and bitwise operators that allow creating a new value + // with the bit-width and sign obtained from primitive type + // + /// @note Note that these functions work as follows: + /// 1) sign or zero extend both values (*this and rhs) to the new bit-width + /// obtained from pType depending on their original signedness; + /// or truncate the values if their original bit-width is greater than new one + /// 2) then perform the operation itself on new given values that have the same bit-width and sign + /// + /// @warning it's better to avoid using these function in favor of operator+, operator- etc + /// + IntVal Add(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) + val.TruncOrExtend(pType); + } + + IntVal Sub(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) - val.TruncOrExtend(pType); + } + + IntVal Mul(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) * val.TruncOrExtend(pType); + } + + IntVal Div(const IntVal &divisor, PrimType pType) const { + return TruncOrExtend(pType) / divisor.TruncOrExtend(pType); + } + + // sign division in terms of new bitWidth + IntVal SDiv(const IntVal &divisor, uint8 bitWidth) const { + return TruncOrExtend(bitWidth, true) / divisor.TruncOrExtend(bitWidth, true); + } + + // unsigned division in terms of new bitWidth + IntVal UDiv(const IntVal &divisor, uint8 bitWidth) const { + return TruncOrExtend(bitWidth, false) / divisor.TruncOrExtend(bitWidth, false); + } + + // unsigned division in terms of new bitWidth + IntVal Rem(const IntVal &divisor, PrimType pType) const { + return TruncOrExtend(pType) % divisor.TruncOrExtend(pType); + } + + // signed modulo in terms of new bitWidth + IntVal SRem(const IntVal &divisor, uint8 bitWidth) const { + return TruncOrExtend(bitWidth, true) % divisor.TruncOrExtend(bitWidth, true); + } + + // unsigned modulo in terms of new bitWidth + IntVal URem(const IntVal &divisor, uint8 bitWidth) const { + return TruncOrExtend(bitWidth, false) % divisor.TruncOrExtend(bitWidth, false); + } + + IntVal And(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) & val.TruncOrExtend(pType); + } + + IntVal Or(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) | val.TruncOrExtend(pType); + } + + IntVal Xor(const IntVal &val, PrimType pType) const { + return TruncOrExtend(pType) ^ val.TruncOrExtend(pType); + } + + // left-shift operators + IntVal Shl(const IntVal &shift, PrimType pType) const { + return Shl(shift.value, pType); + } + + IntVal Shl(uint64 shift, PrimType pType) const { + return TruncOrExtend(pType) << shift; + } + + // logical right-shift operators (MSB is zero extended) + IntVal LShr(const IntVal &shift, PrimType pType) const { + return LShr(shift.value, pType); + } + + IntVal LShr(uint64 shift, PrimType pType) const { + IntVal ret = TruncOrExtend(pType); + + ASSERT(shift <= ret.width, "invalid shift value"); + ret.value >>= shift; + + return ret; + } + + // arithmetic right-shift operators (MSB is sign extended) + IntVal AShr(const IntVal &shift, PrimType pType) const { + return AShr(shift.value, pType); + } + + IntVal AShr(uint64 shift, PrimType pType) const { + IntVal ret = TruncOrExtend(pType); + + ASSERT(shift <= ret.width, "invalid shift value"); + ret.value = ret.GetSXTValue() >> shift; + ret.TruncInPlace(); + + return ret; + } + + /// @brief invert all bits of value + IntVal operator~() const { + return IntVal(~value, width, sign); + } + + /// @return negated value + IntVal operator-() const { + return IntVal(~value + 1, width, sign); + } + + /// @brief truncate value to the given bit-width in-place. + /// @note if bitWidth is not passed (or zero), the original + /// bit-width is preserved and the value is truncated to the original bit-width + void TruncInPlace(uint8 bitWidth = 0) { + ASSERT(valBitSize >= bitWidth, "invalid bit-width for truncate"); + + value &= allOnes >> (valBitSize - (bitWidth ? bitWidth : width)); + + if (bitWidth) { + width = bitWidth; + } + } + + /// @return truncated value to the given bit-width + /// @note returned value will have bit-width and sign obtained from newType + IntVal Trunc(PrimType newType) const { + return Trunc(GetPrimTypeActualBitSize(newType), IsSignedInteger(newType)); + } + + /// @return sign or zero extended value depending on its signedness + /// @note returned value will have bit-width and sign obtained from newType + IntVal Extend(PrimType newType) const { + return Extend(GetPrimTypeActualBitSize(newType), IsSignedInteger(newType)); + } + + /// @return sign/zero extended value or truncated value depending on bit-width + /// @note returned value will have bit-width and sign obtained from newType + IntVal TruncOrExtend(PrimType newType) const { + return TruncOrExtend(GetPrimTypeActualBitSize(newType), IsSignedInteger(newType)); + } + + IntVal TruncOrExtend(uint8 newWidth, bool isSigned) const { + return newWidth <= width ? Trunc(newWidth, isSigned) : Extend(newWidth, isSigned); + } + + private: + bool GetBit(uint8 bit) const { + ASSERT(bit < width, "Required bit is out of value range"); + return (value & (uint64(1) << bit)) != 0; + } + + IntVal Trunc(uint8 newWidth, bool isSigned) const { + return { value, newWidth, isSigned }; + } + + IntVal Extend(uint8 newWidth, bool isSigned) const { + ASSERT(newWidth > width, "invalid size for extension"); + return IntVal(GetExtValue(), newWidth, isSigned); + } + + static constexpr uint8 valBitSize = sizeof(uint64) * CHAR_BIT; + static constexpr uint64 allOnes = uint64(~0); + + uint64 value; + uint8 width; + bool sign; +}; + +// +// Additional comparison operators +// +inline bool operator==(const IntVal &v1, int64 v2) { + return v1.GetExtValue() == v2; +} + +inline bool operator==(int64 v1, const IntVal &v2) { + return v2 == v1; +} + +inline bool operator!=(const IntVal &v1, int64 v2) { + return !(v1 == v2); +} + +inline bool operator!=(int64 v1, const IntVal &v2) { + return !(v2 == v1); +} + +/// @return the smaller of two values +/// @note bit-width and sign must be the same for both parameters +inline IntVal Min(const IntVal &a, const IntVal &b) { + return a < b ? a : b; +} + +/// @return the smaller of two values in terms of newType +/// @note returned value will have bit-width and sign obtained from newType +inline IntVal Min(const IntVal &a, const IntVal &b, PrimType newType) { + return a.Less(b, newType) ? IntVal(a, newType) : IntVal(b, newType); +} + +/// @return the larger of two values +/// @note bit-width and sign must be the same for both parameters +inline IntVal Max(const IntVal &a, const IntVal &b) { + return Min(a, b) == a ? b : a; +} + +/// @return the larger of two values in terms of newType +/// @note returned value will have bit-width and sign obtained from newType +inline IntVal Max(const IntVal &a, const IntVal &b, PrimType newType) { + return Min(a, b, newType) == a ? b : a; +} + +/// @brief dump IntVal object to the output stream +std::ostream &operator<<(std::ostream &os, const IntVal &value); + +// +// Arithmetic operators that manipulate on scalar (uint64) value and IntVal object +// in terms of sign and bit-width of IntVal object +// +inline IntVal operator+(const IntVal &v1, uint64 v2) { + return v1 + IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator+(uint64 v1, const IntVal& v2) { + return v2 + v1; +} + +inline IntVal operator-(const IntVal &v1, uint64 v2) { + return v1 - IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator-(uint64 v1, const IntVal &v2) { + return IntVal(v1, v2.GetBitWidth(), v2.IsSigned()) - v2; +} + +inline IntVal operator*(const IntVal &v1, uint64 v2) { + return v1 * IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator*(uint64 v1, const IntVal& v2) { + return v2 * v1; +} + +inline IntVal operator/(const IntVal &v1, uint64 v2) { + return v1 / IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator/(uint64 v1, const IntVal& v2) { + return IntVal(v1, v2.GetBitWidth(), v2.IsSigned()) / v2; +} + +inline IntVal operator%(const IntVal &v1, uint64 v2) { + return v1 % IntVal(v2, v1.GetBitWidth(), v1.IsSigned()); +} + +inline IntVal operator%(uint64 v1, const IntVal& v2) { + return IntVal(v1, v2.GetBitWidth(), v2.IsSigned()) % v2; +} + +} // namespace maple + +#endif // MAPLE_UTIL_INCLUDE_MPL_INT_VAL_H diff --git a/src/mapleall/maple_util/src/mpl_int_val.cpp b/src/mapleall/maple_util/src/mpl_int_val.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ce246cb4740317e8b165ecf757968d6845b2b3c --- /dev/null +++ b/src/mapleall/maple_util/src/mpl_int_val.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) [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 "mpl_int_val.h" + +namespace maple { + +IntVal IntVal::operator/(const IntVal &divisor) const { + ASSERT(width == divisor.width && sign == divisor.sign, "bit-width and sign must be the same"); + ASSERT(divisor.value != 0, "division by zero"); + ASSERT(!sign || (!IsMinValue() || !divisor.AreAllBitsOne()), "minValue / -1 leads to overflow"); + + bool isNeg = sign && GetSignBit(); + bool isDivisorNeg = divisor.sign && divisor.GetSignBit(); + + uint64 dividendVal = isNeg ? (-*this).value : value; + uint64 divisorVal = isDivisorNeg ? (-divisor).value : divisor.value; + + return isNeg != isDivisorNeg ? -IntVal(dividendVal / divisorVal, width, sign) + : IntVal(dividendVal / divisorVal, width, sign); +} + +IntVal IntVal::operator%(const IntVal &divisor) const { + ASSERT(width == divisor.width && sign == divisor.sign, "bit-width and sign must be the same"); + ASSERT(divisor.value != 0, "division by zero"); + ASSERT(!sign || (!IsMinValue() || !divisor.AreAllBitsOne()), "minValue % -1 leads to overflow"); + + bool isNeg = sign && GetSignBit(); + bool isDivisorNeg = divisor.sign && divisor.GetSignBit(); + + uint64 dividendVal = isNeg ? (-*this).value : value; + uint64 divisorVal = isDivisorNeg ? (-divisor).value : divisor.value; + + return isNeg ? -IntVal(dividendVal % divisorVal, width, sign) : IntVal(dividendVal % divisorVal, width, sign); +} + +std::ostream &operator<<(std::ostream &os, const IntVal &value) { + int64 val = value.GetExtValue(); + constexpr int64 valThreshold = 1024; + + if (val <= valThreshold) { + os << val; + } else { + os << std::hex << "0x" << val << std::dec; + } + + return os; +} + +} // namespace maple \ No newline at end of file diff --git a/src/mapleall/mpl2mpl/include/constantfold.h b/src/mapleall/mpl2mpl/include/constantfold.h index 9f12b71937fc582c49165f37c9a148eeafb0b894..21a6e330a9932a4f242f2f0ed4c688d224ab5cbd 100644 --- a/src/mapleall/mpl2mpl/include/constantfold.h +++ b/src/mapleall/mpl2mpl/include/constantfold.h @@ -18,6 +18,8 @@ #include "phase_impl.h" #include "me_verify.h" +#include + namespace maple { class ConstantFold : public FuncOptimizeImpl { public: @@ -50,7 +52,7 @@ class ConstantFold : public FuncOptimizeImpl { MIRConst *FoldFloorMIRConst(const MIRConst&, PrimType, PrimType, bool isFloor = true) const; MIRConst *FoldRoundMIRConst(const MIRConst&, PrimType, PrimType) const; MIRConst *FoldTypeCvtMIRConst(const MIRConst&, PrimType, PrimType) const; - MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const MIRConst&) const; + MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const IntVal&) const; MIRConst *FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *intConst0, const MIRIntConst *intConst1) const; MIRConst *FoldConstComparisonMIRConst(Opcode, PrimType, PrimType, const MIRConst&, const MIRConst&); @@ -70,20 +72,20 @@ class ConstantFold : public FuncOptimizeImpl { StmtNode *SimplifyUnary(UnaryStmtNode *node); StmtNode *SimplifyAsm(AsmNode* node); StmtNode *SimplifyWhile(WhileStmtNode *node); - std::pair FoldArray(ArrayNode *node); - std::pair FoldBase(BaseNode *node) const; - std::pair FoldBinary(BinaryNode *node); - std::pair FoldCompare(CompareNode *node); - std::pair FoldDepositbits(DepositbitsNode *node); - std::pair FoldExtractbits(ExtractbitsNode *node); + std::pair> FoldArray(ArrayNode *node); + std::pair> FoldBase(BaseNode *node) const; + std::pair> FoldBinary(BinaryNode *node); + std::pair> FoldCompare(CompareNode *node); + std::pair> FoldDepositbits(DepositbitsNode *node); + std::pair> FoldExtractbits(ExtractbitsNode *node); ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const; - std::pair FoldIread(IreadNode *node); - std::pair FoldSizeoftype(SizeoftypeNode *node) const; - std::pair FoldRetype(RetypeNode *node); - std::pair FoldGcmallocjarray(JarrayMallocNode *node); - std::pair FoldUnary(UnaryNode *node); - std::pair FoldTernary(TernaryNode *node); - std::pair FoldTypeCvt(TypeCvtNode *node); + std::pair> FoldIread(IreadNode *node); + std::pair> FoldSizeoftype(SizeoftypeNode *node) const; + std::pair> FoldRetype(RetypeNode *node); + std::pair> FoldGcmallocjarray(JarrayMallocNode *node); + std::pair> FoldUnary(UnaryNode *node); + std::pair> FoldTernary(TernaryNode *node); + std::pair> FoldTypeCvt(TypeCvtNode *node); ConstvalNode *FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; ConstvalNode *FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; ConstvalNode *FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; @@ -122,8 +124,8 @@ class ConstantFold : public FuncOptimizeImpl { BaseNode *Negate(const ConstvalNode *node) const; BinaryNode *NewBinaryNode(BinaryNode *old, Opcode op, PrimType primeType, BaseNode *lhs, BaseNode *rhs) const; UnaryNode *NewUnaryNode(UnaryNode *old, Opcode op, PrimType primeType, BaseNode *expr) const; - std::pair DispatchFold(BaseNode *node); - BaseNode *PairToExpr(PrimType resultType, const std::pair &pair) const; + std::pair> DispatchFold(BaseNode *node); + BaseNode *PairToExpr(PrimType resultType, const std::pair> &pair) const; BaseNode *SimplifyDoubleCompare(CompareNode &node) const; CompareNode *FoldConstComparisonReverse(Opcode opcode, PrimType resultType, PrimType opndType, BaseNode &l, BaseNode &r); diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index 7a2990c7c8f93df34b2523201f9652d3477632a8..e609b04e817968539dbc14dc9202979d283bc5c4 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -682,7 +682,7 @@ void CallGraph::HandleICall(BlockNode &body, CGNode &node, StmtNode *stmt, uint3 MIRConst *result = aggConst; for (size_t i = 1; i < arrayNode->GetNumOpnds(); ++i) { auto *konst = static_cast(arrayNode->GetNopndAt(i))->GetConstVal(); - auto index = static_cast(konst)->GetValue(); + auto index = static_cast(konst)->GetExtValue(); if (result->GetKind() == kConstAggConst) { result = static_cast(result)->GetConstVecItem(index); } diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f436afb2cee12a188d326bb7b5d81a1e7eb68c7e..512808c98404b219863e4b6d661847f6f1649878 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -24,20 +24,63 @@ #include "me_option.h" #include "maple_phase_manager.h" +namespace maple { + namespace { -constexpr maple::uint64 kJsTypeNumber = 4; -constexpr maple::uint64 kJsTypeNumberInHigh32Bit = kJsTypeNumber << 32; // set high 32 bit as JSTYPE_NUMBER -constexpr maple::uint32 kByteSizeOfBit64 = 8; // byte number for 64 bit -constexpr maple::uint32 kBitSizePerByte = 8; + +constexpr uint64 kJsTypeNumber = 4; +constexpr uint64 kJsTypeNumberInHigh32Bit = kJsTypeNumber << 32; // set high 32 bit as JSTYPE_NUMBER +constexpr uint32 kByteSizeOfBit64 = 8; // byte number for 64 bit +constexpr uint32 kBitSizePerByte = 8; constexpr maple::int32 kMaxOffset = INT_MAX - 8; -enum CompareRes : maple::int64 { + +enum CompareRes : int64 { kLess = -1, kEqual = 0, kGreater = 1 }; + +std::optional operator*(const std::optional &v1, const std::optional &v2) { + if (!v1 && !v2) { + return std::nullopt; + } + + // Perform all calculations in terms of the maximum available signed type. + // The value will be truncated for an appropriate type when constant is created in PariToExpr function + // TODO: replace with PTY_i128 when IntVal supports 128bit calculation + return v1 && v2 ? v1->Mul(*v2, PTY_i64) : IntVal(0, PTY_i64); } -namespace maple { +// Perform all calculations in terms of the maximum available signed type. +// The value will be truncated for an appropriate type when constant is created in PariToExpr function +// TODO: replace with PTY_i128 when IntVal supports 128bit calculation +std::optional AddSub(const std::optional &v1, const std::optional &v2, bool isAdd) { + if (!v1 && !v2) { + return std::nullopt; + } + + if (v1 && v2) { + return isAdd ? v1->Add(*v2, PTY_i64) : v1->Sub(*v2, PTY_i64); + } + + if (v1) { + return v1->TruncOrExtend(PTY_i64); + } + + // !v1 && v2 + return isAdd ? v2->TruncOrExtend(PTY_i64) : -(v2->TruncOrExtend(PTY_i64)); +} + +std::optional operator+(const std::optional &v1, const std::optional &v2) { + return AddSub(v1, v2, true); +} + +std::optional operator-(const std::optional &v1, const std::optional &v2) { + return AddSub(v1, v2, false); +} + +} // anonymous namespace + // This phase is designed to achieve compiler optimization by // simplifying constant expressions. The constant expression // is evaluated and replaced by the value calculated on compile @@ -87,33 +130,34 @@ UnaryNode *ConstantFold::NewUnaryNode(UnaryNode *old, Opcode op, PrimType primTy return result; } -BaseNode *ConstantFold::PairToExpr(PrimType resultType, const std::pair &pair) const { +BaseNode *ConstantFold::PairToExpr(PrimType resultType, const std::pair> &pair) const { CHECK_NULL_FATAL(pair.first); BaseNode *result = pair.first; - if (pair.second == 0) { + if (!pair.second || *pair.second == 0) { return result; } - if (pair.first->GetOpCode() == OP_neg && pair.second > 0) { + if (pair.first->GetOpCode() == OP_neg && !pair.second->GetSignBit()) { // -a, 5 -> 5 - a - ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst(pair.second, resultType); + ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst(pair.second->GetExtValue(), resultType); BaseNode *r = static_cast(pair.first)->Opnd(0); result = mirModule->CurFuncCodeMemPool()->New(OP_sub, resultType, val, r); } else { - if (pair.second > 0 || pair.second == LLONG_MIN) { + if ((!pair.second->GetSignBit() && pair.second->GetSXTValue(GetPrimTypeBitSize(resultType)) > 0) || + pair.second->GetSXTValue() == INT64_MIN) { // +-a, 5 -> a + 5 - ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst(pair.second, resultType); + ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst(pair.second->GetExtValue(), resultType); result = mirModule->CurFuncCodeMemPool()->New(OP_add, resultType, pair.first, val); } else { // +-a, -5 -> a + -5 - ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst(-pair.second, resultType); + ConstvalNode *val = mirModule->GetMIRBuilder()->CreateIntConst((-pair.second.value()).GetExtValue(), resultType); result = mirModule->CurFuncCodeMemPool()->New(OP_sub, resultType, pair.first, val); } } return result; } -std::pair ConstantFold::FoldBase(BaseNode *node) const { - return std::make_pair(node, 0); +std::pair> ConstantFold::FoldBase(BaseNode *node) const { + return std::make_pair(node, std::nullopt); } StmtNode *ConstantFold::Simplify(StmtNode *node) { @@ -189,7 +233,7 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { } } -std::pair ConstantFold::DispatchFold(BaseNode *node) { +std::pair> ConstantFold::DispatchFold(BaseNode *node) { CHECK_NULL_FATAL(node); switch (node->GetOpCode()) { case OP_sizeoftype: @@ -295,138 +339,44 @@ BaseNode *ConstantFold::NegateTree(BaseNode *node) const { MIRIntConst *ConstantFold::FoldIntConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType, const MIRIntConst &intConst0, const MIRIntConst &intConst1) const { - int64 result = 0; - bool greater = (intConst0.GetValue() > intConst1.GetValue()); - bool equal = (intConst0.GetValue() == intConst1.GetValue()); - bool less = (intConst0.GetValue() < intConst1.GetValue()); - constexpr uint32 eightBytes = 8; - bool use64 = GetPrimTypeSize(opndType) == eightBytes; + uint64 result = 0; + + bool greater = intConst0.GetValue().Greater(intConst1.GetValue(), opndType); + bool equal = intConst0.GetValue().Equal(intConst1.GetValue(), opndType); + bool less = intConst0.GetValue().Less(intConst1.GetValue(), opndType); + switch (opcode) { case OP_eq: { - if (use64) { - result = equal; - } else { - result = static_cast(intConst0.GetValue()) == static_cast(intConst1.GetValue()); - } + result = equal; break; } case OP_ge: { - if (IsUnsignedInteger(opndType)) { - if (use64) { - result = static_cast(intConst0.GetValue()) >= static_cast(intConst1.GetValue()); - } else { - result = static_cast(intConst0.GetValue()) >= static_cast(intConst1.GetValue()); - } - } else { - if (use64) { - result = (greater || equal); - } else { - result = static_cast(intConst0.GetValue()) >= static_cast(intConst1.GetValue()); - } - } + result = greater || equal; break; } case OP_gt: { - if (IsUnsignedInteger(opndType)) { - if (use64) { - result = static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue()); - } else { - result = static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue()); - } - } else { - if (use64) { - result = greater; - } else { - result = static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue()); - } - } + result = greater; break; } case OP_le: { - if (IsUnsignedInteger(opndType)) { - if (use64) { - result = static_cast(intConst0.GetValue()) <= static_cast(intConst1.GetValue()); - } else { - result = static_cast(intConst0.GetValue()) <= static_cast(intConst1.GetValue()); - } - } else { - if (use64) { - result = (less || equal); - } else { - result = static_cast(intConst0.GetValue()) <= static_cast(intConst1.GetValue()); - } - } + result = less || equal; break; } case OP_lt: { - if (IsUnsignedInteger(opndType)) { - if (use64) { - result = static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue()); - } else { - result = static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue()); - } - } else { - if (use64) { - result = less; - } else { - result = static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue()); - } - } + result = less; break; } case OP_ne: { - if (use64) { - result = !equal; - } else { - result = static_cast(intConst0.GetValue()) != static_cast(intConst1.GetValue()); - } + result = !equal; break; } case OP_cmp: { - if (IsUnsignedInteger(opndType)) { - if (use64) { - if (static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue())) { - result = kGreater; - } - if (static_cast(intConst0.GetValue()) == static_cast(intConst1.GetValue())) { - result = kEqual; - } - if (static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue())) { - result = kLess; - } - } else { - if (static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue())) { - result = kGreater; - } - if (static_cast(intConst0.GetValue()) == static_cast(intConst1.GetValue())) { - result = kEqual; - } - if (static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue())) { - result = kLess; - } - } - } else { - if (use64) { - if (intConst0.GetValue() > intConst1.GetValue()) { - result = kGreater; - } - if (intConst0.GetValue() == intConst1.GetValue()) { - result = kEqual; - } - if (intConst0.GetValue() < intConst1.GetValue()) { - result = kLess; - } - } else { - if (static_cast(intConst0.GetValue()) > static_cast(intConst1.GetValue())) { - result = kGreater; - } - if (static_cast(intConst0.GetValue()) == static_cast(intConst1.GetValue())) { - result = kEqual; - } - if (static_cast(intConst0.GetValue()) < static_cast(intConst1.GetValue())) { - result = kLess; - } - } + if (greater) { + result = kGreater; + } else if (equal) { + result = kEqual; + } else if (less) { + result = kLess; } break; } @@ -440,7 +390,7 @@ MIRIntConst *ConstantFold::FoldIntConstComparisonMIRConst(Opcode opcode, PrimTyp MIRIntConst *constValue = nullptr; if (type.GetPrimType() == PTY_dyni32) { constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, type); - constValue->SetValue(kJsTypeNumberInHigh32Bit | (static_cast(result))); + constValue->SetValue(kJsTypeNumberInHigh32Bit | result); } else { constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result, type); } @@ -463,172 +413,71 @@ ConstvalNode *ConstantFold::FoldIntConstComparison(Opcode opcode, PrimType resul MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *intConst0, const MIRIntConst *intConst1) const { - int64 intValueOfConst0 = intConst0->GetValue(); - int64 intValueOfConst1 = intConst1->GetValue(); - uint64 result64 = 0; - uint32 result32 = 0; - bool useResult64 = (GetPrimTypeSize(resultType) == kByteSizeOfBit64); + IntVal intVal0 = intConst0->GetValue(); + IntVal intVal1 = intConst1->GetValue(); + IntVal result(0, resultType); + switch (opcode) { case OP_add: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) + static_cast(intValueOfConst1); - } + result = intVal0.Add(intVal1, resultType); break; } case OP_sub: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) - static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) - static_cast(intValueOfConst1); - } + result = intVal0.Sub(intVal1, resultType); break; } case OP_mul: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) * static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) * static_cast(intValueOfConst1); - } + result = intVal0.Mul(intVal1, resultType); break; } case OP_div: { - if (IsUnsignedInteger(resultType)) { - if (useResult64) { - result64 = static_cast(intValueOfConst0) / static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) / static_cast(intValueOfConst1); - } - } else { - if (useResult64) { - result64 = static_cast(intValueOfConst0 / intValueOfConst1); - } else { - result32 = static_cast(static_cast(intValueOfConst0) / static_cast(intValueOfConst1)); - } - } + result = intVal0.Div(intVal1, resultType); break; } case OP_rem: { - if (IsUnsignedInteger(resultType)) { - if (useResult64) { - result64 = static_cast(intValueOfConst0) % static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) % static_cast(intValueOfConst1); - } - } else { - if (useResult64) { - result64 = static_cast(intValueOfConst0 % intValueOfConst1); - } else { - result32 = static_cast(static_cast(intValueOfConst0) % static_cast(intValueOfConst1)); - } - } + result = intVal0.Rem(intVal1, resultType); break; } case OP_ashr: { - if (useResult64) { - result64 = intValueOfConst0 >> static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) >> static_cast(intValueOfConst1); - } + result = intVal0.AShr(intVal1.GetZXTValue() % GetPrimTypeBitSize(resultType), resultType); break; } case OP_lshr: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) >> static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) >> static_cast(intValueOfConst1); - } + result = intVal0.LShr(intVal1.GetZXTValue() % GetPrimTypeBitSize(resultType), resultType); break; } case OP_shl: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) << static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) << static_cast(intValueOfConst1); - } + result = intVal0.Shl(intVal1.GetZXTValue() % GetPrimTypeBitSize(resultType), resultType); break; } case OP_max: { - if (IsUnsignedInteger(resultType)) { - if (useResult64) { - result64 = (static_cast(intValueOfConst0) >= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } else { - result32 = (static_cast(intValueOfConst0) >= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } - } else { - if (useResult64) { - result64 = (intValueOfConst0 >= intValueOfConst1) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } else { - result32 = (static_cast(intValueOfConst0) >= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } - } + result = Max(intVal0, intVal1, resultType); break; } case OP_min: { - if (IsUnsignedInteger(resultType)) { - if (useResult64) { - result64 = (static_cast(intValueOfConst0) <= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } else { - result32 = (static_cast(intValueOfConst0) <= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } - } else { - if (useResult64) { - result64 = (intValueOfConst0 <= intValueOfConst1) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } else { - result32 = (static_cast(intValueOfConst0) <= static_cast(intValueOfConst1)) ? - static_cast(intValueOfConst0) : static_cast(intValueOfConst1); - } - } + result = Min(intVal0, intVal1, resultType); break; } case OP_band: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) & static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) & static_cast(intValueOfConst1); - } + result = intVal0.And(intVal1, resultType); break; } case OP_bior: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) | static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) | static_cast(intValueOfConst1); - } + result = intVal0.Or(intVal1, resultType); break; } case OP_bxor: { - if (useResult64) { - result64 = static_cast(intValueOfConst0) ^ static_cast(intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0) ^ static_cast(intValueOfConst1); - } + result = intVal0.Xor(intVal1, resultType); break; } case OP_cand: case OP_land: { - if (useResult64) { - result64 = static_cast(intValueOfConst0 && intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0 && intValueOfConst1); - } + result = IntVal(intVal0.GetExtValue() && intVal1.GetExtValue(), resultType); break; } case OP_cior: case OP_lior: { - if (useResult64) { - result64 = static_cast(intValueOfConst0 || intValueOfConst1); - } else { - result32 = static_cast(intValueOfConst0 || intValueOfConst1); - } + result = IntVal(intVal0.GetExtValue() || intVal1.GetExtValue(), resultType); break; } case OP_depositbits: { @@ -646,12 +495,9 @@ MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resul MIRIntConst *constValue = nullptr; if (type.GetPrimType() == PTY_dyni32) { constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, type); - constValue->SetValue(kJsTypeNumberInHigh32Bit | (static_cast(result32))); - } else if (useResult64) { - constValue = - GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(result64), type); + constValue->SetValue(kJsTypeNumberInHigh32Bit | result.GetExtValue()); } else { - constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result32, type); + constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result.GetExtValue(), type); } return constValue; } @@ -960,49 +806,24 @@ ConstvalNode *ConstantFold::FoldIntConstUnary(Opcode opcode, PrimType resultType CHECK_NULL_FATAL(constNode); const MIRIntConst *cst = safe_cast(constNode->GetConstVal()); ASSERT_NOT_NULL(cst); - uint32 result32 = 0; - uint64 result64 = 0; - bool useResult64 = (GetPrimTypeSize(resultType) == kByteSizeOfBit64); + IntVal result = cst->GetValue().TruncOrExtend(resultType); switch (opcode) { case OP_abs: { - if (IsUnsignedInteger(resultType)) { - if (useResult64) { - result64 = static_cast(cst->GetValue()); - } else { - result32 = static_cast(cst->GetValue()); - } - } else { - if (useResult64) { - result64 = (cst->GetValue() >= 0) ? cst->GetValue() : -cst->GetValue(); - } else { - result32 = (static_cast(cst->GetValue()) >= 0) ? - cst->GetValue() : -static_cast(cst->GetValue()); - } + if (result.IsSigned() && result.GetSignBit()) { + result = -result; } break; } case OP_bnot: { - if (useResult64) { - result64 = ~static_cast(cst->GetValue()); - } else { - result32 = ~static_cast(cst->GetValue()); - } + result = ~result; break; } case OP_lnot: { - if (useResult64) { - result64 = cst->GetValue() == 0; - } else { - result32 = static_cast(cst->GetValue()) == 0; - } + result = { result == 0, resultType }; break; } case OP_neg: { - if (useResult64) { - result64 = -cst->GetValue(); - } else { - result32 = static_cast(-(cst->GetValue())); - } + result = -result; break; } case OP_sext: // handled in FoldExtractbits @@ -1023,12 +844,9 @@ ConstvalNode *ConstantFold::FoldIntConstUnary(Opcode opcode, PrimType resultType MIRIntConst *constValue = nullptr; if (type.GetPrimType() == PTY_dyni32) { constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, type); - constValue->SetValue(kJsTypeNumberInHigh32Bit | (static_cast(result32))); - } else if (useResult64) { - constValue = - GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(result64), type); + constValue->SetValue(kJsTypeNumberInHigh32Bit | result.GetExtValue()); } else { - constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result32, type); + constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result.GetExtValue(), type); } // form the ConstvalNode ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); @@ -1096,7 +914,7 @@ ConstvalNode *ConstantFold::FoldConstUnary(Opcode opcode, PrimType resultType, C return returnValue; } -std::pair ConstantFold::FoldSizeoftype(SizeoftypeNode *node) const { +std::pair> ConstantFold::FoldSizeoftype(SizeoftypeNode *node) const { CHECK_NULL_FATAL(node); BaseNode *result = node; MIRType *argType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(node->GetTyIdx()); @@ -1105,48 +923,46 @@ std::pair ConstantFold::FoldSizeoftype(SizeoftypeNode *node) c uint32 size = GetPrimTypeSize(argType->GetPrimType()); ConstvalNode *constValueNode = mirModule->CurFuncCodeMemPool()->New(); constValueNode->SetPrimType(node->GetPrimType()); - constValueNode->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(size), resultType)); + constValueNode->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst(size, resultType)); result = constValueNode; } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldRetype(RetypeNode *node) { +std::pair> ConstantFold::FoldRetype(RetypeNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = node; - std::pair p = DispatchFold(node->Opnd(0)); + std::pair> p = DispatchFold(node->Opnd(0)); if (node->Opnd(0) != p.first) { RetypeNode *newRetNode = node->CloneTree(mirModule->GetCurFuncCodeMPAllocator()); CHECK_FATAL(newRetNode != nullptr, "newRetNode is null in ConstantFold::FoldRetype"); newRetNode->SetOpnd(PairToExpr(node->Opnd(0)->GetPrimType(), p), 0); result = newRetNode; } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldGcmallocjarray(JarrayMallocNode *node) { +std::pair> ConstantFold::FoldGcmallocjarray(JarrayMallocNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = node; - std::pair p = DispatchFold(node->Opnd(0)); + std::pair> p = DispatchFold(node->Opnd(0)); if (node->Opnd(0) != p.first) { JarrayMallocNode *newRetNode = node->CloneTree(mirModule->GetCurFuncCodeMPAllocator()); CHECK_FATAL(newRetNode != nullptr, "newRetNode is null in ConstantFold::FoldGcmallocjarray"); newRetNode->SetOpnd(PairToExpr(node->Opnd(0)->GetPrimType(), p), 0); result = newRetNode; } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldUnary(UnaryNode *node) { +std::pair> ConstantFold::FoldUnary(UnaryNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; - int64 sum = 0; - std::pair p = DispatchFold(node->Opnd(0)); + std::optional sum = std::nullopt; + std::pair> p = DispatchFold(node->Opnd(0)); ConstvalNode *cst = safe_cast(p.first); if (cst != nullptr) { result = FoldConstUnary(node->GetOpCode(), node->GetPrimType(), cst); - sum = 0; } else { bool isInt = IsPrimitiveInteger(node->GetPrimType()); // The neg node will be recreated regardless of whether the folding is successful or not. And the neg node's @@ -1170,16 +986,17 @@ std::pair ConstantFold::FoldUnary(UnaryNode *node) { } else { if (GetPrimTypeSize(newPtyp) != GetPrimTypeSize(origPtyp)) { // do not fold explicit cvt - return std::make_pair(node, 0); + return std::make_pair(node, std::nullopt); } else { result->SetPrimType(origPtyp); } } } - sum = -p.second; + if (p.second) { + sum = -(*p.second); + } } else { result = NewUnaryNode(node, node->GetOpCode(), node->GetPrimType(), PairToExpr(node->Opnd(0)->GetPrimType(), p)); - sum = 0; } } return std::make_pair(result, sum); @@ -1322,13 +1139,13 @@ MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst &cst, PrimType fromType } else if (toType == PTY_f32 && IsPrimitiveInteger(fromType)) { const auto &constValue = static_cast(cst); if (IsSignedInteger(fromType)) { - int64 fromValue = constValue.GetValue(); + int64 fromValue = constValue.GetExtValue(); float floatValue = round(static_cast(fromValue)); if (static_cast(floatValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue); } } else { - uint64 fromValue = static_cast(constValue.GetValue()); + uint64 fromValue = constValue.GetExtValue(); float floatValue = round(static_cast(fromValue)); if (static_cast(floatValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue); @@ -1337,13 +1154,13 @@ MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst &cst, PrimType fromType } else if (toType == PTY_f64 && IsPrimitiveInteger(fromType)) { const auto &constValue = static_cast(cst); if (IsSignedInteger(fromType)) { - int64 fromValue = constValue.GetValue(); + int64 fromValue = constValue.GetExtValue(); double doubleValue = round(static_cast(fromValue)); if (static_cast(doubleValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); } } else { - uint64 fromValue = static_cast(constValue.GetValue()); + uint64 fromValue = constValue.GetExtValue(); double doubleValue = round(static_cast(fromValue)); if (static_cast(doubleValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); @@ -1407,13 +1224,15 @@ MIRConst *ConstantFold::FoldTypeCvtMIRConst(const MIRConst &cst, PrimType fromTy if (IsSignedInteger(fromType)) { op = OP_sext; } - toConst = FoldSignExtendMIRConst(op, toType, fromSize, cst); + const MIRIntConst *constVal = safe_cast(cst); + ASSERT_NOT_NULL(constVal); + toConst = FoldSignExtendMIRConst(op, toType, fromSize, constVal->GetValue().TruncOrExtend(fromType)); } else { const MIRIntConst *constVal = safe_cast(cst); ASSERT_NOT_NULL(constVal); MIRType &type = *GlobalTables::GetTypeTable().GetPrimType(toType); toConst = - GlobalTables::GetIntConstTable().GetOrCreateIntConst(constVal->GetValue(), type); + GlobalTables::GetIntConstTable().GetOrCreateIntConst(constVal->GetExtValue(), type); } return toConst; } @@ -1568,10 +1387,10 @@ PrimType GetExprValueRangePtyp(BaseNode *expr) { return GetNearestSizePtyp(maxTypeSize, ptyp); } -std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { +std::pair> ConstantFold::FoldTypeCvt(TypeCvtNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; - std::pair p = DispatchFold(node->Opnd(0)); + std::pair> p = DispatchFold(node->Opnd(0)); ConstvalNode *cst = safe_cast(p.first); PrimType destPtyp = node->GetPrimType(); PrimType fromPtyp = node->FromType(); @@ -1606,9 +1425,11 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { (IsPossible32BitAddress(fromPtyp) && IsPossible32BitAddress(destPtyp)) || (IsPrimitivePureScalar(fromPtyp) && IsPrimitivePureScalar(destPtyp) && GetPrimTypeSize(fromPtyp) == GetPrimTypeSize(destPtyp))) { - return p; // the cvt is redundant + // the cvt is redundant + return std::make_pair(p.first, p.second ? IntVal(*p.second, node->GetPrimType()) : p.second); } - } else if (node->GetOpCode() == OP_cvt && p.second != 0 && p.second < INT_MAX && (p.second > -kMaxOffset) && + } else if (node->GetOpCode() == OP_cvt && p.second.has_value() && *p.second != 0 && + p.second->GetExtValue() < INT_MAX && p.second->GetSXTValue() > -kMaxOffset && IsPrimitiveInteger(node->GetPrimType()) && IsSignedInteger(node->FromType()) && GetPrimTypeSize(node->GetPrimType()) > GetPrimTypeSize(node->FromType())) { bool simplifyCvt = false; @@ -1628,7 +1449,7 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { // constVal value range : [I32_MIN - I16MIN, I32_MAX - I16_MAX], (i + constVal) will never pos/neg overflow. PrimType valuePtyp = GetExprValueRangePtyp(p.first); PrimType exprPtyp = p.first->GetPrimType(); - int64 constVal = p.second; + int64 constVal = p.second->GetExtValue(); // cannot only check (min <= constval && constval <= max) here. // If constval = -1, it will be SIZE_T_MAX when converted to size_t if ((constVal < 0 && constVal >= GetIntPrimTypeMin(exprPtyp) - GetIntPrimTypeMin(valuePtyp)) || @@ -1640,10 +1461,7 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { if (simplifyCvt) { result = mirModule->CurFuncCodeMemPool()->New(OP_cvt, node->GetPrimType(), node->FromType(), p.first); - if (IsUnsignedInteger(p.first->GetPrimType())) { - p.second = static_cast(p.second); - } - return std::make_pair(result, p.second); + return std::make_pair(result, p.second->TruncOrExtend(node->GetPrimType())); } } if (result == nullptr) { @@ -1656,29 +1474,25 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { result = node; } } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } MIRConst *ConstantFold::FoldSignExtendMIRConst(Opcode opcode, PrimType resultType, uint8 size, - const MIRConst &cst) const { - const MIRIntConst *constVal = safe_cast(cst); - ASSERT_NOT_NULL(constVal); - uint64 result64 = 0; - if (opcode == OP_sext) { - result64 = (constVal->GetValue() << (64u - size)) >> (64u - size); - } else { - result64 = ((static_cast(constVal->GetValue())) << (64u - size)) >> (64u - size); - } + const IntVal &val) const { + uint64 result = opcode == OP_sext ? val.GetSXTValue(size) : val.GetZXTValue(size); MIRType &type = *GlobalTables::GetTypeTable().GetPrimType(resultType); MIRIntConst *constValue = - GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(result64), type); + GlobalTables::GetIntConstTable().GetOrCreateIntConst(result, type); return constValue; } ConstvalNode *ConstantFold::FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); - MIRConst *toConst = FoldSignExtendMIRConst(opcode, resultType, size, *cst.GetConstVal()); + const auto* intCst = safe_cast(cst.GetConstVal()); + ASSERT_NOT_NULL(intCst); + IntVal val = intCst->GetValue().TruncOrExtend(size, opcode == OP_sext); + MIRConst *toConst = FoldSignExtendMIRConst(opcode, resultType, size, val); resultConst->SetPrimType(toConst->GetType().GetPrimType()); resultConst->SetConstVal(toConst); return resultConst; @@ -1725,17 +1539,17 @@ static bool ExtractbitsRedundant(ExtractbitsNode *x, MIRFunction *f) { } // sext and zext also handled automatically -std::pair ConstantFold::FoldExtractbits(ExtractbitsNode *node) { +std::pair> ConstantFold::FoldExtractbits(ExtractbitsNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; uint8 offset = node->GetBitsOffset(); uint8 size = node->GetBitsSize(); Opcode opcode = node->GetOpCode(); - std::pair p = DispatchFold(node->Opnd(0)); + std::pair> p = DispatchFold(node->Opnd(0)); ConstvalNode *cst = safe_cast(p.first); if (cst != nullptr && (opcode == OP_sext || opcode == OP_zext)) { result = FoldSignExtend(opcode, node->GetPrimType(), size, *cst); - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } BaseNode *e = PairToExpr(node->Opnd(0)->GetPrimType(), p); if (e != node->Opnd(0)) { @@ -1756,20 +1570,20 @@ std::pair ConstantFold::FoldExtractbits(ExtractbitsNode *node) } if (offset == 0 && size >= 8 && IsPowerOf2(size)) { if (ExtractbitsRedundant(static_cast(result), mirModule->CurFunction())) { - return std::make_pair(result->Opnd(0), 0); + return std::make_pair(result->Opnd(0), std::nullopt); } } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldIread(IreadNode *node) { +std::pair> ConstantFold::FoldIread(IreadNode *node) { CHECK_NULL_FATAL(node); - std::pair p = DispatchFold(node->Opnd(0)); + std::pair> p = DispatchFold(node->Opnd(0)); BaseNode *e = PairToExpr(node->Opnd(0)->GetPrimType(), p); node->SetOpnd(e, 0); BaseNode *result = node; if (e->GetOpCode() != OP_addrof) { - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } AddrofNode *addrofNode = static_cast(e); @@ -1785,7 +1599,7 @@ std::pair ConstantFold::FoldIread(IreadNode *node) { // If the high level type of iaddrof/iread doesn't match // the type of addrof's rhs, this optimization cannot be done. if (ptrType->GetPointedType() != msyType) { - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } Opcode op = node->GetOpCode(); @@ -1799,7 +1613,7 @@ std::pair ConstantFold::FoldIread(IreadNode *node) { result = mirModule->CurFuncCodeMemPool()->New( OP_dread, node->GetPrimType(), addrofNode->GetStIdx(), node->GetFieldID() + addrofNode->GetFieldID()); } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } bool ConstantFold::IntegerOpIsOverflow(Opcode op, PrimType primType, int64 cstA, int64 cstB) { @@ -1832,21 +1646,22 @@ bool ConstantFold::IntegerOpIsOverflow(Opcode op, PrimType primType, int64 cstA, } } -std::pair ConstantFold::FoldBinary(BinaryNode *node) { +std::pair> ConstantFold::FoldBinary(BinaryNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; - int64 sum = 0; + std::optional sum = std::nullopt; Opcode op = node->GetOpCode(); PrimType primType = node->GetPrimType(); PrimType lPrimTypes = node->Opnd(0)->GetPrimType(); PrimType rPrimTypes = node->Opnd(1)->GetPrimType(); - std::pair lp = DispatchFold(node->Opnd(0)); - std::pair rp = DispatchFold(node->Opnd(1)); + std::pair> lp = DispatchFold(node->Opnd(0)); + std::pair> rp = DispatchFold(node->Opnd(1)); BaseNode *l = lp.first; BaseNode *r = rp.first; ConstvalNode *lConst = safe_cast(l); ConstvalNode *rConst = safe_cast(r); bool isInt = IsPrimitiveInteger(primType); + if (lConst != nullptr && rConst != nullptr) { MIRConst *lConstVal = lConst->GetConstVal(); MIRConst *rConstVal = rConst->GetConstVal(); @@ -1854,11 +1669,8 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { ASSERT_NOT_NULL(rConstVal); // Don't fold div by 0, for floats div by 0 is well defined. if ((op == OP_div || op == OP_rem) && isInt && - (static_cast(rConstVal)->GetValue() == 0 || - static_cast(lConstVal)->GetValue() == LONG_MIN || - static_cast(lConstVal)->GetValue() == INT_MIN)) { + !IsDivSafe(static_cast(*lConstVal), static_cast(*rConstVal), primType)) { result = NewBinaryNode(node, op, primType, lConst, rConst); - sum = 0; } else { // 4 + 2 -> return a pair(result = ConstValNode(6), sum = 0) // Create a new ConstvalNode for 6 but keep the sum = 0. This simplify the @@ -1866,13 +1678,12 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // Doing so would introduce many nullptr checks in the code. See previous // commits that implemented that logic for a comparison. result = FoldConstBinary(op, primType, *lConst, *rConst); - sum = 0; } } else if (lConst != nullptr && isInt) { MIRIntConst *mcst = safe_cast(lConst->GetConstVal()); ASSERT_NOT_NULL(mcst); PrimType cstTyp = mcst->GetType().GetPrimType(); - int64 cst = mcst->GetValue(); + IntVal cst = mcst->GetValue(); if (op == OP_add) { sum = cst + rp.second; result = r; @@ -1894,7 +1705,6 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // 0 << X -> 0 // 0 & X -> 0 // 0 && X -> 0 - sum = 0; result = mirModule->GetMIRBuilder()->CreateIntConst(0, cstTyp); } else if (op == OP_mul && cst == 1) { // 1 * X --> X @@ -1902,9 +1712,8 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { result = r; } else if (op == OP_bior && cst == -1) { // (-1) | X -> -1 - sum = 0; result = mirModule->GetMIRBuilder()->CreateIntConst(-1, cstTyp); - } else if (op == OP_mul && rp.second != 0) { + } else if (op == OP_mul && rp.second.has_value() && *rp.second != 0) { // lConst * (X + konst) -> the pair [(lConst*X), (lConst*konst)] sum = cst * rp.second; if (GetPrimTypeSize(primType) > GetPrimTypeSize(rp.first->GetPrimType())) { @@ -1912,7 +1721,6 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { } result = NewBinaryNode(node, OP_mul, primType, lConst, rp.first); } else if (op == OP_lior || op == OP_cior) { - sum = 0; if (cst != 0) { // 5 || X -> 1 result = mirModule->GetMIRBuilder()->CreateIntConst(1, cstTyp); @@ -1924,7 +1732,6 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { } } else if ((op == OP_cand || op == OP_land) && cst != 0) { // 5 && X -> (X != 0) - sum = 0; result = mirModule->CurFuncCodeMemPool()->New( OP_ne, primType, r->GetPrimType(), r, mirModule->GetMIRBuilder()->CreateIntConst(0, r->GetPrimType())); } else if ((op == OP_bior || op == OP_bxor) && cst == 0) { @@ -1934,7 +1741,6 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { result = r; } else { result = NewBinaryNode(node, op, primType, l, PairToExpr(rPrimTypes, rp)); - sum = 0; } if (!IsNoCvtNeeded(result->GetPrimType(), primType)) { result = mirModule->CurFuncCodeMemPool()->New(OP_cvt, primType, result->GetPrimType(), result); @@ -1943,16 +1749,15 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { MIRIntConst *mcst = safe_cast(rConst->GetConstVal()); ASSERT_NOT_NULL(mcst); PrimType cstTyp = mcst->GetType().GetPrimType(); - int64 cst = mcst->GetValue(); + IntVal cst = mcst->GetValue(); if (op == OP_add) { - if (IntegerOpIsOverflow(op, cstTyp, lp.second, cst)) { + if (lp.second && IntegerOpIsOverflow(op, cstTyp, lp.second->GetExtValue(), cst.GetExtValue())) { result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), PairToExpr(rPrimTypes, rp)); - sum = 0; } else { result = l; sum = lp.second + cst; } - } else if (op == OP_sub && cst != INT_MIN) { + } else if (op == OP_sub && (!cst.IsSigned() || !cst.IsMinValue())) { { result = l; sum = lp.second - cst; @@ -1961,16 +1766,15 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // X * 0 -> 0 // X & 0 -> 0 // X && 0 -> 0 - sum = 0; result = mirModule->GetMIRBuilder()->CreateIntConst(0, cstTyp); } else if ((op == OP_mul || op == OP_div) && cst == 1) { // case [X * 1 -> X] // case [X / 1 = X] sum = lp.second; result = l; - } else if (op == OP_mul && lp.second != 0 && lp.second > -kMaxOffset) { + } else if (op == OP_mul && lp.second.has_value() && *lp.second != 0 && lp.second->GetSXTValue() > -kMaxOffset) { // (X + konst) * rConst -> the pair [(X*rConst), (konst*rConst)] - sum = static_cast(static_cast(lp.second) * static_cast(cst)); + sum = lp.second * cst; if (GetPrimTypeSize(primType) > GetPrimTypeSize(lp.first->GetPrimType())) { lp.first = mirModule->CurFuncCodeMemPool()->New(OP_cvt, primType, PTY_i32, lp.first); } @@ -1979,14 +1783,14 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // X & (-1) -> X sum = lp.second; result = l; - } else if (op == OP_band && ContiguousBitsOf1(cst) && lp.second == 0) { + } else if (op == OP_band && ContiguousBitsOf1(cst.GetZXTValue()) && (!lp.second.has_value() || lp.second == 0)) { bool fold2extractbits = false; if (l->GetOpCode() == OP_ashr || l->GetOpCode() == OP_lshr) { BinaryNode *shrNode = static_cast(l); if (shrNode->Opnd(1)->GetOpCode() == OP_constval) { ConstvalNode *shrOpnd = static_cast(shrNode->Opnd(1)); - int64 shrAmt = static_cast(shrOpnd->GetConstVal())->GetValue(); - uint64 ucst = cst; + int64 shrAmt = static_cast(shrOpnd->GetConstVal())->GetExtValue(); + uint64 ucst = cst.GetZXTValue(); uint64 bsize = 0; do { bsize++; @@ -1997,27 +1801,25 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // change to use extractbits result = mirModule->GetMIRBuilder()->CreateExprExtractbits(OP_extractbits, GetUnsignedPrimType(primType), shrAmt, bsize, shrNode->Opnd(0)); - sum = 0; + sum = std::nullopt; } } } if (!fold2extractbits) { result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), r); - sum = 0; + sum = std::nullopt; } } else if (op == OP_bior && cst == -1) { // X | (-1) -> -1 - sum = 0; result = mirModule->GetMIRBuilder()->CreateIntConst(-1, cstTyp); } else if ((op == OP_lior || op == OP_cior)) { - sum = 0; - if (cst > 0) { - // X || 5 -> 1 - result = mirModule->GetMIRBuilder()->CreateIntConst(1, cstTyp); - } else if (cst == 0) { + if (cst == 0) { // X || 0 -> X sum = lp.second; result = l; + } else if (!cst.GetSignBit()) { + // X || 5 -> 1 + result = mirModule->GetMIRBuilder()->CreateIntConst(1, cstTyp); } else { result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), r); } @@ -2033,24 +1835,21 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // cvt i32 u1 (regread u1 %13), // constValue i32 1), result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), PairToExpr(rPrimTypes, rp)); - sum = 0; if (l->GetOpCode() == OP_cvt) { TypeCvtNode *cvtNode = static_cast(l); if (cvtNode->Opnd(0)->GetPrimType() == PTY_u1) { BaseNode *base = cvtNode->Opnd(0); BaseNode *constValue = mirModule->GetMIRBuilder()->CreateIntConst(1, base->GetPrimType()); - std::pair p = DispatchFold(base); + std::pair> p = DispatchFold(base); BinaryNode *temp = NewBinaryNode(node, op, PTY_u1, PairToExpr(base->GetPrimType(), p), constValue); result = mirModule->CurFuncCodeMemPool()->New(OP_cvt, primType, PTY_u1, temp); } } } else if (op == OP_rem && cst == 1) { // X % 1 -> 0 - sum = 0; result = mirModule->GetMIRBuilder()->CreateIntConst(0, cstTyp); } else { result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), r); - sum = 0; } if (!IsNoCvtNeeded(result->GetPrimType(), primType)) { result = mirModule->CurFuncCodeMemPool()->New(OP_cvt, primType, result->GetPrimType(), result); @@ -2064,14 +1863,12 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { // (x - neg(z)) Could cross the int limit // return node result = node; - sum = 0; } else { result = NewBinaryNode(node, op, primType, l, r); sum = lp.second - rp.second; } } else { result = NewBinaryNode(node, op, primType, PairToExpr(lPrimTypes, lp), PairToExpr(rPrimTypes, rp)); - sum = 0; } return std::make_pair(result, sum); } @@ -2154,11 +1951,11 @@ BaseNode *ConstantFold::SimplifyDoubleCompare(CompareNode &compareNode) const { return result; } -std::pair ConstantFold::FoldCompare(CompareNode *node) { +std::pair> ConstantFold::FoldCompare(CompareNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; - std::pair lp = DispatchFold(node->Opnd(0)); - std::pair rp = DispatchFold(node->Opnd(1)); + std::pair> lp = DispatchFold(node->Opnd(0)); + std::pair> rp = DispatchFold(node->Opnd(1)); ConstvalNode *lConst = safe_cast(lp.first); ConstvalNode *rConst = safe_cast(rp.first); Opcode opcode = node->GetOpCode(); @@ -2184,14 +1981,14 @@ std::pair ConstantFold::FoldCompare(CompareNode *node) { CHECK_NULL_FATAL(compareNode); result = SimplifyDoubleCompare(*compareNode); } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } BaseNode *ConstantFold::Fold(BaseNode *node) { if (node == nullptr || kOpcodeInfo.IsStmt(node->GetOpCode())) { return nullptr; } - std::pair p = DispatchFold(node); + std::pair> p = DispatchFold(node); BaseNode *result = PairToExpr(node->GetPrimType(), p); if (result == node) { result = nullptr; @@ -2199,13 +1996,13 @@ BaseNode *ConstantFold::Fold(BaseNode *node) { return result; } -std::pair ConstantFold::FoldDepositbits(DepositbitsNode *node) { +std::pair> ConstantFold::FoldDepositbits(DepositbitsNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; uint8 bitsOffset = node->GetBitsOffset(); uint8 bitsSize = node->GetBitsSize(); - std::pair leftPair = DispatchFold(node->Opnd(0)); - std::pair rightPair = DispatchFold(node->Opnd(1)); + std::pair> leftPair = DispatchFold(node->Opnd(0)); + std::pair> rightPair = DispatchFold(node->Opnd(1)); ConstvalNode *leftConst = safe_cast(leftPair.first); ConstvalNode *rightConst = safe_cast(rightPair.first); if (leftConst != nullptr && rightConst != nullptr) { @@ -2223,8 +2020,8 @@ std::pair ConstantFold::FoldDepositbits(DepositbitsNode *node) uint64 mask0 = (1LLU << (bitsSize + bitsOffset)) - 1; uint64 mask1 = (1LLU << bitsOffset) - 1; uint64 op0Mask = ~(mask0 ^ mask1); - op0ExtractVal = (static_cast(intConst0->GetValue()) & op0Mask); - op1ExtractVal = (static_cast(intConst1->GetValue()) << bitsOffset) & + op0ExtractVal = (intConst0->GetExtValue() & op0Mask); + op1ExtractVal = (intConst1->GetExtValue() << bitsOffset) & ((1ULL << (bitsSize + bitsOffset)) - 1); constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst( static_cast(op0ExtractVal | op1ExtractVal), constValue->GetType()); @@ -2241,10 +2038,10 @@ std::pair ConstantFold::FoldDepositbits(DepositbitsNode *node) result = node; } } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldArray(ArrayNode *node) { +std::pair> ConstantFold::FoldArray(ArrayNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = nullptr; size_t i = 0; @@ -2255,7 +2052,7 @@ std::pair ConstantFold::FoldArray(ArrayNode *node) { node->GetTyIdx(), node->GetBoundsCheck()); for (i = 0; i < node->GetNopndSize(); i++) { - std::pair p = DispatchFold(node->GetNopndAt(i)); + std::pair> p = DispatchFold(node->GetNopndAt(i)); BaseNode *tmpNode = PairToExpr(node->GetNopndAt(i)->GetPrimType(), p); if (tmpNode != node->GetNopndAt(i)) { isFolded = true; @@ -2268,14 +2065,14 @@ std::pair ConstantFold::FoldArray(ArrayNode *node) { } else { result = node; } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } -std::pair ConstantFold::FoldTernary(TernaryNode *node) { +std::pair> ConstantFold::FoldTernary(TernaryNode *node) { CHECK_NULL_FATAL(node); BaseNode *result = node; std::vector primTypes; - std::vector> p; + std::vector>> p; for (size_t i = 0; i < node->NumOpnds(); i++) { BaseNode *tempNopnd = node->Opnd(i); CHECK_NULL_FATAL(tempNopnd); @@ -2288,7 +2085,7 @@ std::pair ConstantFold::FoldTernary(TernaryNode *node) { MIRIntConst *intConst0 = safe_cast(const0->GetConstVal()); ASSERT_NOT_NULL(intConst0); // Selecting the first value if not 0, selecting the second value otherwise. - if (intConst0->GetValue()) { + if (!intConst0->IsZero()) { result = PairToExpr(primTypes[1], p[1]); } else { result = PairToExpr(primTypes[2], p[2]); @@ -2316,8 +2113,8 @@ std::pair ConstantFold::FoldTernary(TernaryNode *node) { dconst2 = static_cast(fConst2->GetFloatValue()); } } else { - dconst1 = static_cast(intConst1->GetValue()); - dconst2 = static_cast(intConst2->GetValue()); + dconst1 = static_cast(intConst1->GetExtValue()); + dconst2 = static_cast(intConst2->GetExtValue()); } PrimType foldedPrimType = primTypes[1]; if (!IsPrimitiveInteger(foldedPrimType)) { @@ -2331,13 +2128,13 @@ std::pair ConstantFold::FoldTernary(TernaryNode *node) { result = mirModule->CurFuncCodeMemPool()->New( OP_cvt, foldedPrimType, primTypes[0], result); } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } if (dconst1 == 0.0 && dconst2 == 1.0) { BaseNode *lnot = mirModule->CurFuncCodeMemPool()->New( OP_eq, primTypes[0], primTypes[0], PairToExpr(primTypes[0], p[0]), mirModule->GetMIRBuilder()->CreateIntConst(0, primTypes[0])); - std::pair pairTemp = DispatchFold(lnot); + std::pair> pairTemp = DispatchFold(lnot); if (IsPrimitiveInteger(foldedPrimType)) { result = PairToExpr(foldedPrimType, pairTemp); } else { @@ -2345,7 +2142,7 @@ std::pair ConstantFold::FoldTernary(TernaryNode *node) { result = mirModule->CurFuncCodeMemPool()->New( OP_cvt, foldedPrimType, primTypes[0], result); } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } } } @@ -2358,7 +2155,7 @@ std::pair ConstantFold::FoldTernary(TernaryNode *node) { PrimType(node->GetPrimType()), e0, e1, e2); } - return std::make_pair(result, 0); + return std::make_pair(result, std::nullopt); } StmtNode *ConstantFold::SimplifyDassign(DassignNode *node) { @@ -2484,8 +2281,8 @@ StmtNode *ConstantFold::SimplifyCondGoto(CondGotoNode *node) { } MIRIntConst *intConst = safe_cast(cst->GetConstVal()); ASSERT_NOT_NULL(intConst); - if ((node->GetOpCode() == OP_brtrue && intConst->GetValueUnderType() != 0) || - (node->GetOpCode() == OP_brfalse && intConst->GetValueUnderType() == 0)) { + if ((node->GetOpCode() == OP_brtrue && !intConst->IsZero()) || + (node->GetOpCode() == OP_brfalse && intConst->IsZero())) { uint32 freq = mirModule->CurFunction()->GetFreqFromLastStmt(node->GetStmtID()); GotoNode *gotoNode = mirModule->CurFuncCodeMemPool()->New(OP_goto); gotoNode->SetOffset(node->GetOffset()); @@ -2628,7 +2425,7 @@ StmtNode *ConstantFold::SimplifyAsm(AsmNode* node) { for (size_t i = 0; i < node->NumOpnds(); i++) { const std::string &str = GlobalTables::GetUStrTable().GetStringFromStrIdx(node->inputConstraints[i]); if (str == "i") { - std::pair p = DispatchFold(node->Opnd(i)); + std::pair> p = DispatchFold(node->Opnd(i)); node->SetOpnd(p.first, i); continue; } diff --git a/src/mapleall/mpl2mpl/src/ext_constantfold.cpp b/src/mapleall/mpl2mpl/src/ext_constantfold.cpp index aeb805fb65cc7a4613c7419fedbf268809a32976..eea4960a0602aab5e4397215dab7826e64ad394c 100644 --- a/src/mapleall/mpl2mpl/src/ext_constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/ext_constantfold.cpp @@ -171,7 +171,7 @@ BaseNode *ExtConstantFold::ExtFoldIor(BinaryNode *node) { (bNode->Opnd(1)->GetOpCode() == OP_constval) && (IsPrimitiveInteger(bNode->Opnd(1)->GetPrimType()))) { MIRConst *rConstVal = safe_cast(bNode->Opnd(1))->GetConstVal(); - int64 rVal = static_cast(rConstVal)->GetValue(); + int64 rVal = static_cast(rConstVal)->GetExtValue(); minVal = std::min(minVal, rVal); uniqOperands.push_back(rVal); } else { @@ -243,13 +243,13 @@ BaseNode *ExtConstantFold::ExtFoldXand(BinaryNode *node) { (IsPrimitiveInteger(rnode->Opnd(1)->GetPrimType())) && (lnode->Opnd(0)->Opnd(0)->IsSameContent(rnode->Opnd(0)->Opnd(0)))) { MIRConst *lmConstVal = safe_cast(lnode->Opnd(0)->Opnd(1))->GetConstVal(); - uint64 lmVal = static_cast(static_cast(lmConstVal)->GetValue()); + uint64 lmVal = static_cast(lmConstVal)->GetExtValue(); MIRConst *rmConstVal = safe_cast(rnode->Opnd(0)->Opnd(1))->GetConstVal(); - uint64 rmVal = static_cast(static_cast(rmConstVal)->GetValue()); + uint64 rmVal = static_cast(rmConstVal)->GetExtValue(); MIRConst *lcConstVal = safe_cast(lnode->Opnd(1))->GetConstVal(); - uint64 lcVal = static_cast(static_cast(lcConstVal)->GetValue()); + uint64 lcVal = static_cast(lcConstVal)->GetExtValue(); MIRConst *rcConstVal = safe_cast(rnode->Opnd(1))->GetConstVal(); - uint64 rcVal = static_cast(static_cast(rcConstVal)->GetValue()); + uint64 rcVal = static_cast(rcConstVal)->GetExtValue(); bool isWorkable = true; for (uint64 i = 0; i < 64; i++) { diff --git a/src/mapleall/mpl2mpl/src/muid_replacement.cpp b/src/mapleall/mpl2mpl/src/muid_replacement.cpp index d8f33759cd17ae2872c137108259577ddbb6e8f4..0a497e60bffac21888bb73a3736d7b02d0312653 100644 --- a/src/mapleall/mpl2mpl/src/muid_replacement.cpp +++ b/src/mapleall/mpl2mpl/src/muid_replacement.cpp @@ -641,13 +641,13 @@ void MUIDReplacement::GenerateFuncDefTable() { uint32 muidIdx = iter->second.second; constexpr uint32 weakFuncFlag = 0x80000000; // 0b10000000 00000000 00000000 00000000 auto *indexConst = safe_cast(muidIdxTabConst->GetConstVecItem(muidIdx)); - uint32 tempIdx = (static_cast(indexConst->GetValue()) & weakFuncFlag) | idx; + uint32 tempIdx = (indexConst->GetExtValue() & weakFuncFlag) | idx; indexConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(tempIdx, *GlobalTables::GetTypeTable().GetUInt32()); muidIdxTabConst->SetItem(muidIdx, indexConst, 0); if (reflectionList.find(mirFunc->GetName()) != reflectionList.end()) { auto *tempConst = safe_cast(muidIdxTabConst->GetConstVecItem(idx)); - tempIdx = weakFuncFlag | static_cast(tempConst->GetValue()); + tempIdx = weakFuncFlag | tempConst->GetExtValue(); tempConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(tempIdx, *GlobalTables::GetTypeTable().GetUInt32()); muidIdxTabConst->SetItem(idx, tempConst, 0); @@ -1237,7 +1237,7 @@ void MUIDReplacement::ReplaceAddroffuncConst(MIRConst *&entry, uint32 fieldID, b voidType); } if (fieldID != 0xffffffff) { - constNode = GlobalTables::GetIntConstTable().GetOrCreateIntConst(constNode->GetValue(), + constNode = GlobalTables::GetIntConstTable().GetOrCreateIntConst(constNode->GetExtValue(), constNode->GetType()); } entry = constNode; @@ -1266,7 +1266,7 @@ void MUIDReplacement::ReplaceFieldTypeTable(const std::string &name) { CHECK_NULL_FATAL(mirConst); if (mirConst->GetKind() == kConstInt) { MIRIntConst *newIntConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(mirConst)->GetValue(), mirConst->GetType()); + static_cast(mirConst)->GetExtValue(), mirConst->GetType()); aggrC->SetItem(index, newIntConst, index + 1); } else { aggrC->SetFieldIdOfElement(index, index + 1); @@ -1297,7 +1297,7 @@ void MUIDReplacement::ReplaceDataTable(const std::string &name) { MIRConstPtr mirConst = aggrC->GetConstVecItem(i); if (mirConst->GetKind() == kConstInt) { MIRIntConst *newIntConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(mirConst)->GetValue(), mirConst->GetType()); + static_cast(mirConst)->GetExtValue(), mirConst->GetType()); aggrC->SetItem(i, newIntConst, i + 1); } else { aggrC->SetFieldIdOfElement(i, i + 1); @@ -1326,7 +1326,7 @@ void MUIDReplacement::ReplaceDecoupleKeyTable(MIRAggConst* oldConst) { MIRConstPtr mirConst = aggrC->GetConstVecItem(i); if (mirConst->GetKind() == kConstInt) { MIRIntConst *newIntConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(mirConst)->GetValue(), mirConst->GetType()); + static_cast(mirConst)->GetExtValue(), mirConst->GetType()); aggrC->SetItem(i, newIntConst, i + 1); } else { aggrC->SetFieldIdOfElement(i, i + 1); diff --git a/src/mapleall/mpl2mpl/src/simplify.cpp b/src/mapleall/mpl2mpl/src/simplify.cpp index b33ba416d8a28696b416b5cad353397e46936069..7f2274a4c772f62c1e90941b4bf999c23f6ca070 100644 --- a/src/mapleall/mpl2mpl/src/simplify.cpp +++ b/src/mapleall/mpl2mpl/src/simplify.cpp @@ -520,11 +520,11 @@ static uint64 JoinBytes(int byte, uint32 num) { // Return Fold result expr, does not always return a constant expr // Attention: Fold may modify the input expr, if foldExpr is not a nullptr, we should always replace expr with foldExpr -static BaseNode *FoldIntConst(BaseNode *expr, int64 &out, bool &isIntConst) { +static BaseNode *FoldIntConst(BaseNode *expr, uint64 &out, bool &isIntConst) { if (expr->GetOpCode() == OP_constval) { MIRConst *mirConst = static_cast(expr)->GetConstVal(); if (mirConst->GetKind() == kConstInt) { - out = static_cast(mirConst)->GetValue(); + out = static_cast(mirConst)->GetExtValue(); isIntConst = true; } return nullptr; @@ -535,14 +535,14 @@ static BaseNode *FoldIntConst(BaseNode *expr, int64 &out, bool &isIntConst) { if (foldExpr != nullptr && foldExpr->GetOpCode() == OP_constval) { MIRConst *mirConst = static_cast(foldExpr)->GetConstVal(); if (mirConst->GetKind() == kConstInt) { - out = static_cast(mirConst)->GetValue(); + out = static_cast(mirConst)->GetExtValue(); isIntConst = true; } } return foldExpr; } -static BaseNode *ConstructConstvalNode(int64 val, PrimType primType, MIRBuilder &mirBuilder) { +static BaseNode *ConstructConstvalNode(uint64 val, PrimType primType, MIRBuilder &mirBuilder) { PrimType constPrimType = primType; if (IsPrimitiveFloat(primType)) { constPrimType = GetIntegerPrimTypeBySizeAndSign(GetPrimTypeBitSize(primType), false); @@ -559,7 +559,7 @@ static BaseNode *ConstructConstvalNode(int64 val, PrimType primType, MIRBuilder static BaseNode *ConstructConstvalNode(int64 byte, uint64 num, PrimType primType, MIRBuilder &mirBuilder) { auto val = JoinBytes(byte, static_cast(num)); - return ConstructConstvalNode(static_cast(val), primType, mirBuilder); + return ConstructConstvalNode(val, primType, mirBuilder); } // Input total size of memory, split the memory into several blocks, the max block size is 8 bytes @@ -1380,21 +1380,21 @@ bool SimplifyMemOp::AutoSimplify(StmtNode &stmt, BlockNode &block, bool isLowLev StmtNode *SimplifyMemOp::PartiallyExpandMemsetS(StmtNode &stmt, BlockNode &block) { ErrorNumber errNum = ERRNO_OK; - int64 srcSize = 0; + uint64 srcSize = 0; bool isSrcSizeConst = false; BaseNode *foldSrcSizeExpr = FoldIntConst(stmt.Opnd(kMemsetSSrcSizeOpndIdx), srcSize, isSrcSizeConst); if (foldSrcSizeExpr != nullptr) { stmt.SetOpnd(foldSrcSizeExpr, kMemsetSDstSizeOpndIdx); } - int64 dstSize = 0; + uint64 dstSize = 0; bool isDstSizeConst = false; BaseNode *foldDstSizeExpr = FoldIntConst(stmt.Opnd(kMemsetSDstSizeOpndIdx), dstSize, isDstSizeConst); if (foldDstSizeExpr != nullptr) { stmt.SetOpnd(foldDstSizeExpr, kMemsetSDstSizeOpndIdx); } if (isDstSizeConst) { - if ((srcSize > dstSize && dstSize == 0) || static_cast(dstSize) > kSecurecMemMaxLen) { + if ((srcSize > dstSize && dstSize == 0) || dstSize > kSecurecMemMaxLen) { errNum = ERRNO_RANGE; } } @@ -1500,7 +1500,7 @@ bool SimplifyMemOp::SimplifyMemset(StmtNode &stmt, BlockNode &block, bool isLowL } } - int64 srcSize = 0; + uint64 srcSize = 0; bool isSrcSizeConst = false; BaseNode *foldSrcSizeExpr = FoldIntConst(memsetCallStmt->Opnd(srcSizeOpndIdx), srcSize, isSrcSizeConst); if (foldSrcSizeExpr != nullptr) { @@ -1532,7 +1532,7 @@ bool SimplifyMemOp::SimplifyMemset(StmtNode &stmt, BlockNode &block, bool isLowL ErrorNumber errNum = ERRNO_OK; - int64 val = 0; + uint64 val = 0; bool isIntConst = false; BaseNode *foldValExpr = FoldIntConst(memsetCallStmt->Opnd(srcOpndIdx), val, isIntConst); if (foldValExpr != nullptr) { @@ -1587,7 +1587,7 @@ bool SimplifyMemOp::SimplifyMemcpy(StmtNode &stmt, BlockNode &block, bool isLowL stmt.Dump(0); } - int64 srcSize = 0; + uint64 srcSize = 0; bool isIntConst = false; BaseNode *foldCopySizeExpr = FoldIntConst(stmt.Opnd(srcSizeOpndIdx), srcSize, isIntConst); if (foldCopySizeExpr != nullptr) { @@ -1606,10 +1606,10 @@ bool SimplifyMemOp::SimplifyMemcpy(StmtNode &stmt, BlockNode &block, bool isLowL MayPrintLog(debug, false, memOpKind, "memcpy with src size 0"); return false; } - int64 copySize = srcSize; + uint64 copySize = srcSize; ErrorNumber errNum = ERRNO_OK; if (isSafeVersion) { - int64 dstSize = 0; + uint64 dstSize = 0; bool isDstSizeConst = false; BaseNode *foldDstSizeExpr = FoldIntConst(stmt.Opnd(dstSizeOpndIdx), dstSize, isDstSizeConst); if (foldDstSizeExpr != nullptr) { @@ -1619,7 +1619,7 @@ bool SimplifyMemOp::SimplifyMemcpy(StmtNode &stmt, BlockNode &block, bool isLowL MayPrintLog(debug, false, memOpKind, "dst size is not int const"); return false; } - if (dstSize == 0 || static_cast(dstSize) > kSecurecMemMaxLen) { + if (dstSize == 0 || dstSize > kSecurecMemMaxLen) { copySize = 0; errNum = ERRNO_RANGE; } else if (srcSize > dstSize) { @@ -1653,7 +1653,7 @@ bool SimplifyMemOp::SimplifyMemcpy(StmtNode &stmt, BlockNode &block, bool isLowL } bool ret = false; if (copySize != 0) { - ret = dstMemEntry.ExpandMemcpy(srcMemEntry, static_cast(copySize), *func, stmt, block, isLowLevel, debug, + ret = dstMemEntry.ExpandMemcpy(srcMemEntry, copySize, *func, stmt, block, isLowLevel, debug, errNum); } else { // if copySize == 0, no need to copy memory, just return error number diff --git a/test/c_test/sanity/sum_array.c b/test/c_test/sanity/sum_array.c index 714090b6916b9bc58c7aefc5e172e1ec79b28b41..9235f2768dda33a9b7443afc85956afa6d08933e 100644 --- a/test/c_test/sanity/sum_array.c +++ b/test/c_test/sanity/sum_array.c @@ -15,6 +15,7 @@ #include #include +#include //int main(int argc, char *argv[]) int main() @@ -23,7 +24,7 @@ int main() for (i = 0; i < 10; i++) { b[i] = i << 2; - c[i] = i << b[i]; + c[i] = i << (b[i] % (sizeof(int)*CHAR_BIT)); } for (i = 0; i < 10; i++) { diff --git a/testsuite/c_test/sanity_test/SANITY0018-sum_array/sum_array.c b/testsuite/c_test/sanity_test/SANITY0018-sum_array/sum_array.c index 714090b6916b9bc58c7aefc5e172e1ec79b28b41..9235f2768dda33a9b7443afc85956afa6d08933e 100644 --- a/testsuite/c_test/sanity_test/SANITY0018-sum_array/sum_array.c +++ b/testsuite/c_test/sanity_test/SANITY0018-sum_array/sum_array.c @@ -15,6 +15,7 @@ #include #include +#include //int main(int argc, char *argv[]) int main() @@ -23,7 +24,7 @@ int main() for (i = 0; i < 10; i++) { b[i] = i << 2; - c[i] = i << b[i]; + c[i] = i << (b[i] % (sizeof(int)*CHAR_BIT)); } for (i = 0; i < 10; i++) {