summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-06-27 18:19:56 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-06-27 18:19:56 +0000
commitc8a1169c935ad9d3dfbdd4f72d80abf8f5acb03c (patch)
treeba02374e6ebac3aeaa3c234be27d92c6224cf34f /include
parent4a295dfbf9c5e8a71b8345484eff200058522b4e (diff)
downloadllvm-c8a1169c935ad9d3dfbdd4f72d80abf8f5acb03c.tar.gz
llvm-c8a1169c935ad9d3dfbdd4f72d80abf8f5acb03c.tar.bz2
llvm-c8a1169c935ad9d3dfbdd4f72d80abf8f5acb03c.tar.xz
IR: Add COMDATs to the IR
This new IR facility allows us to represent the object-file semantic of a COMDAT group. COMDATs allow us to tie together sections and make the inclusion of one dependent on another. This is required to implement features like MS ABI VFTables and optimizing away certain kinds of initialization in C++. This functionality is only representable in COFF and ELF, Mach-O has no similar mechanism. Differential Revision: http://reviews.llvm.org/D4178 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211920 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/ADT/UniqueVector.h19
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h11
-rw-r--r--include/llvm/IR/Comdat.h66
-rw-r--r--include/llvm/IR/GlobalAlias.h15
-rw-r--r--include/llvm/IR/GlobalObject.h10
-rw-r--r--include/llvm/IR/GlobalValue.h7
-rw-r--r--include/llvm/IR/Module.h16
-rw-r--r--include/llvm/Linker/Linker.h2
8 files changed, 142 insertions, 4 deletions
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
index 2d02d1ce16..a9cb2f5709 100644
--- a/include/llvm/ADT/UniqueVector.h
+++ b/include/llvm/ADT/UniqueVector.h
@@ -22,13 +22,18 @@ namespace llvm {
/// class should have an implementation of operator== and of operator<.
/// Entries can be fetched using operator[] with the entry ID.
template<class T> class UniqueVector {
+public:
+ typedef typename std::vector<T> VectorType;
+ typedef typename VectorType::iterator iterator;
+ typedef typename VectorType::const_iterator const_iterator;
+
private:
// Map - Used to handle the correspondence of entry to ID.
std::map<T, unsigned> Map;
// Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
//
- std::vector<T> Vector;
+ VectorType Vector;
public:
/// insert - Append entry to the vector if it doesn't already exist. Returns
@@ -68,6 +73,18 @@ public:
return Vector[ID - 1];
}
+ /// \brief Return an iterator to the start of the vector.
+ iterator begin() { return Vector.begin(); }
+
+ /// \brief Return an iterator to the start of the vector.
+ const_iterator begin() const { return Vector.begin(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ iterator end() { return Vector.end(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ const_iterator end() const { return Vector.end(); }
+
/// size - Returns the number of entries in the vector.
///
size_t size() const { return Vector.size(); }
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 10b0f65cbc..f7e30ef1e9 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -71,7 +71,8 @@ namespace bitc {
// MODULE_CODE_PURGEVALS: [numvals]
MODULE_CODE_PURGEVALS = 10,
- MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N]
+ MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N]
+ MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name]
};
/// PARAMATTR blocks have code for defining a parameter attribute set.
@@ -376,6 +377,14 @@ namespace bitc {
ATTR_KIND_JUMP_TABLE = 40
};
+ enum ComdatSelectionKindCodes {
+ COMDAT_SELECTION_KIND_ANY = 1,
+ COMDAT_SELECTION_KIND_EXACT_MATCH = 2,
+ COMDAT_SELECTION_KIND_LARGEST = 3,
+ COMDAT_SELECTION_KIND_NO_DUPLICATES = 4,
+ COMDAT_SELECTION_KIND_SAME_SIZE = 5,
+ };
+
} // End bitc namespace
} // End llvm namespace
diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h
new file mode 100644
index 0000000000..3e77a7709d
--- /dev/null
+++ b/include/llvm/IR/Comdat.h
@@ -0,0 +1,66 @@
+//===-- llvm/IR/Comdat.h - Comdat definitions -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declaration of the Comdat class, which represents a
+/// single COMDAT in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_COMDAT_H
+#define LLVM_IR_COMDAT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class raw_ostream;
+template <typename ValueTy> class StringMapEntry;
+
+// This is a Name X SelectionKind pair. The reason for having this be an
+// independent object instead of just adding the name and the SelectionKind
+// to a GlobalObject is that it is invalid to have two Comdats with the same
+// name but different SelectionKind. This structure makes that unrepresentable.
+class Comdat {
+public:
+ enum SelectionKind {
+ Any, ///< The linker may choose any COMDAT.
+ ExactMatch, ///< The data referenced by the COMDAT must be the same.
+ Largest, ///< The linker will choose the largest COMDAT.
+ NoDuplicates, ///< No other Module may specify this COMDAT.
+ SameSize, ///< The data referenced by the COMDAT must be the same size.
+ };
+
+ Comdat(Comdat &&C);
+ SelectionKind getSelectionKind() const { return SK; }
+ void setSelectionKind(SelectionKind Val) { SK = Val; }
+ StringRef getName() const;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+private:
+ friend class Module;
+ Comdat();
+ Comdat(SelectionKind SK, StringMapEntry<Comdat> *Name);
+ Comdat(const Comdat &) LLVM_DELETED_FUNCTION;
+
+ // Points to the map in Module.
+ StringMapEntry<Comdat> *Name;
+ SelectionKind SK;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
+ C.print(OS);
+ return OS;
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index a77d1630f4..075b5703bc 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -87,6 +87,21 @@ public:
return getOperand(0);
}
+ const GlobalObject *getBaseObject() const {
+ return const_cast<GlobalAlias *>(this)->getBaseObject();
+ }
+ GlobalObject *getBaseObject() {
+ return dyn_cast<GlobalObject>(getAliasee()->stripInBoundsOffsets());
+ }
+
+ const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
+ return const_cast<GlobalAlias *>(this)->getBaseObject(DL, Offset);
+ }
+ GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
+ return dyn_cast<GlobalObject>(
+ getAliasee()->stripAndAccumulateInBoundsConstantOffsets(DL, Offset));
+ }
+
static bool isValidLinkage(LinkageTypes L) {
return isExternalLinkage(L) || isLocalLinkage(L) ||
isWeakLinkage(L) || isLinkOnceLinkage(L);
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 74cc18eeb1..2e042f4897 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -20,7 +20,7 @@
#include "llvm/IR/GlobalValue.h"
namespace llvm {
-
+class Comdat;
class Module;
class GlobalObject : public GlobalValue {
@@ -29,11 +29,12 @@ class GlobalObject : public GlobalValue {
protected:
GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
- : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name) {
+ : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) {
setGlobalValueSubClassData(0);
}
std::string Section; // Section to emit this into, empty means default
+ Comdat *ObjComdat;
public:
unsigned getAlignment() const {
return (1u << getGlobalValueSubClassData()) >> 1;
@@ -44,6 +45,11 @@ public:
const char *getSection() const { return Section.c_str(); }
void setSection(StringRef S);
+ bool hasComdat() const { return getComdat() != nullptr; }
+ const Comdat *getComdat() const { return ObjComdat; }
+ Comdat *getComdat() { return ObjComdat; }
+ void setComdat(Comdat *C) { ObjComdat = C; }
+
void copyAttributesFrom(const GlobalValue *Src) override;
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 5e99886a5f..a3aea70af5 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -23,6 +23,7 @@
namespace llvm {
+class Comdat;
class PointerType;
class Module;
@@ -110,6 +111,12 @@ public:
bool hasUnnamedAddr() const { return UnnamedAddr; }
void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+ bool hasComdat() const { return getComdat() != nullptr; }
+ Comdat *getComdat();
+ const Comdat *getComdat() const {
+ return const_cast<GlobalValue *>(this)->getComdat();
+ }
+
VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 77e5d21e29..26f62db9db 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -16,6 +16,7 @@
#define LLVM_IR_MODULE_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Comdat.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
@@ -123,6 +124,8 @@ public:
typedef iplist<GlobalAlias> AliasListType;
/// The type for the list of named metadata.
typedef ilist<NamedMDNode> NamedMDListType;
+ /// The type of the comdat "symbol" table.
+ typedef StringMap<Comdat> ComdatSymTabType;
/// The Global Variable iterator.
typedef GlobalListType::iterator global_iterator;
@@ -197,6 +200,7 @@ private:
NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values
+ ComdatSymTabType ComdatSymTab; ///< Symbol table for COMDATs
std::unique_ptr<GVMaterializer>
Materializer; ///< Used to materialize GlobalValues
std::string ModuleID; ///< Human readable identifier for the module
@@ -404,6 +408,14 @@ public:
void eraseNamedMetadata(NamedMDNode *NMD);
/// @}
+/// @name Comdat Accessors
+/// @{
+
+ /// Return the Comdat in the module with the specified name. It is created
+ /// if it didn't already exist.
+ Comdat *getOrInsertComdat(StringRef Name);
+
+/// @}
/// @name Module Flags Accessors
/// @{
@@ -504,6 +516,10 @@ public:
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers.
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
+ /// Get the Module's symbol table for COMDATs (constant).
+ const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; }
+ /// Get the Module's symbol table for COMDATs.
+ ComdatSymTabType &getComdatSymbolTable() { return ComdatSymTab; }
/// @}
/// @name Global Variable Iteration
diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h
index 42b2cb37b3..6254bbb6d6 100644
--- a/include/llvm/Linker/Linker.h
+++ b/include/llvm/Linker/Linker.h
@@ -15,6 +15,8 @@
namespace llvm {
+class Comdat;
+class GlobalValue;
class Module;
class StringRef;
class StructType;