diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 47ba9407957..4cdfb39c44a 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 LegalFPImmediates; std::vector > 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 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