summaryrefslogtreecommitdiff
path: root/include/llvm/Target/TargetLowering.h
blob: 4112db3b645ba70a30346712a02a57b3a0eb8b65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
//===-- llvm/Target/TargetLowering.h - Target Lowering Info -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes how to lower LLVM code to machine code.  This has two
// main components:
//
//  1. Which ValueTypes are natively supported by the target.
//  2. Which operations are supported for supported ValueTypes.
//
// In addition it has a few other components, like information about FP
// immediates.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H

#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include <vector>

namespace llvm {
  class Function;
  class TargetMachine;
  class TargetData;
  class TargetRegisterClass;
  class SDNode;
  class SDOperand;
  class SelectionDAG;

//===----------------------------------------------------------------------===//
/// TargetLowering - This class defines information used to lower LLVM code to
/// legal SelectionDAG operators that the target instruction selector can accept
/// natively.
///
/// This class also defines callbacks that targets must implement to lower
/// target-specific constructs to SelectionDAG operators.
///
class TargetLowering {
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.
  };

  enum OutOfRangeShiftAmount {
    Undefined,  // Oversized shift amounts are undefined (default).
    Mask,       // Shift amounts are auto masked (anded) to value size.
    Extend,     // Oversized shift pulls in zeros or sign bits.
  };

  enum SetCCResultValue {
    UndefinedSetCCResult,          // SetCC returns a garbage/unknown extend.
    ZeroOrOneSetCCResult,          // SetCC returns a zero extended result.
    ZeroOrNegativeOneSetCCResult,  // SetCC returns a sign extended result.
  };

  TargetLowering(TargetMachine &TM);
  virtual ~TargetLowering();

  TargetMachine &getTargetMachine() const { return TM; }
  const TargetData &getTargetData() const { return TD; }

  bool isLittleEndian() const { return IsLittleEndian; }
  MVT::ValueType getPointerTy() const { return PointerTy; }
  MVT::ValueType getShiftAmountTy() const { return ShiftAmountTy; }
  OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; }

  /// isSetCCExpensive - Return true if the setcc operation is expensive for
  /// this target.
  bool isSetCCExpensive() const { return SetCCIsExpensive; }

  /// getSetCCResultTy - Return the ValueType of the result of setcc operations.
  ///
  MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; }

  /// getSetCCResultContents - For targets without boolean registers, this flag
  /// returns information about the contents of the high-bits in the setcc
  /// result register.
  SetCCResultValue getSetCCResultContents() const { return SetCCResultContents;}

  /// getRegClassFor - Return the register class that should be used for the
  /// specified value type.  This may only be called on legal types.
  TargetRegisterClass *getRegClassFor(MVT::ValueType VT) const {
    TargetRegisterClass *RC = RegClassForVT[VT];
    assert(RC && "This value type is not natively supported!");
    return RC;
  }

  /// 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) const {
    return RegClassForVT[VT] != 0;
  }

  /// getTypeAction - Return how we should legalize values of this type, either
  /// 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; }

  /// getTypeToTransformTo - For types supported by the target, this is an
  /// identity function.  For types that must be promoted to larger types, this
  /// 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) const {
    return TransformToType[VT];
  }

  typedef std::vector<double>::const_iterator legal_fpimm_iterator;
  legal_fpimm_iterator legal_fpimm_begin() const {
    return LegalFPImmediates.begin();
  }
  legal_fpimm_iterator legal_fpimm_end() const {
    return LegalFPImmediates.end();
  }

  /// 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;
    case Type::BoolTyID:    return MVT::i1;
    case Type::UByteTyID:
    case Type::SByteTyID:   return MVT::i8;
    case Type::ShortTyID:
    case Type::UShortTyID:  return MVT::i16;
    case Type::IntTyID:
    case Type::UIntTyID:    return MVT::i32;
    case Type::LongTyID:
    case Type::ULongTyID:   return MVT::i64;
    case Type::FloatTyID:   return MVT::f32;
    case Type::DoubleTyID:  return MVT::f64;
    case Type::PointerTyID: return PointerTy;
    }
  }

  /// getNumElements - Return the number of registers that this ValueType will
  /// eventually require.  This is always one for all non-integer types, is
  /// one for any types promoted to live in larger registers, but may be more
  /// than one for types (like i64) that are split into pieces.
  unsigned getNumElements(MVT::ValueType VT) const {
    return NumElementsForVT[VT];
  }

  //===--------------------------------------------------------------------===//
  // TargetLowering Configuration Methods - These methods should be invoked by
  // the derived class constructor to configure this object for the target.
  //

