[llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h
Chris Lattner
lattner at cs.uiuc.edu
Sat Jan 15 23:28:04 PST 2005
Changes in directory llvm/include/llvm/Target:
TargetLowering.h updated: 1.4 -> 1.5
---
Log message:
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.
---
Diffs of the changes: (+68 -21)
Index: llvm/include/llvm/Target/TargetLowering.h
diff -u llvm/include/llvm/Target/TargetLowering.h:1.4 llvm/include/llvm/Target/TargetLowering.h:1.5
--- llvm/include/llvm/Target/TargetLowering.h:1.4 Sat Jan 15 19:10:46 2005
+++ llvm/include/llvm/Target/TargetLowering.h Sun Jan 16 01:27:49 2005
@@ -66,15 +66,29 @@
/// 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 @@
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 @@
/// 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 @@
/// 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 @@
legal_fpimm_iterator legal_fpimm_end() const {
return LegalFPImmediates.end();
}
-
- bool isOperationSupported(unsigned Op, MVT::ValueType VT) {
- return (UnsupportedOps[Op] & (1 << VT)) == 0;
- }
-
- MVT::ValueType getValueType(const Type *Ty) {
+
+ /// getOperationAction - Return how this operation should be
+ LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
+ return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
+ }
+
+ /// 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 @@
/// 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 @@
void addLegalFPImmediate(double Imm) {
LegalFPImmediates.push_back(Imm);
}
-
public:
@@ -235,6 +276,12 @@
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
More information about the llvm-commits
mailing list