diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2018-09-19 18:46:29 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2018-09-19 18:46:29 +0000 |
| commit | a9e8765e3ebf1e0b455bc38bbb4ba5b8e7a4c9aa (patch) | |
| tree | 98056820393caa31914d4d1555370399de650ac2 /llvm/lib/Target | |
| parent | 852dd83be8b7586036877065e690f5bcb564ea86 (diff) | |
| download | bcm5719-llvm-a9e8765e3ebf1e0b455bc38bbb4ba5b8e7a4c9aa.tar.gz bcm5719-llvm-a9e8765e3ebf1e0b455bc38bbb4ba5b8e7a4c9aa.zip | |
[mips][microMIPS] Extending size reduction pass with MOVEP
The patch extends size reduction pass for MicroMIPS. Two MOVE
instructions are transformed into one MOVEP instrucition.
Patch by Milena Vujosevic Janicic.
Differential revision: https://reviews.llvm.org/D52037
llvm-svn: 342572
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp | 115 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 5 |
2 files changed, 109 insertions, 11 deletions
diff --git a/llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp b/llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp index 568cdfb5b11..f9062cc23da 100644 --- a/llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp +++ b/llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp @@ -31,13 +31,14 @@ namespace { /// Order of operands to transfer // TODO: Will be extended when additional optimizations are added enum OperandTransfer { - OT_NA, ///< Not applicable - OT_OperandsAll, ///< Transfer all operands - OT_Operands02, ///< Transfer operands 0 and 2 - OT_Operand2, ///< Transfer just operand 2 - OT_OperandsXOR, ///< Transfer operands for XOR16 - OT_OperandsLwp, ///< Transfer operands for LWP - OT_OperandsSwp, ///< Transfer operands for SWP + OT_NA, ///< Not applicable + OT_OperandsAll, ///< Transfer all operands + OT_Operands02, ///< Transfer operands 0 and 2 + OT_Operand2, ///< Transfer just operand 2 + OT_OperandsXOR, ///< Transfer operands for XOR16 + OT_OperandsLwp, ///< Transfer operands for LWP + OT_OperandsSwp, ///< Transfer operands for SWP + OT_OperandsMovep, ///< Transfer operands for MOVEP }; /// Reduction type @@ -170,6 +171,10 @@ private: // returns true on success. static bool ReduceSXtoSX16(ReduceEntryFunArgs *Arguments); + // Attempts to reduce two MOVE instructions into MOVEP instruction, + // returns true on success. + static bool ReduceMoveToMovep(ReduceEntryFunArgs *Arguments); + // Attempts to reduce arithmetic instructions, returns true on success. static bool ReduceArithmeticInstructions(ReduceEntryFunArgs *Arguments); @@ -243,6 +248,8 @@ ReduceEntryVector MicroMipsSizeReduce::ReduceTable = { OpInfo(OT_OperandsLwp), ImmField(0, -2048, 2048, 2)}, {RT_OneInstr, OpCodes(Mips::LW_MM, Mips::LWSP_MM), ReduceXWtoXWSP, OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)}, + {RT_TwoInstr, OpCodes(Mips::MOVE16_MM, Mips::MOVEP_MM), ReduceMoveToMovep, + OpInfo(OT_OperandsMovep), ImmField(0, 0, 0, -1)}, {RT_OneInstr, OpCodes(Mips::SB, Mips::SB16_MM), ReduceSXtoSX16, OpInfo(OT_OperandsAll), ImmField(0, 0, 16, 2)}, {RT_OneInstr, OpCodes(Mips::SB_MM, Mips::SB16_MM), ReduceSXtoSX16, @@ -562,6 +569,89 @@ bool MicroMipsSizeReduce::ReduceSXtoSX16(ReduceEntryFunArgs *Arguments) { return ReplaceInstruction(MI, Entry); } +// Returns true if Reg can be a source register +// of MOVEP instruction +static bool IsMovepSrcRegister(unsigned Reg) { + + if (Reg == Mips::ZERO || Reg == Mips::V0 || Reg == Mips::V1 || + Reg == Mips::S0 || Reg == Mips::S1 || Reg == Mips::S2 || + Reg == Mips::S3 || Reg == Mips::S4) + return true; + + return false; +} + +// Returns true if Reg can be a destination register +// of MOVEP instruction +static bool IsMovepDestinationReg(unsigned Reg) { + + if (Reg == Mips::A0 || Reg == Mips::A1 || Reg == Mips::A2 || + Reg == Mips::A3 || Reg == Mips::S5 || Reg == Mips::S6) + return true; + + return false; +} + +// Returns true if the registers can be a pair of destination +// registers in MOVEP instruction +static bool IsMovepDestinationRegPair(unsigned R0, unsigned R1) { + + if ((R0 == Mips::A0 && R1 == Mips::S5) || + (R0 == Mips::A0 && R1 == Mips::S6) || + (R0 == Mips::A0 && R1 == Mips::A1) || + (R0 == Mips::A0 && R1 == Mips::A2) || + (R0 == Mips::A0 && R1 == Mips::A3) || + (R0 == Mips::A1 && R1 == Mips::A2) || + (R0 == Mips::A1 && R1 == Mips::A3) || + (R0 == Mips::A2 && R1 == Mips::A3)) + return true; + + return false; +} + +bool MicroMipsSizeReduce::ReduceMoveToMovep(ReduceEntryFunArgs *Arguments) { + + const ReduceEntry &Entry = Arguments->Entry; + MachineBasicBlock::instr_iterator &NextMII = Arguments->NextMII; + const MachineBasicBlock::instr_iterator &E = + Arguments->MI->getParent()->instr_end(); + + if (NextMII == E) + return false; + + MachineInstr *MI1 = Arguments->MI; + MachineInstr *MI2 = &*NextMII; + + unsigned RegDstMI1 = MI1->getOperand(0).getReg(); + unsigned RegSrcMI1 = MI1->getOperand(1).getReg(); + + if (!IsMovepSrcRegister(RegSrcMI1)) + return false; + + if (!IsMovepDestinationReg(RegDstMI1)) + return false; + + if (MI2->getOpcode() != Entry.WideOpc()) + return false; + + unsigned RegDstMI2 = MI2->getOperand(0).getReg(); + unsigned RegSrcMI2 = MI2->getOperand(1).getReg(); + + if (!IsMovepSrcRegister(RegSrcMI2)) + return false; + + bool ConsecutiveForward; + if (IsMovepDestinationRegPair(RegDstMI1, RegDstMI2)) { + ConsecutiveForward = true; + } else if (IsMovepDestinationRegPair(RegDstMI2, RegDstMI1)) { + ConsecutiveForward = false; + } else + return false; + + NextMII = std::next(NextMII); + return ReplaceInstruction(MI1, Entry, MI2, ConsecutiveForward); +} + bool MicroMipsSizeReduce::ReduceXORtoXOR16(ReduceEntryFunArgs *Arguments) { MachineInstr *MI = Arguments->MI; @@ -641,18 +731,25 @@ bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI, } break; } + case OT_OperandsMovep: case OT_OperandsLwp: case OT_OperandsSwp: { if (ConsecutiveForward) { MIB.add(MI->getOperand(0)); MIB.add(MI2->getOperand(0)); MIB.add(MI->getOperand(1)); - MIB.add(MI->getOperand(2)); + if (OpTransfer == OT_OperandsMovep) + MIB.add(MI2->getOperand(1)); + else + MIB.add(MI->getOperand(2)); } else { // consecutive backward MIB.add(MI2->getOperand(0)); MIB.add(MI->getOperand(0)); MIB.add(MI2->getOperand(1)); - MIB.add(MI2->getOperand(2)); + if (OpTransfer == OT_OperandsMovep) + MIB.add(MI->getOperand(1)); + else + MIB.add(MI2->getOperand(2)); } LLVM_DEBUG(dbgs() << "and converting 32-bit: " << *MI2 diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index 33f03b954a8..e3823e0dfdb 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -728,9 +728,10 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) continue; - // Instructions LWP/SWP should not be in a delay slot as that + // Instructions LWP/SWP and MOVEP should not be in a delay slot as that // results in unpredictable behaviour - if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM)) + if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM || + Opcode == Mips::MOVEP_MM)) continue; Filler = CurrI; |

