#include "llvm/Constants.h"
#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/STLExtras.h"
#include <map>
#include <vector>
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 {
/// 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;}
+ /// 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 {
LegalizeAction getTypeAction(MVT VT) const {
if (VT.isExtended()) {
- if (VT.isVector()) return Expand;
+ if (VT.isVector()) {
+ // First try vector widening
+ return Promote;
+ }
if (VT.isInteger())
// First promote to a power-of-two size, then expand if necessary.
return VT == VT.getRoundIntegerType() ? Expand : Promote;
return NVT;
}
- if (VT.isVector())
- return MVT::getVectorVT(VT.getVectorElementType(),
- VT.getVectorNumElements() / 2);
- if (VT.isInteger()) {
+ if (VT.isVector()) {
+ unsigned NumElts = VT.getVectorNumElements();
+ MVT EltVT = VT.getVectorElementType();
+ return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ } else if (VT.isInteger()) {
MVT NVT = VT.getRoundIntegerType();
if (NVT == VT)
// Size is a power of two - expand to half the size.
MVT &IntermediateVT,
unsigned &NumIntermediates,
MVT &RegisterVT) const;
-
+
+ /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
+ /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
+ /// this is the case, it returns true and store the intrinsic
+ /// information into the IntrinsicInfo that was passed to the function.
+ typedef struct IntrinsicInfo {
+ unsigned opc; // target opcode
+ MVT memVT; // memory VT
+ const Value* ptrVal; // value representing memory location
+ int offset; // offset off of ptrVal
+ unsigned align; // alignment
+ bool vol; // is volatile?
+ bool readMem; // reads memory?
+ bool writeMem; // writes memory?
+ } IntrinisicInfo;
+
+ virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info,
+ CallInst &I, unsigned Intrinsic) {
+ return false;
+ }
+
+ /// getWidenVectorType: given a vector type, returns the type to widen to
+ /// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
+ /// If there is no vector type that we want to widen to, returns MVT::Other
+ /// When and were to widen is target dependent based on the cost of
+ /// scalarizing vs using the wider vector type.
+ virtual MVT getWidenVectorType(MVT VT);
+
typedef std::vector<APFloat>::const_iterator legal_fpimm_iterator;
legal_fpimm_iterator legal_fpimm_begin() const {
return LegalFPImmediates.begin();
getOperationAction(Op, VT) == Custom);
}
- /// getLoadXAction - Return how this load with extension should be treated:
+ /// getLoadExtAction - Return how this load with extension should be treated:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
- LegalizeAction getLoadXAction(unsigned LType, MVT VT) const {
- assert(LType < array_lengthof(LoadXActions) &&
- (unsigned)VT.getSimpleVT() < sizeof(LoadXActions[0])*4 &&
+ LegalizeAction getLoadExtAction(unsigned LType, MVT VT) const {
+ assert(LType < array_lengthof(LoadExtActions) &&
+ (unsigned)VT.getSimpleVT() < sizeof(LoadExtActions[0])*4 &&
"Table isn't big enough!");
- return (LegalizeAction)((LoadXActions[LType] >> (2*VT.getSimpleVT())) & 3);
+ return (LegalizeAction)((LoadExtActions[LType] >> (2*VT.getSimpleVT())) & 3);
}
- /// isLoadXLegal - Return true if the specified load with extension is legal
+ /// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
- bool isLoadXLegal(unsigned LType, MVT VT) const {
+ bool isLoadExtLegal(unsigned LType, MVT VT) const {
return VT.isSimple() &&
- (getLoadXAction(LType, VT) == Legal ||
- getLoadXAction(LType, VT) == Custom);
+ (getLoadExtAction(LType, VT) == Legal ||
+ getLoadExtAction(LType, VT) == Custom);
}
/// getTruncStoreAction - Return how this store with truncation should be
getConvertAction(FromVT, ToVT) == Custom);
}
+ /// getCondCodeAction - Return how the condition code should be treated:
+ /// either it is legal, needs to be expanded to some other code sequence,
+ /// or the target has a custom expander for it.
+ LegalizeAction
+ getCondCodeAction(ISD::CondCode CC, MVT VT) const {
+ assert((unsigned)CC < array_lengthof(CondCodeActions) &&
+ (unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ "Table isn't big enough!");
+ LegalizeAction Action = (LegalizeAction)
+ ((CondCodeActions[CC] >> (2*VT.getSimpleVT())) & 3);
+ assert(Action != Promote && "Can't promote condition code!");
+ return Action;
+ }
+
+ /// isCondCodeLegal - Return true if the specified condition code is legal
+ /// on this target.
+ bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+ return getCondCodeAction(CC, VT) == Legal ||
+ getCondCodeAction(CC, VT) == Custom;
+ }
+
+
/// getTypeToPromoteTo - If the action for this operation is to promote, this
/// method returns the ValueType to promote to.
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
virtual SDValue getPICJumpTableRelocBase(SDValue Table,
SelectionDAG &DAG) const;
+ /// isOffsetFoldingLegal - Return true if folding a constant offset
+ /// with the given GlobalAddress is legal. It is frequently not legal in
+ /// PIC relocation models.
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
/// 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;
/// 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.
/// amounts. This type defaults to the pointer type.
void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
- /// setSetCCResultContents - Specify how the target extends the result of a
- /// setcc operation in a register.
- void setSetCCResultContents(SetCCResultValue Ty) { SetCCResultContents = Ty; }
+ /// setBooleanContents - Specify how the target extends the result of a
+ /// boolean value from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
/// setSchedulingPreference - Specify the target scheduling preference.
void setSchedulingPreference(SchedPreference Pref) {
OpActions[Op] |= (uint64_t)Action << VT.getSimpleVT()*2;
}
- /// setLoadXAction - Indicate that the specified load with extension does not
- /// work with the with specified type and indicate what to do about it.
- void setLoadXAction(unsigned ExtType, MVT VT,
+ /// setLoadExtAction - Indicate that the specified load with extension does
+ /// not work with the with specified type and indicate what to do about it.
+ void setLoadExtAction(unsigned ExtType, MVT VT,
LegalizeAction Action) {
- assert((unsigned)VT.getSimpleVT() < sizeof(LoadXActions[0])*4 &&
- ExtType < array_lengthof(LoadXActions) &&
+ assert((unsigned)VT.getSimpleVT() < sizeof(LoadExtActions[0])*4 &&
+ ExtType < array_lengthof(LoadExtActions) &&
"Table isn't big enough!");
- LoadXActions[ExtType] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
- LoadXActions[ExtType] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
+ LoadExtActions[ExtType] |= (uint64_t)Action << VT.getSimpleVT()*2;
}
/// setTruncStoreAction - Indicate that the specified truncating store does
ToVT.getSimpleVT()*2;
}
+ /// setCondCodeAction - Indicate that the specified condition code is or isn't
+ /// supported on the target and indicate what to do about it.
+ void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action) {
+ assert((unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ (unsigned)CC < array_lengthof(CondCodeActions) &&
+ "Table isn't big enough!");
+ CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
+ CondCodeActions[(unsigned)CC] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ }
+
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
/// promotion code defaults to trying a larger integer/fp until it can find
/// one that works. If that default is insufficient, this method can be used
typedef std::vector<ArgListEntry> ArgListTy;
virtual std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
- bool isVarArg, unsigned CallingConv, bool isTailCall,
- SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
-
+ bool isVarArg, bool isInreg, unsigned CallingConv,
+ bool isTailCall, SDValue Callee, ArgListTy &Args,
+ SelectionDAG &DAG);
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases
/// 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
}
/// 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) {
MachineModuleInfo *,
DenseMap<const Value *, unsigned> &,
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
- DenseMap<const AllocaInst *, int> &) {
+ DenseMap<const AllocaInst *, int> &
+#ifndef NDEBUG
+ , SmallSet<Instruction*, 8> &CatchInfoLost
+#endif
+ ) {
return 0;
}
//
enum ConstraintType {
- C_Register, // Constraint represents a single register.
- C_RegisterClass, // Constraint represents one or more registers.
+ C_Register, // Constraint represents specific register(s).
+ C_RegisterClass, // Constraint represents any of register(s) in class.
C_Memory, // Memory constraint.
C_Other, // Something else.
C_Unknown // Unsupported constraint.
/// lowering.
struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
/// ConstraintCode - This contains the actual string for the code, like "m".
+ /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
+ /// most closely matches the operand.
std::string ConstraintCode;
/// ConstraintType - Information about the constraint code, e.g. Register,
/// ConstraintVT - The ValueType for the operand value.
MVT ConstraintVT;
+
+ /// isMatchingInputConstraint - Return true of this is an input operand that
+ /// is a matching constraint like "4".
+ bool isMatchingInputConstraint() const;
+
+ /// getMatchedOperand - If this is an input matching constraint, this method
+ /// returns the output operand it matches.
+ unsigned getMatchedOperand() const;
AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
: InlineAsm::ConstraintInfo(info),
OutOfRangeShiftAmount ShiftAmtHandling;
- /// 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.
MVT TransformToType[MVT::LAST_VALUETYPE];
// Defines the capacity of the TargetLowering::OpActions table
- static const int OpActionsCapacity = 212;
+ static const int OpActionsCapacity = 218;
/// OpActions - For each operation and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with the operation.
/// non-legal value types are not described here.
uint64_t OpActions[OpActionsCapacity];
- /// LoadXActions - For each load of load extension type and each value type,
+ /// LoadExtActions - For each load of load extension type and each value type,
/// keep a LegalizeAction that indicates how instruction selection should deal
/// with the load.
- uint64_t LoadXActions[ISD::LAST_LOADX_TYPE];
+ uint64_t LoadExtActions[ISD::LAST_LOADEXT_TYPE];
/// TruncStoreActions - For each truncating store, keep a LegalizeAction that
/// indicates how instruction selection should deal with the store.
/// (FP_EXTEND and FP_ROUND).
uint64_t ConvertActions[MVT::LAST_VALUETYPE];
+ /// CondCodeActions - For each condition code (ISD::CondCode) keep a
+ /// LegalizeAction that indicates how instruction selection should
+ /// deal with the condition code.
+ uint64_t CondCodeActions[ISD::SETCC_INVALID];
+
ValueTypeActionImpl ValueTypeActions;
std::vector<APFloat> LegalFPImmediates;