From 755480681c795d585c73556c028b6143c46bda86 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Oct 2006 03:58:02 +0000 Subject: [PATCH] add two helper methods. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30869 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGISel.h | 4 + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 91 ++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 504319def6f..a348aa4a187 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -123,6 +123,10 @@ protected: void SelectInlineAsmMemoryOperands(std::vector &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, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e17105c0f03..cbe55109f47 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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(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(BBI++))) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (isa(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(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. -- 2.34.1