Handle ARM MOVCC optimization in PeepholeOptimizer.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 16 Aug 2012 23:14:20 +0000 (23:14 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 16 Aug 2012 23:14:20 +0000 (23:14 +0000)
Use the target independent select analysis hooks.

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

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMBaseInstrInfo.h
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td

index aa452538a8a7dd51b3f8d973de58c5e8545f93a0..f5a3bcd11f3cd732d6f7d6fb21c2d57b371d5458 100644 (file)
@@ -1570,9 +1570,8 @@ ARMBaseInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
 
 /// Identify instructions that can be folded into a MOVCC instruction, and
 /// return the corresponding opcode for the predicated pseudo-instruction.
-unsigned llvm::canFoldARMInstrIntoMOVCC(unsigned Reg,
-                                        MachineInstr *&MI,
-                                        const MachineRegisterInfo &MRI) {
+static unsigned canFoldIntoMOVCC(unsigned Reg, MachineInstr *&MI,
+                                 const MachineRegisterInfo &MRI) {
   if (!TargetRegisterInfo::isVirtualRegister(Reg))
     return 0;
   if (!MRI.hasOneNonDBGUse(Reg))
@@ -1617,6 +1616,68 @@ unsigned llvm::canFoldARMInstrIntoMOVCC(unsigned Reg,
   }
 }
 
+bool ARMBaseInstrInfo::analyzeSelect(const MachineInstr *MI,
+                                     SmallVectorImpl<MachineOperand> &Cond,
+                                     unsigned &TrueOp, unsigned &FalseOp,
+                                     bool &Optimizable) const {
+  assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
+         "Unknown select instruction");
+  // MOVCC operands:
+  // 0: Def.
+  // 1: True use.
+  // 2: False use.
+  // 3: Condition code.
+  // 4: CPSR use.
+  TrueOp = 1;
+  FalseOp = 2;
+  Cond.push_back(MI->getOperand(3));
+  Cond.push_back(MI->getOperand(4));
+  // We can always fold a def.
+  Optimizable = true;
+  return false;
+}
+
+MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
+                                               bool PreferFalse) const {
+  assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
+         "Unknown select instruction");
+  const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+  MachineInstr *DefMI = 0;
+  unsigned Opc = canFoldIntoMOVCC(MI->getOperand(2).getReg(), DefMI, MRI);
+  bool Invert = !Opc;
+  if (!Opc)
+    Opc = canFoldIntoMOVCC(MI->getOperand(1).getReg(), DefMI, MRI);
+  if (!Opc)
+    return 0;
+
+  // Create a new predicated version of DefMI.
+  // Rfalse is the first use.
+  MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+                                      get(Opc), MI->getOperand(0).getReg())
+    .addOperand(MI->getOperand(Invert ? 2 : 1));
+
+  // Copy all the DefMI operands, excluding its (null) predicate.
+  const MCInstrDesc &DefDesc = DefMI->getDesc();
+  for (unsigned i = 1, e = DefDesc.getNumOperands();
+       i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
+    NewMI.addOperand(DefMI->getOperand(i));
+
+  unsigned CondCode = MI->getOperand(3).getImm();
+  if (Invert)
+    NewMI.addImm(ARMCC::getOppositeCondition(ARMCC::CondCodes(CondCode)));
+  else
+    NewMI.addImm(CondCode);
+  NewMI.addOperand(MI->getOperand(4));
+
+  // DefMI is not the -S version that sets CPSR, so add an optional %noreg.
+  if (NewMI->hasOptionalDef())
+    AddDefaultCC(NewMI);
+
+  // The caller will erase MI, but not DefMI.
+  DefMI->eraseFromParent();
+  return NewMI;
+}
+
 /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether the
 /// instruction is encoded with an 'S' bit is determined by the optional CPSR
 /// def operand.
index 7a69b868c075a37ff94d82c8fcbfdc640ed049f9..92e5ee8dcbd33ada004809f07fa7d186466069c4 100644 (file)
@@ -202,6 +202,13 @@ public:
                                     unsigned SrcReg2, int CmpMask, int CmpValue,
                                     const MachineRegisterInfo *MRI) const;
 
