#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
+#include "llvm/CallingConv.h"
#include "llvm/InlineAsm.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DebugLoc.h"
+#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
#include <climits>
#include <map>
class MachineFunction;
class MachineFrameInfo;
class MachineInstr;
- class MachineModuleInfo;
- class DwarfWriter;
+ class MachineJumpTableInfo;
+ class MCContext;
+ class MCExpr;
class SDNode;
class SDValue;
class SelectionDAG;
class TargetData;
class TargetMachine;
class TargetRegisterClass;
- class TargetSubtarget;
class TargetLoweringObjectFile;
class Value;
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
- enum SchedPreference {
- SchedulingForLatency, // Scheduling for shortest total latency.
- SchedulingForRegPressure // Scheduling for lowest register pressure.
- };
-
/// NOTE: The constructor takes ownership of TLOF.
- explicit TargetLowering(TargetMachine &TM, TargetLoweringObjectFile *TLOF);
+ explicit TargetLowering(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
virtual ~TargetLowering();
- TargetMachine &getTargetMachine() const { return TM; }
+ const TargetMachine &getTargetMachine() const { return TM; }
const TargetData *getTargetData() const { return TD; }
- TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
+ const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
MVT getPointerTy() const { return PointerTy; }
MVT getShiftAmountTy() const { return ShiftAmountTy; }
- /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC
- /// codegen.
- bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; }
-
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.
bool isSelectExpensive() const { return SelectIsExpensive; }
-
+
/// isIntDivCheap() - Return true if integer divide is usually cheaper than
/// a sequence of several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }
virtual
MVT::SimpleValueType getSetCCResultType(EVT VT) const;
+ /// getCmpLibcallReturnType - Return the ValueType for comparison
+ /// libcalls. Comparions libcalls include floating point comparion calls,
+ /// and Ordered/Unordered check calls on floating point numbers.
+ virtual
+ MVT::SimpleValueType getCmpLibcallReturnType() const;
+
/// 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
BooleanContent getBooleanContents() const { return BooleanContents;}
/// getSchedulingPreference - Return target scheduling preference.
- SchedPreference getSchedulingPreference() const {
+ Sched::Preference getSchedulingPreference() const {
return SchedPreferenceInfo;
}
+ /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to
+ /// different scheduling heuristics for different nodes. This function returns
+ /// the preference (or none) for the given node.
+ virtual Sched::Preference getSchedulingPreference(SDNode *N) const {
+ return Sched::None;
+ }
+
/// getRegClassFor - Return the register class that should be used for the
- /// specified value type. This may only be called on legal types.
- TargetRegisterClass *getRegClassFor(EVT VT) const {
+ /// specified value type.
+ virtual TargetRegisterClass *getRegClassFor(EVT VT) const {
assert(VT.isSimple() && "getRegClassFor called on illegal type!");
TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
assert(RC && "This value type is not natively supported!");
return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0;
}
+ /// isTypeSynthesizable - Return true if it's OK for the compiler to create
+ /// new operations of this type. All Legal types are synthesizable except
+ /// MMX vector types on X86. Non-Legal types are not synthesizable.
+ bool isTypeSynthesizable(EVT VT) const {
+ return isTypeLegal(VT) && Synthesizable[VT.getSimpleVT().SimpleTy];
+ }
+
class ValueTypeActionImpl {
- /// 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)".
- /// dimension by (MVT::MAX_ALLOWED_VALUETYPE/32) * 2
- uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2];
+ /// ValueTypeActions - For each value type, keep a LegalizeAction enum
+ /// that indicates how instruction selection should deal with the type.
+ uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
public:
ValueTypeActionImpl() {
- ValueTypeActions[0] = ValueTypeActions[1] = 0;
- ValueTypeActions[2] = ValueTypeActions[3] = 0;
+ std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
}
- ValueTypeActionImpl(const ValueTypeActionImpl &RHS) {
- ValueTypeActions[0] = RHS.ValueTypeActions[0];
- ValueTypeActions[1] = RHS.ValueTypeActions[1];
- ValueTypeActions[2] = RHS.ValueTypeActions[2];
- ValueTypeActions[3] = RHS.ValueTypeActions[3];
- }
-
- LegalizeAction getTypeAction(EVT VT) const {
+ LegalizeAction getTypeAction(LLVMContext &Context, EVT VT) const {
if (VT.isExtended()) {
if (VT.isVector()) {
return VT.isPow2VectorType() ? Expand : Promote;
}
if (VT.isInteger())
// First promote to a power-of-two size, then expand if necessary.
- return VT == VT.getRoundIntegerType() ? Expand : Promote;
+ return VT == VT.getRoundIntegerType(Context) ? Expand : Promote;
assert(0 && "Unsupported extended type!");
return Legal;
}
unsigned I = VT.getSimpleVT().SimpleTy;
- assert(I<4*array_lengthof(ValueTypeActions)*sizeof(ValueTypeActions[0]));
- return (LegalizeAction)((ValueTypeActions[I>>4] >> ((2*I) & 31)) & 3);
+ return (LegalizeAction)ValueTypeActions[I];
}
void setTypeAction(EVT VT, LegalizeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
- assert(I<4*array_lengthof(ValueTypeActions)*sizeof(ValueTypeActions[0]));
- ValueTypeActions[I>>4] |= Action << ((I*2) & 31);
+ ValueTypeActions[I] = Action;
}
};
-
+
const ValueTypeActionImpl &getValueTypeActions() const {
return ValueTypeActions;
}
/// 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(EVT VT) const {
- return ValueTypeActions.getTypeAction(VT);
+ LegalizeAction getTypeAction(LLVMContext &Context, EVT VT) const {
+ return ValueTypeActions.getTypeAction(Context, VT);
}
/// getTypeToTransformTo - For types supported by the target, this is an
/// than the largest integer register, this contains one step in the expansion
/// to get to the smaller register. For illegal floating point types, this
/// returns the integer type to transform to.
- EVT getTypeToTransformTo(EVT VT) const {
+ EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
- assert((unsigned)VT.getSimpleVT().SimpleTy <
+ assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(TransformToType));
EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy];
- assert(getTypeAction(NVT) != Promote &&
+ assert(getTypeAction(Context, NVT) != Promote &&
"Promote may not follow Expand or Promote");
return NVT;
}
if (VT.isVector()) {
- EVT NVT = VT.getPow2VectorType();
+ EVT NVT = VT.getPow2VectorType(Context);
if (NVT == VT) {
// Vector length is a power of 2 - split to half the size.
unsigned NumElts = VT.getVectorNumElements();
EVT EltVT = VT.getVectorElementType();
- return (NumElts == 1) ? EltVT : EVT::getVectorVT(EltVT, NumElts / 2);
+ return (NumElts == 1) ?
+ EltVT : EVT::getVectorVT(Context, EltVT, NumElts / 2);
}
// Promote to a power of two size, avoiding multi-step promotion.
- return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
+ return getTypeAction(Context, NVT) == Promote ?
+ getTypeToTransformTo(Context, NVT) : NVT;
} else if (VT.isInteger()) {
- EVT NVT = VT.getRoundIntegerType();
+ EVT NVT = VT.getRoundIntegerType(Context);
if (NVT == VT)
// Size is a power of two - expand to half the size.
- return EVT::getIntegerVT(VT.getSizeInBits() / 2);
+ return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2);
else
// Promote to a power of two size, avoiding multi-step promotion.
- return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
+ return getTypeAction(Context, NVT) == Promote ?
+ getTypeToTransformTo(Context, NVT) : NVT;
}
assert(0 && "Unsupported extended type!");
return MVT(MVT::Other); // Not reached
/// identity function. For types that must be expanded (i.e. integer types
/// that are larger than the largest integer register or illegal floating
/// point types), this returns the largest legal type it will be expanded to.
- EVT getTypeToExpandTo(EVT VT) const {
+ EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const {
assert(!VT.isVector());
while (true) {
- switch (getTypeAction(VT)) {
+ switch (getTypeAction(Context, VT)) {
case Legal:
return VT;
case Expand:
- VT = getTypeToTransformTo(VT);
+ VT = getTypeToTransformTo(Context, VT);
break;
default:
assert(false && "Type is not legal nor is it to be expanded!");
/// register. It also returns the VT and quantity of the intermediate values
/// before they are promoted/expanded.
///
- unsigned getVectorTypeBreakdown(EVT VT,
+ unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
EVT &IntermediateVT,
unsigned &NumIntermediates,
EVT &RegisterVT) const;
/// 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 {
+ struct IntrinsicInfo {
unsigned opc; // target opcode
EVT memVT; // memory VT
const Value* ptrVal; // value representing memory location
- int offset; // offset off of ptrVal
+ 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) {
+ virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
+ const CallInst &I, unsigned Intrinsic) const {
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 EVT getWidenVectorType(EVT VT) const;
-
- typedef std::vector<APFloat>::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();
+ /// isFPImmLegal - Returns true if the target can instruction select the
+ /// specified FP immediate natively. If false, the legalizer will materialize
+ /// the FP immediate as a load from a constant pool.
+ virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const {
+ return false;
}
-
+
/// isShuffleMaskLegal - Targets can use this to indicate that they only
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
return true;
}
+ /// canOpTrap - Returns true if the operation can trap for the value type.
+ /// VT must be a legal type. By default, we optimistically assume most
+ /// operations don't trap except for divide and remainder.
+ virtual bool canOpTrap(unsigned Op, EVT VT) const;
+
/// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
/// 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
/// for it.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const {
if (VT.isExtended()) return Expand;
- assert(Op < array_lengthof(OpActions[0]) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(OpActions[0][0])*8 &&
- "Table isn't big enough!");
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
- unsigned J = I & 31;
- I = I >> 5;
- return (LegalizeAction)((OpActions[I][Op] >> (J*2) ) & 3);
+ return (LegalizeAction)OpActions[I][Op];
}
/// isOperationLegalOrCustom - Return true if the specified operation is
/// 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 getLoadExtAction(unsigned LType, EVT VT) const {
- assert(LType < array_lengthof(LoadExtActions) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(LoadExtActions[0])*4 &&
+ LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
+ (unsigned)VT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((LoadExtActions[LType] >>
- (2*VT.getSimpleVT().SimpleTy)) & 3);
+ return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtType];
}
/// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
- bool isLoadExtLegal(unsigned LType, EVT VT) const {
+ bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
return VT.isSimple() &&
- (getLoadExtAction(LType, VT) == Legal ||
- getLoadExtAction(LType, VT) == Custom);
+ (getLoadExtAction(ExtType, VT) == Legal ||
+ getLoadExtAction(ExtType, 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
/// expander for it.
- LegalizeAction getTruncStoreAction(EVT ValVT,
- EVT MemVT) const {
- assert((unsigned)ValVT.getSimpleVT().SimpleTy <
- array_lengthof(TruncStoreActions) &&
- (unsigned)MemVT.getSimpleVT().SimpleTy <
- sizeof(TruncStoreActions[0])*4 &&
+ LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
+ assert((unsigned)ValVT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
+ (unsigned)MemVT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((TruncStoreActions[ValVT.getSimpleVT().SimpleTy] >>
- (2*MemVT.getSimpleVT().SimpleTy)) & 3);
+ return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy]
+ [MemVT.getSimpleVT().SimpleTy];
}
/// isTruncStoreLegal - Return true if the specified store with truncation is
/// for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, EVT VT) const {
- assert( IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
+ assert( IdxMode < ISD::LAST_INDEXED_MODE &&
((unsigned)VT.getSimpleVT().SimpleTy) < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[
- (unsigned)VT.getSimpleVT().SimpleTy][0][IdxMode]));
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
}
/// isIndexedLoadLegal - Return true if the specified indexed load is legal
/// for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < array_lengthof(IndexedModeActions[0][1]) &&
- (unsigned)VT.getSimpleVT().SimpleTy < MVT::LAST_VALUETYPE &&
+ assert( IdxMode < ISD::LAST_INDEXED_MODE &&
+ ((unsigned)VT.getSimpleVT().SimpleTy) < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[
- (unsigned)VT.getSimpleVT().SimpleTy][1][IdxMode]));
- }
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
+ }
/// isIndexedStoreLegal - Return true if the specified indexed load is legal
/// on this target.
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
- /// for it.
- LegalizeAction
- getConvertAction(EVT FromVT, EVT ToVT) const {
- assert((unsigned)FromVT.getSimpleVT().SimpleTy <
- array_lengthof(ConvertActions) &&
- (unsigned)ToVT.getSimpleVT().SimpleTy <
- sizeof(ConvertActions[0])*4 &&
- "Table isn't big enough!");
- return (LegalizeAction)((ConvertActions[FromVT.getSimpleVT().SimpleTy] >>
- (2*ToVT.getSimpleVT().SimpleTy)) & 3);
- }
-
- /// isConvertLegal - Return true if the specified conversion is legal
- /// on this target.
- bool isConvertLegal(EVT FromVT, EVT ToVT) const {
- 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.
assert((VT.isInteger() || VT.isFloatingPoint()) &&
"Cannot autopromote this type, add it with AddPromotedToType.");
-
+
EVT NVT = VT;
do {
NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1);
/// counterpart (e.g. structs), otherwise it will assert.
EVT getValueType(const Type *Ty, bool AllowUnknown = false) const {
EVT VT = EVT::getEVT(Ty, AllowUnknown);
- return VT == MVT:: iPTR ? PointerTy : VT;
+ return VT == MVT::iPTR ? PointerTy : VT;
}
/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area. This is the actual
/// alignment, not its logarithm.
virtual unsigned getByValTypeAlignment(const Type *Ty) const;
-
+
+ /// getRegisterType - Return the type of registers that this ValueType will
+ /// eventually require.
+ EVT getRegisterType(MVT VT) const {
+ assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT));
+ return RegisterTypeForVT[VT.SimpleTy];
+ }
+
/// getRegisterType - Return the type of registers that this ValueType will
/// eventually require.
- EVT getRegisterType(EVT VT) const {
+ EVT getRegisterType(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(RegisterTypeForVT));
if (VT.isVector()) {
EVT VT1, RegisterVT;
unsigned NumIntermediates;
- (void)getVectorTypeBreakdown(VT, VT1, NumIntermediates, RegisterVT);
+ (void)getVectorTypeBreakdown(Context, VT, VT1,
+ NumIntermediates, RegisterVT);
return RegisterVT;
}
if (VT.isInteger()) {
- return getRegisterType(getTypeToTransformTo(VT));
+ return getRegisterType(Context, getTypeToTransformTo(Context, VT));
}
assert(0 && "Unsupported extended type!");
return EVT(MVT::Other); // Not reached
/// into pieces. For types like i140, which are first promoted then expanded,
/// it is the number of registers needed to hold all the bits of the original
/// type. For an i140 on a 32 bit machine this means 5 registers.
- unsigned getNumRegisters(EVT VT) const {
+ unsigned getNumRegisters(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(NumRegistersForVT));
if (VT.isVector()) {
EVT VT1, VT2;
unsigned NumIntermediates;
- return getVectorTypeBreakdown(VT, VT1, NumIntermediates, VT2);
+ return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2);
}
if (VT.isInteger()) {
unsigned BitWidth = VT.getSizeInBits();
- unsigned RegWidth = getRegisterType(VT).getSizeInBits();
+ unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits();
return (BitWidth + RegWidth - 1) / RegWidth;
}
assert(0 && "Unsupported extended type!");
unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; }
/// This function returns true if the target allows unaligned memory accesses.
- /// This is used, for example, in situations where an array copy/move/set is
- /// converted to a sequence of store operations. It's use helps to ensure that
- /// such replacements don't generate code that causes an alignment error
- /// (trap) on the target machine.
+ /// of the specified type. This is used, for example, in situations where an
+ /// array copy/move/set is converted to a sequence of store operations. It's
+ /// use helps to ensure that such replacements don't generate code that causes
+ /// an alignment error (trap) on the target machine.
/// @brief Determine if the target supports unaligned memory accesses.
- bool allowsUnalignedMemoryAccesses() const {
- return allowUnalignedMemoryAccesses;
+ virtual bool allowsUnalignedMemoryAccesses(EVT VT) const {
+ return false;
}
/// This function returns true if the target would benefit from code placement
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
- /// and store operations as a result of memset, memcpy, and memmove lowering.
- /// It returns EVT::iAny if SelectionDAG should be responsible for
- /// determining it.
- virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align,
- bool isSrcConst, bool isSrcStr,
- SelectionDAG &DAG) const {
- return MVT::iAny;
+ /// and store operations as a result of memset, memcpy, and memmove
+ /// lowering. If DstAlign is zero that means it's safe to destination
+ /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
+ /// means there isn't a need to check it against alignment requirement,
+ /// probably because the source does not need to be loaded. If
+ /// 'NonScalarIntSafe' is true, that means it's safe to return a
+ /// non-scalar-integer type, e.g. empty string source, constant, or loaded
+ /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
+ /// constant so it does not need to be loaded.
+ /// It returns EVT::Other if the type should be determined using generic
+ /// target-independent logic.
+ virtual EVT getOptimalMemOpType(uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign,
+ bool NonScalarIntSafe, bool MemcpyStrSrc,
+ MachineFunction &MF) const {
+ return MVT::Other;
}
-
+
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
/// to implement llvm.setjmp.
bool usesUnderscoreSetJmp() const {
return JumpBufAlignment;
}
- /// getIfCvtBlockLimit - returns the target specific if-conversion block size
- /// limit. Any block whose size is greater should not be predicated.
- unsigned getIfCvtBlockSizeLimit() const {
- return IfCvtBlockSizeLimit;
- }
-
- /// getIfCvtDupBlockLimit - returns the target specific size limit for a
- /// block to be considered for duplication. Any block whose size is greater
- /// should not be duplicated to facilitate its predication.
- unsigned getIfCvtDupBlockSizeLimit() const {
- return IfCvtDupBlockSizeLimit;
- }
-
/// getPrefLoopAlignment - return the preferred loop alignment.
///
unsigned getPrefLoopAlignment() const {
return PrefLoopAlignment;
}
-
+
+ /// getShouldFoldAtomicFences - return whether the combiner should fold
+ /// fence MEMBARRIER instructions into the atomic intrinsic instructions.
+ ///
+ bool getShouldFoldAtomicFences() const {
+ return ShouldFoldAtomicFences;
+ }
+
/// 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.
SelectionDAG &DAG) const {
return false;
}
-
+
/// getPostIndexedAddressParts - returns true by value, base pointer and
/// offset pointer and addressing mode by reference if this node can be
/// combined with a load / store to form a post-indexed load / store.
SelectionDAG &DAG) const {
return false;
}
-
+
+ /// getJumpTableEncoding - Return the entry encoding for a jump table in the
+ /// current function. The returned value is a member of the
+ /// MachineJumpTableInfo::JTEntryKind enum.
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB, unsigned uid,
+ MCContext &Ctx) const {
+ assert(0 && "Need to implement this hook if target has custom JTIs");
+ return 0;
+ }
+
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
virtual SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
+ SelectionDAG &DAG) const;
+
+ /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+ /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+ /// MCExpr.
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
/// isOffsetFoldingLegal - Return true if folding a constant offset
/// with the given GlobalAddress is legal. It is frequently not legal in
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *) const = 0;
+ /// getStackCookieLocation - Return true if the target stores stack
+ /// protector cookies at a fixed offset in some non-standard address
+ /// space, and populates the address space and offset as
+ /// appropriate.
+ virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
-
+
/// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
/// SDValues for returning information from TargetLowering to its clients
- /// that want to combine
+ /// that want to combine
struct TargetLoweringOpt {
SelectionDAG &DAG;
+ bool LegalTys;
+ bool LegalOps;
SDValue Old;
SDValue New;
- explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {}
-
- bool CombineTo(SDValue O, SDValue N) {
- Old = O;
- New = N;
+ explicit TargetLoweringOpt(SelectionDAG &InDAG,
+ bool LT, bool LO) :
+ DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+
+ bool LegalTypes() const { return LegalTys; }
+ bool LegalOperations() const { return LegalOps; }
+
+ bool CombineTo(SDValue O, SDValue N) {
+ Old = O;
+ New = N;
return true;
}
-
- /// ShrinkDemandedConstant - Check to see if the specified operand of the
+
+ /// ShrinkDemandedConstant - Check to see if the specified operand of the
/// 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 ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
DebugLoc dl);
};
-
+
/// SimplifyDemandedBits - Look at Op. At this point, we know that only the
/// DemandedMask bits of the result of Op are ever used downstream. If we can
/// use this information to simplify Op, create a new simplified DAG node and
- /// return true, returning the original and new nodes in Old and New.
- /// Otherwise, analyze the expression and return a mask of KnownOne and
- /// KnownZero bits for the expression (used to simplify the caller).
- /// The KnownZero/One bits may only be accurate for those bits in the
+ /// return true, returning the original and new nodes in Old and New.
+ /// Otherwise, analyze the expression and return a mask of KnownOne and
+ /// 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(SDValue 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
+ /// Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
const APInt &Mask,
- APInt &KnownZero,
+ APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
/// DAG Combiner.
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
unsigned Depth = 0) const;
-
+
struct DAGCombinerInfo {
void *DC; // The DAG Combiner object.
bool BeforeLegalize;
bool CalledByLegalizer;
public:
SelectionDAG &DAG;
-
+
DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc)
: DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo),
CalledByLegalizer(cl), DAG(dag) {}
-
+
bool isBeforeLegalize() const { return BeforeLegalize; }
bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; }
bool isCalledByLegalizer() const { return CalledByLegalizer; }
-
+
void AddToWorklist(SDNode *N);
SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
bool AddTo = true);
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
- /// SimplifySetCC - Try to simplify a setcc built with the specified operands
+ /// SimplifySetCC - Try to simplify a setcc built with the specified operands
/// and cc. If it is unable to simplify it, return a null SDValue.
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
/// node is a GlobalAddress + offset.
virtual bool
- isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const;
-
- /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
- /// location that is 'Dist' units away from the location that the 'Base' load
- /// is loading from.
- bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes,
- int Dist, const MachineFrameInfo *MFI) const;
+ isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
/// PerformDAGCombine - This method will be invoked for all target nodes and
/// for any target-independent nodes that the target has registered with
/// more complex transformations.
///
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
-
+
+ /// isTypeDesirableForOp - Return true if the target has native support for
+ /// the specified value type and it is 'desirable' to use the type for the
+ /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
+ /// instruction encodings are longer and some i16 instructions are slow.
+ virtual bool isTypeDesirableForOp(unsigned Opc, EVT VT) const {
+ // By default, assume all legal types are desirable.
+ return isTypeLegal(VT);
+ }
+
+ /// IsDesirableToPromoteOp - This method query the target whether it is
+ /// beneficial for dag combiner to promote the specified node. If true, it
+ /// should return the desired promotion type by reference.
+ virtual bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
//
protected:
- /// setUsesGlobalOffsetTable - Specify that this target does or doesn't use a
- /// GOT for PC-relative code.
- void setUsesGlobalOffsetTable(bool V) { UsesGlobalOffsetTable = V; }
-
/// setShiftAmountType - Describe the type that should be used for shift
/// amounts. This type defaults to the pointer type.
void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
/// setSchedulingPreference - Specify the target scheduling preference.
- void setSchedulingPreference(SchedPreference Pref) {
+ void setSchedulingPreference(Sched::Preference Pref) {
SchedPreferenceInfo = Pref;
}
void setStackPointerRegisterToSaveRestore(unsigned R) {
StackPointerRegisterToSaveRestore = R;
}
-
+
/// setExceptionPointerRegister - If set to a physical register, this sets
/// the register that receives the exception address on entry to a landing
/// pad.
/// expensive, and if possible, should be replaced by an alternate sequence
/// of instructions not containing an integer divide.
void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
-
+
/// setPow2DivIsCheap - Tells the code generator that it shouldn't generate
/// srl/add/sra for a signed divide by power of two, and let the target handle
/// it.
void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
-
+
/// 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(EVT VT, TargetRegisterClass *RC) {
+ void addRegisterClass(EVT VT, TargetRegisterClass *RC,
+ bool isSynthesizable = true) {
assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
AvailableRegClasses.push_back(std::make_pair(VT, RC));
RegClassForVT[VT.getSimpleVT().SimpleTy] = RC;
+ Synthesizable[VT.getSimpleVT().SimpleTy] = isSynthesizable;
}
/// computeRegisterProperties - Once all of the register classes are added,
/// with the specified type and indicate what to do about it.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
- unsigned I = (unsigned)VT.SimpleTy;
- unsigned J = I & 31;
- I = I >> 5;
- OpActions[I][Op] &= ~(uint64_t(3UL) << (J*2));
- OpActions[I][Op] |= (uint64_t)Action << (J*2);
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
}
-
+
/// setLoadExtAction - Indicate that the specified load with extension does
- /// not work with the with specified type and indicate what to do about it.
+ /// not work with the specified type and indicate what to do about it.
void setLoadExtAction(unsigned ExtType, MVT VT,
- LegalizeAction Action) {
- assert((unsigned)VT.SimpleTy < sizeof(LoadExtActions[0])*4 &&
- ExtType < array_lengthof(LoadExtActions) &&
+ LegalizeAction Action) {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
+ (unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.SimpleTy*2);
- LoadExtActions[ExtType] |= (uint64_t)Action << VT.SimpleTy*2;
+ LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
}
-
+
/// setTruncStoreAction - Indicate that the specified truncating store does
- /// not work with the with specified type and indicate what to do about it.
+ /// not work with the specified type and indicate what to do about it.
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
- assert((unsigned)ValVT.SimpleTy < array_lengthof(TruncStoreActions) &&
- (unsigned)MemVT.SimpleTy < sizeof(TruncStoreActions[0])*4 &&
+ assert((unsigned)ValVT.SimpleTy < MVT::LAST_VALUETYPE &&
+ (unsigned)MemVT.SimpleTy < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- TruncStoreActions[ValVT.SimpleTy] &= ~(uint64_t(3UL) << MemVT.SimpleTy*2);
- TruncStoreActions[ValVT.SimpleTy] |= (uint64_t)Action << MemVT.SimpleTy*2;
+ TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
}
/// setIndexedLoadAction - Indicate that the specified indexed load does or
- /// does not work with the with specified type and indicate what to do abort
+ /// does not work with the specified type and indicate what to do abort
/// it. NOTE: All indexed mode loads are initialized to Expand in
/// TargetLowering.cpp
void setIndexedLoadAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
- IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
+ IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf &&
"Table isn't big enough!");
- IndexedModeActions[(unsigned)VT.SimpleTy][0][IdxMode] = (uint8_t)Action;
+ // Load action are kept in the upper half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4;
}
-
+
/// setIndexedStoreAction - Indicate that the specified indexed store does or
- /// does not work with the with specified type and indicate what to do about
+ /// does not work with the specified type and indicate what to do about
/// it. NOTE: All indexed mode stores are initialized to Expand in
/// TargetLowering.cpp
void setIndexedStoreAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
- IdxMode < array_lengthof(IndexedModeActions[0][1] ) &&
- "Table isn't big enough!");
- IndexedModeActions[(unsigned)VT.SimpleTy][1][IdxMode] = (uint8_t)Action;
- }
-
- /// setConvertAction - Indicate that the specified conversion does or does
- /// not work with the with specified type and indicate what to do about it.
- void setConvertAction(MVT FromVT, MVT ToVT,
- LegalizeAction Action) {
- assert((unsigned)FromVT.SimpleTy < array_lengthof(ConvertActions) &&
- (unsigned)ToVT.SimpleTy < sizeof(ConvertActions[0])*4 &&
+ IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf &&
"Table isn't big enough!");
- ConvertActions[FromVT.SimpleTy] &= ~(uint64_t(3UL) << ToVT.SimpleTy*2);
- ConvertActions[FromVT.SimpleTy] |= (uint64_t)Action << ToVT.SimpleTy*2;
+ // Store action are kept in the lower half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action);
}
/// 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.SimpleTy < sizeof(CondCodeActions[0])*4 &&
+ assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
(unsigned)CC < array_lengthof(CondCodeActions) &&
"Table isn't big enough!");
CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.SimpleTy*2);
PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy;
}
- /// addLegalFPImmediate - Indicate that this target can instruction select
- /// the specified FP immediate natively.
- void addLegalFPImmediate(const APFloat& Imm) {
- LegalFPImmediates.push_back(Imm);
- }
-
/// setTargetDAGCombine - Targets should invoke this method for each target
/// independent node that they want to provide a custom DAG combiner for by
/// implementing the PerformDAGCombine virtual method.
assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
}
-
+
/// setJumpBufSize - Set the target's required jmp_buf buffer size (in
/// bytes); default is 200
void setJumpBufSize(unsigned Size) {
JumpBufAlignment = Align;
}
- /// setIfCvtBlockSizeLimit - Set the target's if-conversion block size
- /// limit (in number of instructions); default is 2.
- void setIfCvtBlockSizeLimit(unsigned Limit) {
- IfCvtBlockSizeLimit = Limit;
- }
-
- /// setIfCvtDupBlockSizeLimit - Set the target's block size limit (in number
- /// of instructions) to be considered for code duplication during
- /// if-conversion; default is 2.
- void setIfCvtDupBlockSizeLimit(unsigned Limit) {
- IfCvtDupBlockSizeLimit = Limit;
- }
-
/// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
/// alignment is zero, it means the target does not care about loop alignment.
void setPrefLoopAlignment(unsigned Align) {
PrefLoopAlignment = Align;
}
-
-public:
- virtual const TargetSubtarget *getSubtarget() {
- assert(0 && "Not Implemented");
- return NULL; // this is here to silence compiler errors
+ /// setShouldFoldAtomicFences - Set if the target's implementation of the
+ /// atomic operation intrinsics includes locking. Default is false.
+ void setShouldFoldAtomicFences(bool fold) {
+ ShouldFoldAtomicFences = fold;
}
+public:
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
// the SelectionDAGLowering code knows how to lower these.
///
virtual SDValue
LowerFormalArguments(SDValue Chain,
- unsigned CallConv, bool isVarArg,
+ CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals) {
+ SmallVectorImpl<SDValue> &InVals) const {
assert(0 && "Not Implemented");
return SDValue(); // this is here to silence compiler errors
}
std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned NumFixedArgs,
- unsigned CallConv, bool isTailCall, bool isReturnValueUsed,
- SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl);
+ CallingConv::ID CallConv, bool isTailCall,
+ bool isReturnValueUsed, SDValue Callee, ArgListTy &Args,
+ SelectionDAG &DAG, DebugLoc dl) const;
/// LowerCall - This hook must be implemented to lower calls into the
/// the specified DAG. The outgoing arguments to the call are described
/// described by the Ins array. The implementation should fill in the
/// InVals array with legal-type return values from the call, and return
/// the resulting token chain value.
- ///
- /// The isTailCall flag here is normative. If it is true, the
- /// implementation must emit a tail call. The
- /// IsEligibleForTailCallOptimization hook should be used to catch
- /// cases that cannot be handled.
- ///
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- unsigned CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals) {
+ SmallVectorImpl<SDValue> &InVals) const {
assert(0 && "Not Implemented");
return SDValue(); // this is here to silence compiler errors
}
+ /// CanLowerReturn - This hook should be implemented to check whether the
+ /// return values described by the Outs array can fit into the return
+ /// registers. If false is returned, an sret-demotion is performed.
+ ///
+ virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<EVT> &OutTys,
+ const SmallVectorImpl<ISD::ArgFlagsTy> &ArgsFlags,
+ LLVMContext &Context) const
+ {
+ // Return true by default to get preexisting behavior.
+ return true;
+ }
+
/// LowerReturn - This hook must be implemented to lower outgoing
/// return values, described by the Outs array, into the specified
/// DAG. The implementation should return the resulting token chain
/// value.
///
virtual SDValue
- LowerReturn(SDValue Chain, unsigned CallConv, bool isVarArg,
+ LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
- DebugLoc dl, SelectionDAG &DAG) {
+ const SmallVectorImpl<SDValue> &OutVals,
+ DebugLoc dl, SelectionDAG &DAG) const {
assert(0 && "Not Implemented");
return SDValue(); // this is here to silence compiler errors
}
- /// 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
- /// 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
- /// emit any calls and is strongly encouraged to attempt to emit inline code
- /// even if it is beyond the usual threshold because this intrinsic is being
- /// 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 SDValue
- EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
- 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 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
- /// SDValue if the target declines to use custom code and a different
- /// lowering strategy should be used.
- virtual SDValue
- EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain,
- SDValue Op1, SDValue Op2,
- SDValue Op3, unsigned Align,
- const Value *DstSV, uint64_t DstOff,
- const Value *SrcSV, uint64_t SrcOff) {
- 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
- /// SDValue if the target declines to use custom code and a different
- /// lowering strategy should be used.
- virtual SDValue
- EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain,
- SDValue Op1, SDValue Op2,
- SDValue Op3, unsigned Align,
- const Value *DstSV, uint64_t DstOff) {
- return SDValue();
- }
-
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.
/// The default implementation calls LowerOperation.
virtual void LowerOperationWrapper(SDNode *N,
SmallVectorImpl<SDValue> &Results,
- SelectionDAG &DAG);
+ SelectionDAG &DAG) const;
- /// LowerOperation - This callback is invoked for operations that are
+ /// LowerOperation - This callback is invoked for operations that are
/// unsupported by the target, which are registered to use 'custom' lowering,
/// 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 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
/// ReplaceNodeResults - This callback is invoked when a node result type is
/// illegal for the target, and the operation was registered to use 'custom'
/// If the target has no operations that require custom lowering, it need not
/// implement this. The default implementation aborts.
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG) const {
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(SDValue Callee,
- unsigned CalleeCC,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- SelectionDAG& DAG) const {
- // Conservative default: no calls are eligible.
- return false;
- }
-
- /// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if
- /// it exists. Skip a possible ISD::TokenFactor.
- static SDValue GetPossiblePreceedingTailCall(SDValue Chain,
- unsigned TailCallNodeOpCode) {
- if (Chain.getOpcode() == TailCallNodeOpCode) {
- return Chain;
- } else if (Chain.getOpcode() == ISD::TokenFactor) {
- if (Chain.getNumOperands() &&
- Chain.getOperand(0).getOpcode() == TailCallNodeOpCode)
- return Chain.getOperand(0);
- }
- return Chain;
- }
-
/// getTargetNodeName() - This method returns the name of a target specific
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
/// or null if the target does not support "fast" ISel.
virtual FastISel *
createFastISel(MachineFunction &,
- MachineModuleInfo *, DwarfWriter *,
DenseMap<const Value *, unsigned> &,
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
- DenseMap<const AllocaInst *, int> &
+ DenseMap<const AllocaInst *, int> &,
+ std::vector<std::pair<MachineInstr*, unsigned> > &
#ifndef NDEBUG
- , SmallSet<Instruction*, 8> &CatchInfoLost
+ , SmallSet<const Instruction *, 8> &CatchInfoLost
#endif
- ) {
+ ) const {
return 0;
}
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
//
-
+
/// ExpandInlineAsm - This hook allows the target to expand an inline asm
/// call to be explicit llvm code if it wants to. This is useful for
/// turning simple inline asms into LLVM intrinsics, which gives the
virtual bool ExpandInlineAsm(CallInst *CI) const {
return false;
}
-
+
enum ConstraintType {
C_Register, // Constraint represents specific register(s).
C_RegisterClass, // Constraint represents any of register(s) in class.
C_Other, // Something else.
C_Unknown // Unsupported constraint.
};
-
+
/// AsmOperandInfo - This contains information for each constraint that we are
/// lowering.
struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
/// ConstraintType - Information about the constraint code, e.g. Register,
/// RegisterClass, Memory, Other, Unknown.
TargetLowering::ConstraintType ConstraintType;
-
+
/// CallOperandval - If this is the result output operand or a
/// clobber, this is null, otherwise it is the incoming operand to the
/// CallInst. This gets modified as the asm is processed.
Value *CallOperandVal;
-
+
/// ConstraintVT - The ValueType for the operand value.
EVT 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),
+ : InlineAsm::ConstraintInfo(info),
ConstraintType(TargetLowering::C_Unknown),
CallOperandVal(0), ConstraintVT(MVT::Other) {
}
/// 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 SDValue can be passed. If hasMemory is true it means one of the asm
- /// constraint of the inline asm instruction being processed is 'm'.
+ /// empty SDValue can be passed.
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
SDValue Op,
- bool hasMemory,
SelectionDAG *DAG = 0) const;
-
+
/// getConstraintType - Given a constraint, return the type of constraint it
/// is for this target.
virtual ConstraintType getConstraintType(const std::string &Constraint) const;
-
+
/// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
/// return a list of registers that can be used to satisfy the constraint.
/// This should only be used for C_RegisterClass constraints.
- virtual std::vector<unsigned>
+ virtual std::vector<unsigned>
getRegClassForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const;
///
/// This should only be used for C_Register constraints. On error,
/// this returns a register number of 0 and a null register class pointer..
- virtual std::pair<unsigned, const TargetRegisterClass*>
+ virtual std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const;
-
+
/// LowerXConstraint - try to replace an X constraint, which matches anything,
/// with another that has more specific requirements based on the type of the
/// corresponding operand. This returns null if there is no replacement to
/// make.
virtual const char *LowerXConstraint(EVT ConstraintVT) const;
-
+
/// LowerAsmOperandForConstraint - Lower the specified operand into the 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'.
+ /// vector. If it is invalid, don't add anything to Ops.
virtual void LowerAsmOperandForConstraint(SDValue Op, char ConstraintLetter,
- bool hasMemory,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
-
+
//===--------------------------------------------------------------------===//
- // Scheduler hooks
+ // Instruction Emitting Hooks
//
-
+
// EmitInstrWithCustomInserter - This method should be implemented by targets
- // that mark instructions with the 'usesCustomDAGSchedInserter' flag. These
+ // that mark instructions with the 'usesCustomInserter' flag. These
// instructions are special in various ways, which require special support to
// insert. The specified MachineInstr is created but not inserted into any
- // basic blocks, and the scheduler passes ownership of it to this method.
- virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
- MachineBasicBlock *MBB) const;
+ // basic blocks, and this method is called to expand it into a sequence of
+ // instructions, potentially also creating new basic blocks and control flow.
+ virtual MachineBasicBlock *
+ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
//===--------------------------------------------------------------------===//
// Addressing mode description hooks (used by LSR etc).
int64_t Scale;
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
-
+
/// isLegalAddressingMode - Return true if the addressing mode represented by
/// AM is legal for this target, for a load/store of the specified type.
/// The type may be VoidTy, in which case only return true if the addressing
}
/// isZExtFree - Return true if any actual instruction that defines a
- /// value of type Ty1 implicit zero-extends the value to Ty2 in the result
+ /// value of type Ty1 implicitly zero-extends the value to Ty2 in the result
/// register. This does not necessarily include registers defined in
/// unknown ways, such as incoming arguments, or copies from unknown
/// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this
return false;
}
+ /// isLegalICmpImmediate - Return true if the specified immediate is legal
+ /// icmp immediate, that is the target has icmp instructions which can compare
+ /// a register against the immediate without having to materialize the
+ /// immediate into a register.
+ virtual bool isLegalICmpImmediate(int64_t Imm) const {
+ return true;
+ }
+
//===--------------------------------------------------------------------===//
// Div utility functions
//
- SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const;
- SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG,
std::vector<SDNode*>* Created) const;
return CmpLibcallCCs[Call];
}
+ /// setLibcallCallingConv - Set the CallingConv that should be used for the
+ /// specified libcall.
+ void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
+ LibcallCallingConvs[Call] = CC;
+ }
+
+ /// getLibcallCallingConv - Get the CallingConv that should be used for the
+ /// specified libcall.
+ CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
+ return LibcallCallingConvs[Call];
+ }
+
private:
- TargetMachine &TM;
+ const TargetMachine &TM;
const TargetData *TD;
- TargetLoweringObjectFile &TLOF;
+ const TargetLoweringObjectFile &TLOF;
/// PointerTy - The type to use for pointers, usually i32 or i64.
///
///
bool IsLittleEndian;
- /// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen.
- ///
- bool UsesGlobalOffsetTable;
-
/// SelectIsExpensive - Tells the code generator not to expand operations
/// into sequences that use the select operations if possible.
bool SelectIsExpensive;
/// a real cost model is in place. If we ever optimize for size, this will be
/// set to true unconditionally.
bool IntDivIsCheap;
-
+
/// Pow2DivIsCheap - Tells the code generator that it shouldn't generate
/// srl/add/sra for a signed divide by power of two, and let the target handle
/// it.
bool Pow2DivIsCheap;
-
+
/// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
/// llvm.setjmp. Defaults to false.
bool UseUnderscoreSetJmp;
/// SchedPreferenceInfo - The target scheduling preference: shortest possible
/// total cycles or lowest register usage.
- SchedPreference SchedPreferenceInfo;
-
+ Sched::Preference SchedPreferenceInfo;
+
/// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
unsigned JumpBufSize;
-
+
/// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf
/// buffers
unsigned JumpBufAlignment;
- /// IfCvtBlockSizeLimit - The maximum allowed size for a block to be
- /// if-converted.
- unsigned IfCvtBlockSizeLimit;
-
- /// IfCvtDupBlockSizeLimit - The maximum allowed size for a block to be
- /// duplicated during if-conversion.
- unsigned IfCvtDupBlockSizeLimit;
-
/// PrefLoopAlignment - The perferred loop alignment.
///
unsigned PrefLoopAlignment;
+ /// ShouldFoldAtomicFences - Whether fencing MEMBARRIER instructions should
+ /// be folded into the enclosed atomic intrinsic instruction by the
+ /// combiner.
+ bool ShouldFoldAtomicFences;
+
/// StackPointerRegisterToSaveRestore - If set to a physical register, this
/// specifies the register that llvm.savestack/llvm.restorestack should save
/// and restore.
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
+ /// Synthesizable indicates whether it is OK for the compiler to create new
+ /// operations using this type. All Legal types are Synthesizable except
+ /// MMX types on X86. Non-Legal types are not Synthesizable.
+ bool Synthesizable[MVT::LAST_VALUETYPE];
+
/// 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
/// 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.
- /// This array is accessed using VT.getSimpleVT(), so it is subject to
- /// the MVT::MAX_ALLOWED_VALUETYPE * 2 bits.
- uint64_t OpActions[MVT::MAX_ALLOWED_VALUETYPE/(sizeof(uint64_t)*4)][ISD::BUILTIN_OP_END];
-
- /// LoadExtActions - For each load of load extension type and each value type,
+ uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
+
+ /// LoadExtActions - For each load extension type and each value type,
/// keep a LegalizeAction that indicates how instruction selection should deal
- /// with the load.
- 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.
- uint64_t TruncStoreActions[MVT::LAST_VALUETYPE];
+ /// with a load of a specific value type and extension type.
+ uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
+
+ /// TruncStoreActions - For each value type pair keep a LegalizeAction that
+ /// indicates whether a truncating store of a specific value type and
+ /// truncating type is legal.
+ uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
/// IndexedModeActions - For each indexed mode and each value type,
/// keep a pair of LegalizeAction that indicates how instruction
- /// selection should deal with the load / store. The first
- /// dimension is now the value_type for the reference. The second
- /// dimension is the load [0] vs. store[1]. The third dimension
- /// represents the various modes for load store.
- uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][2][ISD::LAST_INDEXED_MODE];
-
- /// ConvertActions - For each conversion from source type to destination type,
- /// keep a LegalizeAction that indicates how instruction selection should
- /// deal with the conversion.
- /// Currently, this is used only for floating->floating conversions
- /// (FP_EXTEND and FP_ROUND).
- uint64_t ConvertActions[MVT::LAST_VALUETYPE];
+ /// selection should deal with the load / store. The first dimension is the
+ /// value_type for the reference. The second dimension represents the various
+ /// modes for load store.
+ uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE];
/// CondCodeActions - For each condition code (ISD::CondCode) keep a
/// LegalizeAction that indicates how instruction selection should
ValueTypeActionImpl ValueTypeActions;
- std::vector<APFloat> LegalFPImmediates;
-
std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses;
/// TargetDAGCombineArray - Targets can specify ISD nodes that they would
/// which sets a bit in this array.
unsigned char
TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT];
-
+
/// PromoteToType - For operations that must be promoted to a specific type,
/// this holds the destination type. This map should be sparse, so don't hold
/// it as an array.
/// of each of the comparison libcall against zero.
ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
+ /// LibcallCallingConvs - Stores the CallingConv that should be used for each
+ /// libcall.
+ CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
+
protected:
/// When lowering \@llvm.memset this field specifies the maximum number of
/// store operations that may be substituted for the call to memset. Targets
/// @brief Specify maximum bytes of store instructions per memmove call.
unsigned maxStoresPerMemmove;
- /// This field specifies whether the target machine permits unaligned memory
- /// accesses. This is used, for example, to determine the size of store
- /// operations when copying small arrays and other similar tasks.
- /// @brief Indicate whether the target permits unaligned memory accesses.
- bool allowUnalignedMemoryAccesses;
-
/// This field specifies whether the target can benefit from code placement
/// optimization.
bool benefitFromCodePlacementOpt;