[llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp SparcV8InstrInfo.td

Chris Lattner lattner at cs.uiuc.edu
Sun Dec 18 00:14:06 PST 2005



Changes in directory llvm/lib/Target/SparcV8:

SparcV8ISelDAGToDAG.cpp updated: 1.17 -> 1.18
SparcV8InstrInfo.td updated: 1.79 -> 1.80
---
Log message:

Give V8 select_cc, in the spirit of the PPC backend


---
Diffs of the changes:  (+189 -32)

 SparcV8ISelDAGToDAG.cpp |  158 +++++++++++++++++++++++++++++++++++++++++-------
 SparcV8InstrInfo.td     |   63 +++++++++++++++----
 2 files changed, 189 insertions(+), 32 deletions(-)


Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.17 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.18
--- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.17	Sun Dec 18 01:13:32 2005
+++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp	Sun Dec 18 02:13:54 2005
@@ -16,6 +16,7 @@
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/CodeGen/SSARegMap.h"
@@ -40,6 +41,9 @@
     
     FTOI,     // FP to Int within a FP register.
     ITOF,     // Int to FP within a FP register.
+    
+    SELECT_ICC, // Select between two values using the current ICC flags.
+    SELECT_FCC, // Select between two values using the current FCC flags.
   };
 }
 
@@ -66,6 +70,8 @@
     virtual std::pair<SDOperand, SDOperand>
       LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                               SelectionDAG &DAG);
+    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                                       MachineBasicBlock *MBB);
   };
 }
 
@@ -82,9 +88,9 @@
   setOperationAction(ISD::ConstantPool , MVT::i32, Custom);
   
   // Sparc doesn't have sext_inreg, replace them with shl/sra
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
 
   // Sparc has no REM operation.
   setOperationAction(ISD::UREM, MVT::i32, Expand);
@@ -116,6 +122,10 @@
   setOperationAction(ISD::BR_CC, MVT::f32, Custom);
   setOperationAction(ISD::BR_CC, MVT::f64, Custom);
   
+  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
+  
   computeRegisterProperties();
 }
 
@@ -243,22 +253,6 @@
 LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
-  case ISD::BR_CC: {
-    SDOperand Chain = Op.getOperand(0);
-    SDOperand CC = Op.getOperand(1);
-    SDOperand LHS = Op.getOperand(2);
-    SDOperand RHS = Op.getOperand(3);
-    SDOperand Dest = Op.getOperand(4);
-    
-    // Get the condition flag.
-    if (LHS.getValueType() == MVT::i32) {
-      SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
-      return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
-    } else {
-      SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
-      return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
-    }
-  }
   case ISD::GlobalAddress: {
     GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
     SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
@@ -298,10 +292,134 @@
     // Convert the int value to FP in an FP register.
     return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
   }
+  case ISD::BR_CC: {
+    SDOperand Chain = Op.getOperand(0);
+    SDOperand CC = Op.getOperand(1);
+    SDOperand LHS = Op.getOperand(2);
+    SDOperand RHS = Op.getOperand(3);
+    SDOperand Dest = Op.getOperand(4);
+    
+    // Get the condition flag.
+    if (LHS.getValueType() == MVT::i32) {
+      SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
+      return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
+    } else {
+      SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
+      return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
+    }
+  }
+  case ISD::SELECT_CC: {
+    SDOperand LHS = Op.getOperand(0);
+    SDOperand RHS = Op.getOperand(1);
+    unsigned CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
+    SDOperand TrueVal = Op.getOperand(2);
+    SDOperand FalseVal = Op.getOperand(3);
+    
+    unsigned Opc;
+    Opc = LHS.getValueType() == MVT::i32 ? V8ISD::CMPICC : V8ISD::CMPFCC;
+    SDOperand CompareFlag = DAG.getNode(Opc, MVT::Flag, LHS, RHS);
+    
+    Opc = LHS.getValueType() == MVT::i32 ? 
+      V8ISD::SELECT_ICC : V8ISD::SELECT_FCC;
+    return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, 
+                       DAG.getConstant(CC, MVT::i32), CompareFlag);
+  }
   }  
 }
 
