Simplify some logic in ComputeMaskedBits. And change ComputeMaskedBits

to pass the mask APInt by value, not by reference. 


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47096 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2008-02-13 22:28:48 +00:00
parent ea06906559
commit 977a76fbb6
13 changed files with 64 additions and 56 deletions

View File

@ -556,7 +556,7 @@ public:
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
/// processing. Targets can implement the computeMaskedBitsForTargetNode
/// method in the TargetLowering class to allow target nodes to be understood.
void ComputeMaskedBits(SDOperand Op, APInt Mask, APInt &KnownZero,
void ComputeMaskedBits(SDOperand Op, const APInt &Mask, APInt &KnownZero,
APInt &KnownOne, unsigned Depth = 0) const;
/// ComputeMaskedBits - This is a wrapper around the APInt-using

View File

@ -627,7 +627,7 @@ public:
/// Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -1130,7 +1130,7 @@ bool SelectionDAG::MaskedValueIsZero(SDOperand Op, uint64_t Mask,
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
/// processing.
void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
void SelectionDAG::ComputeMaskedBits(SDOperand Op, const APInt &Mask,
APInt &KnownZero, APInt &KnownOne,
unsigned Depth) const {
unsigned BitWidth = Mask.getBitWidth();
@ -1153,8 +1153,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
case ISD::AND:
// If either the LHS or the RHS are Zero, the result is zero.
ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
Mask &= ~KnownZero;
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
ComputeMaskedBits(Op.getOperand(0), Mask & ~KnownZero,
KnownZero2, KnownOne2, Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
@ -1165,8 +1165,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
return;
case ISD::OR:
ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
Mask &= ~KnownOne;
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
ComputeMaskedBits(Op.getOperand(0), Mask & ~KnownOne,
KnownZero2, KnownOne2, Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
@ -1271,21 +1271,19 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
return;
case ISD::SIGN_EXTEND_INREG: {
MVT::ValueType EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
unsigned EBits = MVT::getSizeInBits(EVT);
// Sign extension. Compute the demanded bits in the result that are not
// present in the input.
APInt NewBits = ~APInt::getLowBitsSet(BitWidth,
MVT::getSizeInBits(EVT)) & Mask;
APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - EBits) & Mask;
APInt InSignBit = APInt::getSignBit(MVT::getSizeInBits(EVT));
APInt InputDemandedBits =
Mask & APInt::getLowBitsSet(BitWidth,
MVT::getSizeInBits(EVT));
APInt InSignBit = APInt::getSignBit(EBits);
APInt InputDemandedBits = Mask & APInt::getLowBitsSet(BitWidth, EBits);
// If the sign extended bits are demanded, we know that the sign
// bit is demanded.
InSignBit.zext(BitWidth);
if (!!NewBits)
if (NewBits.getBoolValue())
InputDemandedBits |= InSignBit;
ComputeMaskedBits(Op.getOperand(0), InputDemandedBits,
@ -1318,19 +1316,20 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
if (ISD::isZEXTLoad(Op.Val)) {
LoadSDNode *LD = cast<LoadSDNode>(Op);
MVT::ValueType VT = LD->getMemoryVT();
KnownZero |= ~APInt::getLowBitsSet(BitWidth, MVT::getSizeInBits(VT)) & Mask;
unsigned MemBits = MVT::getSizeInBits(VT);
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits) & Mask;
}
return;
}
case ISD::ZERO_EXTEND: {
MVT::ValueType InVT = Op.getOperand(0).getValueType();
unsigned InBits = MVT::getSizeInBits(InVT);
APInt InMask = APInt::getLowBitsSet(BitWidth, InBits);
APInt NewBits = (~InMask) & Mask;
Mask.trunc(InBits);
APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask;
APInt InMask = Mask;
InMask.trunc(InBits);
KnownZero.trunc(InBits);
KnownOne.trunc(InBits);
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1);
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
KnownZero |= NewBits;
@ -1339,43 +1338,52 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
case ISD::SIGN_EXTEND: {
MVT::ValueType InVT = Op.getOperand(0).getValueType();
unsigned InBits = MVT::getSizeInBits(InVT);
APInt InMask = APInt::getLowBitsSet(BitWidth, InBits);
APInt InSignBit = APInt::getSignBit(InBits);
APInt NewBits = (~InMask) & Mask;
APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask;
APInt InMask = Mask;
InMask.trunc(InBits);
// If any of the sign extended bits are demanded, we know that the sign
// bit is demanded.
InSignBit.zext(BitWidth);
if (!!(NewBits & Mask))
Mask |= InSignBit;
// bit is demanded. Temporarily set this bit in the mask for our callee.
if (NewBits.getBoolValue())
InMask |= InSignBit;
Mask.trunc(InBits);
KnownZero.trunc(InBits);
KnownOne.trunc(InBits);
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1);
// Note if the sign bit is known to be zero or one.
bool SignBitKnownZero = KnownZero.isNegative();
bool SignBitKnownOne = KnownOne.isNegative();
assert(!(SignBitKnownZero && SignBitKnownOne) &&
"Sign bit can't be known to be both zero and one!");
// If the sign bit wasn't actually demanded by our caller, we don't
// want it set in the KnownZero and KnownOne result values. Reset the
// mask and reapply it to the result values.
InMask = Mask;
InMask.trunc(InBits);
KnownZero &= InMask;
KnownOne &= InMask;
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
// If the sign bit is known zero or one, the top bits match.
if (!!(KnownZero & InSignBit)) {
// If the sign bit is known zero or one, the top bits match.
if (SignBitKnownZero)
KnownZero |= NewBits;
KnownOne &= ~NewBits;
} else if (!!(KnownOne & InSignBit)) {
else if (SignBitKnownOne)
KnownOne |= NewBits;
KnownZero &= ~NewBits;
} else { // Otherwise, top bits aren't known.
KnownOne &= ~NewBits;
KnownZero &= ~NewBits;
}
return;
}
case ISD::ANY_EXTEND: {
MVT::ValueType InVT = Op.getOperand(0).getValueType();
unsigned InBits = MVT::getSizeInBits(InVT);
Mask.trunc(InBits);
APInt InMask = Mask;
InMask.trunc(InBits);
KnownZero.trunc(InBits);
KnownOne.trunc(InBits);
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1);
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
return;
@ -1383,10 +1391,11 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
case ISD::TRUNCATE: {
MVT::ValueType InVT = Op.getOperand(0).getValueType();
unsigned InBits = MVT::getSizeInBits(InVT);
Mask.zext(InBits);
APInt InMask = Mask;
InMask.zext(InBits);
KnownZero.zext(InBits);
KnownOne.zext(InBits);
ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero.trunc(BitWidth);
KnownOne.trunc(BitWidth);
@ -1415,8 +1424,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
// Output known-0 bits are known if clear or set in both the low clear bits
// common to both LHS & RHS. For example, 8+(X<<3) is known to have the
// low 3 bits clear.
unsigned KnownZeroOut = std::min((~KnownZero).countTrailingZeros(),
(~KnownZero2).countTrailingZeros());
unsigned KnownZeroOut = std::min(KnownZero.countTrailingOnes(),
KnownZero2.countTrailingOnes());
KnownZero = APInt::getLowBitsSet(BitWidth, KnownZeroOut);
KnownOne = APInt(BitWidth, 0);
@ -1431,7 +1440,7 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask,
// positive if we can prove that X is >= 0 and < 16.
// sign bit clear
if (!(CLHS->getAPIntValue() & APInt::getSignBit(BitWidth))) {
if (CLHS->getAPIntValue().isNonNegative()) {
unsigned NLZ = (CLHS->getAPIntValue()+1).countLeadingZeros();
// NLZ can't be BitWidth with no sign bit
APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ);

View File

@ -1008,7 +1008,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
@ -1019,8 +1019,7 @@ void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Op.getOpcode() == ISD::INTRINSIC_VOID) &&
"Should use MaskedValueIsZero if you don't know whether Op"
" is a target node!");
KnownZero = 0;
KnownOne = 0;
KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
}
/// ComputeNumSignBitsForTargetNode - This method can be implemented by

View File

@ -1762,7 +1762,7 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
}
void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -106,7 +106,7 @@ namespace llvm {
SelectionDAG &DAG);
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -2668,7 +2668,7 @@ SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
void
SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -108,7 +108,7 @@ namespace llvm {
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -3451,7 +3451,7 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
//===----------------------------------------------------------------------===//
void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -254,7 +254,7 @@ namespace llvm {
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -110,7 +110,7 @@ namespace {
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
@ -270,7 +270,7 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
/// be zero. Op is expected to be a target specific node. Used by DAG
/// combiner.
void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -5640,7 +5640,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
//===----------------------------------------------------------------------===//
void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,

View File

@ -379,7 +379,7 @@ namespace llvm {
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
APInt Mask,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,