[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp

Nate Begeman natebegeman at mac.com
Sat Aug 21 13:42:24 PDT 2004



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelSimple.cpp updated: 1.72 -> 1.73
---
Log message:

Back out branchless SetCC code.  While it helped a lot in some cases, it
hurt a lot in others.  Instead, improve branching version of SetCC and
Select instructions.  The old code will be in CVS should we ever need to
dig it up again.


---
Diffs of the changes:  (+25 -188)

Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.72 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.73
--- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.72	Fri Aug 20 04:56:22 2004
+++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp	Sat Aug 21 15:42:14 2004
@@ -1110,148 +1110,12 @@
   if (canFoldSetCCIntoBranchOrSelect(&I))
     return;
 
-  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-  const Type *Ty = Op0->getType();
-  unsigned Class = getClassB(Ty);
-  unsigned Opcode = I.getOpcode();
   unsigned DestReg = getReg(I);
-
-  // If the comparison type is byte, short, or int, then we can emit a
-  // branchless version of the SetCC that puts 0 (false) or 1 (true) in the
-  // destination register.
-  if (Class <= cInt) {
-    ++NumSetCC;
-    MachineBasicBlock::iterator MI = BB->end();
-    unsigned OpNum = getSetCCNumber(Opcode);
-    unsigned Op0Reg = getReg(Op0, BB, MI);
-    Op0Reg = ExtendOrClear(BB, MI, Op0Reg, Ty);
-    
-    // comparisons against constant zero often have shorter sequences than the
-    // general case, handled below.
-    ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
-    if (CI && CI->getRawValue() == 0) {
-      switch(OpNum) {
-      case 0: { // eq0
-        unsigned TempReg = makeAnotherReg(Type::IntTy);
-        BuildMI(*BB, MI, PPC::CNTLZW, 1, TempReg).addReg(Op0Reg);
-        BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(TempReg).addImm(5);
-        break;
-        } 
-      case 1: { // ne0
-        unsigned TempReg = makeAnotherReg(Type::IntTy);
-        BuildMI(*BB, MI, PPC::ADDIC, 2, TempReg).addReg(Op0Reg).addSImm(-1);
-        BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(TempReg).addReg(Op0Reg);
-        break;
-        } 
-      case 2: { // lt0, always false if unsigned
-        if (Ty->isSigned())
-          BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Op0Reg).addImm(31);
-        else
-          BuildMI(*BB, MI, PPC::LI, 1, DestReg).addSImm(0);
-        break;
-        }
-      case 3: { // ge0, always true if unsigned
-        if (Ty->isSigned()) { 
-          unsigned TempReg = makeAnotherReg(Type::IntTy);
-          BuildMI(*BB, MI, PPC::SRWI, 2, TempReg).addReg(Op0Reg).addImm(31);
-          BuildMI(*BB, MI, PPC::XORI, 2, DestReg).addReg(TempReg).addImm(1);
-        } else {
-          BuildMI(*BB, MI, PPC::LI, 1, DestReg).addSImm(1);
-        }
-        break;
-        }
-      case 4: { // gt0, equivalent to ne0 if unsigned
-        unsigned Temp1 = makeAnotherReg(Type::IntTy);
-        unsigned Temp2 = makeAnotherReg(Type::IntTy);
-        if (Ty->isSigned()) { 
-          BuildMI(*BB, MI, PPC::NEG, 2, Temp1).addReg(Op0Reg);
-          BuildMI(*BB, MI, PPC::ANDC, 2, Temp2).addReg(Temp1).addReg(Op0Reg);
-          BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(31);
-        } else {
-          BuildMI(*BB, MI, PPC::ADDIC, 2, Temp1).addReg(Op0Reg).addSImm(-1);
-          BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(Temp1).addReg(Op0Reg);
-        }
-        break;
-        }
-      case 5: { // le0, equivalent to eq0 if unsigned
-        unsigned Temp1 = makeAnotherReg(Type::IntTy);
-        unsigned Temp2 = makeAnotherReg(Type::IntTy);
-        if (Ty->isSigned()) { 
-          BuildMI(*BB, MI, PPC::NEG, 2, Temp1).addReg(Op0Reg);
-          BuildMI(*BB, MI, PPC::ORC, 2, Temp2).addReg(Op0Reg).addReg(Temp1);
-          BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(31);
-        } else {
-          BuildMI(*BB, MI, PPC::CNTLZW, 1, Temp1).addReg(Op0Reg);
-          BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp1).addImm(5);
-        }
-        break;
-        }
-      } // switch
-      return;
-    }
-    unsigned Op1Reg = getReg(Op1, BB, MI);
-    switch(OpNum) {
-    case 0: { // eq
-      unsigned Temp1 = makeAnotherReg(Type::IntTy);
-      unsigned Temp2 = makeAnotherReg(Type::IntTy);
-      BuildMI(*BB, MI, PPC::SUBF, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
-      BuildMI(*BB, MI, PPC::CNTLZW, 1, Temp2).addReg(Temp1);
-      BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(5);
-      break;
-      } 
-    case 1: { // ne
-      unsigned Temp1 = makeAnotherReg(Type::IntTy);
-      unsigned Temp2 = makeAnotherReg(Type::IntTy);
-      BuildMI(*BB, MI, PPC::SUBF, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
-      BuildMI(*BB, MI, PPC::ADDIC, 2, Temp2).addReg(Temp1).addSImm(-1);
-      BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(Temp2).addReg(Temp1);
-      break;
-      } 
-    case 2: 
-    case 4: { // lt, gt
-      unsigned Temp1 = makeAnotherReg(Type::IntTy);
-      unsigned Temp2 = makeAnotherReg(Type::IntTy);
-      unsigned Temp3 = makeAnotherReg(Type::IntTy);
-      unsigned Temp4 = makeAnotherReg(Type::IntTy);
-      if (OpNum == 4) std::swap(Op0Reg, Op1Reg);
-      if (Ty->isSigned()) { 
-        BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op1Reg).addReg(Op0Reg);
-        BuildMI(*BB, MI, PPC::EQV, 2, Temp2).addReg(Op1Reg).addReg(Op0Reg);
-        BuildMI(*BB, MI, PPC::SRWI, 2, Temp3).addReg(Temp2).addImm(31);
-        BuildMI(*BB, MI, PPC::ADDZE, 1, Temp4).addReg(Temp3);
-        BuildMI(*BB, MI, PPC::RLWINM, 4, DestReg).addReg(Temp4).addImm(0)
-          .addImm(31).addImm(31);
-      } else {
-        BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op1Reg).addReg(Op0Reg);
-        BuildMI(*BB, MI, PPC::SUBFE, 2, Temp2).addReg(Temp1).addReg(Temp1);
-        BuildMI(*BB, MI, PPC::NEG, 2, DestReg).addReg(Temp2);
-      }
-      break;
-      }
-    case 3: 
-    case 5: { // le, ge
-      unsigned Temp1 = makeAnotherReg(Type::IntTy);
-      unsigned Temp2 = makeAnotherReg(Type::IntTy);
-      unsigned Temp3 = makeAnotherReg(Type::IntTy);
-      if (OpNum == 3) std::swap(Op0Reg, Op1Reg);
-      if (Ty->isSigned()) {
-        BuildMI(*BB, MI, PPC::SRWI, 2, Temp1).addReg(Op0Reg).addImm(31);
-        BuildMI(*BB, MI, PPC::SRAWI, 2, Temp2).addReg(Op1Reg).addImm(31);
-        BuildMI(*BB, MI, PPC::SUBFC, 2, Temp3).addReg(Op0Reg).addReg(Op1Reg);
-        BuildMI(*BB, MI, PPC::ADDE, 2, DestReg).addReg(Temp2).addReg(Temp1);
-      } else {
-        BuildMI(*BB, MI, PPC::LI, 1, Temp2).addSImm(-1);
-        BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
-        BuildMI(*BB, MI, PPC::SUBFZE, 1, DestReg).addReg(Temp2);
-      }
-      break;
-      }
-    } // switch
-    return;
-  }
-  EmitComparison(Opcode, Op0, Op1, BB, BB->end());
-  
+  unsigned Opcode = I.getOpcode();
   unsigned PPCOpcode = getPPCOpcodeForSetCCNumber(Opcode);
