aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-02-11 20:01:10 -0800
committerStephen Hines <srhines@google.com>2014-02-11 20:01:10 -0800
commitce9904c6ea8fd669978a8eefb854b330eb9828ff (patch)
tree2418ee2e96ea220977c8fb74959192036ab5b133 /include/llvm/Target
parentc27b10b198c1d9e9b51f2303994313ec2778edd7 (diff)
parentdbb832b83351cec97b025b61c26536ef50c3181c (diff)
downloadexternal_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.zip
external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.gz
external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.bz2
Merge remote-tracking branch 'upstream/release_34' into merge-20140211
Conflicts: lib/Linker/LinkModules.cpp lib/Support/Unix/Signals.inc Change-Id: Ia54f291fa5dc828052d2412736e8495c1282aa64
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/CostTable.h35
-rw-r--r--include/llvm/Target/Mangler.h9
-rw-r--r--include/llvm/Target/Target.td31
-rw-r--r--include/llvm/Target/TargetCallingConv.h8
-rw-r--r--include/llvm/Target/TargetCallingConv.td6
-rw-r--r--include/llvm/Target/TargetInstrInfo.h41
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h17
-rw-r--r--include/llvm/Target/TargetLowering.h143
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h4
-rw-r--r--include/llvm/Target/TargetMachine.h13
-rw-r--r--include/llvm/Target/TargetOpcodes.h19
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h16
-rw-r--r--include/llvm/Target/TargetSchedule.td11
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td3
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h68
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h18
16 files changed, 375 insertions, 67 deletions
diff --git a/include/llvm/Target/CostTable.h b/include/llvm/Target/CostTable.h
index a974b56..34f6041 100644
--- a/include/llvm/Target/CostTable.h
+++ b/include/llvm/Target/CostTable.h
@@ -25,18 +25,25 @@ struct CostTblEntry {
unsigned Cost;
};
-/// Find in cost table, TypeTy must be comparable by ==
-template <class TypeTy>
-int CostTableLookup(const CostTblEntry<TypeTy> *Tbl,
- unsigned len, int ISD, TypeTy Ty) {
+/// Find in cost table, TypeTy must be comparable to CompareTy by ==
+template <class TypeTy, class CompareTy>
+int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, unsigned len, int ISD,
+ CompareTy Ty) {
for (unsigned int i = 0; i < len; ++i)
- if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty)
+ if (ISD == Tbl[i].ISD && Ty == Tbl[i].Type)
return i;
// Could not find an entry.
return -1;
}
+/// Find in cost table, TypeTy must be comparable to CompareTy by ==
+template <class TypeTy, class CompareTy, unsigned N>
+int CostTableLookup(const CostTblEntry<TypeTy>(&Tbl)[N], int ISD,
+ CompareTy Ty) {
+ return CostTableLookup(Tbl, N, ISD, Ty);
+}
+
/// Type Conversion Cost Table
template <class TypeTy>
struct TypeConversionCostTblEntry {
@@ -46,18 +53,28 @@ struct TypeConversionCostTblEntry {
unsigned Cost;
};
-/// Find in type conversion cost table, TypeTy must be comparable by ==
-template <class TypeTy>
+/// Find in type conversion cost table, TypeTy must be comparable to CompareTy
+/// by ==
+template <class TypeTy, class CompareTy>
int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl,
- unsigned len, int ISD, TypeTy Dst, TypeTy Src) {
+ unsigned len, int ISD, CompareTy Dst,
+ CompareTy Src) {
for (unsigned int i = 0; i < len; ++i)
- if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst)
+ if (ISD == Tbl[i].ISD && Src == Tbl[i].Src && Dst == Tbl[i].Dst)
return i;
// Could not find an entry.
return -1;
}
+/// Find in type conversion cost table, TypeTy must be comparable to CompareTy
+/// by ==
+template <class TypeTy, class CompareTy, unsigned N>
+int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy>(&Tbl)[N],
+ int ISD, CompareTy Dst, CompareTy Src) {
+ return ConvertCostTableLookup(Tbl, N, ISD, Dst, Src);
+}
+
} // namespace llvm
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index e925cd5..eee7bf6 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -20,7 +20,6 @@ namespace llvm {
class GlobalValue;
class MCContext;
-class MCSymbol;
template <typename T> class SmallVectorImpl;
class TargetMachine;
class Twine;
@@ -34,7 +33,6 @@ public:
};
private:
- MCContext &Context;
const TargetMachine *TM;
/// AnonGlobalIDs - We need to give global values the same name every time
@@ -48,12 +46,7 @@ private:
unsigned NextAnonGlobalID;
public:
- Mangler(MCContext &Context, const TargetMachine *TM)
- : Context(Context), TM(TM), NextAnonGlobalID(1) {}
-
- /// getSymbol - Return the MCSymbol for the specified global value. This
- /// symbol is the main label that is the address of the global.
- MCSymbol *getSymbol(const GlobalValue *GV);
+ Mangler(const TargetMachine *TM) : TM(TM), NextAnonGlobalID(1) {}
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified global variable's name. If the global variable doesn't
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 89ca529..3f6eae6 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -632,6 +632,11 @@ def f64imm : Operand<f64>;
///
def zero_reg;
+/// All operands which the MC layer classifies as predicates should inherit from
+/// this class in some manner. This is already handled for the most commonly
+/// used PredicateOperand, but may be useful in other circumstances.
+class PredicateOp;
+
/// OperandWithDefaultOps - This Operand class can be used as the parent class
/// for an Operand that needs to be initialized with a default value if
/// no value is supplied in a pattern. This class can be used to simplify the
@@ -647,7 +652,7 @@ class OperandWithDefaultOps<ValueType ty, dag defaultops>
/// AlwaysVal specifies the value of this predicate when set to "always
/// execute".
class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
- : OperandWithDefaultOps<ty, AlwaysVal> {
+ : OperandWithDefaultOps<ty, AlwaysVal>, PredicateOp {
let MIOperandInfo = OpTypes;
}
@@ -795,6 +800,19 @@ def LIFETIME_END : Instruction {
let AsmString = "LIFETIME_END";
let neverHasSideEffects = 1;
}
+def STACKMAP : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id, i32imm:$nbytes, variable_ops);
+ let isCall = 1;
+ let mayLoad = 1;
+}
+def PATCHPOINT : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins i32imm:$id, i32imm:$nbytes, unknown:$callee,
+ i32imm:$nargs, i32imm:$cc, variable_ops);
+ let isCall = 1;
+ let mayLoad = 1;
+}
}
//===----------------------------------------------------------------------===//
@@ -1005,6 +1023,17 @@ class SubtargetFeature<string n, string a, string v, string d,
list<SubtargetFeature> Implies = i;
}
+/// Specifies a Subtarget feature that this instruction is deprecated on.
+class Deprecated<SubtargetFeature dep> {
+ SubtargetFeature DeprecatedFeatureMask = dep;
+}
+
+/// A custom predicate used to determine if an instruction is
+/// deprecated or not.
+class ComplexDeprecationPredicate<string dep> {
+ string ComplexDeprecationPredicate = dep;
+}
+
//===----------------------------------------------------------------------===//
// Processor chip sets - These values represent each of the chip sets supported
// by the scheduler. Each Processor definition requires corresponding
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 1fd0bd9..9cc52a5 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -113,6 +113,7 @@ namespace ISD {
struct InputArg {
ArgFlagsTy Flags;
MVT VT;
+ EVT ArgVT;
bool Used;
/// Index original Function's argument.
@@ -124,10 +125,11 @@ namespace ISD {
unsigned PartOffset;
InputArg() : VT(MVT::Other), Used(false) {}
- InputArg(ArgFlagsTy flags, EVT vt, bool used,
+ InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
unsigned origIdx, unsigned partOffs)
: Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
VT = vt.getSimpleVT();
+ ArgVT = argvt;
}
};
@@ -138,6 +140,7 @@ namespace ISD {
struct OutputArg {
ArgFlagsTy Flags;
MVT VT;
+ EVT ArgVT;
/// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
bool IsFixed;
@@ -151,11 +154,12 @@ namespace ISD {
unsigned PartOffset;
OutputArg() : IsFixed(false) {}
- OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed,
+ OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
unsigned origIdx, unsigned partOffs)
: Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
PartOffset(partOffs) {
VT = vt.getSimpleVT();
+ ArgVT = argvt;
}
};
}
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index a53ed29..c1bef28 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -143,4 +143,10 @@ class CallingConv<list<CCAction> actions> {
/// returning from getCallPreservedMask().
class CalleeSavedRegs<dag saves> {
dag SaveList = saves;
+
+ // Registers that are also preserved across function calls, but should not be
+ // included in the generated FOO_SaveList array. These registers will be
+ // included in the FOO_RegMask bit mask. This can be used for registers that
+ // are saved automatically, like the SPARC register windows.
+ dag OtherPreserved;
}
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index f746daf..d4e14f6 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -181,6 +181,23 @@ public:
return false;
}
+ /// Compute the size in bytes and offset within a stack slot of a spilled
+ /// register or subregister.
+ ///
+ /// \param [out] Size in bytes of the spilled value.
+ /// \param [out] Offset in bytes within the stack slot.
+ /// \returns true if both Size and Offset are successfully computed.
+ ///
+ /// Not all subregisters have computable spill slots. For example,
+ /// subregisters registers may not be byte-sized, and a pair of discontiguous
+ /// subregisters has no single offset.
+ ///
+ /// Targets with nontrivial bigendian implementations may need to override
+ /// this, particularly to support spilled vector registers.
+ virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
+ unsigned &Size, unsigned &Offset,
+ const TargetMachine *TM) const;
+
/// reMaterialize - Re-issue the specified 'original' instruction at the
/// specific location targeting a new destination register.
/// The register in Orig->getOperand(0).getReg() will be substituted by
@@ -615,6 +632,8 @@ public:
return false;
}
+ virtual bool enableClusterLoads() const { return false; }
+
virtual bool shouldClusterLoads(MachineInstr *FirstLdSt,
MachineInstr *SecondLdSt,
unsigned NumLoads) const {
@@ -821,6 +840,8 @@ public:
const MachineInstr *MI,
unsigned *PredCost = 0) const;
+ virtual unsigned getPredicationCost(const MachineInstr *MI) const;
+
virtual int getInstrLatency(const InstrItineraryData *ItinData,
SDNode *Node) const;
@@ -938,6 +959,26 @@ public:
return 0;
}
+ /// \brief Return the minimum clearance before an instruction that reads an
+ /// unused register.
+ ///
+ /// For example, AVX instructions may copy part of an register operand into
+ /// the unused high bits of the destination register.
+ ///
+ /// vcvtsi2sdq %rax, %xmm0<undef>, %xmm14
+ ///
+ /// In the code above, vcvtsi2sdq copies %xmm0[127:64] into %xmm14 creating a
+ /// false dependence on any previous write to %xmm0.
+ ///
+ /// This hook works similarly to getPartialRegUpdateClearance, except that it
+ /// does not take an operand index. Instead sets \p OpNum to the index of the
+ /// unused register.
+ virtual unsigned getUndefRegClearance(const MachineInstr *MI, unsigned &OpNum,
+ const TargetRegisterInfo *TRI) const {
+ // The default implementation returns 0 for no undef register dependency.
+ return 0;
+ }
+
/// breakPartialRegDependency - Insert a dependency-breaking instruction
/// before MI to eliminate an unwanted dependency on OpNum.
///
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index 8c1f223..46eaef2 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -46,6 +46,10 @@ namespace llvm {
Znwm,
/// void *new(unsigned long, nothrow);
ZnwmRKSt9nothrow_t,
+ /// double __cospi(double x);
+ cospi,
+ /// float __cospif(float x);
+ cospif,
/// int __cxa_atexit(void (*f)(void *), void *p, void *d);
cxa_atexit,
/// void __cxa_guard_abort(guard_t *guard);
@@ -61,6 +65,14 @@ namespace llvm {
dunder_isoc99_sscanf,
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
memcpy_chk,
+ /// double __sincospi_stret(double x);
+ sincospi_stret,
+ /// float __sincospi_stretf(float x);
+ sincospi_stretf,
+ /// double __sinpi(double x);
+ sinpi,
+ /// float __sinpif(float x);
+ sinpif,
/// double __sqrt_finite(double x);
sqrt_finite,
/// float __sqrt_finite(float x);
@@ -695,10 +707,13 @@ public:
case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl:
+ case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl:
case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl:
case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l:
case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l:
- case LibFunc::memcmp:
+ case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy:
+ case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen:
+ case LibFunc::memchr:
return true;
}
return false;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index c3fa3cc..5ab04f7 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -148,10 +148,13 @@ public:
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
- // Return the pointer type for the given address space, defaults to
- // the pointer type from the data layout.
- // FIXME: The default needs to be removed once all the code is updated.
- virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const { return PointerTy; }
+
+ /// Return the pointer type for the given address space, defaults to
+ /// the pointer type from the data layout.
+ /// FIXME: The default needs to be removed once all the code is updated.
+ virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const;
+ unsigned getPointerSizeInBits(uint32_t AS = 0) const;
+ unsigned getPointerTypeSizeInBits(Type *Ty) const;
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
EVT getShiftAmountTy(EVT LHSTy) const;
@@ -201,6 +204,17 @@ public:
return PredictableSelectIsExpensive;
}
+ /// isLoadBitCastBeneficial() - Return true if the following transform
+ /// is beneficial.
+ /// fold (conv (load x)) -> (load (conv*)x)
+ /// On architectures that don't natively support some vector loads efficiently,
+ /// casting the load to a smaller vector of larger types and loading
+ /// is more efficient, however, this can be undone by optimizations in
+ /// dag combiner.
+ virtual bool isLoadBitCastBeneficial(EVT /* Load */, EVT /* Bitcast */) const {
+ return true;
+ }
+
/// 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
@@ -518,13 +532,12 @@ public:
LegalizeAction
getCondCodeAction(ISD::CondCode CC, MVT VT) const {
assert((unsigned)CC < array_lengthof(CondCodeActions) &&
- (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 &&
+ ((unsigned)VT.SimpleTy >> 4) < array_lengthof(CondCodeActions[0]) &&
"Table isn't big enough!");
- /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit
- /// value and the upper 27 bits index into the second dimension of the
- /// array to select what 64bit value to use.
- LegalizeAction Action = (LegalizeAction)
- ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3);
+ // See setCondCodeAction for how this is encoded.
+ uint32_t Shift = 2 * (VT.SimpleTy & 0xF);
+ uint32_t Value = CondCodeActions[CC][VT.SimpleTy >> 4];
+ LegalizeAction Action = (LegalizeAction) ((Value >> Shift) & 0x3);
assert(Action != Promote && "Can't promote condition code!");
return Action;
}
@@ -568,14 +581,18 @@ public:
/// otherwise it will assert.
EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
// Lower scalar pointers to native pointer types.
- if (Ty->isPointerTy()) return PointerTy;
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ return getPointerTy(PTy->getAddressSpace());
if (Ty->isVectorTy()) {
VectorType *VTy = cast<VectorType>(Ty);
Type *Elm = VTy->getElementType();
// Lower vectors of pointers to native pointer types.
- if (Elm->isPointerTy())
- Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext());
+ if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
+ EVT PointerTy(getPointerTy(PT->getAddressSpace()));
+ Elm = PointerTy.getTypeForEVT(Ty->getContext());
+ }
+
return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
VTy->getNumElements());
}
@@ -821,6 +838,11 @@ public:
return 0;
}
+ /// Returns true if a cast between SrcAS and DestAS is a noop.
+ virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
/// \name Helpers for TargetTransformInfo implementations
/// @{
@@ -1014,13 +1036,12 @@ protected:
assert(VT < MVT::LAST_VALUETYPE &&
(unsigned)CC < array_lengthof(CondCodeActions) &&
"Table isn't big enough!");
- /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit
- /// value and the upper 27 bits index into the second dimension of the
- /// array to select what 64bit value to use.
- CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5]
- &= ~(uint64_t(3UL) << (VT.SimpleTy & 0x1F)*2);
- CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5]
- |= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2;
+ /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 32-bit
+ /// value and the upper 27 bits index into the second dimension of the array
+ /// to select what 32-bit value to use.
+ uint32_t Shift = 2 * (VT.SimpleTy & 0xF);
+ CondCodeActions[CC][VT.SimpleTy >> 4] &= ~((uint32_t)0x3 << Shift);
+ CondCodeActions[CC][VT.SimpleTy >> 4] |= (uint32_t)Action << Shift;
}
/// If Opc/OrigVT is specified as being promoted, the promotion code defaults
@@ -1181,6 +1202,37 @@ public:
return false;
}
+ /// Return true if the target supplies and combines to a paired load
+ /// two loaded values of type LoadedType next to each other in memory.
+ /// RequiredAlignment gives the minimal alignment constraints that must be met
+ /// to be able to select this paired load.
+ ///
+ /// This information is *not* used to generate actual paired loads, but it is
+ /// used to generate a sequence of loads that is easier to combine into a
+ /// paired load.
+ /// For instance, something like this:
+ /// a = load i64* addr
+ /// b = trunc i64 a to i32
+ /// c = lshr i64 a, 32
+ /// d = trunc i64 c to i32
+ /// will be optimized into:
+ /// b = load i32* addr1
+ /// d = load i32* addr2
+ /// Where addr1 = addr2 +/- sizeof(i32).
+ ///
+ /// In other words, unless the target performs a post-isel load combining,
+ /// this information should not be provided because it will generate more
+ /// loads.
+ virtual bool hasPairedLoad(Type * /*LoadedType*/,
+ unsigned & /*RequiredAligment*/) const {
+ return false;
+ }
+
+ virtual bool hasPairedLoad(EVT /*LoadedType*/,
+ unsigned & /*RequiredAligment*/) const {
+ return false;
+ }
+
/// Return true if zero-extending the specific node Val to type VT2 is free
/// (either because it's implicitly zero-extended such as ARM ldrb / ldrh or
/// because it's folded such as X86 zero-extending loads).
@@ -1262,10 +1314,6 @@ private:
const DataLayout *TD;
const TargetLoweringObjectFile &TLOF;
- /// The type to use for pointers for the default address space, usually i32 or
- /// i64.
- MVT PointerTy;
-
/// True if this is a little endian target.
bool IsLittleEndian;
@@ -1414,9 +1462,9 @@ private:
/// indicates how instruction selection should deal with the condition code.
///
/// Because each CC action takes up 2 bits, we need to have the array size be
- /// large enough to fit all of the value types. This can be done by dividing
- /// the MVT::LAST_VALUETYPE by 32 and adding one.
- uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1];
+ /// large enough to fit all of the value types. This can be done by rounding
+ /// up the MVT::LAST_VALUETYPE value to the next multiple of 16.
+ uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 15) / 16];
ValueTypeActionImpl ValueTypeActions;
@@ -1471,10 +1519,12 @@ public:
if (NumElts == 1)
return LegalizeKind(TypeScalarizeVector, EltVT);
- // Try to widen vector elements until a legal type is found.
+ // Try to widen vector elements until the element type is a power of two and
+ // promote it to a legal type later on, for example:
+ // <3 x i8> -> <4 x i8> -> <4 x i32>
if (EltVT.isInteger()) {
// Vectors with a number of elements that is not a power of two are always
- // widened, for example <3 x float> -> <4 x float>.
+ // widened, for example <3 x i8> -> <4 x i8>.
if (!VT.isPow2VectorType()) {
NumElts = (unsigned)NextPowerOf2(NumElts);
EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts);
@@ -1503,7 +1553,8 @@ public:
// Stop trying when getting a non-simple element type.
// Note that vector elements may be greater than legal vector element
- // types. Example: X86 XMM registers hold 64bit element on 32bit systems.
+ // types. Example: X86 XMM registers hold 64bit element on 32bit
+ // systems.
if (!EltVT.isSimple()) break;
// Build a new vector type and check if it is legal.
@@ -1664,7 +1715,8 @@ public:
/// by reference if this node can be combined with a load / store to form a
/// post-indexed load / store.
virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
- SDValue &/*Base*/, SDValue &/*Offset*/,
+ SDValue &/*Base*/,
+ SDValue &/*Offset*/,
ISD::MemIndexedMode &/*AM*/,
SelectionDAG &/*DAG*/) const {
return false;
@@ -1702,9 +1754,12 @@ public:
SDValue &NewLHS, SDValue &NewRHS,
ISD::CondCode &CCCode, SDLoc DL) const;
- SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
- const SDValue *Ops, unsigned NumOps,
- bool isSigned, SDLoc dl) const;
+ /// Returns a pair of (return value, chain).
+ std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC,
+ EVT RetVT, const SDValue *Ops,
+ unsigned NumOps, bool isSigned,
+ SDLoc dl, bool doesNotReturn = false,
+ bool isReturnValueUsed = true) const;
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
@@ -1882,6 +1937,8 @@ public:
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
isSRet(false), isNest(false), isByVal(false), isReturned(false),
Alignment(0) { }
+
+ void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
};
typedef std::vector<ArgListEntry> ArgListTy;
@@ -2015,6 +2072,12 @@ public:
return VT.bitsLT(MinVT) ? MinVT : VT;
}
+ /// Returns a 0 terminated array of registers that can be safely used as
+ /// scratch registers.
+ virtual const uint16_t *getScratchRegisters(CallingConv::ID CC) const {
+ return NULL;
+ }
+
/// 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
@@ -2211,12 +2274,12 @@ public:
// Instruction Emitting Hooks
//
- // This method should be implemented by targets 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 this method is
- // called to expand it into a sequence of instructions, potentially also
- // creating new basic blocks and control flow.
+ /// This method should be implemented by targets 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 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;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 7f15b74..284b6bb 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -117,6 +117,10 @@ public:
MachineModuleInfo *MMI, unsigned Encoding,
MCStreamer &Streamer) const;
+ /// Return the MCSymbol for the specified global value. This symbol is the
+ /// main label that is the address of the global
+ MCSymbol *getSymbol(Mangler &M, const GlobalValue *GV) const;
+
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index fd7228a..11b0f5f 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -29,7 +29,6 @@ class GlobalValue;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
-class PassManagerBase;
class Target;
class DataLayout;
class TargetLibraryInfo;
@@ -47,6 +46,12 @@ class VectorTargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+}
+using legacy::PassManagerBase;
+
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
@@ -70,7 +75,8 @@ protected: // Can only create subclasses.
std::string TargetFS;
/// CodeGenInfo - Low level target information such as relocation model.
- const MCCodeGenInfo *CodeGenInfo;
+ /// Non-const to allow resetting optimization level per-function.
+ MCCodeGenInfo *CodeGenInfo;
/// AsmInfo - Contains target specific asm information.
///
@@ -208,6 +214,9 @@ public:
/// Default, or Aggressive.
CodeGenOpt::Level getOptLevel() const;
+ /// \brief Overrides the optimization level.
+ void setOptLevel(CodeGenOpt::Level Level) const;
+
void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 516e070..bd74cb9 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -69,8 +69,9 @@ namespace TargetOpcode {
DBG_VALUE = 11,
/// REG_SEQUENCE - This variadic instruction is used to form a register that
- /// represent a consecutive sequence of sub-registers. It's used as register
- /// coalescing / allocation aid and must be eliminated before code emission.
+ /// represents a consecutive sequence of sub-registers. It's used as a
+ /// register coalescing / allocation aid and must be eliminated before code
+ /// emission.
// In SDNode form, the first operand encodes the register class created by
// the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
// pair. Once it has been lowered to a MachineInstr, the regclass operand
@@ -91,7 +92,19 @@ namespace TargetOpcode {
/// Lifetime markers.
LIFETIME_START = 15,
- LIFETIME_END = 16
+ LIFETIME_END = 16,
+
+ /// A Stackmap instruction captures the location of live variables at its
+ /// position in the instruction stream. It is followed by a shadow of bytes
+ /// that must lie within the function and not contain another stackmap.
+ STACKMAP = 17,
+
+ /// Patchable call instruction - this instruction represents a call to a
+ /// constant address, followed by a series of NOPs. It is intended to
+ /// support optimizations for dynamic languages (such as javascript) that
+ /// rewrite calls to runtimes with more efficient code sequences.
+ /// This also implies a stack map.
+ PATCHPOINT = 18
};
} // end namespace TargetOpcode
} // end namespace llvm
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 82fccde..958bea6 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -901,6 +901,7 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
/// Usage: OS << PrintRegUnit(Unit, TRI) << '\n';
///
class PrintRegUnit {
+protected:
const TargetRegisterInfo *TRI;
unsigned Unit;
public:
@@ -914,6 +915,21 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) {
return OS;
}
+/// PrintVRegOrUnit - It is often convenient to track virtual registers and
+/// physical register units in the same list.
+class PrintVRegOrUnit : protected PrintRegUnit {
+public:
+ PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *tri)
+ : PrintRegUnit(VRegOrUnit, tri) {}
+ void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS,
+ const PrintVRegOrUnit &PR) {
+ PR.print(OS);
+ return OS;
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 575cb83..9d4858a 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -76,7 +76,7 @@ def instregex;
// See MCSchedule.h for detailed comments.
class SchedMachineModel {
int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
- int MinLatency = -1; // Determines which instrucions are allowed in a group.
+ int MinLatency = -1; // Determines which instructions are allowed in a group.
// (-1) inorder (0) ooo, (1): inorder +var latencies.
int MicroOpBufferSize = -1; // Max micro-ops that can be buffered.
int LoadLatency = -1; // Cycles for loads to access the cache.
@@ -86,6 +86,15 @@ class SchedMachineModel {
// Per-cycle resources tables.
ProcessorItineraries Itineraries = NoItineraries;
+ // Subtargets that define a model for only a subset of instructions
+ // that have a scheduling class (itinerary class or SchedRW list)
+ // and may actually be generated for that subtarget must clear this
+ // bit. Otherwise, the scheduler considers an unmodelled opcode to
+ // be an error. This should only be set during initial bringup,
+ // or there will be no way to catch simple errors in the model
+ // resulting from changes to the instruction definitions.
+ bit CompleteModel = 1;
+
bit NoModel = 0; // Special tag to indicate missing machine model.
}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index befab43..d94bdc6 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -383,6 +383,7 @@ def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>;
def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>;
def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>;
def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
+def frnd : SDNode<"ISD::FROUND" , SDTFPUnaryOp>;
def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>;
def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>;
@@ -464,6 +465,8 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
+def concat_vectors : SDNode<"ISD::CONCAT_VECTORS",
+ SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1, 2>]>,[]>;
// This operator does not do subvector type checking. The ARM
// backend, at least, needs it.
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index fe2fba4..3474ee4 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -94,6 +94,74 @@ public:
MachinePointerInfo DstPtrInfo) const {
return SDValue();
}
+
+ /// EmitTargetCodeForMemcmp - Emit target-specific code that performs a
+ /// memcmp, in cases where that is faster than a libcall. The first
+ /// returned SDValue is the result of the memcmp and the second is
+ /// the chain. Both SDValues can be null if a normal libcall should
+ /// be used.
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForMemcmp(SelectionDAG &DAG, SDLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, MachinePointerInfo Op1PtrInfo,
+ MachinePointerInfo Op2PtrInfo) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
+ /// EmitTargetCodeForMemchr - Emit target-specific code that performs a
+ /// memchr, in cases where that is faster than a libcall. The first
+ /// returned SDValue is the result of the memchr and the second is
+ /// the chain. Both SDValues can be null if a normal libcall should
+ /// be used.
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForMemchr(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
+ SDValue Src, SDValue Char, SDValue Length,
+ MachinePointerInfo SrcPtrInfo) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
+ /// EmitTargetCodeForStrcpy - Emit target-specific code that performs a
+ /// strcpy or stpcpy, in cases where that is faster than a libcall.
+ /// The first returned SDValue is the result of the copy (the start
+ /// of the destination string for strcpy, a pointer to the null terminator
+ /// for stpcpy) and the second is the chain. Both SDValues can be null
+ /// if a normal libcall should be used.
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Dest, SDValue Src,
+ MachinePointerInfo DestPtrInfo,
+ MachinePointerInfo SrcPtrInfo,
+ bool isStpcpy) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
+ /// EmitTargetCodeForStrcmp - Emit target-specific code that performs a
+ /// strcmp, in cases where that is faster than a libcall. The first
+ /// returned SDValue is the result of the strcmp and the second is
+ /// the chain. Both SDValues can be null if a normal libcall should
+ /// be used.
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ MachinePointerInfo Op1PtrInfo,
+ MachinePointerInfo Op2PtrInfo) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Src, MachinePointerInfo SrcPtrInfo) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrnlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Src, SDValue MaxLength,
+ MachinePointerInfo SrcPtrInfo) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
};
} // end llvm namespace
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index b2d405d..1b2e06a 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -25,6 +25,7 @@ class SDep;
class SUnit;
class TargetRegisterClass;
class TargetSchedModel;
+struct MachineSchedPolicy;
template <typename T> class SmallVectorImpl;
//===----------------------------------------------------------------------===//
@@ -55,6 +56,9 @@ public:
return 0;
}
+ /// \brief Temporary API to test migration to MI scheduler.
+ bool useMachineScheduler() const;
+
/// \brief True if the subtarget should run MachineScheduler after aggressive
/// coalescing.
///
@@ -62,6 +66,16 @@ public:
/// scheduler. It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
+ /// \brief Override generic scheduling policy within a region.
+ ///
+ /// This is a convenient way for targets that don't provide any custom
+ /// scheduling heuristics (no custom MachineSchedStrategy) to make
+ /// changes to the generic scheduling policy.
+ virtual void overrideSchedPolicy(MachineSchedPolicy &Policy,
+ MachineInstr *begin,
+ MachineInstr *end,
+ unsigned NumRegionInstrs) const {}
+
// enablePostRAScheduler - If the target can benefit from post-regalloc
// scheduling and the specified optimization level meets the requirement
// return true to enable post-register-allocation scheduling. In
@@ -75,6 +89,10 @@ public:
virtual void adjustSchedDependency(SUnit *def, SUnit *use,
SDep& dep) const { }
+ /// \brief Enable use of alias analysis during code generation (during MI
+ /// scheduling, DAGCombine, etc.).
+ virtual bool useAA() const;
+
/// \brief Reset the features for the subtarget.
virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
};