Remove DisableTailCalls from TargetOptions and the code in resetTargetOptions
[oota-llvm.git] / include / llvm / CodeGen / DIE.h
index 72cecbeed09b3ebef682ed997c9d40ada035fc56..464e0faa0ed3cb01399460e8e79b2dbf7aa6a9f6 100644 (file)
@@ -308,85 +308,131 @@ class DIEValue {
 public:
   enum Type {
     isNone,
-    isInteger,
-    isString,
-    isExpr,
-    isLabel,
-    isDelta,
-    isEntry,
-    isTypeSignature,
-    isBlock,
-    isLoc,
-    isLocList,
+#define HANDLE_DIEVALUE(T) is##T,
+#include "llvm/CodeGen/DIEValue.def"
   };
 
 private:
   /// Ty - Type of data stored in the value.
   ///
-  Type Ty;
+  Type Ty = isNone;
+  dwarf::Attribute Attribute = (dwarf::Attribute)0;
+  dwarf::Form Form = (dwarf::Form)0;
 
-  AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel, DIEDelta *,
-                        DIEEntry, DIETypeSignature, DIEBlock *, DIELoc *,
-                        DIELocList> Val;
-  static_assert(sizeof(Val) == sizeof(uint64_t),
-                "Only small values should be allocated locally");
+  /// 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);
+  }
 
-public:
-  DIEValue() : Ty(isNone) {}
-  DIEValue(const DIEValue &X) = default;
-  DIEValue &operator=(const DIEValue &X) = default;
+  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(); }
 
-  explicit operator bool() const { return Ty; }
+  /// 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 CONSTRUCT_FROM_SMALL(Kind)                                             \
-  DIEValue(const DIE##Kind &V) : Ty(is##Kind) {                                \
-    static_assert(std::is_trivially_copyable<DIE##Kind>::value,                \
-                  "Expected trivial type");                                    \
-    new (reinterpret_cast<void *>(Val.buffer)) DIE##Kind(V);                   \
+#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 CONSTRUCT_FROM_LARGE(Kind)                                             \
-  DIEValue(const DIE##Kind *V) : Ty(is##Kind) {                                \
+#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");                                       \
-    *reinterpret_cast<const DIE##Kind **>(Val.buffer) = V;                     \
+    construct<const DIE##T *>(V);                                              \
   }
-  CONSTRUCT_FROM_SMALL(Integer)
-  CONSTRUCT_FROM_SMALL(Expr)
-  CONSTRUCT_FROM_SMALL(Label)
-  CONSTRUCT_FROM_SMALL(Entry)
-  CONSTRUCT_FROM_SMALL(TypeSignature)
-  CONSTRUCT_FROM_SMALL(LocList)
-  CONSTRUCT_FROM_SMALL(String)
-  CONSTRUCT_FROM_LARGE(Delta)
-  CONSTRUCT_FROM_LARGE(Block)
-  CONSTRUCT_FROM_LARGE(Loc)
-#undef CONSTRUCT_FROM_SMALL
-#undef CONSTRUCT_FROM_LARGE
+#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 GET_VALUE_REF_SMALL(Kind)                                              \
-  const DIE##Kind &getDIE##Kind() const {                                      \
-    assert(getType() == is##Kind && "Expected " #Kind);                        \
-    return *reinterpret_cast<const DIE##Kind *>(Val.buffer);                   \
+#define HANDLE_DIEVALUE_SMALL(T)                                               \
+  const DIE##T &getDIE##T() const {                                            \
+    assert(getType() == is##T && "Expected " #T);                              \
+    return *get<DIE##T>();                                                     \
   }
-#define GET_VALUE_REF_LARGE(Kind)                                              \
-  const DIE##Kind &getDIE##Kind() const {                                      \
-    assert(getType() == is##Kind && "Expected " #Kind);                        \
-    return **reinterpret_cast<const DIE##Kind *const *>(Val.buffer);           \
+#define HANDLE_DIEVALUE_LARGE(T)                                               \
+  const DIE##T &getDIE##T() const {                                            \
+    assert(getType() == is##T && "Expected " #T);                              \
+    return **get<const DIE##T *>();                                            \
   }
-  GET_VALUE_REF_SMALL(Integer)
-  GET_VALUE_REF_SMALL(Expr)
-  GET_VALUE_REF_SMALL(Label)
-  GET_VALUE_REF_SMALL(Entry)
-  GET_VALUE_REF_SMALL(TypeSignature)
-  GET_VALUE_REF_SMALL(LocList)
-  GET_VALUE_REF_SMALL(String)
-  GET_VALUE_REF_LARGE(Delta)
-  GET_VALUE_REF_LARGE(Block)
-  GET_VALUE_REF_LARGE(Loc)
-#undef GET_VALUE_REF_SMALL
-#undef GET_VALUE_REF_LARGE
+#include "llvm/CodeGen/DIEValue.def"
 
   /// EmitValue - Emit value via the Dwarf writer.
   ///
@@ -415,9 +461,11 @@ protected:
   ///
   unsigned Size;
 
-  /// Abbrev - Buffer for constructing abbreviation.
+  unsigned AbbrevNumber = ~0u;
+
+  /// Tag - Dwarf tag code.
   ///
-  DIEAbbrev Abbrev;
+  dwarf::Tag Tag = (dwarf::Tag)0;
 
   /// Children DIEs.
   ///
@@ -436,31 +484,50 @@ protected:
   SmallVector<DIEValue, 12> Values;
 
 protected:
-  DIE()
-      : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no),
-        Parent(nullptr) {}
+  DIE() : Offset(0), Size(0), Parent(nullptr) {}
 
 public:
   explicit DIE(dwarf::Tag Tag)
-      : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
-        Parent(nullptr) {}
+      : Offset(0), Size(0), Tag(Tag), 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 getAbbrevNumber() const { return AbbrevNumber; }
+  dwarf::Tag getTag() const { return Tag; }
   unsigned getOffset() const { return Offset; }
   unsigned getSize() const { return Size; }
-  const std::vector<std::unique_ptr<DIE>> &getChildren() const {
-    return Children;
+  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());
   }
-  const SmallVectorImpl<DIEValue> &getValues() const { return Values; }
+
+  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;
@@ -472,18 +539,19 @@ public:
 
   /// 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);
+  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.
   ///
-  void addChild(std::unique_ptr<DIE> Child) {
+  DIE &addChild(std::unique_ptr<DIE> Child) {
     assert(!Child->getParent());
-    Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
     Child->Parent = this;
     Children.push_back(std::move(Child));
+    return *Children.back();
   }
 
   /// Find a value in the DIE with the attribute given.