+
+  // Create an iterator with which to insert the MBB for copying the false value
+  // and the MBB to hold the PHI instruction for this SetCC.
   MachineBasicBlock *thisMBB = BB;
   const BasicBlock *LLVM_BB = BB->getBasicBlock();
   ilist<MachineBasicBlock>::iterator It = BB;
@@ -1260,32 +1124,18 @@
   //  thisMBB:
   //  ...
   //   cmpTY cr0, r1, r2
-  //   bCC copy1MBB
-  //   b copy0MBB
-
-  // FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
-  // if we could insert other, non-terminator instructions after the
-  // bCC. But MBB->getFirstTerminator() can't understand this.
-  MachineBasicBlock *copy1MBB = new MachineBasicBlock(LLVM_BB);
-  F->getBasicBlockList().insert(It, copy1MBB);
-  BuildMI(BB, PPCOpcode, 2).addReg(PPC::CR0).addMBB(copy1MBB);
+  //   %TrueValue = li 1
+  //   bCC sinkMBB
+  EmitComparison(Opcode, I.getOperand(0), I.getOperand(1), BB, BB->end());
+  unsigned TrueValue = makeAnotherReg(I.getType());
+  BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
   MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
-  F->getBasicBlockList().insert(It, copy0MBB);
-  BuildMI(BB, PPC::B, 1).addMBB(copy0MBB);
   MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+  BuildMI(BB, PPCOpcode, 2).addReg(PPC::CR0).addMBB(sinkMBB);
