diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-26 08:55:52 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-26 08:55:52 +0000 |
commit | 74807f2520715056be399a2bc59dfc8b6f8f3eb2 (patch) | |
tree | bedc636e535f043040900a8c6644aff19b894f4a | |
parent | aed4a430f4f6cc0e3ff06d458e68e5d195bbed7c (diff) |
Delete a bunch of dead code from LegalizeDAG.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72414 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 3696 |
1 files changed, 29 insertions, 3667 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c80b125228..44bf18bef9 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -69,11 +69,6 @@ class VISIBILITY_HIDDEN SelectionDAGLegalize { /// being legalized (which could lead to non-serialized call sequences). bool IsLegalizingCall; - /// IsLegalizingCallArguments - This member is used only for the purpose - /// of providing assert to check for LegalizeTypes because legalizing an - /// operation might introduce call nodes that might need type legalization. - bool IsLegalizingCallArgs; - enum LegalizeAction { Legal, // The target natively supports this operation. Promote, // This operation should be executed in a larger type. @@ -90,51 +85,12 @@ class VISIBILITY_HIDDEN SelectionDAGLegalize { /// allows us to avoid legalizing the same thing more than once. DenseMap<SDValue, SDValue> LegalizedNodes; - /// PromotedNodes - For nodes that are below legal width, and that have more - /// than one use, this map indicates what promoted value to use. This allows - /// us to avoid promoting the same thing more than once. - DenseMap<SDValue, SDValue> PromotedNodes; - - /// ExpandedNodes - For nodes that need to be expanded this map indicates - /// which operands are the expanded version of the input. This allows - /// us to avoid expanding the same node more than once. - DenseMap<SDValue, std::pair<SDValue, SDValue> > ExpandedNodes; - - /// SplitNodes - For vector nodes that need to be split, this map indicates - /// which operands are the split version of the input. This allows us - /// to avoid splitting the same node more than once. - std::map<SDValue, std::pair<SDValue, SDValue> > SplitNodes; - - /// ScalarizedNodes - For nodes that need to be converted from vector types to - /// scalar types, this contains the mapping of ones we have already - /// processed to the result. - std::map<SDValue, SDValue> ScalarizedNodes; - - /// WidenNodes - For nodes that need to be widened from one vector type to - /// another, this contains the mapping of those that we have already widen. - /// This allows us to avoid widening more than once. - std::map<SDValue, SDValue> WidenNodes; - void AddLegalizedOperand(SDValue From, SDValue To) { LegalizedNodes.insert(std::make_pair(From, To)); // If someone requests legalization of the new node, return itself. if (From != To) LegalizedNodes.insert(std::make_pair(To, To)); } - void AddPromotedOperand(SDValue From, SDValue To) { - bool isNew = PromotedNodes.insert(std::make_pair(From, To)).second; - assert(isNew && "Got into the map somehow?"); - isNew = isNew; - // If someone requests legalization of the new node, return itself. - LegalizedNodes.insert(std::make_pair(To, To)); - } - void AddWidenedOperand(SDValue From, SDValue To) { - bool isNew = WidenNodes.insert(std::make_pair(From, To)).second; - assert(isNew && "Got into the map somehow?"); - isNew = isNew; - // If someone requests legalization of the new node, return itself. - LegalizedNodes.insert(std::make_pair(To, To)); - } public: SelectionDAGLegalize(SelectionDAG &DAG, CodeGenOpt::Level ol); @@ -164,12 +120,6 @@ private: /// result. SDValue LegalizeOp(SDValue O); - /// UnrollVectorOp - We know that the given vector has a legal type, however - /// the operation it performs is not legal and is an operation that we have - /// no way of lowering. "Unroll" the vector, splitting out the scalars and - /// operating on each element individually. - SDValue UnrollVectorOp(SDValue O); - /// PerformInsertVectorEltInMemory - Some target cannot handle a variable /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it /// is necessary to spill the vector being inserted into to memory, perform @@ -177,94 +127,9 @@ private: SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, DebugLoc dl); - /// PromoteOp - Given an operation that produces a value in an invalid type, - /// promote it to compute the value into a larger type. The produced value - /// will have the correct bits for the low portion of the register, but no - /// guarantee is made about the top bits: it may be zero, sign-extended, or - /// garbage. - SDValue PromoteOp(SDValue O); - - /// ExpandOp - Expand the specified SDValue into its two component pieces - /// Lo&Hi. Note that the Op MUST be an expanded type. As a result of this, - /// the LegalizedNodes map is filled in for any results that are not expanded, - /// the ExpandedNodes map is filled in for any results that are expanded, and - /// the Lo/Hi values are returned. This applies to integer types and Vector - /// types. - void ExpandOp(SDValue O, SDValue &Lo, SDValue &Hi); - - /// WidenVectorOp - Widen a vector operation to a wider type given by WidenVT - /// (e.g., v3i32 to v4i32). The produced value will have the correct value - /// for the existing elements but no guarantee is made about the new elements - /// at the end of the vector: it may be zero, ones, or garbage. This is useful - /// when we have an instruction operating on an illegal vector type and we - /// want to widen it to do the computation on a legal wider vector type. - SDValue WidenVectorOp(SDValue Op, MVT WidenVT); - - /// SplitVectorOp - Given an operand of vector type, break it down into - /// two smaller values. - void SplitVectorOp(SDValue O, SDValue &Lo, SDValue &Hi); - - /// ScalarizeVectorOp - Given an operand of single-element vector type - /// (e.g. v1f32), convert it into the equivalent operation that returns a - /// scalar (e.g. f32) value. - SDValue ScalarizeVectorOp(SDValue O); - /// Useful 16 element vector type that is used to pass operands for widening. typedef SmallVector<SDValue, 16> SDValueVector; - /// LoadWidenVectorOp - Load a vector for a wider type. Returns true if - /// the LdChain contains a single load and false if it contains a token - /// factor for multiple loads. It takes - /// Result: location to return the result - /// LdChain: location to return the load chain - /// Op: load operation to widen - /// NVT: widen vector result type we want for the load - bool LoadWidenVectorOp(SDValue& Result, SDValue& LdChain, - SDValue Op, MVT NVT); - - /// Helper genWidenVectorLoads - Helper function to generate a set of - /// loads to load a vector with a resulting wider type. It takes - /// LdChain: list of chains for the load we have generated - /// Chain: incoming chain for the ld vector - /// BasePtr: base pointer to load from - /// SV: memory disambiguation source value - /// SVOffset: memory disambiugation offset - /// Alignment: alignment of the memory - /// isVolatile: volatile load - /// LdWidth: width of memory that we want to load - /// ResType: the wider result result type for the resulting loaded vector - SDValue genWidenVectorLoads(SDValueVector& LdChain, SDValue Chain, - SDValue BasePtr, const Value *SV, - int SVOffset, unsigned Alignment, - bool isVolatile, unsigned LdWidth, - MVT ResType, DebugLoc dl); - - /// StoreWidenVectorOp - Stores a widen vector into non widen memory - /// location. It takes - /// ST: store node that we want to replace - /// Chain: incoming store chain - /// BasePtr: base address of where we want to store into - SDValue StoreWidenVectorOp(StoreSDNode *ST, SDValue Chain, - SDValue BasePtr); - - /// Helper genWidenVectorStores - Helper function to generate a set of - /// stores to store a widen vector into non widen memory - // It takes - // StChain: list of chains for the stores we have generated - // Chain: incoming chain for the ld vector - // BasePtr: base pointer to load from - // SV: memory disambiguation source value - // SVOffset: memory disambiugation offset - // Alignment: alignment of the memory - // isVolatile: volatile lod - // ValOp: value to store - // StWidth: width of memory that we want to store - void genWidenVectorStores(SDValueVector& StChain, SDValue Chain, - SDValue BasePtr, const Value *SV, - int SVOffset, unsigned Alignment, - bool isVolatile, SDValue ValOp, - unsigned StWidth, DebugLoc dl); - /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which /// performs the same shuffe in terms of order or result bytes, but on a type /// whose vector element type is narrower than the original shuffle type. @@ -288,7 +153,6 @@ private: SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned, SDValue &Hi); - SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl); SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl); SDValue ExpandBUILD_VECTOR(SDNode *Node); @@ -304,12 +168,7 @@ private: SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); - bool ExpandShift(unsigned Opc, SDValue Op, SDValue Amt, - SDValue &Lo, SDValue &Hi, DebugLoc dl); - void ExpandShiftParts(unsigned NodeOp, SDValue Op, SDValue Amt, - SDValue &Lo, SDValue &Hi, DebugLoc dl); - SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op); SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op); SDValue ExpandExtractFromVectorThroughStack(SDValue Op); }; @@ -359,7 +218,6 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag, void SelectionDAGLegalize::LegalizeDAG() { LastCALLSEQ_END = DAG.getEntryNode(); IsLegalizingCall = false; - IsLegalizingCallArgs = false; // The legalize process is inherently a bottom-up recursive process (users // legalize their uses before themselves). Given infinite stack space, we @@ -377,12 +235,7 @@ void SelectionDAGLegalize::LegalizeDAG() { assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?"); DAG.setRoot(LegalizedNodes[OldRoot]); - ExpandedNodes.clear(); LegalizedNodes.clear(); - PromotedNodes.clear(); - SplitNodes.clear(); - ScalarizedNodes.clear(); - WidenNodes.clear(); // Remove dead nodes now. DAG.RemoveDeadNodes(); @@ -457,17 +310,7 @@ bool SelectionDAGLegalize::LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, // If the first result of this node has been already legalized, then it cannot // reach N. - switch (getTypeAction(N->getValueType(0))) { - case Legal: - if (LegalizedNodes.count(SDValue(N, 0))) return false; - break; - case Promote: - if (PromotedNodes.count(SDValue(N, 0))) return false; - break; - case Expand: - if (ExpandedNodes.count(SDValue(N, 0))) return false; - break; - } + if (LegalizedNodes.count(SDValue(N, 0))) return false; // Okay, this node has not already been legalized. Check and legalize all // operands. If none lead to Dest, then we can legalize this node. @@ -495,43 +338,7 @@ void SelectionDAGLegalize::HandleOp(SDValue Op) { MVT VT = Op.getValueType(); // We should never see any illegal result types here. assert(isTypeLegal(VT) && "Illegal type introduced after type legalization?"); - switch (getTypeAction(VT)) { - default: assert(0 && "Bad type action!"); - case Legal: (void)LegalizeOp(Op); break; - case Promote: - if (!VT.isVector()) { - (void)PromoteOp(Op); - break; - } - else { - // See if we can widen otherwise use Expand to either scalarize or split - MVT WidenVT = TLI.getWidenVectorType(VT); - if (WidenVT != MVT::Other) { - (void) WidenVectorOp(Op, WidenVT); - break; - } - // else fall thru to expand since we can't widen the vector - } - case Expand: - if (!VT.isVector()) { - // If this is an illegal scalar, expand it into its two component - // pieces. - SDValue X, Y; - if (Op.getOpcode() == ISD::TargetConstant) - break; // Allow illegal target nodes. - ExpandOp(Op, X, Y); - } else if (VT.getVectorNumElements() == 1) { - // If this is an illegal single element vector, convert it to a - // scalar operation. - (void)ScalarizeVectorOp(Op); - } else { - // This is an illegal multiple element vector. - // Split it in half and legalize both parts. - SDValue X, Y; - SplitVectorOp(Op, X, Y); - } - break; - } + (void)LegalizeOp(Op); } /// ExpandConstantFP - Expands the ConstantFP node to an integer constant or @@ -582,53 +389,6 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, PseudoSourceValue::getConstantPool(), 0, false, Alignment); } - -/// ExpandFCOPYSIGNToBitwiseOps - Expands fcopysign to a series of bitwise -/// operations. -static -SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT, - SelectionDAG &DAG, - const TargetLowering &TLI) { - DebugLoc dl = Node->getDebugLoc(); - MVT VT = Node->getValueType(0); - MVT SrcVT = Node->getOperand(1).getValueType(); - assert((SrcVT == MVT::f32 || SrcVT == MVT::f64) && - "fcopysign expansion only supported for f32 and f64"); - MVT SrcNVT = (SrcVT == MVT::f64) ? MVT::i64 : MVT::i32; - - // First get the sign bit of second operand. - SDValue Mask1 = (SrcVT == MVT::f64) - ? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT) - : DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT); - Mask1 = DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT, Mask1); - SDValue SignBit= DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT, - Node->getOperand(1)); - SignBit = DAG.getNode(ISD::AND, dl, SrcNVT, SignBit, Mask1); - // Shift right or sign-extend it if the two operands have different types. - int SizeDiff = SrcNVT.getSizeInBits() - NVT.getSizeInBits(); - if (SizeDiff > 0) { - SignBit = DAG.getNode(ISD::SRL, dl, SrcNVT, SignBit, - DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); - SignBit = DAG.getNode(ISD::TRUNCATE, dl, NVT, SignBit); - } else if (SizeDiff < 0) { - SignBit = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, SignBit); - SignBit = DAG.getNode(ISD::SHL, dl, NVT, SignBit, - DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); - } - - // Clear the sign bit of first operand. - SDValue Mask2 = (VT == MVT::f64) - ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT) - : DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT); - Mask2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask2); - SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); - Result = DAG.getNode(ISD::AND, dl, NVT, Result, Mask2); - - // Or the value with the sign bit. - Result = DAG.getNode(ISD::OR, dl, NVT, Result, SignBit); - return Result; -} - /// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. static SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, @@ -864,58 +624,6 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, return DAG.getMergeValues(Ops, 2, dl); } -/// UnrollVectorOp - We know that the given vector has a legal type, however -/// the operation it performs is not legal and is an operation that we have -/// no way of lowering. "Unroll" the vector, splitting out the scalars and -/// operating on each element individually. -SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { - MVT VT = Op.getValueType(); - assert(isTypeLegal(VT) && - "Caller should expand or promote operands that are not legal!"); - assert(Op.getNode()->getNumValues() == 1 && - "Can't unroll a vector with multiple results!"); - unsigned NE = VT.getVectorNumElements(); - MVT EltVT = VT.getVectorElementType(); - DebugLoc dl = Op.getDebugLoc(); - - SmallVector<SDValue, 8> Scalars; - SmallVector<SDValue, 4> Operands(Op.getNumOperands()); - for (unsigned i = 0; i != NE; ++i) { - for (unsigned j = 0; j != Op.getNumOperands(); ++j) { - SDValue Operand = Op.getOperand(j); - MVT OperandVT = Operand.getValueType(); - if (OperandVT.isVector()) { - // A vector operand; extract a single element. - MVT OperandEltVT = OperandVT.getVectorElementType(); - Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, - OperandEltVT, - Operand, - DAG.getConstant(i, MVT::i32)); - } else { - // A scalar operand; just use it as is. - Operands[j] = Operand; - } - } - - switch (Op.getOpcode()) { - default: - Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT, - &Operands[0], Operands.size())); - break; - case ISD::SHL: - case ISD::SRA: - case ISD::SRL: - case ISD::ROTL: - case ISD::ROTR: - Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT, Operands[0], - DAG.getShiftAmountOperand(Operands[1]))); - break; - } - } - - return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Scalars[0], Scalars.size()); -} - /// GetFPLibCall - Return the right libcall for the given floating point type. static RTLIB::Libcall GetFPLibCall(MVT VT, RTLIB::Libcall Call_F32, @@ -1291,20 +999,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (Result.getNode()) break; case TargetLowering::Legal: { - LegalizeAction Action = getTypeAction(Node->getOperand(1).getValueType()); - if (Action == Legal && Tmp1 == Node->getOperand(0)) + if (Tmp1 == Node->getOperand(0)) break; SmallVector<SDValue, 8> Ops; Ops.push_back(Tmp1); - if (Action == Legal) { - Ops.push_back(Node->getOperand(1)); // line # must be legal. - Ops.push_back(Node->getOperand(2)); // col # must be legal. - } else { - // Otherwise promote them. - Ops.push_back(PromoteOp(Node->getOperand(1))); - Ops.push_back(PromoteOp(Node->getOperand(2))); - } + Ops.push_back(Node->getOperand(1)); // line # must be legal. + Ops.push_back(Node->getOperand(2)); // col # must be legal. Ops.push_back(Node->getOperand(3)); // filename must be legal. Ops.push_back(Node->getOperand(4)); // working dir # must be legal. Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); @@ -1784,13 +1485,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Recursively Legalize all of the inputs of the call end that do not lead // to this call start. This ensures that any libcalls that need be inserted // are inserted *before* the CALLSEQ_START. - IsLegalizingCallArgs = true; {SmallPtrSet<SDNode*, 32> NodesLeadingTo; for (unsigned i = 0, e = CallEnd->getNumOperands(); i != e; ++i) LegalizeAllNodesNotLeadingTo(CallEnd->getOperand(i).getNode(), Node, NodesLeadingTo); } - IsLegalizingCallArgs = false; // Now that we legalized all of the inputs (which may have inserted // libcalls) create the new CALLSEQ_START node. @@ -3086,10 +2785,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } - assert(Node->getValueType(0).isVector() && - "Cannot expand this binary operator!"); - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Op)); + assert(0 && "Cannot expand this binary operator!"); break; } case TargetLowering::Promote: { @@ -3336,10 +3032,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } - assert(VT.isVector() && - "Cannot expand this binary operator!"); - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Op)); + assert(0 && "Cannot expand this binary operator!"); break; } } @@ -3620,11 +3313,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::FNEARBYINT: { MVT VT = Node->getValueType(0); - // Expand unsupported unary vector operators by unrolling them. - if (VT.isVector()) { - Result = LegalizeOp(UnrollVectorOp(Op)); - break; - } + assert(!VT.isVector() && "Vector shouldn't get here!"); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch(Node->getOpcode()) { @@ -3695,10 +3384,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT VT = Node->getValueType(0); // Expand unsupported unary vector operators by unrolling them. - if (VT.isVector()) { - Result = LegalizeOp(UnrollVectorOp(Op)); - break; - } + assert(!VT.isVector() && "Vector shouldn't get here!"); // We always lower FPOWI into a libcall. No target support for it yet. RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::POWI_F32, RTLIB::POWI_F64, @@ -3774,11 +3460,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (Tmp1.getNode()) Result = Tmp1; } break; - case TargetLowering::Expand: - assert(Result.getValueType().isVector() && "must be vector type"); - // Unroll the truncate. We should do better. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; } break; @@ -4093,497 +3774,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { return Result; } -/// PromoteOp - Given an operation that produces a value in an invalid type, -/// promote it to compute the value into a larger type. The produced value will -/// have the correct bits for the low portion of the register, but no guarantee -/// is made about the top bits: it may be zero, sign-extended, or garbage. -SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { - assert(0 && "This should be dead!"); - MVT VT = Op.getValueType(); - MVT NVT = TLI.getTypeToTransformTo(VT); - assert(getTypeAction(VT) == Promote && - "Caller should expand or legalize operands that are not promotable!"); - assert(NVT.bitsGT(VT) && NVT.isInteger() == VT.isInteger() && - "Cannot promote to smaller type!"); - - SDValue Tmp1, Tmp2, Tmp3; - SDValue Result; - SDNode *Node = Op.getNode(); - DebugLoc dl = Node->getDebugLoc(); - - DenseMap<SDValue, SDValue>::iterator I = PromotedNodes.find(Op); - if (I != PromotedNodes.end()) return I->second; - - switch (Node->getOpcode()) { - case ISD::CopyFromReg: - assert(0 && "CopyFromReg must be legal!"); - default: -#ifndef NDEBUG - cerr << "NODE: "; Node->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator!"); - abort(); - case ISD::UNDEF: - Result = DAG.getUNDEF(NVT); - break; - case ISD::Constant: - if (VT != MVT::i1) - Result = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Op); - else - Result = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Op); - assert(isa<ConstantSDNode>(Result) && "Didn't constant fold zext?"); - break; - case ISD::ConstantFP: - Result = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op); - assert(isa<ConstantFPSDNode>(Result) && "Didn't constant fold fp_extend?"); - break; - - case ISD::SETCC: { - MVT VT0 = Node->getOperand(0).getValueType(); - assert(isTypeLegal(TLI.getSetCCResultType(VT0)) - && "SetCC type is not legal??"); - Result = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(VT0), - Node->getOperand(0), Node->getOperand(1), - Node->getOperand(2)); - break; - } - case ISD::TRUNCATE: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Legal: - Result = LegalizeOp(Node->getOperand(0)); - assert(Result.getValueType().bitsGE(NVT) && - "This truncation doesn't make sense!"); - if (Result.getValueType().bitsGT(NVT)) // Truncate to NVT instead of VT - Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Result); - break; - case Promote: - // The truncation is not required, because we don't guarantee anything - // about high bits anyway. - Result = PromoteOp(Node->getOperand(0)); - break; - case Expand: - ExpandOp(Node->getOperand(0), Tmp1, Tmp2); - // Truncate the low part of the expanded value to the result type - Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Tmp1); - } - break; - case ISD::SIGN_EXTEND: - case ISD::ZERO_EXTEND: - case ISD::ANY_EXTEND: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Expand: assert(0 && "BUG: Smaller reg should have been promoted!"); - case Legal: - // Input is legal? Just do extend all the way to the larger type. - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0)); - break; - case Promote: - // Promote the reg if it's smaller. - Result = PromoteOp(Node->getOperand(0)); - // The high bits are not guaranteed to be anything. Insert an extend. - if (Node->getOpcode() == ISD::SIGN_EXTEND) - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result, - DAG.getValueType(Node->getOperand(0).getValueType())); - else if (Node->getOpcode() == ISD::ZERO_EXTEND) - Result = DAG.getZeroExtendInReg(Result, dl, - Node->getOperand(0).getValueType()); - break; - } - break; - case ISD::CONVERT_RNDSAT: { - ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode(); - assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU || - CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU || - CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) && - "can only promote integers"); - Result = DAG.getConvertRndSat(NVT, dl, Node->getOperand(0), - Node->getOperand(1), Node->getOperand(2), - Node->getOperand(3), Node->getOperand(4), - CvtCode); - break; - - } - case ISD::BIT_CONVERT: - Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), - Node->getValueType(0), dl); - Result = PromoteOp(Result); - break; - - case ISD::FP_EXTEND: - assert(0 && "Case not implemented. Dynamically dead with 2 FP types!"); - case ISD::FP_ROUND: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Expand: assert(0 && "BUG: Cannot expand FP regs!"); - case Promote: assert(0 && "Unreachable with 2 FP types!"); - case Legal: - if (Node->getConstantOperandVal(1) == 0) { - // Input is legal? Do an FP_ROUND_INREG. - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Node->getOperand(0), - DAG.getValueType(VT)); - } else { - // Just remove the truncate, it isn't affecting the value. - Result = DAG.getNode(ISD::FP_ROUND, dl, NVT, Node->getOperand(0), - Node->getOperand(1)); - } - break; - } - break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Legal: - // No extra round required here. - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0)); - break; - - case Promote: - Result = PromoteOp(Node->getOperand(0)); - if (Node->getOpcode() == ISD::SINT_TO_FP) - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Result.getValueType(), - Result, - DAG.getValueType(Node->getOperand(0).getValueType())); - else - Result = DAG.getZeroExtendInReg(Result, dl, - Node->getOperand(0).getValueType()); - // No extra round required here. - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Result); - break; - case Expand: - Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, NVT, - Node->getOperand(0), dl); - // Round if we cannot tolerate excess precision. - if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - } - break; - - case ISD::SIGN_EXTEND_INREG: - Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result, - Node->getOperand(1)); - break; - case ISD::FP_TO_SINT: - case ISD::FP_TO_UINT: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Legal: - case Expand: - Tmp1 = Node->getOperand(0); - break; - case Promote: - // The input result is prerounded, so we don't have to do anything - // special. - Tmp1 = PromoteOp(Node->getOperand(0)); - break; - } - // If we're promoting a UINT to a larger size, check to see if the new node - // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since - // we can use that instead. This allows us to generate better code for - // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not - // legal, such as PowerPC. - if (Node->getOpcode() == ISD::FP_TO_UINT && - !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) && - (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT) || - TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){ - Result = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Tmp1); - } else { - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); - } - break; - - case ISD::FABS: - case ISD::FNEG: - Tmp1 = PromoteOp(Node->getOperand(0)); - assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); - // NOTE: we do not have to do any extra rounding here for - // NoExcessFPPrecision, because we know the input will have the appropriate - // precision, and these operations don't modify precision at all. - break; - - case ISD::FLOG: - case ISD::FLOG2: - case ISD::FLOG10: - case ISD::FEXP: - case ISD::FEXP2: - case ISD::FSQRT: - case ISD::FSIN: - case ISD::FCOS: - case ISD::FTRUNC: - case ISD::FFLOOR: - case ISD::FCEIL: - case ISD::FRINT: - case ISD::FNEARBYINT: - Tmp1 = PromoteOp(Node->getOperand(0)); - assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); - if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - - case ISD::FPOW: - case ISD::FPOWI: { - // Promote f32 pow(i) to f64 pow(i). Note that this could insert a libcall - // directly as well, which may be better. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = Node->getOperand(1); - if (Node->getOpcode() == ISD::FPOW) - Tmp2 = PromoteOp(Tmp2); - assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - } - - case ISD::ATOMIC_CMP_SWAP: { - AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node); - Tmp2 = PromoteOp(Node->getOperand(2)); - Tmp3 = PromoteOp(Node->getOperand(3)); - Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(), - AtomNode->getChain(), - AtomNode->getBasePtr(), Tmp2, Tmp3, - AtomNode->getSrcValue(), - AtomNode->getAlignment()); - // Remember that we legalized the chain. - AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1))); - break; - } - case ISD::ATOMIC_LOAD_ADD: - case ISD::ATOMIC_LOAD_SUB: - case ISD::ATOMIC_LOAD_AND: - case ISD::ATOMIC_LOAD_OR: - case ISD::ATOMIC_LOAD_XOR: - case ISD::ATOMIC_LOAD_NAND: - case ISD::ATOMIC_LOAD_MIN: - case ISD::ATOMIC_LOAD_MAX: - case ISD::ATOMIC_LOAD_UMIN: - case ISD::ATOMIC_LOAD_UMAX: - case ISD::ATOMIC_SWAP: { - AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node); - Tmp2 = PromoteOp(Node->getOperand(2)); - Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(), - AtomNode->getChain(), - AtomNode->getBasePtr(), Tmp2, - AtomNode->getSrcValue(), - AtomNode->getAlignment()); - // Remember that we legalized the chain. - AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1))); - break; - } - - case ISD::AND: - case ISD::OR: - case ISD::XOR: - case ISD::ADD: - case ISD::SUB: - case ISD::MUL: - // The input may have strange things in the top bits of the registers, but - // these operations don't care. They may have weird bits going out, but - // that too is okay if they are integer operations. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); - assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - break; - case ISD::FADD: - case ISD::FSUB: - case ISD::FMUL: - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); - assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - - // Floating point operations will give excess precision that we may not be - // able to tolerate. If we DO allow excess precision, just leave it, - // otherwise excise it. - // FIXME: Why would we need to round FP ops more than integer ones? - // Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C)) - if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - - case ISD::SDIV: - case ISD::SREM: - // These operators require that their input be sign extended. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); - if (NVT.isInteger()) { - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1, - DAG.getValueType(VT)); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp2, - DAG.getValueType(VT)); - } - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - - // Perform FP_ROUND: this is probably overly pessimistic. - if (NVT.isFloatingPoint() && NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - case ISD::FDIV: - case ISD::FREM: - case ISD::FCOPYSIGN: - // These operators require that their input be fp extended. - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Expand: assert(0 && "not implemented"); - case Legal: Tmp1 = LegalizeOp(Node->getOperand(0)); break; - case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); break; - } - switch (getTypeAction(Node->getOperand(1).getValueType())) { - case Expand: assert(0 && "not implemented"); - case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); break; - case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break; - } - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - - // Perform FP_ROUND: this is probably overly pessimistic. - if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN) - Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, - DAG.getValueType(VT)); - break; - - case ISD::UDIV: - case ISD::UREM: - // These operators require that their input be zero extended. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp2 = PromoteOp(Node->getOperand(1)); - assert(NVT.isInteger() && "Operators don't apply to FP!"); - Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT); - Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, VT); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - break; - - case ISD::SHL: - Tmp1 = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::SHL, dl, NVT, Tmp1, Node->getOperand(1)); - break; - case ISD::SRA: - // The input value must be properly sign extended. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1, - DAG.getValueType(VT)); - Result = DAG.getNode(ISD::SRA, dl, NVT, Tmp1, Node->getOperand(1)); - break; - case ISD::SRL: - // The input value must be properly zero extended. - Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT); - Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, Node->getOperand(1)); - break; - - case ISD::VAARG: - Tmp1 = Node->getOperand(0); // Get the chain. - Tmp2 = Node->getOperand(1); // Get the pointer. - if (TLI.getOperationAction(ISD::VAARG, VT) == TargetLowering::Custom) { - Tmp3 = DAG.getVAArg(VT, dl, Tmp1, Tmp2, Node->getOperand(2)); - Result = TLI.Lowe |