#include "llvm/Constants.h"
#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/STLExtras.h"
#include <map>
#include <vector>
namespace llvm {
+ class AllocaInst;
class Function;
+ class FastISel;
class MachineBasicBlock;
+ class MachineFunction;
class MachineFrameInfo;
class MachineInstr;
+ class MachineModuleInfo;
class SDNode;
- class SDOperand;
+ class SDValue;
class SelectionDAG;
class TargetData;
class TargetMachine;
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.
+ enum BooleanContent { // How the target represents true/false values.
+ UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
+ ZeroOrOneBooleanContent, // All bits zero except for bit 0.
+ ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
enum SchedPreference {
/// getSetCCResultType - Return the ValueType of the result of setcc
/// operations.
- virtual MVT getSetCCResultType(const SDOperand &) const;
+ virtual MVT getSetCCResultType(const SDValue &) const;
- /// 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;}
+ /// getBooleanContents - For targets without i1 registers, this gives the
+ /// nature of the high-bits of boolean values held in types wider than i1.
+ /// "Boolean values" are special true/false values produced by nodes like
+ /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND.
+ /// Not to be confused with general values promoted from i1.
+ BooleanContent getBooleanContents() const { return BooleanContents;}
/// getSchedulingPreference - Return target scheduling preference.
SchedPreference getSchedulingPreference() const {
assert(RC && "This value type is not natively supported!");
return RC;
}
-
+
/// isTypeLegal - 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.
LegalizeAction getTypeAction(MVT VT) const {
if (VT.isExtended()) {
- if (VT.isVector()) return Expand;
+ if (VT.isVector()) {
+ // First try vector widening
+ return Promote;
+ }
if (VT.isInteger())
// First promote to a power-of-two size, then expand if necessary.
return VT == VT.getRoundIntegerType() ? Expand : Promote;
const ValueTypeActionImpl &getValueTypeActions() const {
return ValueTypeActions;
}
-
+
/// 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
return NVT;
}
- if (VT.isVector())
- return MVT::getVectorVT(VT.getVectorElementType(),
- VT.getVectorNumElements() / 2);
- if (VT.isInteger()) {
+ if (VT.isVector()) {
+ unsigned NumElts = VT.getVectorNumElements();
+ MVT EltVT = VT.getVectorElementType();
+ return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ } else if (VT.isInteger()) {
MVT NVT = VT.getRoundIntegerType();
if (NVT == VT)
// Size is a power of two - expand to half the size.
MVT &IntermediateVT,
unsigned &NumIntermediates,
MVT &RegisterVT) const;
-
+
+ /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
+ /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
+ /// this is the case, it returns true and store the intrinsic
+ /// information into the IntrinsicInfo that was passed to the function.
+ typedef struct IntrinsicInfo {
+ unsigned opc; // target opcode
+ MVT memVT; // memory VT
+ const Value* ptrVal; // value representing memory location
+ int offset; // offset off of ptrVal
+ unsigned align; // alignment
+ bool vol; // is volatile?
+ bool readMem; // reads memory?
+ bool writeMem; // writes memory?
+ } IntrinisicInfo;
+
+ virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info,
+ CallInst &I, unsigned Intrinsic) {
+ return false;
+ }
+
+ /// getWidenVectorType: given a vector type, returns the type to widen to
+ /// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
+ /// If there is no vector type that we want to widen to, returns MVT::Other
+ /// When and were to widen is target dependent based on the cost of
+ /// scalarizing vs using the wider vector type.
+ virtual MVT getWidenVectorType(MVT VT);
+
typedef std::vector<APFloat>::const_iterator legal_fpimm_iterator;
legal_fpimm_iterator legal_fpimm_begin() const {
return LegalFPImmediates.begin();
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
/// are assumed to be legal.
- virtual bool isShuffleMaskLegal(SDOperand Mask, MVT VT) const {
+ virtual bool isShuffleMaskLegal(SDValue Mask, MVT VT) const {
return true;
}
/// used by Targets can use this to indicate if there is a suitable
/// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
/// pool entry.
- virtual bool isVectorClearMaskLegal(const std::vector<SDOperand> &BVOps,
+ virtual bool isVectorClearMaskLegal(const std::vector<SDValue> &BVOps,
MVT EVT,
SelectionDAG &DAG) const {
return false;
"Table isn't big enough!");
return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3);
}
-
+
/// isOperationLegal - Return true if the specified operation is legal on this
/// target.
bool isOperationLegal(unsigned Op, MVT VT) const {
- return getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Custom;
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom);
}
-
- /// getLoadXAction - Return how this load with extension should be treated:
+
+ /// getLoadExtAction - Return how this load with extension should be treated:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
- LegalizeAction getLoadXAction(unsigned LType, MVT VT) const {
- assert(LType < array_lengthof(LoadXActions) &&
- (unsigned)VT.getSimpleVT() < sizeof(LoadXActions[0])*4 &&
+ LegalizeAction getLoadExtAction(unsigned LType, MVT VT) const {
+ assert(LType < array_lengthof(LoadExtActions) &&
+ (unsigned)VT.getSimpleVT() < sizeof(LoadExtActions[0])*4 &&
"Table isn't big enough!");
- return (LegalizeAction)((LoadXActions[LType] >> (2*VT.getSimpleVT())) & 3);
+ return (LegalizeAction)((LoadExtActions[LType] >> (2*VT.getSimpleVT())) & 3);
}
-
- /// isLoadXLegal - Return true if the specified load with extension is legal
+
+ /// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
- bool isLoadXLegal(unsigned LType, MVT VT) const {
+ bool isLoadExtLegal(unsigned LType, MVT VT) const {
return VT.isSimple() &&
- (getLoadXAction(LType, VT) == Legal ||
- getLoadXAction(LType, VT) == Custom);
+ (getLoadExtAction(LType, VT) == Legal ||
+ getLoadExtAction(LType, VT) == Custom);
}
-
+
/// getTruncStoreAction - Return how this store with truncation should be
/// treated: either it is legal, needs to be promoted to a larger size, needs
/// to be expanded to some other code sequence, or the target has a custom
return (LegalizeAction)((TruncStoreActions[ValVT.getSimpleVT()] >>
(2*MemVT.getSimpleVT())) & 3);
}
-
+
/// isTruncStoreLegal - Return true if the specified store with truncation is
/// legal on this target.
bool isTruncStoreLegal(MVT ValVT, MVT MemVT) const {
- return MemVT.isSimple() &&
+ return isTypeLegal(ValVT) && MemVT.isSimple() &&
(getTruncStoreAction(ValVT, MemVT) == Legal ||
getTruncStoreAction(ValVT, MemVT) == Custom);
}
/// isIndexedLoadLegal - Return true if the specified indexed load is legal
/// on this target.
bool isIndexedLoadLegal(unsigned IdxMode, MVT VT) const {
- return getIndexedLoadAction(IdxMode, VT) == Legal ||
- getIndexedLoadAction(IdxMode, VT) == Custom;
+ return VT.isSimple() &&
+ (getIndexedLoadAction(IdxMode, VT) == Legal ||
+ getIndexedLoadAction(IdxMode, VT) == Custom);
}
-
+
/// getIndexedStoreAction - Return how the indexed store should be treated:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
return (LegalizeAction)((IndexedModeActions[1][IdxMode] >>
(2*VT.getSimpleVT())) & 3);
}
-
+
/// isIndexedStoreLegal - Return true if the specified indexed load is legal
/// on this target.
bool isIndexedStoreLegal(unsigned IdxMode, MVT VT) const {
- return getIndexedStoreAction(IdxMode, VT) == Legal ||
- getIndexedStoreAction(IdxMode, VT) == Custom;
+ return VT.isSimple() &&
+ (getIndexedStoreAction(IdxMode, VT) == Legal ||
+ getIndexedStoreAction(IdxMode, VT) == Custom);
}
-
+
/// getConvertAction - Return how the conversion should be treated:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// isConvertLegal - Return true if the specified conversion is legal
/// on this target.
bool isConvertLegal(MVT FromVT, MVT ToVT) const {
- return getConvertAction(FromVT, ToVT) == Legal ||
- getConvertAction(FromVT, ToVT) == Custom;
+ return isTypeLegal(FromVT) && isTypeLegal(ToVT) &&
+ (getConvertAction(FromVT, ToVT) == Legal ||
+ getConvertAction(FromVT, ToVT) == Custom);
+ }
+
+ /// getCondCodeAction - Return how the condition code should be treated:
+ /// either it is legal, needs to be expanded to some other code sequence,
+ /// or the target has a custom expander for it.
+ LegalizeAction
+ getCondCodeAction(ISD::CondCode CC, MVT VT) const {
+ assert((unsigned)CC < array_lengthof(CondCodeActions) &&
+ (unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ "Table isn't big enough!");
+ LegalizeAction Action = (LegalizeAction)
+ ((CondCodeActions[CC] >> (2*VT.getSimpleVT())) & 3);
+ assert(Action != Promote && "Can't promote condition code!");
+ return Action;
+ }
+
+ /// isCondCodeLegal - Return true if the specified condition code is legal
+ /// on this target.
+ bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+ return getCondCodeAction(CC, VT) == Legal ||
+ getCondCodeAction(CC, VT) == Custom;
}
+
/// getTypeToPromoteTo - If the action for this operation is to promote, this
/// method returns the ValueType to promote to.
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
"This operation isn't promoted!");
// See if this has an explicit type specified.
- std::map<std::pair<unsigned, MVT>,
- MVT>::const_iterator PTTI =
- PromoteToType.find(std::make_pair(Op, VT));
+ std::map<std::pair<unsigned, MVT::SimpleValueType>,
+ MVT::SimpleValueType>::const_iterator PTTI =
+ PromoteToType.find(std::make_pair(Op, VT.getSimpleVT()));
if (PTTI != PromoteToType.end()) return PTTI->second;
assert((VT.isInteger() || VT.isFloatingPoint()) &&
/// getPreIndexedAddressParts - returns true by value, base pointer and
/// offset pointer and addressing mode by reference if the node's address
/// can be legally represented as pre-indexed load / store address.
- virtual bool getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
- SDOperand &Offset,
+ virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
+ SDValue &Offset,
ISD::MemIndexedMode &AM,
SelectionDAG &DAG) {
return false;
/// offset pointer and addressing mode by reference if this node can be
/// combined with a load / store to form a post-indexed load / store.
virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
- SDOperand &Base, SDOperand &Offset,
+ SDValue &Base, SDValue &Offset,
ISD::MemIndexedMode &AM,
SelectionDAG &DAG) {
return false;
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
- virtual SDOperand getPICJumpTableRelocBase(SDOperand Table,
+ virtual SDValue getPICJumpTableRelocBase(SDValue Table,
SelectionDAG &DAG) const;
+ /// isOffsetFoldingLegal - Return true if folding a constant offset
+ /// with the given GlobalAddress is legal. It is frequently not legal in
+ /// PIC relocation models.
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
/// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
- /// SDOperands for returning information from TargetLowering to its clients
+ /// SDValues for returning information from TargetLowering to its clients
/// that want to combine
struct TargetLoweringOpt {
SelectionDAG &DAG;
- bool AfterLegalize;
- SDOperand Old;
- SDOperand New;
+ SDValue Old;
+ SDValue New;
- explicit TargetLoweringOpt(SelectionDAG &InDAG, bool afterLegalize)
- : DAG(InDAG), AfterLegalize(afterLegalize) {}
+ explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {}
- bool CombineTo(SDOperand O, SDOperand N) {
+ bool CombineTo(SDValue O, SDValue N) {
Old = O;
New = N;
return true;
/// specified instruction is a constant integer. If so, check to see if
/// there are any bits set in the constant that are not demanded. If so,
/// shrink the constant and return true.
- bool ShrinkDemandedConstant(SDOperand Op, const APInt &Demanded);
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
};
/// SimplifyDemandedBits - Look at Op. At this point, we know that only the
/// KnownZero bits for the expression (used to simplify the caller).
/// The KnownZero/One bits may only be accurate for those bits in the
/// DemandedMask.
- bool SimplifyDemandedBits(SDOperand Op, const APInt &DemandedMask,
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
APInt &KnownZero, APInt &KnownOne,
TargetLoweringOpt &TLO, unsigned Depth = 0) const;
/// computeMaskedBitsForTargetNode - Determine which of the bits specified in
/// Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
- virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
+ virtual void computeMaskedBitsForTargetNode(const SDValue Op,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
/// ComputeNumSignBitsForTargetNode - This method can be implemented by
/// targets that want to expose additional information about sign bits to the
/// DAG Combiner.
- virtual unsigned ComputeNumSignBitsForTargetNode(SDOperand Op,
+ virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
unsigned Depth = 0) const;
struct DAGCombinerInfo {
bool isCalledByLegalizer() const { return CalledByLegalizer; }
void AddToWorklist(SDNode *N);
- SDOperand CombineTo(SDNode *N, const std::vector<SDOperand> &To);
- SDOperand CombineTo(SDNode *N, SDOperand Res);
- SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To);
+ SDValue CombineTo(SDNode *N, SDValue Res);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1);
};
/// SimplifySetCC - Try to simplify a setcc built with the specified operands
- /// and cc. If it is unable to simplify it, return a null SDOperand.
- SDOperand SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
+ /// and cc. If it is unable to simplify it, return a null SDValue.
+ SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
DAGCombinerInfo &DCI) const;
///
/// The semantics are as follows:
/// Return Value:
- /// SDOperand.Val == 0 - No change was made
- /// SDOperand.Val == N - N was replaced, is dead, and is already handled.
- /// otherwise - N should be replaced by the returned Operand.
+ /// SDValue.Val == 0 - No change was made
+ /// SDValue.Val == N - N was replaced, is dead, and is already handled.
+ /// otherwise - N should be replaced by the returned Operand.
///
/// In addition, methods provided by DAGCombinerInfo may be used to perform
/// more complex transformations.
///
- virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+ virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
/// amounts. This type defaults to the pointer type.
void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
- /// setSetCCResultContents - Specify how the target extends the result of a
- /// setcc operation in a register.
- void setSetCCResultContents(SetCCResultValue Ty) { SetCCResultContents = Ty; }
+ /// setBooleanContents - Specify how the target extends the result of a
+ /// boolean value from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
/// setSchedulingPreference - Specify the target scheduling preference.
void setSchedulingPreference(SchedPreference Pref) {
OpActions[Op] |= (uint64_t)Action << VT.getSimpleVT()*2;
}
- /// setLoadXAction - Indicate that the specified load with extension does not
- /// work with the with specified type and indicate what to do about it.
- void setLoadXAction(unsigned ExtType, MVT VT,
+ /// setLoadExtAction - Indicate that the specified load with extension does
+ /// not work with the with specified type and indicate what to do about it.
+ void setLoadExtAction(unsigned ExtType, MVT VT,
LegalizeAction Action) {
- assert((unsigned)VT.getSimpleVT() < sizeof(LoadXActions[0])*4 &&
- ExtType < array_lengthof(LoadXActions) &&
+ assert((unsigned)VT.getSimpleVT() < sizeof(LoadExtActions[0])*4 &&
+ ExtType < array_lengthof(LoadExtActions) &&
"Table isn't big enough!");
- LoadXActions[ExtType] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
- LoadXActions[ExtType] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
+ LoadExtActions[ExtType] |= (uint64_t)Action << VT.getSimpleVT()*2;
}
/// setTruncStoreAction - Indicate that the specified truncating store does
ToVT.getSimpleVT()*2;
}
+ /// setCondCodeAction - Indicate that the specified condition code is or isn't
+ /// supported on the target and indicate what to do about it.
+ void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action) {
+ assert((unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ (unsigned)CC < array_lengthof(CondCodeActions) &&
+ "Table isn't big enough!");
+ CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
+ CondCodeActions[(unsigned)CC] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ }
+
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
/// promotion code defaults to trying a larger integer/fp until it can find
/// one that works. If that default is insufficient, this method can be used
/// by the target to override the default.
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT) {
- PromoteToType[std::make_pair(Opc, OrigVT)] = DestVT;
+ PromoteToType[std::make_pair(Opc, OrigVT.getSimpleVT())] =
+ DestVT.getSimpleVT();
}
/// addLegalFPImmediate - Indicate that this target can instruction select
/// 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);
+ virtual void
+ LowerArguments(Function &F, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue>& ArgValues);
/// 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.
struct ArgListEntry {
- SDOperand Node;
+ SDValue Node;
const Type* Ty;
- bool isSExt;
- bool isZExt;
- bool isInReg;
- bool isSRet;
- bool isNest;
- bool isByVal;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
uint16_t Alignment;
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
};
typedef std::vector<ArgListEntry> ArgListTy;
- virtual std::pair<SDOperand, SDOperand>
- LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
- bool isVarArg, unsigned CallingConv, bool isTailCall,
- SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
-
+ virtual std::pair<SDValue, SDValue>
+ LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
+ bool isVarArg, bool isInreg, unsigned CallingConv,
+ bool isTailCall, SDValue Callee, ArgListTy &Args,
+ SelectionDAG &DAG);
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
- /// SDOperand if the target declines to use custom code and a different
+ /// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
///
/// If AlwaysInline is true, the size is constant and the target should not
/// expanded in a place where calls are not feasible (e.g. within the prologue
/// for another call). If the target chooses to decline an AlwaysInline
/// request here, legalize will resort to using simple loads and stores.
- virtual SDOperand
+ virtual SDValue
EmitTargetCodeForMemcpy(SelectionDAG &DAG,
- SDOperand Chain,
- SDOperand Op1, SDOperand Op2,
- SDOperand Op3, unsigned Align,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align,
bool AlwaysInline,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) {
- return SDOperand();
+ return SDValue();
}
/// EmitTargetCodeForMemmove - Emit target-specific code that performs a
/// memmove. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
/// more efficient than using a library call. This function can return a null
- /// SDOperand if the target declines to use custom code and a different
+ /// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
- virtual SDOperand
+ virtual SDValue
EmitTargetCodeForMemmove(SelectionDAG &DAG,
- SDOperand Chain,
- SDOperand Op1, SDOperand Op2,
- SDOperand Op3, unsigned Align,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align,
const Value *DstSV, uint64_t DstOff,
const Value *SrcSV, uint64_t SrcOff) {
- return SDOperand();
+ return SDValue();
}
/// EmitTargetCodeForMemset - Emit target-specific code that performs a
/// memset. This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple stores and can be more
/// efficient than using a library call. This function can return a null
- /// SDOperand if the target declines to use custom code and a different
+ /// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
- virtual SDOperand
+ virtual SDValue
EmitTargetCodeForMemset(SelectionDAG &DAG,
- SDOperand Chain,
- SDOperand Op1, SDOperand Op2,
- SDOperand Op3, unsigned Align,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align,
const Value *DstSV, uint64_t DstOff) {
- return SDOperand();
+ return SDValue();
}
/// LowerOperation - This callback is invoked for operations that are
/// and whose defined values are all legal.
/// 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, SelectionDAG &DAG);
-
- /// ExpandOperationResult - This callback is invoked for operations that are
- /// unsupported by the target, which are registered to use 'custom' lowering,
- /// and whose result type needs to be expanded. This must return a node whose
- /// results precisely match the results of the input node. This typically
- /// involves a MERGE_VALUES node and/or BUILD_PAIR.
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
+
+ /// ReplaceNodeResults - This callback is invoked when a node result type is
+ /// illegal for the target, and the operation was registered to use 'custom'
+ /// lowering for that result type. The target places new result values for
+ /// the node in Results (their number and types must exactly match those of
+ /// the original return values of the node), or leaves Results empty, which
+ /// indicates that the node is not to be custom lowered after all.
///
/// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation of this aborts.
- virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG) {
- assert(0 && "ExpandOperationResult not implemented for this target!");
- return 0;
+ /// implement this. The default implementation aborts.
+ virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG) {
+ assert(0 && "ReplaceNodeResults not implemented for this target!");
}
-
+
/// IsEligibleForTailCallOptimization - Check whether the call is eligible for
/// tail call optimization. Targets which want to do tail call optimization
/// should override this function.
- virtual bool IsEligibleForTailCallOptimization(SDOperand Call,
- SDOperand Ret,
+ virtual bool IsEligibleForTailCallOptimization(CallSDNode *Call,
+ SDValue Ret,
SelectionDAG &DAG) const {
return false;
}
/// preceeds the RET node and whether the return uses the result of the node
/// or is a void return. This function can be used by the target to determine
/// eligiblity of tail call optimization.
- static bool CheckTailCallReturnConstraints(SDOperand Call, SDOperand Ret) {
+ static bool CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret) {
unsigned NumOps = Ret.getNumOperands();
if ((NumOps == 1 &&
- (Ret.getOperand(0) == SDOperand(Call.Val,1) ||
- Ret.getOperand(0) == SDOperand(Call.Val,0))) ||
+ (Ret.getOperand(0) == SDValue(TheCall,1) ||
+ Ret.getOperand(0) == SDValue(TheCall,0))) ||
(NumOps > 1 &&
- Ret.getOperand(0) == SDOperand(Call.Val,Call.Val->getNumValues()-1) &&
- Ret.getOperand(1) == SDOperand(Call.Val,0)))
+ Ret.getOperand(0) == SDValue(TheCall,
+ TheCall->getNumValues()-1) &&
+ Ret.getOperand(1) == SDValue(TheCall,0)))
return true;
return false;
}
/// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if
- /// it exists skip possible ISD:TokenFactor.
- static SDOperand GetPossiblePreceedingTailCall(SDOperand Chain,
+ /// it exists. Skip a possible ISD:TokenFactor.
+ static SDValue GetPossiblePreceedingTailCall(SDValue Chain,
unsigned TailCallNodeOpCode) {
if (Chain.getOpcode() == TailCallNodeOpCode) {
return Chain;
return Chain;
}
- /// CustomPromoteOperation - This callback is invoked for operations that are
- /// unsupported by the target, are registered to use 'custom' lowering, and
- /// whose type needs to be promoted.
- virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG);
-
/// getTargetNodeName() - This method returns the name of a target specific
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
+ /// createFastISel - This method returns a target specific FastISel object,
+ /// or null if the target does not support "fast" ISel.
+ virtual FastISel *
+ createFastISel(MachineFunction &,
+ MachineModuleInfo *,
+ DenseMap<const Value *, unsigned> &,
+ DenseMap<const BasicBlock *, MachineBasicBlock *> &,
+ DenseMap<const AllocaInst *, int> &
+#ifndef NDEBUG
+ , SmallSet<Instruction*, 8> &CatchInfoLost
+#endif
+ ) {
+ return 0;
+ }
+
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
//
enum ConstraintType {
- C_Register, // Constraint represents a single register.
- C_RegisterClass, // Constraint represents one or more registers.
+ C_Register, // Constraint represents specific register(s).
+ C_RegisterClass, // Constraint represents any of register(s) in class.
C_Memory, // Memory constraint.
C_Other, // Something else.
C_Unknown // Unsupported constraint.
/// lowering.
struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
/// ConstraintCode - This contains the actual string for the code, like "m".
+ /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
+ /// most closely matches the operand.
std::string ConstraintCode;
/// ConstraintType - Information about the constraint code, e.g. Register,
/// ConstraintVT - The ValueType for the operand value.
MVT ConstraintVT;
+
+ /// isMatchingInputConstraint - Return true of this is an input operand that
+ /// is a matching constraint like "4".
+ bool isMatchingInputConstraint() const;
+
+ /// getMatchedOperand - If this is an input matching constraint, this method
+ /// returns the output operand it matches.
+ unsigned getMatchedOperand() const;
AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
: InlineAsm::ConstraintInfo(info),
/// type to use for the specific AsmOperandInfo, setting
/// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
/// being passed in is available, it can be passed in as Op, otherwise an
- /// empty SDOperand can be passed.
+ /// empty SDValue can be passed. If hasMemory is true it means one of the asm
+ /// constraint of the inline asm instruction being processed is 'm'.
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
- SDOperand Op,
+ SDValue Op,
+ bool hasMemory,
SelectionDAG *DAG = 0) const;
/// getConstraintType - Given a constraint, return the type of constraint it
virtual const char *LowerXConstraint(MVT ConstraintVT) const;
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
- /// vector. If it is invalid, don't add anything to Ops.
- virtual void LowerAsmOperandForConstraint(SDOperand Op, char ConstraintLetter,
- std::vector<SDOperand> &Ops,
+ /// vector. If it is invalid, don't add anything to Ops. If hasMemory is true
+ /// it means one of the asm constraint of the inline asm instruction being
+ /// processed is 'm'.
+ virtual void LowerAsmOperandForConstraint(SDValue Op, char ConstraintLetter,
+ bool hasMemory,
+ std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// Div utility functions
//
- SDOperand BuildSDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const;
- SDOperand BuildUDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const;
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 PointerTy;
+ /// IsLittleEndian - True if this is a little endian target.
+ ///
+ bool IsLittleEndian;
+
/// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen.
///
bool UsesGlobalOffsetTable;
- /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
- /// PointerTy is.
- MVT ShiftAmountTy;
-
- OutOfRangeShiftAmount ShiftAmtHandling;
-
/// SelectIsExpensive - Tells the code generator not to expand operations
/// into sequences that use the select operations if possible.
bool SelectIsExpensive;
/// it.
bool Pow2DivIsCheap;
- /// SetCCResultContents - Information about the contents of the high-bits in
- /// the result of a setcc comparison operation.
- SetCCResultValue SetCCResultContents;
-
- /// SchedPreferenceInfo - The target scheduling preference: shortest possible
- /// total cycles or lowest register usage.
- SchedPreference SchedPreferenceInfo;
-
/// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
/// llvm.setjmp. Defaults to false.
bool UseUnderscoreSetJmp;
/// llvm.longjmp. Defaults to false.
bool UseUnderscoreLongJmp;
+ /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
+ /// PointerTy is.
+ MVT ShiftAmountTy;
+
+ OutOfRangeShiftAmount ShiftAmtHandling;
+
+ /// BooleanContents - Information about the contents of the high-bits in
+ /// boolean values held in a type wider than i1. See getBooleanContents.
+ BooleanContent BooleanContents;
+
+ /// SchedPreferenceInfo - The target scheduling preference: shortest possible
+ /// total cycles or lowest register usage.
+ SchedPreference SchedPreferenceInfo;
+
/// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
unsigned JumpBufSize;
MVT TransformToType[MVT::LAST_VALUETYPE];
// Defines the capacity of the TargetLowering::OpActions table
- static const int OpActionsCapacity = 176;
+ static const int OpActionsCapacity = 218;
/// OpActions - For each operation and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with the operation.
/// non-legal value types are not described here.
uint64_t OpActions[OpActionsCapacity];
- /// LoadXActions - For each load of load extension type and each value type,
+ /// LoadExtActions - For each load of load extension type and each value type,
/// keep a LegalizeAction that indicates how instruction selection should deal
/// with the load.
- uint64_t LoadXActions[ISD::LAST_LOADX_TYPE];
+ uint64_t LoadExtActions[ISD::LAST_LOADEXT_TYPE];
/// TruncStoreActions - For each truncating store, keep a LegalizeAction that
/// indicates how instruction selection should deal with the store.
/// (FP_EXTEND and FP_ROUND).
uint64_t ConvertActions[MVT::LAST_VALUETYPE];
+ /// CondCodeActions - For each condition code (ISD::CondCode) keep a
+ /// LegalizeAction that indicates how instruction selection should
+ /// deal with the condition code.
+ uint64_t CondCodeActions[ISD::SETCC_INVALID];
+
ValueTypeActionImpl ValueTypeActions;
std::vector<APFloat> LegalFPImmediates;
///
/// Targets add entries to this map with AddPromotedToType(..), clients access
/// this with getTypeToPromoteTo(..).
- std::map<std::pair<unsigned, MVT>, MVT> PromoteToType;
+ std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
+ PromoteToType;
/// LibcallRoutineNames - Stores the name each libcall.
///
ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
protected:
- /// When lowering %llvm.memset this field specifies the maximum number of
+ /// When lowering @llvm.memset this field specifies the maximum number of
/// store operations that may be substituted for the call to memset. Targets
/// must set this value based on the cost threshold for that target. Targets
/// should assume that the memset will be done using as many of the largest
/// @brief Specify maximum number of store instructions per memset call.
unsigned maxStoresPerMemset;
- /// When lowering %llvm.memcpy this field specifies the maximum number of
+ /// When lowering @llvm.memcpy this field specifies the maximum number of
/// store operations that may be substituted for a call to memcpy. Targets
/// must set this value based on the cost threshold for that target. Targets
/// should assume that the memcpy will be done using as many of the largest
/// @brief Specify maximum bytes of store instructions per memcpy call.
unsigned maxStoresPerMemcpy;
- /// When lowering %llvm.memmove this field specifies the maximum number of
+ /// When lowering @llvm.memmove this field specifies the maximum number of
/// store instructions that may be substituted for a call to memmove. Targets
/// must set this value based on the cost threshold for that target. Targets
/// should assume that the memmove will be done using as many of the largest