+  F->getBasicBlockList().insert(It, copy0MBB);
   F->getBasicBlockList().insert(It, sinkMBB);
   // Update machine-CFG edges
-  BB->addSuccessor(copy1MBB);
   BB->addSuccessor(copy0MBB);
-
-  //  copy1MBB:
-  //   %TrueValue = li 1
-  //   b sinkMBB
-  BB = copy1MBB;
-  unsigned TrueValue = makeAnotherReg(I.getType());
-  BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
-  BuildMI(BB, PPC::B, 1).addMBB(sinkMBB);
-  // Update machine-CFG edges
   BB->addSuccessor(sinkMBB);
 
   //  copy0MBB:
@@ -1298,11 +1148,11 @@
   BB->addSuccessor(sinkMBB);
 
   //  sinkMBB:
-  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
+  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
   //  ...
   BB = sinkMBB;
   BuildMI(BB, PPC::PHI, 4, DestReg).addReg(FalseValue)
-    .addMBB(copy0MBB).addReg(TrueValue).addMBB(copy1MBB);
+    .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
 }
 
 void ISel::visitSelectInst(SelectInst &SI) {
@@ -1335,40 +1185,25 @@
     BuildMI(*MBB, IP, PPC::CMPI, 2, PPC::CR0).addReg(CondReg).addSImm(0);
     Opcode = getPPCOpcodeForSetCCNumber(Instruction::SetNE);
   }
-
-  //  thisMBB:
-  //  ...
-  //   cmpTY cr0, r1, r2
-  //   bCC copy1MBB
-  //   b copy0MBB
+  unsigned TrueValue = getReg(TrueVal, BB, BB->end());
 
   MachineBasicBlock *thisMBB = BB;
   const BasicBlock *LLVM_BB = BB->getBasicBlock();
   ilist<MachineBasicBlock>::iterator It = BB;
   ++It;
 
-  // FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
-  // if we could insert other, non-terminator instructions after the
-  // bCC. But MBB->getFirstTerminator() can't understand this.
-  MachineBasicBlock *copy1MBB = new MachineBasicBlock(LLVM_BB);
-  F->getBasicBlockList().insert(It, copy1MBB);
-  BuildMI(BB, Opcode, 2).addReg(PPC::CR0).addMBB(copy1MBB);
+  //  thisMBB:
+  //  ...
+  //   cmpTY cr0, r1, r2
+  //   %TrueValue = ...
+  //   bCC sinkMBB
   MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
-  F->getBasicBlockList().insert(It, copy0MBB);
-  BuildMI(BB, PPC::B, 1).addMBB(copy0MBB);
   MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+  BuildMI(BB, Opcode, 2).addReg(PPC::CR0).addMBB(sinkMBB);
+  F->getBasicBlockList().insert(It, copy0MBB);
   F->getBasicBlockList().insert(It, sinkMBB);
   // Update machine-CFG edges
-  BB->addSuccessor(copy1MBB);
   BB->addSuccessor(copy0MBB);
-
-  //  copy1MBB:
-  //   %TrueValue = ...
-  //   b sinkMBB
-  BB = copy1MBB;
-  unsigned TrueValue = getReg(TrueVal, BB, BB->begin());
-  BuildMI(BB, PPC::B, 1).addMBB(sinkMBB);
-  // Update machine-CFG edges
   BB->addSuccessor(sinkMBB);
 
   //  copy0MBB:
@@ -1380,12 +1215,14 @@
   BB->addSuccessor(sinkMBB);
 
   //  sinkMBB:
-  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
+  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
   //  ...
   BB = sinkMBB;
   BuildMI(BB, PPC::PHI, 4, DestReg).addReg(FalseValue)
-    .addMBB(copy0MBB).addReg(TrueValue).addMBB(copy1MBB);
+    .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
+    
   // For a register pair representing a long value, define the second reg
+  // FIXME: Can this really be correct for selecting longs?
   if (getClassB(TrueVal->getType()) == cLong)
     BuildMI(BB, PPC::LI, 1, DestReg+1).addImm(0);
   return;






More information about the llvm-commits mailing list