Refactor the type legalizer. Switch TargetLowering to a new enum - LegalizeTypeAction.

This patch does not change the behavior of the type legalizer. The codegen
produces the same code.
This infrastructural change is needed in order to enable complex decisions
for vector types (needed by the vector-select patch).




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132263 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nadav Rotem
2011-05-28 17:57:14 +00:00
parent 33858016ea
commit b6aacae941
3 changed files with 62 additions and 53 deletions

View File

@@ -94,6 +94,19 @@ public:
Custom // Use the LowerOperation hook to implement custom lowering. Custom // Use the LowerOperation hook to implement custom lowering.
}; };
/// LegalizeAction - This enum indicates whether a types are legal for a
/// target, and if not, what action should be used to make them valid.
enum LegalizeTypeAction {
TypeLegal, // The target natively supports this type.
TypePromoteInteger, // Replace this integer with a larger one.
TypeExpandInteger, // Split this integer into two of half the size.
TypeSoftenFloat, // Convert this float to a same size integer type.
TypeExpandFloat, // Split this float into two of half the size.
TypeScalarizeVector, // Replace this one-element vector with its element.
TypeSplitVector, // Split this vector into two of half the size.
TypeWidenVector // This vector should be widened into a larger vector.
};
enum BooleanContent { // How the target represents true/false values. enum BooleanContent { // How the target represents true/false values.
UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage. UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
ZeroOrOneBooleanContent, // All bits zero except for bit 0. ZeroOrOneBooleanContent, // All bits zero except for bit 0.
@@ -200,7 +213,7 @@ public:
} }
class ValueTypeActionImpl { class ValueTypeActionImpl {
/// ValueTypeActions - For each value type, keep a LegalizeAction enum /// ValueTypeActions - For each value type, keep a LegalizeTypeAction enum
/// that indicates how instruction selection should deal with the type. /// that indicates how instruction selection should deal with the type.
uint8_t ValueTypeActions[MVT::LAST_VALUETYPE]; uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
@@ -209,11 +222,11 @@ public:
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
} }
LegalizeAction getTypeAction(MVT VT) const { LegalizeTypeAction getTypeAction(MVT VT) const {
return (LegalizeAction)ValueTypeActions[VT.SimpleTy]; return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
} }
void setTypeAction(EVT VT, LegalizeAction Action) { void setTypeAction(EVT VT, LegalizeTypeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy; unsigned I = VT.getSimpleVT().SimpleTy;
ValueTypeActions[I] = Action; ValueTypeActions[I] = Action;
} }
@@ -227,10 +240,10 @@ public:
/// it is already legal (return 'Legal') or we need to promote it to a larger /// it is already legal (return 'Legal') or we need to promote it to a larger
/// type (return 'Promote'), or we need to expand it into multiple registers /// type (return 'Promote'), or we need to expand it into multiple registers
/// of smaller integer type (return 'Expand'). 'Custom' is not an option. /// of smaller integer type (return 'Expand'). 'Custom' is not an option.
LegalizeAction getTypeAction(LLVMContext &Context, EVT VT) const { LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const {
return getTypeConversion(Context, VT).first; return getTypeConversion(Context, VT).first;
} }
LegalizeAction getTypeAction(MVT VT) const { LegalizeTypeAction getTypeAction(MVT VT) const {
return ValueTypeActions.getTypeAction(VT); return ValueTypeActions.getTypeAction(VT);
} }
@@ -1732,7 +1745,7 @@ private:
ValueTypeActionImpl ValueTypeActions; ValueTypeActionImpl ValueTypeActions;
typedef std::pair<LegalizeAction, EVT> LegalizeKind; typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
LegalizeKind LegalizeKind
getTypeConversion(LLVMContext &Context, EVT VT) const { getTypeConversion(LLVMContext &Context, EVT VT) const {
@@ -1741,10 +1754,13 @@ private:
assert((unsigned)VT.getSimpleVT().SimpleTy < assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(TransformToType)); array_lengthof(TransformToType));
EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy];
LegalizeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT()); LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT());
if (NVT.isSimple() && LA != Legal)
assert(ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != Promote && assert((NVT.isSimple() && LA != TypeLegal )?
"Promote may not follow Expand or Promote"); ValueTypeActions.getTypeAction(
NVT.getSimpleVT()) != TypePromoteInteger
: 1 && "Promote may not follow Expand or Promote");
return LegalizeKind(LA, NVT); return LegalizeKind(LA, NVT);
} }
@@ -1758,12 +1774,12 @@ private:
assert(NVT != VT && "Unable to round integer VT"); assert(NVT != VT && "Unable to round integer VT");
LegalizeKind NextStep = getTypeConversion(Context, NVT); LegalizeKind NextStep = getTypeConversion(Context, NVT);
// Avoid multi-step promotion. // Avoid multi-step promotion.
if (NextStep.first == Promote) return NextStep; if (NextStep.first == TypePromoteInteger) return NextStep;
// Return rounded integer type. // Return rounded integer type.
return LegalizeKind(Promote, NVT); return LegalizeKind(TypePromoteInteger, NVT);
} }
return LegalizeKind(Expand, return LegalizeKind(TypeExpandInteger,
EVT::getIntegerVT(Context, VT.getSizeInBits()/2)); EVT::getIntegerVT(Context, VT.getSizeInBits()/2));
} }
@@ -1773,7 +1789,7 @@ private:
// Vectors with only one element are always scalarized. // Vectors with only one element are always scalarized.
if (NumElts == 1) if (NumElts == 1)
return LegalizeKind(Expand, EltVT); return LegalizeKind(TypeScalarizeVector, EltVT);
// Try to widen the vector until a legal type is found. // Try to widen the vector until a legal type is found.
// If there is no wider legal type, split the vector. // If there is no wider legal type, split the vector.
@@ -1788,22 +1804,22 @@ private:
if (LargerVector == MVT()) break; if (LargerVector == MVT()) break;
// If this type is legal then widen the vector. // If this type is legal then widen the vector.
if (ValueTypeActions.getTypeAction(LargerVector) == Legal) if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal)
return LegalizeKind(Promote, LargerVector); return LegalizeKind(TypeWidenVector, LargerVector);
} }
// Widen odd vectors to next power of two. // Widen odd vectors to next power of two.
if (!VT.isPow2VectorType()) { if (!VT.isPow2VectorType()) {
EVT NVT = VT.getPow2VectorType(Context); EVT NVT = VT.getPow2VectorType(Context);
return LegalizeKind(Promote, NVT); return LegalizeKind(TypeWidenVector, NVT);
} }
// Vectors with illegal element types are expanded. // Vectors with illegal element types are expanded.
EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2);
return LegalizeKind(Expand, NVT); return LegalizeKind(TypeSplitVector, NVT);
assert(false && "Unable to handle this kind of vector type"); assert(false && "Unable to handle this kind of vector type");
return LegalizeKind(Legal, VT); return LegalizeKind(TypeLegal, VT);
} }
std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses; std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses;

