#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
-#include "llvm/Constants.h"
#include "llvm/InlineAsm.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/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/DebugLoc.h"
+#include "llvm/Target/TargetMachine.h"
+#include <climits>
#include <map>
#include <vector>
namespace llvm {
class AllocaInst;
+ class CallInst;
class Function;
class FastISel;
class MachineBasicBlock;
class MachineFrameInfo;
class MachineInstr;
class MachineModuleInfo;
+ class DwarfWriter;
class SDNode;
class SDValue;
class SelectionDAG;
class TargetMachine;
class TargetRegisterClass;
class TargetSubtarget;
+ class TargetLoweringObjectFile;
class Value;
- class VectorType;
+
+ // FIXME: should this be here?
+ namespace TLSModel {
+ enum Model {
+ GeneralDynamic,
+ LocalDynamic,
+ InitialExec,
+ LocalExec
+ };
+ }
+ TLSModel::Model getTLSModel(const GlobalValue *GV, Reloc::Model reloc);
+
//===----------------------------------------------------------------------===//
/// TargetLowering - This class defines information used to lower LLVM code to
/// target-specific constructs to SelectionDAG operators.
///
class TargetLowering {
+ TargetLowering(const TargetLowering&); // DO NOT IMPLEMENT
+ void operator=(const TargetLowering&); // DO NOT IMPLEMENT
public:
/// LegalizeAction - This enum indicates whether operations are valid for a
/// target, and if not, what action should be used to make them valid.
Custom // Use the LowerOperation hook to implement custom lowering.
};
- enum OutOfRangeShiftAmount {
- Undefined, // Oversized shift amounts are undefined (default).
- Mask, // Shift amounts are auto masked (anded) to value size.
- Extend // Oversized shift pulls in zeros or sign bits.
- };
-
- enum SetCCResultValue {
- UndefinedSetCCResult, // SetCC returns a garbage/unknown extend.
- ZeroOrOneSetCCResult, // SetCC returns a zero extended result.
- ZeroOrNegativeOneSetCCResult // SetCC returns a sign extended result.
+ 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 {
SchedulingForRegPressure // Scheduling for lowest register pressure.
};
- explicit TargetLowering(TargetMachine &TM);
+ /// NOTE: The constructor takes ownership of TLOF.
+ explicit TargetLowering(TargetMachine &TM, TargetLoweringObjectFile *TLOF);
virtual ~TargetLowering();
TargetMachine &getTargetMachine() const { return TM; }
const TargetData *getTargetData() const { return TD; }
+ 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; }
- OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; }
+ MVT::SimpleValueType getPointerTy() const { return PointerTy; }
+ MVT::SimpleValueType getShiftAmountTy() const { return ShiftAmountTy; }
/// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC
/// codegen.
/// srl/add/sra.
bool isPow2DivCheap() const { return Pow2DivIsCheap; }
- /// getSetCCResultType - Return the ValueType of the result of setcc
- /// operations.
- 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;}
+ /// getSetCCResultType - Return the ValueType of the result of SETCC
+ /// operations. Also used to obtain the target's preferred type for
+ /// the condition operand of SELECT and BRCOND nodes. In the case of
+ /// BRCOND the argument passed is MVT::Other since there are no other
+ /// operands to get a type hint from.
+ virtual
+ MVT::SimpleValueType getSetCCResultType(MVT VT) 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
+ /// 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 {
/// getRegClassFor - Return the register class that should be used for the
/// specified value type. This may only be called on legal types.
TargetRegisterClass *getRegClassFor(MVT VT) const {
- assert((unsigned)VT.getSimpleVT() < array_lengthof(RegClassForVT));
+ assert(VT.isSimple() && "getRegClassFor called on illegal type!");
TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT()];
assert(RC && "This value type is not natively supported!");
return RC;
/// 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)".
- uint32_t ValueTypeActions[2];
+ /// dimension by (MVT::MAX_ALLOWED_VALUETYPE/32) * 2
+ uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2];
public:
ValueTypeActionImpl() {
ValueTypeActions[0] = ValueTypeActions[1] = 0;
+ ValueTypeActions[2] = ValueTypeActions[3] = 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(MVT VT) const {
if (VT.isExtended()) {
- if (VT.isVector()) return Expand;
+ 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;
}
if (VT.isVector()) {
- unsigned NumElts = VT.getVectorNumElements();
- MVT EltVT = VT.getVectorElementType();
- return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ MVT NVT = VT.getPow2VectorType();
+ if (NVT == VT) {
+ // Vector length is a power of 2 - split to half the size.
+ unsigned NumElts = VT.getVectorNumElements();
+ MVT EltVT = VT.getVectorElementType();
+ return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ }
+ // Promote to a power of two size, avoiding multi-step promotion.
+ return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
} else if (VT.isInteger()) {
MVT NVT = VT.getRoundIntegerType();
if (NVT == VT)
return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
}
assert(0 && "Unsupported extended type!");
- return MVT(); // Not reached
+ return MVT(MVT::Other); // Not reached
}
/// getTypeToExpandTo - For types supported by the target, this is an
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) const;
+
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(SDValue Mask, MVT VT) const {
+ virtual bool isShuffleMaskLegal(const SmallVectorImpl<int> &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<SDValue> &BVOps,
- MVT EVT,
- SelectionDAG &DAG) const {
+ virtual bool isVectorClearMaskLegal(const SmallVectorImpl<int> &Mask,
+ MVT VT) const {
return false;
}
/// for it.
LegalizeAction getOperationAction(unsigned Op, MVT VT) const {
if (VT.isExtended()) return Expand;
- assert(Op < array_lengthof(OpActions) &&
- (unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*4 &&
+ assert(Op < array_lengthof(OpActions[0]) &&
+ (unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 &&
"Table isn't big enough!");
- return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3);
+ unsigned I = (unsigned) VT.getSimpleVT();
+ unsigned J = I & 31;
+ I = I >> 5;
+ return (LegalizeAction)((OpActions[I][Op] >> (J*2) ) & 3);
+ }
+
+ /// isOperationLegalOrCustom - Return true if the specified operation is
+ /// legal on this target or can be made legal with custom lowering. This
+ /// is used to help guide high-level lowering decisions.
+ bool isOperationLegalOrCustom(unsigned Op, MVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom);
}
/// isOperationLegal - Return true if the specified operation is legal on this
/// target.
bool isOperationLegal(unsigned Op, MVT VT) const {
return (VT == MVT::Other || isTypeLegal(VT)) &&
- (getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Custom);
+ getOperationAction(Op, VT) == Legal;
}
/// getLoadExtAction - Return how this load with extension should be treated:
/// for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
- assert(IdxMode < array_lengthof(IndexedModeActions[0]) &&
- (unsigned)VT.getSimpleVT() < sizeof(IndexedModeActions[0][0])*4 &&
+ assert( IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
+ ((unsigned)VT.getSimpleVT()) < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[0][IdxMode] >>
- (2*VT.getSimpleVT())) & 3);
+ return (LegalizeAction)((IndexedModeActions[(unsigned)VT.getSimpleVT()][0][IdxMode]));
}
/// isIndexedLoadLegal - Return true if the specified indexed load is legal
/// for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
- assert(IdxMode < array_lengthof(IndexedModeActions[1]) &&
- (unsigned)VT.getSimpleVT() < sizeof(IndexedModeActions[1][0])*4 &&
+ assert(IdxMode < array_lengthof(IndexedModeActions[0][1]) &&
+ (unsigned)VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)((IndexedModeActions[1][IdxMode] >>
- (2*VT.getSimpleVT())) & 3);
+ return (LegalizeAction)((IndexedModeActions[(unsigned)VT.getSimpleVT()][1][IdxMode]));
}
/// isIndexedStoreLegal - Return true if the specified indexed load is legal
return getRegisterType(getTypeToTransformTo(VT));
}
assert(0 && "Unsupported extended type!");
- return MVT(); // Not reached
+ return MVT(MVT::Other); // Not reached
}
/// getNumRegisters - Return the number of registers that this ValueType will
return allowUnalignedMemoryAccesses;
}
+ /// This function returns true if the target would benefit from code placement
+ /// optimization.
+ /// @brief Determine if the target should perform code placement optimization.
+ bool shouldOptimizeCodePlacement() const {
+ return benefitFromCodePlacementOpt;
+ }
+
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// It returns MVT::iAny if SelectionDAG should be responsible for
/// determining it.
virtual MVT getOptimalMemOpType(uint64_t Size, unsigned Align,
- bool isSrcConst, bool isSrcStr) const {
+ bool isSrcConst, bool isSrcStr,
+ SelectionDAG &DAG) const {
return MVT::iAny;
}
virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
SDValue &Offset,
ISD::MemIndexedMode &AM,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG) const {
return false;
}
virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
SDValue &Base, SDValue &Offset,
ISD::MemIndexedMode &AM,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG) const {
return false;
}
/// PIC relocation models.
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+ /// getFunctionAlignment - Return the Log2 alignment of this function.
+ virtual unsigned getFunctionAlignment(const Function *) const = 0;
+
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
/// that want to combine
struct TargetLoweringOpt {
SelectionDAG &DAG;
- bool AfterLegalize;
SDValue Old;
SDValue New;
- explicit TargetLoweringOpt(SelectionDAG &InDAG, bool afterLegalize)
- : DAG(InDAG), AfterLegalize(afterLegalize) {}
+ explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {}
bool CombineTo(SDValue O, SDValue N) {
Old = O;
/// there are any bits set in the constant that are not demanded. If so,
/// shrink the constant and return true.
bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
+
+ /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
+ /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
+ /// cast, but it could be generalized for targets with other types of
+ /// implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ DebugLoc dl);
};
/// SimplifyDemandedBits - Look at Op. At this point, we know that only the
struct DAGCombinerInfo {
void *DC; // The DAG Combiner object.
bool BeforeLegalize;
+ bool BeforeLegalizeOps;
bool CalledByLegalizer;
public:
SelectionDAG &DAG;
- DAGCombinerInfo(SelectionDAG &dag, bool bl, bool cl, void *dc)
- : DC(dc), BeforeLegalize(bl), CalledByLegalizer(cl), DAG(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);
- SDValue CombineTo(SDNode *N, SDValue Res);
- SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+ bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
+
+ void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
/// 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(MVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
- DAGCombinerInfo &DCI) const;
+ DAGCombinerInfo &DCI, DebugLoc dl) const;
/// 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 (which must be a LoadSDNode) is
- /// loading 'Bytes' bytes from a location that is 'Dist' units away from the
- /// location that the 'Base' load is loading from.
- bool isConsecutiveLoad(SDNode *LD, SDNode *Base, unsigned Bytes, int Dist,
- const MachineFrameInfo *MFI) 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;
/// PerformDAGCombine - This method will be invoked for all target nodes and
/// for any target-independent nodes that the target has registered with
/// Return Value:
/// 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.
+ /// otherwise - N should be replaced by the returned Operand.
///
/// In addition, methods provided by DAGCombinerInfo may be used to perform
/// more complex transformations.
/// 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 setShiftAmountType(MVT::SimpleValueType 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) {
SchedPreferenceInfo = Pref;
}
- /// setShiftAmountFlavor - Describe how the target handles out of range shift
- /// amounts.
- void setShiftAmountFlavor(OutOfRangeShiftAmount OORSA) {
- ShiftAmtHandling = OORSA;
- }
-
/// setUseUnderscoreSetJmp - Indicate whether this target prefers to
/// use _setjmp to implement llvm.setjmp or the non _ version.
/// Defaults to false.
/// with the specified type and indicate what to do about it.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
- assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*4 &&
- Op < array_lengthof(OpActions) && "Table isn't big enough!");
- OpActions[Op] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
- OpActions[Op] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 &&
+ Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ unsigned I = (unsigned) VT.getSimpleVT();
+ unsigned J = I & 31;
+ I = I >> 5;
+ OpActions[I][Op] &= ~(uint64_t(3UL) << (J*2));
+ OpActions[I][Op] |= (uint64_t)Action << (J*2);
}
/// setLoadExtAction - Indicate that the specified load with extension does
/// TargetLowering.cpp
void setIndexedLoadAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
- assert((unsigned)VT.getSimpleVT() < sizeof(IndexedModeActions[0])*4 &&
- IdxMode < array_lengthof(IndexedModeActions[0]) &&
+ assert((unsigned)VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ IdxMode < array_lengthof(IndexedModeActions[0][0]) &&
"Table isn't big enough!");
- IndexedModeActions[0][IdxMode] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
- IndexedModeActions[0][IdxMode] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ IndexedModeActions[(unsigned)VT.getSimpleVT()][0][IdxMode] = (uint8_t)Action;
}
/// setIndexedStoreAction - Indicate that the specified indexed store does or
/// TargetLowering.cpp
void setIndexedStoreAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
- assert((unsigned)VT.getSimpleVT() < sizeof(IndexedModeActions[1][0])*4 &&
- IdxMode < array_lengthof(IndexedModeActions[1]) &&
+ assert((unsigned)VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ IdxMode < array_lengthof(IndexedModeActions[0][1] ) &&
"Table isn't big enough!");
- IndexedModeActions[1][IdxMode] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
- IndexedModeActions[1][IdxMode] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ IndexedModeActions[(unsigned)VT.getSimpleVT()][1][IdxMode] = (uint8_t)Action;
}
/// setConvertAction - Indicate that the specified conversion does or does
assert(0 && "Not Implemented");
return NULL; // this is here to silence compiler errors
}
+
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
// the SelectionDAGLowering code knows how to lower these.
//
- /// LowerArguments - This hook must be implemented to indicate how we should
- /// lower the arguments for the specified function, into the specified DAG.
- virtual void
- LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue>& ArgValues);
+ /// LowerFormalArguments - This hook must be implemented to lower the
+ /// incoming (formal) arguments, described by the Ins array, into the
+ /// specified DAG. The implementation should fill in the InVals array
+ /// with legal-type argument values, and return the resulting token
+ /// chain value.
+ ///
+ virtual SDValue
+ LowerFormalArguments(SDValue Chain,
+ unsigned CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
+ assert(0 && "Not Implemented");
+ return SDValue(); // this is here to silence compiler errors
+ }
- /// LowerCallTo - This hook lowers an abstract call to a function into an
+ /// LowerCallTo - This function 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.
+ /// element is the outgoing token chain. It calls LowerCall to do the actual
+ /// lowering.
struct ArgListEntry {
SDValue Node;
const Type* Ty;
isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
};
typedef std::vector<ArgListEntry> ArgListTy;
- virtual std::pair<SDValue, SDValue>
+ 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);
+ bool isVarArg, bool isInreg, unsigned NumFixedArgs,
+ unsigned CallConv, bool isTailCall, bool isReturnValueUsed,
+ SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl);
+
+ /// LowerCall - This hook must be implemented to lower calls into the
+ /// the specified DAG. The outgoing arguments to the call are described
+ /// by the Outs array, and the values to be returned by the call are
+ /// 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,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
+ assert(0 && "Not Implemented");
+ return SDValue(); // this is here to silence compiler errors
+ }
+
+ /// 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,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ DebugLoc dl, SelectionDAG &DAG) {
+ 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
/// 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,
+ EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align,
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
- EmitTargetCodeForMemmove(SelectionDAG &DAG,
+ EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align,
/// SDValue if the target declines to use custom code and a different
/// lowering strategy should be used.
virtual SDValue
- EmitTargetCodeForMemset(SelectionDAG &DAG,
+ EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align,
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 reason we can not do away with LowerOperation entirely is that
+ /// LegalizeDAG isn't yet ready to use this callback.
+ /// TODO: Consider merging with ReplaceNodeResults.
+
+ /// 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.
+ /// The default implementation calls LowerOperation.
+ virtual void LowerOperationWrapper(SDNode *N,
+ SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG);
+
/// 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.
/// implement this. The default implementation of this aborts.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
- /// ReplaceNodeResults - This callback is invoked for operations that are
- /// unsupported by the target, which are registered to use 'custom' lowering,
- /// and whose result type is illegal. 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.
+ /// 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 aborts.
- virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
+ virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG) {
assert(0 && "ReplaceNodeResults not implemented for this target!");
- return 0;
}
/// 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(CallSDNode *Call,
- SDValue Ret,
- SelectionDAG &DAG) const {
- return false;
- }
-
- /// CheckTailCallReturnConstraints - Check whether CALL node immediatly
- /// 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(CallSDNode *TheCall, SDValue Ret) {
- unsigned NumOps = Ret.getNumOperands();
- if ((NumOps == 1 &&
- (Ret.getOperand(0) == SDValue(TheCall,1) ||
- Ret.getOperand(0) == SDValue(TheCall,0))) ||
- (NumOps > 1 &&
- Ret.getOperand(0) == SDValue(TheCall,
- TheCall->getNumValues()-1) &&
- Ret.getOperand(1) == SDValue(TheCall,0)))
- return true;
+ /// 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 possible ISD:TokenFactor.
+ /// it exists. Skip a possible ISD::TokenFactor.
static SDValue GetPossiblePreceedingTailCall(SDValue Chain,
unsigned TailCallNodeOpCode) {
if (Chain.getOpcode() == TailCallNodeOpCode) {
/// or null if the target does not support "fast" ISel.
virtual FastISel *
createFastISel(MachineFunction &,
- MachineModuleInfo *,
+ MachineModuleInfo *, DwarfWriter *,
DenseMap<const Value *, unsigned> &,
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
DenseMap<const AllocaInst *, int> &
// 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
+ /// compiler more information about the behavior of the code.
+ virtual bool ExpandInlineAsm(CallInst *CI) const {
+ return false;
+ }
+
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.
// 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);
+ MachineBasicBlock *MBB) const;
//===--------------------------------------------------------------------===//
// Addressing mode description hooks (used by LSR etc).
/// 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
+ /// mode is legal for a load/store of any legal type.
/// TODO: Handle pre/postinc as well.
virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty) const;
virtual bool isTruncateFree(MVT VT1, MVT VT2) const {
return false;
}
-
+
+ /// isZExtFree - Return true if any actual instruction that defines a
+ /// value of type Ty1 implicit 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
+ /// does not necessarily apply to truncate instructions. e.g. on x86-64,
+ /// all instructions that define 32-bit values implicit zero-extend the
+ /// result out to 64 bits.
+ virtual bool isZExtFree(const Type *Ty1, const Type *Ty2) const {
+ return false;
+ }
+
+ virtual bool isZExtFree(MVT VT1, MVT VT2) const {
+ return false;
+ }
+
+ /// isNarrowingProfitable - Return true if it's profitable to narrow
+ /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow
+ /// from i32 to i8 but not from i32 to i16.
+ virtual bool isNarrowingProfitable(MVT VT1, MVT VT2) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// Div utility functions
//
private:
TargetMachine &TM;
const TargetData *TD;
+ TargetLoweringObjectFile &TLOF;
/// PointerTy - The type to use for pointers, usually i32 or i64.
///
- MVT PointerTy;
+ MVT::SimpleValueType PointerTy;
/// IsLittleEndian - True if this is a little endian target.
///
/// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
/// PointerTy is.
- MVT ShiftAmountTy;
-
- OutOfRangeShiftAmount ShiftAmtHandling;
+ MVT::SimpleValueType ShiftAmountTy;
- /// SetCCResultContents - Information about the contents of the high-bits in
- /// the result of a setcc comparison operation.
- SetCCResultValue SetCCResultContents;
+ /// 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.
/// by the system, this holds the same type (e.g. i32 -> i32).
MVT TransformToType[MVT::LAST_VALUETYPE];
- // Defines the capacity of the TargetLowering::OpActions table
- static const int OpActionsCapacity = 212;
-
/// OpActions - For each operation and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with the operation.
/// Most operations are Legal (aka, supported natively by the target), but
/// operations that are not should be described. Note that operations on
/// non-legal value types are not described here.
- uint64_t OpActions[OpActionsCapacity];
+ /// 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,
/// keep a LegalizeAction that indicates how instruction selection should deal
/// indicates how instruction selection should deal with the store.
uint64_t TruncStoreActions[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.
- uint64_t IndexedModeActions[2][ISD::LAST_INDEXED_MODE];
+ /// 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
/// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
/// which sets a bit in this array.
unsigned char
- TargetDAGCombineArray[OpActionsCapacity/(sizeof(unsigned char)*8)];
+ 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
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
/// 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;
};
} // end llvm namespace