OSDN Git Service

add two helper methods.
authorChris Lattner <sabre@nondot.org>
Wed, 11 Oct 2006 03:58:02 +0000 (03:58 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 11 Oct 2006 03:58:02 +0000 (03:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30869 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGISel.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 504319d..a348aa4 100644 (file)
@@ -123,6 +123,10 @@ protected:
   void SelectInlineAsmMemoryOperands(std::vector<SDOperand> &Ops,
                                      SelectionDAG &DAG);
 
+  // Calls to these predicates are generated by tblgen.
+  bool CheckAndMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);  
+  bool CheckOrMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);  
+  
 private:
   void SplitCritEdgesForPHIConstants(BasicBlock *BB);
   SDOperand CopyValueToVirtualRegister(SelectionDAGLowering &SDL,
index e17105c..cbe5510 100644 (file)
@@ -3204,7 +3204,28 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI,
 /// critical, split them so that the assignments of a constant to a register
 /// will not be executed on a path that isn't relevant.
 void SelectionDAGISel::SplitCritEdgesForPHIConstants(BasicBlock *BB) {
-  PHINode *PN;
+  // The most common case is that this is a PHI node with two incoming
+  // successors handle this case efficiently, because it is simple.
+  PHINode *PN = cast<PHINode>(BB->begin());
+  if (PN->getNumIncomingValues() == 2) {
+    // If neither edge is critical, we never need to split.
+    if (PN->getIncomingBlock(0)->getTerminator()->getNumSuccessors() == 1 &&
+        PN->getIncomingBlock(1)->getTerminator()->getNumSuccessors() == 1)
+      return;
+    
+    BasicBlock::iterator BBI = BB->begin();
+    while ((PN = dyn_cast<PHINode>(BBI++))) {
+      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+        if (isa<Constant>(PN->getIncomingValue(i)))
+          SplitCriticalEdge(PN->getIncomingBlock(i), BB);
+    }
+    return;
+  }
+  
+  // Otherwise, things are a bit trickier.
+  
+  // BE SMART HERE.
+  
   BasicBlock::iterator BBI = BB->begin();
   while ((PN = dyn_cast<PHINode>(BBI++))) {
     for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
@@ -3679,6 +3700,74 @@ HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
   return new HazardRecognizer();
 }
 
+//===----------------------------------------------------------------------===//
+// Helper functions used by the generated instruction selector.
+//===----------------------------------------------------------------------===//
+// Calls to these methods are generated by tblgen.
+
+/// CheckAndMask - The isel is trying to match something like (and X, 255).  If
+/// the dag combiner simplified the 255, we still want to match.  RHS is the
+/// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
+/// specified in the .td file (e.g. 255).
+bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS, 
+                                    int64_t DesiredMaskS) {
+  uint64_t ActualMask = RHS->getValue();
+  uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
+  
+  // If the actual mask exactly matches, success!
+  if (ActualMask == DesiredMask)
+    return true;
+  
+  // If the actual AND mask is allowing unallowed bits, this doesn't match.
+  if (ActualMask & ~DesiredMask)
+    return false;
+  
+  // Otherwise, the DAG Combiner may have proven that the value coming in is
+  // either already zero or is not demanded.  Check for known zero input bits.
+  uint64_t NeededMask = DesiredMask & ~ActualMask;
+  if (getTargetLowering().MaskedValueIsZero(LHS, NeededMask))
+    return true;
+  
+  // TODO: check to see if missing bits are just not demanded.
+
+  // Otherwise, this pattern doesn't match.
+  return false;
+}
+
+/// CheckOrMask - The isel is trying to match something like (or X, 255).  If
+/// the dag combiner simplified the 255, we still want to match.  RHS is the
+/// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
+/// specified in the .td file (e.g. 255).
+bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS, 
+                                    int64_t DesiredMaskS) {
+  uint64_t ActualMask = RHS->getValue();
+  uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
+  
+  // If the actual mask exactly matches, success!
+  if (ActualMask == DesiredMask)
+    return true;
+  
+  // If the actual AND mask is allowing unallowed bits, this doesn't match.
+  if (ActualMask & ~DesiredMask)
+    return false;
+  
+  // Otherwise, the DAG Combiner may have proven that the value coming in is
+  // either already zero or is not demanded.  Check for known zero input bits.
+  uint64_t NeededMask = DesiredMask & ~ActualMask;
+  
+  uint64_t KnownZero, KnownOne;
+  getTargetLowering().ComputeMaskedBits(LHS, NeededMask, KnownZero, KnownOne);
+  
+  // If all the missing bits in the or are already known to be set, match!
+  if ((NeededMask & KnownOne) == NeededMask)
+    return true;
+  
+  // TODO: check to see if missing bits are just not demanded.
+  
+  // Otherwise, this pattern doesn't match.
+  return false;
+}
+
 
 /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
 /// by tblgen.  Others should not call it.