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

Chris Lattner lattner at cs.uiuc.edu
Sun Jan 29 22:14:14 PST 2006



Changes in directory llvm/lib/Target/SparcV8:

SparcV8ISelDAGToDAG.cpp updated: 1.66 -> 1.67
SparcV8InstrInfo.td updated: 1.107 -> 1.108
---
Log message:

Compile:

uint %test(uint %X) {
        %Y = call uint %llvm.ctpop.i32(uint %X)
        ret uint %Y
}

to:

test:
        save -96, %o6, %o6
        sll %i0, 0, %l0
        popc %l0, %i0
        restore %g0, %g0, %g0
        retl
        nop

instead of to 40 logical ops.  Note the shift-by-zero that clears the top
part of the 64-bit V9 register.

Testcase here: CodeGen/SparcV8/ctpop.ll



---
Diffs of the changes:  (+27 -16)

 SparcV8ISelDAGToDAG.cpp |   35 +++++++++++++++++++----------------
 SparcV8InstrInfo.td     |    8 ++++++++
 2 files changed, 27 insertions(+), 16 deletions(-)


Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.66 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.67
--- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.66	Sun Jan 29 23:35:57 2006
+++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp	Mon Jan 30 00:14:02 2006
@@ -33,21 +33,20 @@
 namespace V8ISD {
   enum {
     FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
-    CMPICC,   // Compare two GPR operands, set icc.
-    CMPFCC,   // Compare two FP operands, set fcc.
-    BRICC,    // Branch to dest on icc condition
-    BRFCC,    // Branch to dest on fcc condition
+    CMPICC,      // Compare two GPR operands, set icc.
+    CMPFCC,      // Compare two FP operands, set fcc.
+    BRICC,       // Branch to dest on icc condition
+    BRFCC,       // Branch to dest on fcc condition
+    SELECT_ICC,  // Select between two values using the current ICC flags.
+    SELECT_FCC,  // Select between two values using the current FCC flags.
     
-    Hi, Lo,   // Hi/Lo operations, typically on a global address.
+    Hi, Lo,      // Hi/Lo operations, typically on a global address.
     
-    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.
-    
-    CALL,       // A V8 call instruction.
-    RET_FLAG,   // Return with a flag operand.
+    FTOI,        // FP to Int within a FP register.
+    ITOF,        // Int to FP within a FP register.
+
+    CALL,        // A V8 call instruction.
+    RET_FLAG,    // Return with a flag operand.
   };
 }
 
@@ -173,10 +172,14 @@
   setOperationAction(ISD::VAEND             , MVT::Other, Expand);
   setOperationAction(ISD::STACKSAVE         , MVT::Other, Expand); 
   setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
-  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
+  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Expand);
 
   setStackPointerRegisterToSaveRestore(V8::O6);
 
+  if (TM.getSubtarget<SparcV8Subtarget>().isV9()) {
+    setOperationAction(ISD::CTPOP, MVT::i32, Legal);
+  }
+  
   computeRegisterProperties();
 }
 
@@ -187,12 +190,12 @@
   case V8ISD::CMPFCC:     return "V8ISD::CMPFCC";
   case V8ISD::BRICC:      return "V8ISD::BRICC";
   case V8ISD::BRFCC:      return "V8ISD::BRFCC";
+  case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC";
+  case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC";
   case V8ISD::Hi:         return "V8ISD::Hi";
   case V8ISD::Lo:         return "V8ISD::Lo";
   case V8ISD::FTOI:       return "V8ISD::FTOI";
   case V8ISD::ITOF:       return "V8ISD::ITOF";
-  case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC";
-  case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC";
   case V8ISD::CALL:       return "V8ISD::CALL";
   case V8ISD::RET_FLAG:   return "V8ISD::RET_FLAG";
   }


Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.107 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.108
--- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.107	Sun Jan 29 23:48:37 2006
+++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td	Mon Jan 30 00:14:02 2006
@@ -764,6 +764,14 @@
                    [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>;
 }
 
+// POPCrr - This does a ctpop of a 64-bit register.  As such, we have to clear
+// the top 32-bits before using it.  To do this clearing, we use a SLLri X,0.
+def POPCrr : F3_1<2, 0b101110, 
+                  (ops IntRegs:$dst, IntRegs:$src),
+                  "popc $src, $dst", []>, Requires<[HasV9]>;
+def : Pat<(ctpop IntRegs:$src),
+          (POPCrr (SLLri IntRegs:$src, 0))>;
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //===----------------------------------------------------------------------===//






More information about the llvm-commits mailing list