protected:

  /// setShiftAmountType - Describe the type that should be used for shift
  /// amounts.  This type defaults to the pointer type.
  void setShiftAmountType(MVT::ValueType VT) { ShiftAmountTy = VT; }

  /// setSetCCResultType - Describe the type that shoudl be used as the result
  /// of a setcc operation.  This defaults to the pointer type.
  void setSetCCResultType(MVT::ValueType VT) { SetCCResultTy = VT; }

  /// setSetCCResultContents - Specify how the target extends the result of a
  /// setcc operation in a register.
  void setSetCCResultContents(SetCCResultValue Ty) { SetCCResultContents = Ty; }

  /// setShiftAmountFlavor - Describe how the target handles out of range shift
  /// amounts.
  void setShiftAmountFlavor(OutOfRangeShiftAmount OORSA) {
    ShiftAmtHandling = OORSA;
  }

  /// setSetCCIxExpensive - This is a short term hack for targets that codegen
  /// setcc as a conditional branch.  This encourages the code generator to fold
  /// setcc operations into other operations if possible.
  void setSetCCIsExpensive() { SetCCIsExpensive = true; }

  /// addRegisterClass - Add the specified register class as an available
  /// regclass for the specified value type.  This indicates the selector can
  /// handle values of that class natively.
  void addRegisterClass(MVT::ValueType VT, TargetRegisterClass *RC) {
    AvailableRegClasses.push_back(std::make_pair(VT, RC));
    RegClassForVT[VT] = RC;
  }

  /// computeRegisterProperties - Once all of the register classes are added,
  /// this allows us to compute derived properties we expose.
  void computeRegisterProperties();

  /// 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
  /// the specified FP immediate natively.
  void addLegalFPImmediate(double Imm) {
    LegalFPImmediates.push_back(Imm);
  }

public:

  //===--------------------------------------------------------------------===//
  // Lowering methods - These methods must be implemented by targets so that
  // the SelectionDAGLowering code knows how to lower these.
  //

  /// LowerArguments - This hook must be implemented to indicate how we should
  /// lower the arguments for the specified function, into the specified DAG.
  virtual std::vector<SDOperand>
  LowerArguments(Function &F, SelectionDAG &DAG) = 0;

  /// LowerCallTo - This hook 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 outgoing token chain.
  typedef std::vector<std::pair<SDOperand, const Type*> > ArgListTy;
  virtual std::pair<SDOperand, SDOperand>
  LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
              unsigned CallingConv, bool isTailCall, SDOperand Callee,
              ArgListTy &Args, SelectionDAG &DAG) = 0;

  /// LowerVAStart - This lowers the llvm.va_start intrinsic.  If not
  /// implemented, this method prints a message and aborts.
  virtual std::pair<SDOperand, SDOperand>
  LowerVAStart(SDOperand Chain, SelectionDAG &DAG);

  /// LowerVAEnd - This lowers llvm.va_end and returns the resultant chain.  If
  /// not implemented, this defaults to a noop.
  virtual SDOperand LowerVAEnd(SDOperand Chain, SDOperand L, SelectionDAG &DAG);

  /// LowerVACopy - This lowers llvm.va_copy and returns the resultant
  /// value/chain pair.  If not implemented, this defaults to returning the
  /// input operand.
  virtual std::pair<SDOperand,SDOperand>
  LowerVACopy(SDOperand Chain, SDOperand L, SelectionDAG &DAG);

  /// LowerVAArgNext - This lowers the vaarg and vanext instructions (depending
  /// on whether the first argument is true).  If not implemented, this prints a
  /// message and aborts.
  virtual std::pair<SDOperand,SDOperand>
  LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
                 const Type *ArgTy, SelectionDAG &DAG);

  /// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or
  /// llvm.frameaddress (depending on the value of the first argument).  The
  /// return values are the result pointer and the resultant token chain.  If
  /// not implemented, both of these intrinsics will return null.
  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);


private:
  TargetMachine &TM;
  const TargetData &TD;

  /// IsLittleEndian - True if this is a little endian target.
  ///
  bool IsLittleEndian;

  /// PointerTy - The type to use for pointers, usually i32 or i64.
  ///
  MVT::ValueType PointerTy;

  /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
  /// PointerTy is.
  MVT::ValueType ShiftAmountTy;

  OutOfRangeShiftAmount ShiftAmtHandling;

  /// SetCCIsExpensive - This is a short term hack for targets that codegen
  /// setcc as a conditional branch.  This encourages the code generator to fold
  /// setcc operations into other operations if possible.
  bool SetCCIsExpensive;

  /// SetCCResultTy - The type that SetCC operations use.  This defaults to the
  /// PointerTy.
  MVT::ValueType SetCCResultTy;

  /// SetCCResultContents - Information about the contents of the high-bits in
  /// the result of a setcc comparison operation.
  SetCCResultValue SetCCResultContents;

  /// RegClassForVT - This indicates the default register class to use for
  /// each ValueType the target supports natively.
  TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
  unsigned char NumElementsForVT[MVT::LAST_VALUETYPE];

  /// ValueTypeActions - This is a bitvector that contains two bits for each
  /// value type, where the two bits correspond to the LegalizeAction enum.
  /// This can be queried with "getTypeAction(VT)".
  unsigned ValueTypeActions;

  /// TransformToType - For any value types we are promoting or expanding, this
  /// contains the value type that we are changing to.  For Expanded types, this
  /// contains one step of the expand (e.g. i64 -> i32), even if there are
  /// multiple steps required (e.g. i64 -> i16).  For types natively supported
  /// by the system, this holds the same type (e.g. i32 -> i32).
  MVT::ValueType TransformToType[MVT::LAST_VALUETYPE];

  /// 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;
};
} // end llvm namespace

#endif