View File

@@ -80,35 +80,26 @@ private:
assert(false && "Unknown legalize action!"); assert(false && "Unknown legalize action!");
case TargetLowering::Legal: case TargetLowering::Legal:
return Legal; return Legal;
case TargetLowering::Promote: case TargetLowering::TypePromoteInteger:
// Promote can mean return PromoteInteger;
// 1) For integers, use a larger integer type (e.g. i8 -> i32). case TargetLowering::TypeExpandInteger:
// 2) For vectors, use a wider vector type (e.g. v3i32 -> v4i32). return ExpandInteger;
if (!VT.isVector()) case TargetLowering::TypeExpandFloat:
return PromoteInteger; return ExpandFloat;
case TargetLowering::TypeSoftenFloat:
return SoftenFloat;
case TargetLowering::TypeWidenVector:
return WidenVector; return WidenVector;
case TargetLowering::Expand: case TargetLowering::TypeScalarizeVector:
// Expand can mean return ScalarizeVector;
// 1) split scalar in half, 2) convert a float to an integer, case TargetLowering::TypeSplitVector:
// 3) scalarize a single-element vector, 4) split a vector in two. return SplitVector;
if (!VT.isVector()) {
if (VT.isInteger())
return ExpandInteger;
if (VT.getSizeInBits() ==
TLI.getTypeToTransformTo(*DAG.getContext(), VT).getSizeInBits())
return SoftenFloat;
return ExpandFloat;
}
if (VT.getVectorNumElements() == 1)
return ScalarizeVector;
return SplitVector;
} }
} }
/// isTypeLegal - Return true if this type is legal on this target. /// isTypeLegal - Return true if this type is legal on this target.
bool isTypeLegal(EVT VT) const { bool isTypeLegal(EVT VT) const {
return TLI.getTypeAction(*DAG.getContext(), VT) == TargetLowering::Legal; return TLI.getTypeAction(*DAG.getContext(), VT) == TargetLowering::TypeLegal;
} }
/// IgnoreNodeResults - Pretend all of this node's results are legal. /// IgnoreNodeResults - Pretend all of this node's results are legal.

View File

