public:
/// This enum indicates whether operations are valid for a target, and if not,
/// what action should be used to make them valid.
- enum LegalizeAction {
+ enum LegalizeAction : uint8_t {
Legal, // The target natively supports this operation.
Promote, // This operation should be executed in a larger type.
Expand, // Try to expand this to other ops, otherwise use a libcall.
/// 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 {
+ enum LegalizeTypeAction : uint8_t {
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.
+ TypeSoftenFloat, // Convert this float to a same size integer type,
+ // if an operation is not supported in target HW.
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.
class ValueTypeActionImpl {
/// 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];
+ LegalizeTypeAction ValueTypeActions[MVT::LAST_VALUETYPE];
public:
ValueTypeActionImpl() {
- std::fill(std::begin(ValueTypeActions), std::end(ValueTypeActions), 0);
+ std::fill(std::begin(ValueTypeActions), std::end(ValueTypeActions),
+ TypeLegal);
}
LegalizeTypeAction getTypeAction(MVT VT) const {
- return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
+ return ValueTypeActions[VT.SimpleTy];
}
void setTypeAction(MVT VT, LegalizeTypeAction Action) {
- unsigned I = VT.SimpleTy;
- ValueTypeActions[I] = Action;
+ ValueTypeActions[VT.SimpleTy] = Action;
}
};
// If a target-specific SDNode requires legalization, require the target
// to provide custom legalization for it.
if (Op > array_lengthof(OpActions[0])) return Custom;
- unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
- return (LegalizeAction)OpActions[I][Op];
+ return OpActions[(unsigned)VT.getSimpleVT().SimpleTy][Op];
}
/// Return true if the specified operation is legal on this target or can be
unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::LAST_VALUETYPE &&
MemI < MVT::LAST_VALUETYPE && "Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[ValI][MemI][ExtType];
+ return LoadExtActions[ValI][MemI][ExtType];
}
/// Return true if the specified load with extension is legal on this target.
unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
assert(ValI < MVT::LAST_VALUETYPE && MemI < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)TruncStoreActions[ValI][MemI];
+ return TruncStoreActions[ValI][MemI];
}
/// Return true if the specified store with truncation is legal on this
/// Remove all register classes.
void clearRegisterClasses() {
- memset(RegClassForVT, 0,MVT::LAST_VALUETYPE * sizeof(TargetRegisterClass*));
+ std::fill(std::begin(RegClassForVT), std::end(RegClassForVT), nullptr);
AvailableRegClasses.clear();
}
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
- OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
+ OpActions[(unsigned)VT.SimpleTy][Op] = Action;
}
/// Indicate that the specified load with extension does not work with the
LegalizeAction Action) {
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValVT.isValid() &&
MemVT.isValid() && "Table isn't big enough!");
- LoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy][ExtType] = (uint8_t)Action;
+ LoadExtActions[(unsigned)ValVT.SimpleTy][MemVT.SimpleTy][ExtType] = Action;
}
/// Indicate that the specified truncating store does not work with the
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
assert(ValVT.isValid() && MemVT.isValid() && "Table isn't big enough!");
- TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
+ TruncStoreActions[(unsigned)ValVT.SimpleTy][MemVT.SimpleTy] = Action;
}
/// Indicate that the specified indexed load does or does not work with the
/// operations are Legal (aka, supported natively by the target), but
/// operations that are not should be described. Note that operations on
/// non-legal value types are not described here.
- uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
+ LegalizeAction OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
/// For each load extension type and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with a load of a
/// specific value type and extension type.
- uint8_t LoadExtActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE]
- [ISD::LAST_LOADEXT_TYPE];
+ LegalizeAction LoadExtActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE]
+ [ISD::LAST_LOADEXT_TYPE];
/// For each value type pair keep a LegalizeAction that indicates whether a
/// truncating store of a specific value type and truncating type is legal.
- uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
+ LegalizeAction TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
/// For each indexed mode and each value type, keep a pair of LegalizeAction
/// that indicates how instruction selection should deal with the load /
/// up the MVT::LAST_VALUETYPE value to the next multiple of 8.
uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 7) / 8];
+protected:
ValueTypeActionImpl ValueTypeActions;
private:
return false;
}
+ /// Return true if the target supports that a subset of CSRs for the given
+ /// machine function is handled explicitly via copies.
+ virtual bool supportSplitCSR(MachineFunction *MF) const {
+ return false;
+ }
+
+ /// Return true if the MachineFunction contains a COPY which would imply
+ /// HasCopyImplyingStackAdjustment.
+ virtual bool hasCopyImplyingStackAdjustment(MachineFunction *MF) const {
+ return false;
+ }
+
+ /// Perform necessary initialization to handle a subset of CSRs explicitly
+ /// via copies. This function is called at the beginning of instruction
+ /// selection.
+ virtual void initializeSplitCSR(MachineBasicBlock *Entry) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// Insert explicit copies in entry and exit blocks. We copy a subset of
+ /// CSRs to virtual registers in the entry block, and copy them back to
+ /// physical registers in the exit blocks. This function is called at the end
+ /// of instruction selection.
+ virtual void insertCopiesSplitCSR(
+ MachineBasicBlock *Entry,
+ const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
+ llvm_unreachable("Not Implemented");
+ }
+
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
// the SelectionDAGBuilder code knows how to lower these.
};
- // Mark inreg arguments for lib-calls. For normal calls this is done by
- // the frontend ABI code.
- virtual void markInRegArguments(SelectionDAG &DAG,
- TargetLowering::ArgListTy &Args) const {
- return;
- }
-
/// This function lowers an abstract call to a function into an actual call.
/// This returns a pair of operands. The first element is the return value
/// for the function (if RetTy is not VoidTy). The second element is the