Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.285 -> 1.286 --- Log message: add two helper methods. --- Diffs of the changes: (+90 -1) SelectionDAGISel.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 90 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.285 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.286 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.285 Mon Oct 9 15:57:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 10 22:58:02 2006 @@ -3204,7 +3204,28 @@ /// 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 @@ 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. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits