summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h76
-rw-r--r--include/llvm/CodeGen/CommandFlags.h8
-rw-r--r--include/llvm/CodeGen/DIE.h612
-rw-r--r--include/llvm/CodeGen/DIEValue.def47
-rw-r--r--include/llvm/CodeGen/GCMetadata.h2
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h4
-rw-r--r--include/llvm/CodeGen/MIRParser/MIRParser.h52
-rw-r--r--include/llvm/CodeGen/MIRYamlMapping.h40
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineInstr.h20
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h2
-rw-r--r--include/llvm/CodeGen/Passes.h15
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h4
-rw-r--r--include/llvm/CodeGen/WinEHFuncInfo.h7
15 files changed, 613 insertions, 292 deletions
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index d07265560430e..3e464f4f1e5a9 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -125,23 +125,24 @@ public:
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->isLegalAddressingMode(AM, Ty);
+ return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->getScalingFactorCost(AM, Ty);
+ return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) {
@@ -522,6 +523,73 @@ public:
return Cost;
}
+ unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) {
+ VectorType *VT = dyn_cast<VectorType>(VecTy);
+ assert(VT && "Expect a vector type for interleaved memory op");
+
+ unsigned NumElts = VT->getNumElements();
+ assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
+
+ unsigned NumSubElts = NumElts / Factor;
+ VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts);
+
+ // Firstly, the cost of load/store operation.
+ unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace);
+
+ // Then plus the cost of interleave operation.
+ if (Opcode == Instruction::Load) {
+ // The interleave cost is similar to extract sub vectors' elements
+ // from the wide vector, and insert them into sub vectors.
+ //
+ // E.g. An interleaved load of factor 2 (with one member of index 0):
+ // %vec = load <8 x i32>, <8 x i32>* %ptr
+ // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0
+ // The cost is estimated as extract elements at 0, 2, 4, 6 from the
+ // <8 x i32> vector and insert them into a <4 x i32> vector.
+
+ assert(Indices.size() <= Factor &&
+ "Interleaved memory op has too many members");
+ for (unsigned Index : Indices) {
+ assert(Index < Factor && "Invalid index for interleaved memory op");
+
+ // Extract elements from loaded vector for each sub vector.
+ for (unsigned i = 0; i < NumSubElts; i++)
+ Cost += getVectorInstrCost(Instruction::ExtractElement, VT,
+ Index + i * Factor);
+ }
+
+ unsigned InsSubCost = 0;
+ for (unsigned i = 0; i < NumSubElts; i++)
+ InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i);
+
+ Cost += Indices.size() * InsSubCost;
+ } else {
+ // The interleave cost is extract all elements from sub vectors, and
+ // insert them into the wide vector.
+ //
+ // E.g. An interleaved store of factor 2:
+ // %v0_v1 = shuffle %v0, %v1, <0, 4, 1, 5, 2, 6, 3, 7>
+ // store <8 x i32> %interleaved.vec, <8 x i32>* %ptr
+ // The cost is estimated as extract all elements from both <4 x i32>
+ // vectors and insert into the <8 x i32> vector.
+
+ unsigned ExtSubCost = 0;
+ for (unsigned i = 0; i < NumSubElts; i++)
+ ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i);
+
+ Cost += Factor * ExtSubCost;
+
+ for (unsigned i = 0; i < NumElts; i++)
+ Cost += getVectorInstrCost(Instruction::InsertElement, VT, i);
+ }
+
+ return Cost;
+ }
+
unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<Type *> Tys) {
unsigned ISD = 0;
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index a1b9b4e566a26..b824df3013d9e 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -24,6 +24,7 @@
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRecip.h"
#include <string>
using namespace llvm;
@@ -152,6 +153,12 @@ FuseFPOps("fp-contract",
"Only fuse FP ops when the result won't be effected."),
clEnumValEnd));
+cl::list<std::string>
+ReciprocalOps("recip",
+ cl::CommaSeparated,
+ cl::desc("Choose reciprocal operation types and parameters."),
+ cl::value_desc("all,none,default,divf,!vec-sqrtd,vec-divd:0,sqrt:9..."));
+
cl::opt<bool>
DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::desc("Don't place zero-initialized symbols into bss section"),
@@ -230,6 +237,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
TargetOptions Options;
Options.LessPreciseFPMADOption = EnableFPMAD;
Options.AllowFPOpFusion = FuseFPOps;
+ Options.Reciprocals = TargetRecip(ReciprocalOps);
Options.UnsafeFPMath = EnableUnsafeFPMath;
Options.NoInfsFPMath = EnableNoInfsFPMath;
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index 8e40ef77d374f..464e0faa0ed3c 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -105,153 +105,13 @@ public:
};
//===--------------------------------------------------------------------===//
-/// DIE - A structured debug information entry. Has an abbreviation which
-/// describes its organization.
-class DIEValue;
-
-class DIE {
-protected:
- /// Offset - Offset in debug info section.
- ///
- unsigned Offset;
-
- /// Size - Size of instance + children.
- ///
- unsigned Size;
-
- /// Abbrev - Buffer for constructing abbreviation.
- ///
- DIEAbbrev Abbrev;
-
- /// Children DIEs.
- ///
- // This can't be a vector<DIE> because pointer validity is requirent for the
- // Parent pointer and DIEEntry.
- // It can't be a list<DIE> because some clients need pointer validity before
- // the object has been added to any child list
- // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
- // be more convoluted than beneficial.
- std::vector<std::unique_ptr<DIE>> Children;
-
- DIE *Parent;
-
- /// Attribute values.
- ///
- SmallVector<DIEValue *, 12> Values;
-
-protected:
- DIE()
- : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no),
- Parent(nullptr) {}
-
-public:
- explicit DIE(dwarf::Tag Tag)
- : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
- Parent(nullptr) {}
-
- // Accessors.
- DIEAbbrev &getAbbrev() { return Abbrev; }
- const DIEAbbrev &getAbbrev() const { return Abbrev; }
- unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
- dwarf::Tag getTag() const { return Abbrev.getTag(); }
- unsigned getOffset() const { return Offset; }
- unsigned getSize() const { return Size; }
- const std::vector<std::unique_ptr<DIE>> &getChildren() const {
- return Children;
- }
- const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
- DIE *getParent() const { return Parent; }
- /// Climb up the parent chain to get the compile or type unit DIE this DIE
- /// belongs to.
- const DIE *getUnit() const;
- /// Similar to getUnit, returns null when DIE is not added to an
- /// owner yet.
- const DIE *getUnitOrNull() const;
- void setOffset(unsigned O) { Offset = O; }
- void setSize(unsigned S) { Size = S; }
-
- /// addValue - Add a value and attributes to a DIE.
- ///
- void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) {
- Abbrev.AddAttribute(Attribute, Form);
- Values.push_back(Value);
- }
-
- /// addChild - Add a child to the DIE.
- ///
- void addChild(std::unique_ptr<DIE> Child) {
- assert(!Child->getParent());
- Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
- Child->Parent = this;
- Children.push_back(std::move(Child));
- }
-
- /// findAttribute - Find a value in the DIE with the attribute given,
- /// returns NULL if no such attribute exists.
- DIEValue *findAttribute(dwarf::Attribute Attribute) const;
-
-#ifndef NDEBUG
- void print(raw_ostream &O, unsigned IndentCount = 0) const;
- void dump();
-#endif
-};
-
-//===--------------------------------------------------------------------===//
-/// DIEValue - A debug information entry value. Some of these roughly correlate
-/// to DWARF attribute classes.
-///
-class DIEValue {
-public:
- enum Type {
- isInteger,
- isString,
- isExpr,
- isLabel,
- isDelta,
- isEntry,
- isTypeSignature,
- isBlock,
- isLoc,
- isLocList,
- };
-
-private:
- /// Ty - Type of data stored in the value.
- ///
- Type Ty;
-
-protected:
- explicit DIEValue(Type T) : Ty(T) {}
- ~DIEValue() {}
-
-public:
- // Accessors
- Type getType() const { return Ty; }
-
- /// EmitValue - Emit value via the Dwarf writer.
- ///
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
-
- /// SizeOf - Return the size of a value in bytes.
- ///
- unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
-
-#ifndef NDEBUG
- void print(raw_ostream &O) const;
- void dump() const;
-#endif
-};
-
-//===--------------------------------------------------------------------===//
/// DIEInteger - An integer value DIE.
///
-class DIEInteger : public DIEValue {
- friend DIEValue;
-
+class DIEInteger {
uint64_t Integer;
public:
- explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
+ explicit DIEInteger(uint64_t I) : Integer(I) {}
/// BestForm - Choose the best form for integer.
///
@@ -278,120 +138,91 @@ public:
uint64_t getValue() const { return Integer; }
void setValue(uint64_t Val) { Integer = Val; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEExpr - An expression DIE.
//
-class DIEExpr : public DIEValue {
- friend class DIEValue;
-
+class DIEExpr {
const MCExpr *Expr;
public:
- explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {}
+ explicit DIEExpr(const MCExpr *E) : Expr(E) {}
/// getValue - Get MCExpr.
///
const MCExpr *getValue() const { return Expr; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isExpr; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELabel - A label DIE.
//
-class DIELabel : public DIEValue {
- friend class DIEValue;
-
+class DIELabel {
const MCSymbol *Label;
public:
- explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
+ explicit DIELabel(const MCSymbol *L) : Label(L) {}
/// getValue - Get MCSymbol.
///
const MCSymbol *getValue() const { return Label; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
-class DIEDelta : public DIEValue {
- friend class DIEValue;
-
+class DIEDelta {
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
- DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
- : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
+ DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEString - A container for string values.
///
-class DIEString : public DIEValue {
- friend class DIEValue;
-
+class DIEString {
DwarfStringPoolEntryRef S;
public:
- DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {}
+ DIEString(DwarfStringPoolEntryRef S) : S(S) {}
/// getString - Grab the string out of the object.
StringRef getString() const { return S.getString(); }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *D) { return D->getType() == isString; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
@@ -399,72 +230,350 @@ private:
/// DIEEntry - A pointer to another debug information entry. An instance of
/// this class can also be used as a proxy for a debug information entry not
/// yet defined (ie. types.)
-class DIEEntry : public DIEValue {
- friend class DIEValue;
+class DIE;
+class DIEEntry {
+ DIE *Entry;
- DIE &Entry;
+ DIEEntry() = delete;
public:
- explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) {
- }
+ explicit DIEEntry(DIE &E) : Entry(&E) {}
- DIE &getEntry() const { return Entry; }
+ DIE &getEntry() const { return *Entry; }
/// Returns size of a ref_addr entry.
static unsigned getRefAddrSize(const AsmPrinter *AP);
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// \brief A signature reference to a type unit.
-class DIETypeSignature : public DIEValue {
- friend class DIEValue;
+class DIETypeSignature {
+ const DwarfTypeUnit *Unit;
- const DwarfTypeUnit &Unit;
+ DIETypeSignature() = delete;
public:
- explicit DIETypeSignature(const DwarfTypeUnit &Unit)
- : DIEValue(isTypeSignature), Unit(Unit) {}
+ explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
- // \brief Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) {
- return E->getType() == isTypeSignature;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
+ assert(Form == dwarf::DW_FORM_ref_sig8);
+ return 8;
}
+#ifndef NDEBUG
+ void print(raw_ostream &O) const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIELocList - Represents a pointer to a location list in the debug_loc
+/// section.
+//
+class DIELocList {
+ // Index into the .debug_loc vector.
+ size_t Index;
+
+public:
+ DIELocList(size_t I) : Index(I) {}
+
+ /// getValue - Grab the current index out.
+ size_t getValue() const { return Index; }
+
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
+#ifndef NDEBUG
+ void print(raw_ostream &O) const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIEValue - A debug information entry value. Some of these roughly correlate
+/// to DWARF attribute classes.
+///
+class DIEBlock;
+class DIELoc;
+class DIEValue {
+public:
+ enum Type {
+ isNone,
+#define HANDLE_DIEVALUE(T) is##T,
+#include "llvm/CodeGen/DIEValue.def"
+ };
+
private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
- assert(Form == dwarf::DW_FORM_ref_sig8);
- return 8;
+ /// Ty - Type of data stored in the value.
+ ///
+ Type Ty = isNone;
+ dwarf::Attribute Attribute = (dwarf::Attribute)0;
+ dwarf::Form Form = (dwarf::Form)0;
+
+ /// Storage for the value.
+ ///
+ /// All values that aren't standard layout (or are larger than 8 bytes)
+ /// should be stored by reference instead of by value.
+ typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
+ DIEDelta *, DIEEntry, DIETypeSignature,
+ DIEBlock *, DIELoc *, DIELocList> ValTy;
+ static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
+ sizeof(ValTy) <= sizeof(void *),
+ "Expected all large types to be stored via pointer");
+
+ /// Underlying stored value.
+ ValTy Val;
+
+ template <class T> void construct(T V) {
+ static_assert(std::is_standard_layout<T>::value ||
+ std::is_pointer<T>::value,
+ "Expected standard layout or pointer");
+ new (reinterpret_cast<void *>(Val.buffer)) T(V);
+ }
+
+ template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); }
+ template <class T> const T *get() const {
+ return reinterpret_cast<const T *>(Val.buffer);
+ }
+ template <class T> void destruct() { get<T>()->~T(); }
+
+ /// Destroy the underlying value.
+ ///
+ /// This should get optimized down to a no-op. We could skip it if we could
+ /// add a static assert on \a std::is_trivially_copyable(), but we currently
+ /// support versions of GCC that don't understand that.
+ void destroyVal() {
+ switch (Ty) {
+ case isNone:
+ return;
+#define HANDLE_DIEVALUE_SMALL(T) \
+ case is##T: \
+ destruct<DIE##T>();
+ return;
+#define HANDLE_DIEVALUE_LARGE(T) \
+ case is##T: \
+ destruct<const DIE##T *>();
+ return;
+#include "llvm/CodeGen/DIEValue.def"
+ }
+ }
+
+ /// Copy the underlying value.
+ ///
+ /// This should get optimized down to a simple copy. We need to actually
+ /// construct the value, rather than calling memcpy, to satisfy strict
+ /// aliasing rules.
+ void copyVal(const DIEValue &X) {
+ switch (Ty) {
+ case isNone:
+ return;
+#define HANDLE_DIEVALUE_SMALL(T) \
+ case is##T: \
+ construct<DIE##T>(*X.get<DIE##T>()); \
+ return;
+#define HANDLE_DIEVALUE_LARGE(T) \
+ case is##T: \
+ construct<const DIE##T *>(*X.get<const DIE##T *>()); \
+ return;
+#include "llvm/CodeGen/DIEValue.def"
+ }
}
+public:
+ DIEValue() = default;
+ DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) {
+ copyVal(X);
+ }
+ DIEValue &operator=(const DIEValue &X) {
+ destroyVal();
+ Ty = X.Ty;
+ Attribute = X.Attribute;
+ Form = X.Form;
+ copyVal(X);
+ return *this;
+ }
+ ~DIEValue() { destroyVal(); }
+
+#define HANDLE_DIEVALUE_SMALL(T) \
+ DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \
+ : Ty(is##T), Attribute(Attribute), Form(Form) { \
+ construct<DIE##T>(V); \
+ }
+#define HANDLE_DIEVALUE_LARGE(T) \
+ DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \
+ : Ty(is##T), Attribute(Attribute), Form(Form) { \
+ assert(V && "Expected valid value"); \
+ construct<const DIE##T *>(V); \
+ }
+#include "llvm/CodeGen/DIEValue.def"
+
+ // Accessors
+ Type getType() const { return Ty; }
+ dwarf::Attribute getAttribute() const { return Attribute; }
+ dwarf::Form getForm() const { return Form; }
+ explicit operator bool() const { return Ty; }
+
+#define HANDLE_DIEVALUE_SMALL(T) \
+ const DIE##T &getDIE##T() const { \
+ assert(getType() == is##T && "Expected " #T); \
+ return *get<DIE##T>(); \
+ }
+#define HANDLE_DIEVALUE_LARGE(T) \
+ const DIE##T &getDIE##T() const { \
+ assert(getType() == is##T && "Expected " #T); \
+ return **get<const DIE##T *>(); \
+ }
+#include "llvm/CodeGen/DIEValue.def"
+
+ /// EmitValue - Emit value via the Dwarf writer.
+ ///
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+
+ /// SizeOf - Return the size of a value in bytes.
+ ///
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
+ void dump() const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIE - A structured debug information entry. Has an abbreviation which
+/// describes its organization.
+class DIE {
+protected:
+ /// Offset - Offset in debug info section.
+ ///
+ unsigned Offset;
+
+ /// Size - Size of instance + children.
+ ///
+ unsigned Size;
+
+ unsigned AbbrevNumber = ~0u;
+
+ /// Tag - Dwarf tag code.
+ ///
+ dwarf::Tag Tag = (dwarf::Tag)0;
+
+ /// Children DIEs.
+ ///
+ // This can't be a vector<DIE> because pointer validity is requirent for the
+ // Parent pointer and DIEEntry.
+ // It can't be a list<DIE> because some clients need pointer validity before
+ // the object has been added to any child list
+ // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
+ // be more convoluted than beneficial.
+ std::vector<std::unique_ptr<DIE>> Children;
+
+ DIE *Parent;
+
+ /// Attribute values.
+ ///
+ SmallVector<DIEValue, 12> Values;
+
+protected:
+ DIE() : Offset(0), Size(0), Parent(nullptr) {}
+
+public:
+ explicit DIE(dwarf::Tag Tag)
+ : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {}
+
+ // Accessors.
+ unsigned getAbbrevNumber() const { return AbbrevNumber; }
+ dwarf::Tag getTag() const { return Tag; }
+ unsigned getOffset() const { return Offset; }
+ unsigned getSize() const { return Size; }
+ bool hasChildren() const { return !Children.empty(); }
+
+ typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator;
+ typedef iterator_range<child_iterator> child_range;
+
+ child_range children() const {
+ return llvm::make_range(Children.begin(), Children.end());
+ }
+
+ typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator;
+ typedef iterator_range<value_iterator> value_range;
+
+ value_iterator values_begin() const { return Values.begin(); }
+ value_iterator values_end() const { return Values.end(); }
+ value_range values() const {
+ return llvm::make_range(values_begin(), values_end());
+ }
+
+ void setValue(unsigned I, DIEValue New) {
+ assert(I < Values.size());
+ Values[I] = New;
+ }
+ DIE *getParent() const { return Parent; }
+
+ /// Generate the abbreviation for this DIE.
+ ///
+ /// Calculate the abbreviation for this, which should be uniqued and
+ /// eventually used to call \a setAbbrevNumber().
+ DIEAbbrev generateAbbrev() const;
+
+ /// Set the abbreviation number for this DIE.
+ void setAbbrevNumber(unsigned I) { AbbrevNumber = I; }
+
+ /// Climb up the parent chain to get the compile or type unit DIE this DIE
+ /// belongs to.
+ const DIE *getUnit() const;
+ /// Similar to getUnit, returns null when DIE is not added to an
+ /// owner yet.
+ const DIE *getUnitOrNull() const;
+ void setOffset(unsigned O) { Offset = O; }
+ void setSize(unsigned S) { Size = S; }
+
+ /// addValue - Add a value and attributes to a DIE.
+ ///
+ void addValue(DIEValue Value) { Values.push_back(Value); }
+ template <class T>
+ void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) {
+ Values.emplace_back(Attribute, Form, std::forward<T>(Value));
+ }
+
+ /// addChild - Add a child to the DIE.
+ ///
+ DIE &addChild(std::unique_ptr<DIE> Child) {
+ assert(!Child->getParent());
+ Child->Parent = this;
+ Children.push_back(std::move(Child));
+ return *Children.back();
+ }
+
+ /// Find a value in the DIE with the attribute given.
+ ///
+ /// Returns a default-constructed DIEValue (where \a DIEValue::getType()
+ /// gives \a DIEValue::isNone) if no such attribute exists.
+ DIEValue findAttribute(dwarf::Attribute Attribute) const;
+
+#ifndef NDEBUG
+ void print(raw_ostream &O, unsigned IndentCount = 0) const;
+ void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
-class DIELoc : public DIEValue, public DIE {
- friend class DIEValue;
-
+class DIELoc : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
+
public:
- DIELoc() : DIEValue(isLoc), Size(0) {}
+ DIELoc() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@@ -485,27 +594,22 @@ public:
return dwarf::DW_FORM_block;
}
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEBlock - Represents a block of values.
//
-class DIEBlock : public DIEValue, public DIE {
- friend class DIEValue;
-
+class DIEBlock : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
+
public:
- DIEBlock() : DIEValue(isBlock), Size(0) {}
+ DIEBlock() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@@ -523,43 +627,11 @@ public:
return dwarf::DW_FORM_block;
}
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
-
-#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
-#endif
-};
-
-//===--------------------------------------------------------------------===//
-/// DIELocList - Represents a pointer to a location list in the debug_loc
-/// section.
-//
-class DIELocList : public DIEValue {
- friend class DIEValue;
-
- // Index into the .debug_loc vector.
- size_t Index;
-
-public:
- DIELocList(size_t I) : DIEValue(isLocList), Index(I) {}
-
- /// getValue - Grab the current index out.
- size_t getValue() const { return Index; }
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
diff --git a/include/llvm/CodeGen/DIEValue.def b/include/llvm/CodeGen/DIEValue.def
new file mode 100644
index 0000000000000..2cfae7b608c6a
--- /dev/null
+++ b/include/llvm/CodeGen/DIEValue.def
@@ -0,0 +1,47 @@
+//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Macros for running through all types of DIEValue.
+//
+//===----------------------------------------------------------------------===//
+
+#if !(defined HANDLE_DIEVALUE || defined HANDLE_DIEVALUE_SMALL || \
+ defined HANDLE_DIEVALUE_LARGE)
+#error "Missing macro definition of HANDLE_DIEVALUE"
+#endif
+
+// Handler for all values.
+#ifndef HANDLE_DIEVALUE
+#define HANDLE_DIEVALUE(T)
+#endif
+
+// Handler for small values.
+#ifndef HANDLE_DIEVALUE_SMALL
+#define HANDLE_DIEVALUE_SMALL(T) HANDLE_DIEVALUE(T)
+#endif
+
+// Handler for large values.
+#ifndef HANDLE_DIEVALUE_LARGE
+#define HANDLE_DIEVALUE_LARGE(T) HANDLE_DIEVALUE(T)
+#endif
+
+HANDLE_DIEVALUE_SMALL(Integer)
+HANDLE_DIEVALUE_SMALL(String)
+HANDLE_DIEVALUE_SMALL(Expr)
+HANDLE_DIEVALUE_SMALL(Label)
+HANDLE_DIEVALUE_LARGE(Delta)
+HANDLE_DIEVALUE_SMALL(Entry)
+HANDLE_DIEVALUE_SMALL(TypeSignature)
+HANDLE_DIEVALUE_LARGE(Block)
+HANDLE_DIEVALUE_LARGE(Loc)
+HANDLE_DIEVALUE_SMALL(LocList)
+
+#undef HANDLE_DIEVALUE
+#undef HANDLE_DIEVALUE_SMALL
+#undef HANDLE_DIEVALUE_LARGE
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 357b2d8a7ca7a..e883bd196ea31 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -121,7 +121,7 @@ public:
/// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).
void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
- SafePoints.push_back(GCPoint(Kind, Label, DL));
+ SafePoints.emplace_back(Kind, Label, DL);
}
/// getFrameSize/setFrameSize - Records the function's frame size.
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index de855f2fe7a0f..c97c636abbb4c 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -102,6 +102,10 @@ private:
/// registers are created.
void MRI_NoteNewVirtualRegister(unsigned VReg) override;
+ /// \brief Check if MachineOperand \p MO is a last use/kill either in the
+ /// main live range of \p LI or in one of the matching subregister ranges.
+ bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const;
+
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
/// @param parent The register being spilled or split.
diff --git a/include/llvm/CodeGen/MIRParser/MIRParser.h b/include/llvm/CodeGen/MIRParser/MIRParser.h
new file mode 100644
index 0000000000000..710b2d4bef8e0
--- /dev/null
+++ b/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -0,0 +1,52 @@
+//===- MIRParser.h - MIR serialization format parser ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This MIR serialization library is currently a work in progress. It can't
+// serialize machine functions at this time.
+//
+// This file declares the functions that parse the MIR serialization format
+// files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
+#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace llvm {
+
+class SMDiagnostic;
+
+/// This function is the main interface to the MIR serialization format parser.
+///
+/// It reads a YAML file that has an optional LLVM IR and returns an LLVM
+/// module.
+/// \param Filename - The name of the file to parse.
+/// \param Error - Error result info.
+/// \param Context - Context in which to allocate globals info.
+std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error,
+ LLVMContext &Context);
+
+/// This function is another interface to the MIR serialization format parser.
+///
+/// It parses the optional LLVM IR in the given buffer, and returns an LLVM
+/// module.
+/// \param Contents - The MemoryBuffer containing the machine level IR.
+/// \param Error - Error result info.
+/// \param Context - Context in which to allocate globals info.
+std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents,
+ SMDiagnostic &Error, LLVMContext &Context);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h
new file mode 100644
index 0000000000000..f9d4c7471b93d
--- /dev/null
+++ b/include/llvm/CodeGen/MIRYamlMapping.h
@@ -0,0 +1,40 @@
+//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MIR serialization library is currently a work in progress. It can't
+// serialize machine functions at this time.
+//
+// This file implements the mapping between various MIR data structures and
+// their corresponding YAML representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
+#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace yaml {
+
+struct MachineFunction {
+ StringRef Name;
+};
+
+template <> struct MappingTraits<MachineFunction> {
+ static void mapping(IO &YamlIO, MachineFunction &MF) {
+ YamlIO.mapRequired("name", MF.Name);
+ }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 40f3b4944cc1e..3889d471ccf3f 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -256,11 +256,6 @@ class MachineFrameInfo {
/// Not null, if shrink-wrapping found a better place for the epilogue.
MachineBasicBlock *Restore;
- /// Check if it exists a path from \p MBB leading to the basic
- /// block with a SavePoint (a.k.a. prologue).
- bool isBeforeSavePoint(const MachineFunction &MF,
- const MachineBasicBlock &MBB) const;
-
public:
explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign,
bool RealignOpt)
@@ -627,16 +622,15 @@ public:
MachineBasicBlock *getRestorePoint() const { return Restore; }
void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; }
- /// getPristineRegs - Return a set of physical registers that are pristine on
- /// entry to the MBB.
+ /// Return a set of physical registers that are pristine.
///
/// Pristine registers hold a value that is useless to the current function,
- /// but that must be preserved - they are callee saved registers that have not
- /// been saved yet.
+ /// but that must be preserved - they are callee saved registers that are not
+ /// saved.
///
/// Before the PrologueEpilogueInserter has placed the CSR spill code, this
/// method always returns an empty set.
- BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
+ BitVector getPristineRegs(const MachineFunction &MF) const;
/// print - Used by the MachineFunction printer to print information about
/// stack objects. Implemented in MachineFunction.cpp
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index e57257c76bc70..edda03fe36852 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -331,6 +331,11 @@ public:
operands_begin() + getDesc().getNumDefs(), operands_end());
}
+ /// Returns the number of the operand iterator \p I points to.
+ unsigned getOperandNo(const_mop_iterator I) const {
+ return I - operands_begin();
+ }
+
/// Access to memory operands of the instruction
mmo_iterator memoperands_begin() const { return MemRefs; }
mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; }
@@ -483,6 +488,13 @@ public:
return hasProperty(MCID::NotDuplicable, Type);
}
+ /// Return true if this instruction is convergent.
+ /// Convergent instructions can only be moved to locations that are
+ /// control-equivalent to their initial position.
+ bool isConvergent(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Convergent, Type);
+ }
+
/// Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator.
bool hasDelaySlot(QueryType Type = AnyInBundle) const {
@@ -924,7 +936,7 @@ public:
/// For normal instructions, this is derived from the MCInstrDesc.
/// For inline assembly it is derived from the flag words.
///
- /// Returns NULL if the static register classs constraint cannot be
+ /// Returns NULL if the static register class constraint cannot be
/// determined.
///
const TargetRegisterClass*
@@ -936,10 +948,10 @@ public:
/// the given \p CurRC.
/// If \p ExploreBundle is set and MI is part of a bundle, all the
/// instructions inside the bundle will be taken into account. In other words,
- /// this method accumulates all the constrains of the operand of this MI and
+ /// this method accumulates all the constraints of the operand of this MI and
/// the related bundle if MI is a bundle or inside a bundle.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by MI. Returns NULL if such a register class does not
/// exist.
///
@@ -952,7 +964,7 @@ public:
/// \brief Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by \p OpIdx MI. Returns NULL if such a register class
/// does not exist.
///
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index f7bcf45d93c56..438ef2e37255e 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -114,7 +114,7 @@ public:
}
// isLoopHeader - True if the block is a loop header node
- inline bool isLoopHeader(MachineBasicBlock *BB) const {
+ inline bool isLoopHeader(const MachineBasicBlock *BB) const {
return LI.isLoopHeader(BB);
}
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 39f69549d7cf3..9c7e7b4001a44 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -17,11 +17,11 @@
#include "llvm/Pass.h"
#include "llvm/Target/TargetMachine.h"
+#include <functional>
#include <string>
namespace llvm {
-class FunctionPass;
class MachineFunctionPass;
class PassConfigImpl;
class PassInfo;
@@ -374,6 +374,10 @@ namespace llvm {
createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
+ /// MIRPrinting pass - this pass prints out the LLVM IR into the given stream
+ /// using the MIR serialization format.
+ MachineFunctionPass *createPrintMIRPass(raw_ostream &OS);
+
/// createCodeGenPreparePass - Transform the code to expose more pattern
/// matching during instruction selection.
FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
@@ -488,6 +492,10 @@ namespace llvm {
/// MachineFunctionPrinterPass - This pass prints out MachineInstr's.
extern char &MachineFunctionPrinterPassID;
+ /// MIRPrintingPass - this pass prints out the LLVM IR using the MIR
+ /// serialization format.
+ extern char &MIRPrintingPassID;
+
/// TailDuplicate - Duplicate blocks with unconditional branches
/// into tails of their predecessors.
extern char &TailDuplicateID;
@@ -511,6 +519,8 @@ namespace llvm {
/// IfConverter - This pass performs machine code if conversion.
extern char &IfConverterID;
+ FunctionPass *createIfConverter(std::function<bool(const Function &)> Ftor);
+
/// MachineBlockPlacement - This pass places basic blocks based on branch
/// probabilities.
extern char &MachineBlockPlacementID;
@@ -605,6 +615,9 @@ namespace llvm {
/// UnpackMachineBundles - This pass unpack machine instruction bundles.
extern char &UnpackMachineBundlesID;
+ FunctionPass *
+ createUnpackMachineBundles(std::function<bool(const Function &)> Ftor);
+
/// FinalizeMachineBundles - This pass finalize machine instruction
/// bundles (created earlier, e.g. during pre-RA scheduling).
extern char &FinalizeMachineBundlesID;
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 1196783e820b8..b56d5ec8ce630 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -260,7 +260,7 @@ namespace llvm {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
#endif
- SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
+ SUnits.emplace_back(MI, (unsigned)SUnits.size());
assert((Addr == nullptr || Addr == &SUnits[0]) &&
"SUnits std::vector reallocated on the fly!");
SUnits.back().OrigNode = &SUnits.back();
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 89f9005b8b211..78fdd040773e3 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -878,6 +878,10 @@ public:
/// Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);
+ /// Return a bitcast using the SDLoc of the value operand, and casting to the
+ /// provided type. Use getNode to set a custom SDLoc.
+ SDValue getBitcast(EVT VT, SDValue V);
+
/// Return an AddrSpaceCastSDNode.
SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
unsigned SrcAS, unsigned DestAS);
diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
index e2644edd4d12a..1cff3203f2bbf 100644
--- a/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -23,6 +23,7 @@ class BasicBlock;
class Constant;
class Function;
class GlobalVariable;
+class InvokeInst;
class IntrinsicInst;
class LandingPadInst;
class MCSymbol;
@@ -153,5 +154,11 @@ struct WinEHFuncInfo {
NumIPToStateFuncsVisited(0) {}
};
+/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which
+/// describes the state numbers and tables used by __CxxFrameHandler3. This
+/// analysis assumes that WinEHPrepare has already been run.
+void calculateWinCXXEHStateNumbers(const Function *ParentFn,
+ WinEHFuncInfo &FuncInfo);
+
}
#endif // LLVM_CODEGEN_WINEHFUNCINFO_H