aboutsummaryrefslogtreecommitdiffstats
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
commit1947a38d00ef1c405ca32611f5443e91814ca5d4 (patch)
tree5d1ea52d6c49439229957559901114b55b955cb1
parent21d678009509964af354d5b1e3572db2929b2b17 (diff)
downloadexternal_llvm-1947a38d00ef1c405ca32611f5443e91814ca5d4.zip
external_llvm-1947a38d00ef1c405ca32611f5443e91814ca5d4.tar.gz
external_llvm-1947a38d00ef1c405ca32611f5443e91814ca5d4.tar.bz2
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
-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 c3bde9b..d4e5a45 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 76bbd81..4b927fe 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 5b37c75..e469f25 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 ba8f106..a472a29 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 5c68fe2..0000000
--- 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 9f758ff..0000000
--- 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 74aae7f..392a923 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();