aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-05-26 08:55:52 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-05-26 08:55:52 +0000
commit74807f2520715056be399a2bc59dfc8b6f8f3eb2 (patch)
treebedc636e535f043040900a8c6644aff19b894f4a
parentaed4a430f4f6cc0e3ff06d458e68e5d195bbed7c (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.cpp3696
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