]> granicus.if.org Git - llvm/commitdiff
[mips][microMIPS] Extending size reduction pass with XOR16
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 10 Aug 2017 10:27:29 +0000 (10:27 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 10 Aug 2017 10:27:29 +0000 (10:27 +0000)
Author: milena.vujosevic.janicic
Reviewers: sdardis
The patch extends size reduction pass for MicroMIPS.
XOR instruction is transformed into 16-bit instruction XOR16, if possible.
Differential Revision: https://reviews.llvm.org/D34239

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310579 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MicroMipsSizeReduction.cpp
test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll [new file with mode: 0644]

index 923a9402498f724e8fa2ab5cd35a6e44c93d26e4..cf2bf0be556ce47397af26c96dabb5b4214c763e 100644 (file)
@@ -34,6 +34,7 @@ enum OperandTransfer {
   OT_OperandsAll, ///< Transfer all operands
   OT_Operands02,  ///< Transfer operands 0 and 2
   OT_Operand2,    ///< Transfer just operand 2
+  OT_OperandsXOR, ///< Transfer operands for XOR16
 };
 
 /// Reduction type
@@ -158,6 +159,10 @@ private:
   static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI,
                                      const ReduceEntry &Entry);
 
+  // Attempts to reduce XOR into XOR16 instruction,
+  // returns true on success.
+  static bool ReduceXORtoXOR16(MachineInstr *MI, const ReduceEntry &Entry);
+
   // Changes opcode of an instruction.
   static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry);
 
@@ -221,7 +226,10 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
      OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
     {RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
      OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
-};
+    {RT_OneInstr, OpCodes(Mips::XOR, Mips::XOR16_MM), ReduceXORtoXOR16,
+     OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)},
+    {RT_OneInstr, OpCodes(Mips::XOR_MM, Mips::XOR16_MM), ReduceXORtoXOR16,
+     OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)}};
 } // namespace
 
 // Returns true if the machine operand MO is register SP.
@@ -395,6 +403,20 @@ bool MicroMipsSizeReduce::ReduceSXtoSX16(MachineInstr *MI,
   return ReplaceInstruction(MI, Entry);
 }
 
+bool MicroMipsSizeReduce::ReduceXORtoXOR16(MachineInstr *MI,
+                                           const ReduceEntry &Entry) {
+  if (!isMMThreeBitGPRegister(MI->getOperand(0)) ||
+      !isMMThreeBitGPRegister(MI->getOperand(1)) ||
+      !isMMThreeBitGPRegister(MI->getOperand(2)))
+    return false;
+
+  if (!(MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) &&
+      !(MI->getOperand(0).getReg() == MI->getOperand(1).getReg()))
+    return false;
+
+  return ReplaceInstruction(MI, Entry);
+}
+
 bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
   bool Modified = false;
   MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),
@@ -434,14 +456,30 @@ bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI,
     const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc());
     DebugLoc dl = MI->getDebugLoc();
     MachineInstrBuilder MIB = BuildMI(MBB, MI, dl, NewMCID);
-
-    if (OpTransfer == OT_Operand2)
+    switch (OpTransfer) {
+    case OT_Operand2:
       MIB.add(MI->getOperand(2));
-    else if (OpTransfer == OT_Operands02) {
+      break;
+    case OT_Operands02: {
       MIB.add(MI->getOperand(0));
       MIB.add(MI->getOperand(2));
-    } else
+      break;
+    }
+    case OT_OperandsXOR: {
+      if (MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) {
+        MIB.add(MI->getOperand(0));
+        MIB.add(MI->getOperand(1));
+        MIB.add(MI->getOperand(2));
+      } else {
+        MIB.add(MI->getOperand(0));
+        MIB.add(MI->getOperand(2));
+        MIB.add(MI->getOperand(1));
+      }
+      break;
+    }
+    default:
       llvm_unreachable("Unknown operand transfer!");
+    }
 
     // Transfer MI flags.
     MIB.setMIFlags(MI->getFlags());
diff --git a/test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll b/test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll
new file mode 100644 (file)
index 0000000..e953df6
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs < %s | FileCheck %s
+
+; Function Attrs: nounwind readnone
+define i1 @fun(i32 %a, i32 %b) {
+entry:
+; CHECK-LABEL: fun:
+; CHECK: xor16
+  %reg1 = or i32 %a, %b
+  %reg2 = xor i32 %reg1, -1
+  %bool1 = icmp ne i32 %a, -1
+  %bool1.ext = zext i1 %bool1 to i32
+  %bool2 = icmp eq i32 %bool1.ext, %reg2
+  ret i1 %bool2
+}