+  virtual bool analyzeSelect(const MachineInstr *MI,
+                             SmallVectorImpl<MachineOperand> &Cond,
+                             unsigned &TrueOp, unsigned &FalseOp,
+                             bool &Optimizable) const;
+
+  virtual MachineInstr *optimizeSelect(MachineInstr *MI, bool) const;
+
   /// FoldImmediate - 'Reg' is known to be defined by a move immediate
   /// instruction, try to fold the immediate into the use instruction.
   virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
index a0284e6e153d177747601a8988c518411805839d..77181cfcac39c61d5bd677c37460f3e255a321f6 100644 (file)
@@ -6762,54 +6762,6 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
     return BB;
   }
 
-  case ARM::MOVCCr:
-  case ARM::t2MOVCCr: {
-    // MOVCCr instructions can fold one of its operands as a predicated
-    // instruction:
-    //
-    //   %v1 = AND %v2, %v3
-    //   %v4 = MOVCCr %v5, %v1, CC
-    //
-    // Becomes:
-    //
-    //   %v4 = ANDCCrr %v5, %v2, %v3, CC
-    //
-    const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
-    MachineInstr *DefMI = 0;
-    unsigned Opc = canFoldARMInstrIntoMOVCC(MI->getOperand(2).getReg(),
-                                            DefMI, MRI);
-    bool Invert = !Opc;
-    if (!Opc)
-      Opc = canFoldARMInstrIntoMOVCC(MI->getOperand(1).getReg(), DefMI, MRI);
-    if (!Opc)
-      return BB;
-
-    // Create a new predicated version of DefMI.
-    // Rfalse is the first use.
-    MachineInstrBuilder NewMI = BuildMI(*BB, MI, dl, TII->get(Opc),
-                                        MI->getOperand(0).getReg())
-      .addOperand(MI->getOperand(Invert ? 2 : 1));
-
-    // Copy all the DefMI operands, excluding its (null) predicate.
-    const MCInstrDesc &DefDesc = DefMI->getDesc();
-    for (unsigned i = 1, e = DefDesc.getNumOperands();
-         i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
-      NewMI.addOperand(DefMI->getOperand(i));
-
-    unsigned CondCode = MI->getOperand(3).getImm();
-    if (Invert)
-      NewMI.addImm(ARMCC::getOppositeCondition(ARMCC::CondCodes(CondCode)));
-    else
-      NewMI.addImm(CondCode);
-    NewMI.addOperand(MI->getOperand(4));
-
-    AddDefaultCC(NewMI);
-
-    DefMI->eraseFromParent();
-    MI->eraseFromParent();
-    return BB;
-  }
-
   case ARM::BCCi64:
   case ARM::BCCZi64: {
     // If there is an unconditional branch to the other successor, remove it.
index 9da8f1c3e34ce18bfa432ccede348ee19b7edf05..db83a9feb65649c2eeb07fec276fc894364d6abf 100644 (file)
@@ -3939,7 +3939,7 @@ def BCCZi64 : PseudoInst<(outs),
 // a two-value operand where a dag node expects two operands. :(
 let neverHasSideEffects = 1 in {
 
-let isCommutable = 1, usesCustomInserter = 1 in
+let isCommutable = 1, isSelect = 1 in
 def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p),
                            4, IIC_iCMOVr,
   [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
index 79dc509fd59f2eec325b3a01d761eb5e2bc7b616..2761b50f4410ef17efdf00e600cef5f8e2984b99 100644 (file)
@@ -2938,7 +2938,7 @@ defm t2TEQ  : T2I_cmp_irs<0b0100, "teq",
 // a two-value operand where a dag node expects two operands. :(
 let neverHasSideEffects = 1 in {
 
-let isCommutable = 1, usesCustomInserter = 1 in
+let isCommutable = 1, isSelect = 1 in
 def t2MOVCCr : t2PseudoInst<(outs rGPR:$Rd),
                             (ins rGPR:$false, rGPR:$Rm, pred:$p),
                             4, IIC_iCMOVr,