aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-06-17 14:27:01 +0000
committerDuncan Sands <baldrick@free.fr>2008-06-17 14:27:01 +0000
commit69b01e92a29ce6d7e435171aeea3fbc987b81586 (patch)
tree5d1ea52d6c49439229957559901114b55b955cb1 /lib/CodeGen
parentde9256ad2e33a203e97328e285c3909f67aad4b0 (diff)
Split type expansion into ExpandInteger and ExpandFloat
rather than bundling them together. Rename FloatToInt to PromoteFloat (better, if not perfect). Reorganize files by types rather than by operations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (renamed from lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp)179
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (renamed from lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp)1099
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp148
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h378
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp748
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp233
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (renamed from lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp)326
7 files changed, 1611 insertions, 1500 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index c3bde9b129..d4e5a45876 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -1,4 +1,4 @@
-//===-- LegalizeTypesFloatToInt.cpp - LegalizeTypes float to int support --===//
+//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,17 +7,23 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements float to integer conversion for LegalizeTypes. This
-// is the act of turning a computation in an invalid floating point type into
-// a computation in an integer type of the same size. For example, turning
-// f32 arithmetic into operations using i32. Also known as "soft float".
-// The result is equivalent to bitcasting the float value to the integer type.
+// This file implements float type expansion and conversion of float types to
+// integer types on behalf of LegalizeTypes.
+// Converting to integer is the act of turning a computation in an illegal
+// floating point type into a computation in an integer type of the same size.
+// For example, turning f32 arithmetic into operations using i32. Also known as
+// "soft float". The result is equivalent to bitcasting the float value to the
+// integer type.
+// Expansion is the act of changing a computation in an illegal type to be a
+// computation in multiple registers of a smaller type. For example,
+// implementing ppcf128 arithmetic in two f64 registers.
//
//===----------------------------------------------------------------------===//
+#include "LegalizeTypes.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
-#include "LegalizeTypes.h"
using namespace llvm;
/// GetFPLibCall - Return the right libcall for the given floating point type.
@@ -38,8 +44,8 @@ static RTLIB::Libcall GetFPLibCall(MVT VT,
// Result Float to Integer Conversion.
//===----------------------------------------------------------------------===//
-void DAGTypeLegalizer::FloatToIntResult(SDNode *N, unsigned ResNo) {
- DEBUG(cerr << "FloatToInt node result " << ResNo << ": "; N->dump(&DAG);
+void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Promote float result " << ResNo << ": "; N->dump(&DAG);
cerr << "\n");
SDOperand R = SDOperand();
@@ -61,37 +67,37 @@ void DAGTypeLegalizer::FloatToIntResult(SDNode *N, unsigned ResNo) {
switch (N->getOpcode()) {
default:
#ifndef NDEBUG
- cerr << "FloatToIntResult #" << ResNo << ": ";
+ cerr << "PromoteFloatResult #" << ResNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
assert(0 && "Do not know how to convert the result of this operator!");
abort();
- case ISD::BIT_CONVERT: R = FloatToIntRes_BIT_CONVERT(N); break;
- case ISD::BUILD_PAIR: R = FloatToIntRes_BUILD_PAIR(N); break;
+ case ISD::BIT_CONVERT: R = PromoteFloatRes_BIT_CONVERT(N); break;
+ case ISD::BUILD_PAIR: R = PromoteFloatRes_BUILD_PAIR(N); break;
case ISD::ConstantFP:
- R = FloatToIntRes_ConstantFP(cast<ConstantFPSDNode>(N));
+ R = PromoteFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
break;
- case ISD::FCOPYSIGN: R = FloatToIntRes_FCOPYSIGN(N); break;
- case ISD::LOAD: R = FloatToIntRes_LOAD(N); break;
+ case ISD::FCOPYSIGN: R = PromoteFloatRes_FCOPYSIGN(N); break;
+ case ISD::LOAD: R = PromoteFloatRes_LOAD(N); break;
case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: R = FloatToIntRes_XINT_TO_FP(N); break;
+ case ISD::UINT_TO_FP: R = PromoteFloatRes_XINT_TO_FP(N); break;
- case ISD::FADD: R = FloatToIntRes_FADD(N); break;
- case ISD::FMUL: R = FloatToIntRes_FMUL(N); break;
- case ISD::FSUB: R = FloatToIntRes_FSUB(N); break;
+ case ISD::FADD: R = PromoteFloatRes_FADD(N); break;
+ case ISD::FMUL: R = PromoteFloatRes_FMUL(N); break;
+ case ISD::FSUB: R = PromoteFloatRes_FSUB(N); break;
}
// If R is null, the sub-method took care of registering the result.
if (R.Val)
- SetIntegerOp(SDOperand(N, ResNo), R);
+ SetPromotedFloat(SDOperand(N, ResNo), R);
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_BIT_CONVERT(SDNode *N) {
return BitConvertToInteger(N->getOperand(0));
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_BUILD_PAIR(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_BUILD_PAIR(SDNode *N) {
// Convert the inputs to integers, and build a new pair out of them.
return DAG.getNode(ISD::BUILD_PAIR,
TLI.getTypeToTransformTo(N->getValueType(0)),
@@ -99,15 +105,15 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_BUILD_PAIR(SDNode *N) {
BitConvertToInteger(N->getOperand(1)));
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_ConstantFP(ConstantFPSDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_ConstantFP(ConstantFPSDNode *N) {
return DAG.getConstant(N->getValueAPF().convertToAPInt(),
TLI.getTypeToTransformTo(N->getValueType(0)));
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_FADD(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FADD(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
- GetIntegerOp(N->getOperand(1)) };
+ SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+ GetPromotedFloat(N->getOperand(1)) };
return MakeLibCall(GetFPLibCall(N->getValueType(0),
RTLIB::ADD_F32,
RTLIB::ADD_F64,
@@ -116,8 +122,8 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_FADD(SDNode *N) {
NVT, Ops, 2, false/*sign irrelevant*/);
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_FCOPYSIGN(SDNode *N) {
- SDOperand LHS = GetIntegerOp(N->getOperand(0));
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FCOPYSIGN(SDNode *N) {
+ SDOperand LHS = GetPromotedFloat(N->getOperand(0));
SDOperand RHS = BitConvertToInteger(N->getOperand(1));
MVT LVT = LHS.getValueType();
@@ -155,10 +161,10 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_FCOPYSIGN(SDNode *N) {
return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_FMUL(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FMUL(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
- GetIntegerOp(N->getOperand(1)) };
+ SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+ GetPromotedFloat(N->getOperand(1)) };
return MakeLibCall(GetFPLibCall(N->getValueType(0),
RTLIB::MUL_F32,
RTLIB::MUL_F64,
@@ -167,10 +173,10 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_FMUL(SDNode *N) {
NVT, Ops, 2, false/*sign irrelevant*/);
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_FSUB(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FSUB(SDNode *N) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
- GetIntegerOp(N->getOperand(1)) };
+ SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+ GetPromotedFloat(N->getOperand(1)) };
return MakeLibCall(GetFPLibCall(N->getValueType(0),
RTLIB::SUB_F32,
RTLIB::SUB_F64,
@@ -179,7 +185,7 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_FSUB(SDNode *N) {
NVT, Ops, 2, false/*sign irrelevant*/);
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_LOAD(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) {
LoadSDNode *L = cast<LoadSDNode>(N);
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
@@ -200,7 +206,7 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_LOAD(SDNode *N) {
return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL));
}
-SDOperand DAGTypeLegalizer::FloatToIntRes_XINT_TO_FP(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatRes_XINT_TO_FP(SDNode *N) {
bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
MVT DestVT = N->getValueType(0);
SDOperand Op = N->getOperand(0);
@@ -305,8 +311,8 @@ SDOperand DAGTypeLegalizer::FloatToIntRes_XINT_TO_FP(SDNode *N) {
// Operand Float to Integer Conversion..
//===----------------------------------------------------------------------===//
-bool DAGTypeLegalizer::FloatToIntOperand(SDNode *N, unsigned OpNo) {
- DEBUG(cerr << "FloatToInt node operand " << OpNo << ": "; N->dump(&DAG);
+bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Promote float operand " << OpNo << ": "; N->dump(&DAG);
cerr << "\n");
SDOperand Res(0, 0);
@@ -321,13 +327,13 @@ bool DAGTypeLegalizer::FloatToIntOperand(SDNode *N, unsigned OpNo) {
switch (N->getOpcode()) {
default:
#ifndef NDEBUG
- cerr << "FloatToIntOperand Op #" << OpNo << ": ";
+ cerr << "PromoteFloatOperand Op #" << OpNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
assert(0 && "Do not know how to convert this operator's operand!");
abort();
- case ISD::BIT_CONVERT: Res = FloatToIntOp_BIT_CONVERT(N); break;
+ case ISD::BIT_CONVERT: Res = PromoteFloatOp_BIT_CONVERT(N); break;
}
}
@@ -351,7 +357,96 @@ bool DAGTypeLegalizer::FloatToIntOperand(SDNode *N, unsigned OpNo) {
return false;
}
-SDOperand DAGTypeLegalizer::FloatToIntOp_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::PromoteFloatOp_BIT_CONVERT(SDNode *N) {
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
- GetIntegerOp(N->getOperand(0)));
+ GetPromotedFloat(N->getOperand(0)));
+}
+
+
+//===----------------------------------------------------------------------===//
+// Float Result Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandFloatResult - This method is called when the specified result of the
+/// specified node is found to need expansion. At this point, the node may also
+/// have invalid operands or may have other results that need promotion, we just
+/// know that (at least) one result needs expansion.
+void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Lo, Hi;
+ Lo = Hi = SDOperand();
+
+ // See if the target wants to custom expand this node.
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ TargetLowering::Custom) {
+ // If the target wants to, allow it to lower this itself.
+ if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+ // Everything that once used N now uses P. We are guaranteed that the
+ // result value types of N and the result value types of P match.
+ ReplaceNodeWith(N, P);
+ return;
+ }
+ }
+
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "ExpandFloatResult #" << ResNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to expand the result of this operator!");
+ abort();
+ }
+
+ // If Lo/Hi is null, the sub-method took care of registering results etc.
+ if (Lo.Val)
+ SetExpandedFloat(SDOperand(N, ResNo), Lo, Hi);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Float Operand Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandFloatOperand - This method is called when the specified operand of the
+/// specified node is found to need expansion. At this point, all of the result
+/// types of the node are known to be legal, but other operands of the node may
+/// need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Res(0, 0);
+
+ if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
+ == TargetLowering::Custom)
+ Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+
+ if (Res.Val == 0) {
+ switch (N->getOpcode()) {
+ default:
+ #ifndef NDEBUG
+ cerr << "ExpandFloatOperand Op #" << OpNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+ #endif
+ assert(0 && "Do not know how to expand this operator's operand!");
+ abort();
+ }
+ }
+
+ // If the result is null, the sub-method took care of registering results etc.
+ if (!Res.Val) return false;
+ // If the result is N, the sub-method updated N in place. Check to see if any
+ // operands are new, and if so, mark them.
+ if (Res.Val == N) {
+ // Mark N as new and remark N and its operands. This allows us to correctly
+ // revisit N if it needs another step of expansion and allows us to visit
+ // any new operands to N.
+ ReanalyzeNode(N);
+ return true;
+ }
+
+ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+ "Invalid operand expansion");
+
+ ReplaceValueWith(SDOperand(N, 0), Res);
+ return false;
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 76bbd81858..4b927fec08 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1,4 +1,4 @@
-//===-- LegalizeTypesExpand.cpp - Expansion for LegalizeTypes -------------===//
+//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements expansion support for LegalizeTypes. Expansion is the
-// act of changing a computation in an invalid type to be a computation in
-// multiple registers of a smaller type. For example, implementing i64
-// arithmetic in two i32 registers (as is often needed on 32-bit targets, for
-// example).
+// This file implements integer type expansion and promotion for LegalizeTypes.
+// Promotion is the act of changing a computation in an illegal type into a
+// computation in a larger type. For example, implementing i8 arithmetic in an
+// i32 register (often needed on powerpc).
+// Expansion is the act of changing a computation in an illegal type into a
+// computation in multiple registers of a smaller type. For example,
+// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
+// targets).
//
//===----------------------------------------------------------------------===//
@@ -20,20 +23,720 @@
using namespace llvm;
//===----------------------------------------------------------------------===//
-// Result Expansion
+// Integer Result Promotion
//===----------------------------------------------------------------------===//
-/// ExpandResult - This method is called when the specified result of the
+/// PromoteIntegerResult - This method is called when a result of a node is
+/// found to be in need of promotion to a larger type. At this point, the node
+/// may also have invalid operands or may have other results that need
+/// expansion, we just know that (at least) one result needs promotion.
+void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Promote integer result: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Result = SDOperand();
+
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "PromoteIntegerResult #" << ResNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to promote this operator!");
+ abort();
+ case ISD::UNDEF: Result = PromoteIntRes_UNDEF(N); break;
+ case ISD::Constant: Result = PromoteIntRes_Constant(N); break;
+
+ case ISD::TRUNCATE: Result = PromoteIntRes_TRUNCATE(N); break;
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ case ISD::ANY_EXTEND: Result = PromoteIntRes_INT_EXTEND(N); break;
+ case ISD::FP_ROUND: Result = PromoteIntRes_FP_ROUND(N); break;
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT: Result = PromoteIntRes_FP_TO_XINT(N); break;
+ case ISD::SETCC: Result = PromoteIntRes_SETCC(N); break;
+ case ISD::LOAD: Result = PromoteIntRes_LOAD(cast<LoadSDNode>(N)); break;
+ case ISD::BUILD_PAIR: Result = PromoteIntRes_BUILD_PAIR(N); break;
+ case ISD::BIT_CONVERT: Result = PromoteIntRes_BIT_CONVERT(N); break;
+
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::ADD:
+ case ISD::SUB:
+ case ISD::MUL: Result = PromoteIntRes_SimpleIntBinOp(N); break;
+
+ case ISD::SDIV:
+ case ISD::SREM: Result = PromoteIntRes_SDIV(N); break;
+
+ case ISD::UDIV:
+ case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
+
+ case ISD::SHL: Result = PromoteIntRes_SHL(N); break;
+ case ISD::SRA: Result = PromoteIntRes_SRA(N); break;
+ case ISD::SRL: Result = PromoteIntRes_SRL(N); break;
+
+ case ISD::SELECT: Result = PromoteIntRes_SELECT(N); break;
+ case ISD::SELECT_CC: Result = PromoteIntRes_SELECT_CC(N); break;
+
+ case ISD::CTLZ: Result = PromoteIntRes_CTLZ(N); break;
+ case ISD::CTPOP: Result = PromoteIntRes_CTPOP(N); break;
+ case ISD::CTTZ: Result = PromoteIntRes_CTTZ(N); break;
+
+ case ISD::EXTRACT_VECTOR_ELT:
+ Result = PromoteIntRes_EXTRACT_VECTOR_ELT(N);
+ break;
+ }
+
+ // If Result is null, the sub-method took care of registering the result.
+ if (Result.Val)
+ SetPromotedInteger(SDOperand(N, ResNo), Result);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
+ return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
+ MVT VT = N->getValueType(0);
+ // Zero extend things like i1, sign extend everything else. It shouldn't
+ // matter in theory which one we pick, but this tends to give better code?
+ unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
+ SDOperand(N, 0));
+ assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
+ return Result;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
+ SDOperand Res;
+
+ switch (getTypeAction(N->getOperand(0).getValueType())) {
+ default: assert(0 && "Unknown type action!");
+ case Legal:
+ case ExpandInteger:
+ Res = N->getOperand(0);
+ break;
+ case PromoteInteger:
+ Res = GetPromotedInteger(N->getOperand(0));
+ break;
+ }
+
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ assert(Res.getValueType().getSizeInBits() >= NVT.getSizeInBits() &&
+ "Truncation doesn't make sense!");
+ if (Res.getValueType() == NVT)
+ return Res;
+
+ // Truncate to NVT instead of VT
+ return DAG.getNode(ISD::TRUNCATE, NVT, Res);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+ if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) {
+ SDOperand Res = GetPromotedInteger(N->getOperand(0));
+ assert(Res.getValueType().getSizeInBits() <= NVT.getSizeInBits() &&
+ "Extension doesn't make sense!");
+
+ // If the result and operand types are the same after promotion, simplify
+ // to an in-register extension.
+ if (NVT == Res.getValueType()) {
+ // The high bits are not guaranteed to be anything. Insert an extend.
+ if (N->getOpcode() == ISD::SIGN_EXTEND)
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+ DAG.getValueType(N->getOperand(0).getValueType()));
+ if (N->getOpcode() == ISD::ZERO_EXTEND)
+ return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
+ assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
+ return Res;
+ }
+ }
+
+ // Otherwise, just extend the original operand all the way to the larger type.
+ return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_FP_ROUND(SDNode *N) {
+ // NOTE: Assumes input is legal.
+ if (N->getConstantOperandVal(1) == 0)
+ return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
+ N->getOperand(0), DAG.getValueType(N->getValueType(0)));
+ // If the precision discard isn't needed, just return the operand unrounded.
+ return N->getOperand(0);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
+ unsigned NewOpc = N->getOpcode();
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+ // 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 (N->getOpcode() == ISD::FP_TO_UINT) {
+ if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
+ (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
+ TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom))
+ NewOpc = ISD::FP_TO_SINT;
+ }
+
+ return DAG.getNode(NewOpc, NVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
+ assert(isTypeLegal(TLI.getSetCCResultType(N->getOperand(0)))
+ && "SetCC type is not legal??");
+ return DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(N->getOperand(0)),
+ N->getOperand(0), N->getOperand(1), N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
+ // FIXME: Add support for indexed loads.
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ ISD::LoadExtType ExtType =
+ ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
+ SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
+ N->getSrcValue(), N->getSrcValueOffset(),
+ N->getMemoryVT(), N->isVolatile(),
+ N->getAlignment());
+
+ // Legalized the chain result - switch anything that used the old chain to
+ // use the new one.
+ ReplaceValueWith(SDOperand(N, 1), Res.getValue(1));
+ return Res;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
+ // The pair element type may be legal, or may not promote to the same type as
+ // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
+ return DAG.getNode(ISD::ANY_EXTEND,
+ TLI.getTypeToTransformTo(N->getValueType(0)),
+ JoinIntegers(N->getOperand(0), N->getOperand(1)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
+ SDOperand InOp = N->getOperand(0);
+ MVT InVT = InOp.getValueType();
+ MVT NInVT = TLI.getTypeToTransformTo(InVT);
+ MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+ switch (getTypeAction(InVT)) {
+ default:
+ assert(false && "Unknown type action!");
+ break;
+ case Legal:
+ break;
+ case PromoteInteger:
+ if (OutVT.getSizeInBits() == NInVT.getSizeInBits())
+ // The input promotes to the same size. Convert the promoted value.
+ return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedInteger(InOp));
+ break;
+ case PromoteFloat:
+ // Promote the integer operand by hand.
+ return DAG.getNode(ISD::ANY_EXTEND, OutVT, GetPromotedFloat(InOp));
+ case ExpandInteger:
+ case ExpandFloat:
+ break;
+ case Scalarize:
+ // Convert the element to an integer and promote it by hand.
+ return DAG.getNode(ISD::ANY_EXTEND, OutVT,
+ BitConvertToInteger(GetScalarizedVector(InOp)));
+ case Split:
+ // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split
+ // pieces of the input into integers and reassemble in the final type.
+ SDOperand Lo, Hi;
+ GetSplitVector(N->getOperand(0), Lo, Hi);
+ Lo = BitConvertToInteger(Lo);
+ Hi = BitConvertToInteger(Hi);
+
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+
+ InOp = DAG.getNode(ISD::ANY_EXTEND,
+ MVT::getIntegerVT(OutVT.getSizeInBits()),
+ JoinIntegers(Lo, Hi));
+ return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
+ }
+
+ // Otherwise, lower the bit-convert to a store/load from the stack, then
+ // promote the load.
+ SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
+ return PromoteIntRes_LOAD(cast<LoadSDNode>(Op.Val));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
+ // 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.
+ SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+ SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
+ // Sign extend the input.
+ SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+ SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+ MVT VT = N->getValueType(0);
+ LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS,
+ DAG.getValueType(VT));
+ RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS,
+ DAG.getValueType(VT));
+
+ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
+ // Zero extend the input.
+ SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+ SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+ MVT VT = N->getValueType(0);
+ LHS = DAG.getZeroExtendInReg(LHS, VT);
+ RHS = DAG.getZeroExtendInReg(RHS, VT);
+
+ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
+ return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)),
+ GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
+ // The input value must be properly sign extended.
+ MVT VT = N->getValueType(0);
+ MVT NVT = TLI.getTypeToTransformTo(VT);
+ SDOperand Res = GetPromotedInteger(N->getOperand(0));
+ Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT));
+ return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
+ // The input value must be properly zero extended.
+ MVT VT = N->getValueType(0);
+ MVT NVT = TLI.getTypeToTransformTo(VT);
+ SDOperand Res = ZExtPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
+ SDOperand LHS = GetPromotedInteger(N->getOperand(1));
+ SDOperand RHS = GetPromotedInteger(N->getOperand(2));
+ return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
+ SDOperand LHS = GetPromotedInteger(N->getOperand(2));
+ SDOperand RHS = GetPromotedInteger(N->getOperand(3));
+ return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+ N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ MVT OVT = N->getValueType(0);
+ MVT NVT = Op.getValueType();
+ // Zero extend to the promoted type and do the count there.
+ Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT));
+ // Subtract off the extra leading bits in the bigger type.
+ return DAG.getNode(ISD::SUB, NVT, Op,
+ DAG.getConstant(NVT.getSizeInBits() -
+ OVT.getSizeInBits(), NVT));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ MVT OVT = N->getValueType(0);
+ MVT NVT = Op.getValueType();
+ // Zero extend to the promoted type and do the count there.
+ return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ MVT OVT = N->getValueType(0);
+ MVT NVT = Op.getValueType();
+ // The count is the same in the promoted type except if the original
+ // value was zero. This can be handled by setting the bit just off
+ // the top of the original type.
+ Op = DAG.getNode(ISD::OR, NVT, Op,
+ // FIXME: Do this using an APINT constant.
+ DAG.getConstant(1UL << OVT.getSizeInBits(), NVT));
+ return DAG.getNode(ISD::CTTZ, NVT, Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
+ MVT OldVT = N->getValueType(0);
+ SDOperand OldVec = N->getOperand(0);
+ unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+
+ if (OldElts == 1) {
+ assert(!isTypeLegal(OldVec.getValueType()) &&
+ "Legal one-element vector of a type needing promotion!");
+ // It is tempting to follow GetScalarizedVector by a call to
+ // GetPromotedInteger, but this would be wrong because the
+ // scalarized value may not yet have been processed.
+ return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT),
+ GetScalarizedVector(OldVec));
+ }
+
+ // Convert to a vector half as long with an element type of twice the width,
+ // for example <4 x i16> -> <2 x i32>.
+ assert(!(OldElts & 1) && "Odd length vectors not supported!");
+ MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
+ assert(OldVT.isSimple() && NewVT.isSimple());
+
+ SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
+ MVT::getVectorVT(NewVT, OldElts / 2),
+ OldVec);
+
+ // Extract the element at OldIdx / 2 from the new vector.
+ SDOperand OldIdx = N->getOperand(1);
+ SDOperand NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx,
+ DAG.getConstant(1, TLI.getShiftAmountTy()));
+ SDOperand Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx);
+
+ // Select the appropriate half of the element: Lo if OldIdx was even,
+ // Hi if it was odd.
+ SDOperand Lo = Elt;
+ SDOperand Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
+ DAG.getConstant(OldVT.getSizeInBits(),
+ TLI.getShiftAmountTy()));
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+
+ SDOperand Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(), OldIdx,
+ DAG.getConstant(1, TLI.getShiftAmountTy()));
+ return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+}
+
+//===----------------------------------------------------------------------===//
+// Integer Operand Promotion
+//===----------------------------------------------------------------------===//
+
+/// PromoteIntegerOperand - This method is called when the specified operand of
+/// the specified node is found to need promotion. At this point, all of the
+/// result types of the node are known to be legal, but other operands of the
+/// node may need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n");
+ SDOperand Res;
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "PromoteIntegerOperand Op #" << OpNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to promote this operator's operand!");
+ abort();
+
+ case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
+ case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
+ case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
+ case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
+ case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break;
+ case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break;
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break;
+ case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
+
+ case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
+ case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
+ case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
+ case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
+
+ case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
+ OpNo); break;
+
+ case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
+ case ISD::INSERT_VECTOR_ELT:
+ Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);
+ break;
+
+ case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break;
+ }
+
+ // If the result is null, the sub-method took care of registering results etc.
+ if (!Res.Val) return false;
+ // If the result is N, the sub-method updated N in place.
+ if (Res.Val == N) {
+ // Mark N as new and remark N and its operands. This allows us to correctly
+ // revisit N if it needs another step of promotion and allows us to visit
+ // any new operands to N.
+ ReanalyzeNode(N);
+ return true;
+ }
+
+ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+ "Invalid operand expansion");
+
+ ReplaceValueWith(SDOperand(N, 0), Res);
+ return false;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
+ Op, DAG.getValueType(N->getOperand(0).getValueType()));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_FP_EXTEND(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_FP_ROUND(SDNode *N) {
+ SDOperand Op = GetPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
+ DAG.getIntPtrConstant(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) {
+ SDOperand In = GetPromotedInteger(N->getOperand(0));
+ MVT OpVT = N->getOperand(0).getValueType();
+ if (N->getOpcode() == ISD::UINT_TO_FP)
+ In = DAG.getZeroExtendInReg(In, OpVT);
+ else
+ In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(),
+ In, DAG.getValueType(OpVT));
+
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
+ // Since the result type is legal, the operands must promote to it.
+ MVT OVT = N->getOperand(0).getValueType();
+ SDOperand Lo = GetPromotedInteger(N->getOperand(0));
+ SDOperand Hi = GetPromotedInteger(N->getOperand(1));
+ assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
+
+ Lo = DAG.getZeroExtendInReg(Lo, OVT);
+ Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
+ DAG.getConstant(OVT.getSizeInBits(),
+ TLI.getShiftAmountTy()));
+ return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 0 && "Only know how to promote condition");
+ SDOperand Cond = GetPromotedInteger(N->getOperand(0)); // Promote condition.
+
+ // The top bits of the promoted condition are not necessarily zero, ensure
+ // that the value is properly zero extended.
+ unsigned BitWidth = Cond.getValueSizeInBits();
+ if (!DAG.MaskedValueIsZero(Cond,
+ APInt::getHighBitsSet(BitWidth, BitWidth-1)))
+ Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+
+ // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
+ N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 1 && "only know how to promote condition");
+ SDOperand Cond = GetPromotedInteger(N->getOperand(1)); // Promote condition.
+
+ // The top bits of the promoted condition are not necessarily zero, ensure
+ // that the value is properly zero extended.
+ unsigned BitWidth = Cond.getValueSizeInBits();
+ if (!DAG.MaskedValueIsZero(Cond,
+ APInt::getHighBitsSet(BitWidth, BitWidth-1)))
+ Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+
+ // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
+ N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 2 && "Don't know how to promote this operand");
+
+ SDOperand LHS = N->getOperand(2);
+ SDOperand RHS = N->getOperand(3);
+ PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
+
+ // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
+ // legal types.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+ N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
+ assert(OpNo == 0 && "Don't know how to promote this operand");
+
+ SDOperand LHS = N->getOperand(0);
+ SDOperand RHS = N->getOperand(1);
+ PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
+
+ // The CC (#2) is always legal.
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2));
+}
+
+/// PromoteSetCCOperands - Promote the operands of a comparison. This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
+ ISD::CondCode CCCode) {
+ MVT VT = NewLHS.getValueType();
+
+ // Get the promoted values.
+ NewLHS = GetPromotedInteger(NewLHS);
+ NewRHS = GetPromotedInteger(NewRHS);
+
+ // If this is an FP compare, the operands have already been extended.
+ if (!NewLHS.getValueType().isInteger())
+ return;
+
+ // Otherwise, we have to insert explicit sign or zero extends. Note
+ // that we could insert sign extends for ALL conditions, but zero extend
+ // is cheaper on many machines (an AND instead of two shifts), so prefer
+ // it.
+ switch (CCCode) {
+ default: assert(0 && "Unknown integer comparison!");
+ case ISD::SETEQ:
+ case ISD::SETNE:
+ case ISD::SETUGE:
+ case ISD::SETUGT:
+ case ISD::SETULE:
+ case ISD::SETULT:
+ // ALL of these operations will work if we either sign or zero extend
+ // the operands (including the unsigned comparisons!). Zero extend is
+ // usually a simpler/cheaper operation, so prefer it.
+ NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
+ NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
+ return;
+ case ISD::SETGE:
+ case ISD::SETGT:
+ case ISD::SETLT:
+ case ISD::SETLE:
+ NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
+ DAG.getValueType(VT));
+ NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
+ DAG.getValueType(VT));
+ return;
+ }
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
+ // FIXME: Add support for indexed stores.
+ SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
+ int SVOffset = N->getSrcValueOffset();
+ unsigned Alignment = N->getAlignment();
+ bool isVolatile = N->isVolatile();
+
+ SDOperand Val = GetPromotedInteger(N->getValue()); // Get promoted value.
+
+ assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
+
+ // Truncate the value and store the result.
+ return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
+ SVOffset, N->getMemoryVT(),
+ isVolatile, Alignment);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
+ // The vector type is legal but the element type is not. This implies
+ // that the vector is a power-of-two in length and that the element
+ // type does not have a strange size (eg: it is not i1).
+ MVT VecVT = N->getValueType(0);
+ unsigned NumElts = VecVT.getVectorNumElements();
+ assert(!(NumElts & 1) && "Legal vector of one illegal element?");
+
+ // Build a vector of half the length out of elements of twice the bitwidth.
+ // For example <4 x i16> -> <2 x i32>.
+ MVT OldVT = N->getOperand(0).getValueType();
+ MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
+ assert(OldVT.isSimple() && NewVT.isSimple());
+
+ std::vector<SDOperand> NewElts;
+ NewElts.reserve(NumElts/2);
+
+ for (unsigned i = 0; i < NumElts; i += 2) {
+ // Combine two successive elements into one promoted element.
+ SDOperand Lo = N->getOperand(i);
+ SDOperand Hi = N->getOperand(i+1);
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+ NewElts.push_back(JoinIntegers(Lo, Hi));
+ }
+
+ SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+ MVT::getVectorVT(NewVT, NewElts.size()),
+ &NewElts[0], NewElts.size());
+
+ // Convert the new vector to the old vector type.
+ return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
+ unsigned OpNo) {
+ if (OpNo == 1) {
+ // Promote the inserted value. This is valid because the type does not
+ // have to match the vector element type.
+
+ // Check that any extra bits introduced will be truncated away.
+ assert(N->getOperand(1).getValueType().getSizeInBits() >=
+ N->getValueType(0).getVectorElementType().getSizeInBits() &&
+ "Type of inserted value narrower than vector element type!");
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+ GetPromotedInteger(N->getOperand(1)),
+ N->getOperand(2));
+ }
+
+ assert(OpNo == 2 && "Different operand and result vector types?");
+
+ // Promote the index.
+ SDOperand Idx = N->getOperand(2);
+ Idx = DAG.getZeroExtendInReg(GetPromotedInteger(Idx), Idx.getValueType());
+ return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+ N->getOperand(1), Idx);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
+ SDOperand NewOps[6];
+ NewOps[0] = N->getOperand(0);
+ for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
+ SDOperand Flag = GetPromotedInteger(N->getOperand(i));
+ NewOps[i] = DAG.getZeroExtendInReg(Flag, MVT::i1);
+ }
+ return DAG.UpdateNodeOperands(SDOperand (N, 0), NewOps,
+ array_lengthof(NewOps));
+}
+
+
+//===----------------------------------------------------------------------===//
+// Integer Result Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandIntegerResult - This method is called when the specified result of the
/// specified node is found to need expansion. At this point, the node may also
/// have invalid operands or may have other results that need promotion, we just
/// know that (at least) one result needs expansion.
-void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) {
- DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n");
+void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Expand integer result: "; N->dump(&DAG); cerr << "\n");
SDOperand Lo, Hi;
Lo = Hi = SDOperand();
// See if the target wants to custom expand this node.
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
TargetLowering::Custom) {
// If the target wants to, allow it to lower this itself.
if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
@@ -47,69 +750,69 @@ void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) {
switch (N->getOpcode()) {
default:
#ifndef NDEBUG
- cerr << "ExpandResult #" << ResNo << ": ";
+ cerr << "ExpandIntegerResult #" << ResNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0 && "Do not know how to expand the result of this operator!");
+ assert(0&&"Do not know how to expand the result of this operator!");
abort();
-
- case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break;
- case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break;
- case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break;
- case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break;
- case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break;
- case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break;
- case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break;
- case ISD::AssertZext: ExpandResult_AssertZext(N, Lo, Hi); break;
- case ISD::TRUNCATE: ExpandResult_TRUNCATE(N, Lo, Hi); break;
- case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break;
- case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break;
- case ISD::FP_TO_SINT: ExpandResult_FP_TO_SINT(N, Lo, Hi); break;
- case ISD::FP_TO_UINT: ExpandResult_FP_TO_UINT(N, Lo, Hi); break;
- case ISD::LOAD: ExpandResult_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
-
+
+ case ISD::UNDEF: ExpandIntRes_UNDEF(N, Lo, Hi); break;
+ case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break;
+ case ISD::BUILD_PAIR: ExpandIntRes_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::MERGE_VALUES: ExpandIntRes_MERGE_VALUES(N, Lo, Hi); break;
+ case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
+ case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
+ case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
+ case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break;
+ case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
+ case ISD::BIT_CONVERT: ExpandIntRes_BIT_CONVERT(N, Lo, Hi); break;
+ case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
+ case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
+ case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
+ case ISD::LOAD: ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+
case ISD::AND:
case ISD::OR:
- case ISD::XOR: ExpandResult_Logical(N, Lo, Hi); break;
- case ISD::BSWAP: ExpandResult_BSWAP(N, Lo, Hi); break;
+ case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
+ case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break;
case ISD::ADD:
- case ISD::SUB: ExpandResult_ADDSUB(N, Lo, Hi); break;
+ case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
case ISD::ADDC:
- case ISD::SUBC: ExpandResult_ADDSUBC(N, Lo, Hi); break;
+ case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
case ISD::ADDE:
- case ISD::SUBE: ExpandResult_ADDSUBE(N, Lo, Hi); break;
- case ISD::SELECT: ExpandResult_SELECT(N, Lo, Hi); break;
- case ISD::SELECT_CC: ExpandResult_SELECT_CC(N, Lo, Hi); break;
- case ISD::MUL: ExpandResult_MUL(N, Lo, Hi); break;
- case ISD::SDIV: ExpandResult_SDIV(N, Lo, Hi); break;
- case ISD::SREM: ExpandResult_SREM(N, Lo, Hi); break;
- case ISD::UDIV: ExpandResult_UDIV(N, Lo, Hi); break;
- case ISD::UREM: ExpandResult_UREM(N, Lo, Hi); break;
+ case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
+ case ISD::SELECT: ExpandIntRes_SELECT(N, Lo, Hi); break;
+ case ISD::SELECT_CC: ExpandIntRes_SELECT_CC(N, Lo, Hi); break;
+ case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break;
+ case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break;
+ case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break;
+ case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break;
+ case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break;
case ISD::SHL:
case ISD::SRA:
- case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break;
+ case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
- case ISD::CTLZ: ExpandResult_CTLZ(N, Lo, Hi); break;
- case ISD::CTPOP: ExpandResult_CTPOP(N, Lo, Hi); break;
- case ISD::CTTZ: ExpandResult_CTTZ(N, Lo, Hi); break;
+ case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break;
+ case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break;
+ case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break;
case ISD::EXTRACT_VECTOR_ELT:
- ExpandResult_EXTRACT_VECTOR_ELT(N, Lo, Hi);
+ ExpandIntRes_EXTRACT_VECTOR_ELT(N, Lo, Hi);
break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
if (Lo.Val)
- SetExpandedOp(SDOperand(N, ResNo), Lo, Hi);
+ SetExpandedInteger(SDOperand(N, ResNo), Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_UNDEF(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
}
-void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
unsigned NBitWidth = NVT.getSizeInBits();
@@ -118,26 +821,26 @@ void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N,
Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
}
-void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_BUILD_PAIR(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Return the operands.
Lo = N->getOperand(0);
Hi = N->getOperand(1);
}
-void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// A MERGE_VALUES node can produce any number of values. We know that the
// first illegal one needs to be expanded into Lo/Hi.
unsigned i;
-
+
// The string of legal results gets turns into the input operands, which have
// the same type.
for (i = 0; isTypeLegal(N->getValueType(i)); ++i)
ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
// The first illegal result must be the one that needs to be expanded.
- GetExpandedOp(N->getOperand(i), Lo, Hi);
+ GetExpandedInteger(N->getOperand(i), Lo, Hi);
// Legalize the rest of the results into the input operands whether they are
// legal or not.
@@ -146,7 +849,7 @@ void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N,
ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
}
-void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDOperand Op = N->getOperand(0);
@@ -157,9 +860,9 @@ void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
// promotes to the result type, so will end up being expanded too.
- assert(getTypeAction(Op.getValueType()) == Promote &&
+ assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
"Only know how to promote this result!");
- SDOperand Res = GetPromotedOp(Op);
+ SDOperand Res = GetPromotedInteger(Op);
assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded.
@@ -167,7 +870,7 @@ void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
}
}
-void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDOperand Op = N->getOperand(0);
@@ -178,9 +881,9 @@ void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
// promotes to the result type, so will end up being expanded too.
- assert(getTypeAction(Op.getValueType()) == Promote &&
+ assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
"Only know how to promote this result!");
- SDOperand Res = GetPromotedOp(Op);
+ SDOperand Res = GetPromotedInteger(Op);
assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded.
@@ -191,7 +894,7 @@ void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
}
}
-void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDOperand Op = N->getOperand(0);
@@ -205,9 +908,9 @@ void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
} else {
// For example, extension of an i48 to an i64. The operand type necessarily
// promotes to the result type, so will end up being expanded too.
- assert(getTypeAction(Op.getValueType()) == Promote &&
+ assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
"Only know how to promote this result!");
- SDOperand Res = GetPromotedOp(Op);
+ SDOperand Res = GetPromotedInteger(Op);
assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded.
@@ -219,9 +922,9 @@ void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
}
}
-void DAGTypeLegalizer::ExpandResult_AssertZext(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
unsigned NVTBits = NVT.getSizeInBits();
@@ -237,7 +940,7 @@ void DAGTypeLegalizer::ExpandResult_AssertZext(SDNode *N,
}
}
-void DAGTypeLegalizer::ExpandResult_TRUNCATE(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0));
@@ -247,7 +950,7 @@ void DAGTypeLegalizer::ExpandResult_TRUNCATE(SDNode *N,
Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
}
-void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_BIT_CONVERT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDOperand InOp = N->getOperand(0);
@@ -258,23 +961,29 @@ void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
default:
assert(false && "Unknown type action!");
case Legal:
- case Promote:
+ case PromoteInteger:
break;
- case Expand:
+ case PromoteFloat:
+ // Convert the integer operand instead.
+ SplitInteger(GetPromotedFloat(InOp), Lo, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+ return;
+ case ExpandInteger:
// Convert the expanded pieces of the input.
- GetExpandedOp(InOp, Lo, Hi);
+ GetExpandedInteger(InOp, Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
return;
- case FloatToInt:
- // Convert the integer operand instead.
- SplitInteger(GetIntegerOp(InOp), Lo, Hi);
+ case ExpandFloat:
+ // Convert the expanded pieces of the input.
+ GetExpandedFloat(InOp, Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
return;
case Split:
// Convert the split parts of the input if it was split in two.
- GetSplitOp(InOp, Lo, Hi);
+ GetSplitVector(InOp, Lo, Hi);
if (Lo.getValueType() == Hi.getValueType()) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
@@ -285,7 +994,7 @@ void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
break;
case Scalarize:
// Convert the element instead.
- SplitInteger(BitConvertToInteger(GetScalarizedOp(InOp)), Lo, Hi);
+ SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
return;
@@ -293,12 +1002,12 @@ void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
// Lower the bit-convert to a store/load from the stack, then expand the load.
SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
- ExpandResult_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
+ ExpandIntRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
}
void DAGTypeLegalizer::
-ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
if (EVT.bitsLE(Lo.getValueType())) {
@@ -321,7 +1030,7 @@ ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
}
}
-void DAGTypeLegalizer::ExpandResult_FP_TO_SINT(SDNode *N, SDOperand &Lo,
+void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
MVT VT = N->getValueType(0);
SDOperand Op = N->getOperand(0);
@@ -350,7 +1059,7 @@ void DAGTypeLegalizer::ExpandResult_FP_TO_SINT(SDNode *N, SDOperand &Lo,
SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_FP_TO_UINT(SDNode *N, SDOperand &Lo,
+void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
MVT VT = N->getValueType(0);
SDOperand Op = N->getOperand(0);
@@ -379,7 +1088,7 @@ void DAGTypeLegalizer::ExpandResult_FP_TO_UINT(SDNode *N, SDOperand &Lo,
SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// FIXME: Add support for indexed loads.
MVT VT = N->getValueType(0);
@@ -500,48 +1209,48 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
ReplaceValueWith(SDOperand(N, 1), Ch);
}
-void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
SDOperand LL, LH, RL, RH;
- GetExpandedOp(N->getOperand(0), LL, LH);
- GetExpandedOp(N->getOperand(1), RL, RH);
+ GetExpandedInteger(N->getOperand(0), LL, LH);
+ GetExpandedInteger(N->getOperand(1), RL, RH);
Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL);
Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH);
}
-void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- GetExpandedOp(N->getOperand(0), Hi, Lo); // Note swapped operands.
+ GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands.
Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo);
Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
}
-void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_SELECT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
SDOperand LL, LH, RL, RH;
- GetExpandedOp(N->getOperand(1), LL, LH);
- GetExpandedOp(N->getOperand(2), RL, RH);
+ GetExpandedInteger(N->getOperand(1), LL, LH);
+ GetExpandedInteger(N->getOperand(2), RL, RH);
Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL);
Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH);
}
-void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_SELECT_CC(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
SDOperand LL, LH, RL, RH;
- GetExpandedOp(N->getOperand(2), LL, LH);
- GetExpandedOp(N->getOperand(3), RL, RH);
- Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ GetExpandedInteger(N->getOperand(2), LL, LH);
+ GetExpandedInteger(N->getOperand(3), RL, RH);
+ Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
N->getOperand(1), LL, RL, N->getOperand(4));
- Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
N->getOperand(1), LH, RH, N->getOperand(4));
}
-void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Expand the subcomponents.
SDOperand LHSL, LHSH, RHSL, RHSH;
- GetExpandedOp(N->getOperand(0), LHSL, LHSH);
- GetExpandedOp(N->getOperand(1), RHSL, RHSH);
+ GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+ GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDOperand LoOps[2] = { LHSL, RHSL };
SDOperand HiOps[3] = { LHSH, RHSH };
@@ -557,12 +1266,12 @@ void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N,
}
}
-void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Expand the subcomponents.
SDOperand LHSL, LHSH, RHSL, RHSH;
- GetExpandedOp(N->getOperand(0), LHSL, LHSH);
- GetExpandedOp(N->getOperand(1), RHSL, RHSH);
+ GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+ GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDOperand LoOps[2] = { LHSL, RHSL };
SDOperand HiOps[3] = { LHSH, RHSH };
@@ -582,12 +1291,12 @@ void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N,
ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
}
-void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Expand the subcomponents.
SDOperand LHSL, LHSH, RHSL, RHSH;
- GetExpandedOp(N->getOperand(0), LHSL, LHSH);
- GetExpandedOp(N->getOperand(1), RHSL, RHSH);
+ GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+ GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
SDOperand HiOps[3] = { LHSH, RHSH };
@@ -601,24 +1310,24 @@ void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N,
ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
}
-void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
-
+
bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
SDOperand LL, LH, RL, RH;
- GetExpandedOp(N->getOperand(0), LL, LH);
- GetExpandedOp(N->getOperand(1), RL, RH);
+ GetExpandedInteger(N->getOperand(0), LL, LH);
+ GetExpandedInteger(N->getOperand(1), RL, RH);
unsigned OuterBitSize = VT.getSizeInBits();
unsigned BitSize = NVT.getSizeInBits();
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
-
+
if (DAG.MaskedValueIsZero(N->getOperand(0),
APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
DAG.MaskedValueIsZero(N->getOperand(1),
@@ -672,7 +1381,7 @@ void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_SDIV(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
assert(N->getValueType(0) == MVT::i64 && "Unsupported sdiv!");
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
@@ -680,7 +1389,7 @@ void DAGTypeLegalizer::ExpandResult_SDIV(SDNode *N,
Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_SREM(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
assert(N->getValueType(0) == MVT::i64 && "Unsupported srem!");
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
@@ -688,7 +1397,7 @@ void DAGTypeLegalizer::ExpandResult_SREM(SDNode *N,
Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_UDIV(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
assert(N->getValueType(0) == MVT::i64 && "Unsupported udiv!");
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
@@ -696,7 +1405,7 @@ void DAGTypeLegalizer::ExpandResult_UDIV(SDNode *N,
Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_UREM(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
assert(N->getValueType(0) == MVT::i64 && "Unsupported urem!");
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
@@ -704,11 +1413,11 @@ void DAGTypeLegalizer::ExpandResult_UREM(SDNode *N,
Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT VT = N->getValueType(0);
-
- // If we can emit an efficient shift operation, do so now. Check to see if
+
+ // If we can emit an efficient shift operation, do so now. Check to see if
// the RHS is a constant.
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi);
@@ -717,7 +1426,7 @@ void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
// the low bits are variable, emit this shift in an optimized form.
if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
return;
-
+
// If this target supports shift_PARTS, use it. First, map to the _PARTS opc.
unsigned PartsOpc;
if (N->getOpcode() == ISD::SHL) {
@@ -728,7 +1437,7 @@ void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
PartsOpc = ISD::SRA_PARTS;
}
-
+
// Next check to see if the target supports this SHL_PARTS operation or if it
// will custom expand it.
MVT NVT = TLI.getTypeToTransformTo(VT);
@@ -737,8 +1446,8 @@ void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
Action == TargetLowering::Custom) {
// Expand the subcomponents.
SDOperand LHSL, LHSH;
- GetExpandedOp(N->getOperand(0), LHSL, LHSH);
-
+ GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+
SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) };
MVT VT = LHSL.getValueType();
Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
@@ -767,10 +1476,10 @@ void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi);
}
-void DAGTypeLegalizer::ExpandResult_CTLZ(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
SDOperand HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
@@ -785,20 +1494,20 @@ void DAGTypeLegalizer::ExpandResult_CTLZ(SDNode *N,
Hi = DAG.getConstant(0, NVT);
}
-void DAGTypeLegalizer::ExpandResult_CTPOP(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
DAG.getNode(ISD::CTPOP, NVT, Hi));
Hi = DAG.getConstant(0, NVT);
}
-void DAGTypeLegalizer::ExpandResult_CTTZ(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
MVT NVT = Lo.getValueType();
SDOperand LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo,
@@ -813,7 +1522,7 @@ void DAGTypeLegalizer::ExpandResult_CTTZ(SDNode *N,
Hi = DAG.getConstant(0, NVT);
}
-void DAGTypeLegalizer::ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N,
+void DAGTypeLegalizer::ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N,
SDOperand &Lo,
SDOperand &Hi) {
SDOperand OldVec = N->getOperand(0);
@@ -850,12 +1559,12 @@ void DAGTypeLegalizer::ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N,
/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
/// and the shift amount is a constant 'Amt'. Expand the operation.
-void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
+void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
SDOperand &Lo, SDOperand &Hi) {
// Expand the incoming operand to be shifted, so that we have its parts
SDOperand InL, InH;
- GetExpandedOp(N->getOperand(0), InL, InH);
-
+ GetExpandedInteger(N->getOperand(0), InL, InH);
+
MVT NVT = InL.getValueType();
unsigned VTBits = N->getValueType(0).getSizeInBits();
unsigned NVTBits = NVT.getSizeInBits();
@@ -880,7 +1589,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
}
return;
}
-
+
if (N->getOpcode() == ISD::SRL) {
if (Amt > VTBits) {
Lo = DAG.getConstant(0, NVT);
@@ -901,7 +1610,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
}
return;
}
-
+
assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
if (Amt > VTBits) {
Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
@@ -942,14 +1651,14 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
APInt KnownZero, KnownOne;
DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
-
+
// If we don't know anything about the high bits, exit.
if (((KnownZero|KnownOne) & HighBitMask) == 0)
return false;
// Get the incoming operand to be shifted.
SDOperand InL, InH;
- GetExpandedOp(N->getOperand(0), InL, InH);
+ GetExpandedInteger(N->getOperand(0), InL, InH);
// If we know that any of the high bits of the shift amount are one, then we
// can do this as a couple of simple shifts.
@@ -957,7 +1666,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
// Mask out the high bit, which we know is set.
Amt = DAG.getNode(ISD::AND, ShTy, Amt,
DAG.getConstant(~HighBitMask, ShTy));
-
+
switch (N->getOpcode()) {
default: assert(0 && "Unknown shift");
case ISD::SHL:
@@ -975,7 +1684,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
return true;
}
}
-
+
// If we know that all of the high bits of the shift amount are zero, then we
// can do this as a couple of simple shifts.
if ((KnownZero & HighBitMask) == HighBitMask) {
@@ -990,7 +1699,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
case ISD::SRL:
case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break;
}
-
+
Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
Hi = DAG.getNode(ISD::OR, NVT,
DAG.getNode(Op1, NVT, InH, Amt),
@@ -1003,60 +1712,60 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
//===----------------------------------------------------------------------===//
-// Operand Expansion
+// Integer Operand Expansion
//===----------------------------------------------------------------------===//
-/// ExpandOperand - This method is called when the specified operand of the
-/// specified node is found to need expansion. At this point, all of the result
-/// types of the node are known to be legal, but other operands of the node may
-/// need promotion or expansion as well as the specified one.
-bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) {
- DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n");
+/// ExpandIntegerOperand - This method is called when the specified operand of
+/// the specified node is found to need expansion. At this point, all of the
+/// result types of the node are known to be legal, but other operands of the
+/// node may need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n");
SDOperand Res(0, 0);
-
+
if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
== TargetLowering::Custom)
Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-
+
if (Res.Val == 0) {
switch (N->getOpcode()) {
default:
#ifndef NDEBUG
- cerr << "ExpandOperand Op #" << OpNo << ": ";
+ cerr << "ExpandIntegerOperand Op #" << OpNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
assert(0 && "Do not know how to expand this operator's operand!");
abort();
-
- case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break;
- case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break;
+
+ case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
+ case ISD::BIT_CONVERT: Res = ExpandIntOp_BIT_CONVERT(N); break;
case ISD::SINT_TO_FP:
- Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
+ Res = ExpandIntOp_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
break;
case ISD::UINT_TO_FP:
- Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
+ Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
break;
- case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break;
+ case ISD::EXTRACT_ELEMENT: Res = ExpandIntOp_EXTRACT_ELEMENT(N); break;
- case ISD::BR_CC: Res = ExpandOperand_BR_CC(N); break;
- case ISD::SETCC: Res = ExpandOperand_SETCC(N); break;
+ case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
+ case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
case ISD::STORE:
- Res = ExpandOperand_STORE(cast<StoreSDNode>(N), OpNo);
+ Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
break;
- case ISD::BUILD_VECTOR: Res = ExpandOperand_BUILD_VECTOR(N); break;
+ case ISD::BUILD_VECTOR: Res = ExpandIntOp_BUILD_VECTOR(N); break;
}
}
-
+
// If the result is null, the sub-method took care of registering results etc.
if (!Res.Val) return false;
// If the result is N, the sub-method updated N in place. Check to see if any
// operands are new, and if so, mark them.
if (Res.Val == N) {
// Mark N as new and remark N and its operands. This allows us to correctly
- // revisit N if it needs another step of promotion and allows us to visit
+ // revisit N if it needs another step of expansion and allows us to visit
// any new operands to N.
ReanalyzeNode(N);
return true;
@@ -1064,19 +1773,19 @@ bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) {
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
-
+
ReplaceValueWith(SDOperand(N, 0), Res);
return false;
}
-SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
SDOperand InL, InH;
- GetExpandedOp(N->getOperand(0), InL, InH);
+ GetExpandedInteger(N->getOperand(0), InL, InH);
// Just truncate the low part of the source.
return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
}
-SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_BIT_CONVERT(SDNode *N) {
if (N->getValueType(0).isVector()) {
// An illegal integer type is being converted to a legal vector type.
// Make a two element vector out of the expanded parts and convert that
@@ -1088,7 +1797,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) {
if (isTypeLegal(NVT)) {
SDOperand Parts[2];
- GetExpandedOp(N->getOperand(0), Parts[0], Parts[1]);
+ GetExpandedInteger(N->getOperand(0), Parts[0], Parts[1]);
if (TLI.isBigEndian())
std::swap(Parts[0], Parts[1]);
@@ -1102,11 +1811,11 @@ SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) {
return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
}
-SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source,
+SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDOperand Source,
MVT DestTy) {
// We know the destination is legal, but that the input needs to be expanded.
MVT SourceVT = Source.getValueType();
-
+
// Check to see if the target has a custom way to lower this. If so, use it.
switch (TLI.getOperationAction(ISD::SINT_TO_FP, SourceVT)) {
default: assert(0 && "This action not implemented for this operation!");
@@ -1119,7 +1828,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source,
if (NV.Val) return NV;
break; // The target lowered this.
}
-
+
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (SourceVT == MVT::i64) {
if (DestTy == MVT::f32)
@@ -1148,22 +1857,22 @@ SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source,
return MakeLibCall(LC, DestTy, &Source, 1, true);
}
-SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source,
+SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source,
MVT DestTy) {
// We know the destination is legal, but that the input needs to be expanded.
- assert(getTypeAction(Source.getValueType()) == Expand &&
+ assert(getTypeAction(Source.getValueType()) == ExpandInteger &&
"This is not an expansion!");
-
+
// If this is unsigned, and not supported, first perform the conversion to
// signed, then adjust the result if the sign bit is set.
- SDOperand SignedConv = ExpandOperand_SINT_TO_FP(Source, DestTy);
+ SDOperand SignedConv = ExpandIntOp_SINT_TO_FP(Source, DestTy);
// The 64-bit value loaded will be incorrectly if the 'sign bit' of the
// incoming integer is set. To handle this, we dynamically test to see if
// it is set, and, if so, add a fudge factor.
SDOperand Lo, Hi;
- GetExpandedOp(Source, Lo, Hi);
-
+ GetExpandedInteger(Source, Lo, Hi);
+
SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
DAG.getConstant(0, Hi.getValueType()),
ISD::SETLT);
@@ -1173,7 +1882,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source,
uint64_t FF = 0x5f800000ULL;
if (TLI.isLittleEndian()) FF <<= 32;
Constant *FudgeFactor = ConstantInt::get((Type*)Type::Int64Ty, FF);
-
+
SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
SDOperand FudgeInReg;
@@ -1183,19 +1892,19 @@ SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source,
// FIXME: Avoid the extend by construction the right constantpool?
FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(),
CPIdx, NULL, 0, MVT::f32);
- else
+ else
assert(0 && "Unexpected conversion");
-
+
return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
}
-SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_EXTRACT_ELEMENT(SDNode *N) {
SDOperand Lo, Hi;
- GetExpandedOp(N->getOperand(0), Lo, Hi);
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
}
-SDOperand DAGTypeLegalizer::ExpandOperand_BR_CC(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
@@ -1213,11 +1922,11 @@ SDOperand DAGTypeLegalizer::ExpandOperand_BR_CC(SDNode *N) {
N->getOperand(4));
}
-SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-
+
// If ExpandSetCCOperands returned a scalar, use it.
if (NewRHS.Val == 0) return NewLHS;
@@ -1231,8 +1940,8 @@ SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) {
void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
ISD::CondCode &CCCode) {
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
- GetExpandedOp(NewLHS, LHSLo, LHSHi);
- GetExpandedOp(NewRHS, RHSLo, RHSHi);
+ GetExpandedInteger(NewLHS, LHSLo, LHSHi);
+ GetExpandedInteger(NewRHS, RHSLo, RHSHi);
MVT VT = NewLHS.getValueType();
if (VT == MVT::ppcf128) {
@@ -1262,14 +1971,14 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
NewRHS = RHSLo;
return;
}
-
+
NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS);
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
return;
}
-
+
// If this is a comparison of the sign bit, just look at the top part.
// X > -1, x < 0
if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
@@ -1279,7 +1988,7 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
NewRHS = RHSHi;
return;
}
-
+
// FIXME: This generated code sucks.
ISD::CondCode LowCC;
switch (CCCode) {
@@ -1293,11 +2002,11 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
case ISD::SETGE:
case ISD::SETUGE: LowCC = ISD::SETUGE; break;
}
-
+
// Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison
// Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands
// dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
-
+
// NOTE: on targets without efficient SELECT of bools, we can always use
// this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
@@ -1311,7 +2020,7 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
if (!Tmp2.Val)
Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
DAG.getCondCode(CCCode));
-
+
ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.Val);
ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.Val);
if ((Tmp1C && Tmp1C->isNullValue()) ||
@@ -1328,7 +2037,7 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
NewRHS = SDOperand();
return;
}
-
+
NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
ISD::SETEQ, false, DagCombineInfo);
if (!NewLHS.Val)
@@ -1339,7 +2048,7 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
NewRHS = SDOperand();
}
-SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
// FIXME: Add support for indexed stores.
assert(OpNo == 1 && "Can only expand the stored value so far");
@@ -1356,7 +2065,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
if (!N->isTruncatingStore()) {
unsigned IncrementSize = 0;
- GetExpandedOp(N->getValue(), Lo, Hi);
+ GetExpandedInteger(N->getValue(), Lo, Hi);
IncrementSize = Hi.getValueType().getSizeInBits()/8;
if (TLI.isBigEndian())
@@ -1372,12 +2081,12 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
isVolatile, MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
} else if (N->getMemoryVT().bitsLE(NVT)) {
- GetExpandedOp(N->getValue(), Lo, Hi);
+ GetExpandedInteger(N->getValue(), Lo, Hi);
return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
N->getMemoryVT(), isVolatile, Alignment);
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
- GetExpandedOp(N->getValue(), Lo, Hi);
+ GetExpandedInteger(N->getValue(), Lo, Hi);
Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
isVolatile, Alignment);
@@ -1397,7 +2106,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
} else {
// Big-endian - high bits are at low addresses. Favor aligned stores at
// the cost of some bit-fiddling.
- GetExpandedOp(N->getValue(), Lo, Hi);
+ GetExpandedInteger(N->getValue(), Lo, Hi);
MVT EVT = N->getMemoryVT();
unsigned EBytes = EVT.getStoreSizeInBits()/8;
@@ -1432,7 +2141,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
}
}
-SDOperand DAGTypeLegalizer::ExpandOperand_BUILD_VECTOR(SDNode *N) {
+SDOperand DAGTypeLegalizer::ExpandIntOp_BUILD_VECTOR(SDNode *N) {
// The vector type is legal but the element type needs expansion.
MVT VecVT = N->getValueType(0);
unsigned NumElts = VecVT.getVectorNumElements();
@@ -1449,7 +2158,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_BUILD_VECTOR(SDNode *N) {
for (unsigned i = 0; i < NumElts; ++i) {
SDOperand Lo, Hi;
- GetExpandedOp(N->getOperand(i), Lo, Hi);
+ GetExpandedInteger(N->getOperand(i), Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
NewElts.push_back(Lo);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index 5b37c75f1f..e469f255c3 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -42,7 +42,7 @@ void DAGTypeLegalizer::run() {
// The root of the dag may dangle to deleted nodes until the type legalizer is
// done. Set it to null to avoid confusion.
DAG.setRoot(SDOperand());
-
+
// Walk all nodes in the graph, assigning them a NodeID of 'ReadyToProcess'
// (and remembering them) if they are leaves and assigning 'NewNode' if
// non-leaves.
@@ -55,14 +55,14 @@ void DAGTypeLegalizer::run() {
I->setNodeId(NewNode);
}
}
-
+
// Now that we have a set of nodes to process, handle them all.
while (!Worklist.empty()) {
SDNode *N = Worklist.back();
Worklist.pop_back();
assert(N->getNodeId() == ReadyToProcess &&
"Node should be ready if on worklist!");
-
+
// Scan the values produced by the node, checking to see if any result
// types are illegal.
unsigned i = 0;
@@ -74,14 +74,17 @@ void DAGTypeLegalizer::run() {
assert(false && "Unknown action!");
case Legal:
break;
- case Promote:
- PromoteResult(N, i);
+ case PromoteInteger:
+ PromoteIntegerResult(N, i);
goto NodeDone;
- case Expand:
- ExpandResult(N, i);
+ case ExpandInteger:
+ ExpandIntegerResult(N, i);
goto NodeDone;
- case FloatToInt:
- FloatToIntResult(N, i);
+ case PromoteFloat:
+ PromoteFloatResult(N, i);
+ goto NodeDone;
+ case ExpandFloat:
+ ExpandFloatResult(N, i);
goto NodeDone;
case Scalarize:
ScalarizeResult(N, i);
@@ -104,14 +107,17 @@ void DAGTypeLegalizer::run() {
assert(false && "Unknown action!");
case Legal:
continue;
- case Promote:
- NeedsRevisit = PromoteOperand(N, i);
+ case PromoteInteger:
+ NeedsRevisit = PromoteIntegerOperand(N, i);
+ break;
+ case ExpandInteger:
+ NeedsRevisit = ExpandIntegerOperand(N, i);
break;
- case Expand:
- NeedsRevisit = ExpandOperand(N, i);
+ case PromoteFloat:
+ NeedsRevisit = PromoteFloatOperand(N, i);
break;
- case FloatToInt:
- NeedsRevisit = FloatToIntOperand(N, i);
+ case ExpandFloat:
+ NeedsRevisit = ExpandFloatOperand(N, i);
break;
case Scalarize:
NeedsRevisit = ScalarizeOperand(N, i);
@@ -126,7 +132,7 @@ void DAGTypeLegalizer::run() {
// If the node needs revisiting, don't add all users to the worklist etc.
if (NeedsRevisit)
continue;
-
+
if (i == NumOperands)
DEBUG(cerr << "Legally typed node: "; N->dump(&DAG); cerr << "\n");
}
@@ -135,37 +141,37 @@ NodeDone:
// If we reach here, the node was processed, potentially creating new nodes.
// Mark it as processed and add its users to the worklist as appropriate.
N->setNodeId(Processed);
-
+
for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
UI != E; ++UI) {
SDNode *User = UI->getUser();
int NodeID = User->getNodeId();
assert(NodeID != ReadyToProcess && NodeID != Processed &&
"Invalid node id for user of unprocessed node!");
-
+
// This node has two options: it can either be a new node or its Node ID
// may be a count of the number of operands it has that are not ready.
if (NodeID > 0) {
User->setNodeId(NodeID-1);
-
+
// If this was the last use it was waiting on, add it to the ready list.
if (NodeID-1 == ReadyToProcess)
Worklist.push_back(User);
continue;
}
-
+
// Otherwise, this node is new: this is the first operand of it that
// became ready. Its new NodeID is the number of operands it has minus 1
// (as this node is now processed).
assert(NodeID == NewNode && "Unknown node ID!");
User->setNodeId(User->getNumOperands()-1);
-
+
// If the node only has a single operand, it is now ready.
if (User->getNumOperands() == 1)
Worklist.push_back(User);
}
}
-
+
// If the root changed (e.g. it was a dead load, update the root).
DAG.setRoot(Dummy.getValue());
@@ -315,8 +321,8 @@ void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) {
NodeUpdateListener NUL(*this);
DAG.ReplaceAllUsesOfValueWith(From, To, &NUL);
- // The old node may still be present in a map like ExpandedNodes or
- // PromotedNodes. Inform maps about the replacement.
+ // The old node may still be present in a map like ExpandedIntegers or
+ // PromotedIntegers. Inform maps about the replacement.
NoteReplacement(From, To);
}
@@ -336,8 +342,8 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
NodeUpdateListener NUL(*this);
DAG.ReplaceAllUsesWith(From, To, &NUL);
- // The old node may still be present in a map like ExpandedNodes or
- // PromotedNodes. Inform maps about the replacement.
+ // The old node may still be present in a map like ExpandedIntegers or
+ // PromotedIntegers. Inform maps about the replacement.
for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) {
assert(From->getValueType(i) == To->getValueType(i) &&
"Node results don't match");
@@ -380,29 +386,38 @@ void DAGTypeLegalizer::ExpungeNode(SDOperand N) {
I->second = Replacement;
}
- for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedNodes.begin(),
- E = PromotedNodes.end(); I != E; ++I) {
+ for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedIntegers.begin(),
+ E = PromotedIntegers.end(); I != E; ++I) {
assert(I->first != N);
if (I->second == N)
I->second = Replacement;
}
- for (DenseMap<SDOperand, SDOperand>::iterator I = FloatToIntedNodes.begin(),
- E = FloatToIntedNodes.end(); I != E; ++I) {
+ for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedFloats.begin(),
+ E = PromotedFloats.end(); I != E; ++I) {
assert(I->first != N);
if (I->second == N)
I->second = Replacement;
}
- for (DenseMap<SDOperand, SDOperand>::iterator I = ScalarizedNodes.begin(),
- E = ScalarizedNodes.end(); I != E; ++I) {
+ for (DenseMap<SDOperand, SDOperand>::iterator I = ScalarizedVectors.begin(),
+ E = ScalarizedVectors.end(); I != E; ++I) {
assert(I->first != N);
if (I->second == N)
I->second = Replacement;
}
for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
- I = ExpandedNodes.begin(), E = ExpandedNodes.end(); I != E; ++I) {
+ I = ExpandedIntegers.begin(), E = ExpandedIntegers.end(); I != E; ++I){
+ assert(I->first != N);
+ if (I->second.first == N)
+ I->second.first = Replacement;
+ if (I->second.second == N)
+ I->second.second = Replacement;
+ }
+
+ for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
+ I = ExpandedFloats.begin(), E = ExpandedFloats.end(); I != E; ++I) {
assert(I->first != N);
if (I->second.first == N)
I->second.first = Replacement;
@@ -411,7 +426,7 @@ void DAGTypeLegalizer::ExpungeNode(SDOperand N) {
}
for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
- I = SplitNodes.begin(), E = SplitNodes.end(); I != E; ++I) {
+ I = SplitVectors.begin(), E = SplitVectors.end(); I != E; ++I) {
assert(I->first != N);
if (I->second.first == N)
I->second.first = Replacement;
@@ -422,36 +437,62 @@ void DAGTypeLegalizer::ExpungeNode(SDOperand N) {
}
-void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetPromotedInteger(SDOperand Op, SDOperand Result) {
ExpungeNode(Result);
AnalyzeNewNode(Result.Val);
- SDOperand &OpEntry = PromotedNodes[Op];
+ SDOperand &OpEntry = PromotedIntegers[Op];
assert(OpEntry.Val == 0 && "Node is already promoted!");
OpEntry = Result;
}
-void DAGTypeLegalizer::SetIntegerOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetPromotedFloat(SDOperand Op, SDOperand Result) {
ExpungeNode(Result);
AnalyzeNewNode(Result.Val);
- SDOperand &OpEntry = FloatToIntedNodes[Op];
+ SDOperand &OpEntry = PromotedFloats[Op];
assert(OpEntry.Val == 0 && "Node is already converted to integer!");
OpEntry = Result;
}
-void DAGTypeLegalizer::SetScalarizedOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetScalarizedVector(SDOperand Op, SDOperand Result) {
ExpungeNode(Result);
AnalyzeNewNode(Result.Val);
- SDOperand &OpEntry = ScalarizedNodes[Op];
+ SDOperand &OpEntry = ScalarizedVectors[Op];
assert(OpEntry.Val == 0 && "Node is already scalarized!");
OpEntry = Result;
}
-void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo,
- SDOperand &Hi) {
- std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
+void DAGTypeLegalizer::GetExpandedInteger(SDOperand Op, SDOperand &Lo,
+ SDOperand &Hi) {
+ std::pair<SDOperand, SDOperand> &Entry = ExpandedIntegers[Op];
+ RemapNode(Entry.first);
+ RemapNode(Entry.second);
+ assert(Entry.first.Val && "Operand isn't expanded");
+ Lo = Entry.first;
+ Hi = Entry.second;
+}
+
+void DAGTypeLegalizer::SetExpandedInteger(SDOperand Op, SDOperand Lo,
+ SDOperand Hi) {
+ ExpungeNode(Lo);
+ ExpungeNode(Hi);
+
+ // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
+ AnalyzeNewNode(Lo.Val);
+ AnalyzeNewNode(Hi.Val);
+
+ // Remember that this is the result of the node.
+ std::pair<SDOperand, SDOperand> &Entry = ExpandedIntegers[Op];
+ assert(Entry.first.Val == 0 && "Node already expanded");
+ Entry.first = Lo;
+ Entry.second = Hi;
+}
+
+void DAGTypeLegalizer::GetExpandedFloat(SDOperand Op, SDOperand &Lo,
+ SDOperand &Hi) {
+ std::pair<SDOperand, SDOperand> &Entry = ExpandedFloats[Op];
RemapNode(Entry.first);
RemapNode(Entry.second);
assert(Entry.first.Val && "Operand isn't expanded");
@@ -459,7 +500,8 @@ void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo,
Hi = Entry.second;
}
-void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+void DAGTypeLegalizer::SetExpandedFloat(SDOperand Op, SDOperand Lo,
+ SDOperand Hi) {
ExpungeNode(Lo);
ExpungeNode(Hi);
@@ -468,14 +510,15 @@ void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
AnalyzeNewNode(Hi.Val);
// Remember that this is the result of the node.
- std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
+ std::pair<SDOperand, SDOperand> &Entry = ExpandedFloats[Op];
assert(Entry.first.Val == 0 && "Node already expanded");
Entry.first = Lo;
Entry.second = Hi;
}
-void DAGTypeLegalizer::GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
- std::pair<SDOperand, SDOperand> &Entry = SplitNodes[Op];
+void DAGTypeLegalizer::GetSplitVector(SDOperand Op, SDOperand &Lo,
+ SDOperand &Hi) {
+ std::pair<SDOperand, SDOperand> &Entry = SplitVectors[Op];
RemapNode(Entry.first);
RemapNode(Entry.second);
assert(Entry.first.Val && "Operand isn't split");
@@ -483,7 +526,8 @@ void DAGTypeLegalizer::GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
Hi = Entry.second;
}
-void DAGTypeLegalizer::SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+void DAGTypeLegalizer::SetSplitVector(SDOperand Op, SDOperand Lo,
+ SDOperand Hi) {
ExpungeNode(Lo);
ExpungeNode(Hi);
@@ -492,7 +536,7 @@ void DAGTypeLegalizer::SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
AnalyzeNewNode(Hi.Val);
// Remember that this is the result of the node.
- std::pair<SDOperand, SDOperand> &Entry = SplitNodes[Op];
+ std::pair<SDOperand, SDOperand> &Entry = SplitVectors[Op];
assert(Entry.first.Val == 0 && "Node already split");
Entry.first = Lo;
Entry.second = Hi;
@@ -505,11 +549,11 @@ SDOperand DAGTypeLegalizer::BitConvertToInteger(SDOperand Op) {
return DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerVT(BitWidth), Op);
}
-SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
+SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
MVT DestVT) {
// Create the stack frame object.
SDOperand FIPtr = DAG.CreateStackTemporary(DestVT);
-
+
// Emit a store to the stack slot.
SDOperand Store = DAG.getStore(DAG.getEntryNode(), Op, FIPtr, NULL, 0);
// Result is a load from the stack slot.
@@ -605,6 +649,6 @@ SDOperand DAGTypeLegalizer::GetVectorElementPointer(SDOperand VecPtr, MVT EltVT,
/// the graph.
void SelectionDAG::LegalizeTypes() {
if (ViewLegalizeTypesDAGs) viewGraph();
-
+
DAGTypeLegalizer(*this).run();
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index ba8f106935..a472a296b5 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -47,31 +47,32 @@ public:
/// ReadyToProcess - All operands have been processed, so this node is ready
/// to be handled.
ReadyToProcess = 0,
-
+
/// NewNode - This is a new node that was created in the process of
/// legalizing some other node.
NewNode = -1,
-
+
/// Processed - This is a node that has already been processed.
Processed = -2
-
+
// 1+ - This is a node which has this many unlegalized operands.
};
private:
enum LegalizeAction {
- Legal, // The target natively supports this type.
- Promote, // This type should be executed in a larger type.
- Expand, // This type should be split into two types of half the size.
- FloatToInt, // Convert a floating point type to an integer of the same size.
- Scalarize, // Replace this one-element vector type with its element type.
- Split // This vector type should be split into smaller vectors.
+ Legal, // The target natively supports this type.
+ PromoteInteger, // Replace this integer type with a larger one.
+ ExpandInteger, // Split this integer type into two of half the size.
+ PromoteFloat, // Convert this float type to a same size integer type.
+ ExpandFloat, // Split this float type into two of half the size.
+ Scalarize, // Replace this one-element vector type with its element type.
+ Split // This vector type should be split into smaller vectors.
};
/// ValueTypeActions - This is a bitvector that contains two bits for each
/// simple value type, where the two bits correspond to the LegalizeAction
/// enum from TargetLowering. This can be queried with "getTypeAction(VT)".
TargetLowering::ValueTypeActionImpl ValueTypeActions;
-
+
/// getTypeAction - Return how we should legalize values of this type, either
/// it is already legal, or we need to promote it to a larger integer type, or
/// we need to expand it into multiple registers of a smaller integer type, or
@@ -84,16 +85,19 @@ private:
case TargetLowering::Legal:
return Legal;
case TargetLowering::Promote:
- return Promote;
+ return PromoteInteger;
case TargetLowering::Expand:
// Expand can mean
// 1) split scalar in half, 2) convert a float to an integer,
// 3) scalarize a single-element vector, 4) split a vector in two.
if (!VT.isVector()) {
- if (VT.getSizeInBits() == TLI.getTypeToTransformTo(VT).getSizeInBits())
- return FloatToInt;
+ if (VT.isInteger())
+ return ExpandInteger;
+ else if (VT.getSizeInBits() ==
+ TLI.getTypeToTransformTo(VT).getSizeInBits())
+ return PromoteFloat;
else
- return Expand;
+ return ExpandFloat;
} else if (VT.getVectorNumElements() == 1) {
return Scalarize;
} else {
@@ -107,26 +111,30 @@ private:
return ValueTypeActions.getTypeAction(VT) == TargetLowering::Legal;
}
- /// PromotedNodes - For nodes that are below legal width, this map indicates
- /// what promoted value to use.
- DenseMap<SDOperand, SDOperand> PromotedNodes;
-
- /// ExpandedNodes - For nodes that need to be expanded this map indicates
- /// which operands are the expanded version of the input.
- DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes;
+ /// PromotedIntegers - For integer nodes that are below legal width, this map
+ /// indicates what promoted value to use.
+ DenseMap<SDOperand, SDOperand> PromotedIntegers;
+
+ /// ExpandedIntegers - For integer nodes that need to be expanded this map
+ /// indicates which operands are the expanded version of the input.
+ DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedIntegers;
- /// FloatToIntedNodes - For floating point nodes converted to integers of
+ /// PromotedFloats - For floating point nodes converted to integers of
/// the same size, this map indicates the converted value to use.
- DenseMap<SDOperand, SDOperand> FloatToIntedNodes;
+ DenseMap<SDOperand, SDOperand> PromotedFloats;
- /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the
+ /// ExpandedFloats - For float nodes that need to be expanded this map
+ /// indicates which operands are the expanded version of the input.
+ DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedFloats;
+
+ /// ScalarizedVectors - For nodes that are <1 x ty>, this map indicates the
/// scalar value of type 'ty' to use.
- DenseMap<SDOperand, SDOperand> ScalarizedNodes;
+ DenseMap<SDOperand, SDOperand> ScalarizedVectors;
- /// SplitNodes - For nodes that need to be split this map indicates
+ /// SplitVectors - For nodes that need to be split this map indicates
/// which operands are the expanded version of the input.
- DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > SplitNodes;
-
+ DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > SplitVectors;
+
/// ReplacedNodes - For nodes that have been replaced with another,
/// indicates the replacement node to use.
DenseMap<SDOperand, SDOperand> ReplacedNodes;
@@ -135,17 +143,17 @@ private:
/// pushed onto this worklist, all operands of a node must have already been
/// processed.
SmallVector<SDNode*, 128> Worklist;
-
+
public:
explicit DAGTypeLegalizer(SelectionDAG &dag)
: TLI(dag.getTargetLoweringInfo()), DAG(dag),
ValueTypeActions(TLI.getValueTypeActions()) {
assert(MVT::LAST_VALUETYPE <= 32 &&
"Too many value types for ValueTypeActions to hold!");
- }
-
+ }
+
void run();
-
+
/// ReanalyzeNode - Recompute the NodeID and correct processed operands
/// for the specified node, adding it to the worklist if ready.
void ReanalyzeNode(SDNode *N) {
@@ -183,174 +191,186 @@ private:
SDOperand Index);
//===--------------------------------------------------------------------===//
- // Promotion Support: LegalizeTypesPromote.cpp
+ // Integer Promotion Support: LegalizeIntegerTypes.cpp
//===--------------------------------------------------------------------===//
-
- SDOperand GetPromotedOp(SDOperand Op) {
- SDOperand &PromotedOp = PromotedNodes[Op];
+
+ SDOperand GetPromotedInteger(SDOperand Op) {
+ SDOperand &PromotedOp = PromotedIntegers[Op];
RemapNode(PromotedOp);
assert(PromotedOp.Val && "Operand wasn't promoted?");
return PromotedOp;
}
- void SetPromotedOp(SDOperand Op, SDOperand Result);
-
- /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final
- /// size.
- SDOperand GetPromotedZExtOp(SDOperand Op) {
+ void SetPromotedInteger(SDOperand Op, SDOperand Result);
+
+ /// ZExtPromotedInteger - Get a promoted operand and zero extend it to the
+ /// final size.
+ SDOperand ZExtPromotedInteger(SDOperand Op) {
MVT OldVT = Op.getValueType();
- Op = GetPromotedOp(Op);
+ Op = GetPromotedInteger(Op);
return DAG.getZeroExtendInReg(Op, OldVT);
- }
-
- // Result Promotion.
- void PromoteResult(SDNode *N, unsigned ResNo);
- SDOperand PromoteResult_BIT_CONVERT(SDNode *N);
- SDOperand PromoteResult_BUILD_PAIR(SDNode *N);
- SDOperand PromoteResult_Constant(SDNode *N);
- SDOperand PromoteResult_CTLZ(SDNode *N);
- SDOperand PromoteResult_CTPOP(SDNode *N);
- SDOperand PromoteResult_CTTZ(SDNode *N);
- SDOperand PromoteResult_EXTRACT_VECTOR_ELT(SDNode *N);
- SDOperand PromoteResult_FP_ROUND(SDNode *N);
- SDOperand PromoteResult_FP_TO_XINT(SDNode *N);
- SDOperand PromoteResult_INT_EXTEND(SDNode *N);
- SDOperand PromoteResult_LOAD(LoadSDNode *N);
- SDOperand PromoteResult_SDIV(SDNode *N);
- SDOperand PromoteResult_SELECT (SDNode *N);
- SDOperand PromoteResult_SELECT_CC(SDNode *N);
- SDOperand PromoteResult_SETCC(SDNode *N);
- SDOperand PromoteResult_SHL(SDNode *N);
- SDOperand PromoteResult_SimpleIntBinOp(SDNode *N);
- SDOperand PromoteResult_SRA(SDNode *N);
- SDOperand PromoteResult_SRL(SDNode *N);
- SDOperand PromoteResult_TRUNCATE(SDNode *N);
- SDOperand PromoteResult_UDIV(SDNode *N);
- SDOperand PromoteResult_UNDEF(SDNode *N);
-
- // Operand Promotion.
- bool PromoteOperand(SDNode *N, unsigned OperandNo);
- SDOperand PromoteOperand_ANY_EXTEND(SDNode *N);
- SDOperand PromoteOperand_BUILD_PAIR(SDNode *N);
- SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_BUILD_VECTOR(SDNode *N);
- SDOperand PromoteOperand_FP_EXTEND(SDNode *N);
- SDOperand PromoteOperand_FP_ROUND(SDNode *N);
- SDOperand PromoteOperand_INT_TO_FP(SDNode *N);
- SDOperand PromoteOperand_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_MEMBARRIER(SDNode *N);
- SDOperand PromoteOperand_RET(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N);
- SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo);
- SDOperand PromoteOperand_TRUNCATE(SDNode *N);
- SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N);
+ }
+
+ // Integer Result Promotion.
+ void PromoteIntegerResult(SDNode *N, unsigned ResNo);
+ SDOperand PromoteIntRes_BIT_CONVERT(SDNode *N);
+ SDOperand PromoteIntRes_BUILD_PAIR(SDNode *N);
+ SDOperand PromoteIntRes_Constant(SDNode *N);
+ SDOperand PromoteIntRes_CTLZ(SDNode *N);
+ SDOperand PromoteIntRes_CTPOP(SDNode *N);
+ SDOperand PromoteIntRes_CTTZ(SDNode *N);
+ SDOperand PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
+ SDOperand PromoteIntRes_FP_ROUND(SDNode *N);
+ SDOperand PromoteIntRes_FP_TO_XINT(SDNode *N);
+ SDOperand PromoteIntRes_INT_EXTEND(SDNode *N);
+ SDOperand PromoteIntRes_LOAD(LoadSDNode *N);
+ SDOperand PromoteIntRes_SDIV(SDNode *N);
+ SDOperand PromoteIntRes_SELECT (SDNode *N);
+ SDOperand PromoteIntRes_SELECT_CC(SDNode *N);
+ SDOperand PromoteIntRes_SETCC(SDNode *N);
+ SDOperand PromoteIntRes_SHL(SDNode *N);
+ SDOperand PromoteIntRes_SimpleIntBinOp(SDNode *N);
+ SDOperand PromoteIntRes_SRA(SDNode *N);
+ SDOperand PromoteIntRes_SRL(SDNode *N);
+ SDOperand PromoteIntRes_TRUNCATE(SDNode *N);
+ SDOperand PromoteIntRes_UDIV(SDNode *N);
+ SDOperand PromoteIntRes_UNDEF(SDNode *N);
+
+ // Integer Operand Promotion.
+ bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
+ SDOperand PromoteIntOp_ANY_EXTEND(SDNode *N);
+ SDOperand PromoteIntOp_BUILD_PAIR(SDNode *N);
+ SDOperand PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_BUILD_VECTOR(SDNode *N);
+ SDOperand PromoteIntOp_FP_EXTEND(SDNode *N);
+ SDOperand PromoteIntOp_FP_ROUND(SDNode *N);
+ SDOperand PromoteIntOp_INT_TO_FP(SDNode *N);
+ SDOperand PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_MEMBARRIER(SDNode *N);
+ SDOperand PromoteIntOp_SELECT(SDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_SETCC(SDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_SIGN_EXTEND(SDNode *N);
+ SDOperand PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo);
+ SDOperand PromoteIntOp_TRUNCATE(SDNode *N);
+ SDOperand PromoteIntOp_ZERO_EXTEND(SDNode *N);
void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code);
//===--------------------------------------------------------------------===//
- // Expansion Support: LegalizeTypesExpand.cpp
+ // Integer Expansion Support: LegalizeIntegerTypes.cpp
//===--------------------------------------------------------------------===//
-
- void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
- void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
-
- // Result Expansion.
- void ExpandResult(SDNode *N, unsigned ResNo);
- void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_CTLZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_CTPOP (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_CTTZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_TRUNCATE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_FP_TO_SINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_FP_TO_UINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-
- void ExpandResult_Logical (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_BSWAP (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_SREM (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_UDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_UREM (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandResult_Shift (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-
- void ExpandShiftByConstant(SDNode *N, unsigned Amt,
+
+ void GetExpandedInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+ void SetExpandedInteger(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+ // Integer Result Expansion.
+ void ExpandIntegerResult(SDNode *N, unsigned ResNo);
+ void ExpandIntRes_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_BIT_CONVERT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_CTLZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_CTPOP (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_CTTZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_MERGE_VALUES (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SIGN_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SIGN_EXTEND_INREG (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_TRUNCATE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_ZERO_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_FP_TO_SINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_FP_TO_UINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void ExpandIntRes_Logical (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_BSWAP (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_SREM (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_UDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_UREM (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandIntRes_Shift (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void ExpandShiftByConstant(SDNode *N, unsigned Amt,
SDOperand &Lo, SDOperand &Hi);
bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- // Operand Expansion.
- bool ExpandOperand(SDNode *N, unsigned OperandNo);
- SDOperand ExpandOperand_BIT_CONVERT(SDNode *N);
- SDOperand ExpandOperand_BR_CC(SDNode *N);
- SDOperand ExpandOperand_BUILD_VECTOR(SDNode *N);
- SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N);
- SDOperand ExpandOperand_SETCC(SDNode *N);
- SDOperand ExpandOperand_SINT_TO_FP(SDOperand Source, MVT DestTy);
- SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo);
- SDOperand ExpandOperand_TRUNCATE(SDNode *N);
- SDOperand ExpandOperand_UINT_TO_FP(SDOperand Source, MVT DestTy);
+ // Integer Operand Expansion.
+ bool ExpandIntegerOperand(SDNode *N, unsigned OperandNo);
+ SDOperand ExpandIntOp_BIT_CONVERT(SDNode *N);
+ SDOperand ExpandIntOp_BR_CC(SDNode *N);
+ SDOperand ExpandIntOp_BUILD_VECTOR(SDNode *N);
+ SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
+ SDOperand ExpandIntOp_SETCC(SDNode *N);
+ SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
+ SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
+ SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
+ SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
ISD::CondCode &CCCode);
-
+
//===--------------------------------------------------------------------===//
- // Float to Integer Conversion Support: LegalizeTypesFloatToInt.cpp
+ // Float to Integer Conversion Support: LegalizeFloatTypes.cpp
//===--------------------------------------------------------------------===//
- SDOperand GetIntegerOp(SDOperand Op) {
- SDOperand &IntegerOp = FloatToIntedNodes[Op];
- RemapNode(IntegerOp);
- assert(IntegerOp.Val && "Operand wasn't converted to integer?");
- return IntegerOp;
+ SDOperand GetPromotedFloat(SDOperand Op) {
+ SDOperand &PromotedOp = PromotedFloats[Op];
+ RemapNode(PromotedOp);
+ assert(PromotedOp.Val && "Operand wasn't converted to integer?");
+ return PromotedOp;
}
- void SetIntegerOp(SDOperand Op, SDOperand Result);
+ void SetPromotedFloat(SDOperand Op, SDOperand Result);
// Result Float to Integer Conversion.
- void FloatToIntResult(SDNode *N, unsigned OpNo);
- SDOperand FloatToIntRes_BIT_CONVERT(SDNode *N);
- SDOperand FloatToIntRes_BUILD_PAIR(SDNode *N);
- SDOperand FloatToIntRes_ConstantFP(ConstantFPSDNode *N);
- SDOperand FloatToIntRes_FADD(SDNode *N);
- SDOperand FloatToIntRes_FCOPYSIGN(SDNode *N);
- SDOperand FloatToIntRes_FMUL(SDNode *N);
- SDOperand FloatToIntRes_FSUB(SDNode *N);
- SDOperand FloatToIntRes_LOAD(SDNode *N);
- SDOperand FloatToIntRes_XINT_TO_FP(SDNode *N);
+ void PromoteFloatResult(SDNode *N, unsigned OpNo);
+ SDOperand PromoteFloatRes_BIT_CONVERT(SDNode *N);
+ SDOperand PromoteFloatRes_BUILD_PAIR(SDNode *N);
+ SDOperand PromoteFloatRes_ConstantFP(ConstantFPSDNode *N);
+ SDOperand PromoteFloatRes_FADD(SDNode *N);
+ SDOperand PromoteFloatRes_FCOPYSIGN(SDNode *N);
+ SDOperand PromoteFloatRes_FMUL(SDNode *N);
+ SDOperand PromoteFloatRes_FSUB(SDNode *N);
+ SDOperand PromoteFloatRes_LOAD(SDNode *N);
+ SDOperand PromoteFloatRes_XINT_TO_FP(SDNode *N);
// Operand Float to Integer Conversion.
- bool FloatToIntOperand(SDNode *N, unsigned OpNo);
- SDOperand FloatToIntOp_BIT_CONVERT(SDNode *N);
+ bool PromoteFloatOperand(SDNode *N, unsigned OpNo);
+ SDOperand PromoteFloatOp_BIT_CONVERT(SDNode *N);
//===--------------------------------------------------------------------===//
- // Scalarization Support: LegalizeTypesScalarize.cpp
+ // Float Expansion Support: LegalizeFloatTypes.cpp
//===--------------------------------------------------------------------===//
-
- SDOperand GetScalarizedOp(SDOperand Op) {
- SDOperand &ScalarOp = ScalarizedNodes[Op];
- RemapNode(ScalarOp);
- assert(ScalarOp.Val && "Operand wasn't scalarized?");
- return ScalarOp;
+
+ void GetExpandedFloat(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+ void SetExpandedFloat(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+ // Float Result Expansion.
+ void ExpandFloatResult(SDNode *N, unsigned ResNo);
+
+ // Float Operand Expansion.
+ bool ExpandFloatOperand(SDNode *N, unsigned OperandNo);
+
+ //===--------------------------------------------------------------------===//
+ // Scalarization Support: LegalizeVectorTypes.cpp
+ //===--------------------------------------------------------------------===//
+
+ SDOperand GetScalarizedVector(SDOperand Op) {
+ SDOperand &ScalarizedOp = ScalarizedVectors[Op];
+ RemapNode(ScalarizedOp);
+ assert(ScalarizedOp.Val && "Operand wasn't scalarized?");
+ return ScalarizedOp;
}
- void SetScalarizedOp(SDOperand Op, SDOperand Result);
-
- // Result Vector Scalarization: <1 x ty> -> ty.
+ void SetScalarizedVector(SDOperand Op, SDOperand Result);
+
+ // Vector Result Scalarization: <1 x ty> -> ty.
void ScalarizeResult(SDNode *N, unsigned OpNo);
SDOperand ScalarizeRes_BinOp(SDNode *N);
SDOperand ScalarizeRes_UnaryOp(SDNode *N);
@@ -363,20 +383,20 @@ private:
SDOperand ScalarizeRes_UNDEF(SDNode *N);
SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N);
- // Operand Vector Scalarization: <1 x ty> -> ty.
+ // Vector Operand Scalarization: <1 x ty> -> ty.
bool ScalarizeOperand(SDNode *N, unsigned OpNo);
SDOperand ScalarizeOp_BIT_CONVERT(SDNode *N);
SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo);
//===--------------------------------------------------------------------===//
- // Vector Splitting Support: LegalizeTypesSplit.cpp
+ // Vector Splitting Support: LegalizeVectorTypes.cpp
//===--------------------------------------------------------------------===//
-
- void GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
- void SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
-
- // Result Vector Splitting: <128 x ty> -> 2 x <64 x ty>.
+
+ void GetSplitVector(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+ void SetSplitVector(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+ // Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>.
void SplitResult(SDNode *N, unsigned OpNo);
void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
@@ -392,8 +412,8 @@ private:
void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-
- // Operand Vector Splitting: <128 x ty> -> 2 x <64 x ty>.
+
+ // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
bool SplitOperand(SDNode *N, unsigned OpNo);
SDOperand SplitOp_BIT_CONVERT(SDNode *N);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
deleted file mode 100644
index 5c68fe2dc3..0000000000
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
+++ /dev/null
@@ -1,748 +0,0 @@
-//===-- LegalizeTypesPromote.cpp - Promotion for LegalizeTypes ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements promotion support for LegalizeTypes. Promotion is the
-// act of changing a computation in an invalid type to be a computation in a
-// larger type. For example, implementing i8 arithmetic in an i32 register (as
-// is often needed on powerpc for example).
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// Result Promotion
-//===----------------------------------------------------------------------===//
-
-/// PromoteResult - This method is called when a result of a node is found to be
-/// in need of promotion to a larger type. At this point, the node may also
-/// have invalid operands or may have other results that need expansion, we just
-/// know that (at least) one result needs promotion.
-void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) {
- DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n");
- SDOperand Result = SDOperand();
-
- switch (N->getOpcode()) {
- default:
-#ifndef NDEBUG
- cerr << "PromoteResult #" << ResNo << ": ";
- N->dump(&DAG); cerr << "\n";
-#endif
- assert(0 && "Do not know how to promote this operator!");
- abort();
- case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break;
- case ISD::Constant: Result = PromoteResult_Constant(N); break;
-
- case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break;
- case ISD::SIGN_EXTEND:
- case ISD::ZERO_EXTEND:
- case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break;
- case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break;
- case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT: Result = PromoteResult_FP_TO_XINT(N); break;
- case ISD::SETCC: Result = PromoteResult_SETCC(N); break;
- case ISD::LOAD: Result = PromoteResult_LOAD(cast<LoadSDNode>(N)); break;
- case ISD::BUILD_PAIR: Result = PromoteResult_BUILD_PAIR(N); break;
- case ISD::BIT_CONVERT: Result = PromoteResult_BIT_CONVERT(N); break;
-
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::ADD:
- case ISD::SUB:
- case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break;
-
- case ISD::SDIV:
- case ISD::SREM: Result = PromoteResult_SDIV(N); break;
-
- case ISD::UDIV:
- case ISD::UREM: Result = PromoteResult_UDIV(N); break;
-
- case ISD::SHL: Result = PromoteResult_SHL(N); break;
- case ISD::SRA: Result = PromoteResult_SRA(N); break;
- case ISD::SRL: Result = PromoteResult_SRL(N); break;
-
- case ISD::SELECT: Result = PromoteResult_SELECT(N); break;
- case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break;
-
- case ISD::CTLZ: Result = PromoteResult_CTLZ(N); break;
- case ISD::CTPOP: Result = PromoteResult_CTPOP(N); break;
- case ISD::CTTZ: Result = PromoteResult_CTTZ(N); break;
-
- case ISD::EXTRACT_VECTOR_ELT:
- Result = PromoteResult_EXTRACT_VECTOR_ELT(N);
- break;
- }
-
- // If Result is null, the sub-method took care of registering the result.
- if (Result.Val)
- SetPromotedOp(SDOperand(N, ResNo), Result);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) {
- return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) {
- MVT VT = N->getValueType(0);
- // Zero extend things like i1, sign extend everything else. It shouldn't
- // matter in theory which one we pick, but this tends to give better code?
- unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
- SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
- SDOperand(N, 0));
- assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
- return Result;
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
- SDOperand Res;
-
- switch (getTypeAction(N->getOperand(0).getValueType())) {
- default: assert(0 && "Unknown type action!");
- case Legal:
- case Expand:
- Res = N->getOperand(0);
- break;
- case Promote:
- Res = GetPromotedOp(N->getOperand(0));
- break;
- }
-
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- assert(Res.getValueType().getSizeInBits() >= NVT.getSizeInBits() &&
- "Truncation doesn't make sense!");
- if (Res.getValueType() == NVT)
- return Res;
-
- // Truncate to NVT instead of VT
- return DAG.getNode(ISD::TRUNCATE, NVT, Res);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) {
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-
- if (getTypeAction(N->getOperand(0).getValueType()) == Promote) {
- SDOperand Res = GetPromotedOp(N->getOperand(0));
- assert(Res.getValueType().getSizeInBits() <= NVT.getSizeInBits() &&
- "Extension doesn't make sense!");
-
- // If the result and operand types are the same after promotion, simplify
- // to an in-register extension.
- if (NVT == Res.getValueType()) {
- // The high bits are not guaranteed to be anything. Insert an extend.
- if (N->getOpcode() == ISD::SIGN_EXTEND)
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
- DAG.getValueType(N->getOperand(0).getValueType()));
- if (N->getOpcode() == ISD::ZERO_EXTEND)
- return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
- assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
- return Res;
- }
- }
-
- // Otherwise, just extend the original operand all the way to the larger type.
- return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
- // NOTE: Assumes input is legal.
- if (N->getConstantOperandVal(1) == 0)
- return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
- N->getOperand(0), DAG.getValueType(N->getValueType(0)));
- // If the precision discard isn't needed, just return the operand unrounded.
- return N->getOperand(0);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) {
- SDOperand Op = N->getOperand(0);
- // If the operand needed to be promoted, do so now.
- if (getTypeAction(Op.getValueType()) == Promote)
- // The input result is prerounded, so we don't have to do anything special.
- Op = GetPromotedOp(Op);
-
- unsigned NewOpc = N->getOpcode();
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-
- // 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 (N->getOpcode() == ISD::FP_TO_UINT) {
- if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
- (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
- TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom))
- NewOpc = ISD::FP_TO_SINT;
- }
-
- return DAG.getNode(NewOpc, NVT, Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
- assert(isTypeLegal(TLI.getSetCCResultType(N->getOperand(0)))
- && "SetCC type is not legal??");
- return DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(N->getOperand(0)),
- N->getOperand(0), N->getOperand(1), N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) {
- // FIXME: Add support for indexed loads.
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- ISD::LoadExtType ExtType =
- ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
- SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
- N->getSrcValue(), N->getSrcValueOffset(),
- N->getMemoryVT(), N->isVolatile(),
- N->getAlignment());
-
- // Legalized the chain result - switch anything that used the old chain to
- // use the new one.
- ReplaceValueWith(SDOperand(N, 1), Res.getValue(1));
- return Res;
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_BUILD_PAIR(SDNode *N) {
- // The pair element type may be legal, or may not promote to the same type as
- // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
- return DAG.getNode(ISD::ANY_EXTEND,
- TLI.getTypeToTransformTo(N->getValueType(0)),
- JoinIntegers(N->getOperand(0), N->getOperand(1)));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
- SDOperand InOp = N->getOperand(0);
- MVT InVT = InOp.getValueType();
- MVT NInVT = TLI.getTypeToTransformTo(InVT);
- MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
-
- switch (getTypeAction(InVT)) {
- default:
- assert(false && "Unknown type action!");
- break;
- case Legal:
- break;
- case Promote:
- if (OutVT.getSizeInBits() == NInVT.getSizeInBits())
- // The input promotes to the same size. Convert the promoted value.
- return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedOp(InOp));
- break;
- case Expand:
- break;
- case FloatToInt:
- // Promote the integer operand by hand.
- return DAG.getNode(ISD::ANY_EXTEND, OutVT, GetIntegerOp(InOp));
- case Scalarize:
- // Convert the element to an integer and promote it by hand.
- return DAG.getNode(ISD::ANY_EXTEND, OutVT,
- BitConvertToInteger(GetScalarizedOp(InOp)));
- case Split:
- // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split
- // pieces of the input into integers and reassemble in the final type.
- SDOperand Lo, Hi;
- GetSplitOp(N->getOperand(0), Lo, Hi);
- Lo = BitConvertToInteger(Lo);
- Hi = BitConvertToInteger(Hi);
-
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-
- InOp = DAG.getNode(ISD::ANY_EXTEND,
- MVT::getIntegerVT(OutVT.getSizeInBits()),
- JoinIntegers(Lo, Hi));
- return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
- }
-
- // Otherwise, lower the bit-convert to a store/load from the stack, then
- // promote the load.
- SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
- return PromoteResult_LOAD(cast<LoadSDNode>(Op.Val));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) {
- // 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.
- SDOperand LHS = GetPromotedOp(N->getOperand(0));
- SDOperand RHS = GetPromotedOp(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) {
- // Sign extend the input.
- SDOperand LHS = GetPromotedOp(N->getOperand(0));
- SDOperand RHS = GetPromotedOp(N->getOperand(1));
- MVT VT = N->getValueType(0);
- LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS,
- DAG.getValueType(VT));
- RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS,
- DAG.getValueType(VT));
-
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) {
- // Zero extend the input.
- SDOperand LHS = GetPromotedOp(N->getOperand(0));
- SDOperand RHS = GetPromotedOp(N->getOperand(1));
- MVT VT = N->getValueType(0);
- LHS = DAG.getZeroExtendInReg(LHS, VT);
- RHS = DAG.getZeroExtendInReg(RHS, VT);
-
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) {
- return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)),
- GetPromotedOp(N->getOperand(0)), N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) {
- // The input value must be properly sign extended.
- MVT VT = N->getValueType(0);
- MVT NVT = TLI.getTypeToTransformTo(VT);
- SDOperand Res = GetPromotedOp(N->getOperand(0));
- Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT));
- return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) {
- // The input value must be properly zero extended.
- MVT VT = N->getValueType(0);
- MVT NVT = TLI.getTypeToTransformTo(VT);
- SDOperand Res = GetPromotedZExtOp(N->getOperand(0));
- return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) {
- SDOperand LHS = GetPromotedOp(N->getOperand(1));
- SDOperand RHS = GetPromotedOp(N->getOperand(2));
- return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) {
- SDOperand LHS = GetPromotedOp(N->getOperand(2));
- SDOperand RHS = GetPromotedOp(N->getOperand(3));
- return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
- N->getOperand(1), LHS, RHS, N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTLZ(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- MVT OVT = N->getValueType(0);
- MVT NVT = Op.getValueType();
- // Zero extend to the promoted type and do the count there.
- Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT));
- // Subtract off the extra leading bits in the bigger type.
- return DAG.getNode(ISD::SUB, NVT, Op,
- DAG.getConstant(NVT.getSizeInBits() -
- OVT.getSizeInBits(), NVT));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTPOP(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- MVT OVT = N->getValueType(0);
- MVT NVT = Op.getValueType();
- // Zero extend to the promoted type and do the count there.
- return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTTZ(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- MVT OVT = N->getValueType(0);
- MVT NVT = Op.getValueType();
- // The count is the same in the promoted type except if the original
- // value was zero. This can be handled by setting the bit just off
- // the top of the original type.
- Op = DAG.getNode(ISD::OR, NVT, Op,
- // FIXME: Do this using an APINT constant.
- DAG.getConstant(1UL << OVT.getSizeInBits(), NVT));
- return DAG.getNode(ISD::CTTZ, NVT, Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_EXTRACT_VECTOR_ELT(SDNode *N) {
- MVT OldVT = N->getValueType(0);
- SDOperand OldVec = N->getOperand(0);
- unsigned OldElts = OldVec.getValueType().getVectorNumElements();
-
- if (OldElts == 1) {
- assert(!isTypeLegal(OldVec.getValueType()) &&
- "Legal one-element vector of a type needing promotion!");
- // It is tempting to follow GetScalarizedOp by a call to GetPromotedOp,
- // but this would be wrong because the scalarized value may not yet have
- // been processed.
- return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT),
- GetScalarizedOp(OldVec));
- }
-
- // Convert to a vector half as long with an element type of twice the width,
- // for example <4 x i16> -> <2 x i32>.
- assert(!(OldElts & 1) && "Odd length vectors not supported!");
- MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
- assert(OldVT.isSimple() && NewVT.isSimple());
-
- SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
- MVT::getVectorVT(NewVT, OldElts / 2),
- OldVec);
-
- // Extract the element at OldIdx / 2 from the new vector.
- SDOperand OldIdx = N->getOperand(1);
- SDOperand NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx,
- DAG.getConstant(1, TLI.getShiftAmountTy()));
- SDOperand Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx);
-
- // Select the appropriate half of the element: Lo if OldIdx was even,
- // Hi if it was odd.
- SDOperand Lo = Elt;
- SDOperand Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
- DAG.getConstant(OldVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-
- SDOperand Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(), OldIdx,
- DAG.getConstant(1, TLI.getShiftAmountTy()));
- return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
-}
-
-//===----------------------------------------------------------------------===//
-// Operand Promotion
-//===----------------------------------------------------------------------===//
-
-/// PromoteOperand - This method is called when the specified operand of the
-/// specified node is found to need promotion. At this point, all of the result
-/// types of the node are known to be legal, but other operands of the node may
-/// need promotion or expansion as well as the specified one.
-bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
- DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n");
- SDOperand Res;
- switch (N->getOpcode()) {
- default:
-#ifndef NDEBUG
- cerr << "PromoteOperand Op #" << OpNo << ": ";
- N->dump(&DAG); cerr << "\n";
-#endif
- assert(0 && "Do not know how to promote this operator's operand!");
- abort();
-
- case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break;
- case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break;
- case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break;
- case ISD::TRUNCATE: Res = PromoteOperand_TRUNCATE(N); break;
- case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break;
- case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break;
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: Res = PromoteOperand_INT_TO_FP(N); break;
- case ISD::BUILD_PAIR: Res = PromoteOperand_BUILD_PAIR(N); break;
-
- case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break;
- case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break;
- case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break;
- case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break;
-
- case ISD::STORE: Res = PromoteOperand_STORE(cast<StoreSDNode>(N),
- OpNo); break;
-
- case ISD::BUILD_VECTOR: Res = PromoteOperand_BUILD_VECTOR(N); break;
- case ISD::INSERT_VECTOR_ELT:
- Res = PromoteOperand_INSERT_VECTOR_ELT(N, OpNo);
- break;
-
- case ISD::RET: Res = PromoteOperand_RET(N, OpNo); break;
-
- case ISD::MEMBARRIER: Res = PromoteOperand_MEMBARRIER(N); break;
- }
-
- // If the result is null, the sub-method took care of registering results etc.
- if (!Res.Val) return false;
- // If the result is N, the sub-method updated N in place.
- if (Res.Val == N) {
- // Mark N as new and remark N and its operands. This allows us to correctly
- // revisit N if it needs another step of promotion and allows us to visit
- // any new operands to N.
- ReanalyzeNode(N);
- return true;
- }
-
- assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
- "Invalid operand expansion");
-
- ReplaceValueWith(SDOperand(N, 0), Res);
- return false;
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
- return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
- return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
- Op, DAG.getValueType(N->getOperand(0).getValueType()));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) {
- SDOperand Op = GetPromotedOp(N->getOperand(0));
- return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
- DAG.getIntPtrConstant(0));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) {
- SDOperand In = GetPromotedOp(N->getOperand(0));
- MVT OpVT = N->getOperand(0).getValueType();
- if (N->getOpcode() == ISD::UINT_TO_FP)
- In = DAG.getZeroExtendInReg(In, OpVT);
- else
- In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(),
- In, DAG.getValueType(OpVT));
-
- return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_PAIR(SDNode *N) {
- // Since the result type is legal, the operands must promote to it.
- MVT OVT = N->getOperand(0).getValueType();
- SDOperand Lo = GetPromotedOp(N->getOperand(0));
- SDOperand Hi = GetPromotedOp(N->getOperand(1));
- assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
-
- Lo = DAG.getZeroExtendInReg(Lo, OVT);
- Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
- DAG.getConstant(OVT.getSizeInBits(),
- TLI.getShiftAmountTy()));
- return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
- assert(OpNo == 0 && "Only know how to promote condition");
- SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition.
-
- // The top bits of the promoted condition are not necessarily zero, ensure
- // that the value is properly zero extended.
- unsigned BitWidth = Cond.getValueSizeInBits();
- if (!DAG.MaskedValueIsZero(Cond,
- APInt::getHighBitsSet(BitWidth, BitWidth-1)))
- Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
-
- // The chain (Op#0) and basic block destination (Op#2) are always legal types.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
- N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
- assert(OpNo == 1 && "only know how to promote condition");
- SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition.
-
- // The top bits of the promoted condition are not necessarily zero, ensure
- // that the value is properly zero extended.
- unsigned BitWidth = Cond.getValueSizeInBits();
- if (!DAG.MaskedValueIsZero(Cond,
- APInt::getHighBitsSet(BitWidth, BitWidth-1)))
- Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
-
- // The chain (Op#0) and basic block destination (Op#2) are always legal types.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
- N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) {
- assert(OpNo == 2 && "Don't know how to promote this operand");
-
- SDOperand LHS = N->getOperand(2);
- SDOperand RHS = N->getOperand(3);
- PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
-
- // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
- // legal types.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
- N->getOperand(1), LHS, RHS, N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) {
- assert(OpNo == 0 && "Don't know how to promote this operand");
-
- SDOperand LHS = N->getOperand(0);
- SDOperand RHS = N->getOperand(1);
- PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
-
- // The CC (#2) is always legal.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2));
-}
-
-/// PromoteSetCCOperands - Promote the operands of a comparison. This code is
-/// shared among BR_CC, SELECT_CC, and SETCC handlers.
-void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
- ISD::CondCode CCCode) {
- MVT VT = NewLHS.getValueType();
-
- // Get the promoted values.
- NewLHS = GetPromotedOp(NewLHS);
- NewRHS = GetPromotedOp(NewRHS);
-
- // If this is an FP compare, the operands have already been extended.
- if (!NewLHS.getValueType().isInteger())
- return;
-
- // Otherwise, we have to insert explicit sign or zero extends. Note
- // that we could insert sign extends for ALL conditions, but zero extend
- // is cheaper on many machines (an AND instead of two shifts), so prefer
- // it.
- switch (CCCode) {
- default: assert(0 && "Unknown integer comparison!");
- case ISD::SETEQ:
- case ISD::SETNE:
- case ISD::SETUGE:
- case ISD::SETUGT:
- case ISD::SETULE:
- case ISD::SETULT:
- // ALL of these operations will work if we either sign or zero extend
- // the operands (including the unsigned comparisons!). Zero extend is
- // usually a simpler/cheaper operation, so prefer it.
- NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
- NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
- return;
- case ISD::SETGE:
- case ISD::SETGT:
- case ISD::SETLT:
- case ISD::SETLE:
- NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
- DAG.getValueType(VT));
- NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
- DAG.getValueType(VT));
- return;
- }
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
- // FIXME: Add support for indexed stores.
- SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
- int SVOffset = N->getSrcValueOffset();
- unsigned Alignment = N->getAlignment();
- bool isVolatile = N->isVolatile();
-
- SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value.
-
- assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
-
- // Truncate the value and store the result.
- return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
- SVOffset, N->getMemoryVT(),
- isVolatile, Alignment);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_VECTOR(SDNode *N) {
- // The vector type is legal but the element type is not. This implies
- // that the vector is a power-of-two in length and that the element
- // type does not have a strange size (eg: it is not i1).
- MVT VecVT = N->getValueType(0);
- unsigned NumElts = VecVT.getVectorNumElements();
- assert(!(NumElts & 1) && "Legal vector of one illegal element?");
-
- // Build a vector of half the length out of elements of twice the bitwidth.
- // For example <4 x i16> -> <2 x i32>.
- MVT OldVT = N->getOperand(0).getValueType();
- MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
- assert(OldVT.isSimple() && NewVT.isSimple());
-
- std::vector<SDOperand> NewElts;
- NewElts.reserve(NumElts/2);
-
- for (unsigned i = 0; i < NumElts; i += 2) {
- // Combine two successive elements into one promoted element.
- SDOperand Lo = N->getOperand(i);
- SDOperand Hi = N->getOperand(i+1);
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
- NewElts.push_back(JoinIntegers(Lo, Hi));
- }
-
- SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
- MVT::getVectorVT(NewVT, NewElts.size()),
- &NewElts[0], NewElts.size());
-
- // Convert the new vector to the old vector type.
- return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_INSERT_VECTOR_ELT(SDNode *N,
- unsigned OpNo) {
- if (OpNo == 1) {
- // Promote the inserted value. This is valid because the type does not
- // have to match the vector element type.
-
- // Check that any extra bits introduced will be truncated away.
- assert(N->getOperand(1).getValueType().getSizeInBits() >=
- N->getValueType(0).getVectorElementType().getSizeInBits() &&
- "Type of inserted value narrower than vector element type!");
- return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
- GetPromotedOp(N->getOperand(1)),
- N->getOperand(2));
- }
-
- assert(OpNo == 2 && "Different operand and result vector types?");
-
- // Promote the index.
- SDOperand Idx = N->getOperand(2);
- Idx = DAG.getZeroExtendInReg(GetPromotedOp(Idx), Idx.getValueType());
- return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
- N->getOperand(1), Idx);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_RET(SDNode *N, unsigned OpNo) {
- assert(!(OpNo & 1) && "Return values should be legally typed!");
- assert((N->getNumOperands() & 1) && "Wrong number of operands!");
-
- // It's a flag. Promote all the flags in one hit, as an optimization.
- SmallVector<SDOperand, 8> NewValues(N->getNumOperands());
- NewValues[0] = N->getOperand(0); // The chain
- for (unsigned i = 1, e = N->getNumOperands(); i < e; i += 2) {
- // The return value.
- NewValues[i] = N->getOperand(i);
-
- // The flag.
- SDOperand Flag = N->getOperand(i + 1);
- if (getTypeAction(Flag.getValueType()) == Promote)
- // The promoted value may have rubbish in the new bits, but that
- // doesn't matter because those bits aren't queried anyway.
- Flag = GetPromotedOp(Flag);
- NewValues[i + 1] = Flag;
- }
-
- return DAG.UpdateNodeOperands(SDOperand (N, 0),
- &NewValues[0], NewValues.size());
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_MEMBARRIER(SDNode *N) {
- SDOperand NewOps[6];
- NewOps[0] = N->getOperand(0);
- for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
- SDOperand Flag = GetPromotedOp(N->getOperand(i));
- NewOps[i] = DAG.getZeroExtendInReg(Flag, MVT::i1);
- }
- return DAG.UpdateNodeOperands(SDOperand (N, 0), NewOps,
- array_lengthof(NewOps));
-}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
deleted file mode 100644
index 9f758ff088..0000000000
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-//===-- LegalizeTypesScalarize.cpp - Scalarization for LegalizeTypes ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements scalarization support for LegalizeTypes. Scalarization
-// is the act of changing a computation in an invalid single-element vector type
-// to be a computation in its scalar element type. For example, implementing
-// <1 x f32> arithmetic in a scalar f32 register. This is needed as a base case
-// when scalarizing vector arithmetic like <4 x f32>, which eventually
-// decomposes to scalars if the target doesn't support v4f32 or v2f32 types.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// Result Vector Scalarization: <1 x ty> -> ty.
-//===----------------------------------------------------------------------===//
-
-void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
- DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
- cerr << "\n");
- SDOperand R = SDOperand();
-
- // FIXME: Custom lowering for scalarization?
-#if 0
- // See if the target wants to custom expand this node.
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
- TargetLowering::Custom) {
- // If the target wants to, allow it to lower this itself.
- if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
- // Everything that once used N now uses P. We are guaranteed that the
- // result value types of N and the result value types of P match.
- ReplaceNodeWith(N, P);
- return;
- }
- }
-#endif
-
- switch (N->getOpcode()) {
- default:
-#ifndef NDEBUG
- cerr << "ScalarizeResult #" << ResNo << ": ";
- N->dump(&DAG); cerr << "\n";
-#endif
- assert(0 && "Do not know how to scalarize the result of this operator!");
- abort();
-
- case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break;
- case ISD::LOAD: R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
- case ISD::ADD:
- case ISD::FADD:
- case ISD::SUB:
- case ISD::FSUB:
- case ISD::MUL:
- case ISD::FMUL:
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::FDIV:
- case ISD::SREM:
- case ISD::UREM:
- case ISD::FREM:
- case ISD::FPOW:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR: R = ScalarizeRes_BinOp(N); break;
- case ISD::FNEG:
- case ISD::FABS:
- case ISD::FSQRT:
- case ISD::FSIN:
- case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break;
- case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break;
- case ISD::BUILD_VECTOR: R = N->getOperand(0); break;
- case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
- case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
- case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break;
- case ISD::SELECT: R = ScalarizeRes_SELECT(N); break;
- }
-
- // If R is null, the sub-method took care of registering the result.
- if (R.Val)
- SetScalarizedOp(SDOperand(N, ResNo), R);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
- return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
- // FIXME: Add support for indexed loads.
- SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(),
- N->getChain(), N->getBasePtr(),
- N->getSrcValue(), N->getSrcValueOffset(),
- N->isVolatile(), N->getAlignment());
-
- // Legalized the chain result - switch anything that used the old chain to
- // use the new one.
- ReplaceValueWith(SDOperand(N, 1), Result.getValue(1));
- return Result;
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
- SDOperand LHS = GetScalarizedOp(N->getOperand(0));
- SDOperand RHS = GetScalarizedOp(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
- SDOperand Op = GetScalarizedOp(N->getOperand(0));
- return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
- SDOperand Op = GetScalarizedOp(N->getOperand(0));
- return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
- // The value to insert may have a wider type than the vector element type,
- // so be sure to truncate it to the element type if necessary.
- SDOperand Op = N->getOperand(1);
- MVT EltVT = N->getValueType(0).getVectorElementType();
- if (Op.getValueType().bitsGT(EltVT))
- Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
- assert(Op.getValueType() == EltVT && "Invalid type for inserted value!");
- return Op;
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
- // Figure out if the scalar is the LHS or RHS and return it.
- SDOperand EltNum = N->getOperand(2).getOperand(0);
- unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
- return GetScalarizedOp(N->getOperand(Op));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
- MVT NewVT = N->getValueType(0).getVectorElementType();
- return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
- SDOperand LHS = GetScalarizedOp(N->getOperand(1));
- return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
- GetScalarizedOp(N->getOperand(2)));
-}
-
-
-//===----------------------------------------------------------------------===//
-// Operand Vector Scalarization <1 x ty> -> ty.
-//===----------------------------------------------------------------------===//
-
-bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
- DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
- cerr << "\n");
- SDOperand Res(0, 0);
-
- // FIXME: Should we support custom lowering for scalarization?
-#if 0
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
- TargetLowering::Custom)
- Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-#endif
-
- if (Res.Val == 0) {
- switch (N->getOpcode()) {
- default:
-#ifndef NDEBUG
- cerr << "ScalarizeOperand Op #" << OpNo << ": ";
- N->dump(&DAG); cerr << "\n";
-#endif
- assert(0 && "Do not know how to scalarize this operator's operand!");
- abort();
-
- case ISD::BIT_CONVERT:
- Res = ScalarizeOp_BIT_CONVERT(N); break;
-
- case ISD::EXTRACT_VECTOR_ELT:
- Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
-
- case ISD::STORE:
- Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
- }
- }
-
- // If the result is null, the sub-method took care of registering results etc.
- if (!Res.Val) return false;
-
- // If the result is N, the sub-method updated N in place. Check to see if any
- // operands are new, and if so, mark them.
- if (Res.Val == N) {
- // Mark N as new and remark N and its operands. This allows us to correctly
- // revisit N if it needs another step of promotion and allows us to visit
- // any new operands to N.
- ReanalyzeNode(N);
- return true;
- }
-
- assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
- "Invalid operand expansion");
-
- ReplaceValueWith(SDOperand(N, 0), Res);
- return false;
-}
-
-/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
-/// to be scalarized, it must be <1 x ty>. Convert the element instead.
-SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
- SDOperand Elt = GetScalarizedOp(N->getOperand(0));
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
-}
-
-/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
-/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
-/// index.
-SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
- return GetScalarizedOp(N->getOperand(0));
-}
-
-/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
-/// scalarized, it must be <1 x ty>. Just store the element.
-SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
- // FIXME: Add support for indexed stores.
- assert(OpNo == 1 && "Do not know how to scalarize this operand!");
- return DAG.getStore(N->getChain(), GetScalarizedOp(N->getOperand(1)),
- N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
- N->isVolatile(), N->getAlignment());
-}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 74aae7f4c8..392a923a10 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1,4 +1,4 @@
-//===-- LegalizeTypesSplit.cpp - Vector Splitting for LegalizeTypes -------===//
+//===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements vector splitting support for LegalizeTypes. Vector
-// splitting is the act of changing a computation in an invalid vector type to
+// This file performs vector type splitting and scalarization for LegalizeTypes.
+// Scalarization is the act of changing a computation in an illegal one-element
+// vector type to be a computation in its scalar element type. For example,
+// implementing <1 x f32> arithmetic in a scalar f32 register. This is needed
+// as a base case when scalarizing vector arithmetic like <4 x f32>, which
+// eventually decomposes to scalars if the target doesn't support v4f32 or v2f32
+// types.
+// Splitting is the act of changing a computation in an invalid vector type to
// be a computation in multiple vectors of a smaller type. For example,
// implementing <128 x f32> operations in terms of two <64 x f32> operations.
//
@@ -17,6 +23,220 @@
#include "LegalizeTypes.h"
using namespace llvm;
+//===----------------------------------------------------------------------===//
+// Result Vector Scalarization: <1 x ty> -> ty.
+//===----------------------------------------------------------------------===//
+
+void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
+ DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
+ cerr << "\n");
+ SDOperand R = SDOperand();
+
+ // FIXME: Custom lowering for scalarization?
+#if 0
+ // See if the target wants to custom expand this node.
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ TargetLowering::Custom) {
+ // If the target wants to, allow it to lower this itself.
+ if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+ // Everything that once used N now uses P. We are guaranteed that the
+ // result value types of N and the result value types of P match.
+ ReplaceNodeWith(N, P);
+ return;
+ }
+ }
+#endif
+
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "ScalarizeResult #" << ResNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to scalarize the result of this operator!");
+ abort();
+
+ case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break;
+ case ISD::LOAD: R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
+ case ISD::ADD:
+ case ISD::FADD:
+ case ISD::SUB:
+ case ISD::FSUB:
+ case ISD::MUL:
+ case ISD::FMUL:
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::FDIV:
+ case ISD::SREM:
+ case ISD::UREM:
+ case ISD::FREM:
+ case ISD::FPOW:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR: R = ScalarizeRes_BinOp(N); break;
+ case ISD::FNEG:
+ case ISD::FABS:
+ case ISD::FSQRT:
+ case ISD::FSIN:
+ case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break;
+ case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break;
+ case ISD::BUILD_VECTOR: R = N->getOperand(0); break;
+ case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
+ case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
+ case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break;
+ case ISD::SELECT: R = ScalarizeRes_SELECT(N); break;
+ }
+
+ // If R is null, the sub-method took care of registering the result.
+ if (R.Val)
+ SetScalarizedVector(SDOperand(N, ResNo), R);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
+ return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
+ // FIXME: Add support for indexed loads.
+ SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(),
+ N->getChain(), N->getBasePtr(),
+ N->getSrcValue(), N->getSrcValueOffset(),
+ N->isVolatile(), N->getAlignment());
+
+ // Legalized the chain result - switch anything that used the old chain to
+ // use the new one.
+ ReplaceValueWith(SDOperand(N, 1), Result.getValue(1));
+ return Result;
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
+ SDOperand LHS = GetScalarizedVector(N->getOperand(0));
+ SDOperand RHS = GetScalarizedVector(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
+ SDOperand Op = GetScalarizedVector(N->getOperand(0));
+ return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
+ SDOperand Op = GetScalarizedVector(N->getOperand(0));
+ return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
+ // The value to insert may have a wider type than the vector element type,
+ // so be sure to truncate it to the element type if necessary.
+ SDOperand Op = N->getOperand(1);
+ MVT EltVT = N->getValueType(0).getVectorElementType();
+ if (Op.getValueType().bitsGT(EltVT))
+ Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
+ assert(Op.getValueType() == EltVT && "Invalid type for inserted value!");
+ return Op;
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
+ // Figure out if the scalar is the LHS or RHS and return it.
+ SDOperand EltNum = N->getOperand(2).getOperand(0);
+ unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
+ return GetScalarizedVector(N->getOperand(Op));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
+ MVT NewVT = N->getValueType(0).getVectorElementType();
+ return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
+ SDOperand LHS = GetScalarizedVector(N->getOperand(1));
+ return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
+ GetScalarizedVector(N->getOperand(2)));
+}
+
+
+//===----------------------------------------------------------------------===//
+// Operand Vector Scalarization <1 x ty> -> ty.
+//===----------------------------------------------------------------------===//
+
+bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
+ DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
+ cerr << "\n");
+ SDOperand Res(0, 0);
+
+ // FIXME: Should we support custom lowering for scalarization?
+#if 0
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ TargetLowering::Custom)
+ Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+#endif
+
+ if (Res.Val == 0) {
+ switch (N->getOpcode()) {
+ default:
+#ifndef NDEBUG
+ cerr << "ScalarizeOperand Op #" << OpNo << ": ";
+ N->dump(&DAG); cerr << "\n";
+#endif
+ assert(0 && "Do not know how to scalarize this operator's operand!");
+ abort();
+
+ case ISD::BIT_CONVERT:
+ Res = ScalarizeOp_BIT_CONVERT(N); break;
+
+ case ISD::EXTRACT_VECTOR_ELT:
+ Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
+
+ case ISD::STORE:
+ Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+ }
+ }
+
+ // If the result is null, the sub-method took care of registering results etc.
+ if (!Res.Val) return false;
+
+ // If the result is N, the sub-method updated N in place. Check to see if any
+ // operands are new, and if so, mark them.
+ if (Res.Val == N) {
+ // Mark N as new and remark N and its operands. This allows us to correctly
+ // revisit N if it needs another step of promotion and allows us to visit
+ // any new operands to N.
+ ReanalyzeNode(N);
+ return true;
+ }
+
+ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+ "Invalid operand expansion");
+
+ ReplaceValueWith(SDOperand(N, 0), Res);
+ return false;
+}
+
+/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
+/// to be scalarized, it must be <1 x ty>. Convert the element instead.
+SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
+ SDOperand Elt = GetScalarizedVector(N->getOperand(0));
+ return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
+}
+
+/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
+/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
+/// index.
+SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+ return GetScalarizedVector(N->getOperand(0));
+}
+
+/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
+/// scalarized, it must be <1 x ty>. Just store the element.
+SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
+ // FIXME: Add support for indexed stores.
+ assert(OpNo == 1 && "Do not know how to scalarize this operand!");
+ return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)),
+ N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
+ N->isVolatile(), N->getAlignment());
+}
+
+
/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector
/// type that needs to be split. This handles non-power of two vectors.
static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) {
@@ -46,10 +266,10 @@ static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) {
void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n");
SDOperand Lo, Hi;
-
+
#if 0
// See if the target wants to custom expand this node.
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
TargetLowering::Custom) {
// If the target wants to, allow it to lower this itself.
if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
@@ -60,7 +280,7 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
}
}
#endif
-
+
switch (N->getOpcode()) {
default:
#ifndef NDEBUG
@@ -69,7 +289,7 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
#endif
assert(0 && "Do not know how to split the result of this operator!");
abort();
-
+
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
case ISD::BUILD_PAIR: SplitRes_BUILD_PAIR(N, Lo, Hi); break;
@@ -109,10 +329,10 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
case ISD::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
}
-
+
// If Lo/Hi is null, the sub-method took care of registering results etc.
if (Lo.Val)
- SetSplitOp(SDOperand(N, ResNo), Lo, Hi);
+ SetSplitVector(SDOperand(N, ResNo), Lo, Hi);
}
void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
@@ -123,19 +343,19 @@ void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
Hi = DAG.getNode(ISD::UNDEF, HiVT);
}
-void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
+void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
SDOperand &Lo, SDOperand &Hi) {
// FIXME: Add support for indexed loads.
MVT LoVT, HiVT;
GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
-
+
SDOperand Ch = LD->getChain();
SDOperand Ptr = LD->getBasePtr();
const Value *SV = LD->getSrcValue();
int SVOffset = LD->getSrcValueOffset();
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
-
+
Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
unsigned IncrementSize = LoVT.getSizeInBits()/8;
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
@@ -143,12 +363,12 @@ void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
-
+
// Build a factor node to remember that this load is independent of the
// other one.
SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
Hi.getValue(1));
-
+
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDOperand(LD, 1), TF);
@@ -165,7 +385,7 @@ void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
SDOperand Vec = N->getOperand(0);
SDOperand Elt = N->getOperand(1);
SDOperand Idx = N->getOperand(2);
- GetSplitOp(Vec, Lo, Hi);
+ GetSplitVector(Vec, Lo, Hi);
if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
unsigned IdxVal = CIdx->getValue();
@@ -195,7 +415,7 @@ void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
}
-void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
+void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Build the low part.
SDOperand Mask = N->getOperand(2);
@@ -206,7 +426,7 @@ void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
unsigned LoNumElts = LoVT.getVectorNumElements();
unsigned NumElements = Mask.getNumOperands();
- // Insert all of the elements from the input that are needed. We use
+ // Insert all of the elements from the input that are needed. We use
// buildvector of extractelement here because the input vectors will have
// to be legalized, so this makes the code simpler.
for (unsigned i = 0; i != LoNumElts; ++i) {
@@ -221,7 +441,7 @@ void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
}
Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
Ops.clear();
-
+
for (unsigned i = LoNumElts; i != NumElements; ++i) {
unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
SDOperand InVec = N->getOperand(0);
@@ -235,19 +455,19 @@ void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
}
-void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
+void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
SDOperand &Hi) {
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
unsigned LoNumElts = LoVT.getVectorNumElements();
SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
-
+
SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
}
-void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
+void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// FIXME: Handle non-power-of-two vectors?
unsigned NumSubvectors = N->getNumOperands() / 2;
@@ -262,12 +482,12 @@ void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
-
+
SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
}
-void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
+void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// We know the result is a vector. The input may be either a vector or a
// scalar value.
@@ -282,16 +502,20 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
default:
assert(false && "Unknown type action!");
case Legal:
- case FloatToInt:
- case Promote:
+ case PromoteInteger:
+ case PromoteFloat:
case Scalarize:
break;
- case Expand:
+ case ExpandInteger:
+ case ExpandFloat:
// A scalar to vector conversion, where the scalar needs expansion.
// If the vector is being split in two then we can just convert the
// expanded pieces.
if (LoVT == HiVT) {
- GetExpandedOp(InOp, Lo, Hi);
+ if (InVT.isInteger())
+ GetExpandedInteger(InOp, Lo, Hi);
+ else
+ GetExpandedFloat(InOp, Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
@@ -302,7 +526,7 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
case Split:
// If the input is a vector that needs to be split, convert each split
// piece of the input now.
- GetSplitOp(InOp, Lo, Hi);
+ GetSplitVector(InOp, Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
return;
@@ -324,10 +548,10 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
SDOperand LHSLo, LHSHi;
- GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
+ GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
SDOperand RHSLo, RHSHi;
- GetSplitOp(N->getOperand(1), RHSLo, RHSHi);
-
+ GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
+
Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo);
Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
}
@@ -337,13 +561,13 @@ void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
- GetSplitOp(N->getOperand(0), Lo, Hi);
+ GetSplitVector(N->getOperand(0), Lo, Hi);
Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
}
void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
- GetSplitOp(N->getOperand(0), Lo, Hi);
+ GetSplitVector(N->getOperand(0), Lo, Hi);
Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
}
@@ -351,9 +575,9 @@ void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
SDOperand LL, LH, RL, RH;
- GetSplitOp(N->getOperand(1), LL, LH);
- GetSplitOp(N->getOperand(2), RL, RH);
-
+ GetSplitVector(N->getOperand(1), LL, LH);
+ GetSplitVector(N->getOperand(2), RL, RH);
+
SDOperand Cond = N->getOperand(0);
Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
@@ -371,13 +595,13 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n");
SDOperand Res(0, 0);
-
+
#if 0
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+ if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
TargetLowering::Custom)
Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
#endif
-
+
if (Res.Val == 0) {
switch (N->getOpcode()) {
default:
@@ -397,10 +621,10 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
case ISD::VECTOR_SHUFFLE: Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
}
}
-
+
// If the result is null, the sub-method took care of registering results etc.
if (!Res.Val) return false;
-
+
// If the result is N, the sub-method updated N in place. Check to see if any
// operands are new, and if so, mark them.
if (Res.Val == N) {
@@ -413,7 +637,7 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
-
+
ReplaceValueWith(SDOperand(N, 0), Res);
return false;
}
@@ -421,23 +645,23 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) {
// FIXME: Add support for indexed stores.
assert(OpNo == 1 && "Can only split the stored value");
-
+
SDOperand Ch = N->getChain();
SDOperand Ptr = N->getBasePtr();
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVol = N->isVolatile();
SDOperand Lo, Hi;
- GetSplitOp(N->getOperand(1), Lo, Hi);
+ GetSplitVector(N->getOperand(1), Lo, Hi);
unsigned IncrementSize = Lo.getValueType().getSizeInBits()/8;
Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment);
-
+
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
-
+
Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
isVol, MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
@@ -448,11 +672,11 @@ SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) {
// FIXME: Returns of gcc generic vectors larger than a legal vector
// type should be returned by reference!
SDOperand Lo, Hi;
- GetSplitOp(N->getOperand(1), Lo, Hi);
+ GetSplitVector(N->getOperand(1), Lo, Hi);
SDOperand Chain = N->getOperand(0); // The chain.
SDOperand Sign = N->getOperand(2); // Signness
-
+
return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
}
@@ -461,7 +685,7 @@ SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
// end up being split all the way down to individual components. Convert the
// split pieces into integers and reassemble.
SDOperand Lo, Hi;
- GetSplitOp(N->getOperand(0), Lo, Hi);
+ GetSplitVector(N->getOperand(0), Lo, Hi);
Lo = BitConvertToInteger(Lo);
Hi = BitConvertToInteger(Hi);
@@ -482,7 +706,7 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!");
SDOperand Lo, Hi;
- GetSplitOp(Vec, Lo, Hi);
+ GetSplitVector(Vec, Lo, Hi);
uint64_t LoElts = Lo.getValueType().getVectorNumElements();
@@ -510,7 +734,7 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
MVT SubVT = N->getValueType(0);
SDOperand Idx = N->getOperand(1);
SDOperand Lo, Hi;
- GetSplitOp(N->getOperand(0), Lo, Hi);
+ GetSplitVector(N->getOperand(0), Lo, Hi);
uint64_t LoElts = Lo.getValueType().getVectorNumElements();
uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();