[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