X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FTargetLowering.cpp;h=79e8013e4f585e3fc1c349f6e788a3b07e2a6abc;hb=d97321ceb313f06fd9a824cf26b9dc5b80b3eb9d;hp=1c00c9136c39c279f94478c389e4bd2acd4a1d65;hpb=cf9668f23d67b171d3529087061b1387b20eb8b9;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 1c00c9136c3..79e8013e4f5 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -28,6 +28,15 @@ TargetLowering::TargetLowering(TargetMachine &tm) // All operations default to being supported. memset(OpActions, 0, sizeof(OpActions)); memset(LoadXActions, 0, sizeof(LoadXActions)); + memset(&StoreXActions, 0, sizeof(StoreXActions)); + // Initialize all indexed load / store to expand. + for (unsigned VT = 0; VT != (unsigned)MVT::LAST_VALUETYPE; ++VT) { + for (unsigned IM = (unsigned)ISD::PRE_INC; + IM != (unsigned)ISD::LAST_INDEXED_MODE; ++IM) { + setIndexedLoadAction(IM, (MVT::ValueType)VT, Expand); + setIndexedStoreAction(IM, (MVT::ValueType)VT, Expand); + } + } IsLittleEndian = TD->isLittleEndian(); UsesGlobalOffsetTable = false; @@ -38,7 +47,8 @@ TargetLowering::TargetLowering(TargetMachine &tm) sizeof(TargetDAGCombineArray)/sizeof(TargetDAGCombineArray[0])); maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8; allowUnalignedMemoryAccesses = false; - UseUnderscoreSetJmpLongJmp = false; + UseUnderscoreSetJmp = false; + UseUnderscoreLongJmp = false; IntDivIsCheap = false; Pow2DivIsCheap = false; StackPointerRegisterToSaveRestore = 0; @@ -77,10 +87,17 @@ static void SetValueTypeAction(MVT::ValueType VT, assert(VT < PromoteTo && "Must promote to a larger type!"); TransformToType[VT] = PromoteTo; } else if (Action == TargetLowering::Expand) { - assert((VT == MVT::Vector || MVT::isInteger(VT)) && VT > MVT::i8 && - "Cannot expand this type: target must support SOME integer reg!"); - // Expand to the next smaller integer type! - TransformToType[VT] = (MVT::ValueType)(VT-1); + // f32 and f64 is each expanded to corresponding integer type of same size. + if (VT == MVT::f32) + TransformToType[VT] = MVT::i32; + else if (VT == MVT::f64) + TransformToType[VT] = MVT::i64; + else { + assert((VT == MVT::Vector || MVT::isInteger(VT)) && VT > MVT::i8 && + "Cannot expand this type: target must support SOME integer reg!"); + // Expand to the next smaller integer type! + TransformToType[VT] = (MVT::ValueType)(VT-1); + } } } @@ -120,12 +137,27 @@ void TargetLowering::computeRegisterProperties() { else TransformToType[(MVT::ValueType)IntReg] = (MVT::ValueType)IntReg; - // If the target does not have native support for F32, promote it to F64. - if (!isTypeLegal(MVT::f32)) - SetValueTypeAction(MVT::f32, Promote, *this, - TransformToType, ValueTypeActions); - else + // If the target does not have native F64 support, expand it to I64. We will + // be generating soft float library calls. If the target does not have native + // support for F32, promote it to F64 if it is legal. Otherwise, expand it to + // I32. + if (isTypeLegal(MVT::f64)) + TransformToType[MVT::f64] = MVT::f64; + else { + NumElementsForVT[MVT::f64] = NumElementsForVT[MVT::i64]; + SetValueTypeAction(MVT::f64, Expand, *this, TransformToType, + ValueTypeActions); + } + if (isTypeLegal(MVT::f32)) TransformToType[MVT::f32] = MVT::f32; + else if (isTypeLegal(MVT::f64)) + SetValueTypeAction(MVT::f32, Promote, *this, TransformToType, + ValueTypeActions); + else { + NumElementsForVT[MVT::f32] = NumElementsForVT[MVT::i32]; + SetValueTypeAction(MVT::f32, Expand, *this, TransformToType, + ValueTypeActions); + } // Set MVT::Vector to always be Expanded SetValueTypeAction(MVT::Vector, Expand, *this, TransformToType, @@ -138,9 +170,6 @@ void TargetLowering::computeRegisterProperties() { if (isTypeLegal((MVT::ValueType)i)) TransformToType[i] = (MVT::ValueType)i; } - - assert(isTypeLegal(MVT::f64) && "Target does not support FP?"); - TransformToType[MVT::f64] = MVT::f64; } const char *TargetLowering::getTargetNodeName(unsigned Opcode) const { @@ -354,20 +383,20 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask, return TLO.CombineTo(Op, Op.getOperand(0)); if ((DemandedMask & KnownZero2) == DemandedMask) return TLO.CombineTo(Op, Op.getOperand(1)); + + // If all of the unknown bits are known to be zero on one side or the other + // (but not both) turn this into an *inclusive* or. + // e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 + if ((DemandedMask & ~KnownZero & ~KnownZero2) == 0) + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, Op.getValueType(), + Op.getOperand(0), + Op.getOperand(1))); // Output known-0 bits are known if clear or set in both the LHS & RHS. KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2); // Output known-1 are known to be set if set in only one of the LHS, RHS. KnownOneOut = (KnownZero & KnownOne2) | (KnownOne & KnownZero2); - // If all of the unknown bits are known to be zero on one side or the other - // (but not both) turn this into an *inclusive* or. - // e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 - if (uint64_t UnknownBits = DemandedMask & ~(KnownZeroOut|KnownOneOut)) - if ((UnknownBits & (KnownZero|KnownZero2)) == UnknownBits) - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, Op.getValueType(), - Op.getOperand(0), - Op.getOperand(1))); // If all of the demanded bits on one side are known, and all of the set // bits on that side are also known to be set on the other side, turn this // into an AND, as we know the bits will be cleared. @@ -503,7 +532,6 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask, } break; case ISD::SIGN_EXTEND_INREG: { - MVT::ValueType VT = Op.getValueType(); MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); // Sign extension. Compute the demanded bits in the result that are not @@ -552,9 +580,10 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask, KnownOne = 0; break; } - case ISD::LOADX: { + case ISD::LOAD: { if (ISD::isZEXTLoad(Op.Val)) { - MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + LoadSDNode *LD = cast(Op); + MVT::ValueType VT = LD->getLoadedVT(); KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask; } break; @@ -850,7 +879,6 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask, } return; case ISD::SIGN_EXTEND_INREG: { - MVT::ValueType VT = Op.getValueType(); MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); // Sign extension. Compute the demanded bits in the result that are not @@ -892,9 +920,10 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask, KnownOne = 0; return; } - case ISD::LOADX: { + case ISD::LOAD: { if (ISD::isZEXTLoad(Op.Val)) { - MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + LoadSDNode *LD = cast(Op); + MVT::ValueType VT = LD->getLoadedVT(); KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask; } return; @@ -1197,15 +1226,16 @@ unsigned TargetLowering::ComputeNumSignBits(SDOperand Op, unsigned Depth) const{ } // Handle LOADX separately here. EXTLOAD case will fallthrough. - if (Op.getOpcode() == ISD::LOADX) { - unsigned LType = Op.getConstantOperandVal(4); - switch (LType) { + if (Op.getOpcode() == ISD::LOAD) { + LoadSDNode *LD = cast(Op); + unsigned ExtType = LD->getExtensionType(); + switch (ExtType) { default: break; case ISD::SEXTLOAD: // '17' bits known - Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + Tmp = MVT::getSizeInBits(LD->getLoadedVT()); return VTBits-Tmp+1; case ISD::ZEXTLOAD: // '16' bits known - Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + Tmp = MVT::getSizeInBits(LD->getLoadedVT()); return VTBits-Tmp; } } @@ -1296,18 +1326,21 @@ TargetLowering::getConstraintType(char ConstraintLetter) const { } } -bool TargetLowering::isOperandValidForConstraint(SDOperand Op, - char ConstraintLetter) { +/// isOperandValidForConstraint - Return the specified operand (possibly +/// modified) if the specified SDOperand is valid for the specified target +/// constraint letter, otherwise return null. +SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op, + char ConstraintLetter, + SelectionDAG &DAG) { switch (ConstraintLetter) { - default: return false; + default: return SDOperand(0,0); case 'i': // Simple Integer or Relocatable Constant case 'n': // Simple Integer case 's': // Relocatable Constant - return true; // FIXME: not right. + return Op; // FIXME: not right. } } - std::vector TargetLowering:: getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const {