class TargetMachine;
class TargetRegisterClass;
class TargetSubtarget;
+ class TargetLoweringObjectFile;
class Value;
// FIXME: should this be here?
/// 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 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.
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.
/// 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 getSetCCResultType(MVT VT) const;
+ 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.
/// 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;
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);
/// 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; }
/// setBooleanContents - Specify how the target extends the result of a
/// boolean value from i1 to a wider type. See getBooleanContents.
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.
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, DebugLoc dl);
+ /// 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 NumFixedArgs,
- unsigned CallingConv, bool isTailCall, SDValue Callee,
- ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl);
+ 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
/// 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 {
+ /// 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;
}
- /// 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);
-
/// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if
/// it exists. Skip a possible ISD::TokenFactor.
static SDValue GetPossiblePreceedingTailCall(SDValue Chain,
// 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 specific register(s).
C_RegisterClass, // Constraint represents any of register(s) in class.
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;
/// BooleanContents - Information about the contents of the high-bits in
/// boolean values held in a type wider than i1. See getBooleanContents.