@@ -749,7 +749,7 @@ void TargetLowering::computeRegisterProperties() {
NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1]; NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1];
RegisterTypeForVT[ExpandedReg] = (MVT::SimpleValueType)LargestIntReg; RegisterTypeForVT[ExpandedReg] = (MVT::SimpleValueType)LargestIntReg;
TransformToType[ExpandedReg] = (MVT::SimpleValueType)(ExpandedReg - 1); TransformToType[ExpandedReg] = (MVT::SimpleValueType)(ExpandedReg - 1);
ValueTypeActions.setTypeAction(ExpandedVT, Expand); ValueTypeActions.setTypeAction(ExpandedVT, TypeExpandInteger);
} }
// Inspect all of the ValueType's smaller than the largest integer // Inspect all of the ValueType's smaller than the largest integer
@@ -763,7 +763,7 @@ void TargetLowering::computeRegisterProperties() {
} else { } else {
RegisterTypeForVT[IntReg] = TransformToType[IntReg] = RegisterTypeForVT[IntReg] = TransformToType[IntReg] =
(MVT::SimpleValueType)LegalIntReg; (MVT::SimpleValueType)LegalIntReg;
ValueTypeActions.setTypeAction(IVT, Promote); ValueTypeActions.setTypeAction(IVT, TypePromoteInteger);
} }
} }
@@ -772,7 +772,7 @@ void TargetLowering::computeRegisterProperties() {
NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64]; NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64];
RegisterTypeForVT[MVT::ppcf128] = MVT::f64; RegisterTypeForVT[MVT::ppcf128] = MVT::f64;
TransformToType[MVT::ppcf128] = MVT::f64; TransformToType[MVT::ppcf128] = MVT::f64;
ValueTypeActions.setTypeAction(MVT::ppcf128, Expand); ValueTypeActions.setTypeAction(MVT::ppcf128, TypeExpandFloat);
} }
// Decide how to handle f64. If the target does not have native f64 support, // Decide how to handle f64. If the target does not have native f64 support,
@@ -781,7 +781,7 @@ void TargetLowering::computeRegisterProperties() {
NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64]; NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];
RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64]; RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64];
TransformToType[MVT::f64] = MVT::i64; TransformToType[MVT::f64] = MVT::i64;
ValueTypeActions.setTypeAction(MVT::f64, Expand); ValueTypeActions.setTypeAction(MVT::f64, TypeSoftenFloat);
} }
// Decide how to handle f32. If the target does not have native support for // Decide how to handle f32. If the target does not have native support for
@@ -791,12 +791,12 @@ void TargetLowering::computeRegisterProperties() {
NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64]; NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64];
RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64]; RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64];
TransformToType[MVT::f32] = MVT::f64; TransformToType[MVT::f32] = MVT::f64;
ValueTypeActions.setTypeAction(MVT::f32, Promote); ValueTypeActions.setTypeAction(MVT::f32, TypePromoteInteger);
} else { } else {
NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32]; NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32]; RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32];
TransformToType[MVT::f32] = MVT::i32; TransformToType[MVT::f32] = MVT::i32;
ValueTypeActions.setTypeAction(MVT::f32, Expand); ValueTypeActions.setTypeAction(MVT::f32, TypeSoftenFloat);
} }
} }
@@ -820,7 +820,7 @@ void TargetLowering::computeRegisterProperties() {
TransformToType[i] = SVT; TransformToType[i] = SVT;
RegisterTypeForVT[i] = SVT; RegisterTypeForVT[i] = SVT;
NumRegistersForVT[i] = 1; NumRegistersForVT[i] = 1;
ValueTypeActions.setTypeAction(VT, Promote); ValueTypeActions.setTypeAction(VT, TypeWidenVector);
IsLegalWiderType = true; IsLegalWiderType = true;
break; break;
} }
@@ -840,10 +840,12 @@ void TargetLowering::computeRegisterProperties() {
if (NVT == VT) { if (NVT == VT) {
// Type is already a power of 2. The default action is to split. // Type is already a power of 2. The default action is to split.
TransformToType[i] = MVT::Other; TransformToType[i] = MVT::Other;
ValueTypeActions.setTypeAction(VT, Expand); unsigned NumElts = VT.getVectorNumElements();
ValueTypeActions.setTypeAction(VT,
NumElts > 1 ? TypeSplitVector : TypeScalarizeVector);
} else { } else {
TransformToType[i] = NVT; TransformToType[i] = NVT;
ValueTypeActions.setTypeAction(VT, Promote); ValueTypeActions.setTypeAction(VT, TypeWidenVector);
} }
} }
@@ -892,7 +894,7 @@ unsigned TargetLowering::getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
// If there is a wider vector type with the same element type as this one, // If there is a wider vector type with the same element type as this one,
// we should widen to that legal vector type. This handles things like // we should widen to that legal vector type. This handles things like
// <2 x float> -> <4 x float>. // <2 x float> -> <4 x float>.
if (NumElts != 1 && getTypeAction(Context, VT) == Promote) { if (NumElts != 1 && getTypeAction(Context, VT) == TypeWidenVector) {
RegisterVT = getTypeToTransformTo(Context, VT); RegisterVT = getTypeToTransformTo(Context, VT);
if (isTypeLegal(RegisterVT)) { if (isTypeLegal(RegisterVT)) {
IntermediateVT = RegisterVT; IntermediateVT = RegisterVT;