aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-01-16 07:27:49 +0000
committerChris Lattner <sabre@nondot.org>2005-01-16 07:27:49 +0000
commit7e5ee4097940d9e3b49b858ffbb3e52b0953fde0 (patch)
tree7f7878fd05c85f27ce7d24325bd3a89d578c6394
parentcd7c1cae1cfad5490e263829fda7308655a76cbb (diff)
Revamp supported ops. Instead of just being supported or not, we now keep
track of how to deal with it, and provide the target with a hook that they can use to legalize arbitrary operations in arbitrary ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19609 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetLowering.h85
1 files changed, 66 insertions, 19 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 47ba940795..4cdfb39c44 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -66,15 +66,29 @@ class TargetLowering {
/// by the system, this holds the same type (e.g. i32 -> i32).
MVT::ValueType TransformToType[MVT::LAST_VALUETYPE];
- unsigned short UnsupportedOps[128];
+ /// OpActions - For each operation and each value type, keep a LegalizeAction
+ /// that indicates how instruction selection should deal with the operation.
+ /// Most 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.
+ unsigned OpActions[128];
std::vector<double> LegalFPImmediates;
std::vector<std::pair<MVT::ValueType,
TargetRegisterClass*> > AvailableRegClasses;
public:
+ /// LegalizeAction - This enum indicates whether operations are valid for a
+ /// target, and if not, what action should be used to make them valid.
+ enum LegalizeAction {
+ 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.
+ Custom, // Use the LowerOperation hook to implement custom lowering.
+ };
+
TargetLowering(TargetMachine &TM);
- virtual ~TargetLowering() {}
+ virtual ~TargetLowering();
TargetMachine &getTargetMachine() const { return TM; }
const TargetData &getTargetData() const { return TD; }
@@ -82,7 +96,7 @@ public:
bool isLittleEndian() const { return IsLittleEndian; }
MVT::ValueType getPointerTy() const { return PointerTy; }
- TargetRegisterClass *getRegClassFor(MVT::ValueType VT) {
+ TargetRegisterClass *getRegClassFor(MVT::ValueType VT) const {
TargetRegisterClass *RC = RegClassForVT[VT];
assert(RC && "This value type is not natively supported!");
return RC;
@@ -91,16 +105,16 @@ public:
/// hasNativeSupportFor - Return true if the target has native support for the
/// specified value type. This means that it has a register that directly
/// holds it without promotions or expansions.
- bool hasNativeSupportFor(MVT::ValueType VT) {
+ bool hasNativeSupportFor(MVT::ValueType VT) const {
return RegClassForVT[VT] != 0;
}
/// getTypeAction - Return how we should legalize values of this type, either
- /// it is already legal (return 0) or we need to promote it to a larger type
- /// (return 1), or we need to expand it into multiple registers of smaller
- /// integer type (return 2).
- unsigned getTypeAction(MVT::ValueType VT) const {
- return (ValueTypeActions >> (2*VT)) & 3;
+ /// 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(MVT::ValueType VT) const {
+ return (LegalizeAction)((ValueTypeActions >> (2*VT)) & 3);
}
unsigned getValueTypeActions() const { return ValueTypeActions; }
@@ -109,7 +123,7 @@ public:
/// returns the larger type to promote to. For types that are larger than the
/// largest integer register, this contains one step in the expansion to get
/// to the smaller register.
- MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) {
+ MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) const {
return TransformToType[VT];
}
@@ -120,12 +134,37 @@ public:
legal_fpimm_iterator legal_fpimm_end() const {
return LegalFPImmediates.end();
}
-
- bool isOperationSupported(unsigned Op, MVT::ValueType VT) {
- return (UnsupportedOps[Op] & (1 << VT)) == 0;
+
+ /// getOperationAction - Return how this operation should be
+ LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
+ return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
}
- MVT::ValueType getValueType(const Type *Ty) {
+ /// hasNativeSupportForOperation - Return true if this operation is legal for
+ /// this type.
+ ///
+ bool hasNativeSupportForOperation(unsigned Op, MVT::ValueType VT) const {
+ return getOperationAction(Op, VT) == Legal;
+ }
+
+ /// getTypeToPromoteTo - If the action for this operation is to promote, this
+ /// method returns the ValueType to promote to.
+ MVT::ValueType getTypeToPromoteTo(unsigned Op, MVT::ValueType VT) const {
+ assert(getOperationAction(Op, VT) == Promote &&
+ "This operation isn't promoted!");
+ MVT::ValueType NVT = VT;
+ do {
+ NVT = (MVT::ValueType)(NVT+1);
+ assert(MVT::isInteger(NVT) == MVT::isInteger(VT) && NVT != MVT::isVoid &&
+ "Didn't find type to promote to!");
+ } while (!hasNativeSupportFor(NVT) ||
+ getOperationAction(Op, NVT) == Promote);
+ return NVT;
+ }
+
+ /// getValueType - Return the MVT::ValueType corresponding to this LLVM type.
+ /// This is fixed by the LLVM operations except for the pointer size.
+ MVT::ValueType getValueType(const Type *Ty) const {
switch (Ty->getTypeID()) {
default: assert(0 && "Unknown type!");
case Type::VoidTyID: return MVT::isVoid;
@@ -171,10 +210,13 @@ protected:
/// this allows us to compute derived properties we expose.
void computeRegisterProperties();
-
- void setOperationUnsupported(unsigned Op, MVT::ValueType VT) {
- assert(VT < 16 && "Too many value types!");
- UnsupportedOps[Op] |= 1 << VT;
+ /// setOperationAction - Indicate that the specified operation does not work
+ /// with the specified type and indicate what to do about it.
+ void setOperationAction(unsigned Op, MVT::ValueType VT,
+ LegalizeAction Action) {
+ assert(VT < 16 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
+ "Table isn't big enough!");
+ OpActions[Op] |= Action << VT*2;
}
/// addLegalFPImmediate - Indicate that this target can instruction select
@@ -182,7 +224,6 @@ protected:
void addLegalFPImmediate(double Imm) {
LegalFPImmediates.push_back(Imm);
}
-
public:
@@ -235,6 +276,12 @@ public:
virtual std::pair<SDOperand, SDOperand>
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG);
+
+ /// LowerOperation - For operations that are unsupported by the target, and
+ /// which are registered to use 'custom' lowering. This callback is invoked.
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation of this aborts.
+ virtual SDOperand LowerOperation(SDOperand Op);
};
} // end llvm namespace