llvm.org GIT mirror llvm / d4b7306
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342572 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Atanasyan 1 year, 9 months ago
4 changed file(s) with 224 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
3030 /// Order of operands to transfer
3131 // TODO: Will be extended when additional optimizations are added
3232 enum OperandTransfer {
33 OT_NA, ///< Not applicable
34 OT_OperandsAll, ///< Transfer all operands
35 OT_Operands02, ///< Transfer operands 0 and 2
36 OT_Operand2, ///< Transfer just operand 2
37 OT_OperandsXOR, ///< Transfer operands for XOR16
38 OT_OperandsLwp, ///< Transfer operands for LWP
39 OT_OperandsSwp, ///< Transfer operands for SWP
33 OT_NA, ///< Not applicable
34 OT_OperandsAll, ///< Transfer all operands
35 OT_Operands02, ///< Transfer operands 0 and 2
36 OT_Operand2, ///< Transfer just operand 2
37 OT_OperandsXOR, ///< Transfer operands for XOR16
38 OT_OperandsLwp, ///< Transfer operands for LWP
39 OT_OperandsSwp, ///< Transfer operands for SWP
40 OT_OperandsMovep, ///< Transfer operands for MOVEP
4041 };
4142
4243 /// Reduction type
168169 // Attempts to reduce SB/SH instruction into SB16/SH16,
169170 // returns true on success.
170171 static bool ReduceSXtoSX16(ReduceEntryFunArgs *Arguments);
172
173 // Attempts to reduce two MOVE instructions into MOVEP instruction,
174 // returns true on success.
175 static bool ReduceMoveToMovep(ReduceEntryFunArgs *Arguments);
171176
172177 // Attempts to reduce arithmetic instructions, returns true on success.
173178 static bool ReduceArithmeticInstructions(ReduceEntryFunArgs *Arguments);
242247 OpInfo(OT_OperandsLwp), ImmField(0, -2048, 2048, 2)},
243248 {RT_OneInstr, OpCodes(Mips::LW_MM, Mips::LWSP_MM), ReduceXWtoXWSP,
244249 OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
250 {RT_TwoInstr, OpCodes(Mips::MOVE16_MM, Mips::MOVEP_MM), ReduceMoveToMovep,
251 OpInfo(OT_OperandsMovep), ImmField(0, 0, 0, -1)},
245252 {RT_OneInstr, OpCodes(Mips::SB, Mips::SB16_MM), ReduceSXtoSX16,
246253 OpInfo(OT_OperandsAll), ImmField(0, 0, 16, 2)},
247254 {RT_OneInstr, OpCodes(Mips::SB_MM, Mips::SB16_MM), ReduceSXtoSX16,
561568 return ReplaceInstruction(MI, Entry);
562569 }
563570
571 // Returns true if Reg can be a source register
572 // of MOVEP instruction
573 static bool IsMovepSrcRegister(unsigned Reg) {
574
575 if (Reg == Mips::ZERO || Reg == Mips::V0 || Reg == Mips::V1 ||
576 Reg == Mips::S0 || Reg == Mips::S1 || Reg == Mips::S2 ||
577 Reg == Mips::S3 || Reg == Mips::S4)
578 return true;
579
580 return false;
581 }
582
583 // Returns true if Reg can be a destination register
584 // of MOVEP instruction
585 static bool IsMovepDestinationReg(unsigned Reg) {
586
587 if (Reg == Mips::A0 || Reg == Mips::A1 || Reg == Mips::A2 ||
588 Reg == Mips::A3 || Reg == Mips::S5 || Reg == Mips::S6)
589 return true;
590
591 return false;
592 }
593
594 // Returns true if the registers can be a pair of destination
595 // registers in MOVEP instruction
596 static bool IsMovepDestinationRegPair(unsigned R0, unsigned R1) {
597
598 if ((R0 == Mips::A0 && R1 == Mips::S5) ||
599 (R0 == Mips::A0 && R1 == Mips::S6) ||
600 (R0 == Mips::A0 && R1 == Mips::A1) ||
601 (R0 == Mips::A0 && R1 == Mips::A2) ||
602 (R0 == Mips::A0 && R1 == Mips::A3) ||
603 (R0 == Mips::A1 && R1 == Mips::A2) ||
604 (R0 == Mips::A1 && R1 == Mips::A3) ||
605 (R0 == Mips::A2 && R1 == Mips::A3))
606 return true;
607
608 return false;
609 }
610
611 bool MicroMipsSizeReduce::ReduceMoveToMovep(ReduceEntryFunArgs *Arguments) {
612
613 const ReduceEntry &Entry = Arguments->Entry;
614 MachineBasicBlock::instr_iterator &NextMII = Arguments->NextMII;
615 const MachineBasicBlock::instr_iterator &E =
616 Arguments->MI->getParent()->instr_end();
617
618 if (NextMII == E)
619 return false;
620
621 MachineInstr *MI1 = Arguments->MI;
622 MachineInstr *MI2 = &*NextMII;
623
624 unsigned RegDstMI1 = MI1->getOperand(0).getReg();
625 unsigned RegSrcMI1 = MI1->getOperand(1).getReg();
626
627 if (!IsMovepSrcRegister(RegSrcMI1))
628 return false;
629
630 if (!IsMovepDestinationReg(RegDstMI1))
631 return false;
632
633 if (MI2->getOpcode() != Entry.WideOpc())
634 return false;
635
636 unsigned RegDstMI2 = MI2->getOperand(0).getReg();
637 unsigned RegSrcMI2 = MI2->getOperand(1).getReg();
638
639 if (!IsMovepSrcRegister(RegSrcMI2))
640 return false;
641
642 bool ConsecutiveForward;
643 if (IsMovepDestinationRegPair(RegDstMI1, RegDstMI2)) {
644 ConsecutiveForward = true;
645 } else if (IsMovepDestinationRegPair(RegDstMI2, RegDstMI1)) {
646 ConsecutiveForward = false;
647 } else
648 return false;
649
650 NextMII = std::next(NextMII);
651 return ReplaceInstruction(MI1, Entry, MI2, ConsecutiveForward);
652 }
653
564654 bool MicroMipsSizeReduce::ReduceXORtoXOR16(ReduceEntryFunArgs *Arguments) {
565655
566656 MachineInstr *MI = Arguments->MI;
640730 }
641731 break;
642732 }
733 case OT_OperandsMovep:
643734 case OT_OperandsLwp:
644735 case OT_OperandsSwp: {
645736 if (ConsecutiveForward) {
646737 MIB.add(MI->getOperand(0));
647738 MIB.add(MI2->getOperand(0));
648739 MIB.add(MI->getOperand(1));
649 MIB.add(MI->getOperand(2));
740 if (OpTransfer == OT_OperandsMovep)
741 MIB.add(MI2->getOperand(1));
742 else
743 MIB.add(MI->getOperand(2));
650744 } else { // consecutive backward
651745 MIB.add(MI2->getOperand(0));
652746 MIB.add(MI->getOperand(0));
653747 MIB.add(MI2->getOperand(1));
654 MIB.add(MI2->getOperand(2));
748 if (OpTransfer == OT_OperandsMovep)
749 MIB.add(MI->getOperand(1));
750 else
751 MIB.add(MI2->getOperand(2));
655752 }
656753
657754 LLVM_DEBUG(dbgs() << "and converting 32-bit: " << *MI2
727727 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
728728 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
729729 continue;
730 // Instructions LWP/SWP should not be in a delay slot as that
730 // Instructions LWP/SWP and MOVEP should not be in a delay slot as that
731731 // results in unpredictable behaviour
732 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM))
732 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
733 Opcode == Mips::MOVEP_MM))
733734 continue;
734735
735736 Filler = CurrI;
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mattr=+micromips -mcpu=mips32r2 \
2 ; RUN: -verify-machineinstrs < %s | FileCheck %s
3
4 ; Function Attrs: nounwind
5 define i64 @move() {
6 ; CHECK-LABEL: move:
7 ; CHECK: # %bb.0: # %entry
8 ; CHECK-NEXT: addiusp -24
9 ; CHECK-NEXT: .cfi_def_cfa_offset 24
10 ; CHECK-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
11 ; CHECK-NEXT: .cfi_offset 31, -4
12 ; CHECK-NEXT: jal g
13 ; CHECK-NEXT: nop
14 ; CHECK-NEXT: movep $4, $5, $2, $3
15 ; CHECK-NEXT: jal f
16 ; CHECK-NEXT: nop
17 ; CHECK-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
18 ; CHECK-NEXT: addiusp 24
19 ; CHECK-NEXT: jrc $ra
20 entry:
21 %call = call i64 @g()
22 %call1 = call i64 @f(i64 signext %call)
23 ret i64 %call1
24 }
25
26 declare i64 @f(i64 signext %a)
27 declare i64 @g()
28
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=mipsel-unknown-linux-gnu -mattr=+micromips -mcpu=mips32r2 \
2 # RUN: -verify-machineinstrs -run-pass micromips-reduce-size \
3 # RUN: %s -o - | FileCheck %s
4
5 --- |
6 define i64 @move1() { ret i64 0 }
7 define i64 @move2() { ret i64 0 }
8
9 declare i64 @f(i64 signext)
10 declare i64 @g()
11
12 ...
13 ---
14 name: move1
15 stack:
16 - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
17 stack-id: 0, callee-saved-register: '$ra', callee-saved-restored: true,
18 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
19 constants:
20 body: |
21 bb.0:
22 liveins: $ra
23
24 ; CHECK-LABEL: name: move1
25 ; CHECK: ADDIUSP_MM -24
26 ; CHECK: CFI_INSTRUCTION def_cfa_offset 24
27 ; CHECK: SWSP_MM killed $ra, $sp, 20 :: (store 4 into %stack.0)
28 ; CHECK: CFI_INSTRUCTION offset $ra_64, -4
29 ; CHECK: JAL_MM @g, csr_o32, implicit-def dead $ra, implicit-def $sp, implicit-def $v0, implicit-def $v1
30 ; CHECK: $a0, $a1 = MOVEP_MM $v0, $v1
31 ; CHECK: JAL_MM @f, csr_o32, implicit-def dead $ra, implicit $a0, implicit $a1, implicit-def $sp, implicit-def $v0, implicit-def $v1
32 ; CHECK: $ra = LWSP_MM $sp, 20 :: (load 4 from %stack.0)
33 ; CHECK: ADDIUSP_MM 24
34 ; CHECK: PseudoReturn undef $ra, implicit $v0, implicit $v1
35 $sp = ADDiu $sp, -24
36 CFI_INSTRUCTION def_cfa_offset 24
37 SW killed $ra, $sp, 20 :: (store 4 into %stack.0)
38 CFI_INSTRUCTION offset $ra_64, -4
39 JAL_MM @g, csr_o32, implicit-def dead $ra, implicit-def $sp, implicit-def $v0, implicit-def $v1
40 $a0 = MOVE16_MM $v0
41 $a1 = MOVE16_MM $v1
42 JAL_MM @f, csr_o32, implicit-def dead $ra, implicit $a0, implicit $a1, implicit-def $sp, implicit-def $v0, implicit-def $v1
43 $ra = LW $sp, 20 :: (load 4 from %stack.0)
44 $sp = ADDiu $sp, 24
45 PseudoReturn undef $ra, implicit $v0, implicit $v1
46
47 ...
48 ---
49 name: move2
50 stack:
51 - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
52 stack-id: 0, callee-saved-register: '$ra', callee-saved-restored: true,
53 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
54 constants:
55 body: |
56 bb.0:
57 liveins: $ra
58
59 ; CHECK-LABEL: name: move2
60 ; CHECK: ADDIUSP_MM -24
61 ; CHECK: CFI_INSTRUCTION def_cfa_offset 24
62 ; CHECK: SWSP_MM killed $ra, $sp, 20 :: (store 4 into %stack.0)
63 ; CHECK: CFI_INSTRUCTION offset $ra_64, -4
64 ; CHECK: JAL_MM @g, csr_o32, implicit-def dead $ra, implicit-def $sp, implicit-def $v0, implicit-def $v1
65 ; CHECK: $a0, $a1 = MOVEP_MM $v0, $v1
66 ; CHECK: JAL_MM @f, csr_o32, implicit-def dead $ra, implicit $a0, implicit $a1, implicit-def $sp, implicit-def $v0, implicit-def $v1
67 ; CHECK: $ra = LWSP_MM $sp, 20 :: (load 4 from %stack.0)
68 ; CHECK: ADDIUSP_MM 24
69 ; CHECK: PseudoReturn undef $ra, implicit $v0, implicit $v1
70 $sp = ADDiu $sp, -24
71 CFI_INSTRUCTION def_cfa_offset 24
72 SW killed $ra, $sp, 20 :: (store 4 into %stack.0)
73 CFI_INSTRUCTION offset $ra_64, -4
74 JAL_MM @g, csr_o32, implicit-def dead $ra, implicit-def $sp, implicit-def $v0, implicit-def $v1
75 $a1 = MOVE16_MM $v1
76 $a0 = MOVE16_MM $v0
77 JAL_MM @f, csr_o32, implicit-def dead $ra, implicit $a0, implicit $a1, implicit-def $sp, implicit-def $v0, implicit-def $v1
78 $ra = LW $sp, 20 :: (load 4 from %stack.0)
79 $sp = ADDiu $sp, 24
80 PseudoReturn undef $ra, implicit $v0, implicit $v1
81
82 ...
83 ---
84
85