[llvm] r211740 - [FastISel][X86] More refactoring of select lowering and XALU folding. NFC.

Juergen Ributzka juergen at apple.com
Wed Jun 25 15:50:59 PDT 2014


Author: ributzka
Date: Wed Jun 25 17:50:59 2014
New Revision: 211740

URL: http://llvm.org/viewvc/llvm-project?rev=211740&view=rev
Log:
[FastISel][X86] More refactoring of select lowering and XALU folding. NFC.

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=211740&r1=211739&r2=211740&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Jun 25 17:50:59 2014
@@ -111,11 +111,11 @@ private:
 
   bool X86SelectDivRem(const Instruction *I);
 
-  bool X86FastEmitCMoveSelect(const Instruction *I);
+  bool X86FastEmitCMoveSelect(MVT RetVT, const Instruction *I);
 
-  bool X86FastEmitSSESelect(const Instruction *I);
+  bool X86FastEmitSSESelect(MVT RetVT, const Instruction *I);
 
-  bool X86FastEmitPseudoSelect(const Instruction *I);
+  bool X86FastEmitPseudoSelect(MVT RetVT, const Instruction *I);
 
   bool X86SelectSelect(const Instruction *I);
 
@@ -158,8 +158,8 @@ private:
   bool TryEmitSmallMemcpy(X86AddressMode DestAM,
                           X86AddressMode SrcAM, uint64_t Len);
 
-  std::pair<bool, X86::CondCode>
-  foldX86XALUIntrinsic(const Instruction *I, const Value *Cond);
+  bool foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
+                            const Value *Cond);
 };
 
 } // end anonymous namespace.
@@ -278,15 +278,15 @@ getX86SSECondtionCode(CmpInst::Predicate
 }
 
 /// \brief Check if it is possible to fold the condition from the XALU intrinsic
