implement SELECT_CC fully for the DAG->DAG isel!
authorChris Lattner <sabre@nondot.org>
Fri, 26 Aug 2005 21:23:58 +0000 (21:23 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 26 Aug 2005 21:23:58 +0000 (21:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23101 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h
lib/Target/PowerPC/PPCInstrInfo.td

index 934f811fb14524cdc76492491dce00272f21f638..4c06e3d97bc947ac61e20b74cb9422d6b631fffb 100644 (file)
@@ -1400,8 +1400,17 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
                                  Tmp.getValue(1));
             break;
           }
-    
-    assert(0 && "Select_cc not implemented yet!");
+
+    SDOperand CCReg = SelectCC(Select(N->getOperand(0)),
+                               Select(N->getOperand(1)), CC);
+    unsigned BROpc = getBCCForSetCC(CC);
+
+    bool isFP = MVT::isFloatingPoint(N->getValueType(0));
+    unsigned SelectCCOp = isFP ? PPC::SELECT_CC_FP : PPC::SELECT_CC_Int;
+    CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
+                         Select(N->getOperand(2)), Select(N->getOperand(3)),
+                         getI32Imm(BROpc));
+    break;
   }
     
   case ISD::CALLSEQ_START:
index d84552c5c0a6143bc15a1b4a003c5c95c197ec20..beeb0f8c42a676104d2d82044cd0226ed01652fd 100644 (file)
@@ -15,6 +15,7 @@
 #include "PPC32TargetMachine.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
@@ -553,3 +554,57 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
   assert(0 && "LowerFrameReturnAddress unimplemented");
   abort();
 }
+
+MachineBasicBlock *
+PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                             MachineBasicBlock *BB) {
+  assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
+          MI->getOpcode() == PPC::SELECT_CC_FP) &&
+         "Unexpected instr type to insert");
+  
+  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
+  // control-flow pattern.  The incoming instruction knows the destination vreg
+  // to set, the condition code register to branch on, the true/false values to
+  // select between, and a branch opcode to use.
+  const BasicBlock *LLVM_BB = BB->getBasicBlock();
+  ilist<MachineBasicBlock>::iterator It = BB;
+  ++It;
+  
+  //  thisMBB:
+  //  ...
+  //   TrueVal = ...
+  //   cmpTY ccX, r1, r2
+  //   bCC copy1MBB
+  //   fallthrough --> copy0MBB
+  MachineBasicBlock *thisMBB = BB;
+  MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+  BuildMI(BB, MI->getOperand(4).getImmedValue(), 2)
+    .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB);
+  MachineFunction *F = BB->getParent();
+  F->getBasicBlockList().insert(It, copy0MBB);
+  F->getBasicBlockList().insert(It, sinkMBB);
+  // Update machine-CFG edges
+  BB->addSuccessor(copy0MBB);
+  BB->addSuccessor(sinkMBB);
+  
+  //  copy0MBB:
+  //   %FalseValue = ...
+  //   # fallthrough to sinkMBB
+  BB = copy0MBB;
+  
+  // Update machine-CFG edges
+  BB->addSuccessor(sinkMBB);
+  
+  //  sinkMBB:
+  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+  //  ...
+  BB = sinkMBB;
+  BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg())
+    .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB)
+    .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
+
+  delete MI;   // The pseudo instruction is gone now.
+  return BB;
+}
+
index b2dd4daedde9126955276e03644ce0971fc856d1..bdd55480b7444e7107682dd7b4a1765fe6c037b3 100644 (file)
@@ -64,6 +64,9 @@ namespace llvm {
     virtual std::pair<SDOperand, SDOperand>
       LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                               SelectionDAG &DAG);
+    
+    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                                       MachineBasicBlock *MBB);
   };
 }
 
index fc4566836ddd2af4d60a79eaced9d199510ca23b..595fd478007b7675ea29b9acf8e2aeb2f5a55517 100644 (file)
@@ -67,6 +67,16 @@ def ADJCALLSTACKUP : Pseudo<(ops u16imm), "; ADJCALLSTACKUP">;
 def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">;
 def IMPLICIT_DEF_FP  : Pseudo<(ops FPRC:$rD), "; %rD = IMPLICIT_DEF_FP">;
 
+// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
+// scheduler into a branch sequence.
+let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
+  def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F,
+                              i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+  def SELECT_CC_FP  : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F,
+                             i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+}
+
+
 let Defs = [LR] in
   def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">;