mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-20 19:20:23 +00:00
add two helper methods.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30869 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be8e72120d
commit
755480681c
@ -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,
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user