-/// into the user.
-std::pair<bool, X86::CondCode>
-X86FastISel::foldX86XALUIntrinsic(const Instruction *I, const Value *Cond) {
+/// into the user. The condition code will only be updated on success.
+bool X86FastISel::foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
+                                       const Value *Cond) {
   if (!isa<ExtractValueInst>(Cond))
-    return std::make_pair(false, X86::COND_INVALID);
+    return false;
 
   const auto *EV = cast<ExtractValueInst>(Cond);
   if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
-    return std::make_pair(false, X86::COND_INVALID);
+    return false;
 
   const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
   MVT RetVT;
@@ -294,25 +294,25 @@ X86FastISel::foldX86XALUIntrinsic(const
   Type *RetTy =
     cast<StructType>(Callee->getReturnType())->getTypeAtIndex(0U);
   if (!isTypeLegal(RetTy, RetVT))
-    return std::make_pair(false, X86::COND_INVALID);
+    return false;
 
   if (RetVT != MVT::i32 && RetVT != MVT::i64)
-    return std::make_pair(false, X86::COND_INVALID);
+    return false;
 
-  X86::CondCode CC;
+  X86::CondCode TmpCC;
   switch (II->getIntrinsicID()) {
-  default: return std::make_pair(false, X86::COND_INVALID);
+  default: return false;
   case Intrinsic::sadd_with_overflow:
   case Intrinsic::ssub_with_overflow:
   case Intrinsic::smul_with_overflow:
-  case Intrinsic::umul_with_overflow: CC = X86::COND_O; break;
+  case Intrinsic::umul_with_overflow: TmpCC = X86::COND_O; break;
   case Intrinsic::uadd_with_overflow:
-  case Intrinsic::usub_with_overflow: CC = X86::COND_B; break;
+  case Intrinsic::usub_with_overflow: TmpCC = X86::COND_B; break;
   }
 
   // Check if both instructions are in the same basic block.
   if (II->getParent() != I->getParent())
-    return std::make_pair(false, X86::COND_INVALID);
+    return false;
 
   // Make sure nothing is in the way
   BasicBlock::const_iterator Start = I;
@@ -321,15 +321,16 @@ X86FastISel::foldX86XALUIntrinsic(const
     // We only expect extractvalue instructions between the intrinsic and the
     // instruction to be selected.
     if (!isa<ExtractValueInst>(Itr))
-      return std::make_pair(false, X86::COND_INVALID);
+      return false;
 
     // Check that the extractvalue operand comes from the intrinsic.
     const auto *EVI = cast<ExtractValueInst>(Itr);
     if (EVI->getAggregateOperand() != II)
-      return std::make_pair(false, X86::COND_INVALID);
+      return false;
   }
 
-  return std::make_pair(true, CC);
+  CC = TmpCC;
+  return true;
 }
 
 bool X86FastISel::isTypeLegal(Type *Ty, MVT &VT, bool AllowI1) {
@@ -1335,6 +1336,7 @@ bool X86FastISel::X86SelectBranch(const
   // Fold the common case of a conditional branch with a comparison
   // in the same block (values defined on other blocks may not have
   // initialized registers).
+  X86::CondCode CC;
   if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
     if (CI->hasOneUse() && CI->getParent() == I->getParent()) {
       EVT VT = TLI.getValueType(CI->getOperand(0)->getType());
@@ -1382,7 +1384,6 @@ bool X86FastISel::X86SelectBranch(const
         break;
       }
 
-      X86::CondCode CC;
       bool SwapArgs;
       unsigned BranchOpc;
       std::tie(CC, SwapArgs) = getX86ConditonCode(Predicate);
@@ -1456,29 +1457,24 @@ bool X86FastISel::X86SelectBranch(const
         return true;
       }
     }
-  } else {
-    bool FoldIntrinsic;
-    X86::CondCode CC;
-    std::tie(FoldIntrinsic, CC) = foldX86XALUIntrinsic(BI, BI->getCondition());
-    if (FoldIntrinsic) {
-      // Fake request the condition, otherwise the intrinsic might be completely
-      // optimized away.
-      unsigned TmpReg = getRegForValue(BI->getCondition());
-      if (TmpReg == 0)
-        return false;
-
-      unsigned BranchOpc = X86::GetCondBranchFromCond(CC);
-
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
-        .addMBB(TrueMBB);
-      FastEmitBranch(FalseMBB, DbgLoc);
-      uint32_t BranchWeight = 0;
-      if (FuncInfo.BPI)
-        BranchWeight = FuncInfo.BPI->getEdgeWeight(BI->getParent(),
-                                                   TrueMBB->getBasicBlock());
-      FuncInfo.MBB->addSuccessor(TrueMBB, BranchWeight);
-      return true;
-    }
+  } else if (foldX86XALUIntrinsic(CC, BI, BI->getCondition())) {
+    // Fake request the condition, otherwise the intrinsic might be completely
+    // optimized away.
+    unsigned TmpReg = getRegForValue(BI->getCondition());
+    if (TmpReg == 0)
+      return false;
+
+    unsigned BranchOpc = X86::GetCondBranchFromCond(CC);
+
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
+      .addMBB(TrueMBB);
+    FastEmitBranch(FalseMBB, DbgLoc);
+    uint32_t BranchWeight = 0;
+    if (FuncInfo.BPI)
+      BranchWeight = FuncInfo.BPI->getEdgeWeight(BI->getParent(),
+                                                 TrueMBB->getBasicBlock());
+    FuncInfo.MBB->addSuccessor(TrueMBB, BranchWeight);
+    return true;
   }
 
   // Otherwise do a clumsy setcc and re-test it.
@@ -1735,27 +1731,19 @@ bool X86FastISel::X86SelectDivRem(const
 
 /// \brief Emit a conditional move instruction (if the are supported) to lower
 /// the select.
-bool X86FastISel::X86FastEmitCMoveSelect(const Instruction *I) {
-  MVT RetVT;
-  if (!isTypeLegal(I->getType(), RetVT))
-    return false;
-
+bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT, const Instruction *I) {
   // Check if the subtarget supports these instructions.
   if (!Subtarget->hasCMov())
     return false;
 
   // FIXME: Add support for i8.
-  unsigned Opc;
-  switch (RetVT.SimpleTy) {
-  default: return false;
-  case MVT::i16: Opc = X86::CMOVNE16rr; break;
-  case MVT::i32: Opc = X86::CMOVNE32rr; break;
-  case MVT::i64: Opc = X86::CMOVNE64rr; break;
-  }
+  if (RetVT < MVT::i16 || RetVT > MVT::i64)
+    return false;
 
   const Value *Cond = I->getOperand(0);
   const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
   bool NeedTest = true;
+  X86::CondCode CC = X86::COND_NE;
 
   // Optimize conditons coming from a compare if both instructions are in the
   // same basic block (values defined in other basic blocks may not have
@@ -1782,11 +1770,9 @@ bool X86FastISel::X86FastEmitCMoveSelect
       break;
     }
 
-    X86::CondCode CC;
     bool NeedSwap;
     std::tie(CC, NeedSwap) = getX86ConditonCode(Predicate);
     assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
-    Opc = X86::getCMovFromCond(CC, RC->getSize());
 
     const Value *CmpLHS = CI->getOperand(0);
     const Value *CmpRHS = CI->getOperand(1);
@@ -1816,21 +1802,14 @@ bool X86FastISel::X86FastEmitCMoveSelect
       }
     }
     NeedTest = false;
-  } else {
-    bool FoldIntrinsic;
-    X86::CondCode CC;
-    std::tie(FoldIntrinsic, CC) = foldX86XALUIntrinsic(I, Cond);
-
-    if (FoldIntrinsic) {
-      // Fake request the condition, otherwise the intrinsic might be completely
-      // optimized away.
-      unsigned TmpReg = getRegForValue(Cond);
-      if (TmpReg == 0)
-        return false;
+  } else if (foldX86XALUIntrinsic(CC, I, Cond)) {
+    // Fake request the condition, otherwise the intrinsic might be completely
+    // optimized away.
+    unsigned TmpReg = getRegForValue(Cond);
+    if (TmpReg == 0)
+      return false;
 
-      Opc = X86::getCMovFromCond(CC, RC->getSize());
-      NeedTest = false;
-    }
+    NeedTest = false;
   }
 
   if (NeedTest) {
@@ -1860,6 +1839,7 @@ bool X86FastISel::X86FastEmitCMoveSelect
   if (!LHSReg || !RHSReg)
     return false;
 
+  unsigned Opc = X86::getCMovFromCond(CC, RC->getSize());
   unsigned ResultReg = FastEmitInst_rr(Opc, RC, RHSReg, RHSIsKill,
                                        LHSReg, LHSIsKill);
   UpdateValueMap(I, ResultReg);
@@ -1871,11 +1851,7 @@ bool X86FastISel::X86FastEmitCMoveSelect
 /// Try to use SSE1/SSE2 instructions to simulate a select without branches.
 /// This lowers fp selects into a CMP/AND/ANDN/OR sequence when the necessary
 /// SSE instructions are available.
-bool X86FastISel::X86FastEmitSSESelect(const Instruction *I) {
-  MVT RetVT;
-  if (!isTypeLegal(I->getType(), RetVT))
-    return false;
-
+bool X86FastISel::X86FastEmitSSESelect(MVT RetVT, const Instruction *I) {
   // Optimize conditons coming from a compare if both instructions are in the
   // same basic block (values defined in other basic blocks may not have
   // initialized registers).
@@ -1956,11 +1932,7 @@ bool X86FastISel::X86FastEmitSSESelect(c
   return true;
 }
 
-bool X86FastISel::X86FastEmitPseudoSelect(const Instruction *I) {
-  MVT RetVT;
-  if (!isTypeLegal(I->getType(), RetVT))
-    return false;
-
+bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT, const Instruction *I) {
   // These are pseudo CMOV instructions and will be later expanded into control-
   // flow.
   unsigned Opc;
@@ -2055,16 +2027,16 @@ bool X86FastISel::X86SelectSelect(const
   }
 
   // First try to use real conditional move instructions.
-  if (X86FastEmitCMoveSelect(I))
+  if (X86FastEmitCMoveSelect(RetVT, I))
     return true;
 
   // Try to use a sequence of SSE instructions to simulate a conditonal move.
-  if (X86FastEmitSSESelect(I))
+  if (X86FastEmitSSESelect(RetVT, I))
     return true;
 
   // Fall-back to pseudo conditional move instructions, which will be later
   // converted to control-flow.
-  if (X86FastEmitPseudoSelect(I))
+  if (X86FastEmitPseudoSelect(RetVT, I))
     return true;
 
   return false;





More information about the llvm-commits mailing list