aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Support
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-06-02 17:52:33 +0000
committerEd Schouten <ed@FreeBSD.org>2009-06-02 17:52:33 +0000
commit009b1c42aa6266385f2c37e227516b24077e6dd7 (patch)
tree64ba909838c23261cace781ece27d106134ea451 /include/llvm/Support
downloadsrc-009b1c42aa6266385f2c37e227516b24077e6dd7.tar.gz
src-009b1c42aa6266385f2c37e227516b24077e6dd7.zip
Import LLVM, at r72732.vendor/llvm/llvm-r72732
Notes
Notes: svn path=/vendor/llvm/dist/; revision=193323 svn path=/vendor/llvm/llvm-r72732/; revision=193324; tag=vendor/llvm/llvm-r72732
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/AIXDataTypesFix.h25
-rw-r--r--include/llvm/Support/AlignOf.h60
-rw-r--r--include/llvm/Support/Allocator.h91
-rw-r--r--include/llvm/Support/Annotation.h216
-rw-r--r--include/llvm/Support/CFG.h265
-rw-r--r--include/llvm/Support/CallSite.h199
-rw-r--r--include/llvm/Support/Casting.h303
-rw-r--r--include/llvm/Support/CommandLine.h1386
-rw-r--r--include/llvm/Support/Compiler.h59
-rw-r--r--include/llvm/Support/ConstantFolder.h189
-rw-r--r--include/llvm/Support/ConstantRange.h195
-rw-r--r--include/llvm/Support/DOTGraphTraits.h141
-rw-r--r--include/llvm/Support/DataFlow.h103
-rw-r--r--include/llvm/Support/DataTypes.h.cmake147
-rw-r--r--include/llvm/Support/DataTypes.h.in144
-rw-r--r--include/llvm/Support/Debug.h78
-rw-r--r--include/llvm/Support/Dwarf.h587
-rw-r--r--include/llvm/Support/DynamicLinker.h40
-rw-r--r--include/llvm/Support/ELF.h309
-rw-r--r--include/llvm/Support/FileUtilities.h59
-rw-r--r--include/llvm/Support/Format.h155
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h112
-rw-r--r--include/llvm/Support/GraphWriter.h323
-rw-r--r--include/llvm/Support/IRBuilder.h704
-rw-r--r--include/llvm/Support/InstIterator.h147
-rw-r--r--include/llvm/Support/InstVisitor.h221
-rw-r--r--include/llvm/Support/LeakDetector.h91
-rw-r--r--include/llvm/Support/ManagedStatic.h120
-rw-r--r--include/llvm/Support/Mangler.h112
-rw-r--r--include/llvm/Support/MathExtras.h437
-rw-r--r--include/llvm/Support/MemoryBuffer.h109
-rw-r--r--include/llvm/Support/MutexGuard.h41
-rw-r--r--include/llvm/Support/NoFolder.h178
-rw-r--r--include/llvm/Support/OutputBuffer.h154
-rw-r--r--include/llvm/Support/PassNameParser.h133
-rw-r--r--include/llvm/Support/PatternMatch.h531
-rw-r--r--include/llvm/Support/PluginLoader.h37
-rw-r--r--include/llvm/Support/PointerLikeTypeTraits.h77
-rw-r--r--include/llvm/Support/PredIteratorCache.h70
-rw-r--r--include/llvm/Support/PrettyStackTrace.h65
-rw-r--r--include/llvm/Support/Recycler.h116
-rw-r--r--include/llvm/Support/RecyclingAllocator.h59
-rw-r--r--include/llvm/Support/Registry.h224
-rw-r--r--include/llvm/Support/RegistryParser.h55
-rw-r--r--include/llvm/Support/SlowOperationInformer.h65
-rw-r--r--include/llvm/Support/StableBasicBlockNumbering.h59
-rw-r--r--include/llvm/Support/Streams.h91
-rw-r--r--include/llvm/Support/StringPool.h148
-rw-r--r--include/llvm/Support/SystemUtils.h42
-rw-r--r--include/llvm/Support/TargetFolder.h209
-rw-r--r--include/llvm/Support/Timer.h172
-rw-r--r--include/llvm/Support/TypeBuilder.h464
-rw-r--r--include/llvm/Support/ValueHandle.h272
-rw-r--r--include/llvm/Support/raw_ostream.h346
-rw-r--r--include/llvm/Support/type_traits.h54
55 files changed, 10789 insertions, 0 deletions
diff --git a/include/llvm/Support/AIXDataTypesFix.h b/include/llvm/Support/AIXDataTypesFix.h
new file mode 100644
index 000000000000..a9a9147de294
--- /dev/null
+++ b/include/llvm/Support/AIXDataTypesFix.h
@@ -0,0 +1,25 @@
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
new file mode 100644
index 000000000000..6a7a1a6bd223
--- /dev/null
+++ b/include/llvm/Support/AlignOf.h
@@ -0,0 +1,60 @@
+//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AlignOf function that computes alignments for
+// arbitrary types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALIGNOF_H
+#define LLVM_SUPPORT_ALIGNOF_H
+
+namespace llvm {
+
+template <typename T>
+struct AlignmentCalcImpl {
+ char x;
+ T t;
+private:
+ AlignmentCalcImpl() {} // Never instantiate.
+};
+
+/// AlignOf - A templated class that contains an enum value representing
+/// the alignment of the template argument. For example,
+/// AlignOf<int>::Alignment represents the alignment of type "int". The
+/// alignment calculated is the minimum alignment, and not necessarily
+/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
+/// that because the alignment is an enum value, it can be used as a
+/// compile-time constant (e.g., for template instantiation).
+template <typename T>
+struct AlignOf {
+ enum { Alignment =
+ static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
+
+ enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
+
+ enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
+ enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
+ enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
+ enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
+
+};
+
+/// alignof - A templated function that returns the mininum alignment of
+/// of a type. This provides no extra functionality beyond the AlignOf
+/// class besides some cosmetic cleanliness. Example usage:
+/// alignof<int>() returns the alignment of an int.
+template <typename T>
+static inline unsigned alignof() { return AlignOf<T>::Alignment; }
+
+} // end namespace llvm
+#endif
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
new file mode 100644
index 000000000000..c0414f970a29
--- /dev/null
+++ b/include/llvm/Support/Allocator.h
@@ -0,0 +1,91 @@
+//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MallocAllocator and BumpPtrAllocator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATOR_H
+#define LLVM_SUPPORT_ALLOCATOR_H
+
+#include "llvm/Support/AlignOf.h"
+#include <cstdlib>
+
+namespace llvm {
+
+class MallocAllocator {
+public:
+ MallocAllocator() {}
+ ~MallocAllocator() {}
+
+ void Reset() {}
+
+ void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
+
+ template <typename T>
+ T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); }
+
+ template <typename T>
+ T *Allocate(size_t Num) {
+ return static_cast<T*>(malloc(sizeof(T)*Num));
+ }
+
+ void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); }
+
+ void PrintStats() const {}
+};
+
+/// BumpPtrAllocator - This allocator is useful for containers that need very
+/// simple memory allocation strategies. In particular, this just keeps
+/// allocating memory, and never deletes it until the entire block is dead. This
+/// makes allocation speedy, but must only be used when the trade-off is ok.
+class BumpPtrAllocator {
+ BumpPtrAllocator(const BumpPtrAllocator &); // do not implement
+ void operator=(const BumpPtrAllocator &); // do not implement
+
+ void *TheMemory;
+public:
+ BumpPtrAllocator();
+ ~BumpPtrAllocator();
+
+ void Reset();
+
+ void *Allocate(size_t Size, size_t Alignment);
+
+ /// Allocate space, but do not construct, one object.
+ ///
+ template <typename T>
+ T *Allocate() {
+ return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
+ }
+
+ /// Allocate space for an array of objects. This does not construct the
+ /// objects though.
+ template <typename T>
+ T *Allocate(size_t Num) {
+ return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ }
+
+ /// Allocate space for a specific count of elements and with a specified
+ /// alignment.
+ template <typename T>
+ T *Allocate(size_t Num, size_t Alignment) {
+ // Round EltSize up to the specified alignment.
+ size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment);
+ return static_cast<T*>(Allocate(Num * EltSize, Alignment));
+ }
+
+ void Deallocate(const void * /*Ptr*/) {}
+
+ void PrintStats() const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Annotation.h b/include/llvm/Support/Annotation.h
new file mode 100644
index 000000000000..ffc92965e602
--- /dev/null
+++ b/include/llvm/Support/Annotation.h
@@ -0,0 +1,216 @@
+//===-- llvm/Support/Annotation.h - Annotation classes ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations for two classes: Annotation & Annotable.
+// Using these two simple classes, anything that derives from Annotable can have
+// Annotation subclasses attached to them, ready for easy retrieval.
+//
+// Annotations are designed to be easily attachable to various classes.
+//
+// The AnnotationManager class is essential for using these classes. It is
+// responsible for turning Annotation name strings into tokens [unique id #'s]
+// that may be used to search for and create annotations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ANNOTATION_H
+#define LLVM_SUPPORT_ANNOTATION_H
+
+#include <cassert>
+
+namespace llvm {
+
+class AnnotationID;
+class Annotation;
+class Annotable;
+struct AnnotationManager;
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationID - This class is a thin wrapper around an unsigned integer that
+// is used to hopefully prevent errors using AnnotationID's. They may be copied
+// freely around and passed byvalue with little or no overhead.
+//
+class AnnotationID {
+ friend struct AnnotationManager;
+ unsigned ID;
+
+ AnnotationID(); // Default ctor is disabled
+
+ // AnnotationID is only creatable from AnnMgr.
+ explicit inline AnnotationID(unsigned i) : ID(i) {}
+public:
+ inline AnnotationID(const AnnotationID &A) : ID(A.ID) {}
+
+ inline bool operator==(const AnnotationID &A) const {
+ return A.ID == ID;
+ }
+ inline bool operator<(const AnnotationID &A) const {
+ return ID < A.ID;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotation Class - This class serves as a base class for any specific
+// annotations that you might need. Simply subclass this to add extra
+// information to the annotations.
+//
+class Annotation {
+ friend class Annotable; // Annotable manipulates Next list
+ AnnotationID ID; // ID number, as obtained from AnnotationManager
+ Annotation *Next; // The next annotation in the linked list
+public:
+ explicit inline Annotation(AnnotationID id) : ID(id), Next(0) {}
+ virtual ~Annotation(); // Designed to be subclassed
+
+ // getID - Return the unique ID# of this annotation
+ inline AnnotationID getID() const { return ID; }
+
+ // getNext - Return the next annotation in the list...
+ inline Annotation *getNext() const { return Next; }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotable - This class is used as a base class for all objects that would
+// like to have annotation capability.
+//
+// Annotable objects keep their annotation list sorted as annotations are
+// inserted and deleted. This is used to ensure that annotations with identical
+// ID#'s are stored sequentially.
+//
+class Annotable {
+ mutable Annotation *AnnotationList;
+
+ Annotable(const Annotable &); // Do not implement
+ void operator=(const Annotable &); // Do not implement
+public:
+ Annotable() : AnnotationList(0) {}
+ ~Annotable();
+
+ // getAnnotation - Search the list for annotations of the specified ID. The
+ // pointer returned is either null (if no annotations of the specified ID
+ // exist), or it points to the first element of a potentially list of elements
+ // with identical ID #'s.
+ //
+ Annotation *getAnnotation(AnnotationID ID) const {
+ for (Annotation *A = AnnotationList; A; A = A->getNext())
+ if (A->getID() == ID) return A;
+ return 0;
+ }
+
+ // getOrCreateAnnotation - Search through the annotation list, if there is
+ // no annotation with the specified ID, then use the AnnotationManager to
+ // create one.
+ //
+ inline Annotation *getOrCreateAnnotation(AnnotationID ID) const;
+
+ // addAnnotation - Insert the annotation into the list in a sorted location.
+ //
+ void addAnnotation(Annotation *A) const {
+ assert(A->Next == 0 && "Annotation already in list?!?");
+
+ Annotation **AL = &AnnotationList;
+ while (*AL && (*AL)->ID < A->getID()) // Find where to insert annotation
+ AL = &((*AL)->Next);
+ A->Next = *AL; // Link the annotation in
+ *AL = A;
+ }
+
+ // unlinkAnnotation - Remove the first annotation of the specified ID... and
+ // then return the unlinked annotation. The annotation object is not deleted.
+ //
+ inline Annotation *unlinkAnnotation(AnnotationID ID) const {
+ for (Annotation **A = &AnnotationList; *A; A = &((*A)->Next))
+ if ((*A)->getID() == ID) {
+ Annotation *Ret = *A;
+ *A = Ret->Next;
+ Ret->Next = 0;
+ return Ret;
+ }
+ return 0;
+ }
+
+ // deleteAnnotation - Delete the first annotation of the specified ID in the
+ // list. Unlink unlinkAnnotation, this actually deletes the annotation object
+ //
+ bool deleteAnnotation(AnnotationID ID) const {
+ Annotation *A = unlinkAnnotation(ID);
+ delete A;
+ return A != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationManager - This class is primarily responsible for maintaining a
+// one-to-one mapping between string Annotation names and Annotation ID numbers.
+//
+// Compared to the rest of the Annotation system, these mapping methods are
+// relatively slow, so they should be avoided by locally caching Annotation
+// ID #'s. These methods are safe to call at any time, even by static ctors, so
+// they should be used by static ctors most of the time.
+//
+// This class also provides support for annotations that are created on demand
+// by the Annotable::getOrCreateAnnotation method. To get this to work, simply
+// register an annotation handler
+//
+struct AnnotationManager {
+ typedef Annotation *(*Factory)(AnnotationID, const Annotable *, void*);
+
+ //===--------------------------------------------------------------------===//
+ // Basic ID <-> Name map functionality
+
+ static AnnotationID getID(const char *Name); // Name -> ID
+ static const char *getName(AnnotationID ID); // ID -> Name
+
+ // getID - Name -> ID + registration of a factory function for demand driven
+ // annotation support.
+ static AnnotationID getID(const char *Name, Factory Fact, void *Data = 0);
+
+ //===--------------------------------------------------------------------===//
+ // Annotation creation on demand support...
+
+ // registerAnnotationFactory - This method is used to register a callback
+ // function used to create an annotation on demand if it is needed by the
+ // Annotable::getOrCreateAnnotation method.
+ //
+ static void registerAnnotationFactory(AnnotationID ID, Factory Func,
+ void *ExtraData = 0);
+
+ // createAnnotation - Create an annotation of the specified ID for the
+ // specified object, using a register annotation creation function.
+ //
+ static Annotation *createAnnotation(AnnotationID ID, const Annotable *Obj);
+};
+
+
+
+// getOrCreateAnnotation - Search through the annotation list, if there is
+// no annotation with the specified ID, then use the AnnotationManager to
+// create one.
+//
+inline Annotation *Annotable::getOrCreateAnnotation(AnnotationID ID) const {
+ Annotation *A = getAnnotation(ID); // Fast path, check for preexisting ann
+ if (A) return A;
+
+ // No annotation found, ask the annotation manager to create an annotation...
+ A = AnnotationManager::createAnnotation(ID, this);
+ assert(A && "AnnotationManager could not create annotation!");
+ addAnnotation(A);
+ return A;
+}
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
new file mode 100644
index 000000000000..b0b857bf0280
--- /dev/null
+++ b/include/llvm/Support/CFG.h
@@ -0,0 +1,265 @@
+//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines specializations of GraphTraits that allow Function and
+// BasicBlock graphs to be treated as proper graphs for generic algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CFG_H
+#define LLVM_SUPPORT_CFG_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/ADT/iterator.h"
+
+namespace llvm {
+
+//===--------------------------------------------------------------------===//
+// BasicBlock pred_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class _Ptr, class _USE_iterator> // Predecessor Iterator
+class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
+ typedef forward_iterator<_Ptr, ptrdiff_t> super;
+ _USE_iterator It;
+public:
+ typedef PredIterator<_Ptr,_USE_iterator> _Self;
+ typedef typename super::pointer pointer;
+
+ inline void advancePastNonTerminators() {
+ // Loop to ignore non terminator uses (for example PHI nodes)...
+ while (!It.atEnd() && !isa<TerminatorInst>(*It))
+ ++It;
+ }
+
+ inline PredIterator(_Ptr *bb) : It(bb->use_begin()) {
+ advancePastNonTerminators();
+ }
+ inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {}
+
+ inline bool operator==(const _Self& x) const { return It == x.It; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ return cast<TerminatorInst>(*It)->getParent();
+ }
+ inline pointer *operator->() const { return &(operator*()); }
+
+ inline _Self& operator++() { // Preincrement
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ ++It; advancePastNonTerminators();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
+typedef PredIterator<const BasicBlock,
+ Value::use_const_iterator> pred_const_iterator;
+
+inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
+inline pred_const_iterator pred_begin(const BasicBlock *BB) {
+ return pred_const_iterator(BB);
+}
+inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
+inline pred_const_iterator pred_end(const BasicBlock *BB) {
+ return pred_const_iterator(BB, true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// BasicBlock succ_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class Term_, class BB_> // Successor Iterator
+class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
+ const Term_ Term;
+ unsigned idx;
+ typedef bidirectional_iterator<BB_, ptrdiff_t> super;
+public:
+ typedef SuccIterator<Term_, BB_> _Self;
+ typedef typename super::pointer pointer;
+ // TODO: This can be random access iterator, need operator+ and stuff tho
+
+ inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
+ assert(T && "getTerminator returned null!");
+ }
+ inline SuccIterator(Term_ T, bool) // end iterator
+ : Term(T), idx(Term->getNumSuccessors()) {
+ assert(T && "getTerminator returned null!");
+ }
+
+ inline const _Self &operator=(const _Self &I) {
+ assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
+ idx = I.idx;
+ return *this;
+ }
+
+ /// getSuccessorIndex - This is used to interface between code that wants to
+ /// operate on terminator instructions directly.
+ unsigned getSuccessorIndex() const { return idx; }
+
+ inline bool operator==(const _Self& x) const { return idx == x.idx; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline pointer operator->() const { return operator*(); }
+
+ inline _Self& operator++() { ++idx; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ inline _Self& operator--() { --idx; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+
+typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
+typedef SuccIterator<const TerminatorInst*,
+ const BasicBlock> succ_const_iterator;
+
+inline succ_iterator succ_begin(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator());
+}
+inline succ_const_iterator succ_begin(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator());
+}
+inline succ_iterator succ_end(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator(), true);
+}
+inline succ_const_iterator succ_end(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator(), true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks...
+
+template <> struct GraphTraits<BasicBlock*> {
+ typedef BasicBlock NodeType;
+ typedef succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<const BasicBlock*> {
+ typedef const BasicBlock NodeType;
+ typedef succ_const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<BasicBlock*> > {
+ typedef BasicBlock NodeType;
+ typedef pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<const BasicBlock*> > {
+ typedef const BasicBlock NodeType;
+ typedef pred_const_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... these are the same as the basic block iterators,
+// except that the root node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
+ static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (Function *F) { return F->end(); }
+};
+template <> struct GraphTraits<const Function*> :
+ public GraphTraits<const BasicBlock*> {
+ static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (const Function *F) { return F->end(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<Function*> > :
+ public GraphTraits<Inverse<BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<Function*> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+template <> struct GraphTraits<Inverse<const Function*> > :
+ public GraphTraits<Inverse<const BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const Function *> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
new file mode 100644
index 000000000000..dc41590fb8a5
--- /dev/null
+++ b/include/llvm/Support/CallSite.h
@@ -0,0 +1,199 @@
+//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CallSite class, which is a handy wrapper for code that
+// wants to treat Call and Invoke instructions in a generic way.
+//
+// NOTE: This class is supposed to have "value semantics". So it should be
+// passed by value, not by reference; it should not be "new"ed or "delete"d. It
+// is efficiently copyable, assignable and constructable, with cost equivalent
+// to copying a pointer (notice that it has only a single data member).
+// The internal representation carries a flag which indicates which of the two
+// variants is enclosed. This allows for cheaper checks when various accessors
+// of CallSite are employed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CALLSITE_H
+#define LLVM_SUPPORT_CALLSITE_H
+
+#include "llvm/Attributes.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
+
+namespace llvm {
+
+class CallInst;
+class InvokeInst;
+
+class CallSite {
+ PointerIntPair<Instruction*, 1, bool> I;
+public:
+ CallSite() : I(0, false) {}
+ CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI), true) {}
+ CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II), false) {}
+ CallSite(Instruction *C);
+ CallSite(const CallSite &CS) : I(CS.I) {}
+ CallSite &operator=(const CallSite &CS) { I = CS.I; return *this; }
+
+ bool operator==(const CallSite &CS) const { return I == CS.I; }
+ bool operator!=(const CallSite &CS) const { return I != CS.I; }
+
+ /// CallSite::get - This static method is sort of like a constructor. It will
+ /// create an appropriate call site for a Call or Invoke instruction, but it
+ /// can also create a null initialized CallSite object for something which is
+ /// NOT a call site.
+ ///
+ static CallSite get(Value *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V)) {
+ if (I->getOpcode() == Instruction::Call)
+ return CallSite(reinterpret_cast<CallInst*>(I));
+ else if (I->getOpcode() == Instruction::Invoke)
+ return CallSite(reinterpret_cast<InvokeInst*>(I));
+ }
+ return CallSite();
+ }
+
+ /// getCallingConv/setCallingConv - get or set the calling convention of the
+ /// call.
+ unsigned getCallingConv() const;
+ void setCallingConv(unsigned CC);
+
+ /// getAttributes/setAttributes - get or set the parameter attributes of
+ /// the call.
+ const AttrListPtr &getAttributes() const;
+ void setAttributes(const AttrListPtr &PAL);
+
+ /// paramHasAttr - whether the call or the callee has the given attribute.
+ bool paramHasAttr(uint16_t i, Attributes attr) const;
+
+ /// @brief Extract the alignment for a call or parameter (0=unknown).
+ uint16_t getParamAlignment(uint16_t i) const;
+
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const;
+ void setDoesNotAccessMemory(bool doesNotAccessMemory = true);
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const;
+ void setOnlyReadsMemory(bool onlyReadsMemory = true);
+
+ /// @brief Determine if the call cannot return.
+ bool doesNotReturn() const;
+ void setDoesNotReturn(bool doesNotReturn = true);
+
+ /// @brief Determine if the call cannot unwind.
+ bool doesNotThrow() const;
+ void setDoesNotThrow(bool doesNotThrow = true);
+
+ /// getType - Return the type of the instruction that generated this call site
+ ///
+ const Type *getType() const { return getInstruction()->getType(); }
+
+ /// isCall - true if a CallInst is enclosed.
+ /// Note that !isCall() does not mean it is an InvokeInst enclosed,
+ /// it also could signify a NULL Instruction pointer.
+ bool isCall() const { return I.getInt(); }
+
+ /// isInvoke - true if a InvokeInst is enclosed.
+ ///
+ bool isInvoke() const { return getInstruction() && !I.getInt(); }
+
+ /// getInstruction - Return the instruction this call site corresponds to
+ ///
+ Instruction *getInstruction() const { return I.getPointer(); }
+
+ /// getCaller - Return the caller function for this call site
+ ///
+ Function *getCaller() const { return getInstruction()
+ ->getParent()->getParent(); }
+
+ /// getCalledValue - Return the pointer to function that is being called...
+ ///
+ Value *getCalledValue() const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ return getInstruction()->getOperand(0);
+ }
+
+ /// getCalledFunction - Return the function being called if this is a direct
+ /// call, otherwise return null (if it's an indirect call).
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(getCalledValue());
+ }
+
+ /// setCalledFunction - Set the callee to the specified value...
+ ///
+ void setCalledFunction(Value *V) {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ getInstruction()->setOperand(0, V);
+ }
+
+ Value *getArgument(unsigned ArgNo) const {
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ return *(arg_begin()+ArgNo);
+ }
+
+ void setArgument(unsigned ArgNo, Value* newVal) {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ getInstruction()->setOperand(getArgumentOffset() + ArgNo, newVal);
+ }
+
+ /// Given an operand number, returns the argument that corresponds to it.
+ /// OperandNo must be a valid operand number that actually corresponds to an
+ /// argument.
+ unsigned getArgumentNo(unsigned OperandNo) const {
+ assert(OperandNo >= getArgumentOffset() && "Operand number passed was not "
+ "a valid argument");
+ return OperandNo - getArgumentOffset();
+ }
+
+ /// hasArgument - Returns true if this CallSite passes the given Value* as an
+ /// argument to the called function.
+ bool hasArgument(const Value *Arg) const;
+
+ /// arg_iterator - The type of iterator to use when looping over actual
+ /// arguments at this call site...
+ typedef User::op_iterator arg_iterator;
+
+ /// arg_begin/arg_end - Return iterators corresponding to the actual argument
+ /// list for a call site.
+ arg_iterator arg_begin() const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ // Skip non-arguments
+ return getInstruction()->op_begin() + getArgumentOffset();
+ }
+
+ arg_iterator arg_end() const { return getInstruction()->op_end(); }
+ bool arg_empty() const { return arg_end() == arg_begin(); }
+ unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+
+ bool operator<(const CallSite &CS) const {
+ return getInstruction() < CS.getInstruction();
+ }
+
+ bool isCallee(Value::use_iterator UI) const {
+ return getInstruction()->op_begin() == &UI.getUse();
+ }
+
+private:
+ /// Returns the operand number of the first argument
+ unsigned getArgumentOffset() const {
+ if (isCall())
+ return 1; // Skip Function
+ else
+ return 3; // Skip Function, BB, BB
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
new file mode 100644
index 000000000000..48988f8a6bb8
--- /dev/null
+++ b/include/llvm/Support/Casting.h
@@ -0,0 +1,303 @@
+//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
+// and dyn_cast_or_null<X>() templates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CASTING_H
+#define LLVM_SUPPORT_CASTING_H
+
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// isa<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<typename FromCl> struct isa_impl_cl;
+
+// Define a template that can be specialized by smart pointers to reflect the
+// fact that they are automatically dereferenced, and are not involved with the
+// template selection process... the default implementation is a noop.
+//
+template<typename From> struct simplify_type {
+ typedef From SimpleType; // The real type this represents...
+
+ // An accessor to get the real value...
+ static SimpleType &getSimplifiedValue(From &Val) { return Val; }
+};
+
+template<typename From> struct simplify_type<const From> {
+ typedef const From SimpleType;
+ static SimpleType &getSimplifiedValue(const From &Val) {
+ return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ }
+};
+
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument. Used like this:
+//
+// if (isa<Type*>(myVal)) { ... }
+//
+template <typename To, typename From>
+inline bool isa_impl(const From &Val) {
+ return To::classof(&Val);
+}
+
+template<typename To, typename From, typename SimpleType>
+struct isa_impl_wrap {
+ // When From != SimplifiedType, we can simplify the type some more by using
+ // the simplify_type template.
+ static bool doit(const From &Val) {
+ return isa_impl_cl<const SimpleType>::template
+ isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
+ }
+};
+
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, const FromTy, const FromTy> {
+ // When From == SimpleType, we are as simple as we are going to get.
+ static bool doit(const FromTy &Val) {
+ return isa_impl<To,FromTy>(Val);
+ }
+};
+
+// isa_impl_cl - Use class partial specialization to transform types to a single
+// canonical form for isa_impl.
+//
+template<typename FromCl>
+struct isa_impl_cl {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_wrap<ToCl,const FromCl,
+ typename simplify_type<const FromCl>::SimpleType>::doit(Val);
+ }
+};
+
+// Specialization used to strip const qualifiers off of the FromCl type...
+template<typename FromCl>
+struct isa_impl_cl<const FromCl> {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
+ }
+};
+
+// Define pointer traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl*> {
+ template<class ToCl>
+ static bool isa(FromCl *Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
+ }
+};
+
+// Define reference traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl&> {
+ template<class ToCl>
+ static bool isa(FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
+ }
+};
+
+template <class X, class Y>
+inline bool isa(const Y &Val) {
+ return isa_impl_cl<Y>::template isa<X>(Val);
+}
+
+//===----------------------------------------------------------------------===//
+// cast<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<class To, class From> struct cast_retty;
+
+
+// Calculate what type the 'cast' function should return, based on a requested
+// type of To and a source type of From.
+template<class To, class From> struct cast_retty_impl {
+ typedef To& ret_type; // Normal case, return Ty&
+};
+template<class To, class From> struct cast_retty_impl<To, const From> {
+ typedef const To &ret_type; // Normal case, return Ty&
+};
+
+template<class To, class From> struct cast_retty_impl<To, From*> {
+ typedef To* ret_type; // Pointer arg case, return Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*const> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+
+template<class To, class From, class SimpleFrom>
+struct cast_retty_wrap {
+ // When the simplified type and the from type are not the same, use the type
+ // simplifier to reduce the type, then reuse cast_retty_impl to get the
+ // resultant type.
+ typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+};
+
+template<class To, class FromTy>
+struct cast_retty_wrap<To, FromTy, FromTy> {
+ // When the simplified type is equal to the from type, use it directly.
+ typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+};
+
+template<class To, class From>
+struct cast_retty {
+ typedef typename cast_retty_wrap<To, From,
+ typename simplify_type<From>::SimpleType>::ret_type ret_type;
+};
+
+// Ensure the non-simple values are converted using the simplify_type template
+// that may be specialized by smart pointers...
+//
+template<class To, class From, class SimpleFrom> struct cast_convert_val {
+ // This is not a simple type, use the template to simplify it...
+ static typename cast_retty<To, From>::ret_type doit(const From &Val) {
+ return cast_convert_val<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
+ }
+};
+
+template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
+ // This _is_ a simple type, just cast it.
+ static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
+ return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>(
+ const_cast<FromTy&>(Val));
+ }
+};
+
+
+
+// cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator asserts that the type is correct, so it does not return null
+// on failure. But it will correctly return NULL when the input is NULL.
+// Used Like this:
+//
+// cast<Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
+ assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+ return cast_convert_val<X, Y,
+ typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+// cast_or_null<X> - Functionally identical to cast, except that a null value is
+// accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+ if (Val == 0) return 0;
+ assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
+ return cast<X>(Val);
+}
+
+
+// dyn_cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator returns null if the argument is of the wrong type, so it can
+// be used to test for a type as well as cast if successful. This should be
+// used in the context of an if statement like this:
+//
+// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
+//
+
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
+ return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+}
+
+// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
+// value is accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(const Y &Val) {
+ return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
+}
+
+
+#ifdef DEBUG_CAST_OPERATORS
+#include "llvm/Support/Streams.h"
+
+struct bar {
+ bar() {}
+private:
+ bar(const bar &);
+};
+struct foo {
+ void ext() const;
+ /* static bool classof(const bar *X) {
+ cerr << "Classof: " << X << "\n";
+ return true;
+ }*/
+};
+
+template <> inline bool isa_impl<foo,bar>(const bar &Val) {
+ cerr << "Classof: " << &Val << "\n";
+ return true;
+}
+
+
+bar *fub();
+void test(bar &B1, const bar *B2) {
+ // test various configurations of const
+ const bar &B3 = B1;
+ const bar *const B4 = B2;
+
+ // test isa
+ if (!isa<foo>(B1)) return;
+ if (!isa<foo>(B2)) return;
+ if (!isa<foo>(B3)) return;
+ if (!isa<foo>(B4)) return;
+
+ // test cast
+ foo &F1 = cast<foo>(B1);
+ const foo *F3 = cast<foo>(B2);
+ const foo *F4 = cast<foo>(B2);
+ const foo &F8 = cast<foo>(B3);
+ const foo *F9 = cast<foo>(B4);
+ foo *F10 = cast<foo>(fub());
+
+ // test cast_or_null
+ const foo *F11 = cast_or_null<foo>(B2);
+ const foo *F12 = cast_or_null<foo>(B2);
+ const foo *F13 = cast_or_null<foo>(B4);
+ const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
+
+ // These lines are errors...
+ //foo *F20 = cast<foo>(B2); // Yields const foo*
+ //foo &F21 = cast<foo>(B3); // Yields const foo&
+ //foo *F22 = cast<foo>(B4); // Yields const foo*
+ //foo &F23 = cast_or_null<foo>(B1);
+ //const foo &F24 = cast_or_null<foo>(B3);
+}
+
+bar *fub() { return 0; }
+void main() {
+ bar B;
+ test(B, &B);
+}
+
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
new file mode 100644
index 000000000000..fa3b8701d349
--- /dev/null
+++ b/include/llvm/Support/CommandLine.h
@@ -0,0 +1,1386 @@
+//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a command line argument processor that is useful when
+// creating a tool. It provides a simple, minimalistic interface that is easily
+// extensible and supports nonlocal (library) command line options.
+//
+// Note that rather than trying to figure out what this code does, you should
+// read the library documentation located in docs/CommandLine.html or looks at
+// the many example usages in tools/*/*.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMMANDLINE_H
+#define LLVM_SUPPORT_COMMANDLINE_H
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <climits>
+#include <cstdarg>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+/// cl Namespace - This namespace contains all of the command line option
+/// processing machinery. It is intentionally a short name to make qualified
+/// usage concise.
+namespace cl {
+
+//===----------------------------------------------------------------------===//
+// ParseCommandLineOptions - Command line option processing entry point.
+//
+void ParseCommandLineOptions(int argc, char **argv,
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
+
+//===----------------------------------------------------------------------===//
+// ParseEnvironmentOptions - Environment variable option processing alternate
+// entry point.
+//
+void ParseEnvironmentOptions(const char *progName, const char *envvar,
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
+
+///===---------------------------------------------------------------------===//
+/// SetVersionPrinter - Override the default (LLVM specific) version printer
+/// used to print out the version when --version is given
+/// on the command line. This allows other systems using the
+/// CommandLine utilities to print their own version string.
+void SetVersionPrinter(void (*func)());
+
+
+// MarkOptionsChanged - Internal helper function.
+void MarkOptionsChanged();
+
+//===----------------------------------------------------------------------===//
+// Flags permitted to be passed to command line arguments
+//
+
+enum NumOccurrences { // Flags for the number of occurrences allowed
+ Optional = 0x01, // Zero or One occurrence
+ ZeroOrMore = 0x02, // Zero or more occurrences allowed
+ Required = 0x03, // One occurrence required
+ OneOrMore = 0x04, // One or more occurrences required
+
+ // ConsumeAfter - Indicates that this option is fed anything that follows the
+ // last positional argument required by the application (it is an error if
+ // there are zero positional arguments, and a ConsumeAfter option is used).
+ // Thus, for example, all arguments to LLI are processed until a filename is
+ // found. Once a filename is found, all of the succeeding arguments are
+ // passed, unprocessed, to the ConsumeAfter option.
+ //
+ ConsumeAfter = 0x05,
+
+ OccurrencesMask = 0x07
+};
+
+enum ValueExpected { // Is a value required for the option?
+ ValueOptional = 0x08, // The value can appear... or not
+ ValueRequired = 0x10, // The value is required to appear!
+ ValueDisallowed = 0x18, // A value may not be specified (for flags)
+ ValueMask = 0x18
+};
+
+enum OptionHidden { // Control whether -help shows this option
+ NotHidden = 0x20, // Option included in --help & --help-hidden
+ Hidden = 0x40, // -help doesn't, but --help-hidden does
+ ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg
+ HiddenMask = 0x60
+};
+
+// Formatting flags - This controls special features that the option might have
+// that cause it to be parsed differently...
+//
+// Prefix - This option allows arguments that are otherwise unrecognized to be
+// matched by options that are a prefix of the actual value. This is useful for
+// cases like a linker, where options are typically of the form '-lfoo' or
+// '-L../../include' where -l or -L are the actual flags. When prefix is
+// enabled, and used, the value for the flag comes from the suffix of the
+// argument.
+//
+// Grouping - With this option enabled, multiple letter options are allowed to
+// bunch together with only a single hyphen for the whole group. This allows
+// emulation of the behavior that ls uses for example: ls -la === ls -l -a
+//
+
+enum FormattingFlags {
+ NormalFormatting = 0x000, // Nothing special
+ Positional = 0x080, // Is a positional argument, no '-' required
+ Prefix = 0x100, // Can this option directly prefix its value?
+ Grouping = 0x180, // Can this option group with other options?
+ FormattingMask = 0x180 // Union of the above flags.
+};
+
+enum MiscFlags { // Miscellaneous flags to adjust argument
+ CommaSeparated = 0x200, // Should this cl::list split between commas?
+ PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
+ Sink = 0x800, // Should this cl::list eat all unknown options?
+ MiscMask = 0xE00 // Union of the above flags.
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Option Base class
+//
+class alias;
+class Option {
+ friend class alias;
+
+ // handleOccurrences - Overriden by subclasses to handle the value passed into
+ // an argument. Should return true if there was an error processing the
+ // argument and the program should exit.
+ //
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) = 0;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // Out of line virtual function to provide home for the class.
+ virtual void anchor();
+
+ int NumOccurrences; // The number of times specified
+ int Flags; // Flags for the argument
+ unsigned Position; // Position of last occurrence of the option
+ unsigned AdditionalVals;// Greater than 0 for multi-valued option.
+ Option *NextRegistered; // Singly linked list of registered options.
+public:
+ const char *ArgStr; // The argument string itself (ex: "help", "o")
+ const char *HelpStr; // The descriptive text message for --help
+ const char *ValueStr; // String describing what the value of this option is
+
+ inline enum NumOccurrences getNumOccurrencesFlag() const {
+ return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
+ }
+ inline enum ValueExpected getValueExpectedFlag() const {
+ int VE = Flags & ValueMask;
+ return VE ? static_cast<enum ValueExpected>(VE)
+ : getValueExpectedFlagDefault();
+ }
+ inline enum OptionHidden getOptionHiddenFlag() const {
+ return static_cast<enum OptionHidden>(Flags & HiddenMask);
+ }
+ inline enum FormattingFlags getFormattingFlag() const {
+ return static_cast<enum FormattingFlags>(Flags & FormattingMask);
+ }
+ inline unsigned getMiscFlags() const {
+ return Flags & MiscMask;
+ }
+ inline unsigned getPosition() const { return Position; }
+ inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
+
+ // hasArgStr - Return true if the argstr != ""
+ bool hasArgStr() const { return ArgStr[0] != 0; }
+
+ //-------------------------------------------------------------------------===
+ // Accessor functions set by OptionModifiers
+ //
+ void setArgStr(const char *S) { ArgStr = S; }
+ void setDescription(const char *S) { HelpStr = S; }
+ void setValueStr(const char *S) { ValueStr = S; }
+
+ void setFlag(unsigned Flag, unsigned FlagMask) {
+ Flags &= ~FlagMask;
+ Flags |= Flag;
+ }
+
+ void setNumOccurrencesFlag(enum NumOccurrences Val) {
+ setFlag(Val, OccurrencesMask);
+ }
+ void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
+ void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
+ void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
+ void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
+ void setPosition(unsigned pos) { Position = pos; }
+protected:
+ explicit Option(unsigned DefaultFlags)
+ : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
+ AdditionalVals(0), NextRegistered(0),
+ ArgStr(""), HelpStr(""), ValueStr("") {
+ assert(getNumOccurrencesFlag() != 0 &&
+ getOptionHiddenFlag() != 0 && "Not all default flags specified!");
+ }
+
+ inline void setNumAdditionalVals(unsigned n)
+ { AdditionalVals = n; }
+public:
+ // addArgument - Register this argument with the commandline system.
+ //
+ void addArgument();
+
+ Option *getNextRegisteredOption() const { return NextRegistered; }
+
+ // Return the width of the option tag for printing...
+ virtual size_t getOptionWidth() const = 0;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(size_t GlobalWidth) const = 0;
+
+ virtual void getExtraOptionNames(std::vector<const char*> &) {}
+
+ // addOccurrence - Wrapper around handleOccurrence that enforces Flags
+ //
+ bool addOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Value, bool MultiArg = false);
+
+ // Prints option name followed by message. Always returns true.
+ bool error(std::string Message, const char *ArgName = 0);
+
+public:
+ inline int getNumOccurrences() const { return NumOccurrences; }
+ virtual ~Option() {}
+};
+
+
+//===----------------------------------------------------------------------===//
+// Command line option modifiers that can be used to modify the behavior of
+// command line option parsers...
+//
+
+// desc - Modifier to set the description shown in the --help output...
+struct desc {
+ const char *Desc;
+ desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setDescription(Desc); }
+};
+
+// value_desc - Modifier to set the value description shown in the --help
+// output...
+struct value_desc {
+ const char *Desc;
+ value_desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setValueStr(Desc); }
+};
+
+// init - Specify a default (initial) value for the command line argument, if
+// the default constructor for the argument type does not give you what you
+// want. This is only valid on "opt" arguments, not on "list" arguments.
+//
+template<class Ty>
+struct initializer {
+ const Ty &Init;
+ initializer(const Ty &Val) : Init(Val) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setInitialValue(Init); }
+};
+
+template<class Ty>
+initializer<Ty> init(const Ty &Val) {
+ return initializer<Ty>(Val);
+}
+
+
+// location - Allow the user to specify which external variable they want to
+// store the results of the command line argument processing into, if they don't
+// want to store it in the option itself.
+//
+template<class Ty>
+struct LocationClass {
+ Ty &Loc;
+ LocationClass(Ty &L) : Loc(L) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setLocation(O, Loc); }
+};
+
+template<class Ty>
+LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+
+
+//===----------------------------------------------------------------------===//
+// Enum valued command line option
+//
+#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
+#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
+#define clEnumValEnd (reinterpret_cast<void*>(0))
+
+// values - For custom data types, allow specifying a group of values together
+// as the values that go into the mapping that the option handler uses. Note
+// that the values list must always have a 0 at the end of the list to indicate
+// that the list has ended.
+//
+template<class DataType>
+class ValuesClass {
+ // Use a vector instead of a map, because the lists should be short,
+ // the overhead is less, and most importantly, it keeps them in the order
+ // inserted so we can print our option out nicely.
+ SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
+ void processValues(va_list Vals);
+public:
+ ValuesClass(const char *EnumName, DataType Val, const char *Desc,
+ va_list ValueArgs) {
+ // Insert the first value, which is required.
+ Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
+
+ // Process the varargs portion of the values...
+ while (const char *enumName = va_arg(ValueArgs, const char *)) {
+ DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
+ const char *EnumDesc = va_arg(ValueArgs, const char *);
+ Values.push_back(std::make_pair(enumName, // Add value to value map
+ std::make_pair(EnumVal, EnumDesc)));
+ }
+ }
+
+ template<class Opt>
+ void apply(Opt &O) const {
+ for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
+ i != e; ++i)
+ O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
+ Values[i].second.second);
+ }
+};
+
+template<class DataType>
+ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
+ const char *Desc, ...) {
+ va_list ValueArgs;
+ va_start(ValueArgs, Desc);
+ ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
+ va_end(ValueArgs);
+ return Vals;
+}
+
+
+//===----------------------------------------------------------------------===//
+// parser class - Parameterizable parser for different data types. By default,
+// known data types (string, int, bool) have specialized parsers, that do what
+// you would expect. The default parser, used for data types that are not
+// built-in, uses a mapping table to map specific options to values, which is
+// used, among other things, to handle enum types.
+
+//--------------------------------------------------
+// generic_parser_base - This class holds all the non-generic code that we do
+// not need replicated for every instance of the generic parser. This also
+// allows us to put stuff into CommandLine.cpp
+//
+struct generic_parser_base {
+ virtual ~generic_parser_base() {} // Base class should have virtual-dtor
+
+ // getNumOptions - Virtual function implemented by generic subclass to
+ // indicate how many entries are in Values.
+ //
+ virtual unsigned getNumOptions() const = 0;
+
+ // getOption - Return option name N.
+ virtual const char *getOption(unsigned N) const = 0;
+
+ // getDescription - Return description N
+ virtual const char *getDescription(unsigned N) const = 0;
+
+ // Return the width of the option tag for printing...
+ virtual size_t getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+ void initialize(Option &O) {
+ // All of the modifiers for the option have been processed by now, so the
+ // argstr field should be stable, copy it down now.
+ //
+ hasArgStr = O.hasArgStr();
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ // If there has been no argstr specified, that means that we need to add an
+ // argument for every possible option. This ensures that our options are
+ // vectored to us.
+ if (!hasArgStr)
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ OptionNames.push_back(getOption(i));
+ }
+
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ // If there is an ArgStr specified, then we are of the form:
+ //
+ // -opt=O2 or -opt O2 or -optO2
+ //
+ // In which case, the value is required. Otherwise if an arg str has not
+ // been specified, we are of the form:
+ //
+ // -O2 or O2 or -la (where -l and -a are separate options)
+ //
+ // If this is the case, we cannot allow a value.
+ //
+ if (hasArgStr)
+ return ValueRequired;
+ else
+ return ValueDisallowed;
+ }
+
+ // findOption - Return the option number corresponding to the specified
+ // argument string. If the option is not found, getNumOptions() is returned.
+ //
+ unsigned findOption(const char *Name);
+
+protected:
+ bool hasArgStr;
+};
+
+// Default parser implementation - This implementation depends on having a
+// mapping of recognized options to values of some sort. In addition to this,
+// each entry in the mapping also tracks a help message that is printed with the
+// command line option for --help. Because this is a simple mapping parser, the
+// data type can be any unsupported type.
+//
+template <class DataType>
+class parser : public generic_parser_base {
+protected:
+ SmallVector<std::pair<const char *,
+ std::pair<DataType, const char *> >, 8> Values;
+public:
+ typedef DataType parser_data_type;
+
+ // Implement virtual functions needed by generic_parser_base
+ unsigned getNumOptions() const { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const { return Values[N].first; }
+ const char *getDescription(unsigned N) const {
+ return Values[N].second.second;
+ }
+
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ DataType &V) {
+ std::string ArgVal;
+ if (hasArgStr)
+ ArgVal = Arg;
+ else
+ ArgVal = ArgName;
+
+ for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
+ i != e; ++i)
+ if (ArgVal == Values[i].first) {
+ V = Values[i].second.first;
+ return false;
+ }
+
+ return O.error(": Cannot find option named '" + ArgVal + "'!");
+ }
+
+ /// addLiteralOption - Add an entry to the mapping table.
+ ///
+ template <class DT>
+ void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
+ assert(findOption(Name) == Values.size() && "Option already exists!");
+ Values.push_back(std::make_pair(Name,
+ std::make_pair(static_cast<DataType>(V),HelpStr)));
+ MarkOptionsChanged();
+ }
+
+ /// removeLiteralOption - Remove the specified option.
+ ///
+ void removeLiteralOption(const char *Name) {
+ unsigned N = findOption(Name);
+ assert(N != Values.size() && "Option not found!");
+ Values.erase(Values.begin()+N);
+ }
+};
+
+//--------------------------------------------------
+// basic_parser - Super class of parsers to provide boilerplate code
+//
+struct basic_parser_impl { // non-template implementation of basic_parser<t>
+ virtual ~basic_parser_impl() {}
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueRequired;
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &) {}
+
+ void initialize(Option &) {}
+
+ // Return the width of the option tag for printing...
+ size_t getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "value"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+// basic_parser - The real basic parser is just a template wrapper that provides
+// a typedef for the provided data type.
+//
+template<class DataType>
+struct basic_parser : public basic_parser_impl {
+ typedef DataType parser_data_type;
+};
+
+//--------------------------------------------------
+// parser<bool>
+//
+template<>
+class parser<bool> : public basic_parser<bool> {
+ const char *ArgStr;
+public:
+
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+
+ template <class Opt>
+ void initialize(Opt &O) {
+ ArgStr = O.ArgStr;
+ }
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+
+//--------------------------------------------------
+// parser<boolOrDefault>
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ boolOrDefault &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+
+//--------------------------------------------------
+// parser<int>
+//
+template<>
+class parser<int> : public basic_parser<int> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "int"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+
+
+//--------------------------------------------------
+// parser<unsigned>
+//
+template<>
+class parser<unsigned> : public basic_parser<unsigned> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "uint"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+
+//--------------------------------------------------
+// parser<double>
+//
+template<>
+class parser<double> : public basic_parser<double> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+
+//--------------------------------------------------
+// parser<float>
+//
+template<>
+class parser<float> : public basic_parser<float> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+
+//--------------------------------------------------
+// parser<std::string>
+//
+template<>
+class parser<std::string> : public basic_parser<std::string> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &, const char *, const std::string &Arg,
+ std::string &Value) {
+ Value = Arg;
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "string"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+
+//--------------------------------------------------
+// parser<char>
+//
+template<>
+class parser<char> : public basic_parser<char> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &, const char *, const std::string &Arg,
+ char &Value) {
+ Value = Arg[0];
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "char"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
+
+//===----------------------------------------------------------------------===//
+// applicator class - This class is used because we must use partial
+// specialization to handle literal string arguments specially (const char* does
+// not correctly respond to the apply method). Because the syntax to use this
+// is a pain, we have the 'apply' method below to handle the nastiness...
+//
+template<class Mod> struct applicator {
+ template<class Opt>
+ static void opt(const Mod &M, Opt &O) { M.apply(O); }
+};
+
+// Handle const char* as a special case...
+template<unsigned n> struct applicator<char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<unsigned n> struct applicator<const char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<> struct applicator<const char*> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+
+template<> struct applicator<NumOccurrences> {
+ static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
+};
+template<> struct applicator<ValueExpected> {
+ static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
+};
+template<> struct applicator<OptionHidden> {
+ static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
+};
+template<> struct applicator<FormattingFlags> {
+ static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
+};
+template<> struct applicator<MiscFlags> {
+ static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
+};
+
+// apply method - Apply a modifier to an option in a type safe way.
+template<class Mod, class Opt>
+void apply(const Mod &M, Opt *O) {
+ applicator<Mod>::opt(M, *O);
+}
+
+
+//===----------------------------------------------------------------------===//
+// opt_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, bool ExternalStorage, bool isClass>
+class opt_storage {
+ DataType *Location; // Where to store the object...
+
+ void check() const {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage, "
+ "or cl::init specified before cl::location()!!");
+ }
+public:
+ opt_storage() : Location(0) {}
+
+ bool setLocation(Option &O, DataType &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void setValue(const T &V) {
+ check();
+ *Location = V;
+ }
+
+ DataType &getValue() { check(); return *Location; }
+ const DataType &getValue() const { check(); return *Location; }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class opt_storage<DataType,false,true> : public DataType {
+public:
+ template<class T>
+ void setValue(const T &V) { DataType::operator=(V); }
+
+ DataType &getValue() { return *this; }
+ const DataType &getValue() const { return *this; }
+};
+
+// Define a partial specialization to handle things we cannot inherit from. In
+// this case, we store an instance through containment, and overload operators
+// to get at the value.
+//
+template<class DataType>
+class opt_storage<DataType, false, false> {
+public:
+ DataType Value;
+
+ // Make sure we initialize the value with the default constructor for the
+ // type.
+ opt_storage() : Value(DataType()) {}
+
+ template<class T>
+ void setValue(const T &V) { Value = V; }
+ DataType &getValue() { return Value; }
+ DataType getValue() const { return Value; }
+
+ // If the datatype is a pointer, support -> on it.
+ DataType operator->() const { return Value; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// opt - A scalar command line option.
+//
+template <class DataType, bool ExternalStorage = false,
+ class ParserClass = parser<DataType> >
+class opt : public Option,
+ public opt_storage<DataType, ExternalStorage,
+ is_class<DataType>::value> {
+ ParserClass Parser;
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse error!
+ this->setValue(Val);
+ this->setPosition(pos);
+ return false;
+ }
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ // setInitialValue - Used by the cl::init modifier...
+ void setInitialValue(const DataType &V) { this->setValue(V); }
+
+ ParserClass &getParser() { return Parser; }
+
+ operator DataType() const { return this->getValue(); }
+
+ template<class T>
+ DataType &operator=(const T &Val) {
+ this->setValue(Val);
+ return this->getValue();
+ }
+
+ // One option...
+ template<class M0t>
+ explicit opt(const M0t &M0) : Option(Optional | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+
+ // Two options...
+ template<class M0t, class M1t>
+ opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ opt(const M0t &M0, const M1t &M1,
+ const M2t &M2) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2,
+ const M3t &M3) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5,
+ const M6t &M6) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+
+//===----------------------------------------------------------------------===//
+// list_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class list_storage {
+ StorageClass *Location; // Where to store the object...
+
+public:
+ list_storage() : Location(0) {}
+
+ bool setLocation(Option &O, StorageClass &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ Location->push_back(V);
+ }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class list_storage<DataType, bool> : public std::vector<DataType> {
+public:
+ template<class T>
+ void addValue(const T &V) { push_back(V); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// list - A list of command line options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class list : public Option, public list_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ void setNumAdditionalVals(unsigned n) {
+ Option::setNumAdditionalVals(n);
+ }
+
+ // One option...
+ template<class M0t>
+ explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+// multi_arg - Modifier to set the number of additional values.
+struct multi_val {
+ unsigned AdditionalVals;
+ explicit multi_val(unsigned N) : AdditionalVals(N) {}
+
+ template <typename D, typename S, typename P>
+ void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class bits_storage {
+ unsigned *Location; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ bits_storage() : Location(0) {}
+
+ bool setLocation(Option &O, unsigned &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ *Location |= Bit(V);
+ }
+
+ unsigned getBits() { return *Location; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (*Location & Bit(V)) != 0;
+ }
+};
+
+
+// Define how to hold bits. Since we can inherit from a class, we do so.
+// This makes us exactly compatible with the bits in all cases that it is used.
+//
+template<class DataType>
+class bits_storage<DataType, bool> {
+ unsigned Bits; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ template<class T>
+ void addValue(const T &V) {
+ Bits |= Bit(V);
+ }
+
+ unsigned getBits() { return Bits; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (Bits & Bit(V)) != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits - A bit vector of command options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class bits : public Option, public bits_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Aliased command line option (alias this name to a preexisting name)
+//
+
+class alias : public Option {
+ Option *AliasFor;
+ virtual bool handleOccurrence(unsigned pos, const char * /*ArgName*/,
+ const std::string &Arg) {
+ return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
+ }
+ // Handle printing stuff...
+ virtual size_t getOptionWidth() const;
+ virtual void printOptionInfo(size_t GlobalWidth) const;
+
+ void done() {
+ if (!hasArgStr())
+ error(": cl::alias must have argument name specified!");
+ if (AliasFor == 0)
+ error(": cl::alias must have an cl::aliasopt(option) specified!");
+ addArgument();
+ }
+public:
+ void setAliasFor(Option &O) {
+ if (AliasFor)
+ error(": cl::alias must only have one cl::aliasopt(...) specified!");
+ AliasFor = &O;
+ }
+
+ // One option...
+ template<class M0t>
+ explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+};
+
+// aliasfor - Modifier to set the option an alias aliases.
+struct aliasopt {
+ Option &Opt;
+ explicit aliasopt(Option &O) : Opt(O) {}
+ void apply(alias &A) const { A.setAliasFor(Opt); }
+};
+
+// extrahelp - provide additional help at the end of the normal help
+// output. All occurrences of cl::extrahelp will be accumulated and
+// printed to std::cerr at the end of the regular help, just before
+// exit is called.
+struct extrahelp {
+ const char * morehelp;
+ explicit extrahelp(const char* help);
+};
+
+void PrintVersionMessage();
+// This function just prints the help message, exactly the same way as if the
+// --help option had been given on the command line.
+// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+void PrintHelpMessage();
+
+} // End namespace cl
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
new file mode 100644
index 000000000000..90292df38196
--- /dev/null
+++ b/include/llvm/Support/Compiler.h
@@ -0,0 +1,59 @@
+//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines several macros, based on the current compiler. This allows
+// use of compiler-specific features in a way that remains portable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPILER_H
+#define LLVM_SUPPORT_COMPILER_H
+
+// The VISIBILITY_HIDDEN macro, used for marking classes with the GCC-specific
+// visibility("hidden") attribute.
+#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define VISIBILITY_HIDDEN __attribute__ ((visibility("hidden")))
+#else
+#define VISIBILITY_HIDDEN
+#endif
+
+#if (__GNUC__ >= 4)
+#define ATTRIBUTE_USED __attribute__((__used__))
+#else
+#define ATTRIBUTE_USED
+#endif
+
+#if (__GNUC__ >= 4)
+#define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE))
+#else
+#define BUILTIN_EXPECT(EXPR, VALUE) (EXPR)
+#endif
+
+// C++ doesn't support 'extern template' of template specializations. GCC does,
+// but requires __extension__ before it. In the header, use this:
+// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
+// in the .cpp file, use this:
+// TEMPLATE_INSTANTIATION(class foo<bar>);
+#ifdef __GNUC__
+#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
+#define TEMPLATE_INSTANTIATION(X) template X
+#else
+#define EXTERN_TEMPLATE_INSTANTIATION(X)
+#define TEMPLATE_INSTANTIATION(X)
+#endif
+
+// DISABLE_INLINE - On compilers where we have a directive to do so, mark a
+// method "not for inlining".
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#define DISABLE_INLINE __attribute__((noinline))
+#else
+#define DISABLE_INLINE
+#endif
+
+#endif
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
new file mode 100644
index 000000000000..ca8bcae85981
--- /dev/null
+++ b/include/llvm/Support/ConstantFolder.h
@@ -0,0 +1,189 @@
+//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ConstantFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants
+// with minimal folding. For general constant creation and folding,
+// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
+#define LLVM_SUPPORT_CONSTANTFOLDER_H
+
+#include "llvm/Constants.h"
+
+namespace llvm {
+
+/// ConstantFolder - Create constants with minimum, target independent, folding.
+class ConstantFolder {
+public:
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getAdd(LHS, RHS);
+ }
+ Constant *CreateSub(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getSub(LHS, RHS);
+ }
+ Constant *CreateMul(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getMul(LHS, RHS);
+ }
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getUDiv(LHS, RHS);
+ }
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getSDiv(LHS, RHS);
+ }
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFDiv(LHS, RHS);
+ }
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getURem(LHS, RHS);
+ }
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getSRem(LHS, RHS);
+ }
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFRem(LHS, RHS);
+ }
+ Constant *CreateShl(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getShl(LHS, RHS);
+ }
+ Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getLShr(LHS, RHS);
+ }
+ Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getAShr(LHS, RHS);
+ }
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getAnd(LHS, RHS);
+ }
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getOr(LHS, RHS);
+ }
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getXor(LHS, RHS);
+ }
+
+ Constant *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::get(Opc, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateNeg(Constant *C) const {
+ return ConstantExpr::getNeg(C);
+ }
+ Constant *CreateNot(Constant *C) const {
+ return ConstantExpr::getNot(C);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
+ }
+ Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+ const Type *DestTy) const {
+ return ConstantExpr::getCast(Op, C, DestTy);
+ }
+ Constant *CreateIntCast(Constant *C, const Type *DestTy,
+ bool isSigned) const {
+ return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
+ }
+
+ Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getTruncOrBitCast(C, DestTy);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+ Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+ Constant *CreateVICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+ Constant *CreateVFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ return ConstantExpr::getSelect(C, True, False);
+ }
+
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return ConstantExpr::getExtractElement(Vec, Idx);
+ }
+
+ Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
+ }
+
+ Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
+ return ConstantExpr::getShuffleVector(V1, V2, Mask);
+ }
+
+ Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx);
+ }
+
+ Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+ const unsigned *IdxList, unsigned NumIdx) const {
+ return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
new file mode 100644
index 000000000000..098fab5f98dd
--- /dev/null
+++ b/include/llvm/Support/ConstantRange.h
@@ -0,0 +1,195 @@
+//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Represent a range of possible values that may occur when the program is run
+// for an integral value. This keeps track of a lower and upper bound for the
+// constant, which MAY wrap around the end of the numeric range. To do this, it
+// keeps track of a [lower, upper) bound, which specifies an interval just like
+// STL iterators. When used with boolean values, the following are important
+// ranges: :
+//
+// [F, F) = {} = Empty set
+// [T, F) = {T}
+// [F, T) = {F}
+// [T, T) = {F, T} = Full set
+//
+// The other integral ranges use min/max values for special range values. For
+// example, for 8-bit types, it uses:
+// [0, 0) = {} = Empty set
+// [255, 255) = {0..255} = Full Set
+//
+// Note that ConstantRange always keeps unsigned values.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
+#define LLVM_SUPPORT_CONSTANT_RANGE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class ConstantRange {
+ APInt Lower, Upper;
+ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
+ const ConstantRange &RHS);
+ public:
+ /// Initialize a full (the default) or empty set for the specified bit width.
+ ///
+ explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
+
+ /// Initialize a range to hold the single specified value.
+ ///
+ ConstantRange(const APInt &Value);
+
+ /// @brief Initialize a range of values explicitly. This will assert out if
+ /// Lower==Upper and Lower != Min or Max value for its type. It will also
+ /// assert out if the two APInt's are not the same bit width.
+ ConstantRange(const APInt& Lower, const APInt& Upper);
+
+ /// getLower - Return the lower value for this range...
+ ///
+ const APInt &getLower() const { return Lower; }
+
+ /// getUpper - Return the upper value for this range...
+ ///
+ const APInt &getUpper() const { return Upper; }
+
+ /// getBitWidth - get the bit width of this ConstantRange
+ ///
+ uint32_t getBitWidth() const { return Lower.getBitWidth(); }
+
+ /// isFullSet - Return true if this set contains all of the elements possible
+ /// for this data-type
+ ///
+ bool isFullSet() const;
+
+ /// isEmptySet - Return true if this set contains no members.
+ ///
+ bool isEmptySet() const;
+
+ /// isWrappedSet - Return true if this set wraps around the top of the range,
+ /// for example: [100, 8)
+ ///
+ bool isWrappedSet() const;
+
+ /// contains - Return true if the specified value is in the set.
+ ///
+ bool contains(const APInt &Val) const;
+
+ /// getSingleElement - If this set contains a single element, return it,
+ /// otherwise return null.
+ ///
+ const APInt *getSingleElement() const {
+ if (Upper == Lower + 1)
+ return &Lower;
+ return 0;
+ }
+
+ /// isSingleElement - Return true if this set contains exactly one member.
+ ///
+ bool isSingleElement() const { return getSingleElement() != 0; }
+
+ /// getSetSize - Return the number of elements in this set.
+ ///
+ APInt getSetSize() const;
+
+ /// getUnsignedMax - Return the largest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMax() const;
+
+ /// getUnsignedMin - Return the smallest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMin() const;
+
+ /// getSignedMax - Return the largest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMax() const;
+
+ /// getSignedMin - Return the smallest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMin() const;
+
+ /// operator== - Return true if this range is equal to another range.
+ ///
+ bool operator==(const ConstantRange &CR) const {
+ return Lower == CR.Lower && Upper == CR.Upper;
+ }
+ bool operator!=(const ConstantRange &CR) const {
+ return !operator==(CR);
+ }
+
+ /// subtract - Subtract the specified constant from the endpoints of this
+ /// constant range.
+ ConstantRange subtract(const APInt &CI) const;
+
+ /// intersectWith - Return the range that results from the intersection of
+ /// this range with another range. The resultant range is pruned as much as
+ /// possible, but there may be cases where elements are included that are in
+ /// one of the sets but not the other. For example: [100, 8) intersect [3,
+ /// 120) yields [3, 120)
+ ///
+ ConstantRange intersectWith(const ConstantRange &CR) const;
+
+ /// maximalIntersectWith - Return the range that results from the intersection
+ /// of this range with another range. The resultant range is guaranteed to
+ /// include all elements contained in both input ranges, and to have the
+ /// smallest possible set size that does so. Because there may be two
+ /// intersections with the same set size, A.maximalIntersectWith(B) might not
+ /// be equal to B.maximalIntersectWith(A).
+ ///
+ ConstantRange maximalIntersectWith(const ConstantRange &CR) const;
+
+ /// unionWith - Return the range that results from the union of this range
+ /// with another range. The resultant range is guaranteed to include the
+ /// elements of both sets, but may contain more. For example, [3, 9) union
+ /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
+ /// in either set before.
+ ///
+ ConstantRange unionWith(const ConstantRange &CR) const;
+
+ /// zeroExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// zero extended to BitWidth.
+ ConstantRange zeroExtend(uint32_t BitWidth) const;
+
+ /// signExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// sign extended to BitWidth.
+ ConstantRange signExtend(uint32_t BitWidth) const;
+
+ /// truncate - Return a new range in the specified integer type, which must be
+ /// strictly smaller than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// truncated to the specified type.
+ ConstantRange truncate(uint32_t BitWidth) const;
+
+ /// print - Print out the bounds to a stream...
+ ///
+ void print(raw_ostream &OS) const;
+
+ /// dump - Allow printing from a debugger easily...
+ ///
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
+ CR.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
new file mode 100644
index 000000000000..7a61b2b16512
--- /dev/null
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -0,0 +1,141 @@
+//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a template class that can be used to customize dot output
+// graphs generated by the GraphWriter.h file. The default implementation of
+// this file will produce a simple, but not very polished graph. By
+// specializing this template, lots of customization opportunities are possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
+#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
+
+#include <string>
+
+namespace llvm {
+
+/// DefaultDOTGraphTraits - This class provides the default implementations of
+/// all of the DOTGraphTraits methods. If a specialization does not need to
+/// override all methods here it should inherit so that it can get the default
+/// implementations.
+///
+struct DefaultDOTGraphTraits {
+ /// getGraphName - Return the label for the graph as a whole. Printed at the
+ /// top of the graph.
+ ///
+ template<typename GraphType>
+ static std::string getGraphName(const GraphType& Graph) { return ""; }
+
+ /// getGraphProperties - Return any custom properties that should be included
+ /// in the top level graph structure for dot.
+ ///
+ template<typename GraphType>
+ static std::string getGraphProperties(const GraphType& Graph) {
+ return "";
+ }
+
+ /// renderGraphFromBottomUp - If this function returns true, the graph is
+ /// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work
+ /// though.
+ static bool renderGraphFromBottomUp() {
+ return false;
+ }
+
+ /// getNodeLabel - Given a node and a pointer to the top level graph, return
+ /// the label to print in the node.
+ template<typename GraphType>
+ static std::string getNodeLabel(const void *Node, const GraphType& Graph) {
+ return "";
+ }
+
+ /// hasNodeAddressLabel - If this method returns true, the address of the node
+ /// is added to the label of the node.
+ template<typename GraphType>
+ static bool hasNodeAddressLabel(const void *Node, const GraphType& Graph) {
+ return false;
+ }
+
+ /// If you want to specify custom node attributes, this is the place to do so
+ ///
+ template<typename GraphType>
+ static std::string getNodeAttributes(const void *Node,
+ const GraphType& Graph) {
+ return "";
+ }
+
+ /// If you want to override the dot attributes printed for a particular edge,
+ /// override this method.
+ template<typename EdgeIter>
+ static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
+ return "";
+ }
+
+ /// getEdgeSourceLabel - If you want to label the edge source itself,
+ /// implement this method.
+ template<typename EdgeIter>
+ static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
+ return "";
+ }
+
+ /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
+ /// should actually target another edge source, not a node. If this method is
+ /// implemented, getEdgeTarget should be implemented.
+ template<typename EdgeIter>
+ static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
+ return false;
+ }
+
+ /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+ /// called to determine which outgoing edge of Node is the target of this
+ /// edge.
+ template<typename EdgeIter>
+ static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
+ return I;
+ }
+
+ /// hasEdgeDestLabels - If this function returns true, the graph is able
+ /// to provide labels for edge destinations.
+ static bool hasEdgeDestLabels() {
+ return false;
+ }
+
+ /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
+ /// number of incoming edge labels the given node has.
+ static unsigned numEdgeDestLabels(const void *Node) {
+ return 0;
+ }
+
+ /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
+ /// incoming edge label with the given index in the given node.
+ static std::string getEdgeDestLabel(const void *Node, unsigned i) {
+ return "";
+ }
+
+ /// addCustomGraphFeatures - If a graph is made up of more than just
+ /// straight-forward nodes and edges, this is the place to put all of the
+ /// custom stuff necessary. The GraphWriter object, instantiated with your
+ /// GraphType is passed in as an argument. You may call arbitrary methods on
+ /// it to add things to the output graph.
+ ///
+ template<typename GraphType, typename GraphWriter>
+ static void addCustomGraphFeatures(const GraphType& Graph, GraphWriter &GW) {}
+};
+
+
+/// DOTGraphTraits - Template class that can be specialized to customize how
+/// graphs are converted to 'dot' graphs. When specializing, you may inherit
+/// from DefaultDOTGraphTraits if you don't need to override everything.
+///
+template <typename Ty>
+struct DOTGraphTraits : public DefaultDOTGraphTraits {};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h
new file mode 100644
index 000000000000..8f79ead1c533
--- /dev/null
+++ b/include/llvm/Support/DataFlow.h
@@ -0,0 +1,103 @@
+//===-- llvm/Support/DataFlow.h - dataflow as graphs ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines specializations of GraphTraits that allows Use-Def and
+// Def-Use relations to be treated as proper graphs for generic algorithms.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DATAFLOW_H
+#define LLVM_SUPPORT_DATAFLOW_H
+
+#include "llvm/User.h"
+#include "llvm/ADT/GraphTraits.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Provide specializations of GraphTraits to be able to treat def-use/use-def
+// chains as graphs
+
+template <> struct GraphTraits<const Value*> {
+ typedef const Value NodeType;
+ typedef Value::use_const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const Value *G) {
+ return G;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->use_begin();
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->use_end();
+ }
+};
+
+template <> struct GraphTraits<Value*> {
+ typedef Value NodeType;
+ typedef Value::use_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Value *G) {
+ return G;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->use_begin();
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->use_end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const User*> > {
+ typedef const Value NodeType;
+ typedef User::const_op_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<const User*> G) {
+ return G.Graph;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ if (const User *U = dyn_cast<User>(N))
+ return U->op_begin();
+ return NULL;
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ if(const User *U = dyn_cast<User>(N))
+ return U->op_end();
+ return NULL;
+ }
+};
+
+template <> struct GraphTraits<Inverse<User*> > {
+ typedef Value NodeType;
+ typedef User::op_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<User*> G) {
+ return G.Graph;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ if (User *U = dyn_cast<User>(N))
+ return U->op_begin();
+ return NULL;
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ if (User *U = dyn_cast<User>(N))
+ return U->op_end();
+ return NULL;
+ }
+};
+
+}
+#endif
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
new file mode 100644
index 000000000000..4d6fcc8e0974
--- /dev/null
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -0,0 +1,147 @@
+//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions to figure out the size of _HOST_ data types.
+// This file is important because different host OS's define different macros,
+// which makes portability tough. This file exports the following definitions:
+//
+// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
+// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
+#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
+#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
+#undef HAVE_UINT64_T
+#undef HAVE_U_INT64_T
+
+// FIXME: UGLY HACK (Added by Kevin)
+#define HAVE_UINT64_T 1
+
+#ifndef _MSC_VER
+
+// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+// being defined. We would define it here, but in order to prevent Bad Things
+// happening when system headers or C++ STL headers include stdint.h before
+// we define it here, we define it on the g++ command line (in Makefile.rules).
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including Support/DataTypes.h"
+#endif
+
+// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system.
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+// Handle incorrect definition of uint64_t as u_int64_t
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+// Visual C++ doesn't provide standard integer headers, but it does provide
+// built-in data types.
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#define INT8_C(C) C
+#define UINT8_C(C) C
+#define INT16_C(C) C
+#define UINT16_C(C) C
+#define INT32_C(C) C
+#define UINT32_C(C) C ## U
+#define INT64_C(C) ((int64_t) C ## LL)
+#define UINT64_C(C) ((uint64_t) C ## ULL)
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
new file mode 100644
index 000000000000..72063f7d2add
--- /dev/null
+++ b/include/llvm/Support/DataTypes.h.in
@@ -0,0 +1,144 @@
+//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions to figure out the size of _HOST_ data types.
+// This file is important because different host OS's define different macros,
+// which makes portability tough. This file exports the following definitions:
+//
+// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
+// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#undef HAVE_SYS_TYPES_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_STDINT_H
+#undef HAVE_UINT64_T
+#undef HAVE_U_INT64_T
+
+#ifndef _MSC_VER
+
+// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+// being defined. We would define it here, but in order to prevent Bad Things
+// happening when system headers or C++ STL headers include stdint.h before
+// we define it here, we define it on the g++ command line (in Makefile.rules).
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including Support/DataTypes.h"
+#endif
+
+// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system.
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+// Handle incorrect definition of uint64_t as u_int64_t
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+// Visual C++ doesn't provide standard integer headers, but it does provide
+// built-in data types.
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#define INT8_C(C) C
+#define UINT8_C(C) C
+#define INT16_C(C) C
+#define UINT16_C(C) C
+#define INT32_C(C) C
+#define UINT32_C(C) C ## U
+#define INT64_C(C) ((int64_t) C ## LL)
+#define UINT64_C(C) ((uint64_t) C ## ULL)
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
new file mode 100644
index 000000000000..52d0d3fb4055
--- /dev/null
+++ b/include/llvm/Support/Debug.h
@@ -0,0 +1,78 @@
+//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a handy way of adding debugging information to your
+// code, without it being enabled all of the time, and without having to add
+// command line options to enable it.
+//
+// In particular, just wrap your code with the DEBUG() macro, and it will be
+// enabled automatically if you specify '-debug' on the command-line.
+// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
+// that your debug code belongs to class "foo". Then, on the command line, you
+// can specify '-debug-only=foo' to enable JUST the debug information for the
+// foo class.
+//
+// When compiling in release mode, the -debug-* options and all code in DEBUG()
+// statements disappears, so it does not effect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUG_H
+#define LLVM_SUPPORT_DEBUG_H
+
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+
+// DebugFlag - This boolean is set to true if the '-debug' command line option
+// is specified. This should probably not be referenced directly, instead, use
+// the DEBUG macro below.
+//
+extern bool DebugFlag;
+
+// isCurrentDebugType - Return true if the specified string is the debug type
+// specified on the command line, or if none was specified on the command line
+// with the -debug-only=X option.
+//
+bool isCurrentDebugType(const char *Type);
+
+// DEBUG macro - This macro should be used by passes to emit debug information.
+// In the '-debug' option is specified on the commandline, and if this is a
+// debug build, then the code specified as the option to the macro will be
+// executed. Otherwise it will not be. Example:
+//
+// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
+//
+
+#ifndef DEBUG_TYPE
+#define DEBUG_TYPE ""
+#endif
+
+#ifdef NDEBUG
+#define DEBUG(X)
+#else
+#define DEBUG(X) \
+ do { if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { X; } } while (0)
+#endif
+
+/// getErrorOutputStream - Returns the error output stream (std::cerr). This
+/// places the std::c* I/O streams into one .cpp file and relieves the whole
+/// program from having to have hundreds of static c'tor/d'tors for them.
+///
+OStream &getErrorOutputStream(const char *DebugType);
+
+#ifdef NDEBUG
+#define DOUT llvm::OStream(0)
+#else
+#define DOUT llvm::getErrorOutputStream(DEBUG_TYPE)
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
new file mode 100644
index 000000000000..55838b8144bc
--- /dev/null
+++ b/include/llvm/Support/Dwarf.h
@@ -0,0 +1,587 @@
+//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants used for implementing Dwarf debug support. For
+// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
+// V.3 reference manual http://dwarf.freestandards.org ,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DWARF_H
+#define LLVM_SUPPORT_DWARF_H
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Debug info constants.
+
+enum {
+ LLVMDebugVersion = (7 << 16), // Current version of debug information.
+ LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+};
+
+namespace dwarf {
+
+//===----------------------------------------------------------------------===//
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// reference manual http://dwarf.freestandards.org .
+//
+
+// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
+// enumeration base type.
+
+enum llvm_dwarf_constants {
+ // llvm mock tags
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
+
+ DW_TAG_anchor = 0, // Tag for descriptor anchors.
+ DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+ DW_TAG_arg_variable = 0x101, // Tag for argument variables.
+ DW_TAG_return_variable = 0x102, // Tag for return variables.
+
+ DW_TAG_vector_type = 0x103, // Tag for vector types.
+
+ DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+
+ DW_CIE_VERSION = 1, // Common frame information version.
+ DW_CIE_ID = 0xffffffff // Common frame information mark.
+};
+
+enum dwarf_constants {
+ DWARF_VERSION = 2,
+
+ // Tags
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_parameter = 0x2f,
+ DW_TAG_template_value_parameter = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ DW_TAG_dwarf_procedure = 0x36,
+ DW_TAG_restrict_type = 0x37,
+ DW_TAG_interface_type = 0x38,
+ DW_TAG_namespace = 0x39,
+ DW_TAG_imported_module = 0x3a,
+ DW_TAG_unspecified_type = 0x3b,
+ DW_TAG_partial_unit = 0x3c,
+ DW_TAG_imported_unit = 0x3d,
+ DW_TAG_condition = 0x3f,
+ DW_TAG_shared_type = 0x40,
+ DW_TAG_lo_user = 0x4080,
+ DW_TAG_hi_user = 0xffff,
+
+ // Children flag
+ DW_CHILDREN_no = 0x00,
+ DW_CHILDREN_yes = 0x01,
+
+ // Attributes
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_item = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_allocated = 0x4e,
+ DW_AT_associated = 0x4f,
+ DW_AT_data_location = 0x50,
+ DW_AT_byte_stride = 0x51,
+ DW_AT_entry_pc = 0x52,
+ DW_AT_use_UTF8 = 0x53,
+ DW_AT_extension = 0x54,
+ DW_AT_ranges = 0x55,
+ DW_AT_trampoline = 0x56,
+ DW_AT_call_column = 0x57,
+ DW_AT_call_file = 0x58,
+ DW_AT_call_line = 0x59,
+ DW_AT_description = 0x5a,
+ DW_AT_binary_scale = 0x5b,
+ DW_AT_decimal_scale = 0x5c,
+ DW_AT_small = 0x5d,
+ DW_AT_decimal_sign = 0x5e,
+ DW_AT_digit_count = 0x5f,
+ DW_AT_picture_string = 0x60,
+ DW_AT_mutable = 0x61,
+ DW_AT_threads_scaled = 0x62,
+ DW_AT_explicit = 0x63,
+ DW_AT_object_pointer = 0x64,
+ DW_AT_endianity = 0x65,
+ DW_AT_elemental = 0x66,
+ DW_AT_pure = 0x67,
+ DW_AT_recursive = 0x68,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106,
+ DW_AT_GNU_vector = 0x2107,
+ DW_AT_lo_user = 0x2000,
+ DW_AT_hi_user = 0x3fff,
+
+ // Apple extensions.
+ DW_AT_APPLE_optimized = 0x3fe1,
+ DW_AT_APPLE_flags = 0x3fe2,
+ DW_AT_APPLE_isa = 0x3fe3,
+ DW_AT_APPLE_block = 0x3fe4,
+ DW_AT_APPLE_major_runtime_vers = 0x3fe5,
+ DW_AT_APPLE_runtime_class = 0x3fe6,
+
+ // Attribute form encodings
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16,
+
+ // Operation encodings
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_skip = 0x2f,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96,
+ DW_OP_push_object_address = 0x97,
+ DW_OP_call2 = 0x98,
+ DW_OP_call4 = 0x99,
+ DW_OP_call_ref = 0x9a,
+ DW_OP_form_tls_address = 0x9b,
+ DW_OP_call_frame_cfa = 0x9c,
+ DW_OP_lo_user = 0xe0,
+ DW_OP_hi_user = 0xff,
+
+ // Encoding attribute values
+ DW_ATE_address = 0x01,
+ DW_ATE_boolean = 0x02,
+ DW_ATE_complex_float = 0x03,
+ DW_ATE_float = 0x04,
+ DW_ATE_signed = 0x05,
+ DW_ATE_signed_char = 0x06,
+ DW_ATE_unsigned = 0x07,
+ DW_ATE_unsigned_char = 0x08,
+ DW_ATE_imaginary_float = 0x09,
+ DW_ATE_packed_decimal = 0x0a,
+ DW_ATE_numeric_string = 0x0b,
+ DW_ATE_edited = 0x0c,
+ DW_ATE_signed_fixed = 0x0d,
+ DW_ATE_unsigned_fixed = 0x0e,
+ DW_ATE_decimal_float = 0x0f,
+ DW_ATE_lo_user = 0x80,
+ DW_ATE_hi_user = 0xff,
+
+ // Decimal sign attribute values
+ DW_DS_unsigned = 0x01,
+ DW_DS_leading_overpunch = 0x02,
+ DW_DS_trailing_overpunch = 0x03,
+ DW_DS_leading_separate = 0x04,
+ DW_DS_trailing_separate = 0x05,
+
+ // Endianity attribute values
+ DW_END_default = 0x00,
+ DW_END_big = 0x01,
+ DW_END_little = 0x02,
+ DW_END_lo_user = 0x40,
+ DW_END_hi_user = 0xff,
+
+ // Accessibility codes
+ DW_ACCESS_public = 0x01,
+ DW_ACCESS_protected = 0x02,
+ DW_ACCESS_private = 0x03,
+
+ // Visibility codes
+ DW_VIS_local = 0x01,
+ DW_VIS_exported = 0x02,
+ DW_VIS_qualified = 0x03,
+
+ // Virtuality codes
+ DW_VIRTUALITY_none = 0x00,
+ DW_VIRTUALITY_virtual = 0x01,
+ DW_VIRTUALITY_pure_virtual = 0x02,
+
+ // Language names
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_C99 = 0x000c,
+ DW_LANG_Ada95 = 0x000d,
+ DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_PLI = 0x000f,
+ DW_LANG_ObjC = 0x0010,
+ DW_LANG_ObjC_plus_plus = 0x0011,
+ DW_LANG_UPC = 0x0012,
+ DW_LANG_D = 0x0013,
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_hi_user = 0xffff,
+
+ // Identifier case codes
+ DW_ID_case_sensitive = 0x00,
+ DW_ID_up_case = 0x01,
+ DW_ID_down_case = 0x02,
+ DW_ID_case_insensitive = 0x03,
+
+ // Calling convention codes
+ DW_CC_normal = 0x01,
+ DW_CC_program = 0x02,
+ DW_CC_nocall = 0x03,
+ DW_CC_lo_user = 0x40,
+ DW_CC_hi_user = 0xff,
+
+ // Inline codes
+ DW_INL_not_inlined = 0x00,
+ DW_INL_inlined = 0x01,
+ DW_INL_declared_not_inlined = 0x02,
+ DW_INL_declared_inlined = 0x03,
+
+ // Array ordering
+ DW_ORD_row_major = 0x00,
+ DW_ORD_col_major = 0x01,
+
+ // Discriminant descriptor values
+ DW_DSC_label = 0x00,
+ DW_DSC_range = 0x01,
+
+ // Line Number Standard Opcode Encodings
+ DW_LNS_copy = 0x01,
+ DW_LNS_advance_pc = 0x02,
+ DW_LNS_advance_line = 0x03,
+ DW_LNS_set_file = 0x04,
+ DW_LNS_set_column = 0x05,
+ DW_LNS_negate_stmt = 0x06,
+ DW_LNS_set_basic_block = 0x07,
+ DW_LNS_const_add_pc = 0x08,
+ DW_LNS_fixed_advance_pc = 0x09,
+ DW_LNS_set_prologue_end = 0x0a,
+ DW_LNS_set_epilogue_begin = 0x0b,
+ DW_LNS_set_isa = 0x0c,
+
+ // Line Number Extended Opcode Encodings
+ DW_LNE_end_sequence = 0x01,
+ DW_LNE_set_address = 0x02,
+ DW_LNE_define_file = 0x03,
+ DW_LNE_lo_user = 0x80,
+ DW_LNE_hi_user = 0xff,
+
+ // Macinfo Type Encodings
+ DW_MACINFO_define = 0x01,
+ DW_MACINFO_undef = 0x02,
+ DW_MACINFO_start_file = 0x03,
+ DW_MACINFO_end_file = 0x04,
+ DW_MACINFO_vendor_ext = 0xff,
+
+ // Call frame instruction encodings
+ DW_CFA_extended = 0x00,
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ DW_CFA_offset_extended_sf = 0x11,
+ DW_CFA_def_cfa_sf = 0x12,
+ DW_CFA_def_cfa_offset_sf = 0x13,
+ DW_CFA_val_offset = 0x14,
+ DW_CFA_val_offset_sf = 0x15,
+ DW_CFA_val_expression = 0x16,
+ DW_CFA_lo_user = 0x1c,
+ DW_CFA_hi_user = 0x3f,
+
+ DW_EH_PE_absptr = 0x00,
+ DW_EH_PE_omit = 0xff,
+ DW_EH_PE_uleb128 = 0x01,
+ DW_EH_PE_udata2 = 0x02,
+ DW_EH_PE_udata4 = 0x03,
+ DW_EH_PE_udata8 = 0x04,
+ DW_EH_PE_sleb128 = 0x09,
+ DW_EH_PE_sdata2 = 0x0A,
+ DW_EH_PE_sdata4 = 0x0B,
+ DW_EH_PE_sdata8 = 0x0C,
+ DW_EH_PE_signed = 0x08,
+ DW_EH_PE_pcrel = 0x10,
+ DW_EH_PE_textrel = 0x20,
+ DW_EH_PE_datarel = 0x30,
+ DW_EH_PE_funcrel = 0x40,
+ DW_EH_PE_aligned = 0x50,
+ DW_EH_PE_indirect = 0x80
+};
+
+/// TagString - Return the string for the specified tag.
+///
+const char *TagString(unsigned Tag);
+
+/// ChildrenString - Return the string for the specified children flag.
+///
+const char *ChildrenString(unsigned Children);
+
+/// AttributeString - Return the string for the specified attribute.
+///
+const char *AttributeString(unsigned Attribute);
+
+/// FormEncodingString - Return the string for the specified form encoding.
+///
+const char *FormEncodingString(unsigned Encoding);
+
+/// OperationEncodingString - Return the string for the specified operation
+/// encoding.
+const char *OperationEncodingString(unsigned Encoding);
+
+/// AttributeEncodingString - Return the string for the specified attribute
+/// encoding.
+const char *AttributeEncodingString(unsigned Encoding);
+
+/// DecimalSignString - Return the string for the specified decimal sign
+/// attribute.
+const char *DecimalSignString(unsigned Sign);
+
+/// EndianityString - Return the string for the specified endianity.
+///
+const char *EndianityString(unsigned Endian);
+
+/// AccessibilityString - Return the string for the specified accessibility.
+///
+const char *AccessibilityString(unsigned Access);
+
+/// VisibilityString - Return the string for the specified visibility.
+///
+const char *VisibilityString(unsigned Visibility);
+
+/// VirtualityString - Return the string for the specified virtuality.
+///
+const char *VirtualityString(unsigned Virtuality);
+
+/// LanguageString - Return the string for the specified language.
+///
+const char *LanguageString(unsigned Language);
+
+/// CaseString - Return the string for the specified identifier case.
+///
+const char *CaseString(unsigned Case);
+
+/// ConventionString - Return the string for the specified calling convention.
+///
+const char *ConventionString(unsigned Convention);
+
+/// InlineCodeString - Return the string for the specified inline code.
+///
+const char *InlineCodeString(unsigned Code);
+
+/// ArrayOrderString - Return the string for the specified array order.
+///
+const char *ArrayOrderString(unsigned Order);
+
+/// DiscriminantString - Return the string for the specified discriminant
+/// descriptor.
+const char *DiscriminantString(unsigned Discriminant);
+
+/// LNStandardString - Return the string for the specified line number standard.
+///
+const char *LNStandardString(unsigned Standard);
+
+/// LNExtendedString - Return the string for the specified line number extended
+/// opcode encodings.
+const char *LNExtendedString(unsigned Encoding);
+
+/// MacinfoString - Return the string for the specified macinfo type encodings.
+///
+const char *MacinfoString(unsigned Encoding);
+
+/// CallFrameString - Return the string for the specified call frame instruction
+/// encodings.
+const char *CallFrameString(unsigned Encoding);
+
+} // End of namespace dwarf
+
+} // End of namespace llvm
+
+#endif
diff --git a/include/llvm/Support/DynamicLinker.h b/include/llvm/Support/DynamicLinker.h
new file mode 100644
index 000000000000..b60ffa875c63
--- /dev/null
+++ b/include/llvm/Support/DynamicLinker.h
@@ -0,0 +1,40 @@
+//===-- llvm/Support/DynamicLinker.h - Portable Dynamic Linker --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Lightweight interface to dynamic library linking and loading, and dynamic
+// symbol lookup functionality, in whatever form the operating system
+// provides it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DYNAMICLINKER_H
+#define LLVM_SUPPORT_DYNAMICLINKER_H
+
+#include <string>
+
+namespace llvm {
+
+/// LinkDynamicObject - Load the named file as a dynamic library
+/// and link it with the currently running process. Returns false
+/// on success, true if there is an error (and sets ErrorMessage
+/// if it is not NULL). Analogous to dlopen().
+///
+bool LinkDynamicObject (const char *filename, std::string *ErrorMessage);
+
+/// GetAddressOfSymbol - Returns the address of the named symbol in
+/// the currently running process, as reported by the dynamic linker,
+/// or NULL if the symbol does not exist or some other error has
+/// occurred.
+///
+void *GetAddressOfSymbol (const char *symbolName);
+void *GetAddressOfSymbol (const std::string &symbolName);
+
+} // End llvm namespace
+
+#endif // SUPPORT_DYNAMICLINKER_H
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
new file mode 100644
index 000000000000..aa27946e433b
--- /dev/null
+++ b/include/llvm/Support/ELF.h
@@ -0,0 +1,309 @@
+//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the ELF file format.
+//
+// The details of the ELF32 bits in this file are largely based on
+// the Tool Interface Standard (TIS) Executable and Linking Format
+// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
+// standardized, as far as I can tell. It was largely based on information
+// I found in OpenBSD header files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELF_H
+#define LLVM_SUPPORT_ELF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+
+namespace llvm {
+
+namespace ELF {
+
+typedef uint32_t Elf32_Addr; // Program address
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off; // File offset
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Shalf;
+typedef int32_t Elf64_Sword;
+typedef uint32_t Elf64_Word;
+typedef int64_t Elf64_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef uint32_t Elf64_Half;
+typedef uint16_t Elf64_Quarter;
+
+// Object file magic string.
+static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
+
+struct Elf32_Ehdr {
+ unsigned char e_ident[16]; // ELF Identification bytes
+ Elf32_Half e_type; // Type of file (see ET_* below)
+ Elf32_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf32_Word e_version; // Must be equal to 1
+ Elf32_Addr e_entry; // Address to jump to in order to start program
+ Elf32_Off e_phoff; // Program header table's file offset, in bytes
+ Elf32_Off e_shoff; // Section header table's file offset, in bytes
+ Elf32_Word e_flags; // Processor-specific flags
+ Elf32_Half e_ehsize; // Size of ELF header, in bytes
+ Elf32_Half e_phentsize; // Size of an entry in the program header table
+ Elf32_Half e_phnum; // Number of entries in the program header table
+ Elf32_Half e_shentsize; // Size of an entry in the section header table
+ Elf32_Half e_shnum; // Number of entries in the section header table
+ Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
+ bool checkMagic () const {
+ return (memcmp (e_ident, ElfMagic, strlen (ElfMagic))) == 0;
+ }
+ unsigned char getFileClass () const { return e_ident[4]; }
+ unsigned char getDataEncoding () { return e_ident[5]; }
+};
+
+// 64-bit ELF header. Fields are the same as for ELF32, but with different
+// types (see above).
+struct Elf64_Ehdr {
+ unsigned char e_ident[16];
+ Elf64_Quarter e_type;
+ Elf64_Quarter e_machine;
+ Elf64_Half e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Half e_flags;
+ Elf64_Quarter e_ehsize;
+ Elf64_Quarter e_phentsize;
+ Elf64_Quarter e_phnum;
+ Elf64_Quarter e_shentsize;
+ Elf64_Quarter e_shnum;
+ Elf64_Quarter e_shstrndx;
+};
+
+// File types
+enum {
+ ET_NONE = 0, // No file type
+ ET_REL = 1, // Relocatable file
+ ET_EXEC = 2, // Executable file
+ ET_DYN = 3, // Shared object file
+ ET_CORE = 4, // Core file
+ ET_LOPROC = 0xff00, // Beginning of processor-specific codes
+ ET_HIPROC = 0xffff // Processor-specific
+};
+
+// Machine architectures
+enum {
+ EM_NONE = 0, // No machine
+ EM_M32 = 1, // AT&T WE 32100
+ EM_SPARC = 2, // SPARC
+ EM_386 = 3, // Intel 386
+ EM_68K = 4, // Motorola 68000
+ EM_88K = 5, // Motorola 88000
+ EM_486 = 6, // Intel 486 (deprecated)
+ EM_860 = 7, // Intel 80860
+ EM_MIPS = 8, // MIPS R3000
+ EM_PPC = 20, // PowerPC
+ EM_ARM = 40, // ARM
+ EM_ALPHA = 41, // DEC Alpha
+ EM_SPARCV9 = 43, // SPARC V9
+ EM_X86_64 = 62 // AMD64
+};
+
+// Object file classes.
+enum {
+ ELFCLASS32 = 1, // 32-bit object file
+ ELFCLASS64 = 2 // 64-bit object file
+};
+
+// Object file byte orderings.
+enum {
+ ELFDATA2LSB = 1, // Little-endian object file
+ ELFDATA2MSB = 2 // Big-endian object file
+};
+
+// Section header.
+struct Elf32_Shdr {
+ Elf32_Word sh_name; // Section name (index into string table)
+ Elf32_Word sh_type; // Section type (SHT_*)
+ Elf32_Word sh_flags; // Section flags (SHF_*)
+ Elf32_Addr sh_addr; // Address where section is to be loaded
+ Elf32_Off sh_offset; // File offset of section data, in bytes
+ Elf32_Word sh_size; // Size of section, in bytes
+ Elf32_Word sh_link; // Section type-specific header table index link
+ Elf32_Word sh_info; // Section type-specific extra information
+ Elf32_Word sh_addralign; // Section address alignment
+ Elf32_Word sh_entsize; // Size of records contained within the section
+};
+
+// Section header for ELF64 - same fields as ELF32, different types.
+struct Elf64_Shdr {
+ Elf64_Half sh_name;
+ Elf64_Half sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Half sh_link;
+ Elf64_Half sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+};
+
+// Special section indices.
+enum {
+ SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
+ SHN_LORESERVE = 0xff00, // Lowest reserved index
+ SHN_LOPROC = 0xff00, // Lowest processor-specific index
+ SHN_HIPROC = 0xff1f, // Highest processor-specific index
+ SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
+ SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
+ SHN_HIRESERVE = 0xffff // Highest reserved index
+};
+
+// Section types.
+enum {
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
+ SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+};
+
+// Section flags.
+enum {
+ SHF_WRITE = 0x1, // Section data should be writable during execution.
+ SHF_ALLOC = 0x2, // Section occupies memory during program execution.
+ SHF_EXECINSTR = 0x4, // Section contains executable machine instructions.
+ SHF_MASKPROC = 0xf0000000 // Bits indicating processor-specific flags.
+};
+
+// Symbol table entries.
+struct Elf32_Sym {
+ Elf32_Word st_name; // Symbol name (index into string table)
+ Elf32_Addr st_value; // Value or address associated with the symbol
+ Elf32_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf32_Half st_shndx; // Which section (header table index) it's defined in
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding () const { return st_info >> 4; }
+ unsigned char getType () const { return st_info & 0x0f; }
+ void setBinding (unsigned char b) { setBindingAndType (b, getType ()); }
+ void setType (unsigned char t) { setBindingAndType (getBinding (), t); }
+ void setBindingAndType (unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+// Symbol bindings.
+enum {
+ STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
+ STB_GLOBAL = 1, // Global symbol, visible to all object files being combined
+ STB_WEAK = 2, // Weak symbol, like global but lower-precedence
+ STB_LOPROC = 13, // Lowest processor-specific binding type
+ STB_HIPROC = 15 // Highest processor-specific binding type
+};
+
+// Symbol types.
+enum {
+ STT_NOTYPE = 0, // Symbol's type is not specified
+ STT_OBJECT = 1, // Symbol is a data object (variable, array, etc.)
+ STT_FUNC = 2, // Symbol is executable code (function, etc.)
+ STT_SECTION = 3, // Symbol refers to a section
+ STT_FILE = 4, // Local, absolute symbol that refers to a file
+ STT_LOPROC = 13, // Lowest processor-specific symbol type
+ STT_HIPROC = 15 // Highest processor-specific symbol type
+};
+
+// Relocation entry, without explicit addend.
+struct Elf32_Rel {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Relocation entry with explicit addend.
+struct Elf32_Rela {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+ Elf32_Sword r_addend; // Compute value for relocatable field by adding this
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Program header.
+struct Elf32_Phdr {
+ Elf32_Word p_type; // Type of segment
+ Elf32_Off p_offset; // File offset where segment is located, in bytes
+ Elf32_Addr p_vaddr; // Virtual address of beginning of segment
+ Elf32_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf32_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf32_Word p_flags; // Segment flags
+ Elf32_Word p_align; // Segment alignment constraint
+};
+
+// Segment types.
+enum {
+ PT_NULL = 0, // Unused segment.
+ PT_LOAD = 1, // Loadable segment.
+ PT_DYNAMIC = 2, // Dynamic linking information.
+ PT_INTERP = 3, // Interpreter pathname.
+ PT_NOTE = 4, // Auxiliary information.
+ PT_SHLIB = 5, // Reserved.
+ PT_PHDR = 6, // The program header table itself.
+ PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
+ PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
+};
+
+// Segment flag bits.
+enum {
+ PF_X = 1, // Execute
+ PF_W = 2, // Write
+ PF_R = 4, // Read
+ PF_MASKPROC = 0xf0000000 // Unspecified
+};
+
+} // end namespace ELF
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
new file mode 100644
index 000000000000..cc8f95372b11
--- /dev/null
+++ b/include/llvm/Support/FileUtilities.h
@@ -0,0 +1,59 @@
+//===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEUTILITIES_H
+#define LLVM_SUPPORT_FILEUTILITIES_H
+
+#include "llvm/System/Path.h"
+
+namespace llvm {
+
+ /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
+ /// the files match, 1 if they are different, and 2 if there is a file error.
+ /// This function allows you to specify an absolete and relative FP error that
+ /// is allowed to exist. If you specify a string to fill in for the error
+ /// option, it will set the string to an error message if an error occurs, or
+ /// if the files are different.
+ ///
+ int DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
+ const sys::PathWithStatus &FileB,
+ double AbsTol, double RelTol,
+ std::string *Error = 0);
+
+
+ /// FileRemover - This class is a simple object meant to be stack allocated.
+ /// If an exception is thrown from a region, the object removes the filename
+ /// specified (if deleteIt is true).
+ ///
+ class FileRemover {
+ sys::Path Filename;
+ bool DeleteIt;
+ public:
+ explicit FileRemover(const sys::Path &filename, bool deleteIt = true)
+ : Filename(filename), DeleteIt(deleteIt) {}
+
+ ~FileRemover() {
+ if (DeleteIt) {
+ // Ignore problems deleting the file.
+ Filename.eraseFromDisk();
+ }
+ }
+
+ /// releaseFile - Take ownership of the file away from the FileRemover so it
+ /// will not be removed when the object is destroyed.
+ void releaseFile() { DeleteIt = false; }
+ };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
new file mode 100644
index 000000000000..2ab097faf56d
--- /dev/null
+++ b/include/llvm/Support/Format.h
@@ -0,0 +1,155 @@
+//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the format() function, which can be used with other
+// LLVM subsystems to provide printf-style formatting. This gives all the power
+// and risk of printf. This can be used like this (with raw_ostreams as an
+// example):
+//
+// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
+//
+// Or if you prefer:
+//
+// OS << format("mynumber: %4.5f\n", 1234.412);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMAT_H
+#define LLVM_SUPPORT_FORMAT_H
+
+#include <cstdio>
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+
+namespace llvm {
+
+/// format_object_base - This is a helper class used for handling formatted
+/// output. It is the abstract base class of a templated derived class.
+class format_object_base {
+protected:
+ const char *Fmt;
+ virtual void home(); // Out of line virtual method.
+public:
+ format_object_base(const char *fmt) : Fmt(fmt) {}
+ virtual ~format_object_base() {}
+
+ /// print - Format the object into the specified buffer. On success, this
+ /// returns the length of the formatted string. If the buffer is too small,
+ /// this returns a length to retry with, which will be larger than BufferSize.
+ virtual unsigned print(char *Buffer, unsigned BufferSize) const = 0;
+};
+
+/// format_object1 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T>
+class format_object1 : public format_object_base {
+ T Val;
+public:
+ format_object1(const char *fmt, const T &val)
+ : format_object_base(fmt), Val(val) {
+ }
+
+ /// print - Format the object into the specified buffer. On success, this
+ /// returns the length of the formatted string. If the buffer is too small,
+ /// this returns a length to retry with, which will be larger than BufferSize.
+ virtual unsigned print(char *Buffer, unsigned BufferSize) const {
+ int N = snprintf(Buffer, BufferSize-1, Fmt, Val);
+ if (N < 0) // VC++ and old GlibC return negative on overflow.
+ return BufferSize*2;
+ if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
+ return N+1;
+ // If N is positive and <= BufferSize-1, then the string fit, yay.
+ return N;
+ }
+};
+
+/// format_object2 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2>
+class format_object2 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+public:
+ format_object2(const char *fmt, const T1 &val1, const T2 &val2)
+ : format_object_base(fmt), Val1(val1), Val2(val2) {
+ }
+
+ /// print - Format the object into the specified buffer. On success, this
+ /// returns the length of the formatted string. If the buffer is too small,
+ /// this returns a length to retry with, which will be larger than BufferSize.
+ virtual unsigned print(char *Buffer, unsigned BufferSize) const {
+ int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2);
+ if (N < 0) // VC++ and old GlibC return negative on overflow.
+ return BufferSize*2;
+ if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
+ return N+1;
+ // If N is positive and <= BufferSize-1, then the string fit, yay.
+ return N;
+ }
+};
+
+/// format_object3 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2, typename T3>
+class format_object3 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+public:
+ format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3)
+ : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
+ }
+
+ /// print - Format the object into the specified buffer. On success, this
+ /// returns the length of the formatted string. If the buffer is too small,
+ /// this returns a length to retry with, which will be larger than BufferSize.
+ virtual unsigned print(char *Buffer, unsigned BufferSize) const {
+ int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2, Val3);
+ if (N < 0) // VC++ and old GlibC return negative on overflow.
+ return BufferSize*2;
+ if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
+ return N+1;
+ // If N is positive and <= BufferSize-1, then the string fit, yay.
+ return N;
+ }
+};
+
+/// format - This is a helper function that is used to produce formatted output.
+/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+template <typename T>
+inline format_object1<T> format(const char *Fmt, const T &Val) {
+ return format_object1<T>(Fmt, Val);
+}
+
+/// format - This is a helper function that is used to produce formatted output.
+/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+template <typename T1, typename T2>
+inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
+ const T2 &Val2) {
+ return format_object2<T1, T2>(Fmt, Val1, Val2);
+}
+
+/// format - This is a helper function that is used to produce formatted output.
+/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+template <typename T1, typename T2, typename T3>
+ inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
+ const T2 &Val2, const T3 &Val3) {
+ return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
new file mode 100644
index 000000000000..e1cda75c5f6a
--- /dev/null
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -0,0 +1,112 @@
+//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an iterator for walking through the types indexed by
+// getelementptr instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+
+#include "llvm/User.h"
+#include "llvm/DerivedTypes.h"
+
+namespace llvm {
+ template<typename ItTy = User::const_op_iterator>
+ class generic_gep_type_iterator
+ : public forward_iterator<const Type *, ptrdiff_t> {
+ typedef forward_iterator<const Type*, ptrdiff_t> super;
+
+ ItTy OpIt;
+ const Type *CurTy;
+ generic_gep_type_iterator() {}
+ public:
+
+ static generic_gep_type_iterator begin(const Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = 0;
+ I.OpIt = It;
+ return I;
+ }
+
+ bool operator==(const generic_gep_type_iterator& x) const {
+ return OpIt == x.OpIt;
+ }
+ bool operator!=(const generic_gep_type_iterator& x) const {
+ return !operator==(x);
+ }
+
+ const Type *operator*() const {
+ return CurTy;
+ }
+
+ const Type *getIndexedType() const {
+ const CompositeType *CT = cast<CompositeType>(CurTy);
+ return CT->getTypeAtIndex(getOperand());
+ }
+
+ // This is a non-standard operator->. It allows you to call methods on the
+ // current type directly.
+ const Type *operator->() const { return operator*(); }
+
+ Value *getOperand() const { return *OpIt; }
+
+ generic_gep_type_iterator& operator++() { // Preincrement
+ if (const CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ CurTy = CT->getTypeAtIndex(getOperand());
+ } else {
+ CurTy = 0;
+ }
+ ++OpIt;
+ return *this;
+ }
+
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+ typedef generic_gep_type_iterator<> gep_type_iterator;
+
+ inline gep_type_iterator gep_type_begin(const User *GEP) {
+ return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
+ GEP->op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User *GEP) {
+ return gep_type_iterator::end(GEP->op_end());
+ }
+ inline gep_type_iterator gep_type_begin(const User &GEP) {
+ return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
+ GEP.op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User &GEP) {
+ return gep_type_iterator::end(GEP.op_end());
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_begin(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::begin(Op0, I);
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_end(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::end(E);
+ }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
new file mode 100644
index 000000000000..ca28aafa7898
--- /dev/null
+++ b/include/llvm/Support/GraphWriter.h
@@ -0,0 +1,323 @@
+//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple interface that can be used to print out generic
+// LLVM graphs to ".dot" files. "dot" is a tool that is part of the AT&T
+// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
+// be used to turn the files output by this interface into a variety of
+// different graphics formats.
+//
+// Graphs do not need to implement any interface past what is already required
+// by the GraphTraits template, but they can choose to implement specializations
+// of the DOTGraphTraits template if they want to customize the graphs output in
+// any way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GRAPHWRITER_H
+#define LLVM_SUPPORT_GRAPHWRITER_H
+
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/System/Path.h"
+#include <fstream>
+#include <vector>
+
+namespace llvm {
+
+namespace DOT { // Private functions...
+ inline std::string EscapeString(const std::string &Label) {
+ std::string Str(Label);
+ for (unsigned i = 0; i != Str.length(); ++i)
+ switch (Str[i]) {
+ case '\n':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i;
+ Str[i] = 'n';
+ break;
+ case '\t':
+ Str.insert(Str.begin()+i, ' '); // Convert to two spaces
+ ++i;
+ Str[i] = ' ';
+ break;
+ case '\\':
+ if (i+1 != Str.length())
+ switch (Str[i+1]) {
+ case 'l': continue; // don't disturb \l
+ case '|': case '{': case '}':
+ Str.erase(Str.begin()+i); continue;
+ default: break;
+ }
+ case '{': case '}':
+ case '<': case '>':
+ case '|': case '"':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i; // don't infinite loop
+ break;
+ }
+ return Str;
+ }
+}
+
+void DisplayGraph(const sys::Path& Filename);
+
+template<typename GraphType>
+class GraphWriter {
+ std::ostream &O;
+ const GraphType &G;
+
+ typedef DOTGraphTraits<GraphType> DOTTraits;
+ typedef GraphTraits<GraphType> GTraits;
+ typedef typename GTraits::NodeType NodeType;
+ typedef typename GTraits::nodes_iterator node_iterator;
+ typedef typename GTraits::ChildIteratorType child_iterator;
+public:
+ GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {}
+
+ void writeHeader(const std::string &Name) {
+ std::string GraphName = DOTTraits::getGraphName(G);
+
+ if (!Name.empty())
+ O << "digraph \"" << DOT::EscapeString(Name) << "\" {\n";
+ else if (!GraphName.empty())
+ O << "digraph \"" << DOT::EscapeString(GraphName) << "\" {\n";
+ else
+ O << "digraph unnamed {\n";
+
+ if (DOTTraits::renderGraphFromBottomUp())
+ O << "\trankdir=\"BT\";\n";
+
+ if (!Name.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(Name) << "\";\n";
+ else if (!GraphName.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
+ O << DOTTraits::getGraphProperties(G);
+ O << "\n";
+ }
+
+ void writeFooter() {
+ // Finish off the graph
+ O << "}\n";
+ }
+
+ void writeNodes() {
+ // Loop over the graph, printing it out...
+ for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
+ I != E; ++I)
+ writeNode(*I);
+ }
+
+ void writeNode(NodeType& Node) {
+ writeNode(&Node);
+ }
+
+ void writeNode(NodeType *const *Node) {
+ writeNode(*Node);
+ }
+
+ void writeNode(NodeType *Node) {
+ std::string NodeAttributes = DOTTraits::getNodeAttributes(Node, G);
+
+ O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,";
+ if (!NodeAttributes.empty()) O << NodeAttributes << ",";
+ O << "label=\"{";
+
+ if (!DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ // Print out the fields of the current node...
+ child_iterator EI = GTraits::child_begin(Node);
+ child_iterator EE = GTraits::child_end(Node);
+ if (EI != EE) {
+ if (!DOTTraits::renderGraphFromBottomUp()) O << "|";
+ O << "{";
+
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
+ if (i) O << "|";
+ O << "<s" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
+ }
+
+ if (EI != EE)
+ O << "|<s64>truncated...";
+ O << "}";
+ if (DOTTraits::renderGraphFromBottomUp()) O << "|";
+ }
+
+ if (DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ if (DOTTraits::hasEdgeDestLabels()) {
+ O << "|{";
+
+ unsigned i = 0, e = DOTTraits::numEdgeDestLabels(Node);
+ for (; i != e && i != 64; ++i) {
+ if (i) O << "|";
+ O << "<d" << i << ">" << DOTTraits::getEdgeDestLabel(Node, i);
+ }
+
+ if (i != e)
+ O << "|<d64>truncated...";
+ O << "}";
+ }
+
+ O << "}\"];\n"; // Finish printing the "node" line
+
+ // Output all of the edges now
+ EI = GTraits::child_begin(Node);
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
+ writeEdge(Node, i, EI);
+ for (; EI != EE; ++EI)
+ writeEdge(Node, 64, EI);
+ }
+
+ void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
+ if (NodeType *TargetNode = *EI) {
+ int DestPort = -1;
+ if (DOTTraits::edgeTargetsEdgeSource(Node, EI)) {
+ child_iterator TargetIt = DOTTraits::getEdgeTarget(Node, EI);
+
+ // Figure out which edge this targets...
+ unsigned Offset =
+ (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
+ DestPort = static_cast<int>(Offset);
+ }
+
+ emitEdge(static_cast<const void*>(Node), edgeidx,
+ static_cast<const void*>(TargetNode), DestPort,
+ DOTTraits::getEdgeAttributes(Node, EI));
+ }
+ }
+
+ /// emitSimpleNode - Outputs a simple (non-record) node
+ void emitSimpleNode(const void *ID, const std::string &Attr,
+ const std::string &Label, unsigned NumEdgeSources = 0,
+ const std::vector<std::string> *EdgeSourceLabels = 0) {
+ O << "\tNode" << ID << "[ ";
+ if (!Attr.empty())
+ O << Attr << ",";
+ O << " label =\"";
+ if (NumEdgeSources) O << "{";
+ O << DOT::EscapeString(Label);
+ if (NumEdgeSources) {
+ O << "|{";
+
+ for (unsigned i = 0; i != NumEdgeSources; ++i) {
+ if (i) O << "|";
+ O << "<g" << i << ">";
+ if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i];
+ }
+ O << "}}";
+ }
+ O << "\"];\n";
+ }
+
+ /// emitEdge - Output an edge from a simple node into the graph...
+ void emitEdge(const void *SrcNodeID, int SrcNodePort,
+ const void *DestNodeID, int DestNodePort,
+ const std::string &Attrs) {
+ if (SrcNodePort > 64) return; // Eminating from truncated part?
+ if (DestNodePort > 64) DestNodePort = 64; // Targetting the truncated part?
+
+ O << "\tNode" << SrcNodeID;
+ if (SrcNodePort >= 0)
+ O << ":s" << SrcNodePort;
+ O << " -> Node" << DestNodeID;
+ if (DestNodePort >= 0)
+ O << ":d" << DestNodePort;
+
+ if (!Attrs.empty())
+ O << "[" << Attrs << "]";
+ O << ";\n";
+ }
+};
+
+template<typename GraphType>
+std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
+ const std::string &Name = "",
+ const std::string &Title = "") {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G);
+
+ // Output the header for the graph...
+ W.writeHeader(Title);
+
+ // Emit all of the nodes in the graph...
+ W.writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, W);
+
+ // Output the end of the graph
+ W.writeFooter();
+ return O;
+}
+
+template<typename GraphType>
+sys::Path WriteGraph(const GraphType &G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ std::string ErrMsg;
+ sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (Filename.isEmpty()) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return Filename;
+ }
+ Filename.appendComponent(Name + ".dot");
+ if (Filename.makeUnique(true,&ErrMsg)) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return sys::Path();
+ }
+
+ cerr << "Writing '" << Filename << "'... ";
+
+ std::ofstream O(Filename.c_str());
+
+ if (O.good()) {
+ WriteGraph(O, G, Name, Title);
+ cerr << " done. \n";
+
+ O.close();
+ } else {
+ cerr << "error opening file for writing!\n";
+ Filename.clear();
+ }
+
+ return Filename;
+}
+
+/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
+/// then cleanup. For use from the debugger.
+///
+template<typename GraphType>
+void ViewGraph(const GraphType& G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ sys::Path Filename = WriteGraph(G, Name, Title);
+
+ if (Filename.isEmpty()) {
+ return;
+ }
+
+ DisplayGraph(Filename);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
new file mode 100644
index 000000000000..9ef14af51d9e
--- /dev/null
+++ b/include/llvm/Support/IRBuilder.h
@@ -0,0 +1,704 @@
+//===---- llvm/Support/IRBuilder.h - Builder for LLVM Instrs ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IRBuilder class, which is used as a convenient way
+// to create LLVM instructions with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_IRBUILDER_H
+#define LLVM_SUPPORT_IRBUILDER_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Function.h"
+#include "llvm/Support/ConstantFolder.h"
+
+namespace llvm {
+
+/// IRBuilder - This provides a uniform API for creating instructions and
+/// inserting them into a basic block: either at the end of a BasicBlock, or
+/// at a specific iterator location in a block.
+///
+/// Note that the builder does not expose the full generality of LLVM
+/// instructions. For example, it cannot be used to create instructions with
+/// arbitrary names (specifically, names with nul characters in them) - It only
+/// supports nul-terminated C strings. For fully generic names, use
+/// I->setName(). For access to extra instruction properties, use the mutators
+/// (e.g. setVolatile) on the instructions after they have been created.
+/// The first template argument handles whether or not to preserve names in the
+/// final instruction output. This defaults to on. The second template argument
+/// specifies a class to use for creating constants. This defaults to creating
+/// minimally folded constants.
+template <bool preserveNames=true, typename T = ConstantFolder> class IRBuilder{
+ BasicBlock *BB;
+ BasicBlock::iterator InsertPt;
+ T Folder;
+public:
+ IRBuilder(const T& F = T()) : Folder(F) { ClearInsertionPoint(); }
+ explicit IRBuilder(BasicBlock *TheBB, const T& F = T())
+ : Folder(F) { SetInsertPoint(TheBB); }
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F = T())
+ : Folder(F) { SetInsertPoint(TheBB, IP); }
+
+ /// getFolder - Get the constant folder being used.
+ const T& getFolder() { return Folder; }
+
+ /// isNamePreserving - Return true if this builder is configured to actually
+ /// add the requested names to IR created through it.
+ bool isNamePreserving() const { return preserveNames; }
+
+ //===--------------------------------------------------------------------===//
+ // Builder configuration methods
+ //===--------------------------------------------------------------------===//
+
+ /// ClearInsertionPoint - Clear the insertion point: created instructions will
+ /// not be inserted into a block.
+ void ClearInsertionPoint() {
+ BB = 0;
+ }
+
+ BasicBlock *GetInsertBlock() const { return BB; }
+
+ BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// appended to the end of the specified block.
+ void SetInsertPoint(BasicBlock *TheBB) {
+ BB = TheBB;
+ InsertPt = BB->end();
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// inserted at the specified point.
+ void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ BB = TheBB;
+ InsertPt = IP;
+ }
+
+ /// Insert - Insert and return the specified instruction.
+ template<typename InstTy>
+ InstTy *Insert(InstTy *I, const char *Name = "") const {
+ InsertHelper(I, Name);
+ return I;
+ }
+
+ /// InsertHelper - Insert the specified instruction at the specified insertion
+ /// point. This is split out of Insert so that it isn't duplicated for every
+ /// template instantiation.
+ void InsertHelper(Instruction *I, const char *Name) const {
+ if (BB) BB->getInstList().insert(InsertPt, I);
+ if (preserveNames && Name[0])
+ I->setName(Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Terminators
+ //===--------------------------------------------------------------------===//
+
+ /// CreateRetVoid - Create a 'ret void' instruction.
+ ReturnInst *CreateRetVoid() {
+ return Insert(ReturnInst::Create());
+ }
+
+ /// @verbatim
+ /// CreateRet - Create a 'ret <val>' instruction.
+ /// @endverbatim
+ ReturnInst *CreateRet(Value *V) {
+ return Insert(ReturnInst::Create(V));
+ }
+
+ /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
+ /// with one Value from the retVals array each, that build a aggregate
+ /// return value one value at a time, and a ret instruction to return
+ /// the resulting aggregate value. This is a convenience function for
+ /// code that uses aggregate return values as a vehicle for having
+ /// multiple return values.
+ ///
+ ReturnInst *CreateAggregateRet(Value * const* retVals, unsigned N) {
+ const Type *RetType = BB->getParent()->getReturnType();
+ Value *V = UndefValue::get(RetType);
+ for (unsigned i = 0; i != N; ++i)
+ V = CreateInsertValue(V, retVals[i], i, "mrv");
+ return Insert(ReturnInst::Create(V));
+ }
+
+ /// CreateBr - Create an unconditional 'br label X' instruction.
+ BranchInst *CreateBr(BasicBlock *Dest) {
+ return Insert(BranchInst::Create(Dest));
+ }
+
+ /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
+ /// instruction.
+ BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
+ return Insert(BranchInst::Create(True, False, Cond));
+ }
+
+ /// CreateSwitch - Create a switch instruction with the specified value,
+ /// default dest, and with a hint for the number of cases that will be added
+ /// (for efficient allocation).
+ SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
+ return Insert(SwitchInst::Create(V, Dest, NumCases));
+ }
+
+ /// CreateInvoke - Create an invoke instruction.
+ template<typename InputIterator>
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, InputIterator ArgBegin,
+ InputIterator ArgEnd, const char *Name = "") {
+ return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
+ ArgBegin, ArgEnd), Name);
+ }
+
+ UnwindInst *CreateUnwind() {
+ return Insert(new UnwindInst());
+ }
+
+ UnreachableInst *CreateUnreachable() {
+ return Insert(new UnreachableInst());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateAdd(LC, RC);
+ return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name);
+ }
+ Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateSub(LC, RC);
+ return Insert(BinaryOperator::CreateSub(LHS, RHS), Name);
+ }
+ Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateMul(LC, RC);
+ return Insert(BinaryOperator::CreateMul(LHS, RHS), Name);
+ }
+ Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateUDiv(LC, RC);
+ return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ }
+ Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateSDiv(LC, RC);
+ return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+ }
+ Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateFDiv(LC, RC);
+ return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name);
+ }
+ Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateURem(LC, RC);
+ return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
+ }
+ Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateSRem(LC, RC);
+ return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
+ }
+ Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateFRem(LC, RC);
+ return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
+ }
+ Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateShl(LC, RC);
+ return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
+ }
+ Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateLShr(LC, RC);
+ return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ }
+ Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateAShr(LC, RC);
+ return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ }
+ Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateAnd(LC, RC);
+ return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
+ }
+ Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateOr(LC, RC);
+ return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
+ }
+ Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateXor(LC, RC);
+ return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
+ }
+
+ Value *CreateBinOp(Instruction::BinaryOps Opc,
+ Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateBinOp(Opc, LC, RC);
+ return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+ }
+
+ Value *CreateNeg(Value *V, const char *Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateNeg(VC);
+ return Insert(BinaryOperator::CreateNeg(V), Name);
+ }
+ Value *CreateNot(Value *V, const char *Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateNot(VC);
+ return Insert(BinaryOperator::CreateNot(V), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new MallocInst(Ty, ArraySize), Name);
+ }
+ AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new AllocaInst(Ty, ArraySize), Name);
+ }
+ FreeInst *CreateFree(Value *Ptr) {
+ return Insert(new FreeInst(Ptr));
+ }
+ LoadInst *CreateLoad(Value *Ptr, const char *Name = "") {
+ return Insert(new LoadInst(Ptr), Name);
+ }
+ LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = "") {
+ return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
+ }
+ StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
+ return Insert(new StoreInst(Val, Ptr, isVolatile));
+ }
+ template<typename InputIterator>
+ Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+ const char *Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ InputIterator i;
+ for (i = IdxBegin; i < IdxEnd; ++i) {
+ if (!dyn_cast<Constant>(*i))
+ break;
+ }
+ if (i == IdxEnd)
+ return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
+ }
+ return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name);
+ }
+ Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Folder.CreateGetElementPtr(PC, &IC, 1);
+ return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ }
+ Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") {
+ Value *Idx = ConstantInt::get(Type::Int32Ty, Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
+ }
+ Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const char *Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::Int32Ty, Idx0),
+ ConstantInt::get(Type::Int32Ty, Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
+ }
+ Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") {
+ Value *Idx = ConstantInt::get(Type::Int64Ty, Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
+ }
+ Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const char *Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::Int64Ty, Idx0),
+ ConstantInt::get(Type::Int64Ty, Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
+ }
+ Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
+ return CreateConstGEP2_32(Ptr, 0, Idx, Name);
+ }
+ Value *CreateGlobalString(const char *Str = "", const char *Name = "") {
+ Constant *StrConstant = ConstantArray::get(Str, true);
+ GlobalVariable *gv = new GlobalVariable(StrConstant->getType(),
+ true,
+ GlobalValue::InternalLinkage,
+ StrConstant,
+ "",
+ BB->getParent()->getParent(),
+ false);
+ gv->setName(Name);
+ return gv;
+ }
+ Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") {
+ Value *gv = CreateGlobalString(Str, Name);
+ Value *zero = ConstantInt::get(Type::Int32Ty, 0);
+ Value *Args[] = { zero, zero };
+ return CreateGEP(gv, Args, Args+2, Name);
+ }
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
+ return CreateCast(Instruction::Trunc, V, DestTy, Name);
+ }
+ Value *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return CreateCast(Instruction::ZExt, V, DestTy, Name);
+ }
+ Value *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return CreateCast(Instruction::SExt, V, DestTy, Name);
+ }
+ Value *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){
+ return CreateCast(Instruction::FPToUI, V, DestTy, Name);
+ }
+ Value *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){
+ return CreateCast(Instruction::FPToSI, V, DestTy, Name);
+ }
+ Value *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return CreateCast(Instruction::UIToFP, V, DestTy, Name);
+ }
+ Value *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return CreateCast(Instruction::SIToFP, V, DestTy, Name);
+ }
+ Value *CreateFPTrunc(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
+ }
+ Value *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return CreateCast(Instruction::FPExt, V, DestTy, Name);
+ }
+ Value *CreatePtrToInt(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
+ }
+ Value *CreateIntToPtr(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
+ }
+ Value *CreateBitCast(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return CreateCast(Instruction::BitCast, V, DestTy, Name);
+ }
+
+ Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
+ const char *Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateCast(Op, VC, DestTy);
+ return Insert(CastInst::Create(Op, V, DestTy), Name);
+ }
+ Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
+ const char *Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateIntCast(VC, DestTy, isSigned);
+ return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
+ }
+ Value *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
+ }
+
+ Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
+ }
+
+ Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateICmp(P, LC, RC);
+ return Insert(new ICmpInst(P, LHS, RHS), Name);
+ }
+ Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateFCmp(P, LC, RC);
+ return Insert(new FCmpInst(P, LHS, RHS), Name);
+ }
+
+ Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateVICmp(P, LC, RC);
+ return Insert(new VICmpInst(P, LHS, RHS), Name);
+ }
+ Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateVFCmp(P, LC, RC);
+ return Insert(new VFCmpInst(P, LHS, RHS), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ PHINode *CreatePHI(const Type *Ty, const char *Name = "") {
+ return Insert(PHINode::Create(Ty), Name);
+ }
+
+ CallInst *CreateCall(Value *Callee, const char *Name = "") {
+ return Insert(CallInst::Create(Callee), Name);
+ }
+ CallInst *CreateCall(Value *Callee, Value *Arg, const char *Name = "") {
+ return Insert(CallInst::Create(Callee, Arg), Name);
+ }
+ CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
+ const char *Name = "") {
+ Value *Args[] = { Arg1, Arg2 };
+ return Insert(CallInst::Create(Callee, Args, Args+2), Name);
+ }
+ CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+ const char *Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3 };
+ return Insert(CallInst::Create(Callee, Args, Args+3), Name);
+ }
+ CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+ Value *Arg4, const char *Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
+ return Insert(CallInst::Create(Callee, Args, Args+4), Name);
+ }
+
+ template<typename InputIterator>
+ CallInst *CreateCall(Value *Callee, InputIterator ArgBegin,
+ InputIterator ArgEnd, const char *Name = "") {
+ return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name);
+ }
+
+ Value *CreateSelect(Value *C, Value *True, Value *False,
+ const char *Name = "") {
+ if (Constant *CC = dyn_cast<Constant>(C))
+ if (Constant *TC = dyn_cast<Constant>(True))
+ if (Constant *FC = dyn_cast<Constant>(False))
+ return Folder.CreateSelect(CC, TC, FC);
+ return Insert(SelectInst::Create(C, True, False), Name);
+ }
+
+ VAArgInst *CreateVAArg(Value *List, const Type *Ty, const char *Name = "") {
+ return Insert(new VAArgInst(List, Ty), Name);
+ }
+
+ Value *CreateExtractElement(Value *Vec, Value *Idx,
+ const char *Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(Vec))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Folder.CreateExtractElement(VC, IC);
+ return Insert(new ExtractElementInst(Vec, Idx), Name);
+ }
+
+ Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+ const char *Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(Vec))
+ if (Constant *NC = dyn_cast<Constant>(NewElt))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Folder.CreateInsertElement(VC, NC, IC);
+ return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
+ }
+
+ Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+ const char *Name = "") {
+ if (Constant *V1C = dyn_cast<Constant>(V1))
+ if (Constant *V2C = dyn_cast<Constant>(V2))
+ if (Constant *MC = dyn_cast<Constant>(Mask))
+ return Folder.CreateShuffleVector(V1C, V2C, MC);
+ return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
+ }
+
+ Value *CreateExtractValue(Value *Agg, unsigned Idx,
+ const char *Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ return Folder.CreateExtractValue(AggC, &Idx, 1);
+ return Insert(ExtractValueInst::Create(Agg, Idx), Name);
+ }
+
+ template<typename InputIterator>
+ Value *CreateExtractValue(Value *Agg,
+ InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ const char *Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ return Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd - IdxBegin);
+ return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
+ }
+
+ Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx,
+ const char *Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ if (Constant *ValC = dyn_cast<Constant>(Val))
+ return Folder.CreateInsertValue(AggC, ValC, &Idx, 1);
+ return Insert(InsertValueInst::Create(Agg, Val, Idx), Name);
+ }
+
+ template<typename InputIterator>
+ Value *CreateInsertValue(Value *Agg, Value *Val,
+ InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ const char *Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ if (Constant *ValC = dyn_cast<Constant>(Val))
+ return Folder.CreateInsertValue(AggC, ValC,
+ IdxBegin, IdxEnd - IdxBegin);
+ return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Utility creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
+ Value *CreateIsNull(Value *Arg, const char *Name = "") {
+ return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
+ Name);
+ }
+
+ /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null.
+ Value *CreateIsNotNull(Value *Arg, const char *Name = "") {
+ return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
+ Name);
+ }
+
+ /// CreatePtrDiff - Return the i64 difference between two pointer values,
+ /// dividing out the size of the pointed-to objects. This is intended to
+ /// implement C-style pointer subtraction.
+ Value *CreatePtrDiff(Value *LHS, Value *RHS, const char *Name = "") {
+ assert(LHS->getType() == RHS->getType() &&
+ "Pointer subtraction operand types must match!");
+ const PointerType *ArgType = cast<PointerType>(LHS->getType());
+ Value *LHS_int = CreatePtrToInt(LHS, Type::Int64Ty);
+ Value *RHS_int = CreatePtrToInt(RHS, Type::Int64Ty);
+ Value *Difference = CreateSub(LHS_int, RHS_int);
+ return CreateSDiv(Difference,
+ ConstantExpr::getSizeOf(ArgType->getElementType()),
+ Name);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h
new file mode 100644
index 000000000000..7d3f8835098e
--- /dev/null
+++ b/include/llvm/Support/InstIterator.h
@@ -0,0 +1,147 @@
+//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions of two iterators for iterating over the
+// instructions in a function. This is effectively a wrapper around a two level
+// iterator that can probably be genericized later.
+//
+// Note that this iterator gets invalidated any time that basic blocks or
+// instructions are moved around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INSTITERATOR_H
+#define LLVM_SUPPORT_INSTITERATOR_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+
+namespace llvm {
+
+// This class implements inst_begin() & inst_end() for
+// inst_iterator and const_inst_iterator's.
+//
+template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
+class InstIterator {
+ typedef _BB_t BBty;
+ typedef _BB_i_t BBIty;
+ typedef _BI_t BIty;
+ typedef _II_t IIty;
+ _BB_t *BBs; // BasicBlocksType
+ _BB_i_t BB; // BasicBlocksType::iterator
+ _BI_t BI; // BasicBlock::iterator
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef IIty value_type;
+ typedef signed difference_type;
+ typedef IIty* pointer;
+ typedef IIty& reference;
+
+ // Default constructor
+ InstIterator() {}
+
+ // Copy constructor...
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(const InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<class M> InstIterator(M &m)
+ : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
+ if (BB != BBs->end()) {
+ BI = BB->begin();
+ advanceToNextBB();
+ }
+ }
+
+ template<class M> InstIterator(M &m, bool)
+ : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
+ }
+
+ // Accessors to get at the underlying iterators...
+ inline BBIty &getBasicBlockIterator() { return BB; }
+ inline BIty &getInstructionIterator() { return BI; }
+
+ inline reference operator*() const { return *BI; }
+ inline pointer operator->() const { return &operator*(); }
+
+ inline bool operator==(const InstIterator &y) const {
+ return BB == y.BB && (BB == BBs->end() || BI == y.BI);
+ }
+ inline bool operator!=(const InstIterator& y) const {
+ return !operator==(y);
+ }
+
+ InstIterator& operator++() {
+ ++BI;
+ advanceToNextBB();
+ return *this;
+ }
+ inline InstIterator operator++(int) {
+ InstIterator tmp = *this; ++*this; return tmp;
+ }
+
+ InstIterator& operator--() {
+ while (BB == BBs->end() || BI == BB->begin()) {
+ --BB;
+ BI = BB->end();
+ }
+ --BI;
+ return *this;
+ }
+ inline InstIterator operator--(int) {
+ InstIterator tmp = *this; --*this; return tmp;
+ }
+
+ inline bool atEnd() const { return BB == BBs->end(); }
+
+private:
+ inline void advanceToNextBB() {
+ // The only way that the II could be broken is if it is now pointing to
+ // the end() of the current BasicBlock and there are successor BBs.
+ while (BI == BB->end()) {
+ ++BB;
+ if (BB == BBs->end()) break;
+ BI = BB->begin();
+ }
+ }
+};
+
+
+typedef InstIterator<iplist<BasicBlock>,
+ Function::iterator, BasicBlock::iterator,
+ Instruction> inst_iterator;
+typedef InstIterator<const iplist<BasicBlock>,
+ Function::const_iterator,
+ BasicBlock::const_iterator,
+ const Instruction> const_inst_iterator;
+
+inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
+inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
+inline const_inst_iterator inst_begin(const Function *F) {
+ return const_inst_iterator(*F);
+}
+inline const_inst_iterator inst_end(const Function *F) {
+ return const_inst_iterator(*F, true);
+}
+inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
+inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
+inline const_inst_iterator inst_begin(const Function &F) {
+ return const_inst_iterator(F);
+}
+inline const_inst_iterator inst_end(const Function &F) {
+ return const_inst_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
new file mode 100644
index 000000000000..597cc9d90542
--- /dev/null
+++ b/include/llvm/Support/InstVisitor.h
@@ -0,0 +1,221 @@
+//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_INSTVISITOR_H
+#define LLVM_SUPPORT_INSTVISITOR_H
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+
+namespace llvm {
+
+// We operate on opaque instruction classes, so forward declare all instruction
+// types now...
+//
+#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
+#include "llvm/Instruction.def"
+
+#define DELEGATE(CLASS_TO_VISIT) \
+ return static_cast<SubClass*>(this)-> \
+ visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
+
+
+/// @brief Base class for instruction visitors
+///
+/// Instruction visitors are used when you want to perform different action for
+/// different kinds of instruction without without having to use lots of casts
+/// and a big switch statement (in your code that is).
+///
+/// To define your own visitor, inherit from this class, specifying your
+/// new type for the 'SubClass' template parameter, and "override" visitXXX
+/// functions in your class. I say "overriding" because this class is defined
+/// in terms of statically resolved overloading, not virtual functions.
+///
+/// For example, here is a visitor that counts the number of malloc
+/// instructions processed:
+///
+/// /// Declare the class. Note that we derive from InstVisitor instantiated
+/// /// with _our new subclasses_ type.
+/// ///
+/// struct CountMallocVisitor : public InstVisitor<CountMallocVisitor> {
+/// unsigned Count;
+/// CountMallocVisitor() : Count(0) {}
+///
+/// void visitMallocInst(MallocInst &MI) { ++Count; }
+/// };
+///
+/// And this class would be used like this:
+/// CountMallocVistor CMV;
+/// CMV.visit(function);
+/// NumMallocs = CMV.Count;
+///
+/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
+/// Function, and Module, which recursively process all conained instructions.
+///
+/// Note that if you don't implement visitXXX for some instruction type,
+/// the visitXXX method for instruction superclass will be invoked. So
+/// if instructions are added in the future, they will be automatically
+/// supported, if you handle on of their superclasses.
+///
+/// The optional second template argument specifies the type that instruction
+/// visitation functions should return. If you specify this, you *MUST* provide
+/// an implementation of visitInstruction though!.
+///
+/// Note that this class is specifically designed as a template to avoid
+/// virtual function call overhead. Defining and using an InstVisitor is just
+/// as efficient as having your own switch statement over the instruction
+/// opcode.
+template<typename SubClass, typename RetTy=void>
+class InstVisitor {
+ //===--------------------------------------------------------------------===//
+ // Interface code - This is the public interface of the InstVisitor that you
+ // use to visit instructions...
+ //
+
+public:
+ // Generic visit method - Allow visitation to all instructions in a range
+ template<class Iterator>
+ void visit(Iterator Start, Iterator End) {
+ while (Start != End)
+ static_cast<SubClass*>(this)->visit(*Start++);
+ }
+
+ // Define visitors for functions and basic blocks...
+ //
+ void visit(Module &M) {
+ static_cast<SubClass*>(this)->visitModule(M);
+ visit(M.begin(), M.end());
+ }
+ void visit(Function &F) {
+ static_cast<SubClass*>(this)->visitFunction(F);
+ visit(F.begin(), F.end());
+ }
+ void visit(BasicBlock &BB) {
+ static_cast<SubClass*>(this)->visitBasicBlock(BB);
+ visit(BB.begin(), BB.end());
+ }
+
+ // Forwarding functions so that the user can visit with pointers AND refs.
+ void visit(Module *M) { visit(*M); }
+ void visit(Function *F) { visit(*F); }
+ void visit(BasicBlock *BB) { visit(*BB); }
+ RetTy visit(Instruction *I) { return visit(*I); }
+
+ // visit - Finally, code to visit an instruction...
+ //
+ RetTy visit(Instruction &I) {
+ switch (I.getOpcode()) {
+ default: assert(0 && "Unknown instruction type encountered!");
+ abort();
+ // Build the switch statement using the Instruction.def file...
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: return \
+ static_cast<SubClass*>(this)-> \
+ visit##OPCODE(static_cast<CLASS&>(I));
+#include "llvm/Instruction.def"
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Visitation functions... these functions provide default fallbacks in case
+ // the user does not specify what to do for a particular instruction type.
+ // The default behavior is to generalize the instruction type to its subtype
+ // and try visiting the subtype. All of this should be inlined perfectly,
+ // because there are no virtual functions to get in the way.
+ //
+
+ // When visiting a module, function or basic block directly, these methods get
+ // called to indicate when transitioning into a new unit.
+ //
+ void visitModule (Module &M) {}
+ void visitFunction (Function &F) {}
+ void visitBasicBlock(BasicBlock &BB) {}
+
+ // Define instruction specific visitor functions that can be overridden to
+ // handle SPECIFIC instructions. These functions automatically define
+ // visitMul to proxy to visitBinaryOperator for instance in case the user does
+ // not need this generality.
+ //
+ // The one problem case we have to handle here though is that the PHINode
+ // class and opcode name are the exact same. Because of this, we cannot
+ // define visitPHINode (the inst version) to forward to visitPHINode (the
+ // generic version) without multiply defined symbols and recursion. To handle
+ // this, we do not autoexpand "Other" instructions, we do it manually.
+ //
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+#include "llvm/Instruction.def"
+
+ // Specific Instruction type classes... note that all of the casts are
+ // necessary because we use the instruction classes as opaque types...
+ //
+ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitVICmpInst(VICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitVFCmpInst(VFCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
+ RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); }
+ RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
+ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); }
+ RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); }
+ RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); }
+ RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); }
+ RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); }
+ RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); }
+ RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); }
+ RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
+ RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); }
+ RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
+ RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
+ RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);}
+ RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
+
+ // Next level propagators... if the user does not overload a specific
+ // instruction type, they can overload one of these to get the whole class
+ // of instructions...
+ //
+ RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
+ RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
+ RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
+ RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
+
+ // If the user wants a 'default' case, they can choose to override this
+ // function. If this function is not overloaded in the users subclass, then
+ // this instruction just gets ignored.
+ //
+ // Note that you MUST override this function if your return type is not void.
+ //
+ void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+};
+
+#undef DELEGATE
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h
new file mode 100644
index 000000000000..8d74ac663b11
--- /dev/null
+++ b/include/llvm/Support/LeakDetector.h
@@ -0,0 +1,91 @@
+//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a class that can be used to provide very simple memory leak
+// checks for an API. Basically LLVM uses this to make sure that Instructions,
+// for example, are deleted when they are supposed to be, and not leaked away.
+//
+// When compiling with NDEBUG (Release build), this class does nothing, thus
+// adding no checking overhead to release builds. Note that this class is
+// implemented in a very simple way, requiring completely manual manipulation
+// and checking for garbage, but this is intentional: users should not be using
+// this API, only other APIs should.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
+#define LLVM_SUPPORT_LEAKDETECTOR_H
+
+#include <string>
+
+namespace llvm {
+
+class Value;
+
+struct LeakDetector {
+ /// addGarbageObject - Add a pointer to the internal set of "garbage" object
+ /// pointers. This should be called when objects are created, or if they are
+ /// taken out of an owning collection.
+ ///
+ static void addGarbageObject(void *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// removeGarbageObject - Remove a pointer from our internal representation of
+ /// our "garbage" objects. This should be called when an object is added to
+ /// an "owning" collection.
+ ///
+ static void removeGarbageObject(void *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// checkForGarbage - Traverse the internal representation of garbage
+ /// pointers. If there are any pointers that have been add'ed, but not
+ /// remove'd, big obnoxious warnings about memory leaks are issued.
+ ///
+ /// The specified message will be printed indicating when the check was
+ /// performed.
+ ///
+ static void checkForGarbage(const std::string &Message) {
+#ifndef NDEBUG
+ checkForGarbageImpl(Message);
+#endif
+ }
+
+ /// Overload the normal methods to work better with Value*'s because they are
+ /// by far the most common in LLVM. This does not affect the actual
+ /// functioning of this class, it just makes the warning messages nicer.
+ ///
+ static void addGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+ static void removeGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+private:
+ // If we are debugging, the actual implementations will be called...
+ static void addGarbageObjectImpl(const Value *Object);
+ static void removeGarbageObjectImpl(const Value *Object);
+ static void addGarbageObjectImpl(void *Object);
+ static void removeGarbageObjectImpl(void *Object);
+ static void checkForGarbageImpl(const std::string &Message);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
new file mode 100644
index 000000000000..619cc2055250
--- /dev/null
+++ b/include/llvm/Support/ManagedStatic.h
@@ -0,0 +1,120 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+#include "llvm/System/Atomic.h"
+
+namespace llvm {
+
+/// object_creator - Helper method for ManagedStatic.
+template<class C>
+void* object_creator() {
+ return new C();
+}
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<class C>
+void object_deleter(void *Ptr) {
+ delete (C*)Ptr;
+}
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+ // This should only be used as a static variable, which guarantees that this
+ // will be zero initialized.
+ mutable void *Ptr;
+ mutable void (*DeleterFn)(void*);
+ mutable const ManagedStaticBase *Next;
+
+ void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
+public:
+ /// isConstructed - Return true if this object has not been created yet.
+ bool isConstructed() const { return Ptr != 0; }
+
+ void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+
+ // Accessors.
+ C &operator*() {
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
+ return *static_cast<C*>(Ptr);
+ }
+ C *operator->() {
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
+ return static_cast<C*>(Ptr);
+ }
+ const C &operator*() const {
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
+ return *static_cast<C*>(Ptr);
+ }
+ const C *operator->() const {
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
+ return static_cast<C*>(Ptr);
+ }
+};
+
+template<void (*CleanupFn)(void*)>
+class ManagedCleanup : public ManagedStaticBase {
+public:
+ void Register() { RegisterManagedStatic(0, CleanupFn); }
+};
+
+
+/// llvm_start_multithreaded - Allocate and initialize structures needed to
+/// make LLVM safe for multithreading. The return value indicates whether
+/// multithreaded initialization succeeded. LLVM will still be operational
+/// on "failed" return, but will not be safe to run multithreaded.
+bool llvm_start_multithreaded();
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown();
+
+
+/// llvm_shutdown_obj - This is a simple helper class that calls
+/// llvm_shutdown() when it is destroyed.
+struct llvm_shutdown_obj {
+ llvm_shutdown_obj() { }
+ explicit llvm_shutdown_obj(bool multithreaded) {
+ if (multithreaded) llvm_start_multithreaded();
+ }
+ ~llvm_shutdown_obj() { llvm_shutdown(); }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h
new file mode 100644
index 000000000000..8f672bdd6f65
--- /dev/null
+++ b/include/llvm/Support/Mangler.h
@@ -0,0 +1,112 @@
+//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANGLER_H
+#define LLVM_SUPPORT_MANGLER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <string>
+
+namespace llvm {
+class Type;
+class Module;
+class Value;
+class GlobalValue;
+
+class Mangler {
+ /// Prefix - This string is added to each symbol that is emitted, unless the
+ /// symbol is marked as not needing this prefix.
+ const char *Prefix;
+
+ /// PrivatePrefix - This string is emitted before each symbol with private
+ /// linkage.
+ const char *PrivatePrefix;
+
+ /// UseQuotes - If this is set, the target accepts global names in quotes,
+ /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping
+ /// the space character. By default, this is false.
+ bool UseQuotes;
+
+ /// PreserveAsmNames - If this is set, the asm escape character is not removed
+ /// from names with 'asm' specifiers.
+ bool PreserveAsmNames;
+
+ /// Memo - This is used to remember the name that we assign a value.
+ ///
+ DenseMap<const Value*, std::string> Memo;
+
+ /// Count - This simple counter is used to unique value names.
+ ///
+ unsigned Count;
+
+ /// TypeMap - If the client wants us to unique types, this keeps track of the
+ /// current assignments and TypeCounter keeps track of the next id to assign.
+ DenseMap<const Type*, unsigned> TypeMap;
+ unsigned TypeCounter;
+
+ /// AcceptableChars - This bitfield contains a one for each character that is
+ /// allowed to be part of an unmangled name.
+ unsigned AcceptableChars[256/32];
+public:
+
+ // Mangler ctor - if a prefix is specified, it will be prepended onto all
+ // symbols.
+ Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "");
+
+ /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted
+ /// strings for assembler labels.
+ void setUseQuotes(bool Val) { UseQuotes = Val; }
+
+ /// setPreserveAsmNames - If the mangler should not strip off the asm name
+ /// @verbatim identifier (\001), this should be set. @endverbatim
+ void setPreserveAsmNames(bool Val) { PreserveAsmNames = Val; }
+
+ /// Acceptable Characters - This allows the target to specify which characters
+ /// are acceptable to the assembler without being mangled. By default we
+ /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts.
+ void markCharAcceptable(unsigned char X) {
+ AcceptableChars[X/32] |= 1 << (X&31);
+ }
+ void markCharUnacceptable(unsigned char X) {
+ AcceptableChars[X/32] &= ~(1 << (X&31));
+ }
+ bool isCharAcceptable(unsigned char X) const {
+ return (AcceptableChars[X/32] & (1 << (X&31))) != 0;
+ }
+
+ /// getValueName - Returns the mangled name of V, an LLVM Value,
+ /// in the current module.
+ ///
+ std::string getValueName(const GlobalValue *V, const char *Suffix = "");
+ std::string getValueName(const Value *V);
+
+ /// makeNameProper - We don't want identifier names with ., space, or
+ /// - in them, so we mangle these characters into the strings "d_",
+ /// "s_", and "D_", respectively. This is a very simple mangling that
+ /// doesn't guarantee unique names for values. getValueName already
+ /// does this for you, so there's no point calling it on the result
+ /// from getValueName.
+ ///
+ std::string makeNameProper(const std::string &x, const char *Prefix = 0,
+ const char *PrivatePrefix = 0);
+
+private:
+ /// getTypeID - Return a unique ID for the specified LLVM type.
+ ///
+ unsigned getTypeID(const Type *Ty);
+};
+
+} // End llvm namespace
+
+#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
new file mode 100644
index 000000000000..85e19acd9ea7
--- /dev/null
+++ b/include/llvm/Support/MathExtras.h
@@ -0,0 +1,437 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MATHEXTRAS_H
+#define LLVM_SUPPORT_MATHEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+inline uint32_t Hi_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+inline uint32_t Lo_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value);
+}
+
+/// is?Type - these functions produce optimal testing for integer data types.
+inline bool isInt8 (int64_t Value) {
+ return static_cast<int8_t>(Value) == Value;
+}
+inline bool isUInt8 (int64_t Value) {
+ return static_cast<uint8_t>(Value) == Value;
+}
+inline bool isInt16 (int64_t Value) {
+ return static_cast<int16_t>(Value) == Value;
+}
+inline bool isUInt16(int64_t Value) {
+ return static_cast<uint16_t>(Value) == Value;
+}
+inline bool isInt32 (int64_t Value) {
+ return static_cast<int32_t>(Value) == Value;
+}
+inline bool isUInt32(int64_t Value) {
+ return static_cast<uint32_t>(Value) == Value;
+}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version). Ex. isMask_32(0x0000FFFFU) == true.
+inline bool isMask_32(uint32_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+inline bool isMask_64(uint64_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+inline bool isShiftedMask_32(uint32_t Value) {
+ return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+inline bool isShiftedMask_64(uint64_t Value) {
+ return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+inline bool isPowerOf2_32(uint32_t Value) {
+ return Value && !(Value & (Value - 1));
+}
+
+/// isPowerOf2_64 - This function returns true if the argument is a power of two
+/// > 0 (64 bit edition.)
+inline bool isPowerOf2_64(uint64_t Value) {
+ return Value && !(Value & (Value - int64_t(1L)));
+}
+
+/// ByteSwap_16 - This function returns a byte-swapped representation of the
+/// 16-bit argument, Value.
+inline uint16_t ByteSwap_16(uint16_t Value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(Value);
+#else
+ uint16_t Hi = Value << 8;
+ uint16_t Lo = Value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// ByteSwap_32 - This function returns a byte-swapped representation of the
+/// 32-bit argument, Value.
+inline uint32_t ByteSwap_32(uint32_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap32(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(Value);
+#else
+ uint32_t Byte0 = Value & 0x000000FF;
+ uint32_t Byte1 = Value & 0x0000FF00;
+ uint32_t Byte2 = Value & 0x00FF0000;
+ uint32_t Byte3 = Value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// ByteSwap_64 - This function returns a byte-swapped representation of the
+/// 64-bit argument, Value.
+inline uint64_t ByteSwap_64(uint64_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap64(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(Value);
+#else
+ uint64_t Hi = ByteSwap_32(uint32_t(Value));
+ uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+/// CountLeadingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the most significant bit to the first one
+/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountLeadingZeros_32(uint32_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clz(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 32;
+#endif
+ Count = __builtin_clz(Value);
+#else
+ if (!Value) return 32;
+ Count = 0;
+ // bisecton method for count leading zeros
+ for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
+ uint32_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountLeadingOnes_32 - this function performs the operation of
+/// counting the number of ones from the most significant bit to the first zero
+/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountLeadingOnes_32(uint32_t Value) {
+ return CountLeadingZeros_32(~Value);
+}
+
+/// CountLeadingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the most significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountLeadingZeros_64(uint64_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clzll(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 64;
+#endif
+ Count = __builtin_clzll(Value);
+#else
+ if (sizeof(long) == sizeof(int64_t)) {
+ if (!Value) return 64;
+ Count = 0;
+ // bisecton method for count leading zeros
+ for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) {
+ uint64_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+ } else {
+ // get hi portion
+ uint32_t Hi = Hi_32(Value);
+
+ // if some bits in hi portion
+ if (Hi) {
+ // leading zeros in hi portion plus all bits in lo portion
+ Count = CountLeadingZeros_32(Hi);
+ } else {
+ // get lo portion
+ uint32_t Lo = Lo_32(Value);
+ // same as 32 bit value
+ Count = CountLeadingZeros_32(Lo)+32;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountLeadingOnes_64 - This function performs the operation
+/// of counting the number of ones from the most significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountLeadingOnes_64(uint64_t Value) {
+ return CountLeadingZeros_64(~Value);
+}
+
+/// CountTrailingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the least significant bit to the first one
+/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountTrailingZeros_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctz(Value) : 32;
+#else
+ static const unsigned Mod37BitPosition[] = {
+ 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
+ 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
+ 5, 20, 8, 19, 18
+ };
+ return Mod37BitPosition[(-Value & Value) % 37];
+#endif
+}
+
+/// CountTrailingOnes_32 - this function performs the operation of
+/// counting the number of ones from the least significant bit to the first zero
+/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountTrailingOnes_32(uint32_t Value) {
+ return CountTrailingZeros_32(~Value);
+}
+
+/// CountTrailingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the least significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountTrailingZeros_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctzll(Value) : 64;
+#else
+ static const unsigned Mod67Position[] = {
+ 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
+ 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
+ 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
+ 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
+ 7, 48, 35, 6, 34, 33, 0
+ };
+ return Mod67Position[(-Value & Value) % 67];
+#endif
+}
+
+/// CountTrailingOnes_64 - This function performs the operation
+/// of counting the number of ones from the least significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountTrailingOnes_64(uint64_t Value) {
+ return CountTrailingZeros_64(~Value);
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcount(Value);
+#else
+ uint32_t v = Value - ((Value >> 1) & 0x55555555);
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcountll(Value);
+#else
+ uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+inline unsigned Log2_32(uint32_t Value) {
+ return 31 - CountLeadingZeros_32(Value);
+}
+
+/// Log2_64 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64(uint64_t Value) {
+ return 63 - CountLeadingZeros_64(Value);
+}
+
+/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 32 if the value is zero. (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+inline unsigned Log2_32_Ceil(uint32_t Value) {
+ return 32-CountLeadingZeros_32(Value-1);
+}
+
+/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 64 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64_Ceil(uint64_t Value) {
+ return 64-CountLeadingZeros_64(Value-1);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+ while (B) {
+ uint64_t T = B;
+ B = A % B;
+ A = T;
+ }
+ return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+inline double BitsToDouble(uint64_t Bits) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.L = Bits;
+ return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+inline float BitsToFloat(uint32_t Bits) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = Bits;
+ return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer. Note that copying doubles around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint64_t DoubleToBits(double Double) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.D = Double;
+ return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer. Note that copying floats around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint32_t FloatToBits(float Float) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = Float;
+ return T.I;
+}
+
+/// Platform-independent wrappers for the C99 isnan() function.
+int IsNAN(float f);
+int IsNAN(double d);
+
+/// Platform-independent wrappers for the C99 isinf() function.
+int IsInf(float f);
+int IsInf(double d);
+
+/// MinAlign - A and B are either alignments or offsets. Return the minimum
+/// alignment that may be assumed after adding the two together.
+static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
+ // The largest power of 2 that divides both A and B.
+ return (A | B) & -(A | B);
+}
+
+/// NextPowerOf2 - Returns the next power of two (in 64-bits)
+/// that is strictly greater than A. Returns zero on overflow.
+static inline uint64_t NextPowerOf2(uint64_t A) {
+ A |= (A >> 1);
+ A |= (A >> 2);
+ A |= (A >> 4);
+ A |= (A >> 8);
+ A |= (A >> 16);
+ A |= (A >> 32);
+ return A + 1;
+}
+
+/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
+/// greater than or equal to \arg Value and is a multiple of \arg
+/// Align. Align must be non-zero.
+///
+/// Examples:
+/// RoundUpToAlignment(5, 8) = 8
+/// RoundUpToAlignment(17, 8) = 24
+/// RoundUpToAlignment(~0LL, 8) = 0
+inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
+ return ((Value + Align - 1) / Align) * Align;
+}
+
+/// abs64 - absolute value of a 64-bit int. Not all environments support
+/// "abs" on whatever their name for the 64-bit int type is. The absolute
+/// value of the largest negative number is undefined, as with "abs".
+inline int64_t abs64(int64_t x) {
+ return (x < 0) ? -x : x;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
new file mode 100644
index 000000000000..58a217f6c79e
--- /dev/null
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -0,0 +1,109 @@
+//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
+#define LLVM_SUPPORT_MEMORYBUFFER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+/// MemoryBuffer - This interface provides simple read-only access to a block
+/// of memory, and provides simple methods for reading files and standard input
+/// into a memory buffer. In addition to basic access to the characters in the
+/// file, this interface guarantees you can read one character past the end of
+/// @verbatim the file, and that this character will read as '\0'. @endverbatim
+class MemoryBuffer {
+ const char *BufferStart; // Start of the buffer.
+ const char *BufferEnd; // End of the buffer.
+
+ /// MustDeleteBuffer - True if we allocated this buffer. If so, the
+ /// destructor must know the delete[] it.
+ bool MustDeleteBuffer;
+protected:
+ MemoryBuffer() : MustDeleteBuffer(false) {}
+ void init(const char *BufStart, const char *BufEnd);
+ void initCopyOf(const char *BufStart, const char *BufEnd);
+public:
+ virtual ~MemoryBuffer();
+
+ const char *getBufferStart() const { return BufferStart; }
+ const char *getBufferEnd() const { return BufferEnd; }
+ size_t getBufferSize() const { return BufferEnd-BufferStart; }
+
+ /// getBufferIdentifier - Return an identifier for this buffer, typically the
+ /// filename it was read from.
+ virtual const char *getBufferIdentifier() const {
+ return "Unknown buffer";
+ }
+
+ /// getFile - Open the specified file as a MemoryBuffer, returning a new
+ /// MemoryBuffer if successful, otherwise returning null. If FileSize is
+ /// specified, this means that the client knows that the file exists and that
+ /// it has the specified size.
+ static MemoryBuffer *getFile(const char *Filename,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1);
+
+ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
+ /// that EndPtr[0] must be a null byte and be accessible!
+ static MemoryBuffer *getMemBuffer(const char *StartPtr, const char *EndPtr,
+ const char *BufferName = "");
+
+ /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
+ /// copying the contents and taking ownership of it. This has no requirements
+ /// on EndPtr[0].
+ static MemoryBuffer *getMemBufferCopy(const char *StartPtr,const char *EndPtr,
+ const char *BufferName = "");
+
+ /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
+ /// is completely initialized to zeros. Note that the caller should
+ /// initialize the memory allocated by this method. The memory is owned by
+ /// the MemoryBuffer object.
+ static MemoryBuffer *getNewMemBuffer(size_t Size,
+ const char *BufferName = "");
+
+ /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
+ /// that is not initialized. Note that the caller should initialize the
+ /// memory allocated by this method. The memory is owned by the MemoryBuffer
+ /// object.
+ static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
+ const char *BufferName = "");
+
+ /// getSTDIN - Read all of stdin into a file buffer, and return it. This
+ /// returns null if stdin is empty.
+ static MemoryBuffer *getSTDIN();
+
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN)
+ /// returns an empty buffer.
+ static MemoryBuffer *getFileOrSTDIN(const char *Filename,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1);
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason.
+ static MemoryBuffer *getFileOrSTDIN(const std::string &FN,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1) {
+ return getFileOrSTDIN(FN.c_str(), ErrStr, FileSize);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
new file mode 100644
index 000000000000..9958b97a3e64
--- /dev/null
+++ b/include/llvm/Support/MutexGuard.h
@@ -0,0 +1,41 @@
+//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a guard for a block of code that ensures a Mutex is locked
+// upon construction and released upon destruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEXGUARD_H
+#define LLVM_SUPPORT_MUTEXGUARD_H
+
+#include "llvm/System/Mutex.h"
+
+namespace llvm {
+ /// Instances of this class acquire a given Mutex Lock when constructed and
+ /// hold that lock until destruction. The intention is to instantiate one of
+ /// these on the stack at the top of some scope to be assured that C++
+ /// destruction of the object will always release the Mutex and thus avoid
+ /// a host of nasty multi-threading problems in the face of exceptions, etc.
+ /// @brief Guard a section of code with a Mutex.
+ class MutexGuard {
+ sys::Mutex &M;
+ MutexGuard(const MutexGuard &); // DO NOT IMPLEMENT
+ void operator=(const MutexGuard &); // DO NOT IMPLEMENT
+ public:
+ MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
+ ~MutexGuard() { M.release(); }
+ /// holds - Returns true if this locker instance holds the specified lock.
+ /// This is mostly used in assertions to validate that the correct mutex
+ /// is held.
+ bool holds(const sys::Mutex& lock) const { return &M == &lock; }
+ };
+}
+
+#endif // LLVM_SUPPORT_MUTEXGUARD_H
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
new file mode 100644
index 000000000000..1dce497017bf
--- /dev/null
+++ b/include/llvm/Support/NoFolder.h
@@ -0,0 +1,178 @@
+//======-- llvm/Support/NoFolder.h - Constant folding helper -*- C++ -*-======//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NoFolder class, a helper for IRBuilder. It provides
+// IRBuilder with a set of methods for creating unfolded constants. This is
+// useful for learners trying to understand how LLVM IR works, and who don't
+// want details to be hidden by the constant folder. For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
+//
+// Note: since it is not actually possible to create unfolded constants, this
+// class returns values rather than constants. The values do not have names,
+// even if names were provided to IRBuilder, which may be confusing.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_NOFOLDER_H
+#define LLVM_SUPPORT_NOFOLDER_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+
+/// NoFolder - Create "constants" (actually, values) with no folding.
+class NoFolder {
+public:
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateAdd(LHS, RHS);
+ }
+ Value *CreateSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateSub(LHS, RHS);
+ }
+ Value *CreateMul(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateMul(LHS, RHS);
+ }
+ Value *CreateUDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateUDiv(LHS, RHS);
+ }
+ Value *CreateSDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateSDiv(LHS, RHS);
+ }
+ Value *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFDiv(LHS, RHS);
+ }
+ Value *CreateURem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateURem(LHS, RHS);
+ }
+ Value *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateSRem(LHS, RHS);
+ }
+ Value *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFRem(LHS, RHS);
+ }
+ Value *CreateShl(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateShl(LHS, RHS);
+ }
+ Value *CreateLShr(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateLShr(LHS, RHS);
+ }
+ Value *CreateAShr(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateAShr(LHS, RHS);
+ }
+ Value *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateAnd(LHS, RHS);
+ }
+ Value *CreateOr(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateOr(LHS, RHS);
+ }
+ Value *CreateXor(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateXor(LHS, RHS);
+ }
+
+ Value *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::Create(Opc, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateNeg(Constant *C) const {
+ return BinaryOperator::CreateNeg(C);
+ }
+ Value *CreateNot(Constant *C) const {
+ return BinaryOperator::CreateNot(C);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
+ }
+ Value *CreateGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateCast(Instruction::CastOps Op, Constant *C,
+ const Type *DestTy) const {
+ return CastInst::Create(Op, C, DestTy);
+ }
+ Value *CreateIntCast(Constant *C, const Type *DestTy,
+ bool isSigned) const {
+ return CastInst::CreateIntegerCast(C, DestTy, isSigned);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateICmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ return new ICmpInst(P, LHS, RHS);
+ }
+ Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ return new FCmpInst(P, LHS, RHS);
+ }
+ Value *CreateVICmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ return new VICmpInst(P, LHS, RHS);
+ }
+ Value *CreateVFCmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ return new VFCmpInst(P, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ return SelectInst::Create(C, True, False);
+ }
+
+ Value *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return new ExtractElementInst(Vec, Idx);
+ }
+
+ Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return InsertElementInst::Create(Vec, NewElt, Idx);
+ }
+
+ Value *CreateShuffleVector(Constant *V1, Constant *V2, Constant *Mask) const {
+ return new ShuffleVectorInst(V1, V2, Mask);
+ }
+
+ Value *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
+ unsigned NumIdx) const {
+ return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx);
+ }
+
+ Value *CreateInsertValue(Constant *Agg, Constant *Val,
+ const unsigned *IdxList, unsigned NumIdx) const {
+ return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/OutputBuffer.h b/include/llvm/Support/OutputBuffer.h
new file mode 100644
index 000000000000..b2077c55143f
--- /dev/null
+++ b/include/llvm/Support/OutputBuffer.h
@@ -0,0 +1,154 @@
+//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods to output values to a data buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
+#define LLVM_SUPPORT_OUTPUTBUFFER_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+ class OutputBuffer {
+ /// Output buffer.
+ std::vector<unsigned char> &Output;
+
+ /// is64Bit/isLittleEndian - This information is inferred from the target
+ /// machine directly, indicating what header values and flags to set.
+ bool is64Bit, isLittleEndian;
+ public:
+ OutputBuffer(std::vector<unsigned char> &Out,
+ bool is64bit, bool le)
+ : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
+
+ // align - Emit padding into the file until the current output position is
+ // aligned to the specified power of two boundary.
+ void align(unsigned Boundary) {
+ assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+ "Must align to 2^k boundary");
+ size_t Size = Output.size();
+
+ if (Size & (Boundary - 1)) {
+ // Add padding to get alignment to the correct place.
+ size_t Pad = Boundary - (Size & (Boundary - 1));
+ Output.resize(Size + Pad);
+ }
+ }
+
+ //===------------------------------------------------------------------===//
+ // Out Functions - Output the specified value to the data buffer.
+
+ void outbyte(unsigned char X) {
+ Output.push_back(X);
+ }
+ void outhalf(unsigned short X) {
+ if (isLittleEndian) {
+ Output.push_back(X & 255);
+ Output.push_back(X >> 8);
+ } else {
+ Output.push_back(X >> 8);
+ Output.push_back(X & 255);
+ }
+ }
+ void outword(unsigned X) {
+ if (isLittleEndian) {
+ Output.push_back((X >> 0) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 24) & 255);
+ } else {
+ Output.push_back((X >> 24) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 0) & 255);
+ }
+ }
+ void outxword(uint64_t X) {
+ if (isLittleEndian) {
+ Output.push_back(unsigned(X >> 0) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 56) & 255);
+ } else {
+ Output.push_back(unsigned(X >> 56) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 0) & 255);
+ }
+ }
+ void outaddr32(unsigned X) {
+ outword(X);
+ }
+ void outaddr64(uint64_t X) {
+ outxword(X);
+ }
+ void outaddr(uint64_t X) {
+ if (!is64Bit)
+ outword((unsigned)X);
+ else
+ outxword(X);
+ }
+ void outstring(const std::string &S, unsigned Length) {
+ unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
+ ? static_cast<unsigned>(S.length()) : Length;
+ unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
+ ? Length - static_cast<unsigned>(S.length()) : 0;
+
+ for (unsigned i = 0; i < len_to_copy; ++i)
+ outbyte(S[i]);
+
+ for (unsigned i = 0; i < len_to_fill; ++i)
+ outbyte(0);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Fix Functions - Replace an existing entry at an offset.
+
+ void fixhalf(unsigned short X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
+ }
+ void fixword(unsigned X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
+ P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
+ P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
+ }
+ void fixaddr(uint64_t X, unsigned Offset) {
+ if (!is64Bit)
+ fixword((unsigned)X, Offset);
+ else
+ assert(0 && "Emission of 64-bit data not implemented yet!");
+ }
+
+ unsigned char &operator[](unsigned Index) {
+ return Output[Index];
+ }
+ const unsigned char &operator[](unsigned Index) const {
+ return Output[Index];
+ }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
new file mode 100644
index 000000000000..e489e0a6f0b5
--- /dev/null
+++ b/include/llvm/Support/PassNameParser.h
@@ -0,0 +1,133 @@
+//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file the PassNameParser and FilteredPassNameParser<> classes, which are
+// used to add command line arguments to a utility for all of the passes that
+// have been registered into the system.
+//
+// The PassNameParser class adds ALL passes linked into the system (that are
+// creatable) as command line arguments to the tool (when instantiated with the
+// appropriate command line option template). The FilteredPassNameParser<>
+// template is used for the same purposes as PassNameParser, except that it only
+// includes passes that have a PassType that are compatible with the filter
+// (which is the template argument).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
+#define LLVM_SUPPORT_PASS_NAME_PARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+#include <cstring>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// PassNameParser class - Make use of the pass registration mechanism to
+// automatically add a command line argument to opt for each pass.
+//
+class PassNameParser : public PassRegistrationListener,
+ public cl::parser<const PassInfo*> {
+ cl::Option *Opt;
+public:
+ PassNameParser() : Opt(0) {}
+
+ void initialize(cl::Option &O) {
+ Opt = &O;
+ cl::parser<const PassInfo*>::initialize(O);
+
+ // Add all of the passes to the map that got initialized before 'this' did.
+ enumeratePasses();
+ }
+
+ // ignorablePassImpl - Can be overriden in subclasses to refine the list of
+ // which passes we want to include.
+ //
+ virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
+
+ inline bool ignorablePass(const PassInfo *P) const {
+ // Ignore non-selectable and non-constructible passes! Ignore
+ // non-optimizations.
+ return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
+ P->getNormalCtor() == 0 || ignorablePassImpl(P);
+ }
+
+ // Implement the PassRegistrationListener callbacks used to populate our map
+ //
+ virtual void passRegistered(const PassInfo *P) {
+ if (ignorablePass(P) || !Opt) return;
+ if (findOption(P->getPassArgument()) != getNumOptions()) {
+ cerr << "Two passes with the same argument (-"
+ << P->getPassArgument() << ") attempted to be registered!\n";
+ abort();
+ }
+ addLiteralOption(P->getPassArgument(), P, P->getPassName());
+ }
+ virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
+
+ // ValLessThan - Provide a sorting comparator for Values elements...
+ typedef std::pair<const char*,
+ std::pair<const PassInfo*, const char*> > ValType;
+ static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
+ return std::string(VT1.first) < std::string(VT2.first);
+ }
+
+ // printOptionInfo - Print out information about this option. Override the
+ // default implementation to sort the table before we print...
+ virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
+ PassNameParser *PNP = const_cast<PassNameParser*>(this);
+ std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+ cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
+ }
+};
+
+///===----------------------------------------------------------------------===//
+/// FilteredPassNameParser class - Make use of the pass registration
+/// mechanism to automatically add a command line argument to opt for
+/// each pass that satisfies a filter criteria. Filter should return
+/// true for passes to be registered as command-line options.
+///
+template<typename Filter>
+class FilteredPassNameParser : public PassNameParser {
+private:
+ Filter filter;
+
+public:
+ bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
+};
+
+///===----------------------------------------------------------------------===//
+/// PassArgFilter - A filter for use with PassNameFilterParser that only
+/// accepts a Pass whose Arg matches certain strings.
+///
+/// Use like this:
+///
+/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
+///
+/// static cl::list<
+/// const PassInfo*,
+/// bool,
+/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
+/// PassList(cl::desc("Passes available:"));
+///
+/// Only the -anders_aa and -dse options will be available to the user.
+///
+template<const char *Args>
+class PassArgFilter {
+public:
+ bool operator()(const PassInfo &P) const {
+ return(std::strstr(Args, P.getPassArgument()));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
new file mode 100644
index 000000000000..d27a7f1ed786
--- /dev/null
+++ b/include/llvm/Support/PatternMatch.h
@@ -0,0 +1,531 @@
+//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a simple and efficient mechanism for performing general
+// tree-based pattern matches on the LLVM IR. The power of these routines is
+// that it allows you to write concise patterns that are expressive and easy to
+// understand. The other major advantage of this is that it allows you to
+// trivially capture/bind elements in the pattern to variables. For example,
+// you can do something like this:
+//
+// Value *Exp = ...
+// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
+// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
+// m_And(m_Value(Y), m_ConstantInt(C2))))) {
+// ... Pattern is matched and variables are bound ...
+// }
+//
+// This is primarily useful to things like the instruction combiner, but can
+// also be useful for static analysis tools or code generators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATTERNMATCH_H
+#define LLVM_SUPPORT_PATTERNMATCH_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+namespace PatternMatch {
+
+template<typename Val, typename Pattern>
+bool match(Val *V, const Pattern &P) {
+ return const_cast<Pattern&>(P).match(V);
+}
+
+template<typename Class>
+struct leaf_ty {
+ template<typename ITy>
+ bool match(ITy *V) { return isa<Class>(V); }
+};
+
+/// m_Value() - Match an arbitrary value and ignore it.
+inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
+/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
+inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
+
+template<int64_t Val>
+struct constantint_ty {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ const APInt &CIV = CI->getValue();
+ if (Val >= 0)
+ return CIV == Val;
+ // If Val is negative, and CI is shorter than it, truncate to the right
+ // number of bits. If it is larger, then we have to sign extend. Just
+ // compare their negated values.
+ return -CIV == -Val;
+ }
+ return false;
+ }
+};
+
+/// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value
+/// and ignore it.
+template<int64_t Val>
+inline constantint_ty<Val> m_ConstantInt() {
+ return constantint_ty<Val>();
+}
+
+struct zero_ty {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNullValue();
+ return false;
+ }
+};
+
+/// m_Zero() - Match an arbitrary zero/null constant.
+inline zero_ty m_Zero() { return zero_ty(); }
+
+
+template<typename Class>
+struct bind_ty {
+ Class *&VR;
+ bind_ty(Class *&V) : VR(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (Class *CV = dyn_cast<Class>(V)) {
+ VR = CV;
+ return true;
+ }
+ return false;
+ }
+};
+
+/// m_Value - Match a value, capturing it if we match.
+inline bind_ty<Value> m_Value(Value *&V) { return V; }
+
+/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
+inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+
+/// specificval_ty - Match a specified Value*.
+struct specificval_ty {
+ const Value *Val;
+ specificval_ty(const Value *V) : Val(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ return V == Val;
+ }
+};
+
+/// m_Specific - Match if we have a specific specified value.
+inline specificval_ty m_Specific(const Value *V) { return V; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for specific binary operators.
+//
+
+template<typename LHS_t, typename RHS_t,
+ unsigned Opcode, typename ConcreteTy = BinaryOperator>
+struct BinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Opcode) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for either AShr or LShr .. for convenience
+//
+template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
+struct Shr_match {
+ LHS_t L;
+ RHS_t R;
+
+ Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
+ V->getValueID() == Value::InstructionVal + Instruction::AShr) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return (I->getOpcode() == Instruction::AShr ||
+ I->getOpcode() == Instruction::LShr) &&
+ L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return (CE->getOpcode() == Instruction::LShr ||
+ CE->getOpcode() == Instruction::AShr) &&
+ L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
+ return Shr_match<LHS, RHS>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for binary classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
+struct BinaryOpClass_match {
+ OpcType *Opcode;
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Opcode(&Op), L(LHS), R(RHS) {}
+ BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
+ : Opcode(0), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ if (Opcode)
+ *Opcode = I->getOpcode();
+ return true;
+ }
+#if 0 // Doesn't handle constantexprs yet!
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+#endif
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(Op, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for CmpInst classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct CmpClass_match {
+ PredicateTy &Predicate;
+ LHS_t L;
+ RHS_t R;
+
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Predicate(Pred), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ Predicate = I->getPredicate();
+ return true;
+ }
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ ICmpInst, ICmpInst::Predicate>(Pred, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ FCmpInst, FCmpInst::Predicate>(Pred, L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for SelectInst classes
+//
+
+template<typename Cond_t, typename LHS_t, typename RHS_t>
+struct SelectClass_match {
+ Cond_t C;
+ LHS_t L;
+ RHS_t R;
+
+ SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : C(Cond), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (SelectInst *I = dyn_cast<SelectInst>(V))
+ return C.match(I->getOperand(0)) &&
+ L.match(I->getOperand(1)) &&
+ R.match(I->getOperand(2));
+ return false;
+ }
+};
+
+template<typename Cond, typename LHS, typename RHS>
+inline SelectClass_match<Cond, RHS, LHS>
+m_Select(const Cond &C, const LHS &L, const RHS &R) {
+ return SelectClass_match<Cond, LHS, RHS>(C, L, R);
+}
+
+/// m_SelectCst - This matches a select of two constants, e.g.:
+/// m_SelectCst(m_Value(V), -1, 0)
+template<int64_t L, int64_t R, typename Cond>
+inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
+m_SelectCst(const Cond &C) {
+ return SelectClass_match<Cond, constantint_ty<L>,
+ constantint_ty<R> >(C, m_ConstantInt<L>(),
+ m_ConstantInt<R>());
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for CastInst classes
+//
+
+template<typename Op_t, typename Class>
+struct CastClass_match {
+ Op_t Op;
+
+ CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ return Op.match(I->getOperand(0));
+ return false;
+ }
+};
+
+template<typename Class, typename OpTy>
+inline CastClass_match<OpTy, Class> m_Cast(const OpTy &Op) {
+ return CastClass_match<OpTy, Class>(Op);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for unary operators
+//
+
+template<typename LHS_t>
+struct not_match {
+ LHS_t L;
+
+ not_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getOpcode() == Instruction::Xor)
+ return matchIfNot(I->getOperand(0), I->getOperand(1));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::Xor)
+ return matchIfNot(CE->getOperand(0), CE->getOperand(1));
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return L.match(ConstantExpr::getNot(CI));
+ return false;
+ }
+private:
+ bool matchIfNot(Value *LHS, Value *RHS) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+ return CI->isAllOnesValue() && L.match(LHS);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
+ return CI->isAllOnesValue() && L.match(RHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
+ return CV->isAllOnesValue() && L.match(LHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
+ return CV->isAllOnesValue() && L.match(RHS);
+ return false;
+ }
+};
+
+template<typename LHS>
+inline not_match<LHS> m_Not(const LHS &L) { return L; }
+
+
+template<typename LHS_t>
+struct neg_match {
+ LHS_t L;
+
+ neg_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getOpcode() == Instruction::Sub)
+ return matchIfNeg(I->getOperand(0), I->getOperand(1));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::Sub)
+ return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return L.match(ConstantExpr::getNeg(CI));
+ return false;
+ }
+private:
+ bool matchIfNeg(Value *LHS, Value *RHS) {
+ return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
+ L.match(RHS);
+ }
+};
+
+template<typename LHS>
+inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for control flow
+//
+
+template<typename Cond_t>
+struct brc_match {
+ Cond_t Cond;
+ BasicBlock *&T, *&F;
+ brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
+ : Cond(C), T(t), F(f) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isConditional()) {
+ if (Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+template<typename Cond_t>
+inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
+ return brc_match<Cond_t>(C, T, F);
+}
+
+} // end namespace PatternMatch
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PluginLoader.h b/include/llvm/Support/PluginLoader.h
new file mode 100644
index 000000000000..bdbb134b28eb
--- /dev/null
+++ b/include/llvm/Support/PluginLoader.h
@@ -0,0 +1,37 @@
+//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A tool can #include this file to get a -load option that allows the user to
+// load arbitrary shared objects into the tool's address space. Note that this
+// header can only be included by a program ONCE, so it should never to used by
+// library authors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PLUGINLOADER_H
+#define LLVM_SUPPORT_PLUGINLOADER_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ struct PluginLoader {
+ void operator=(const std::string &Filename);
+ static unsigned getNumPlugins();
+ static std::string& getPlugin(unsigned num);
+ };
+
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+ // This causes operator= above to be invoked for every -load option.
+ static cl::opt<PluginLoader, false, cl::parser<std::string> >
+ LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
+ cl::desc("Load the specified plugin"));
+#endif
+}
+
+#endif
diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h
new file mode 100644
index 000000000000..b0edd3bd09f9
--- /dev/null
+++ b/include/llvm/Support/PointerLikeTypeTraits.h
@@ -0,0 +1,77 @@
+//===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PointerLikeTypeTraits class. This allows data
+// structures to reason about pointers and other things that are pointer sized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// PointerLikeTypeTraits - This is a traits object that is used to handle
+/// pointer types and things that are just wrappers for pointers as a uniform
+/// entity.
+template <typename T>
+class PointerLikeTypeTraits {
+ // getAsVoidPointer
+ // getFromVoidPointer
+ // getNumLowBitsAvailable
+};
+
+// Provide PointerLikeTypeTraits for non-cvr pointers.
+template<typename T>
+class PointerLikeTypeTraits<T*> {
+public:
+ static inline void *getAsVoidPointer(T* P) { return P; }
+ static inline T *getFromVoidPointer(void *P) {
+ return static_cast<T*>(P);
+ }
+
+ /// Note, we assume here that malloc returns objects at least 8-byte aligned.
+ /// However, this may be wrong, or pointers may be from something other than
+ /// malloc. In this case, you should specialize this template to reduce this.
+ ///
+ /// All clients should use assertions to do a run-time check to ensure that
+ /// this is actually true.
+ enum { NumLowBitsAvailable = 2 };
+};
+
+// Provide PointerLikeTypeTraits for const pointers.
+template<typename T>
+class PointerLikeTypeTraits<const T*> {
+public:
+ static inline const void *getAsVoidPointer(const T* P) { return P; }
+ static inline const T *getFromVoidPointer(const void *P) {
+ return static_cast<const T*>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+// Provide PointerLikeTypeTraits for uintptr_t.
+template<>
+class PointerLikeTypeTraits<uintptr_t> {
+public:
+ static inline void *getAsVoidPointer(uintptr_t P) {
+ return reinterpret_cast<void*>(P);
+ }
+ static inline uintptr_t getFromVoidPointer(void *P) {
+ return reinterpret_cast<uintptr_t>(P);
+ }
+ // No bits are available!
+ enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h
new file mode 100644
index 000000000000..bb66a8ed58b7
--- /dev/null
+++ b/include/llvm/Support/PredIteratorCache.h
@@ -0,0 +1,70 @@
+//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PredIteratorCache class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
+#define LLVM_SUPPORT_PREDITERATORCACHE_H
+
+namespace llvm {
+
+ /// PredIteratorCache - This class is an extremely trivial cache for
+ /// predecessor iterator queries. This is useful for code that repeatedly
+ /// wants the predecessor list for the same blocks.
+ class PredIteratorCache {
+ /// BlockToPredsMap - Pointer to null-terminated list.
+ DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
+ DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
+
+ /// Memory - This is the space that holds cached preds.
+ BumpPtrAllocator Memory;
+ public:
+
+ /// GetPreds - Get a cached list for the null-terminated predecessor list of
+ /// the specified block. This can be used in a loop like this:
+ /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
+ /// use(*PI);
+ /// instead of:
+ /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
+ BasicBlock **GetPreds(BasicBlock *BB) {
+ BasicBlock **&Entry = BlockToPredsMap[BB];
+ if (Entry) return Entry;
+
+ SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
+ PredCache.push_back(0); // null terminator.
+
+ BlockToPredCountMap[BB] = PredCache.size()-1;
+
+ Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
+ std::copy(PredCache.begin(), PredCache.end(), Entry);
+ return Entry;
+ }
+
+ unsigned GetNumPreds(BasicBlock *BB) {
+ GetPreds(BB);
+ return BlockToPredCountMap[BB];
+ }
+
+ /// clear - Remove all information.
+ void clear() {
+ BlockToPredsMap.clear();
+ BlockToPredCountMap.clear();
+ Memory.Reset();
+ }
+ };
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
new file mode 100644
index 000000000000..909d286f28b6
--- /dev/null
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -0,0 +1,65 @@
+//===- llvm/Support/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PrettyStackTraceEntry class, which is used to make
+// crashes give more contextual information about what the program was doing
+// when it crashed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H
+#define LLVM_SUPPORT_PRETTYSTACKTRACE_H
+
+namespace llvm {
+ class raw_ostream;
+
+ /// PrettyStackTraceEntry - This class is used to represent a frame of the
+ /// "pretty" stack trace that is dumped when a program crashes. You can define
+ /// subclasses of this and declare them on the program stack: when they are
+ /// constructed and destructed, they will add their symbolic frames to a
+ /// virtual stack trace. This gets dumped out if the program crashes.
+ class PrettyStackTraceEntry {
+ const PrettyStackTraceEntry *NextEntry;
+ PrettyStackTraceEntry(const PrettyStackTraceEntry &); // DO NOT IMPLEMENT
+ void operator=(const PrettyStackTraceEntry&); // DO NOT IMPLEMENT
+ public:
+ PrettyStackTraceEntry();
+ virtual ~PrettyStackTraceEntry();
+
+ /// print - Emit information about this stack frame to OS.
+ virtual void print(raw_ostream &OS) const = 0;
+
+ /// getNextEntry - Return the next entry in the list of frames.
+ const PrettyStackTraceEntry *getNextEntry() const { return NextEntry; }
+ };
+
+ /// PrettyStackTraceString - This object prints a specified string (which
+ /// should not contain newlines) to the stream as the stack trace when a crash
+ /// occurs.
+ class PrettyStackTraceString : public PrettyStackTraceEntry {
+ const char *Str;
+ public:
+ PrettyStackTraceString(const char *str) : Str(str) {}
+ virtual void print(raw_ostream &OS) const;
+ };
+
+ /// PrettyStackTraceProgram - This object prints a specified program arguments
+ /// to the stream as the stack trace when a crash occurs.
+ class PrettyStackTraceProgram : public PrettyStackTraceEntry {
+ int ArgC;
+ const char *const *ArgV;
+ public:
+ PrettyStackTraceProgram(int argc, const char * const*argv)
+ : ArgC(argc), ArgV(argv) {}
+ virtual void print(raw_ostream &OS) const;
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
new file mode 100644
index 000000000000..2fa0365d5f50
--- /dev/null
+++ b/include/llvm/Support/Recycler.h
@@ -0,0 +1,116 @@
+//==- llvm/Support/Recycler.h - Recycling Allocator --------------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Recycler class template. See the doxygen comment for
+// Recycler for more details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLER_H
+#define LLVM_SUPPORT_RECYCLER_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/Support/AlignOf.h"
+#include <cassert>
+
+namespace llvm {
+
+/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
+/// printing statistics.
+///
+void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
+
+/// RecyclerStruct - Implementation detail for Recycler. This is a
+/// class that the recycler imposes on free'd memory to carve out
+/// next/prev pointers.
+struct RecyclerStruct {
+ RecyclerStruct *Prev, *Next;
+};
+
+template<>
+struct ilist_traits<RecyclerStruct> : ilist_default_traits<RecyclerStruct> {
+ static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
+ static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
+ static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
+ static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; }
+
+ mutable RecyclerStruct Sentinel;
+ RecyclerStruct *createSentinel() const {
+ return &Sentinel;
+ }
+ static void destroySentinel(RecyclerStruct *) {}
+
+ RecyclerStruct *provideInitialHead() const { return createSentinel(); }
+ RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); }
+ static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
+
+ static void deleteNode(RecyclerStruct *) {
+ assert(0 && "Recycler's ilist_traits shouldn't see a deleteNode call!");
+ }
+};
+
+/// Recycler - This class manages a linked-list of deallocated nodes
+/// and facilitates reusing deallocated memory in place of allocating
+/// new memory.
+///
+template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class Recycler {
+ /// FreeList - Doubly-linked list of nodes that have deleted contents and
+ /// are not in active use.
+ ///
+ iplist<RecyclerStruct> FreeList;
+
+public:
+ ~Recycler() {
+ // If this fails, either the callee has lost track of some allocation,
+ // or the callee isn't tracking allocations and should just call
+ // clear() before deleting the Recycler.
+ assert(FreeList.empty() && "Non-empty recycler deleted!");
+ }
+
+ /// clear - Release all the tracked allocations to the allocator. The
+ /// recycler must be free of any tracked allocations before being
+ /// deleted; calling clear is one way to ensure this.
+ template<class AllocatorType>
+ void clear(AllocatorType &Allocator) {
+ while (!FreeList.empty()) {
+ T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin()));
+ Allocator.Deallocate(t);
+ }
+ }
+
+ template<class SubClass, class AllocatorType>
+ SubClass *Allocate(AllocatorType &Allocator) {
+ assert(sizeof(SubClass) <= Size &&
+ "Recycler allocation size is less than object size!");
+ assert(AlignOf<SubClass>::Alignment <= Align &&
+ "Recycler allocation alignment is less than object alignment!");
+ return !FreeList.empty() ?
+ reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
+ static_cast<SubClass *>(Allocator.Allocate(Size, Align));
+ }
+
+ template<class AllocatorType>
+ T *Allocate(AllocatorType &Allocator) {
+ return Allocate<T>(Allocator);
+ }
+
+ template<class SubClass, class AllocatorType>
+ void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
+ FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element));
+ }
+
+ void PrintStats() {
+ PrintRecyclerStats(Size, Align, FreeList.size());
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h
new file mode 100644
index 000000000000..8e957f1b2645
--- /dev/null
+++ b/include/llvm/Support/RecyclingAllocator.h
@@ -0,0 +1,59 @@
+//==- llvm/Support/RecyclingAllocator.h - Recycling Allocator ----*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RecyclingAllocator class. See the doxygen comment for
+// RecyclingAllocator for more details on the implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+#define LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+
+#include "llvm/Support/Recycler.h"
+
+namespace llvm {
+
+/// RecyclingAllocator - This class wraps an Allocator, adding the
+/// functionality of recycling deleted objects.
+///
+template<class AllocatorType, class T,
+ size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class RecyclingAllocator {
+private:
+ /// Base - Implementation details.
+ ///
+ Recycler<T, Size, Align> Base;
+
+ /// Allocator - The wrapped allocator.
+ ///
+ AllocatorType Allocator;
+
+public:
+ ~RecyclingAllocator() { Base.clear(Allocator); }
+
+ /// Allocate - Return a pointer to storage for an object of type
+ /// SubClass. The storage may be either newly allocated or recycled.
+ ///
+ template<class SubClass>
+ SubClass *Allocate() { return Base.Allocate<SubClass>(Allocator); }
+
+ T *Allocate() { return Base.Allocate(Allocator); }
+
+ /// Deallocate - Release storage for the pointed-to object. The
+ /// storage will be kept track of and may be recycled.
+ ///
+ template<class SubClass>
+ void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); }
+
+ void PrintStats() { Base.PrintStats(); }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
new file mode 100644
index 000000000000..454679bda834
--- /dev/null
+++ b/include/llvm/Support/Registry.h
@@ -0,0 +1,224 @@
+//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a registry template for discovering pluggable modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_H
+#define LLVM_SUPPORT_REGISTRY_H
+
+namespace llvm {
+ /// A simple registry entry which provides only a name, description, and
+ /// no-argument constructor.
+ template <typename T>
+ class SimpleRegistryEntry {
+ const char *Name, *Desc;
+ T *(*Ctor)();
+
+ public:
+ SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
+ : Name(N), Desc(D), Ctor(C)
+ {}
+
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+ T *instantiate() const { return Ctor(); }
+ };
+
+
+ /// Traits for registry entries. If using other than SimpleRegistryEntry, it
+ /// is necessary to define an alternate traits class.
+ template <typename T>
+ class RegistryTraits {
+ RegistryTraits(); // Do not implement.
+
+ public:
+ typedef SimpleRegistryEntry<T> entry;
+
+ /// nameof/descof - Accessors for name and description of entries. These are
+ // used to generate help for command-line options.
+ static const char *nameof(const entry &Entry) { return Entry.getName(); }
+ static const char *descof(const entry &Entry) { return Entry.getDesc(); }
+ };
+
+
+ /// A global registry used in conjunction with static constructors to make
+ /// pluggable components (like targets or garbage collectors) "just work" when
+ /// linked with an executable.
+ template <typename T, typename U = RegistryTraits<T> >
+ class Registry {
+ public:
+ typedef U traits;
+ typedef typename U::entry entry;
+
+ class node;
+ class listener;
+ class iterator;
+
+ private:
+ Registry(); // Do not implement.
+
+ static void Announce(const entry &E) {
+ for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
+ Cur->registered(E);
+ }
+
+ friend class node;
+ static node *Head, *Tail;
+
+ friend class listener;
+ static listener *ListenerHead, *ListenerTail;
+
+ public:
+ class iterator;
+
+
+ /// Node in linked list of entries.
+ ///
+ class node {
+ friend class iterator;
+
+ node *Next;
+ const entry& Val;
+
+ public:
+ node(const entry& V) : Next(0), Val(V) {
+ if (Tail)
+ Tail->Next = this;
+ else
+ Head = this;
+ Tail = this;
+
+ Announce(V);
+ }
+ };
+
+
+ /// Iterators for registry entries.
+ ///
+ class iterator {
+ const node *Cur;
+
+ public:
+ explicit iterator(const node *N) : Cur(N) {}
+
+ bool operator==(const iterator &That) const { return Cur == That.Cur; }
+ bool operator!=(const iterator &That) const { return Cur != That.Cur; }
+ iterator &operator++() { Cur = Cur->Next; return *this; }
+ const entry &operator*() const { return Cur->Val; }
+ const entry *operator->() const { return &Cur->Val; }
+ };
+
+ static iterator begin() { return iterator(Head); }
+ static iterator end() { return iterator(0); }
+
+
+ /// Abstract base class for registry listeners, which are informed when new
+ /// entries are added to the registry. Simply subclass and instantiate:
+ ///
+ /// class CollectorPrinter : public Registry<Collector>::listener {
+ /// protected:
+ /// void registered(const Registry<Collector>::entry &e) {
+ /// cerr << "collector now available: " << e->getName() << "\n";
+ /// }
+ ///
+ /// public:
+ /// CollectorPrinter() { init(); } // Print those already registered.
+ /// };
+ ///
+ /// CollectorPrinter Printer;
+ ///
+ class listener {
+ listener *Prev, *Next;
+
+ friend void Registry::Announce(const entry &E);
+
+ protected:
+ /// Called when an entry is added to the registry.
+ ///
+ virtual void registered(const entry &) = 0;
+
+ /// Calls 'registered' for each pre-existing entry.
+ ///
+ void init() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ registered(*I);
+ }
+
+ public:
+ listener() : Prev(ListenerTail), Next(0) {
+ if (Prev)
+ Prev->Next = this;
+ else
+ ListenerHead = this;
+ ListenerTail = this;
+ }
+
+ virtual ~listener() {
+ if (Next)
+ Next->Prev = Prev;
+ else
+ ListenerTail = Prev;
+ if (Prev)
+ Prev->Next = Next;
+ else
+ ListenerHead = Next;
+ }
+ };
+
+
+ /// A static registration template. Use like such:
+ ///
+ /// Registry<Collector>::Add<FancyGC>
+ /// X("fancy-gc", "Newfangled garbage collector.");
+ ///
+ /// Use of this template requires that:
+ ///
+ /// 1. The registered subclass has a default constructor.
+ //
+ /// 2. The registry entry type has a constructor compatible with this
+ /// signature:
+ ///
+ /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
+ ///
+ /// If you have more elaborate requirements, then copy and modify.
+ ///
+ template <typename V>
+ class Add {
+ entry Entry;
+ node Node;
+
+ static T *CtorFn() { return new V(); }
+
+ public:
+ Add(const char *Name, const char *Desc)
+ : Entry(Name, Desc, CtorFn), Node(Entry) {}
+ };
+
+ /// Registry::Parser now lives in llvm/Support/RegistryParser.h.
+
+ };
+
+
+ template <typename T, typename U>
+ typename Registry<T,U>::node *Registry<T,U>::Head;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::node *Registry<T,U>::Tail;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
+
+}
+
+#endif
diff --git a/include/llvm/Support/RegistryParser.h b/include/llvm/Support/RegistryParser.h
new file mode 100644
index 000000000000..2cc578370fef
--- /dev/null
+++ b/include/llvm/Support/RegistryParser.h
@@ -0,0 +1,55 @@
+//=== RegistryParser.h - Linker-supported plugin registries -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a command-line parser for a registry.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H
+#define LLVM_SUPPORT_REGISTRY_PARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Registry.h"
+
+namespace llvm {
+
+ /// A command-line parser for a registry. Use like such:
+ ///
+ /// static cl::opt<Registry<Collector>::entry, false,
+ /// RegistryParser<Collector> >
+ /// GCOpt("gc", cl::desc("Garbage collector to use."),
+ /// cl::value_desc());
+ ///
+ /// To make use of the value:
+ ///
+ /// Collector *TheCollector = GCOpt->instantiate();
+ ///
+ template <typename T, typename U = RegistryTraits<T> >
+ class RegistryParser :
+ public cl::parser<const typename U::entry*>,
+ public Registry<T, U>::listener {
+ typedef U traits;
+ typedef typename U::entry entry;
+ typedef typename Registry<T, U>::listener listener;
+
+ protected:
+ void registered(const entry &E) {
+ addLiteralOption(traits::nameof(E), &E, traits::descof(E));
+ }
+
+ public:
+ void initialize(cl::Option &O) {
+ listener::init();
+ cl::parser<const typename U::entry*>::initialize(O);
+ }
+ };
+
+}
+
+#endif // LLVM_SUPPORT_REGISTRY_PARSER_H
diff --git a/include/llvm/Support/SlowOperationInformer.h b/include/llvm/Support/SlowOperationInformer.h
new file mode 100644
index 000000000000..b30aa987523c
--- /dev/null
+++ b/include/llvm/Support/SlowOperationInformer.h
@@ -0,0 +1,65 @@
+//===- llvm/Support/SlowOperationInformer.h - Keep user informed *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple object which can be used to let the user know what
+// is going on when a slow operation is happening, and gives them the ability to
+// cancel it. Potentially slow operations can stack allocate one of these
+// objects, and periodically call the "progress" method to update the progress
+// bar. If the operation takes more than 1 second to complete, the progress bar
+// is automatically shown and updated. As such, the slow operation should not
+// print stuff to the screen, and should not be confused if an extra line
+// appears on the screen (ie, the cursor should be at the start of the line).
+//
+// If the user presses CTRL-C during the operation, the next invocation of the
+// progress method return true indicating that the operation was cancelled.
+//
+// Because SlowOperationInformers fiddle around with signals, they cannot be
+// nested, and interact poorly with threads. The SIGALRM handler is set back to
+// SIGDFL, but the SIGINT signal handler is restored when the
+// SlowOperationInformer is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+#define LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+
+#include <string>
+#include <cassert>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class SlowOperationInformer {
+ std::string OperationName;
+ unsigned LastPrintAmount;
+
+ SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ public:
+ SlowOperationInformer(const std::string &Name);
+ ~SlowOperationInformer();
+
+ /// progress - Clients should periodically call this method when they can
+ /// handle cancellation. The Amount variable should indicate how far
+ /// along the operation is, given in 1/10ths of a percent (in other words,
+ /// Amount should range from 0 to 1000). If the user cancels the operation,
+ /// this returns true, false otherwise.
+ bool progress(unsigned Amount);
+
+ /// progress - Same as the method above, but this performs the division for
+ /// you, and helps you avoid overflow if you are dealing with largish
+ /// numbers.
+ bool progress(unsigned Current, unsigned Maximum) {
+ assert(Maximum != 0 &&
+ "Shouldn't be doing work if there is nothing to do!");
+ return progress(Current*uint64_t(1000UL)/Maximum);
+ }
+ };
+} // end namespace llvm
+
+#endif /* SLOW_OPERATION_INFORMER_H */
diff --git a/include/llvm/Support/StableBasicBlockNumbering.h b/include/llvm/Support/StableBasicBlockNumbering.h
new file mode 100644
index 000000000000..5e0f87e48950
--- /dev/null
+++ b/include/llvm/Support/StableBasicBlockNumbering.h
@@ -0,0 +1,59 @@
+//===- StableBasicBlockNumbering.h - Provide BB identifiers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class provides a *stable* numbering of basic blocks that does not depend
+// on their address in memory (which is nondeterministic). When requested, this
+// class simply provides a unique ID for each basic block in the function
+// specified and the inverse mapping.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+#define LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+
+#include "llvm/Function.h"
+#include "llvm/ADT/UniqueVector.h"
+
+namespace llvm {
+ class StableBasicBlockNumbering {
+ // BBNumbering - Holds the numbering.
+ UniqueVector<BasicBlock*> BBNumbering;
+ public:
+ StableBasicBlockNumbering(Function *F = 0) {
+ if (F) compute(*F);
+ }
+
+ /// compute - If we have not computed a numbering for the function yet, do
+ /// so.
+ void compute(Function &F) {
+ if (BBNumbering.empty()) {
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ BBNumbering.insert(I);
+ }
+ }
+
+ /// getNumber - Return the ID number for the specified BasicBlock.
+ ///
+ unsigned getNumber(BasicBlock *BB) const {
+ unsigned Idx = BBNumbering.idFor(BB);
+ assert(Idx && "Invalid basic block or numbering not computed!");
+ return Idx-1;
+ }
+
+ /// getBlock - Return the BasicBlock corresponding to a particular ID.
+ ///
+ BasicBlock *getBlock(unsigned N) const {
+ assert(N < BBNumbering.size() &&
+ "Block ID out of range or numbering not computed!");
+ return BBNumbering[N+1];
+ }
+ };
+}
+
+#endif
diff --git a/include/llvm/Support/Streams.h b/include/llvm/Support/Streams.h
new file mode 100644
index 000000000000..445ab98c476d
--- /dev/null
+++ b/include/llvm/Support/Streams.h
@@ -0,0 +1,91 @@
+//===- llvm/Support/Streams.h - Wrappers for iostreams ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a wrapper for the STL I/O streams. It prevents the need
+// to include <iostream> in a file just to get I/O.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STREAMS_H
+#define LLVM_SUPPORT_STREAMS_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+ /// FlushStream - Function called by BaseStream to flush an ostream.
+ void FlushStream(std::ostream &S);
+
+ /// BaseStream - Acts like the STL streams. It's a wrapper for the std::cerr,
+ /// std::cout, std::cin, etc. streams. However, it doesn't require #including
+ /// @verbatim <iostream> @endverbatm in every file (doing so increases static
+ /// c'tors & d'tors in the object code).
+ ///
+ template <typename StreamTy>
+ class BaseStream {
+ StreamTy *Stream;
+ public:
+ BaseStream() : Stream(0) {}
+ BaseStream(StreamTy &S) : Stream(&S) {}
+ BaseStream(StreamTy *S) : Stream(S) {}
+
+ StreamTy *stream() const { return Stream; }
+
+ inline BaseStream &operator << (std::ios_base &(*Func)(std::ios_base&)) {
+ if (Stream) *Stream << Func;
+ return *this;
+ }
+
+ inline BaseStream &operator << (StreamTy &(*Func)(StreamTy&)) {
+ if (Stream) *Stream << Func;
+ return *this;
+ }
+
+ void flush() {
+ if (Stream)
+ FlushStream(*Stream);
+ }
+
+ template <typename Ty>
+ BaseStream &operator << (const Ty &Thing) {
+ if (Stream) *Stream << Thing;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &operator >> (Ty &Thing) {
+ if (Stream) *Stream >> Thing;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &write(const Ty &A, unsigned N) {
+ if (Stream) Stream->write(A, N);
+ return *this;
+ }
+
+ operator StreamTy* () { return Stream; }
+
+ bool operator == (const StreamTy &S) { return &S == Stream; }
+ bool operator != (const StreamTy &S) { return !(*this == S); }
+ bool operator == (const BaseStream &S) { return S.Stream == Stream; }
+ bool operator != (const BaseStream &S) { return !(*this == S); }
+ };
+
+ typedef BaseStream<std::ostream> OStream;
+ typedef BaseStream<std::istream> IStream;
+ typedef BaseStream<std::stringstream> StringStream;
+
+ extern OStream cout;
+ extern OStream cerr;
+ extern IStream cin;
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
new file mode 100644
index 000000000000..98db8e2bf37c
--- /dev/null
+++ b/include/llvm/Support/StringPool.h
@@ -0,0 +1,148 @@
+//===-- StringPool.h - Interned string pool -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares an interned string pool, which helps reduce the cost of
+// strings by using the same storage for identical strings.
+//
+// To intern a string:
+//
+// StringPool Pool;
+// PooledStringPtr Str = Pool.intern("wakka wakka");
+//
+// To use the value of an interned string, use operator bool and operator*:
+//
+// if (Str)
+// cerr << "the string is" << *Str << "\n";
+//
+// Pooled strings are immutable, but you can change a PooledStringPtr to point
+// to another instance. So that interned strings can eventually be freed,
+// strings in the string pool are reference-counted (automatically).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STRINGPOOL_H
+#define LLVM_SUPPORT_STRINGPOOL_H
+
+#include "llvm/ADT/StringMap.h"
+#include <new>
+#include <cassert>
+
+namespace llvm {
+
+ class PooledStringPtr;
+
+ /// StringPool - An interned string pool. Use the intern method to add a
+ /// string. Strings are removed automatically as PooledStringPtrs are
+ /// destroyed.
+ class StringPool {
+ /// PooledString - This is the value of an entry in the pool's interning
+ /// table.
+ struct PooledString {
+ StringPool *Pool; ///< So the string can remove itself.
+ unsigned Refcount; ///< Number of referencing PooledStringPtrs.
+
+ public:
+ PooledString() : Pool(0), Refcount(0) { }
+ };
+
+ friend class PooledStringPtr;
+
+ typedef StringMap<PooledString> table_t;
+ typedef StringMapEntry<PooledString> entry_t;
+ table_t InternTable;
+
+ public:
+ StringPool();
+ ~StringPool();
+
+ /// intern - Adds a string to the pool and returns a reference-counted
+ /// pointer to it. No additional memory is allocated if the string already
+ /// exists in the pool.
+ PooledStringPtr intern(const char *Begin, const char *End);
+
+ /// intern - Adds a null-terminated string to the pool and returns a
+ /// reference-counted pointer to it. No additional memory is allocated if
+ /// the string already exists in the pool.
+ inline PooledStringPtr intern(const char *Str);
+
+ /// empty - Checks whether the pool is empty. Returns true if so.
+ ///
+ inline bool empty() const { return InternTable.empty(); }
+ };
+
+ /// PooledStringPtr - A pointer to an interned string. Use operator bool to
+ /// test whether the pointer is valid, and operator * to get the string if so.
+ /// This is a lightweight value class with storage requirements equivalent to
+ /// a single pointer, but it does have reference-counting overhead when
+ /// copied.
+ class PooledStringPtr {
+ typedef StringPool::entry_t entry_t;
+ entry_t *S;
+
+ public:
+ PooledStringPtr() : S(0) {}
+
+ explicit PooledStringPtr(entry_t *E) : S(E) {
+ if (S) ++S->getValue().Refcount;
+ }
+
+ PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
+ if (S) ++S->getValue().Refcount;
+ }
+
+ PooledStringPtr &operator=(const PooledStringPtr &That) {
+ if (S != That.S) {
+ clear();
+ S = That.S;
+ if (S) ++S->getValue().Refcount;
+ }
+ return *this;
+ }
+
+ void clear() {
+ if (!S)
+ return;
+ if (--S->getValue().Refcount == 0) {
+ S->getValue().Pool->InternTable.remove(S);
+ S->Destroy();
+ }
+ S = 0;
+ }
+
+ ~PooledStringPtr() { clear(); }
+
+ inline const char *begin() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyData();
+ }
+
+ inline const char *end() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyData() + S->getKeyLength();
+ }
+
+ inline unsigned size() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyLength();
+ }
+
+ inline const char *operator*() const { return begin(); }
+ inline operator bool() const { return S != 0; }
+
+ inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
+ inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
+ };
+
+ PooledStringPtr StringPool::intern(const char *Str) {
+ return intern(Str, Str + strlen(Str));
+ }
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
new file mode 100644
index 000000000000..9a33fa31f226
--- /dev/null
+++ b/include/llvm/Support/SystemUtils.h
@@ -0,0 +1,42 @@
+//===- SystemUtils.h - Utilities to do low-level system stuff ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions used to do a variety of low-level, often
+// system-specific, tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
+#define LLVM_SUPPORT_SYSTEMUTILS_H
+
+#include "llvm/System/Program.h"
+
+namespace llvm {
+
+/// Determine if the ostream provided is connected to the std::cout and
+/// displayed or not (to a console window). If so, generate a warning message
+/// advising against display of bitcode and return true. Otherwise just return
+/// false
+/// @brief Check for output written to a console
+bool CheckBitcodeOutputToConsole(
+ std::ostream* stream_to_check, ///< The stream to be checked
+ bool print_warning = true ///< Control whether warnings are printed
+);
+
+/// FindExecutable - Find a named executable, giving the argv[0] of program
+/// being executed. This allows us to find another LLVM tool if it is built into
+/// the same directory, but that directory is neither the current directory, nor
+/// in the PATH. If the executable cannot be found, return an empty string.
+/// @brief Find a named executable.
+sys::Path FindExecutable(const std::string &ExeName,
+ const std::string &ProgramPath);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
new file mode 100644
index 000000000000..14f2c9b244f8
--- /dev/null
+++ b/include/llvm/Support/TargetFolder.h
@@ -0,0 +1,209 @@
+//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants with
+// target dependent folding. For general constant creation and folding,
+// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETFOLDER_H
+#define LLVM_SUPPORT_TARGETFOLDER_H
+
+#include "llvm/Constants.h"
+#include "llvm/Analysis/ConstantFolding.h"
+
+namespace llvm {
+
+class TargetData;
+
+/// TargetFolder - Create constants with target dependent folding.
+class TargetFolder {
+ const TargetData &TD;
+
+ /// Fold - Fold the constant using target specific information.
+ Constant *Fold(Constant *C) const {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ if (Constant *CF = ConstantFoldConstantExpression(CE, &TD))
+ return CF;
+ return C;
+ }
+
+public:
+ TargetFolder(const TargetData &TheTD) : TD(TheTD) {}
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getAdd(LHS, RHS));
+ }
+ Constant *CreateSub(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getSub(LHS, RHS));
+ }
+ Constant *CreateMul(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getMul(LHS, RHS));
+ }
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getUDiv(LHS, RHS));
+ }
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getSDiv(LHS, RHS));
+ }
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFDiv(LHS, RHS));
+ }
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getURem(LHS, RHS));
+ }
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getSRem(LHS, RHS));
+ }
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFRem(LHS, RHS));
+ }
+ Constant *CreateShl(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getShl(LHS, RHS));
+ }
+ Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getLShr(LHS, RHS));
+ }
+ Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getAShr(LHS, RHS));
+ }
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getAnd(LHS, RHS));
+ }
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getOr(LHS, RHS));
+ }
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getXor(LHS, RHS));
+ }
+
+ Constant *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::get(Opc, LHS, RHS));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateNeg(Constant *C) const {
+ return Fold(ConstantExpr::getNeg(C));
+ }
+ Constant *CreateNot(Constant *C) const {
+ return Fold(ConstantExpr::getNot(C));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
+ }
+ Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+ const Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getCast(Op, C, DestTy));
+ }
+ Constant *CreateIntCast(Constant *C, const Type *DestTy,
+ bool isSigned) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
+ }
+
+ Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+ Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+ Constant *CreateVICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+ Constant *CreateVFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ return Fold(ConstantExpr::getSelect(C, True, False));
+ }
+
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return Fold(ConstantExpr::getExtractElement(Vec, Idx));
+ }
+
+ Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
+ }
+
+ Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
+ return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
+ }
+
+ Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx));
+ }
+
+ Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+ const unsigned *IdxList, unsigned NumIdx) const {
+ return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx));
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
new file mode 100644
index 000000000000..584199f44007
--- /dev/null
+++ b/include/llvm/Support/Timer.h
@@ -0,0 +1,172 @@
+//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines three classes: Timer, TimeRegion, and TimerGroup,
+// documented below.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMER_H
+#define LLVM_SUPPORT_TIMER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include <cassert>
+
+namespace llvm {
+
+class TimerGroup;
+
+/// Timer - This class is used to track the amount of time spent between
+/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS
+/// support it can also keep track of the RSS of the program at various points.
+/// By default, the Timer will print the amount of time it has captured to
+/// standard error when the laster timer is destroyed, otherwise it is printed
+/// when its TimerGroup is destroyed. Timers do not print their information
+/// if they are never started.
+///
+class Timer {
+ double Elapsed; // Wall clock time elapsed in seconds
+ double UserTime; // User time elapsed
+ double SystemTime; // System time elapsed
+ ssize_t MemUsed; // Memory allocated (in bytes)
+ size_t PeakMem; // Peak memory used
+ size_t PeakMemBase; // Temporary for peak calculation...
+ std::string Name; // The name of this time variable
+ bool Started; // Has this time variable ever been started?
+ TimerGroup *TG; // The TimerGroup this Timer is in.
+public:
+ explicit Timer(const std::string &N);
+ Timer(const std::string &N, TimerGroup &tg);
+ Timer(const Timer &T);
+ ~Timer();
+
+ double getProcessTime() const { return UserTime+SystemTime; }
+ double getWallTime() const { return Elapsed; }
+ ssize_t getMemUsed() const { return MemUsed; }
+ size_t getPeakMem() const { return PeakMem; }
+ std::string getName() const { return Name; }
+
+ const Timer &operator=(const Timer &T) {
+ Elapsed = T.Elapsed;
+ UserTime = T.UserTime;
+ SystemTime = T.SystemTime;
+ MemUsed = T.MemUsed;
+ PeakMem = T.PeakMem;
+ PeakMemBase = T.PeakMemBase;
+ Name = T.Name;
+ Started = T.Started;
+ assert(TG == T.TG && "Can only assign timers in the same TimerGroup!");
+ return *this;
+ }
+
+ // operator< - Allow sorting...
+ bool operator<(const Timer &T) const {
+ // Sort by Wall Time elapsed, as it is the only thing really accurate
+ return Elapsed < T.Elapsed;
+ }
+ bool operator>(const Timer &T) const { return T.operator<(*this); }
+
+ /// startTimer - Start the timer running. Time between calls to
+ /// startTimer/stopTimer is counted by the Timer class. Note that these calls
+ /// must be correctly paired.
+ ///
+ void startTimer();
+
+ /// stopTimer - Stop the timer.
+ ///
+ void stopTimer();
+
+ /// addPeakMemoryMeasurement - This method should be called whenever memory
+ /// usage needs to be checked. It adds a peak memory measurement to the
+ /// currently active timers, which will be printed when the timer group prints
+ ///
+ static void addPeakMemoryMeasurement();
+
+ /// print - Print the current timer to standard error, and reset the "Started"
+ /// flag.
+ void print(const Timer &Total, std::ostream &OS);
+
+private:
+ friend class TimerGroup;
+
+ // Copy ctor, initialize with no TG member.
+ Timer(bool, const Timer &T);
+
+ /// sum - Add the time accumulated in the specified timer into this timer.
+ ///
+ void sum(const Timer &T);
+};
+
+
+/// The TimeRegion class is used as a helper class to call the startTimer() and
+/// stopTimer() methods of the Timer class. When the object is constructed, it
+/// starts the timer specified as it's argument. When it is destroyed, it stops
+/// the relevant timer. This makes it easy to time a region of code.
+///
+class TimeRegion {
+ Timer *T;
+ TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
+public:
+ explicit TimeRegion(Timer &t) : T(&t) {
+ T->startTimer();
+ }
+ explicit TimeRegion(Timer *t) : T(t) {
+ if (T)
+ T->startTimer();
+ }
+ ~TimeRegion() {
+ if (T)
+ T->stopTimer();
+ }
+};
+
+
+/// NamedRegionTimer - This class is basically a combination of TimeRegion and
+/// Timer. It allows you to declare a new timer, AND specify the region to
+/// time, all in one statement. All timers with the same name are merged. This
+/// is primarily used for debugging and for hunting performance problems.
+///
+struct NamedRegionTimer : public TimeRegion {
+ explicit NamedRegionTimer(const std::string &Name);
+ explicit NamedRegionTimer(const std::string &Name,
+ const std::string &GroupName);
+};
+
+
+/// The TimerGroup class is used to group together related timers into a single
+/// report that is printed when the TimerGroup is destroyed. It is illegal to
+/// destroy a TimerGroup object before all of the Timers in it are gone. A
+/// TimerGroup can be specified for a newly created timer in its constructor.
+///
+class TimerGroup {
+ std::string Name;
+ unsigned NumTimers;
+ std::vector<Timer> TimersToPrint;
+public:
+ explicit TimerGroup(const std::string &name) : Name(name), NumTimers(0) {}
+ ~TimerGroup() {
+ assert(NumTimers == 0 &&
+ "TimerGroup destroyed before all contained timers!");
+ }
+
+private:
+ friend class Timer;
+ void addTimer() { ++NumTimers; }
+ void removeTimer();
+ void addTimerToPrint(const Timer &T) {
+ TimersToPrint.push_back(Timer(true, T));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h
new file mode 100644
index 000000000000..5198c8173998
--- /dev/null
+++ b/include/llvm/Support/TypeBuilder.h
@@ -0,0 +1,464 @@
+//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TypeBuilder class, which is used as a convenient way to
+// create LLVM types with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPEBUILDER_H
+#define LLVM_SUPPORT_TYPEBUILDER_H
+
+#include "llvm/DerivedTypes.h"
+#include <limits.h>
+
+namespace llvm {
+
+/// TypeBuilder - This provides a uniform API for looking up types
+/// known at compile time. To support cross-compilation, we define a
+/// series of tag types in the llvm::types namespace, like i<N>,
+/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be
+/// any of these, a native C type (whose size may depend on the host
+/// compiler), or a pointer, function, or struct type built out of
+/// these. TypeBuilder<T, true> removes native C types from this set
+/// to guarantee that its result is suitable for cross-compilation.
+/// We define the primitive types, pointer types, and functions up to
+/// 5 arguments here, but to use this class with your own types,
+/// you'll need to specialize it. For example, say you want to call a
+/// function defined externally as:
+///
+/// struct MyType {
+/// int32 a;
+/// int32 *b;
+/// void *array[1]; // Intended as a flexible array.
+/// };
+/// int8 AFunction(struct MyType *value);
+///
+/// You'll want to use
+/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
+/// to declare the function, but when you first try this, your compiler will
+/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
+/// write:
+///
+/// namespace llvm {
+/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
+/// public:
+/// static const StructType *get() {
+/// // Using the static result variable ensures that the type is
+/// // only looked up once.
+/// static const StructType *const result = StructType::get(
+/// TypeBuilder<types::i<32>, xcompile>::get(),
+/// TypeBuilder<types::i<32>*, xcompile>::get(),
+/// TypeBuilder<types::i<8>*[], xcompile>::get(),
+/// NULL);
+/// return result;
+/// }
+///
+/// // You may find this a convenient place to put some constants
+/// // to help with getelementptr. They don't have any effect on
+/// // the operation of TypeBuilder.
+/// enum Fields {
+/// FIELD_A,
+/// FIELD_B,
+/// FIELD_ARRAY
+/// };
+/// }
+/// } // namespace llvm
+///
+/// Using the static result variable ensures that the type is only looked up
+/// once.
+///
+/// TypeBuilder cannot handle recursive types or types you only know at runtime.
+/// If you try to give it a recursive type, it will deadlock, infinitely
+/// recurse, or throw a recursive_init exception.
+template<typename T, bool cross_compilable> class TypeBuilder {};
+
+// Types for use with cross-compilable TypeBuilders. These correspond
+// exactly with an LLVM-native type.
+namespace types {
+/// i<N> corresponds to the LLVM IntegerType with N bits.
+template<uint32_t num_bits> class i {};
+
+// The following classes represent the LLVM floating types.
+class ieee_float {};
+class ieee_double {};
+class x86_fp80 {};
+class fp128 {};
+class ppc_fp128 {};
+} // namespace types
+
+// LLVM doesn't have const or volatile types.
+template<typename T, bool cross> class TypeBuilder<const T, cross>
+ : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<volatile T, cross>
+ : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
+ : public TypeBuilder<T, cross> {};
+
+// Pointers
+template<typename T, bool cross> class TypeBuilder<T*, cross> {
+public:
+ static const PointerType *get() {
+ static const PointerType *const result =
+ PointerType::getUnqual(TypeBuilder<T,cross>::get());
+ return result;
+ }
+};
+
+/// There is no support for references
+template<typename T, bool cross> class TypeBuilder<T&, cross> {};
+
+// Arrays
+template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
+public:
+ static const ArrayType *get() {
+ static const ArrayType *const result =
+ ArrayType::get(TypeBuilder<T, cross>::get(), N);
+ return result;
+ }
+};
+/// LLVM uses an array of length 0 to represent an unknown-length array.
+template<typename T, bool cross> class TypeBuilder<T[], cross> {
+public:
+ static const ArrayType *get() {
+ static const ArrayType *const result =
+ ArrayType::get(TypeBuilder<T, cross>::get(), 0);
+ return result;
+ }
+};
+
+// Define the C integral types only for TypeBuilder<T, false>.
+//
+// C integral types do not have a defined size. It would be nice to use the
+// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
+// following problem:
+//
+// On an ILP32 machine, stdint.h might define:
+//
+// typedef int int32_t;
+// typedef long long int64_t;
+// typedef long size_t;
+//
+// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
+// TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in
+// addition to the defined-size types because we'd get duplicate definitions on
+// platforms where stdint.h instead defines:
+//
+// typedef int int32_t;
+// typedef long long int64_t;
+// typedef int size_t;
+//
+// So we define all the primitive C types and nothing else.
+#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
+template<> class TypeBuilder<T, false> { \
+public: \
+ static const IntegerType *get() { \
+ static const IntegerType *const result = \
+ IntegerType::get(sizeof(T) * CHAR_BIT); \
+ return result; \
+ } \
+}; \
+template<> class TypeBuilder<T, true> { \
+ /* We provide a definition here so users don't accidentally */ \
+ /* define these types to work. */ \
+}
+DEFINE_INTEGRAL_TYPEBUILDER(char);
+DEFINE_INTEGRAL_TYPEBUILDER(signed char);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
+DEFINE_INTEGRAL_TYPEBUILDER(short);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
+DEFINE_INTEGRAL_TYPEBUILDER(int);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
+DEFINE_INTEGRAL_TYPEBUILDER(long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
+#ifdef _MSC_VER
+DEFINE_INTEGRAL_TYPEBUILDER(__int64);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
+#else /* _MSC_VER */
+DEFINE_INTEGRAL_TYPEBUILDER(long long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
+#endif /* _MSC_VER */
+#undef DEFINE_INTEGRAL_TYPEBUILDER
+
+template<uint32_t num_bits, bool cross>
+class TypeBuilder<types::i<num_bits>, cross> {
+public:
+ static const IntegerType *get() {
+ static const IntegerType *const result = IntegerType::get(num_bits);
+ return result;
+ }
+};
+
+template<> class TypeBuilder<float, false> {
+public:
+ static const Type *get() {
+ return Type::FloatTy;
+ }
+};
+template<> class TypeBuilder<float, true> {};
+
+template<> class TypeBuilder<double, false> {
+public:
+ static const Type *get() {
+ return Type::DoubleTy;
+ }
+};
+template<> class TypeBuilder<double, true> {};
+
+template<bool cross> class TypeBuilder<types::ieee_float, cross> {
+public:
+ static const Type *get() { return Type::FloatTy; }
+};
+template<bool cross> class TypeBuilder<types::ieee_double, cross> {
+public:
+ static const Type *get() { return Type::DoubleTy; }
+};
+template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
+public:
+ static const Type *get() { return Type::X86_FP80Ty; }
+};
+template<bool cross> class TypeBuilder<types::fp128, cross> {
+public:
+ static const Type *get() { return Type::FP128Ty; }
+};
+template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
+public:
+ static const Type *get() { return Type::PPC_FP128Ty; }
+};
+
+template<bool cross> class TypeBuilder<void, cross> {
+public:
+ static const Type *get() {
+ return Type::VoidTy;
+ }
+};
+
+/// void* is disallowed in LLVM types, but it occurs often enough in C code that
+/// we special case it.
+template<> class TypeBuilder<void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+
+template<typename R, bool cross> class TypeBuilder<R(), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(1);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(2);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(3);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ bool cross>
+class TypeBuilder<R(A1, A2, A3, A4), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(4);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ params.push_back(TypeBuilder<A4, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(5);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ params.push_back(TypeBuilder<A4, cross>::get());
+ params.push_back(TypeBuilder<A5, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ }
+};
+
+template<typename R, bool cross> class TypeBuilder<R(...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+template<typename R, typename A1, bool cross>
+class TypeBuilder<R(A1, ...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(1);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2, ...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(2);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3, ...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(3);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(4);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ params.push_back(TypeBuilder<A4, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
+public:
+ static const FunctionType *get() {
+ static const FunctionType *const result = create();
+ return result;
+ }
+
+private:
+ static const FunctionType *create() {
+ std::vector<const Type*> params;
+ params.reserve(5);
+ params.push_back(TypeBuilder<A1, cross>::get());
+ params.push_back(TypeBuilder<A2, cross>::get());
+ params.push_back(TypeBuilder<A3, cross>::get());
+ params.push_back(TypeBuilder<A4, cross>::get());
+ params.push_back(TypeBuilder<A5, cross>::get());
+ return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
new file mode 100644
index 000000000000..a97a5e88142d
--- /dev/null
+++ b/include/llvm/Support/ValueHandle.h
@@ -0,0 +1,272 @@
+//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ValueHandle class and its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_VALUEHANDLE_H
+#define LLVM_SUPPORT_VALUEHANDLE_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Value.h"
+
+namespace llvm {
+class ValueHandleBase;
+
+// ValueHandleBase** is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<ValueHandleBase**> {
+public:
+ static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
+ static inline ValueHandleBase **getFromVoidPointer(void *P) {
+ return static_cast<ValueHandleBase**>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+/// ValueHandleBase - This is the common base class of value handles.
+/// ValueHandle's are smart pointers to Value's that have special behavior when
+/// the value is deleted or ReplaceAllUsesWith'd. See the specific handles
+/// below for details.
+///
+class ValueHandleBase {
+ friend class Value;
+protected:
+ /// HandleBaseKind - This indicates what sub class the handle actually is.
+ /// This is to avoid having a vtable for the light-weight handle pointers. The
+ /// fully general Callback version does have a vtable.
+ enum HandleBaseKind {
+ Assert,
+ Weak,
+ Callback
+ };
+private:
+
+ PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
+ ValueHandleBase *Next;
+ Value *VP;
+public:
+ explicit ValueHandleBase(HandleBaseKind Kind)
+ : PrevPair(0, Kind), Next(0), VP(0) {}
+ ValueHandleBase(HandleBaseKind Kind, Value *V)
+ : PrevPair(0, Kind), Next(0), VP(V) {
+ if (V)
+ AddToUseList();
+ }
+ ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
+ : PrevPair(0, Kind), Next(0), VP(RHS.VP) {
+ if (VP)
+ AddToExistingUseList(RHS.getPrevPtr());
+ }
+ ~ValueHandleBase() {
+ if (VP)
+ RemoveFromUseList();
+ }
+
+ Value *operator=(Value *RHS) {
+ if (VP == RHS) return RHS;
+ if (VP) RemoveFromUseList();
+ VP = RHS;
+ if (VP) AddToUseList();
+ return RHS;
+ }
+
+ Value *operator=(const ValueHandleBase &RHS) {
+ if (VP == RHS.VP) return RHS.VP;
+ if (VP) RemoveFromUseList();
+ VP = RHS.VP;
+ if (VP) AddToExistingUseList(RHS.getPrevPtr());
+ return VP;
+ }
+
+ Value *operator->() const { return getValPtr(); }
+ Value &operator*() const { return *getValPtr(); }
+
+protected:
+ Value *getValPtr() const { return VP; }
+private:
+ // Callbacks made from Value.
+ static void ValueIsDeleted(Value *V);
+ static void ValueIsRAUWd(Value *Old, Value *New);
+
+ // Internal implementation details.
+ ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
+ HandleBaseKind getKind() const { return PrevPair.getInt(); }
+ void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
+
+ /// AddToUseList - Add this ValueHandle to the use list for VP, where List is
+ /// known to point into the existing use list.
+ void AddToExistingUseList(ValueHandleBase **List);
+
+ /// AddToUseList - Add this ValueHandle to the use list for VP.
+ void AddToUseList();
+ /// RemoveFromUseList - Remove this ValueHandle from its current use list.
+ void RemoveFromUseList();
+};
+
+/// WeakVH - This is a value handle that tries hard to point to a Value, even
+/// across RAUW operations, but will null itself out if the value is destroyed.
+/// this is useful for advisory sorts of information, but should not be used as
+/// the key of a map (since the map would have to rearrange itself when the
+/// pointer changes).
+class WeakVH : public ValueHandleBase {
+public:
+ WeakVH() : ValueHandleBase(Weak) {}
+ WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
+ WeakVH(const WeakVH &RHS)
+ : ValueHandleBase(Weak, RHS) {}
+
+ operator Value*() const {
+ return getValPtr();
+ }
+};
+
+// Specialize simplify_type to allow WeakVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const WeakVH> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const WeakVH &WVH) {
+ return static_cast<Value *>(WVH);
+ }
+};
+template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {};
+
+/// AssertingVH - This is a Value Handle that points to a value and asserts out
+/// if the value is destroyed while the handle is still live. This is very
+/// useful for catching dangling pointer bugs and other things which can be
+/// non-obvious. One particularly useful place to use this is as the Key of a
+/// map. Dangling pointer bugs often lead to really subtle bugs that only occur
+/// if another object happens to get allocated to the same address as the old
+/// one. Using an AssertingVH ensures that an assert is triggered as soon as
+/// the bad delete occurs.
+///
+/// Note that an AssertingVH handle does *not* follow values across RAUW
+/// operations. This means that RAUW's need to explicitly update the
+/// AssertingVH's as it moves. This is required because in non-assert mode this
+/// class turns into a trivial wrapper around a pointer.
+template <typename ValueTy>
+class AssertingVH
+#ifndef NDEBUG
+ : public ValueHandleBase
+#endif
+ {
+
+#ifndef NDEBUG
+ ValueTy *getValPtr() const {
+ return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+ }
+ void setValPtr(ValueTy *P) {
+ ValueHandleBase::operator=(P);
+ }
+#else
+ ValueTy *ThePtr;
+ ValueTy *getValPtr() const { return ThePtr; }
+ void setValPtr(ValueTy *P) { ThePtr = P; }
+#endif
+
+public:
+#ifndef NDEBUG
+ AssertingVH() : ValueHandleBase(Assert) {}
+ AssertingVH(ValueTy *P) : ValueHandleBase(Assert, P) {}
+ AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
+#else
+ AssertingVH() : ThePtr(0) {}
+ AssertingVH(ValueTy *P) : ThePtr(P) {}
+#endif
+
+ operator ValueTy*() const {
+ return getValPtr();
+ }
+
+ ValueTy *operator=(ValueTy *RHS) {
+ setValPtr(RHS);
+ return getValPtr();
+ }
+ ValueTy *operator=(AssertingVH<ValueTy> &RHS) {
+ setValPtr(RHS.getValPtr());
+ return getValPtr();
+ }
+
+ ValueTy *operator->() const { return getValPtr(); }
+ ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize simplify_type to allow AssertingVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const AssertingVH<Value> > {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) {
+ return static_cast<Value *>(AVH);
+ }
+};
+template<> struct simplify_type<AssertingVH<Value> >
+ : public simplify_type<const AssertingVH<Value> > {};
+
+/// CallbackVH - This is a value handle that allows subclasses to define
+/// callbacks that run when the underlying Value has RAUW called on it or is
+/// destroyed. This class can be used as the key of a map, as long as the user
+/// takes it out of the map before calling setValPtr() (since the map has to
+/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
+/// class has a vtable and a virtual destructor.
+class CallbackVH : public ValueHandleBase {
+protected:
+ CallbackVH(const CallbackVH &RHS)
+ : ValueHandleBase(Callback, RHS) {}
+
+ virtual ~CallbackVH();
+
+ void setValPtr(Value *P) {
+ ValueHandleBase::operator=(P);
+ }
+
+public:
+ CallbackVH() : ValueHandleBase(Callback) {}
+ CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
+
+ operator Value*() const {
+ return getValPtr();
+ }
+
+ /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
+ /// call any non-virtual Value method on getValPtr(), but no subclass methods.
+ /// If WeakVH were implemented as a CallbackVH, it would use this method to
+ /// call setValPtr(NULL). AssertingVH would use this method to cause an
+ /// assertion failure.
+ ///
+ /// All implementations must remove the reference from this object to the
+ /// Value that's being destroyed.
+ virtual void deleted() {
+ setValPtr(NULL);
+ }
+
+ /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
+ /// _before_ any of the uses have actually been replaced. If WeakVH were
+ /// implemented as a CallbackVH, it would use this method to call
+ /// setValPtr(new_value). AssertingVH would do nothing in this method.
+ virtual void allUsesReplacedWith(Value *new_value) {}
+};
+
+// Specialize simplify_type to allow CallbackVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const CallbackVH> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const CallbackVH &CVH) {
+ return static_cast<Value *>(CVH);
+ }
+};
+template<> struct simplify_type<CallbackVH>
+ : public simplify_type<const CallbackVH> {};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
new file mode 100644
index 000000000000..b67d12675fef
--- /dev/null
+++ b/include/llvm/Support/raw_ostream.h
@@ -0,0 +1,346 @@
+//===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the raw_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OSTREAM_H
+
+#include "llvm/ADT/StringExtras.h"
+#include <cassert>
+#include <cstring>
+#include <string>
+#include <iosfwd>
+
+namespace llvm {
+ class format_object_base;
+ template <typename T>
+ class SmallVectorImpl;
+
+/// raw_ostream - This class implements an extremely fast bulk output stream
+/// that can *only* output to a stream. It does not support seeking, reopening,
+/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
+/// a chunk at a time.
+class raw_ostream {
+private:
+ /// The buffer is handled in such a way that the buffer is
+ /// uninitialized, unbuffered, or out of space when OutBufCur >=
+ /// OutBufEnd. Thus a single comparison suffices to determine if we
+ /// need to take the slow path to write a single character.
+ ///
+ /// The buffer is in one of three states:
+ /// 1. Unbuffered (Unbuffered == true)
+ /// 1. Uninitialized (Unbuffered == false && OutBufStart == 0).
+ /// 2. Buffered (Unbuffered == false && OutBufStart != 0 &&
+ /// OutBufEnd - OutBufStart >= 64).
+ char *OutBufStart, *OutBufEnd, *OutBufCur;
+ bool Unbuffered;
+
+public:
+ explicit raw_ostream(bool unbuffered=false) : Unbuffered(unbuffered) {
+ // Start out ready to flush.
+ OutBufStart = OutBufEnd = OutBufCur = 0;
+ }
+
+ virtual ~raw_ostream() {
+ delete [] OutBufStart;
+ }
+
+ /// tell - Return the current offset with the file.
+ uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); }
+
+ //===--------------------------------------------------------------------===//
+ // Configuration Interface
+ //===--------------------------------------------------------------------===//
+
+ /// SetBufferSize - Set the internal buffer size to the specified amount
+ /// instead of the default.
+ void SetBufferSize(unsigned Size=4096) {
+ assert(Size >= 64 &&
+ "Buffer size must be somewhat large for invariants to hold");
+ flush();
+
+ delete [] OutBufStart;
+ OutBufStart = new char[Size];
+ OutBufEnd = OutBufStart+Size;
+ OutBufCur = OutBufStart;
+ Unbuffered = false;
+ }
+
+ /// SetUnbuffered - Set the streams buffering status. When
+ /// unbuffered the stream will flush after every write. This routine
+ /// will also flush the buffer immediately when the stream is being
+ /// set to unbuffered.
+ void SetUnbuffered() {
+ flush();
+
+ delete [] OutBufStart;
+ OutBufStart = OutBufEnd = OutBufCur = 0;
+ Unbuffered = true;
+ }
+
+ unsigned GetNumBytesInBuffer() const {
+ return OutBufCur - OutBufStart;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Data Output Interface
+ //===--------------------------------------------------------------------===//
+
+ void flush() {
+ if (OutBufCur != OutBufStart)
+ flush_nonempty();
+ }
+
+ raw_ostream &operator<<(char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(unsigned char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(signed char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(const char *Str) {
+ // Inline fast path, particulary for constant strings where a
+ // sufficiently smart compiler will simplify strlen.
+
+ unsigned Size = strlen(Str);
+
+ // Make sure we can use the fast path.
+ if (OutBufCur+Size > OutBufEnd)
+ return write(Str, Size);
+
+ memcpy(OutBufCur, Str, Size);
+ OutBufCur += Size;
+ return *this;
+ }
+
+ raw_ostream &operator<<(const std::string& Str) {
+ write(Str.data(), Str.length());
+ return *this;
+ }
+
+ raw_ostream &operator<<(unsigned long N);
+ raw_ostream &operator<<(long N);
+ raw_ostream &operator<<(unsigned long long N);
+ raw_ostream &operator<<(long long N);
+ raw_ostream &operator<<(const void *P);
+ raw_ostream &operator<<(unsigned int N) {
+ this->operator<<(static_cast<unsigned long>(N));
+ return *this;
+ }
+
+ raw_ostream &operator<<(int N) {
+ this->operator<<(static_cast<long>(N));
+ return *this;
+ }
+
+ raw_ostream &operator<<(double N) {
+ this->operator<<(ftostr(N));
+ return *this;
+ }
+
+ raw_ostream &write(unsigned char C);
+ raw_ostream &write(const char *Ptr, unsigned Size);
+
+ // Formatted output, see the format() function in Support/Format.h.
+ raw_ostream &operator<<(const format_object_base &Fmt);
+
+ //===--------------------------------------------------------------------===//
+ // Subclass Interface
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// write_impl - The is the piece of the class that is implemented
+ /// by subclasses. This writes the \args Size bytes starting at
+ /// \arg Ptr to the underlying stream.
+ ///
+ /// \invariant { Size > 0 }
+ virtual void write_impl(const char *Ptr, unsigned Size) = 0;
+
+ // An out of line virtual method to provide a home for the class vtable.
+ virtual void handle();
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Private Interface
+ //===--------------------------------------------------------------------===//
+private:
+ /// flush_nonempty - Flush the current buffer, which is known to be
+ /// non-empty. This outputs the currently buffered data and resets
+ /// the buffer to empty.
+ void flush_nonempty();
+};
+
+//===----------------------------------------------------------------------===//
+// File Output Streams
+//===----------------------------------------------------------------------===//
+
+/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
+///
+class raw_fd_ostream : public raw_ostream {
+ int FD;
+ bool ShouldClose;
+ uint64_t pos;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, unsigned Size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() { return pos; }
+
+public:
+ /// raw_fd_ostream - Open the specified file for writing. If an
+ /// error occurs, information about the error is put into ErrorInfo,
+ /// and the stream should be immediately destroyed; the string will
+ /// be empty if no error occurred.
+ ///
+ /// \param Filename - The file to open. If this is "-" then the
+ /// stream will use stdout instead.
+ /// \param Binary - The file should be opened in binary mode on
+ /// platforms that support this distinction.
+ raw_fd_ostream(const char *Filename, bool Binary, std::string &ErrorInfo);
+
+ /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
+ /// ShouldClose is true, this closes the file when the stream is destroyed.
+ raw_fd_ostream(int fd, bool shouldClose,
+ bool unbuffered=false) : raw_ostream(unbuffered), FD(fd),
+ ShouldClose(shouldClose) {}
+
+ ~raw_fd_ostream();
+
+ /// close - Manually flush the stream and close the file.
+ void close();
+
+ /// tell - Return the current offset with the file.
+ uint64_t tell() { return pos + GetNumBytesInBuffer(); }
+
+ /// seek - Flushes the stream and repositions the underlying file descriptor
+ /// positition to the offset specified from the beginning of the file.
+ uint64_t seek(uint64_t off);
+};
+
+/// raw_stdout_ostream - This is a stream that always prints to stdout.
+///
+class raw_stdout_ostream : public raw_fd_ostream {
+ // An out of line virtual method to provide a home for the class vtable.
+ virtual void handle();
+public:
+ raw_stdout_ostream();
+};
+
+/// raw_stderr_ostream - This is a stream that always prints to stderr.
+///
+class raw_stderr_ostream : public raw_fd_ostream {
+ // An out of line virtual method to provide a home for the class vtable.
+ virtual void handle();
+public:
+ raw_stderr_ostream();
+};
+
+/// outs() - This returns a reference to a raw_ostream for standard output.
+/// Use it like: outs() << "foo" << "bar";
+raw_ostream &outs();
+
+/// errs() - This returns a reference to a raw_ostream for standard error.
+/// Use it like: errs() << "foo" << "bar";
+raw_ostream &errs();
+
+
+//===----------------------------------------------------------------------===//
+// Output Stream Adaptors
+//===----------------------------------------------------------------------===//
+
+/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
+/// simple adaptor class.
+class raw_os_ostream : public raw_ostream {
+ std::ostream &OS;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, unsigned Size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos();
+
+public:
+ raw_os_ostream(std::ostream &O) : OS(O) {}
+ ~raw_os_ostream();
+
+ /// tell - Return the current offset with the stream.
+ uint64_t tell();
+};
+
+/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
+/// simple adaptor class.
+class raw_string_ostream : public raw_ostream {
+ std::string &OS;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, unsigned Size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() { return OS.size(); }
+public:
+ raw_string_ostream(std::string &O) : OS(O) {}
+ ~raw_string_ostream();
+
+ /// tell - Return the current offset with the stream.
+ uint64_t tell() { return OS.size() + GetNumBytesInBuffer(); }
+
+ /// str - Flushes the stream contents to the target string and returns
+ /// the string's reference.
+ std::string& str() {
+ flush();
+ return OS;
+ }
+};
+
+/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
+/// SmallString. This is a simple adaptor class.
+class raw_svector_ostream : public raw_ostream {
+ SmallVectorImpl<char> &OS;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, unsigned Size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos();
+public:
+ raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {}
+ ~raw_svector_ostream();
+
+ /// tell - Return the current offset with the stream.
+ uint64_t tell();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
new file mode 100644
index 000000000000..5000a8b859b8
--- /dev/null
+++ b/include/llvm/Support/type_traits.h
@@ -0,0 +1,54 @@
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a template class that determines if a type is a class or
+// not. The basic mechanism, based on using the pointer to member function of
+// a zero argument to a function was "boosted" from the boost type_traits
+// library. See http://www.boost.org/ for all the gory details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
+#define LLVM_SUPPORT_TYPE_TRAITS_H
+
+// This is actually the conforming implementation which works with abstract
+// classes. However, enough compilers have trouble with it that most will use
+// the one in boost/type_traits/object_traits.hpp. This implementation actually
+// works with VC7.0, but other interactions seem to fail when we use it.
+
+namespace llvm {
+
+namespace dont_use
+{
+ // These two functions should never be used. They are helpers to
+ // the is_class template below. They cannot be located inside
+ // is_class because doing so causes at least GCC to think that
+ // the value of the "value" enumerator is not constant. Placing
+ // them out here (for some strange reason) allows the sizeof
+ // operator against them to magically be constant. This is
+ // important to make the is_class<T>::value idiom zero cost. it
+ // evaluates to a constant 1 or 0 depending on whether the
+ // parameter T is a class or not (respectively).
+ template<typename T> char is_class_helper(void(T::*)(void));
+ template<typename T> double is_class_helper(...);
+}
+
+template <typename T>
+struct is_class
+{
+ // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
+ // more details:
+ // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
+ public:
+ enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
+};
+
+}
+
+#endif