diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index f81c2d35ec04100620078e8bf1d0ce32a378930c..d0ed6542d6aa96a21982f5d93a16de0340e04a5c 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 1b37e3b04a12f02f27e530dfece9bfa1b0c6d216..901cc4b03afab609cedf4457ce37ec7187295200 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/include/be/common_utils.h b/src/mapleall/maple_be/include/be/common_utils.h index a487d101a7d4316b5cec7308238f104186a94d45..63c2db9053208aa4472c6bb89739c52885b3a7a8 100644 --- a/src/mapleall/maple_be/include/be/common_utils.h +++ b/src/mapleall/maple_be/include/be/common_utils.h @@ -43,9 +43,14 @@ constexpr uint32 k56BitSize = 56; constexpr uint32 k64BitSize = 64; constexpr uint32 k128BitSize = 128; constexpr uint32 k256BitSize = 256; +constexpr uint32 k512BitSize = 512; + +constexpr int32 kNegative256BitSize = -256; +constexpr int32 kNegative512BitSize = -512; constexpr uint32 k1ByteSize = 1; constexpr uint32 k2ByteSize = 2; +constexpr uint32 k3ByteSize = 3; constexpr uint32 k4ByteSize = 4; constexpr uint32 k8ByteSize = 8; constexpr uint32 k12ByteSize = 12; @@ -111,6 +116,18 @@ constexpr int32 kEARetTempNameSize = 10; constexpr uint32 kMaxImmVal8Bits = 8; constexpr uint32 kMaxImmVal12Bits = 12; constexpr uint32 kMaxImmVal13Bits = 13; +constexpr uint32 kMaxImmVal16Bits = 16; + +constexpr int32 kMaxPimm8 = 4095; +constexpr int32 kMaxPimm16 = 8190; +constexpr int32 kMaxPimm32 = 16380; +constexpr int32 kMaxPimm64 = 32760; + +constexpr int32 kMaxPimm[k4BitSize] = {kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64}; + +constexpr int32 kMax12UnsignedImm = 4096; +constexpr int32 kMax13UnsignedImm = 8192; +constexpr int32 kMax16UnsignedImm = 65535; /* aarch64 assembly takes up to 24-bits */ constexpr uint32 kMaxImmVal24Bits = 24; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index a85256630e3726640f89cd796b4e214f7360a710..c685cc7b84887d26e2e5e97b0dd9c1d96237a51b 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -134,7 +134,7 @@ class AArch64CGFunc : public CGFunc { Operand *SelectStr16Const(MIRStr16Const &str16Const) override; void SelectAdd(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType) override; - Operand *SelectAdd(BinaryNode &node, Operand &o0, Operand &o1) override; + Operand *SelectAdd(BinaryNode &node, Operand &o0, Operand &o1, const BaseNode &parent) override; Operand &SelectCGArrayElemAdd(BinaryNode &node) override; Operand *SelectShift(BinaryNode &node, Operand &o0, Operand &o1) override; Operand *SelectSub(BinaryNode &node, Operand &o0, Operand &o1) override; @@ -172,6 +172,7 @@ class AArch64CGFunc : public CGFunc { AArch64reg regNum, bool &isOutOfRange); void SelectAddAfterInsn(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType, bool isDest, Insn &insn); bool IsImmediateOffsetOutOfRange(AArch64MemOperand &memOpnd, uint32 bitLen); + bool IsOperandImmValid(MOperator mOp, Operand *o, uint32 opndIdx); Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1) override; void SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1) override; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a69dd953a975c733e8a65a3bcb8d85c2564f1e57..236c987922bef3218ce4f30f4732af27cdbaef8c 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -29,7 +29,7 @@ namespace maplebe { #define OPTIMIZE_FOR_PROLOG #undef REUSE_SPILLMEM #undef COLOR_SPLIT -#undef MOVE_COALESCE +#define MOVE_COALESCE /* for robust test */ #undef CONSISTENT_MEMOPND @@ -1079,6 +1079,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { localRegVec(alloc.Adapter()), bbRegInfo(alloc.Adapter()), unconstrained(alloc.Adapter()), + unconstrainedPref(alloc.Adapter()), constrained(alloc.Adapter()), mustAssigned(alloc.Adapter()), #ifdef OPTIMIZE_FOR_PROLOG @@ -1283,6 +1284,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { MapleVector localRegVec; /* local reg info for each bb, no local reg if null */ MapleVector bbRegInfo; /* register assignment info for each bb */ MapleVector unconstrained; + MapleVector unconstrainedPref; MapleVector constrained; MapleVector mustAssigned; #ifdef OPTIMIZE_FOR_PROLOG diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_immediate.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_immediate.h index 27075e4ee8432e09b1d115dd37eddea5e1796cdc..82ffafdfe1ea49f0981aa8bfbdd7615def54d805 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_immediate.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_immediate.h @@ -19,9 +19,10 @@ #include namespace maplebe { +bool IsBitSizeImmediate(maple::uint64 val, maple::uint32 bitLen, maple::uint32 nLowerZeroBits); bool IsBitmaskImmediate(maple::uint64 val, maple::uint32 bitLen); bool IsMoveWidableImmediate(maple::uint64 val, maple::uint32 bitLen); bool BetterUseMOVZ(maple::uint64 val); } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_IMMEDIATE_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_IMMEDIATE_H */ diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h index 590e264989f8fad039ad517e695afb9cf3846046..e1e5fd7fe0c76198c96362cd389448e9e6226f98 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h @@ -242,12 +242,45 @@ class AArch64OpndProp : public OpndProp { return static_cast(size); } + void SetContainImm() { + isContainImm = true; + } + + bool IsContainImm() const { + return isContainImm; + } + + protected: + bool isContainImm = false; + private: Operand::OperandType opndType; RegProp regProp; uint8 size; }; +/* + * Operand which might include immediate value. + * function ptr returns whether a immediate is legal in specific target + */ +class AArch64ImmOpndProp : public AArch64OpndProp { + public: + AArch64ImmOpndProp(Operand::OperandType t, RegProp p, uint8 s, const std::function f) + : AArch64OpndProp(t, p, s), + validFunc(f) { + SetContainImm(); + } + virtual ~AArch64ImmOpndProp() = default; + + bool IsValidImmOpnd(int64 value) const { + CHECK_FATAL(validFunc, " Have not set valid function yet in AArch64ImmOpndProp"); + return validFunc(value); + } + + private: + std::function validFunc; +}; + struct AArch64MD { MOperator opc; std::vector operand; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def index 4bc556f1702af3067403ab9ec8af5dcb945961bb..7ed2f8d2e52afed5c88d084e36497928ed95bffc 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def @@ -60,7 +60,6 @@ DEFINE_MOP(MOP_xaddrrrs, {mopdReg64ID,mopdReg64IS,mopdReg64IS,mopdBitShift64},0, /* MOP_xxwaddrrre */ DEFINE_MOP(MOP_xxwaddrrre, {mopdReg64ID,mopdReg64IS,mopdReg32IS,mopdExtendShift64},0,kLtAluShift,"add","0,1,2,3",1) /* MOP_xaddrri24 */ - DEFINE_MOP(MOP_xaddrri24, {mopdReg64ID,mopdReg64IS,mopdImm12,mopdLSL12},0,kLtShift,"add","0,1,2,3",1) /* MOP_xaddrri12 */ DEFINE_MOP(MOP_xaddrri12, {mopdReg64ID,mopdReg64IS,mopdImm12},0,kLtAlu,"add","0,1,2",1) @@ -231,47 +230,44 @@ DEFINE_MOP(MOP_xandrrr, {mopdReg64ID,mopdReg64IS,mopdReg64IS},0,kLtAlu,"and","0, /* MOP_xandrrrs */ DEFINE_MOP(MOP_xandrrrs, {mopdReg64ID,mopdReg64IS,mopdReg64IS,mopdBitShift64},0,kLtAluShift,"and","0,1,2,3",1) /* MOP_xandrri13 */ -DEFINE_MOP(MOP_xandrri13, {mopdReg64ID,mopdReg64IS,mopdImm13},0,kLtAlu,"and","0,1,2",1) +DEFINE_MOP(MOP_xandrri13, {mopdReg64ID,mopdReg64IS,mopdImmBm13},0,kLtAlu,"and","0,1,2",1) /* MOP_wandrrr */ DEFINE_MOP(MOP_wandrrr, {mopdReg32ID,mopdReg32IS,mopdReg32IS},0,kLtAlu,"and","0,1,2",1) /* MOP_wandrrrs */ DEFINE_MOP(MOP_wandrrrs, {mopdReg32ID,mopdReg32IS,mopdReg32IS,mopdBitShift32},0,kLtAluShift,"and","0,1,2,3",1) /* MOP_wandrri12 */ -DEFINE_MOP(MOP_wandrri12, {mopdReg32ID,mopdReg32IS,mopdImm12},0,kLtAlu,"and","0,1,2",1) +DEFINE_MOP(MOP_wandrri12, {mopdReg32ID,mopdReg32IS,mopdImmBm12},0,kLtAlu,"and","0,1,2",1) /* MOP_xiorrrr */ DEFINE_MOP(MOP_xiorrrr, {mopdReg64ID,mopdReg64IS,mopdReg64IS},0,kLtAlu,"orr","0,1,2",1) /* MOP_xiorrrrs */ DEFINE_MOP(MOP_xiorrrrs, {mopdReg64ID,mopdReg64IS,mopdReg64IS,mopdBitShift64},0,kLtAlu,"orr","0,1,2,3",1) /* MOP_xiorrri13 */ -DEFINE_MOP(MOP_xiorrri13, {mopdReg64ID,mopdReg64IS,mopdImm13},0,kLtAlu,"orr","0,1,2",1) +DEFINE_MOP(MOP_xiorrri13, {mopdReg64ID,mopdReg64IS,mopdImmBm13},0,kLtAlu,"orr","0,1,2",1) /* MOP_wiorrrr */ DEFINE_MOP(MOP_wiorrrr, {mopdReg32ID,mopdReg32IS,mopdReg32IS},0,kLtAlu,"orr","0,1,2",1) /* MOP_wiorrrrs */ DEFINE_MOP(MOP_wiorrrrs, {mopdReg32ID,mopdReg32IS,mopdReg32IS,mopdBitShift32},0,kLtAlu,"orr","0,1,2,3",1) /* MOP_wiorrri12 */ -DEFINE_MOP(MOP_wiorrri12, {mopdReg32ID,mopdReg32IS,mopdImm12},0,kLtAlu,"orr","0,1,2",1) +DEFINE_MOP(MOP_wiorrri12, {mopdReg32ID,mopdReg32IS,mopdImmBm12},0,kLtAlu,"orr","0,1,2",1) /* MOP_xiorri13r */ -DEFINE_MOP(MOP_xiorri13r, {mopdReg64ID,mopdImm13,mopdReg64IS},0,kLtAlu,"orr","0,2,1",1) +DEFINE_MOP(MOP_xiorri13r, {mopdReg64ID,mopdImmBm13,mopdReg64IS},0,kLtAlu,"orr","0,2,1",1) /* MOP_wiorri12r */ -DEFINE_MOP(MOP_wiorri12r, {mopdReg32ID,mopdImm12,mopdReg32IS},0,kLtAlu,"orr","0,2,1",1) +DEFINE_MOP(MOP_wiorri12r, {mopdReg32ID,mopdImmBm12,mopdReg32IS},0,kLtAlu,"orr","0,2,1",1) /* MOP_xeorrrr */ DEFINE_MOP(MOP_xeorrrr, {mopdReg64ID,mopdReg64IS,mopdReg64IS},0,kLtAlu,"eor","0,1,2",1) /* MOP_xeorrrrs */ DEFINE_MOP(MOP_xeorrrrs, {mopdReg64ID,mopdReg64IS,mopdReg64IS,mopdBitShift64},0,kLtAlu,"eor","0,1,2,3",1) /* MOP_xeorrri13 */ -DEFINE_MOP(MOP_xeorrri13, {mopdReg64ID,mopdReg64IS,mopdImm13},0,kLtAlu,"eor","0,1,2",1) +DEFINE_MOP(MOP_xeorrri13, {mopdReg64ID,mopdReg64IS,mopdImmBm13},0,kLtAlu,"eor","0,1,2",1) /* MOP_weorrrr */ DEFINE_MOP(MOP_weorrrr, {mopdReg32ID,mopdReg32IS,mopdReg32IS},0,kLtAlu,"eor","0,1,2",1) /* MOP_weorrrrs */ DEFINE_MOP(MOP_weorrrrs, {mopdReg32ID,mopdReg32IS,mopdReg32IS,mopdBitShift32},0,kLtAlu,"eor","0,1,2,3",1) /* MOP_weorrri12 */ -DEFINE_MOP(MOP_weorrri12, {mopdReg32ID,mopdReg32IS,mopdImm12},0,kLtAlu,"eor","0,1,2",1) - -/* MOP_weorrri8m */ -DEFINE_MOP(MOP_weorrri8m, {mopdReg32ID,mopdReg32IS,mopdImm8},0,kLtAlu,"eor","0,1,2",1) +DEFINE_MOP(MOP_weorrri12, {mopdReg32ID,mopdReg32IS,mopdImmBm12},0,kLtAlu,"eor","0,1,2",1) /* MOP_xnotrr */ DEFINE_MOP(MOP_xnotrr, {mopdReg64ID,mopdReg64IS},0,kLtAlu,"mvn","0,1",1) @@ -423,15 +419,15 @@ DEFINE_MOP(MOP_dldr, {mopdReg64FD,mopdMem64S},ISLOAD|CANTHROW,kLtFLoadMany,"ldr" /* AArch64 LDP/LDPSW */ /* MOP_wldp */ -DEFINE_MOP(MOP_wldp, {mopdReg32ID,mopdReg32ID,mopdMem32S},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad2,"ldp","0,1,2",1) +DEFINE_MOP(MOP_wldp, {mopdReg32ID,mopdReg32ID,mopdMem32PS},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad2,"ldp","0,1,2",1) /* MOP_xldp */ -DEFINE_MOP(MOP_xldp, {mopdReg64ID,mopdReg64ID,mopdMem64S},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad3plus,"ldp","0,1,2",1) +DEFINE_MOP(MOP_xldp, {mopdReg64ID,mopdReg64ID,mopdMem64PS},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad3plus,"ldp","0,1,2",1) /* MOP_xldpsw */ -DEFINE_MOP(MOP_xldpsw, {mopdReg64ID,mopdReg64ID,mopdMem32S},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad2,"ldpsw","0,1,2",1) +DEFINE_MOP(MOP_xldpsw, {mopdReg64ID,mopdReg64ID,mopdMem32PS},ISLOAD|ISLOADPAIR|CANTHROW,kLtLoad2,"ldpsw","0,1,2",1) /* MOP_sldp */ -DEFINE_MOP(MOP_sldp, {mopdReg32FD,mopdReg32FD,mopdMem32S},ISLOAD|ISLOADPAIR|CANTHROW,kLtFLoad64,"ldp","0,1,2",1) +DEFINE_MOP(MOP_sldp, {mopdReg32FD,mopdReg32FD,mopdMem32PS},ISLOAD|ISLOADPAIR|CANTHROW,kLtFLoad64,"ldp","0,1,2",1) /* MOP_dldp */ -DEFINE_MOP(MOP_dldp, {mopdReg64FD,mopdReg64FD,mopdMem64S},ISLOAD|ISLOADPAIR|CANTHROW,kLtFLoadMany,"ldp","0,1,2",1) +DEFINE_MOP(MOP_dldp, {mopdReg64FD,mopdReg64FD,mopdMem64PS},ISLOAD|ISLOADPAIR|CANTHROW,kLtFLoadMany,"ldp","0,1,2",1) /* AARCH64 Load with Acquire semantics */ /* MOP_wldarb */ @@ -548,7 +544,7 @@ DEFINE_MOP(MOP_wcmpri, {mopdRegCCD, mopdReg32IS,mopdImm12},0,kLtAlu,"cmp","1,2", /* MOP_wcmprr -- register, shifted register, AArch64 cmp has no dest operand */ DEFINE_MOP(MOP_wcmprr, {mopdRegCCD, mopdReg32IS,mopdReg32IS},0,kLtAlu,"cmp","1,2",1) /* MOP_xcmpri -- AArch64 cmp has no dest operand */ -DEFINE_MOP(MOP_xcmpri, {mopdRegCCD, mopdReg64IS,mopdImm12},0,kLtAlu,"cmp","1,2",1) +DEFINE_MOP(MOP_xcmpri, {mopdRegCCD, mopdReg64IS,mopdImm16},0,kLtAlu,"cmp","1,2",1) /* MOP_xcmprr -- register, shifted register, AArch64 cmp has no dest operand */ DEFINE_MOP(MOP_xcmprr, {mopdRegCCD, mopdReg64IS,mopdReg64IS},0,kLtAlu,"cmp","1,2",1) @@ -566,7 +562,7 @@ DEFINE_MOP(MOP_wcmnri, {mopdRegCCD, mopdReg32IS,mopdImm12},0,kLtAlu,"cmn","1,2", /* MOP_wcmnrr -- register, shifted register, AArch64 cmp has no dest operand */ DEFINE_MOP(MOP_wcmnrr, {mopdRegCCD, mopdReg32IS,mopdReg32IS},0,kLtAlu,"cmn","1,2",1) /* MOP_xcmnri -- AArch64 cmp has no dest operand */ -DEFINE_MOP(MOP_xcmnri, {mopdRegCCD, mopdReg64IS,mopdImm12},0,kLtAlu,"cmn","1,2",1) +DEFINE_MOP(MOP_xcmnri, {mopdRegCCD, mopdReg64IS,mopdImm16},0,kLtAlu,"cmn","1,2",1) /* MOP_xcmnrr -- register, shifted register, AArch64 cmp has no dest operand */ DEFINE_MOP(MOP_xcmnrr, {mopdRegCCD, mopdReg64IS,mopdReg64IS},0,kLtAlu,"cmn","1,2",1) @@ -611,9 +607,9 @@ DEFINE_MOP(MOP_dstr, {mopdReg64FS,mopdMem64D},ISSTORE|CANTHROW,kLtStore3plus,"st /* AArch64 STP. */ /* MOP_wstp */ -DEFINE_MOP(MOP_wstp, {mopdReg32IS,mopdReg32IS,mopdMem32D},ISSTORE|ISSTOREPAIR|CANTHROW,kLtStore2,"stp","0,1,2",1) +DEFINE_MOP(MOP_wstp, {mopdReg32IS,mopdReg32IS,mopdMem32PD},ISSTORE|ISSTOREPAIR|CANTHROW,kLtStore2,"stp","0,1,2",1) /* MOP_xstp */ -DEFINE_MOP(MOP_xstp, {mopdReg64IS,mopdReg64IS,mopdMem64D},ISSTORE|ISSTOREPAIR|CANTHROW,kLtStore3plus,"stp","0,1,2",1) +DEFINE_MOP(MOP_xstp, {mopdReg64IS,mopdReg64IS,mopdMem64PD},ISSTORE|ISSTOREPAIR|CANTHROW,kLtStore3plus,"stp","0,1,2",1) /* AArch64 does not define STPSW. It has no practical value. */ /* MOP_sstp */ DEFINE_MOP(MOP_sstp, {mopdReg32FS,mopdReg32FS,mopdMem32D},ISSTORE|ISSTOREPAIR|CANTHROW,kLtAdvsimdMulQ,"stp","0,1,2",1) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_offset_adjust.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_offset_adjust.h index 97ce1185037102fa71ca17207e42007ca2bb3dbe..bb690c970dab52fe0720fc7a85e368a6505eb7f8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_offset_adjust.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_offset_adjust.h @@ -31,6 +31,7 @@ class AArch64FPLROffsetAdjustment : public FPLROffsetAdjustment { private: void AdjustmentOffsetForOpnd(Insn &insn, AArch64CGFunc &aarchCGFunc); + void AdjustmentOffsetForImmOpnd(Insn &insn, uint32 index, AArch64CGFunc &aarchCGFunc); void AdjustmentOffsetForFPLR(); }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h index 2cbd68cfc3bf0f4c520558f6d99defc2c67c7083..6eb3c1430eac62447ae685712e6fee494cd619aa 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -150,11 +150,7 @@ class AArch64ImmOperand : public ImmOperand { } bool IsInBitSize(uint8 size, uint8 nLowerZeroBits) const override { - /* mask1 is a 64bits number that is all 1 shifts left size bits */ - const uint64 mask1 = 0xffffffffffffffffUL << size; - /* mask2 is a 64 bits number that nlowerZeroBits are all 1, higher bits aro all 0 */ - uint64 mask2 = (static_cast(1) << static_cast(nLowerZeroBits)) - 1UL; - return (mask2 & value) == 0UL && (mask1 & ((static_cast(value)) >> nLowerZeroBits)) == 0UL; + return maplebe::IsBitSizeImmediate(static_cast(value), size, nLowerZeroBits); } bool IsBitmaskImmediate() const { @@ -812,11 +808,6 @@ class AArch64MemOperand : public MemOperand { static constexpr int32 kLdpStp64SimmLowerBound = -512; /* multiple of 8 */ static constexpr int32 kLdpStp64SimmUpperBound = 504; - static constexpr int32 kMaxPimm8 = 4095; - static constexpr int32 kMaxPimm16 = 8190; - static constexpr int32 kMaxPimm32 = 16380; - static constexpr int32 kMaxPimm64 = 32760; - static const int32 kMaxPimms[4]; AArch64AddressingMode addrMode; diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 9a59aa68fd58d994d85d1e90e2ceece9d13a1be0..4e4d45d429e78cf7ee90352777842ad256dca0c9 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -189,7 +189,7 @@ class CGFunc { virtual Operand *SelectStrConst(MIRStrConst &strConst) = 0; virtual Operand *SelectStr16Const(MIRStr16Const &strConst) = 0; virtual void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; - virtual Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1) = 0; + virtual Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; virtual Operand &SelectCGArrayElemAdd(BinaryNode &node) = 0; virtual Operand *SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1) = 0; virtual void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; 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 9b8c86a90addfdb20c8c978ff85e0262466ac5b0..71bbf519f592fcd30e59615947f18912e6613673 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -525,6 +525,8 @@ bool AArch64CGFunc::IsImmediateValueInRange(MOperator mOp, int64 immVal, bool is bool AArch64CGFunc::IsStoreMop(MOperator mOp) const { switch (mOp) { + case MOP_sstr: + case MOP_dstr: case MOP_xstr: case MOP_wstr: case MOP_wstrb: @@ -631,7 +633,12 @@ void AArch64CGFunc::SelectCopyRegOpnd(Operand &dest, PrimType dtype, Operand::Op bool isIntactIndexed = memOpnd->IsIntactIndexed(); bool isPostIndexed = memOpnd->IsPostIndexed(); bool isPreIndexed = memOpnd->IsPreIndexed(); - bool isInRange = IsImmediateValueInRange(strMop, immVal, is64Bits, isIntactIndexed, isPostIndexed, isPreIndexed); + bool isInRange = false; + if (!GetMirModule().IsCModule()) { + isInRange = IsImmediateValueInRange(strMop, immVal, is64Bits, isIntactIndexed, isPostIndexed, isPreIndexed); + } else { + isInRange = !IsPrimitiveFloat(stype) && IsOperandImmValid(strMop, memOpnd, kInsnSecondOpnd); + } bool isMopStr = IsStoreMop(strMop); if (isInRange || !isMopStr) { GetCurBB()->AppendInsn(GetCG()->BuildInstruction(strMop, src, dest)); @@ -741,6 +748,38 @@ bool AArch64CGFunc::IsImmediateOffsetOutOfRange(AArch64MemOperand &memOpnd, uint } } +bool AArch64CGFunc::IsOperandImmValid(MOperator mOp, Operand *o, uint32 opndIdx) { + const AArch64MD *md = &AArch64CG::kMd[mOp]; + if (md->IsLoadStorePair()) { + opndIdx++; + } + auto *opndProp = static_cast(md->operand[opndIdx]); + if (!opndProp->IsContainImm()) { + return true; + } + Operand::OperandType opndTy = opndProp->GetOperandType(); + if (opndTy == Operand::kOpdMem) { + auto *memOpnd = static_cast(o); + if (md->IsLoadStorePair() || + (memOpnd->GetAddrMode() == AArch64MemOperand::kAddrModeBOi && memOpnd->IsIntactIndexed())) { + int32 offsetValue = memOpnd->GetOffsetImmediate()->GetOffsetValue(); + if (memOpnd->GetOffsetImmediate()->GetVary() == kUnAdjustVary) { + offsetValue += static_cast(GetMemlayout())->RealStackFrameSize() + 0xff; + } + offsetValue += 2 * kIntregBytelen; /* Refer to the above comment */ + return static_cast(opndProp)->IsValidImmOpnd(offsetValue); + } else { + int32 offsetValue = memOpnd->GetOffsetImmediate()->GetOffsetValue(); + return (offsetValue <= static_cast(k256BitSize) && offsetValue >= kNegative256BitSize); + } + } else if (opndTy == Operand::kOpdImmediate) { + return static_cast(opndProp)->IsValidImmOpnd(static_cast(o)->GetValue()); + } else { + CHECK_FATAL(false, "This Operand does not contain immediate"); + } + return true; +} + AArch64MemOperand &AArch64CGFunc::CreateReplacementMemOperand(uint32 bitLen, RegOperand &baseReg, int32 offset) { return static_cast(CreateMemOpnd(baseReg, offset, bitLen)); @@ -2385,7 +2424,7 @@ void AArch64CGFunc::SelectGoto(GotoNode &stmt) { GetCurBB()->SetKind(BB::kBBGoto); } -Operand *AArch64CGFunc::SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1) { +Operand *AArch64CGFunc::SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) { PrimType dtype = node.GetPrimType(); bool isSigned = IsSignedInteger(dtype); uint32 dsize = GetPrimTypeBitSize(dtype); @@ -2394,9 +2433,22 @@ Operand *AArch64CGFunc::SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opn /* promoted type */ PrimType primType = isFloat ? dtype : ((is64Bits ? (isSigned ? PTY_i64 : PTY_u64) : (isSigned ? PTY_i32 : PTY_u32))); - RegOperand &resOpnd = CreateRegisterOperandOfType(primType); - SelectAdd(resOpnd, opnd0, opnd1, primType); - return &resOpnd; + RegOperand *resOpnd = nullptr; + if (parent.GetOpCode() == OP_regassign) { + auto ®AssignNode = static_cast(parent); + PregIdx pregIdx = regAssignNode.GetRegIdx(); + if (IsSpecialPseudoRegister(pregIdx)) { + /* if it is one of special registers */ + ASSERT(-pregIdx != kSregRetval0, "the dest of RegAssign node must not be kSregRetval0"); + resOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx); + } else { + resOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); + } + } else { + resOpnd = &CreateRegisterOperandOfType(primType); + } + SelectAdd(*resOpnd, opnd0, opnd1, primType); + return resOpnd; } void AArch64CGFunc::SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { 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 81f57852c202735f6d2a2cccf2547bbead437002..911401f937c5de89f44a0059a6daf83befd32f1d 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 @@ -617,9 +617,13 @@ void GraphColorRegAllocator::SetupLiveRangeByOp(Operand &op, Insn &insn, bool is } #ifdef MOVE_COALESCE if (insn.GetMachineOpcode() == MOP_xmovrr || insn.GetMachineOpcode() == MOP_wmovrr) { - RegOperand &opnd = static_cast(insn.GetOperand(1)); - if (opnd.GetRegisterNumber() < kAllRegNum) { - lr->InsertElemToPrefs(opnd->GetRegisterNumber() - R0); + RegOperand &opnd1 = static_cast(insn.GetOperand(1)); + if (opnd1.GetRegisterNumber() < kAllRegNum) { + lr->InsertElemToPrefs(opnd1.GetRegisterNumber() - R0); + } + RegOperand &opnd0 = static_cast(insn.GetOperand(0)); + if (opnd0.GetRegisterNumber() < kAllRegNum) { + lr->InsertElemToPrefs(opnd0.GetRegisterNumber() - R0); } } #endif /* MOVE_COALESCE */ @@ -1142,7 +1146,11 @@ void GraphColorRegAllocator::Separate() { } #endif /* OPTIMIZE_FOR_PROLOG */ if (HaveAvailableColor(*lr, lr->GetNumBBConflicts() + lr->GetPregvetoSize() + lr->GetForbiddenSize())) { - unconstrained.emplace_back(lr); + if (lr->GetPrefs().size()) { + unconstrainedPref.emplace_back(lr); + } else { + unconstrained.emplace_back(lr); + } } else if (lr->IsMustAssigned()) { mustAssigned.emplace_back(lr); } else { @@ -1151,6 +1159,9 @@ void GraphColorRegAllocator::Separate() { } if (GCRA_DUMP) { LogInfo::MapleLogger() << "Unconstrained : "; + for (auto lr : unconstrainedPref) { + LogInfo::MapleLogger() << lr->GetRegNO() << " "; + } for (auto lr : unconstrained) { LogInfo::MapleLogger() << lr->GetRegNO() << " "; } @@ -2008,6 +2019,9 @@ void GraphColorRegAllocator::SplitAndColor() { /* handle constrained */ SplitAndColorForEachLr(constrained, true); + /* assign color for unconstained */ + SplitAndColorForEachLr(unconstrainedPref, false); + /* assign color for unconstained */ SplitAndColorForEachLr(unconstrained, false); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_immediate.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_immediate.cpp index ac20dfd6eb419ef4f23e2197a30181a9199960a6..d08f9f5ca0bc9ad62fdb884bcf1a0d32541f23a8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_immediate.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_immediate.cpp @@ -35,6 +35,14 @@ constexpr std::array bitmaskImmMultTable = { }; }; +bool IsBitSizeImmediate(uint64 val, uint32 bitLen, uint32 nLowerZeroBits) { + /* mask1 is a 64bits number that is all 1 shifts left size bits */ + const uint64 mask1 = 0xffffffffffffffffUL << bitLen; + /* mask2 is a 64 bits number that nlowerZeroBits are all 1, higher bits aro all 0 */ + uint64 mask2 = (1UL << static_cast(nLowerZeroBits)) - 1UL; + return (mask2 & val) == 0UL && (mask1 & ((static_cast(val)) >> nLowerZeroBits)) == 0UL; +}; + bool IsBitmaskImmediate(uint64 val, uint32 bitLen) { ASSERT(val != 0, "IsBitmaskImmediate() don's accept 0 or -1"); ASSERT(static_cast(val) != -1, "IsBitmaskImmediate() don's accept 0 or -1"); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index ee6ea075627d8be168795dc7a8bdd5e41524a9a8..364b836ba4623a6b93552adf32965ce8836b3d15 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -14,6 +14,7 @@ */ #include "aarch64_offset_adjust.h" #include "aarch64_cgfunc.h" +#include "aarch64_cg.h" namespace maplebe { void AArch64FPLROffsetAdjustment::Run() { @@ -50,21 +51,47 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF ofstOpnd->SetVary(kAdjustVary); } if (ofstOpnd->GetVary() == kAdjustVary) { - if (aarchCGFunc.IsImmediateOffsetOutOfRange(memOpnd, memOpnd.GetSize())) { + bool condition = aarchCGFunc.IsOperandImmValid(insn.GetMachineOpcode(), &memOpnd, i); + if (!condition) { AArch64MemOperand &newMemOpnd = aarchCGFunc.SplitOffsetWithAddInstruction( memOpnd, memOpnd.GetSize(), static_cast(R17), false, &insn); insn.SetOperand(i, newMemOpnd); } } } else if (opnd.IsIntImmediate()) { - auto &immOpnd = static_cast(opnd); - if (immOpnd.GetVary() == kUnAdjustVary) { - immOpnd.Add(static_cast(memLayout)->RealStackFrameSize() - - memLayout->SizeOfArgsToStackPass()); + AdjustmentOffsetForImmOpnd(insn, i, aarchCGFunc); + } + } +} + +void AArch64FPLROffsetAdjustment::AdjustmentOffsetForImmOpnd(Insn &insn, uint32 index, AArch64CGFunc &aarchCGFunc) { + auto &immOpnd = static_cast(insn.GetOperand(static_cast(index))); + MemLayout *memLayout = aarchCGFunc.GetMemlayout(); + if (immOpnd.GetVary() == kUnAdjustVary) { + int64 ofst = static_cast(memLayout)->RealStackFrameSize() - memLayout->SizeOfArgsToStackPass(); + immOpnd.Add(ofst); + } + if (!aarchCGFunc.IsOperandImmValid(insn.GetMachineOpcode(), &immOpnd, index)) { + if (insn.GetMachineOpcode() >= MOP_xaddrri24 && insn.GetMachineOpcode() <= MOP_waddrri12) { + PrimType destTy = + static_cast(insn.GetOperand(kInsnFirstOpnd)).GetSize() == k64BitSize ? PTY_i64 : PTY_i32; + RegOperand *resOpnd = aarchCGFunc.GetBaseRegForSplit(static_cast(R17)); + AArch64ImmOperand ©ImmOpnd = aarchCGFunc.CreateImmOperand( + immOpnd.GetValue(), immOpnd.GetSize(), immOpnd.IsSignedValue()); + aarchCGFunc.SelectAddAfterInsn(*resOpnd, insn.GetOperand(kInsnSecondOpnd), copyImmOpnd, destTy, false, insn); + insn.SetOperand(index, *resOpnd); + if (destTy == PTY_i64) { + insn.SetMOperator(MOP_xaddrrr); + } else { + insn.SetMOperator(MOP_waddrrr); } - immOpnd.SetVary(kAdjustVary); + } else { + CHECK_FATAL(false, "NIY"); } } + immOpnd.SetVary(kAdjustVary); + ASSERT(aarchCGFunc.IsOperandImmValid(insn.GetMachineOpcode(), &immOpnd, index), + "Invalid imm operand appears before offset adjusted"); } void AArch64FPLROffsetAdjustment::AdjustmentOffsetForFPLR() { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp index 8076213897aa611bc4e48dc61afd30d861fe2b10..7f27ec0c3f5ee9e2f62b0ef3bce556e71e9a557e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -189,8 +189,7 @@ void StImmOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { } } -const int32 AArch64MemOperand::kMaxPimms[4] = { AArch64MemOperand::kMaxPimm8, AArch64MemOperand::kMaxPimm16, - AArch64MemOperand::kMaxPimm32, AArch64MemOperand::kMaxPimm64 }; +const int32 AArch64MemOperand::kMaxPimms[4] = { kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64 }; Operand *AArch64MemOperand::GetOffset() const { switch (addrMode) { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_opnd.def b/src/mapleall/maple_be/src/cg/aarch64/aarch64_opnd.def index fdebd29b8475376546e8279d3b73c519d59c4f5b..1c6382288ee63b9abdbef64d734f148af899f84f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_opnd.def +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_opnd.def @@ -32,27 +32,119 @@ AArch64OpndProp mopdIntImm4Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegN AArch64OpndProp mopdIntImm5Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 5}; AArch64OpndProp mopdIntImm6Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 6}; AArch64OpndProp mopdIntImm8Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 8}; -AArch64OpndProp mopdIntImm12Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 12}; -AArch64OpndProp mopdIntImm13Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 13}; -AArch64OpndProp mopdIntImm16Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 16}; + +bool Imm12BitValid(int64 value) { + bool result = maplebe::IsBitSizeImmediate(value, kMaxImmVal12Bits, 0); + result |= maplebe::IsBitSizeImmediate(value, kMaxImmVal12Bits, kMaxImmVal12Bits); // for target linux-aarch64-gnu + return result; +} + +bool Imm12BitMaskValid(int64 value) { + if (value == 0 || static_cast(value) == -1) { + return true; + } + return maplebe::IsBitmaskImmediate(static_cast(value), k32BitSize); +} + +bool Imm13BitValid(int64 value) { + bool result = maplebe::IsBitSizeImmediate(value, kMaxImmVal13Bits, 0); + result |= maplebe::IsBitSizeImmediate(value, kMaxImmVal13Bits, kMaxImmVal13Bits); // for target linux-aarch64-gnu + return result; +} + +bool Imm13BitMaskValid(int64 value) { + if (value == 0 || static_cast(value) == -1) { + return true; + } + return maplebe::IsBitmaskImmediate(static_cast(value), k64BitSize); +} + +bool Imm16BitValid(int64 value) { + bool result = maplebe::IsBitSizeImmediate(value, kMaxImmVal16Bits, 0); + /* + * for target linux-aarch64-gnu + * aarch64 assembly takes up to 24-bits immediate, generating + * either cmp or cmp with shift 12 encoding + */ + result |= maplebe::IsBitSizeImmediate(value, kMaxImmVal12Bits, kMaxImmVal12Bits); + return result; +} + +AArch64ImmOpndProp mopdIntImm12Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 12, Imm12BitValid}; +AArch64ImmOpndProp mopdIntImm13Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 13, Imm13BitValid}; +AArch64ImmOpndProp mopdIntBitMaskImm12Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 12, Imm12BitMaskValid}; +AArch64ImmOpndProp mopdIntBitMaskImm13Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 13, Imm13BitMaskValid}; +AArch64ImmOpndProp mopdIntImm16Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 16, Imm16BitValid}; AArch64OpndProp mopdIntImm24Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 24}; AArch64OpndProp mopdIntImm32Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 32}; AArch64OpndProp mopdIntImm32Literal = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse | kLoadLiteral}, 32}; AArch64OpndProp mopdIntImm64Src = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 64}; AArch64OpndProp mopdIntImm64Literal = {Operand::kOpdImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse | kLoadLiteral}, 64}; AArch64OpndProp mopdFpzeroImm8Src = {Operand::kOpdFPZeroImmediate, {kRegTyUndef, kAllRegNum, kRegPropUse}, 8}; -AArch64OpndProp mopdMem8Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 8}; -AArch64OpndProp mopdMem16Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 16}; -AArch64OpndProp mopdMem32Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 32}; + +/* + * halfword : 1 + * 32bit - word : 2 + * 64bit - word : 3 + */ +bool StrLdrSignedOfstValid(int64 value, uint wordSize) { + if (value <= k256BitSize && value >= kNegative256BitSize) { + return true; + } else if ((value > k256BitSize) && (value <= kMaxPimm[wordSize])) { + uint64 mask = (1 << wordSize) - 1U; + return (static_cast(value) & mask) ? false : true; + } + return false; +} + + +bool StrLdr8ImmValid(int64 value) { + return StrLdrSignedOfstValid(value, 0); +} + +bool StrLdr16ImmValid(int64 value) { + return StrLdrSignedOfstValid(value, k1ByteSize); +} + +bool StrLdr32ImmValid(int64 value) { + return StrLdrSignedOfstValid(value, k2ByteSize); +} + +bool StrLdr32PairImmValid(int64 value) { + if ((value < k256BitSize) && (value >= kNegative256BitSize)) { + return (static_cast(value) & 3) ? false : true; + } + return false; +} + +bool StrLdr64ImmValid(int64 value) { + return StrLdrSignedOfstValid(value, k3ByteSize); +} + +bool StrLdr64PairImmValid(int64 value) { + if (value < k512BitSize && (value >= kNegative512BitSize)) { + return (static_cast(value) & 7) ? false : true; + } + return false; +} + +AArch64ImmOpndProp mopdMem8Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 8, StrLdr8ImmValid}; +AArch64ImmOpndProp mopdMem16Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 16, StrLdr16ImmValid}; +AArch64ImmOpndProp mopdMem32Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 32, StrLdr32ImmValid}; +AArch64ImmOpndProp mopdMemPair32Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 32, StrLdr32PairImmValid}; AArch64OpndProp mopdMem32SrcH = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse | kMemLow12}, 16}; AArch64OpndProp mopdMem32SrcL = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse | kMemLow12}, 16}; -AArch64OpndProp mopdMem64Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 64}; +AArch64ImmOpndProp mopdMem64Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 64, StrLdr64ImmValid}; +AArch64ImmOpndProp mopdMemPair64Src = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse}, 64, StrLdr64PairImmValid}; AArch64OpndProp mopdMem64SrcL = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropUse | kMemLow12}, 12}; -AArch64OpndProp mopdMem8Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 8}; -AArch64OpndProp mopdMem16Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 16}; -AArch64OpndProp mopdMem32Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 32}; -AArch64OpndProp mopdMem64Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 64}; +AArch64ImmOpndProp mopdMem8Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 8, StrLdr8ImmValid}; +AArch64ImmOpndProp mopdMem16Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 16, StrLdr16ImmValid}; +AArch64ImmOpndProp mopdMem32Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 32, StrLdr32ImmValid}; +AArch64ImmOpndProp mopdMem64Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 64, StrLdr64ImmValid}; +AArch64ImmOpndProp mopdMemPair32Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 32, StrLdr32PairImmValid}; +AArch64ImmOpndProp mopdMemPair64Dest = {Operand::kOpdMem, {kRegTyUndef, kAllRegNum, kRegPropDef }, 64, StrLdr64PairImmValid}; + AArch64OpndProp mopdLbl64Src = {Operand::kOpdBBAddress, {kRegTyUndef,kAllRegNum, kRegPropUse}, 64}; AArch64OpndProp mopdLiteralSrc = {Operand::kOpdStImmediate, {kRegTyUndef,kAllRegNum, kRegPropUse}, 64}; @@ -105,14 +197,18 @@ AArch64OpndProp *mopdMem = &mopdMem32Src; AArch64OpndProp *mopdMem8S = &mopdMem8Src; AArch64OpndProp *mopdMem16S = &mopdMem16Src; AArch64OpndProp *mopdMem32S = &mopdMem32Src; +AArch64OpndProp *mopdMem32PS = &mopdMemPair32Src; AArch64OpndProp *mopdMem32SL = &mopdMem32SrcL; AArch64OpndProp *mopdMem32SH = &mopdMem32SrcH; +AArch64OpndProp *mopdMem64PS = &mopdMemPair64Src; AArch64OpndProp *mopdMem64S = &mopdMem64Src; AArch64OpndProp *mopdMem64SL = &mopdMem64SrcL; AArch64OpndProp *mopdMem8D = &mopdMem8Dest; AArch64OpndProp *mopdMem16D = &mopdMem16Dest; AArch64OpndProp *mopdMem32D = &mopdMem32Dest; +AArch64OpndProp *mopdMem32PD = &mopdMemPair32Dest; AArch64OpndProp *mopdMem64D = &mopdMem64Dest; +AArch64OpndProp *mopdMem64PD = &mopdMemPair64Dest; AArch64OpndProp *mopdMem32SPRE = &mopdMem32SrcPre; AArch64OpndProp *mopdMem32SPOST = &mopdMem32SrcPost; AArch64OpndProp *mopdMem64SPRE = &mopdMem64SrcPre; @@ -124,7 +220,9 @@ AArch64OpndProp *mopdImm5 = &mopdIntImm5Src; AArch64OpndProp *mopdImm6 = &mopdIntImm6Src; AArch64OpndProp *mopdImm8 = &mopdIntImm8Src; AArch64OpndProp *mopdImm12 = &mopdIntImm12Src; +AArch64OpndProp *mopdImmBm12 = &mopdIntBitMaskImm12Src; AArch64OpndProp *mopdImm13 = &mopdIntImm13Src; +AArch64OpndProp *mopdImmBm13 = &mopdIntBitMaskImm13Src; AArch64OpndProp *mopdImm16 = &mopdIntImm16Src; AArch64OpndProp *mopdImm24 = &mopdIntImm24Src; AArch64OpndProp *mopdImm32 = &mopdIntImm32Src; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index a8d92666ee373c53c750f4f08e3b9226c862c737..3cd16e26c986ee1b5ed4aa4286b03db0bceb3816 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -160,7 +160,7 @@ bool AArch64GenProEpilog::TailCallOpt() { exitBB = cgFunc.GetExitBBsVec().front(); } - CHECK_FATAL(exitBB->GetFirstInsn() == nullptr, "exit bb should be empty."); + CHECK_FATAL(exitBB->GetFirstMachineInsn() == nullptr, "exit bb should be empty."); /* Count how many call insns in the whole function. */ uint32 nCount = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index e49ded12a0cc72885675888bad1ed934fb862ec5..45985bcb9a1d92d9a445d2b234dc9f00754c9ab8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -872,6 +872,10 @@ void AArch64ReachingDefinition::InitInfoForMemOperand(Insn &insn, Operand &opnd, return; } if ((mode & kRDMemAnalysis) && IsFrameReg(*base)) { + if (index != nullptr) { + SetAnalysisMode(kRDRegAnalysis); + return; + } CHECK_FATAL(index == nullptr, "Existing [x29 + index] Memory Address"); ASSERT(memOpnd.GetOffsetImmediate(), "offset must be a immediate value"); int32 offsetVal = memOpnd.GetOffsetImmediate()->GetOffsetValue(); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 68b230b2b5b9c71b74ff13e525e0ee3e8a590774..dfdde05331251be84bdbd2a2cf6fe533fd46f775 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -87,9 +87,8 @@ Operand *HandleConstStr16(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc } Operand *HandleAdd(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { - (void)parent; return cgFunc.SelectAdd(static_cast(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), - *cgFunc.HandleExpr(expr, *expr.Opnd(1))); + *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent); } Operand *HandleCGArrayElemAdd(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { diff --git a/src/mapleall/maple_driver/defs/phases.def b/src/mapleall/maple_driver/defs/phases.def index 6e54cc430e6433d582e22a793b14febee6e4eb45..24de1a99aeb4ec4fd1e697c7dc7f36afd1fe0ed0 100644 --- a/src/mapleall/maple_driver/defs/phases.def +++ b/src/mapleall/maple_driver/defs/phases.def @@ -25,8 +25,8 @@ ADD_PHASE("javaintrnlowering", JAVALANG) ADD_PHASE("simplify", Options::O2) ADD_PHASE("inline", Options::O2 && Options::useInline) // mephase begin -ADD_PHASE("mecfgbuild", CLANG && MeOption::optLevel >= 3) -ADD_PHASE("injectiv", CLANG && MeOption::optLevel >= 3) +ADD_PHASE("mecfgbuild", CLANG && MeOption::optLevel >= 3) +ADD_PHASE("injectiv", CLANG && MeOption::optLevel >= 3) ADD_PHASE("ssatab", CLANG && MeOption::optLevel >= 3) ADD_PHASE("aliasclass", CLANG && MeOption::optLevel >= 3) ADD_PHASE("ssa", CLANG && MeOption::optLevel >= 3) diff --git a/src/mapleall/maple_ipa/include/inline.h b/src/mapleall/maple_ipa/include/inline.h index de4104c382a1a341e6fac321d3f842ddeb5b68db..fced8cb914bd8455617b32fd8b25af909008a2f5 100644 --- a/src/mapleall/maple_ipa/include/inline.h +++ b/src/mapleall/maple_ipa/include/inline.h @@ -110,7 +110,7 @@ class MInline { void InitRCWhiteList(); void ApplyInlineListInfo(const std::string &list, MapleMap*> &listCallee); uint32 RenameSymbols(MIRFunction&, const MIRFunction&, uint32) const; - void ReplaceSymbols(BaseNode*, uint32, const std::unordered_map&) const; + void ReplaceSymbols(BaseNode*, uint32, const std::vector*) const; uint32 RenameLabels(MIRFunction&, const MIRFunction&, uint32) const; void ReplaceLabels(BaseNode&, uint32) const; uint32 RenamePregs(const MIRFunction&, const MIRFunction&, std::unordered_map&) const; @@ -126,6 +126,7 @@ class MInline { return false; } + void ConvertPStaticToFStatic(MIRFunction &func) const; bool CheckCalleeAndInline(MIRFunction*, BlockNode *enclosingBlk, CallNode*, MIRFunction*); void InlineCalls(const CGNode&); void InlineCallsBlock(MIRFunction&, BlockNode&, BaseNode&, bool&); diff --git a/src/mapleall/maple_ipa/src/inline.cpp b/src/mapleall/maple_ipa/src/inline.cpp index fd52719f406d443e12d4808e592e1b550ac63576..2d2aae4fb30b710872015cb8b5605d242c62c5d6 100644 --- a/src/mapleall/maple_ipa/src/inline.cpp +++ b/src/mapleall/maple_ipa/src/inline.cpp @@ -199,6 +199,7 @@ uint32 MInline::RenameSymbols(MIRFunction &caller, const MIRFunction &callee, ui if (sym == nullptr) { continue; } + CHECK_FATAL(sym->GetStorageClass() != kScPstatic, "pstatic symbols should have been converted to fstatic ones"); std::string syName(kUnderlineStr); // Use puIdx here instead of func name because our mangled func name can be // really long. @@ -232,31 +233,33 @@ uint32 MInline::RenameSymbols(MIRFunction &caller, const MIRFunction &callee, ui return stIdxOff; } -static StIdx UpdateIdx(const StIdx &stIdx, uint32 stIdxOff, const std::unordered_map &staticOld2New) { +static StIdx UpdateIdx(const StIdx &stIdx, uint32 stIdxOff, const std::vector *oldStIdx2New) { + // If the callee has pstatic symbols, we will save all symbol mapping info in the oldStIdx2New. + // So if this oldStIdx2New is nullptr, we only use stIdxOff to update stIdx, otherwise we only use oldStIdx2New. StIdx newStIdx = stIdx; - auto it = staticOld2New.find(newStIdx.FullIdx()); - if (it != staticOld2New.end()) { - newStIdx.SetFullIdx(it->second); - } else { + if (oldStIdx2New == nullptr) { newStIdx.SetIdx(newStIdx.Idx() + stIdxOff); + } else { + CHECK_FATAL(newStIdx.Idx() < oldStIdx2New->size(), "stIdx out of range"); + newStIdx.SetFullIdx((*oldStIdx2New)[newStIdx.Idx()]); } return newStIdx; } void MInline::ReplaceSymbols(BaseNode *baseNode, uint32 stIdxOff, - const std::unordered_map &staticOld2New) const { + const std::vector *oldStIdx2New) const { if (baseNode == nullptr) { return; } // IfStmtNode's `numOpnds` and actual operands number are different, so we treat it as a special case if (baseNode->GetOpCode() == OP_if) { IfStmtNode *ifStmtNode = static_cast(baseNode); - ReplaceSymbols(baseNode->Opnd(0), stIdxOff, staticOld2New); + ReplaceSymbols(baseNode->Opnd(0), stIdxOff, oldStIdx2New); if (ifStmtNode->GetThenPart() != nullptr) { - ReplaceSymbols(ifStmtNode->GetThenPart(), stIdxOff, staticOld2New); + ReplaceSymbols(ifStmtNode->GetThenPart(), stIdxOff, oldStIdx2New); } if (ifStmtNode->GetElsePart() != nullptr) { - ReplaceSymbols(ifStmtNode->GetElsePart(), stIdxOff, staticOld2New); + ReplaceSymbols(ifStmtNode->GetElsePart(), stIdxOff, oldStIdx2New); } return; } @@ -264,19 +267,19 @@ void MInline::ReplaceSymbols(BaseNode *baseNode, uint32 stIdxOff, if (baseNode->GetOpCode() == OP_block) { BlockNode *blockNode = static_cast(baseNode); for (auto &stmt : blockNode->GetStmtNodes()) { - ReplaceSymbols(&stmt, stIdxOff, staticOld2New); + ReplaceSymbols(&stmt, stIdxOff, oldStIdx2New); } } else if (baseNode->GetOpCode() == OP_dassign) { DassignNode *dassNode = static_cast(baseNode); // Skip globals. if (dassNode->GetStIdx().Islocal()) { - dassNode->SetStIdx(UpdateIdx(dassNode->GetStIdx(), stIdxOff, staticOld2New)); + dassNode->SetStIdx(UpdateIdx(dassNode->GetStIdx(), stIdxOff, oldStIdx2New)); } } else if ((baseNode->GetOpCode() == OP_addrof || baseNode->GetOpCode() == OP_dread)) { AddrofNode *addrNode = static_cast(baseNode); // Skip globals. if (addrNode->GetStIdx().Islocal()) { - addrNode->SetStIdx(UpdateIdx(addrNode->GetStIdx(), stIdxOff, staticOld2New)); + addrNode->SetStIdx(UpdateIdx(addrNode->GetStIdx(), stIdxOff, oldStIdx2New)); } } else if (returnVector != nullptr) { if (returnVector->size() > 1) { @@ -284,27 +287,27 @@ void MInline::ReplaceSymbols(BaseNode *baseNode, uint32 stIdxOff, } // Skip globals. if (returnVector->size() == 1 && !(*returnVector).at(0).second.IsReg() && (*returnVector).at(0).first.Islocal()) { - (*returnVector)[0].first = UpdateIdx((*returnVector).at(0).first, stIdxOff, staticOld2New); + (*returnVector)[0].first = UpdateIdx((*returnVector).at(0).first, stIdxOff, oldStIdx2New); } } else if (baseNode->GetOpCode() == OP_foreachelem) { ForeachelemNode *forEachNode = static_cast(baseNode); // Skip globals. if (forEachNode->GetElemStIdx().Idx() != 0) { - forEachNode->SetElemStIdx(UpdateIdx(forEachNode->GetElemStIdx(), stIdxOff, staticOld2New)); + forEachNode->SetElemStIdx(UpdateIdx(forEachNode->GetElemStIdx(), stIdxOff, oldStIdx2New)); } if (forEachNode->GetArrayStIdx().Idx() != 0) { - forEachNode->SetArrayStIdx(UpdateIdx(forEachNode->GetArrayStIdx(), stIdxOff, staticOld2New)); + forEachNode->SetArrayStIdx(UpdateIdx(forEachNode->GetArrayStIdx(), stIdxOff, oldStIdx2New)); } } else if (baseNode->GetOpCode() == OP_doloop) { DoloopNode *doLoopNode = static_cast(baseNode); // Skip globals. if (!doLoopNode->IsPreg() && doLoopNode->GetDoVarStIdx().Idx()) { - doLoopNode->SetDoVarStIdx(UpdateIdx(doLoopNode->GetDoVarStIdx(), stIdxOff, staticOld2New)); + doLoopNode->SetDoVarStIdx(UpdateIdx(doLoopNode->GetDoVarStIdx(), stIdxOff, oldStIdx2New)); } } // Search for nested dassign/dread/addrof node that may include a symbol index. for (size_t i = 0; i < baseNode->NumOpnds(); ++i) { - ReplaceSymbols(baseNode->Opnd(i), stIdxOff, staticOld2New); + ReplaceSymbols(baseNode->Opnd(i), stIdxOff, oldStIdx2New); } } @@ -600,6 +603,61 @@ void MInline::RecordRealCaller(MIRFunction &caller, const MIRFunction &callee) { } } +void MInline::ConvertPStaticToFStatic(MIRFunction &func) const { + bool hasPStatic = false; + for (int i = 0; i < func.GetSymbolTabSize(); ++i) { + MIRSymbol *sym = func.GetSymbolTabItem(i); + if (sym != nullptr && sym->GetStorageClass() == kScPstatic) { + hasPStatic = true; + break; + } + } + if (!hasPStatic) { + return; // No pu-static symbols, just return + } + std::vector localSymbols; + std::vector oldStIdx2New(func.GetSymbolTabSize(), 0); + int pstaticNum = 0; + for (int i = 0; i < func.GetSymbolTabSize(); ++i) { + MIRSymbol *sym = func.GetSymbolTabItem(i); + if (sym == nullptr) { + continue; + } + StIdx oldStIdx = sym->GetStIdx(); + if (sym->GetStorageClass() == kScPstatic) { + ++pstaticNum; + // convert pu-static to file-static + // pstatic symbol name mangling example: "foo_bar" --> "__pstatic__125__foo_bar" + const auto &symNameOrig = sym->GetName(); + std::string symNameMangling = "__pstatic__" + std::to_string(func.GetPuidx()) + kVerticalLineStr + symNameOrig; + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(symNameMangling); + MIRSymbol *newSym = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); + newSym->SetNameStrIdx(strIdx); + newSym->SetStorageClass(kScFstatic); + newSym->SetTyIdx(sym->GetTyIdx()); + newSym->SetSKind(sym->GetSKind()); + newSym->SetAttrs(sym->GetAttrs()); + newSym->SetValue(sym->GetValue()); + bool success = GlobalTables::GetGsymTable().AddToStringSymbolMap(*newSym); + CHECK_FATAL(success, "Found repeated global symbols!"); + oldStIdx2New[i] = newSym->GetStIdx().FullIdx(); + } else { + StIdx newStIdx(oldStIdx); + newStIdx.SetIdx(oldStIdx.Idx() - pstaticNum); + oldStIdx2New[i] = newStIdx.FullIdx(); + sym->SetStIdx(newStIdx); + localSymbols.push_back(sym); + } + } + func.GetSymTab()->Clear(); + func.GetSymTab()->PushNullSymbol(); + for (MIRSymbol *sym : localSymbols) { + func.GetSymTab()->AddStOutside(sym); + } + // The stIdxOff will be ignored, 0 is just a placeholder + ReplaceSymbols(func.GetBody(), 0, &oldStIdx2New); +} + // Inline CALLEE into CALLER. bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNode &callStmt, MIRFunction &callee) { if (callee.IsEmpty()) { @@ -616,6 +674,9 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo } else { inlinedTimes = 0; } + // If the callee has local static variables, We convert local pu-static symbols to global file-static symbol to avoid + // multiple definition for these static symbols + ConvertPStaticToFStatic(callee); // Step 1: Clone CALLEE's body. auto getBody = [callee, this] (BlockNode* funcBody) { if (callee.IsFromMpltInline()) { @@ -650,20 +711,21 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo newBody = getBody(callee.GetBody()); } // Step 2: Rename symbols, labels, pregs - std::unordered_map staticOld2New; uint32 stIdxOff = RenameSymbols(caller, callee, inlinedTimes); uint32 labIdxOff = RenameLabels(caller, callee, inlinedTimes); std::unordered_map pregOld2New; uint32 regIdxOff = RenamePregs(caller, callee, pregOld2New); // Step 3: Replace symbols, labels, pregs CHECK_NULL_FATAL(newBody); - ReplaceSymbols(newBody, stIdxOff, staticOld2New); + // Callee has no pu-static symbols now, so we only use stIdxOff to update stIdx, set oldStIdx2New nullptr + ReplaceSymbols(newBody, stIdxOff, nullptr); ReplaceLabels(*newBody, labIdxOff); ReplacePregs(newBody, pregOld2New); // Step 4: Null check 'this' and assign actuals to formals. if (static_cast(callStmt.NumOpnds()) != callee.GetFormalCount()) { LogInfo::MapleLogger() << "warning: # formal arguments != # actual arguments in the function " << - callee.GetName() << "\n"; + callee.GetName() << ". [formal count] " << callee.GetFormalCount() << ", " << + "[argument count] " << callStmt.NumOpnds() << std::endl; } if (callee.GetFormalCount() > 0 && callee.GetFormal(0)->GetName() == kThisStr) { UnaryStmtNode *nullCheck = module.CurFuncCodeMemPool()->New(OP_assertnonnull); @@ -1024,7 +1086,7 @@ bool MInline::FuncInlinable(const MIRFunction &func) const { return false; } if (func.GetAttr(FUNCATTR_abstract) || func.GetAttr(FUNCATTR_const) || func.GetAttr(FUNCATTR_declared_synchronized) || - func.GetAttr(FUNCATTR_synchronized) || func.GetAttr(FUNCATTR_weak) || + func.GetAttr(FUNCATTR_synchronized) || func.GetAttr(FUNCATTR_weak) || func.GetAttr(FUNCATTR_varargs) || ((func.GetAttr(FUNCATTR_critical_native) || func.GetAttr(FUNCATTR_fast_native) || func.GetAttr(FUNCATTR_native)) && (func.GetBody() == nullptr || func.GetBody()->GetFirst() == nullptr))) { @@ -1064,11 +1126,13 @@ void MInline::InlineCalls(const CGNode &node) { return; } bool changed = false; + int currInlineDepth = 0; do { changed = false; currFuncBody = nullptr; InlineCallsBlock(*func, *(func->GetBody()), *(func->GetBody()), changed); - } while (changed); + ++currInlineDepth; + } while (changed && currInlineDepth < Options::inlineDepth); } void MInline::InlineCallsBlock(MIRFunction &func, BlockNode &enclosingBlk, BaseNode &baseNode, bool &changed) { @@ -1109,7 +1173,7 @@ InlineResult MInline::AnalyzeCallsite(const MIRFunction &caller, MIRFunction &ca if (callerList->empty()) { return InlineResult(false, "LIST_NOINLINE_FUNC"); } - if (callerList->find(calleeStrIdx) != callerList->end()) { + if (callerList->find(callerStrIdx) != callerList->end()) { return InlineResult(false, "LIST_NOINLINE_CALLSITE"); } } @@ -1137,6 +1201,15 @@ InlineResult MInline::AnalyzeCallsite(const MIRFunction &caller, MIRFunction &ca if (!FuncInlinable(callee)) { return InlineResult(false, "ATTR"); } + // Incompatible type conversion from arguments to formals + size_t realArgNum = std::min(callStmt.NumOpnds(), callee.GetFormalCount()); + for (size_t i = 0; i < realArgNum; ++i) { + PrimType formalPrimType = callee.GetFormal(i)->GetType()->GetPrimType(); + PrimType realArgPrimType = callStmt.Opnd(i)->GetPrimType(); + if (formalPrimType == PTY_agg ^ realArgPrimType == PTY_agg) { + return InlineResult(false, "INCOMPATIBLE_TYPE_CVT_FORM_ARG_TO_FORMAL"); + } + } if (!callee.GetLabelTab()->GetAddrTakenLabels().empty()) { return InlineResult(false, "ADDR_TAKEN_LABELS"); } @@ -1219,7 +1292,6 @@ InlineResult MInline::AnalyzeCallee(const MIRFunction &caller, MIRFunction &call // This is self recursive inline calleeBody = currFuncBody; } - if (funcToCostMap.find(&callee) != funcToCostMap.end()) { cost = funcToCostMap[&callee]; } else { @@ -1420,7 +1492,12 @@ AnalysisResult *DoInline::Run(MIRModule *module, ModuleResultMgr *mgr) { MemPool *memPool = memPoolCtrler.NewMemPool("inline mempool", false /* isLocalPool */); CallGraph *cg = static_cast(mgr->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, module)); CHECK_FATAL(cg != nullptr, "Expecting a valid CallGraph, found nullptr"); - + // Reset inlining threshold for other srcLang, especially for srcLangJava. Because those methods related to + // reflection in Java cannot be inlined safely. + if (module->GetSrcLang() != kSrcLangC) { + Options::inlineSmallFunctionThreshold = 15; + Options::inlineHotFunctionThreshold = 30; + } MInline mInline(*module, memPool, cg); mInline.Inline(); mInline.CleanupInline(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 8c2652799071f65022458c696169dcedef6b97c2..37a8fa4bc98c0b90411f56274e7712110c9e595f 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -530,6 +530,7 @@ class MIRSymbolTable { void Clear() { symbolTable.clear(); + strIdxToStIdxMap.clear(); } MIRSymbol *CloneLocalSymbol(const MIRSymbol &oldSym) const { diff --git a/src/mapleall/maple_ir/include/option.h b/src/mapleall/maple_ir/include/option.h index b69caa50fa1e38a8109a343b1d8975b388354421..0d7876538d987a24f5ec4b8633e92d8f1b44f8b8 100644 --- a/src/mapleall/maple_ir/include/option.h +++ b/src/mapleall/maple_ir/include/option.h @@ -73,6 +73,7 @@ class Options : public MapleDriverOptionBase { static uint32 inlineSmallFunctionThreshold; static uint32 inlineHotFunctionThreshold; static uint32 inlineRecursiveFunctionThreshold; + static uint32 inlineDepth; static uint32 inlineModuleGrowth; static uint32 inlineColdFunctionThreshold; static uint32 profileHotCount; diff --git a/src/mapleall/maple_ir/src/option.cpp b/src/mapleall/maple_ir/src/option.cpp index 2bdce1eb8cb2e02233d49195c96459018a64f99a..a5537228dbd2832788721ceb520737568a9d6376 100644 --- a/src/mapleall/maple_ir/src/option.cpp +++ b/src/mapleall/maple_ir/src/option.cpp @@ -36,9 +36,10 @@ bool Options::inlineWithProfile = false; bool Options::useInline = true; // Enabled by default bool Options::useCrossModuleInline = true; // Enabled by default std::string Options::noInlineFuncList = ""; -uint32 Options::inlineSmallFunctionThreshold = 15; -uint32 Options::inlineHotFunctionThreshold = 30; +uint32 Options::inlineSmallFunctionThreshold = 60; // Only for srcLangC, value will be reset later for other srcLang +uint32 Options::inlineHotFunctionThreshold = 100; // Only for srcLangC, value will be reset later for other srcLang uint32 Options::inlineRecursiveFunctionThreshold = 15; +uint32 Options::inlineDepth = 8; uint32 Options::inlineModuleGrowth = 10; uint32 Options::inlineColdFunctionThreshold = 3; uint32 Options::profileHotCount = 1000; @@ -129,6 +130,7 @@ enum OptionIndex { kInlineSmallFunctionThreshold, kInlineHotFunctionThreshold, kInlineRecursiveFunctionThreshold, + kInlineDepth, kInlineModuleGrowth, kInlineColdFunctionThreshold, kProfileHotCount, @@ -323,6 +325,15 @@ const Descriptor kUsage[] = { " --inline-recursive-function-threshold=15 \tThreshold for inlining recursive function\n", "mpl2mpl", {} }, + { kInlineDepth, + 0, + "", + "inline-depth", + kBuildTypeExperimental, + kArgCheckPolicyRequired, + " --inline-depth=8 \tMax call graph depth for inlining\n", + "mpl2mpl", + {} }, { kInlineModuleGrowth, 0, "", @@ -935,6 +946,14 @@ bool Options::SolveOptions(const std::vector