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.
UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
ZeroOrOneBooleanContent, // All bits zero except for bit 0.
}
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.
uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
}
- LegalizeAction getTypeAction(MVT VT) const {
- return (LegalizeAction)ValueTypeActions[VT.SimpleTy];
+ LegalizeTypeAction getTypeAction(MVT VT) const {
+ return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
}
- void setTypeAction(EVT VT, LegalizeAction Action) {
+ void setTypeAction(EVT VT, LegalizeTypeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
ValueTypeActions[I] = Action;
}
/// 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
/// 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;
}
- LegalizeAction getTypeAction(MVT VT) const {
+ LegalizeTypeAction getTypeAction(MVT VT) const {
return ValueTypeActions.getTypeAction(VT);
}
ValueTypeActionImpl ValueTypeActions;
- typedef std::pair<LegalizeAction, EVT> LegalizeKind;
+ typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
LegalizeKind
getTypeConversion(LLVMContext &Context, EVT VT) const {
assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(TransformToType));
EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy];
- LegalizeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT());
- if (NVT.isSimple() && LA != Legal)
- assert(ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != Promote &&
- "Promote may not follow Expand or Promote");
+ LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT());
+
+ assert((NVT.isSimple() && LA != TypeLegal )?
+ ValueTypeActions.getTypeAction(
+ NVT.getSimpleVT()) != TypePromoteInteger
+ : 1 && "Promote may not follow Expand or Promote");
+
return LegalizeKind(LA, NVT);
}
assert(NVT != VT && "Unable to round integer VT");
LegalizeKind NextStep = getTypeConversion(Context, NVT);
// Avoid multi-step promotion.
- if (NextStep.first == Promote) return NextStep;
+ if (NextStep.first == TypePromoteInteger) return NextStep;
// Return rounded integer type.
- return LegalizeKind(Promote, NVT);
+ return LegalizeKind(TypePromoteInteger, NVT);
}
- return LegalizeKind(Expand,
+ return LegalizeKind(TypeExpandInteger,
EVT::getIntegerVT(Context, VT.getSizeInBits()/2));
}
// Vectors with only one element are always scalarized.
if (NumElts == 1)
- return LegalizeKind(Expand, EltVT);
+ return LegalizeKind(TypeScalarizeVector, EltVT);
// Try to widen the vector until a legal type is found.
// If there is no wider legal type, split the vector.
if (LargerVector == MVT()) break;
// If this type is legal then widen the vector.
- if (ValueTypeActions.getTypeAction(LargerVector) == Legal)
- return LegalizeKind(Promote, LargerVector);
+ if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal)
+ return LegalizeKind(TypeWidenVector, LargerVector);
}
// Widen odd vectors to next power of two.
if (!VT.isPow2VectorType()) {
EVT NVT = VT.getPow2VectorType(Context);
- return LegalizeKind(Promote, NVT);
+ return LegalizeKind(TypeWidenVector, NVT);
}
// Vectors with illegal element types are expanded.
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");
- return LegalizeKind(Legal, VT);
+ return LegalizeKind(TypeLegal, VT);
}
std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses;
assert(false && "Unknown legalize action!");
case TargetLowering::Legal:
return Legal;
- case TargetLowering::Promote:
- // Promote can mean
- // 1) For integers, use a larger integer type (e.g. i8 -> i32).
- // 2) For vectors, use a wider vector type (e.g. v3i32 -> v4i32).
- if (!VT.isVector())
- return PromoteInteger;
+ case TargetLowering::TypePromoteInteger:
+ return PromoteInteger;
+ case TargetLowering::TypeExpandInteger:
+ return ExpandInteger;
+ case TargetLowering::TypeExpandFloat:
+ return ExpandFloat;
+ case TargetLowering::TypeSoftenFloat:
+ return SoftenFloat;
+ case TargetLowering::TypeWidenVector:
return WidenVector;
- 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.isInteger())
- return ExpandInteger;
- if (VT.getSizeInBits() ==
- TLI.getTypeToTransformTo(*DAG.getContext(), VT).getSizeInBits())
- return SoftenFloat;
- return ExpandFloat;
- }
-
- if (VT.getVectorNumElements() == 1)
- return ScalarizeVector;
- return SplitVector;
+ case TargetLowering::TypeScalarizeVector:
+ return ScalarizeVector;
+ case TargetLowering::TypeSplitVector:
+ return SplitVector;
}
}
/// isTypeLegal - Return true if this type is legal on this target.
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.
NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1];
RegisterTypeForVT[ExpandedReg] = (MVT::SimpleValueType)LargestIntReg;
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
} else {
RegisterTypeForVT[IntReg] = TransformToType[IntReg] =
(MVT::SimpleValueType)LegalIntReg;
- ValueTypeActions.setTypeAction(IVT, Promote);
+ ValueTypeActions.setTypeAction(IVT, TypePromoteInteger);
}
}
NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64];
RegisterTypeForVT[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,
NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];
RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[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
NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64];
RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64];
TransformToType[MVT::f32] = MVT::f64;
- ValueTypeActions.setTypeAction(MVT::f32, Promote);
+ ValueTypeActions.setTypeAction(MVT::f32, TypePromoteInteger);
} else {
NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32];
TransformToType[MVT::f32] = MVT::i32;
- ValueTypeActions.setTypeAction(MVT::f32, Expand);
+ ValueTypeActions.setTypeAction(MVT::f32, TypeSoftenFloat);
}
}
TransformToType[i] = SVT;
RegisterTypeForVT[i] = SVT;
NumRegistersForVT[i] = 1;
- ValueTypeActions.setTypeAction(VT, Promote);
+ ValueTypeActions.setTypeAction(VT, TypeWidenVector);
IsLegalWiderType = true;
break;
}
if (NVT == VT) {
// Type is already a power of 2. The default action is to split.
TransformToType[i] = MVT::Other;
- ValueTypeActions.setTypeAction(VT, Expand);
+ unsigned NumElts = VT.getVectorNumElements();
+ ValueTypeActions.setTypeAction(VT,
+ NumElts > 1 ? TypeSplitVector : TypeScalarizeVector);
} else {
TransformToType[i] = NVT;
- ValueTypeActions.setTypeAction(VT, Promote);
+ ValueTypeActions.setTypeAction(VT, TypeWidenVector);
}
}
// 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
// <2 x float> -> <4 x float>.
- if (NumElts != 1 && getTypeAction(Context, VT) == Promote) {
+ if (NumElts != 1 && getTypeAction(Context, VT) == TypeWidenVector) {
RegisterVT = getTypeToTransformTo(Context, VT);
if (isTypeLegal(RegisterVT)) {
IntermediateVT = RegisterVT;