-
+MachineBasicBlock *
+SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                               MachineBasicBlock *BB) {
+  unsigned BROpcode;
+  // Figure out the conditional branch opcode to use for this select_cc.
+  switch (MI->getOpcode()) {
+  default: assert(0 && "Unknown SELECT_CC!");
+  case V8::SELECT_CC_Int_ICC:
+  case V8::SELECT_CC_FP_ICC:
+  case V8::SELECT_CC_DFP_ICC:
+    // Integer compare.
+    switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) {
+    default: assert(0 && "Unknown integer condition code!");
+    case ISD::SETEQ:  BROpcode = V8::BE; break;
+    case ISD::SETNE:  BROpcode = V8::BNE; break;
+    case ISD::SETLT:  BROpcode = V8::BL; break;
+    case ISD::SETGT:  BROpcode = V8::BG; break;
+    case ISD::SETLE:  BROpcode = V8::BLE; break;
+    case ISD::SETGE:  BROpcode = V8::BGE; break;
+    case ISD::SETULT: BROpcode = V8::BCS; break;
+    case ISD::SETULE: BROpcode = V8::BLEU; break;
+    case ISD::SETUGT: BROpcode = V8::BGU; break;
+    case ISD::SETUGE: BROpcode = V8::BCC; break;
+    }
+    break;
+  case V8::SELECT_CC_Int_FCC:
+  case V8::SELECT_CC_FP_FCC:
+  case V8::SELECT_CC_DFP_FCC:
+    // FP compare.
+    switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) {
+    default: assert(0 && "Unknown fp condition code!");
+    case ISD::SETEQ:  BROpcode = V8::FBE; break;
+    case ISD::SETNE:  BROpcode = V8::FBNE; break;
+    case ISD::SETLT:  BROpcode = V8::FBL; break;
+    case ISD::SETGT:  BROpcode = V8::FBG; break;
+    case ISD::SETLE:  BROpcode = V8::FBLE; break;
+    case ISD::SETGE:  BROpcode = V8::FBGE; break;
+    case ISD::SETULT: BROpcode = V8::FBUL; break;
+    case ISD::SETULE: BROpcode = V8::FBULE; break;
+    case ISD::SETUGT: BROpcode = V8::FBUG; break;
+    case ISD::SETUGE: BROpcode = V8::FBUGE; break;
+    case ISD::SETUO:  BROpcode = V8::FBU; break;
+    case ISD::SETO:   BROpcode = V8::FBO; break;
+    case ISD::SETONE: BROpcode = V8::FBLG; break;
+    case ISD::SETUEQ: BROpcode = V8::FBUE; break;
+    }
+    break;
+  }
+  
+  // 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 = ...
+  //   [f]bCC copy1MBB
+  //   fallthrough --> copy0MBB
+  MachineBasicBlock *thisMBB = BB;
+  MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+  BuildMI(BB, BROpcode, 1).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, V8::PHI, 4, MI->getOperand(0).getReg())
+    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
+    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
+  
+  delete MI;   // The pseudo instruction is gone now.
+  return BB;
+}
+  
 //===----------------------------------------------------------------------===//
 // Instruction Selector Implementation
 //===----------------------------------------------------------------------===//


Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.79 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.80
--- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.79	Sun Dec 18 01:15:17 2005
+++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td	Sun Dec 18 02:13:54 2005
@@ -77,7 +77,10 @@
 SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
 def SDTV8brcc : 
 SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>,
-                    SDTCisVT<2, FlagVT>]>;
+                     SDTCisVT<2, FlagVT>]>;
+def SDTV8selectcc :
+SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
+                     SDTCisVT<3, i32>, SDTCisVT<4, FlagVT>]>;
 
 def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTV8cmpicc>;
 def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc>;
@@ -90,25 +93,61 @@
 def V8ftoi  : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>;
 def V8itof  : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>;
 
+def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>;
+def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
 
 // Pseudo instructions.
-class PseudoInstV8<string asmstr, dag ops> : InstV8  {
+class Pseudo<dag ops, string asmstr, list<dag> pattern> : InstV8  {
   let AsmString = asmstr;
   dag OperandList = ops;
+  let Pattern = pattern;
+}
+def PHI : Pseudo<(ops variable_ops), "PHI", []>;
+def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt), "!ADJCALLSTACKDOWN $amt",[]>;
+def ADJCALLSTACKUP : Pseudo<(ops i32imm:$amt), "!ADJCALLSTACKUP $amt", []>;
+def IMPLICIT_DEF : Pseudo<(ops IntRegs:$dst), "!IMPLICIT_DEF $dst", []>;
+def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src),
+                    "!FpMOVD", []>;      // pseudo 64-bit double move
+
+// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
+// scheduler into a branch sequence.  This has to handle all permutations of
+// selection between i32/f32/f64 on ICC and FCC.
+let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
+  def SELECT_CC_Int_ICC
+   : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_Int_ICC PSEUDO!",
+            [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F,
+                                             imm:$Cond, ICC))]>;
+  def SELECT_CC_Int_FCC
+   : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_Int_FCC PSEUDO!",
+            [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F,
+                                             imm:$Cond, FCC))]>;
+  def SELECT_CC_FP_ICC
+   : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_FP_ICC PSEUDO!",
+            [(set FPRegs:$dst, (V8selecticc FPRegs:$T, FPRegs:$F,
+                                            imm:$Cond, ICC))]>;
+  def SELECT_CC_FP_FCC
+   : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_FP_FCC PSEUDO!",
+            [(set FPRegs:$dst, (V8selectfcc FPRegs:$T, FPRegs:$F,
+                                            imm:$Cond, FCC))]>;
+  def SELECT_CC_DFP_ICC
+   : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_DFP_ICC PSEUDO!",
+            [(set DFPRegs:$dst, (V8selecticc DFPRegs:$T, DFPRegs:$F,
+                                             imm:$Cond, ICC))]>;
+  def SELECT_CC_DFP_FCC
+   : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond),
+            "; SELECT_CC_DFP_FCC PSEUDO!",
+            [(set DFPRegs:$dst, (V8selectfcc DFPRegs:$T, DFPRegs:$F,
+                                             imm:$Cond, FCC))]>;
 }
-def PHI : PseudoInstV8<"PHI", (ops variable_ops)>;
-def ADJCALLSTACKDOWN : PseudoInstV8<"!ADJCALLSTACKDOWN $amt",
-                                    (ops i32imm:$amt)>;
-def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
-                                  (ops i32imm:$amt)>;
-//def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
-def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst", 
-                                (ops IntRegs:$dst)>;
-def FpMOVD : PseudoInstV8<"!FpMOVD",       // pseudo 64-bit double move
-                          (ops DFPRegs:$dst, DFPRegs:$src)>;
 
 // Section A.3 - Synthetic Instructions, p. 85
 // special cases of JMPL:






More information about the llvm-commits mailing list