[llvm-commits] [llvm] r57549 - /llvm/trunk/lib/Target/X86/X86FastISel.cpp

Chris Lattner sabre at nondot.org
Tue Oct 14 21:26:38 PDT 2008


Author: lattner
Date: Tue Oct 14 23:26:38 2008
New Revision: 57549

URL: http://llvm.org/viewvc/llvm-project?rev=57549&view=rev
Log:
refactor compare emission out into a new X86FastEmitCompare method,
which makes it easy to share the compare/imm folding logic with 'setcc'.
This shaves a bunch of instructions off the common select case, which
happens a lot in llvm-gcc.

Modified:
    llvm/trunk/lib/Target/X86/X86FastISel.cpp

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=57549&r1=57548&r2=57549&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Tue Oct 14 23:26:38 2008
@@ -73,6 +73,8 @@
 #include "X86GenFastISel.inc"
 
 private:
+  bool X86FastEmitCompare(Value *LHS, Value *RHS, MVT VT);
+  
   bool X86FastEmitLoad(MVT VT, const X86AddressMode &AM, unsigned &RR);
 
   bool X86FastEmitStore(MVT VT, unsigned Val,
@@ -534,8 +536,6 @@
 /// of the comparison, return an opcode that works for the compare (e.g.
 /// CMP32ri) otherwise return 0.
 static unsigned X86ChooseCmpImmediateOpcode(ConstantInt *RHSC) {
-  if (RHSC == 0) return 0;
-  
   if (RHSC->getType() == Type::Int8Ty)
     return X86::CMP8ri;
   if (RHSC->getType() == Type::Int16Ty)
@@ -553,6 +553,31 @@
   return 0;
 }
 
+bool X86FastISel::X86FastEmitCompare(Value *Op0, Value *Op1, MVT VT) {
+  unsigned Op0Reg = getRegForValue(Op0);
+  if (Op0Reg == 0) return false;
+  
+  // We have two options: compare with register or immediate.  If the RHS of
+  // the compare is an immediate that we can fold into this compare, use
+  // CMPri, otherwise use CMPrr.
+  if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
+    if (unsigned CompareImmOpc = X86ChooseCmpImmediateOpcode(Op1C)) {
+      BuildMI(MBB, TII.get(CompareImmOpc)).addReg(Op0Reg)
+                                          .addImm(Op1C->getSExtValue());
+      return true;
+    }
+  }
+  
+  unsigned CompareOpc = X86ChooseCmpOpcode(VT);
+  if (CompareOpc == 0) return false;
+    
+  unsigned Op1Reg = getRegForValue(Op1);
+  if (Op1Reg == 0) return false;
+  BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg).addReg(Op1Reg);
+  
+  return true;
+}
+
 bool X86FastISel::X86SelectCmp(Instruction *I) {
   CmpInst *CI = cast<CmpInst>(I);
 
@@ -560,18 +585,17 @@
   if (!isTypeLegal(I->getOperand(0)->getType(), TLI, VT))
     return false;
 
-  unsigned Op0Reg = getRegForValue(CI->getOperand(0));
-  if (Op0Reg == 0) return false;
-  unsigned Op1Reg = getRegForValue(CI->getOperand(1));
-  if (Op1Reg == 0) return false;
-
-  unsigned Opc = X86ChooseCmpOpcode(VT);
-
   unsigned ResultReg = createResultReg(&X86::GR8RegClass);
   unsigned SetCCOpc;
   bool SwapArgs;  // false -> compare Op0, Op1.  true -> compare Op1, Op0.
   switch (CI->getPredicate()) {
   case CmpInst::FCMP_OEQ: {
+    unsigned Op0Reg = getRegForValue(CI->getOperand(0));
+    if (Op0Reg == 0) return false;
+    unsigned Op1Reg = getRegForValue(CI->getOperand(1));
+    if (Op1Reg == 0) return false;
+    unsigned Opc = X86ChooseCmpOpcode(VT);
+    
     unsigned EReg = createResultReg(&X86::GR8RegClass);
     unsigned NPReg = createResultReg(&X86::GR8RegClass);
     BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
@@ -582,6 +606,12 @@
     return true;
   }
   case CmpInst::FCMP_UNE: {
+    unsigned Op0Reg = getRegForValue(CI->getOperand(0));
+    if (Op0Reg == 0) return false;
+    unsigned Op1Reg = getRegForValue(CI->getOperand(1));
+    if (Op1Reg == 0) return false;
+    unsigned Opc = X86ChooseCmpOpcode(VT);
+    
     unsigned NEReg = createResultReg(&X86::GR8RegClass);
     unsigned PReg = createResultReg(&X86::GR8RegClass);
     BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
@@ -618,11 +648,13 @@
     return false;
   }
 
+  Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
   if (SwapArgs)
-    BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
-  else
-    BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
+    std::swap(Op0, Op1);
 
+  // Emit a compare of Op0/Op1.
+  X86FastEmitCompare(Op0, Op1, VT);
+  
   BuildMI(MBB, TII.get(SetCCOpc), ResultReg);
   UpdateValueMap(I, ResultReg);
   return true;
@@ -642,6 +674,7 @@
   return false;
 }
 
+
 bool X86FastISel::X86SelectBranch(Instruction *I) {
   // Unconditional branches are selected by tablegen-generated code.
   // Handle a conditional branch.
@@ -677,6 +710,7 @@
       case CmpInst::FCMP_UGE: SwapArgs = true;  BranchOpc = X86::JBE; break;
       case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB;  break;
       case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE; break;
+          
       case CmpInst::ICMP_EQ:  SwapArgs = false; BranchOpc = X86::JE;  break;
       case CmpInst::ICMP_NE:  SwapArgs = false; BranchOpc = X86::JNE; break;
       case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA;  break;
@@ -695,23 +729,9 @@
       if (SwapArgs)
         std::swap(Op0, Op1);
 
-      unsigned CompareOpc = X86ChooseCmpOpcode(VT);
-      if (CompareOpc == 0) return false;
-      unsigned Op0Reg = getRegForValue(Op0);
-      if (Op0Reg == 0) return false;
-      
-      // We have two options: compare with register or immediate.  If the RHS of
-      // the compare is an immediate that we can fold into this compare, use
-      // CMPri, otherwise use CMPrr.
-      ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1);
-      if (unsigned CompareImmOpc = X86ChooseCmpImmediateOpcode(Op1C)) {
-        BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg)
-                                         .addImm(Op1C->getSExtValue());
-      } else {
-        unsigned Op1Reg = getRegForValue(Op1);
-        if (Op1Reg == 0) return false;
-        BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg).addReg(Op1Reg);
-      }
+      // Emit a compare of the LHS and RHS, setting the flags.
+      if (!X86FastEmitCompare(Op0, Op1, VT))
+        return false;
       
       BuildMI(MBB, TII.get(BranchOpc)).addMBB(TrueMBB);
       FastEmitBranch(FalseMBB);





More information about the llvm-commits mailing list