diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /include/llvm/Support | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'include/llvm/Support')
46 files changed, 2060 insertions, 931 deletions
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index c0414f9..4c84878 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -15,6 +15,8 @@ #define LLVM_SUPPORT_ALLOCATOR_H #include "llvm/Support/AlignOf.h" +#include "llvm/Support/DataTypes.h" +#include <cassert> #include <cstdlib> namespace llvm { @@ -41,21 +43,104 @@ public: void PrintStats() const {} }; -/// BumpPtrAllocator - This allocator is useful for containers that need very -/// simple memory allocation strategies. In particular, this just keeps +/// MemSlab - This structure lives at the beginning of every slab allocated by +/// the bump allocator. +class MemSlab { +public: + size_t Size; + MemSlab *NextPtr; +}; + +/// SlabAllocator - This class can be used to parameterize the underlying +/// allocation strategy for the bump allocator. In particular, this is used +/// by the JIT to allocate contiguous swathes of executable memory. The +/// interface uses MemSlab's instead of void *'s so that the allocator +/// doesn't have to remember the size of the pointer it allocated. +class SlabAllocator { +public: + virtual ~SlabAllocator(); + virtual MemSlab *Allocate(size_t Size) = 0; + virtual void Deallocate(MemSlab *Slab) = 0; +}; + +/// MallocSlabAllocator - The default slab allocator for the bump allocator +/// is an adapter class for MallocAllocator that just forwards the method +/// calls and translates the arguments. +class MallocSlabAllocator : public SlabAllocator { + /// Allocator - The underlying allocator that we forward to. + /// + MallocAllocator Allocator; + +public: + MallocSlabAllocator() : Allocator() { } + virtual ~MallocSlabAllocator(); + virtual MemSlab *Allocate(size_t Size); + virtual void Deallocate(MemSlab *Slab); +}; + +/// 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; + /// SlabSize - Allocate data into slabs of this size unless we get an + /// allocation above SizeThreshold. + size_t SlabSize; + + /// SizeThreshold - For any allocation larger than this threshold, we should + /// allocate a separate slab. + size_t SizeThreshold; + + /// Allocator - The underlying allocator we use to get slabs of memory. This + /// defaults to MallocSlabAllocator, which wraps malloc, but it could be + /// changed to use a custom allocator. + SlabAllocator &Allocator; + + /// CurSlab - The slab that we are currently allocating into. + /// + MemSlab *CurSlab; + + /// CurPtr - The current pointer into the current slab. This points to the + /// next free byte in the slab. + char *CurPtr; + + /// End - The end of the current slab. + /// + char *End; + + /// BytesAllocated - This field tracks how many bytes we've allocated, so + /// that we can compute how much space was wasted. + size_t BytesAllocated; + + /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should + /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and + /// AlignPtr(8, 4) == 8. + static char *AlignPtr(char *Ptr, size_t Alignment); + + /// StartNewSlab - Allocate a new slab and move the bump pointers over into + /// the new slab. Modifies CurPtr and End. + void StartNewSlab(); + + /// DeallocateSlabs - Deallocate all memory slabs after and including this + /// one. + void DeallocateSlabs(MemSlab *Slab); + + static MallocSlabAllocator DefaultSlabAllocator; + public: - BumpPtrAllocator(); + BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096, + SlabAllocator &allocator = DefaultSlabAllocator); ~BumpPtrAllocator(); + /// Reset - Deallocate all but the current slab and reset the current pointer + /// to the beginning of it, freeing all memory allocated so far. void Reset(); + /// Allocate - Allocate space at the specified alignment. + /// void *Allocate(size_t Size, size_t Alignment); /// Allocate space, but do not construct, one object. @@ -83,9 +168,11 @@ public: void Deallocate(const void * /*Ptr*/) {} + unsigned GetNumSlabs() const; + void PrintStats() const; }; } // end namespace llvm -#endif +#endif // LLVM_SUPPORT_ALLOCATOR_H diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index b0b857b..3a20696 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -18,17 +18,17 @@ #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; +class PredIterator : public std::iterator<std::forward_iterator_tag, + _Ptr, ptrdiff_t> { + typedef std::iterator<std::forward_iterator_tag, _Ptr, ptrdiff_t> super; _USE_iterator It; public: typedef PredIterator<_Ptr,_USE_iterator> _Self; @@ -80,15 +80,16 @@ inline pred_const_iterator pred_end(const BasicBlock *BB) { -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // BasicBlock succ_iterator definition -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// template <class Term_, class BB_> // Successor Iterator -class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> { +class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, + BB_, ptrdiff_t> { const Term_ Term; unsigned idx; - typedef bidirectional_iterator<BB_, ptrdiff_t> super; + typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super; public: typedef SuccIterator<Term_, BB_> _Self; typedef typename super::pointer pointer; diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index dc41590..285b558 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -26,6 +26,7 @@ #include "llvm/Attributes.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/BasicBlock.h" +#include "llvm/CallingConv.h" #include "llvm/Instruction.h" namespace llvm { @@ -40,8 +41,6 @@ public: 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; } @@ -63,8 +62,8 @@ public: /// getCallingConv/setCallingConv - get or set the calling convention of the /// call. - unsigned getCallingConv() const; - void setCallingConv(unsigned CC); + CallingConv::ID getCallingConv() const; + void setCallingConv(CallingConv::ID CC); /// getAttributes/setAttributes - get or set the parameter attributes of /// the call. diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 48988f8..35fb29e 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -235,7 +235,7 @@ inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(const Y &Val) { #ifdef DEBUG_CAST_OPERATORS -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" struct bar { bar() {} @@ -251,7 +251,7 @@ struct foo { }; template <> inline bool isa_impl<foo,bar>(const bar &Val) { - cerr << "Classof: " << &Val << "\n"; + errs() << "Classof: " << &Val << "\n"; return true; } diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 3ae5013..dc73979 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -21,18 +21,17 @@ #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 "llvm/ADT/Twine.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. @@ -68,7 +67,7 @@ void MarkOptionsChanged(); // Flags permitted to be passed to command line arguments // -enum NumOccurrences { // Flags for the number of occurrences allowed +enum NumOccurrencesFlag { // 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 @@ -143,8 +142,8 @@ class Option { // 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 bool handleOccurrence(unsigned pos, StringRef ArgName, + StringRef Arg) = 0; virtual enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; @@ -163,8 +162,8 @@ public: 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 NumOccurrencesFlag getNumOccurrencesFlag() const { + return static_cast<enum NumOccurrencesFlag>(Flags & OccurrencesMask); } inline enum ValueExpected getValueExpectedFlag() const { int VE = Flags & ValueMask; @@ -198,7 +197,7 @@ public: Flags |= Flag; } - void setNumOccurrencesFlag(enum NumOccurrences Val) { + void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { setFlag(Val, OccurrencesMask); } void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); } @@ -215,8 +214,7 @@ protected: getOptionHiddenFlag() != 0 && "Not all default flags specified!"); } - inline void setNumAdditionalVals(unsigned n) - { AdditionalVals = n; } + inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } public: // addArgument - Register this argument with the commandline system. // @@ -232,15 +230,15 @@ public: // virtual void printOptionInfo(size_t GlobalWidth) const = 0; - virtual void getExtraOptionNames(std::vector<const char*> &) {} + virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {} - // addOccurrence - Wrapper around handleOccurrence that enforces Flags + // addOccurrence - Wrapper around handleOccurrence that enforces Flags. // - bool addOccurrence(unsigned pos, const char *ArgName, - const std::string &Value, bool MultiArg = false); + bool addOccurrence(unsigned pos, StringRef ArgName, + StringRef Value, bool MultiArg = false); // Prints option name followed by message. Always returns true. - bool error(std::string Message, const char *ArgName = 0); + bool error(const Twine &Message, StringRef ArgName = StringRef()); public: inline int getNumOccurrences() const { return NumOccurrences; } @@ -399,7 +397,7 @@ struct generic_parser_base { hasArgStr = O.hasArgStr(); } - void getExtraOptionNames(std::vector<const char*> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<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. @@ -458,9 +456,8 @@ public: } // parse - Return true on error. - bool parse(Option &O, const char *ArgName, const std::string &Arg, - DataType &V) { - std::string ArgVal; + bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { + StringRef ArgVal; if (hasArgStr) ArgVal = Arg; else @@ -468,12 +465,12 @@ public: for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); i != e; ++i) - if (ArgVal == Values[i].first) { + if (Values[i].first == ArgVal) { V = Values[i].second.first; return false; } - return O.error(": Cannot find option named '" + ArgVal + "'!"); + return O.error("Cannot find option named '" + ArgVal + "'!"); } /// addLiteralOption - Add an entry to the mapping table. @@ -505,7 +502,7 @@ struct basic_parser_impl { // non-template implementation of basic_parser<t> return ValueRequired; } - void getExtraOptionNames(std::vector<const char*> &) {} + void getExtraOptionNames(SmallVectorImpl<const char*> &) {} void initialize(Option &) {} @@ -541,7 +538,7 @@ class parser<bool> : public basic_parser<bool> { public: // parse - Return true on error. - bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val); + bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val); template <class Opt> void initialize(Opt &O) { @@ -568,8 +565,7 @@ 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); + bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val); enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; @@ -591,7 +587,7 @@ 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); + bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "int"; } @@ -610,7 +606,7 @@ 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); + bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "uint"; } @@ -628,7 +624,7 @@ 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); + bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "number"; } @@ -646,7 +642,7 @@ 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); + bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "number"; } @@ -664,9 +660,8 @@ 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; + bool parse(Option &, StringRef ArgName, StringRef Arg, std::string &Value) { + Value = Arg.str(); return false; } @@ -686,8 +681,7 @@ 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) { + bool parse(Option &, StringRef ArgName, StringRef Arg, char &Value) { Value = Arg[0]; return false; } @@ -726,8 +720,10 @@ template<> struct applicator<const char*> { 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<NumOccurrencesFlag> { + static void opt(NumOccurrencesFlag NO, Option &O) { + O.setNumOccurrencesFlag(NO); + } }; template<> struct applicator<ValueExpected> { static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); } @@ -770,7 +766,7 @@ public: bool setLocation(Option &O, DataType &L) { if (Location) - return O.error(": cl::location(x) specified more than once!"); + return O.error("cl::location(x) specified more than once!"); Location = &L; return false; } @@ -833,8 +829,8 @@ class opt : public Option, is_class<DataType>::value> { ParserClass Parser; - virtual bool handleOccurrence(unsigned pos, const char *ArgName, - const std::string &Arg) { + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, + StringRef Arg) { typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -847,7 +843,7 @@ class opt : public Option, virtual enum ValueExpected getValueExpectedFlagDefault() const { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) { + virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { return Parser.getExtraOptionNames(OptionNames); } @@ -964,7 +960,7 @@ public: bool setLocation(Option &O, StorageClass &L) { if (Location) - return O.error(": cl::location(x) specified more than once!"); + return O.error("cl::location(x) specified more than once!"); Location = &L; return false; } @@ -1002,12 +998,11 @@ class list : public Option, public list_storage<DataType, Storage> { virtual enum ValueExpected getValueExpectedFlagDefault() const { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) { + virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { return Parser.getExtraOptionNames(OptionNames); } - virtual bool handleOccurrence(unsigned pos, const char *ArgName, - const std::string &Arg) { + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){ typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -1139,7 +1134,7 @@ public: bool setLocation(Option &O, unsigned &L) { if (Location) - return O.error(": cl::location(x) specified more than once!"); + return O.error("cl::location(x) specified more than once!"); Location = &L; return false; } @@ -1202,12 +1197,11 @@ class bits : public Option, public bits_storage<DataType, Storage> { virtual enum ValueExpected getValueExpectedFlagDefault() const { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) { + virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { return Parser.getExtraOptionNames(OptionNames); } - virtual bool handleOccurrence(unsigned pos, const char *ArgName, - const std::string &Arg) { + virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){ typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -1307,8 +1301,8 @@ public: class alias : public Option { Option *AliasFor; - virtual bool handleOccurrence(unsigned pos, const char * /*ArgName*/, - const std::string &Arg) { + virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, + StringRef Arg) { return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); } // Handle printing stuff... @@ -1317,15 +1311,15 @@ class alias : public Option { void done() { if (!hasArgStr()) - error(": cl::alias must have argument name specified!"); + error("cl::alias must have argument name specified!"); if (AliasFor == 0) - error(": cl::alias must have an cl::aliasopt(option) specified!"); + 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!"); + error("cl::alias must only have one cl::aliasopt(...) specified!"); AliasFor = &O; } @@ -1366,7 +1360,7 @@ struct aliasopt { // 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 +// printed to stderr at the end of the regular help, just before // exit is called. struct extrahelp { const char * morehelp; diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 90292df..342a97d 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -23,7 +23,7 @@ #define VISIBILITY_HIDDEN #endif -#if (__GNUC__ >= 4) +#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define ATTRIBUTE_USED __attribute__((__used__)) #else #define ATTRIBUTE_USED @@ -56,4 +56,10 @@ #define DISABLE_INLINE #endif +#ifdef __GNUC__ +#define NORETURN __attribute__((noreturn)) +#else +#define NORETURN +#endif + #endif diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index 35065a0..99cb920 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -21,9 +21,12 @@ namespace llvm { +class LLVMContext; + /// ConstantFolder - Create constants with minimum, target independent, folding. class ConstantFolder { public: + explicit ConstantFolder(LLVMContext &) {} //===--------------------------------------------------------------------===// // Binary Operators @@ -32,12 +35,18 @@ public: Constant *CreateAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getAdd(LHS, RHS); } + Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNSWAdd(LHS, RHS); + } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFAdd(LHS, RHS); } Constant *CreateSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getSub(LHS, RHS); } + Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNSWSub(LHS, RHS); + } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFSub(LHS, RHS); } @@ -53,6 +62,9 @@ public: Constant *CreateSDiv(Constant *LHS, Constant *RHS) const { return ConstantExpr::getSDiv(LHS, RHS); } + Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getExactSDiv(LHS, RHS); + } Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFDiv(LHS, RHS); } @@ -116,6 +128,15 @@ public: return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, + unsigned NumIdx) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, + unsigned NumIdx) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + } + //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// @@ -124,10 +145,16 @@ public: const Type *DestTy) const { return ConstantExpr::getCast(Op, C, DestTy); } + Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + return ConstantExpr::getPointerCast(C, DestTy); + } Constant *CreateIntCast(Constant *C, const Type *DestTy, bool isSigned) const { return ConstantExpr::getIntegerCast(C, DestTy, isSigned); } + Constant *CreateFPCast(Constant *C, const Type *DestTy) const { + return ConstantExpr::getFPCast(C, DestTy); + } Constant *CreateBitCast(Constant *C, const Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); @@ -138,6 +165,13 @@ public: Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } + Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + return ConstantExpr::getZExtOrBitCast(C, DestTy); + } + Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + return ConstantExpr::getSExtOrBitCast(C, DestTy); + } + Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { return ConstantExpr::getTruncOrBitCast(C, DestTy); } @@ -154,14 +188,6 @@ public: 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 diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h index 098fab5..e9c8c7c 100644 --- a/include/llvm/Support/ConstantRange.h +++ b/include/llvm/Support/ConstantRange.h @@ -24,7 +24,9 @@ // [0, 0) = {} = Empty set // [255, 255) = {0..255} = Full Set // -// Note that ConstantRange always keeps unsigned values. +// Note that ConstantRange can be used to represent either signed or +// unsigned ranges. +// //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_CONSTANT_RANGE_H @@ -35,11 +37,14 @@ namespace llvm { +/// ConstantRange - This class represents an range of values. +/// class ConstantRange { APInt Lower, Upper; static ConstantRange intersect1Wrapped(const ConstantRange &LHS, const ConstantRange &RHS); - public: + +public: /// Initialize a full (the default) or empty set for the specified bit width. /// explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true); @@ -53,6 +58,16 @@ class ConstantRange { /// assert out if the two APInt's are not the same bit width. ConstantRange(const APInt& Lower, const APInt& Upper); + /// makeICmpRegion - Produce the smallest range that contains all values that + /// might satisfy the comparison specified by Pred when compared to any value + /// contained within Other. + /// + /// Solves for range X in 'for all x in X, there exists a y in Y such that + /// icmp op x, y is true'. Every value that might make the comparison true + /// is included in the resulting range. + static ConstantRange makeICmpRegion(unsigned Pred, + const ConstantRange &Other); + /// getLower - Return the lower value for this range... /// const APInt &getLower() const { return Lower; } @@ -83,6 +98,10 @@ class ConstantRange { /// bool contains(const APInt &Val) const; + /// contains - Return true if the other range is a subset of this one. + /// + bool contains(const ConstantRange &CR) const; + /// getSingleElement - If this set contains a single element, return it, /// otherwise return null. /// @@ -134,21 +153,13 @@ class ConstantRange { 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 + /// 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). + /// intersections with the same set size, A.intersectWith(B) might not + /// be equal to B.intersectWith(A). /// - ConstantRange maximalIntersectWith(const ConstantRange &CR) const; + ConstantRange intersectWith(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 @@ -176,6 +187,28 @@ class ConstantRange { /// truncated to the specified type. ConstantRange truncate(uint32_t BitWidth) const; + /// add - Return a new range representing the possible values resulting + /// from an addition of a value in this range and a value in Other. + ConstantRange add(const ConstantRange &Other) const; + + /// multiply - Return a new range representing the possible values resulting + /// from a multiplication of a value in this range and a value in Other. + /// TODO: This isn't fully implemented yet. + ConstantRange multiply(const ConstantRange &Other) const; + + /// smax - Return a new range representing the possible values resulting + /// from a signed maximum of a value in this range and a value in Other. + ConstantRange smax(const ConstantRange &Other) const; + + /// umax - Return a new range representing the possible values resulting + /// from an unsigned maximum of a value in this range and a value in Other. + ConstantRange umax(const ConstantRange &Other) const; + + /// udiv - Return a new range representing the possible values resulting + /// from an unsigned division of a value in this range and a value in Other. + /// TODO: This isn't fully implemented yet. + ConstantRange udiv(const ConstantRange &Other) const; + /// print - Print out the bounds to a stream... /// void print(raw_ostream &OS) const; diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index 4d6fcc8..ad210ed 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -1,22 +1,25 @@ -//===-- 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. -// -//===----------------------------------------------------------------------===// +/*===-- 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. *| +|* *| +|*===----------------------------------------------------------------------===*/ + +/* Please leave this file C-compatible. */ #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -24,18 +27,21 @@ #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 +#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T} +#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T} -// FIXME: UGLY HACK (Added by Kevin) -#define HAVE_UINT64_T 1 +#ifdef __cplusplus +#include <cmath> +#else +#include <math.h> +#endif #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). +/* 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 @@ -45,7 +51,7 @@ "#including Support/DataTypes.h" #endif -// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. +/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */ #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -58,17 +64,11 @@ #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 +/* 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; @@ -90,11 +90,16 @@ typedef u_int64_t uint64_t; #endif #else /* _MSC_VER */ -// Visual C++ doesn't provide standard integer headers, but it does provide -// built-in data types. +/* 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> +#ifdef __cplusplus +#include <cmath> +#else +#include <math.h> +#endif typedef __int64 int64_t; typedef unsigned __int64 uint64_t; typedef signed int int32_t; diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in index 72063f7..405f476 100644 --- a/include/llvm/Support/DataTypes.h.in +++ b/include/llvm/Support/DataTypes.h.in @@ -1,22 +1,25 @@ -//===-- 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. -// -//===----------------------------------------------------------------------===// +/*===-- 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. *| +|* *| +|*===----------------------------------------------------------------------===*/ + +/* Please leave this file C-compatible. */ #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -27,12 +30,18 @@ #undef HAVE_UINT64_T #undef HAVE_U_INT64_T +#ifdef __cplusplus +#include <cmath> +#else +#include <math.h> +#endif + #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). +/* 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 @@ -42,7 +51,7 @@ "#including Support/DataTypes.h" #endif -// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. +/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */ #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -55,17 +64,11 @@ #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 +/* 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; @@ -87,8 +90,8 @@ typedef u_int64_t uint64_t; #endif #else /* _MSC_VER */ -// Visual C++ doesn't provide standard integer headers, but it does provide -// built-in data types. +/* 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> diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index 52d0d3f..6f82ea7 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -18,61 +18,65 @@ // 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. +// When compiling without assertions, 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. // +#ifndef NDEBUG extern bool DebugFlag; +#endif // 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. // +#ifndef NDEBUG bool isCurrentDebugType(const char *Type); +#else +#define isCurrentDebugType(X) (false) +#endif + +// DEBUG_WITH_TYPE 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_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n"); +// +// This will emit the debug information if -debug is present, and -debug-only is +// not specified, or is specified as "bitset". + +#ifdef NDEBUG +#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0) +#else +#define DEBUG_WITH_TYPE(TYPE, X) \ + do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0) +#endif // 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"); +// DEBUG(errs() << "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 - +#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X) + } // End llvm namespace #endif diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index 5c089ef..55c3c4f 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -19,20 +19,25 @@ #include <vector> namespace llvm { - class GlobalVariable; + class MDNode; /// DebugLocTuple - Debug location tuple of filename id, line and column. /// struct DebugLocTuple { - GlobalVariable *CompileUnit; + MDNode *Scope; + MDNode *InlinedAtLoc; unsigned Line, Col; - DebugLocTuple(GlobalVariable *v, unsigned l, unsigned c) - : CompileUnit(v), Line(l), Col(c) {}; + DebugLocTuple() + : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {}; + + DebugLocTuple(MDNode *n, MDNode *i, unsigned l, unsigned c) + : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {}; bool operator==(const DebugLocTuple &DLT) const { - return CompileUnit == DLT.CompileUnit && - Line == DLT.Line && Col == DLT.Col; + return Scope == DLT.Scope && + InlinedAtLoc == DLT.InlinedAtLoc && + Line == DLT.Line && Col == DLT.Col; } bool operator!=(const DebugLocTuple &DLT) const { return !(*this == DLT); @@ -60,23 +65,25 @@ namespace llvm { bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } }; - // Partially specialize DenseMapInfo for DebugLocTyple. + // Specialize DenseMapInfo for DebugLocTuple. template<> struct DenseMapInfo<DebugLocTuple> { static inline DebugLocTuple getEmptyKey() { - return DebugLocTuple(0, ~0U, ~0U); + return DebugLocTuple(0, 0, ~0U, ~0U); } static inline DebugLocTuple getTombstoneKey() { - return DebugLocTuple((GlobalVariable*)~1U, ~1U, ~1U); + return DebugLocTuple((MDNode*)~1U, (MDNode*)~1U, ~1U, ~1U); } static unsigned getHashValue(const DebugLocTuple &Val) { - return DenseMapInfo<GlobalVariable*>::getHashValue(Val.CompileUnit) ^ + return DenseMapInfo<MDNode*>::getHashValue(Val.Scope) ^ + DenseMapInfo<MDNode*>::getHashValue(Val.InlinedAtLoc) ^ DenseMapInfo<unsigned>::getHashValue(Val.Line) ^ DenseMapInfo<unsigned>::getHashValue(Val.Col); } static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) { - return LHS.CompileUnit == RHS.CompileUnit && - LHS.Line == RHS.Line && - LHS.Col == RHS.Col; + return LHS.Scope == RHS.Scope && + LHS.InlinedAtLoc == RHS.InlinedAtLoc && + LHS.Line == RHS.Line && + LHS.Col == RHS.Col; } static bool isPod() { return true; } diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 55838b8..bfccc52 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -449,6 +449,7 @@ enum dwarf_constants { // Call frame instruction encodings DW_CFA_extended = 0x00, + DW_CFA_nop = 0x00, DW_CFA_advance_loc = 0x40, DW_CFA_offset = 0x80, DW_CFA_restore = 0xc0, diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h new file mode 100644 index 0000000..67bccf0 --- /dev/null +++ b/include/llvm/Support/ErrorHandling.h @@ -0,0 +1,87 @@ +//===- llvm/Support/ErrorHandling.h - Callbacks for errors ------*- 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 an API used to indicate error conditions. +// Callbacks can be registered for these errors through this API. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ERRORHANDLING_H +#define LLVM_SUPPORT_ERRORHANDLING_H + +#include "llvm/Support/Compiler.h" +#include <string> + +namespace llvm { + class Twine; + + /// An error handler callback. + typedef void (*llvm_error_handler_t)(void *user_data, + const std::string& reason); + + /// llvm_instal_error_handler - Installs a new error handler to be used + /// whenever a serious (non-recoverable) error is encountered by LLVM. + /// + /// If you are using llvm_start_multithreaded, you should register the handler + /// before doing that. + /// + /// If no error handler is installed the default is to print the error message + /// to stderr, and call exit(1). If an error handler is installed then it is + /// the handler's responsibility to log the message, it will no longer be + /// printed to stderr. If the error handler returns, then exit(1) will be + /// called. + /// + /// It is dangerous to naively use an error handler which throws an exception. + /// Even though some applications desire to gracefully recover from arbitrary + /// faults, blindly throwing exceptions through unfamiliar code isn't a way to + /// achieve this. + /// + /// \param user_data - An argument which will be passed to the install error + /// handler. + void llvm_install_error_handler(llvm_error_handler_t handler, + void *user_data = 0); + + /// Restores default error handling behaviour. + /// This must not be called between llvm_start_multithreaded() and + /// llvm_stop_multithreaded(). + void llvm_remove_error_handler(); + + /// Reports a serious error, calling any installed error handler. These + /// functions are intended to be used for error conditions which are outside + /// the control of the compiler (I/O errors, invalid user input, etc.) + /// + /// If no error handler is installed the default is to print the message to + /// standard error, followed by a newline. + /// After the error handler is called this function will call exit(1), it + /// does not return. + void llvm_report_error(const char *reason) NORETURN; + void llvm_report_error(const std::string &reason) NORETURN; + void llvm_report_error(const Twine &reason) NORETURN; + + /// This function calls abort(), and prints the optional message to stderr. + /// Use the llvm_unreachable macro (that adds location info), instead of + /// calling this function directly. + void llvm_unreachable_internal(const char *msg=0, const char *file=0, + unsigned line=0) NORETURN; +} + +/// Prints the message and location info to stderr in !NDEBUG builds. +/// This is intended to be used for "impossible" situations that imply +/// a bug in the compiler. +/// +/// In NDEBUG mode it only prints "UNREACHABLE executed". +/// Use this instead of assert(0), so that the compiler knows this path +/// is not reachable even for NDEBUG builds. +#ifndef NDEBUG +#define llvm_unreachable(msg) llvm_unreachable_internal(msg, __FILE__, __LINE__) +#else +#define llvm_unreachable(msg) llvm_unreachable_internal() +#endif + +#endif diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index 2ab097f..df03f66 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -36,6 +36,10 @@ class format_object_base { protected: const char *Fmt; virtual void home(); // Out of line virtual method. + + /// snprint - Call snprintf() for this object, on the given buffer and size. + virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; + public: format_object_base(const char *fmt) : Fmt(fmt) {} virtual ~format_object_base() {} @@ -43,7 +47,23 @@ public: /// 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; + unsigned print(char *Buffer, unsigned BufferSize) const { + assert(BufferSize && "Invalid buffer size!"); + + // Print the string, leaving room for the terminating null. + int N = snprint(Buffer, BufferSize); + + // VC++ and old GlibC return negative on overflow, just double the size. + if (N < 0) + return BufferSize*2; + + // Other impls yield number of bytes needed, not including the final '\0'. + if (unsigned(N) >= BufferSize) + return N+1; + + // Otherwise N is the length of output (not including the final '\0'). + return N; + } }; /// format_object1 - This is a templated helper class used by the format @@ -58,17 +78,8 @@ public: : 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; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val); } }; @@ -85,17 +96,8 @@ public: : 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; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); } }; @@ -113,17 +115,8 @@ public: : 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; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); } }; diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h new file mode 100644 index 0000000..24a3546 --- /dev/null +++ b/include/llvm/Support/FormattedStream.h @@ -0,0 +1,150 @@ +//===-- llvm/CodeGen/FormattedStream.h - Formatted 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 contains raw_ostream implementations for streams to do +// things like pretty-print comments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H +#define LLVM_SUPPORT_FORMATTEDSTREAM_H + +#include "llvm/Support/raw_ostream.h" + +namespace llvm +{ + /// formatted_raw_ostream - Formatted raw_fd_ostream to handle + /// asm-specific constructs. + /// + class formatted_raw_ostream : public raw_ostream { + public: + /// DELETE_STREAM - Tell the destructor to delete the held stream. + /// + static const bool DELETE_STREAM = true; + + /// PRESERVE_STREAM - Tell the destructor to not delete the held + /// stream. + /// + static const bool PRESERVE_STREAM = false; + + private: + /// TheStream - The real stream we output to. We set it to be + /// unbuffered, since we're already doing our own buffering. + /// + raw_ostream *TheStream; + + /// DeleteStream - Do we need to delete TheStream in the + /// destructor? + /// + bool DeleteStream; + + /// ColumnScanned - The current output column of the data that's + /// been flushed and the portion of the buffer that's been + /// scanned. The column scheme is zero-based. + /// + unsigned ColumnScanned; + + /// Scanned - This points to one past the last character in the + /// buffer we've scanned. + /// + const char *Scanned; + + virtual void write_impl(const char *Ptr, size_t Size); + + /// current_pos - Return the current position within the stream, + /// not counting the bytes currently in the buffer. + virtual uint64_t current_pos() { + // This has the same effect as calling TheStream.current_pos(), + // but that interface is private. + return TheStream->tell() - TheStream->GetNumBytesInBuffer(); + } + + /// ComputeColumn - Examine the given output buffer and figure out which + /// column we end up in after output. + /// + void ComputeColumn(const char *Ptr, size_t size); + + public: + /// formatted_raw_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. + /// + /// As a side effect, the given Stream is set to be Unbuffered. + /// This is because formatted_raw_ostream does its own buffering, + /// so it doesn't want another layer of buffering to be happening + /// underneath it. + /// + formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) + : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + setStream(Stream, Delete); + } + explicit formatted_raw_ostream() + : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + Scanned = 0; + } + + ~formatted_raw_ostream() { + flush(); + releaseStream(); + } + + void setStream(raw_ostream &Stream, bool Delete = false) { + releaseStream(); + + TheStream = &Stream; + DeleteStream = Delete; + + // This formatted_raw_ostream inherits from raw_ostream, so it'll do its + // own buffering, and it doesn't need or want TheStream to do another + // layer of buffering underneath. Resize the buffer to what TheStream + // had been using, and tell TheStream not to do its own buffering. + if (size_t BufferSize = TheStream->GetBufferSize()) + SetBufferSize(BufferSize); + else + SetUnbuffered(); + TheStream->SetUnbuffered(); + + Scanned = 0; + } + + /// PadToColumn - Align the output to some column number. If the current + /// column is already equal to or more than NewCol, PadToColumn inserts one + /// space. + /// + /// \param NewCol - The column to move to. + void PadToColumn(unsigned NewCol); + + private: + void releaseStream() { + // Delete the stream if needed. Otherwise, transfer the buffer + // settings from this raw_ostream back to the underlying stream. + if (!TheStream) + return; + if (DeleteStream) + delete TheStream; + else if (size_t BufferSize = GetBufferSize()) + TheStream->SetBufferSize(BufferSize); + else + TheStream->SetUnbuffered(); + } + }; + +/// fouts() - This returns a reference to a formatted_raw_ostream for +/// standard output. Use it like: fouts() << "foo" << "bar"; +formatted_raw_ostream &fouts(); + +/// ferrs() - This returns a reference to a formatted_raw_ostream for +/// standard error. Use it like: ferrs() << "foo" << "bar"; +formatted_raw_ostream &ferrs(); + +} // end llvm namespace + + +#endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h index e1cda75..f5915c9 100644 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/include/llvm/Support/GetElementPtrTypeIterator.h @@ -21,8 +21,9 @@ 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; + : public std::iterator<std::forward_iterator_tag, const Type *, ptrdiff_t> { + typedef std::iterator<std::forward_iterator_tag, + const Type *, ptrdiff_t> super; ItTy OpIt; const Type *CurTy; diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 01b44d0..bd3fcea 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -24,53 +24,33 @@ #define LLVM_SUPPORT_GRAPHWRITER_H #include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/System/Path.h" -#include <fstream> #include <vector> +#include <cassert> 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; - } + std::string EscapeString(const std::string &Label); +} + +namespace GraphProgram { + enum Name { + DOT, + FDP, + NEATO, + TWOPI, + CIRCO + }; } -void DisplayGraph(const sys::Path& Filename); +void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT); template<typename GraphType> class GraphWriter { - std::ostream &O; + raw_ostream &O; const GraphType &G; bool ShortNames; @@ -80,7 +60,7 @@ class GraphWriter { typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; public: - GraphWriter(std::ostream &o, const GraphType &g, bool SN) : + GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g), ShortNames(SN) {} void writeHeader(const std::string &Name) { @@ -222,7 +202,7 @@ public: for (unsigned i = 0; i != NumEdgeSources; ++i) { if (i) O << "|"; - O << "<g" << i << ">"; + O << "<s" << i << ">"; if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i]; } O << "}}"; @@ -241,8 +221,12 @@ public: if (SrcNodePort >= 0) O << ":s" << SrcNodePort; O << " -> Node" << DestNodeID; - if (DestNodePort >= 0) - O << ":d" << DestNodePort; + if (DestNodePort >= 0) { + if (DOTTraits::hasEdgeDestLabels()) + O << ":d" << DestNodePort; + else + O << ":s" << DestNodePort; + } if (!Attrs.empty()) O << "[" << Attrs << "]"; @@ -251,10 +235,10 @@ public: }; template<typename GraphType> -std::ostream &WriteGraph(std::ostream &O, const GraphType &G, - bool ShortNames = false, - const std::string &Name = "", - const std::string &Title = "") { +raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G, + bool ShortNames = false, + const std::string &Name = "", + const std::string &Title = "") { // Start the graph emission process... GraphWriter<GraphType> W(O, G, ShortNames); @@ -273,33 +257,30 @@ std::ostream &WriteGraph(std::ostream &O, const GraphType &G, } template<typename GraphType> -sys::Path WriteGraph(const GraphType &G, - const std::string& Name, - bool ShortNames = false, - const std::string& Title = "") { +sys::Path WriteGraph(const GraphType &G, const std::string &Name, + bool ShortNames = false, const std::string &Title = "") { std::string ErrMsg; sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg); if (Filename.isEmpty()) { - cerr << "Error: " << ErrMsg << "\n"; + errs() << "Error: " << ErrMsg << "\n"; return Filename; } Filename.appendComponent(Name + ".dot"); if (Filename.makeUnique(true,&ErrMsg)) { - cerr << "Error: " << ErrMsg << "\n"; + errs() << "Error: " << ErrMsg << "\n"; return sys::Path(); } - cerr << "Writing '" << Filename << "'... "; + errs() << "Writing '" << Filename.str() << "'... "; - std::ofstream O(Filename.c_str()); + std::string ErrorInfo; + raw_fd_ostream O(Filename.c_str(), ErrorInfo); - if (O.good()) { + if (ErrorInfo.empty()) { WriteGraph(O, G, ShortNames, Name, Title); - cerr << " done. \n"; - - O.close(); + errs() << " done. \n"; } else { - cerr << "error opening file for writing!\n"; + errs() << "error opening file '" << Filename.str() << "' for writing!\n"; Filename.clear(); } @@ -310,17 +291,15 @@ sys::Path WriteGraph(const GraphType &G, /// then cleanup. For use from the debugger. /// template<typename GraphType> -void ViewGraph(const GraphType& G, - const std::string& Name, - bool ShortNames = false, - const std::string& Title = "") { - sys::Path Filename = WriteGraph(G, Name, ShortNames, Title); +void ViewGraph(const GraphType &G, const std::string &Name, + bool ShortNames = false, const std::string &Title = "", + GraphProgram::Name Program = GraphProgram::DOT) { + sys::Path Filename = WriteGraph(G, Name, ShortNames, Title); - if (Filename.isEmpty()) { + if (Filename.isEmpty()) return; - } - DisplayGraph(Filename); + DisplayGraph(Filename, true, Program); } } // End llvm namespace diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index ed6a3f1..1f65978 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -20,37 +20,86 @@ #include "llvm/GlobalAlias.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" +#include "llvm/Metadata.h" +#include "llvm/LLVMContext.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/ConstantFolder.h" namespace llvm { +/// IRBuilderDefaultInserter - This provides the default implementation of the +/// IRBuilder 'InsertHelper' method that is called whenever an instruction is +/// created by IRBuilder and needs to be inserted. By default, this inserts the +/// instruction at the insertion point. +template <bool preserveNames = true> +class IRBuilderDefaultInserter { +protected: + void InsertHelper(Instruction *I, const Twine &Name, + BasicBlock *BB, BasicBlock::iterator InsertPt) const { + if (BB) BB->getInstList().insert(InsertPt, I); + if (preserveNames) + I->setName(Name); + } +}; + + /// 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 +/// instructions. 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{ +/// minimally folded constants. The fourth template argument allows clients to +/// specify custom insertion hooks that are called on every newly created +/// insertion. +template<bool preserveNames = true, typename T = ConstantFolder, + typename Inserter = IRBuilderDefaultInserter<preserveNames> > +class IRBuilder : public Inserter { BasicBlock *BB; BasicBlock::iterator InsertPt; + unsigned MDKind; + MDNode *CurDbgLocation; + LLVMContext &Context; 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); } + IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) + : Inserter(I), MDKind(0), CurDbgLocation(0), Context(C), Folder(F) { + ClearInsertionPoint(); + } + + explicit IRBuilder(LLVMContext &C) + : MDKind(0), CurDbgLocation(0), Context(C), Folder(C) { + ClearInsertionPoint(); + } + + explicit IRBuilder(BasicBlock *TheBB, const T &F) + : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB); + } + + explicit IRBuilder(BasicBlock *TheBB) + : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), + Folder(Context) { + SetInsertPoint(TheBB); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) + : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB, IP); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) + : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), + Folder(Context) { + SetInsertPoint(TheBB, IP); + } /// getFolder - Get the constant folder being used. - const T& getFolder() { return Folder; } + const T &getFolder() { return Folder; } /// isNamePreserving - Return true if this builder is configured to actually /// add the requested names to IR created through it. @@ -84,20 +133,75 @@ public: InsertPt = IP; } + /// SetCurrentDebugLocation - Set location information used by debugging + /// information. + void SetCurrentDebugLocation(MDNode *L) { + if (MDKind == 0) + MDKind = Context.getMetadata().getMDKind("dbg"); + if (MDKind == 0) + MDKind = Context.getMetadata().RegisterMDKind("dbg"); + CurDbgLocation = L; + } + + MDNode *getCurrentDebugLocation() const { return CurDbgLocation; } + + /// SetDebugLocation - Set location information for the given instruction. + void SetDebugLocation(Instruction *I) { + if (CurDbgLocation) + Context.getMetadata().addMD(MDKind, CurDbgLocation, I); + } + /// Insert - Insert and return the specified instruction. template<typename InstTy> - InstTy *Insert(InstTy *I, const char *Name = "") const { - InsertHelper(I, Name); + InstTy *Insert(InstTy *I, const Twine &Name = "") const { + this->InsertHelper(I, Name, BB, InsertPt); + if (CurDbgLocation) + Context.getMetadata().addMD(MDKind, CurDbgLocation, I); 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); + //===--------------------------------------------------------------------===// + // Type creation methods + //===--------------------------------------------------------------------===// + + /// getInt1Ty - Fetch the type representing a single bit + const Type *getInt1Ty() { + return Type::getInt1Ty(Context); + } + + /// getInt8Ty - Fetch the type representing an 8-bit integer. + const Type *getInt8Ty() { + return Type::getInt8Ty(Context); + } + + /// getInt16Ty - Fetch the type representing a 16-bit integer. + const Type *getInt16Ty() { + return Type::getInt16Ty(Context); + } + + /// getInt32Ty - Fetch the type resepresenting a 32-bit integer. + const Type *getInt32Ty() { + return Type::getInt32Ty(Context); + } + + /// getInt64Ty - Fetch the type representing a 64-bit integer. + const Type *getInt64Ty() { + return Type::getInt64Ty(Context); + } + + /// getFloatTy - Fetch the type representing a 32-bit floating point value. + const Type *getFloatTy() { + return Type::getFloatTy(Context); + } + + /// getDoubleTy - Fetch the type representing a 64-bit floating point value. + const Type *getDoubleTy() { + return Type::getDoubleTy(Context); + } + + /// getVoidTy - Fetch the type representing void. + const Type *getVoidTy() { + return Type::getVoidTy(Context); } //===--------------------------------------------------------------------===// @@ -106,14 +210,14 @@ public: /// CreateRetVoid - Create a 'ret void' instruction. ReturnInst *CreateRetVoid() { - return Insert(ReturnInst::Create()); + return Insert(ReturnInst::Create(Context)); } /// @verbatim /// CreateRet - Create a 'ret <val>' instruction. /// @endverbatim ReturnInst *CreateRet(Value *V) { - return Insert(ReturnInst::Create(V)); + return Insert(ReturnInst::Create(Context, V)); } /// CreateAggregateRet - Create a sequence of N insertvalue instructions, @@ -128,7 +232,7 @@ public: Value *V = UndefValue::get(RetType); for (unsigned i = 0; i != N; ++i) V = CreateInsertValue(V, retVals[i], i, "mrv"); - return Insert(ReturnInst::Create(V)); + return Insert(ReturnInst::Create(Context, V)); } /// CreateBr - Create an unconditional 'br label X' instruction. @@ -153,126 +257,144 @@ public: template<typename InputIterator> InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, InputIterator ArgBegin, - InputIterator ArgEnd, const char *Name = "") { + InputIterator ArgEnd, const Twine &Name = "") { return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, ArgBegin, ArgEnd), Name); } UnwindInst *CreateUnwind() { - return Insert(new UnwindInst()); + return Insert(new UnwindInst(Context)); } UnreachableInst *CreateUnreachable() { - return Insert(new UnreachableInst()); + return Insert(new UnreachableInst(Context)); } //===--------------------------------------------------------------------===// // Instruction creation methods: Binary Operators //===--------------------------------------------------------------------===// - Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateAdd(Value *LHS, Value *RHS, const Twine &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 *CreateFAdd(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNSWAdd(LC, RC); + return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name); + } + Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateFAdd(LC, RC); return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name); } - Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateSub(Value *LHS, Value *RHS, const Twine &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 *CreateFSub(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNSWSub(LC, RC); + return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name); + } + Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateFSub(LC, RC); return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name); } - Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateMul(Value *LHS, Value *RHS, const Twine &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 *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateFMul(LC, RC); return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name); } - Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateExactSDiv(LC, RC); + return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); + } + Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateURem(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateSRem(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateFRem(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateShl(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateLShr(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateAShr(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateAnd(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateOr(Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Folder.CreateXor(LC, RC); @@ -280,24 +402,24 @@ public: } Value *CreateBinOp(Instruction::BinaryOps Opc, - Value *LHS, Value *RHS, const char *Name = "") { + Value *LHS, Value *RHS, const Twine &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 = "") { + Value *CreateNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) return Folder.CreateNeg(VC); return Insert(BinaryOperator::CreateNeg(V), Name); } - Value *CreateFNeg(Value *V, const char *Name = "") { + Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) return Folder.CreateFNeg(VC); return Insert(BinaryOperator::CreateFNeg(V), Name); } - Value *CreateNot(Value *V, const char *Name = "") { + Value *CreateNot(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) return Folder.CreateNot(VC); return Insert(BinaryOperator::CreateNot(V), Name); @@ -308,20 +430,25 @@ public: //===--------------------------------------------------------------------===// MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0, - const char *Name = "") { + const Twine &Name = "") { return Insert(new MallocInst(Ty, ArraySize), Name); } AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0, - const char *Name = "") { + const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } FreeInst *CreateFree(Value *Ptr) { return Insert(new FreeInst(Ptr)); } - LoadInst *CreateLoad(Value *Ptr, const char *Name = "") { + // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of + // converting the string to 'bool' for the isVolatile parameter. + LoadInst *CreateLoad(Value *Ptr, const char *Name) { + return Insert(new LoadInst(Ptr), Name); + } + LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { return Insert(new LoadInst(Ptr), Name); } - LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = "") { + LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") { return Insert(new LoadInst(Ptr, 0, isVolatile), Name); } StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { @@ -329,38 +456,69 @@ public: } template<typename InputIterator> Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - const char *Name = "") { + const Twine &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)) + for (i = IdxBegin; i < IdxEnd; ++i) + if (!isa<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 = "") { + template<typename InputIterator> + Value *CreateInBoundsGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, + const Twine &Name = "") { + if (Constant *PC = dyn_cast<Constant>(Ptr)) { + // Every index must be constant. + InputIterator i; + for (i = IdxBegin; i < IdxEnd; ++i) + if (!isa<Constant>(*i)) + break; + if (i == IdxEnd) + return Folder.CreateInBoundsGetElementPtr(PC, + &IdxBegin[0], + IdxEnd - IdxBegin); + } + return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd), + Name); + } + Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &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); + Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { + if (Constant *PC = dyn_cast<Constant>(Ptr)) + if (Constant *IC = dyn_cast<Constant>(Idx)) + return Folder.CreateInBoundsGetElementPtr(PC, &IC, 1); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); + } + Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { + Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); if (Constant *PC = dyn_cast<Constant>(Ptr)) return Folder.CreateGetElementPtr(PC, &Idx, 1); return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name); } + Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0, + const Twine &Name = "") { + Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); + + if (Constant *PC = dyn_cast<Constant>(Ptr)) + return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1); + + return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + } Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, - const char *Name = "") { + const Twine &Name = "") { Value *Idxs[] = { - ConstantInt::get(Type::Int32Ty, Idx0), - ConstantInt::get(Type::Int32Ty, Idx1) + ConstantInt::get(Type::getInt32Ty(Context), Idx0), + ConstantInt::get(Type::getInt32Ty(Context), Idx1) }; if (Constant *PC = dyn_cast<Constant>(Ptr)) @@ -368,19 +526,40 @@ public: 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); + Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, + const Twine &Name = "") { + Value *Idxs[] = { + ConstantInt::get(Type::getInt32Ty(Context), Idx0), + ConstantInt::get(Type::getInt32Ty(Context), Idx1) + }; + + if (Constant *PC = dyn_cast<Constant>(Ptr)) + return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2); + + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name); + } + Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { + Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), 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 *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0, + const Twine &Name = "") { + Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); + + if (Constant *PC = dyn_cast<Constant>(Ptr)) + return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1); + + return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + } + Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, + const Twine &Name = "") { Value *Idxs[] = { - ConstantInt::get(Type::Int64Ty, Idx0), - ConstantInt::get(Type::Int64Ty, Idx1) + ConstantInt::get(Type::getInt64Ty(Context), Idx0), + ConstantInt::get(Type::getInt64Ty(Context), Idx1) }; if (Constant *PC = dyn_cast<Constant>(Ptr)) @@ -388,235 +567,272 @@ public: 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 *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, + const Twine &Name = "") { + Value *Idxs[] = { + ConstantInt::get(Type::getInt64Ty(Context), Idx0), + ConstantInt::get(Type::getInt64Ty(Context), Idx1) + }; + + if (Constant *PC = dyn_cast<Constant>(Ptr)) + return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2); + + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name); + } + Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { + return CreateConstInBoundsGEP2_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(), + Value *CreateGlobalString(const char *Str = "", const Twine &Name = "") { + Constant *StrConstant = ConstantArray::get(Context, Str, true); + Module &M = *BB->getParent()->getParent(); + GlobalVariable *gv = new GlobalVariable(M, + StrConstant->getType(), true, GlobalValue::InternalLinkage, StrConstant, "", - BB->getParent()->getParent(), + 0, false); gv->setName(Name); return gv; } - Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") { + Value *CreateGlobalStringPtr(const char *Str = "", const Twine &Name = "") { Value *gv = CreateGlobalString(Str, Name); - Value *zero = ConstantInt::get(Type::Int32Ty, 0); + Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; - return CreateGEP(gv, Args, Args+2, Name); + return CreateInBoundsGEP(gv, Args, Args+2, Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// - Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") { + Value *CreateTrunc(Value *V, const Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::Trunc, V, DestTy, Name); } - Value *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") { + Value *CreateZExt(Value *V, const Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::ZExt, V, DestTy, Name); } - Value *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") { + Value *CreateSExt(Value *V, const Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } - Value *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){ + Value *CreateFPToUI(Value *V, const Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToUI, V, DestTy, Name); } - Value *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){ + Value *CreateFPToSI(Value *V, const Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToSI, V, DestTy, Name); } - Value *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){ + Value *CreateUIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::UIToFP, V, DestTy, Name); } - Value *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){ + Value *CreateSIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::SIToFP, V, DestTy, Name); } Value *CreateFPTrunc(Value *V, const Type *DestTy, - const char *Name = "") { + const Twine &Name = "") { return CreateCast(Instruction::FPTrunc, V, DestTy, Name); } - Value *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") { + Value *CreateFPExt(Value *V, const Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPExt, V, DestTy, Name); } Value *CreatePtrToInt(Value *V, const Type *DestTy, - const char *Name = "") { + const Twine &Name = "") { return CreateCast(Instruction::PtrToInt, V, DestTy, Name); } Value *CreateIntToPtr(Value *V, const Type *DestTy, - const char *Name = "") { + const Twine &Name = "") { return CreateCast(Instruction::IntToPtr, V, DestTy, Name); } Value *CreateBitCast(Value *V, const Type *DestTy, - const char *Name = "") { + const Twine &Name = "") { return CreateCast(Instruction::BitCast, V, DestTy, Name); } - + Value *CreateZExtOrBitCast(Value *V, const Type *DestTy, + const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateZExtOrBitCast(VC, DestTy); + return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name); + } + Value *CreateSExtOrBitCast(Value *V, const Type *DestTy, + const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateSExtOrBitCast(VC, DestTy); + return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name); + } + Value *CreateTruncOrBitCast(Value *V, const Type *DestTy, + const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateTruncOrBitCast(VC, DestTy); + return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name); + } Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy, - const char *Name = "") { + const Twine &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 *CreatePointerCast(Value *V, const Type *DestTy, + const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreatePointerCast(VC, DestTy); + return Insert(CastInst::CreatePointerCast(V, DestTy), Name); + } Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned, - const char *Name = "") { + const Twine &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); } + Value *CreateFPCast(Value *V, const Type *DestTy, const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateFPCast(VC, DestTy); + return Insert(CastInst::CreateFPCast(V, DestTy), Name); + } //===--------------------------------------------------------------------===// // Instruction creation methods: Compare Instructions //===--------------------------------------------------------------------===// - Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name); } - Value *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name); } - Value *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name); } - Value *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name); } - Value *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name); } - Value *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name); } - Value *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name); } - Value *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name); } - Value *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name); } - Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); } - Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name); } - Value *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name); } - Value *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name); } - Value *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name); } - Value *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name); } - Value *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name); } - Value *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name); } - Value *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name); } - Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name); } - Value *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name); } - Value *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name); } - Value *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name); } - Value *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name); } - Value *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name); } Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, - const char *Name = "") { + const Twine &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 = "") { + const Twine &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 = "") { + PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") { return Insert(PHINode::Create(Ty), Name); } - CallInst *CreateCall(Value *Callee, const char *Name = "") { + CallInst *CreateCall(Value *Callee, const Twine &Name = "") { return Insert(CallInst::Create(Callee), Name); } - CallInst *CreateCall(Value *Callee, Value *Arg, const char *Name = "") { + CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") { return Insert(CallInst::Create(Callee, Arg), Name); } CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2, - const char *Name = "") { + const Twine &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 = "") { + const Twine &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 *Arg4, const Twine &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 = "") { + InputIterator ArgEnd, const Twine &Name = "") { return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name); } Value *CreateSelect(Value *C, Value *True, Value *False, - const char *Name = "") { + const Twine &Name = "") { if (Constant *CC = dyn_cast<Constant>(C)) if (Constant *TC = dyn_cast<Constant>(True)) if (Constant *FC = dyn_cast<Constant>(False)) @@ -624,20 +840,20 @@ public: return Insert(SelectInst::Create(C, True, False), Name); } - VAArgInst *CreateVAArg(Value *List, const Type *Ty, const char *Name = "") { + VAArgInst *CreateVAArg(Value *List, const Type *Ty, const Twine &Name = "") { return Insert(new VAArgInst(List, Ty), Name); } Value *CreateExtractElement(Value *Vec, Value *Idx, - const char *Name = "") { + const Twine &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); + return Insert(ExtractElementInst::Create(Vec, Idx), Name); } Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, - const char *Name = "") { + const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(Vec)) if (Constant *NC = dyn_cast<Constant>(NewElt)) if (Constant *IC = dyn_cast<Constant>(Idx)) @@ -646,7 +862,7 @@ public: } Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask, - const char *Name = "") { + const Twine &Name = "") { if (Constant *V1C = dyn_cast<Constant>(V1)) if (Constant *V2C = dyn_cast<Constant>(V2)) if (Constant *MC = dyn_cast<Constant>(Mask)) @@ -655,7 +871,7 @@ public: } Value *CreateExtractValue(Value *Agg, unsigned Idx, - const char *Name = "") { + const Twine &Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) return Folder.CreateExtractValue(AggC, &Idx, 1); return Insert(ExtractValueInst::Create(Agg, Idx), Name); @@ -665,14 +881,14 @@ public: Value *CreateExtractValue(Value *Agg, InputIterator IdxBegin, InputIterator IdxEnd, - const char *Name = "") { + const Twine &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 = "") { + const Twine &Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) if (Constant *ValC = dyn_cast<Constant>(Val)) return Folder.CreateInsertValue(AggC, ValC, &Idx, 1); @@ -683,11 +899,10 @@ public: Value *CreateInsertValue(Value *Agg, Value *Val, InputIterator IdxBegin, InputIterator IdxEnd, - const char *Name = "") { + const Twine &Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) if (Constant *ValC = dyn_cast<Constant>(Val)) - return Folder.CreateInsertValue(AggC, ValC, - IdxBegin, IdxEnd - IdxBegin); + return Folder.CreateInsertValue(AggC, ValC, IdxBegin, IdxEnd-IdxBegin); return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name); } @@ -696,30 +911,32 @@ public: //===--------------------------------------------------------------------===// /// CreateIsNull - Return an i1 value testing if \arg Arg is null. - Value *CreateIsNull(Value *Arg, const char *Name = "") { + Value *CreateIsNull(Value *Arg, const Twine &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 = "") { + Value *CreateIsNotNull(Value *Arg, const Twine &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 = "") { + /// implement C-style pointer subtraction. As such, the pointers must be + /// appropriately aligned for their element types and pointing into the + /// same object. + Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &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 *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); + Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); Value *Difference = CreateSub(LHS_int, RHS_int); - return CreateSDiv(Difference, - ConstantExpr::getSizeOf(ArgType->getElementType()), - Name); + return CreateExactSDiv(Difference, + ConstantExpr::getSizeOf(ArgType->getElementType()), + Name); } }; diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h new file mode 100644 index 0000000..e7780b0 --- /dev/null +++ b/include/llvm/Support/IRReader.h @@ -0,0 +1,115 @@ +//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- 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 functions for reading LLVM IR. They support both +// Bitcode and Assembly, automatically detecting the input format. +// +// These functions must be defined in a header file in order to avoid +// library dependencies, since they reference both Bitcode and Assembly +// functions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_IRREADER_H +#define LLVM_SUPPORT_IRREADER_H + +#include "llvm/Assembly/Parser.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/ModuleProvider.h" + +namespace llvm { + + /// If the given MemoryBuffer holds a bitcode image, return a ModuleProvider + /// for it which does lazy deserialization of function bodies. Otherwise, + /// attempt to parse it as LLVM Assembly and return a fully populated + /// ModuleProvider. This function *always* takes ownership of the given + /// MemoryBuffer. + inline ModuleProvider *getIRModuleProvider(MemoryBuffer *Buffer, + SMDiagnostic &Err, + LLVMContext &Context) { + if (isBitcode((const unsigned char *)Buffer->getBufferStart(), + (const unsigned char *)Buffer->getBufferEnd())) { + std::string ErrMsg; + ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, &ErrMsg); + if (MP == 0) { + Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, ""); + // ParseBitcodeFile does not take ownership of the Buffer in the + // case of an error. + delete Buffer; + } + return MP; + } + + Module *M = ParseAssembly(Buffer, 0, Err, Context); + if (M == 0) + return 0; + return new ExistingModuleProvider(M); + } + + /// If the given file holds a bitcode image, return a ModuleProvider + /// for it which does lazy deserialization of function bodies. Otherwise, + /// attempt to parse it as LLVM Assembly and return a fully populated + /// ModuleProvider. + inline ModuleProvider *getIRFileModuleProvider(const std::string &Filename, + SMDiagnostic &Err, + LLVMContext &Context) { + std::string ErrMsg; + MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); + if (F == 0) { + Err = SMDiagnostic(Filename, -1, -1, + "Could not open input file '" + Filename + "'", ""); + return 0; + } + + return getIRModuleProvider(F, Err, Context); + } + + /// If the given MemoryBuffer holds a bitcode image, return a Module + /// for it. Otherwise, attempt to parse it as LLVM Assembly and return + /// a Module for it. This function *always* takes ownership of the given + /// MemoryBuffer. + inline Module *ParseIR(MemoryBuffer *Buffer, + SMDiagnostic &Err, + LLVMContext &Context) { + if (isBitcode((const unsigned char *)Buffer->getBufferStart(), + (const unsigned char *)Buffer->getBufferEnd())) { + std::string ErrMsg; + Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg); + // ParseBitcodeFile does not take ownership of the Buffer. + delete Buffer; + if (M == 0) + Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, ""); + return M; + } + + return ParseAssembly(Buffer, 0, Err, Context); + } + + /// If the given file holds a bitcode image, return a Module for it. + /// Otherwise, attempt to parse it as LLVM Assembly and return a Module + /// for it. + inline Module *ParseIRFile(const std::string &Filename, + SMDiagnostic &Err, + LLVMContext &Context) { + std::string ErrMsg; + MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); + if (F == 0) { + Err = SMDiagnostic(Filename, -1, -1, + "Could not open input file '" + Filename + "'", ""); + return 0; + } + + return ParseIR(F, Err, Context); + } + +} + +#endif diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 597cc9d..5d7c2f7 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -14,6 +14,7 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -30,13 +31,13 @@ namespace llvm { /// @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). +/// Instruction visitors are used when you want to perform different actions +/// for different kinds of instructions 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 +/// functions in your class. I say "override" 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 @@ -58,12 +59,12 @@ namespace llvm { /// NumMallocs = CMV.Count; /// /// The defined has 'visit' methods for Instruction, and also for BasicBlock, -/// Function, and Module, which recursively process all conained instructions. +/// Function, and Module, which recursively process all contained 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. +/// supported, if you handle one of their superclasses. /// /// The optional second template argument specifies the type that instruction /// visitation functions should return. If you specify this, you *MUST* provide @@ -113,8 +114,7 @@ public: // RetTy visit(Instruction &I) { switch (I.getOpcode()) { - default: assert(0 && "Unknown instruction type encountered!"); - abort(); + default: llvm_unreachable("Unknown instruction type encountered!"); // Build the switch statement using the Instruction.def file... #define HANDLE_INST(NUM, OPCODE, CLASS) \ case Instruction::OPCODE: return \ @@ -165,8 +165,6 @@ public: 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); } @@ -195,7 +193,7 @@ public: RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } - // Next level propagators... if the user does not overload a specific + // 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... // @@ -206,7 +204,7 @@ public: 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 + // function. If this function is not overloaded in the user's subclass, then // this instruction just gets ignored. // // Note that you MUST override this function if your return type is not void. diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h index 8d74ac6..7dbfdbf 100644 --- a/include/llvm/Support/LeakDetector.h +++ b/include/llvm/Support/LeakDetector.h @@ -56,9 +56,9 @@ struct LeakDetector { /// The specified message will be printed indicating when the check was /// performed. /// - static void checkForGarbage(const std::string &Message) { + static void checkForGarbage(LLVMContext &C, const std::string &Message) { #ifndef NDEBUG - checkForGarbageImpl(Message); + checkForGarbageImpl(C, Message); #endif } @@ -83,7 +83,7 @@ private: static void removeGarbageObjectImpl(const Value *Object); static void addGarbageObjectImpl(void *Object); static void removeGarbageObjectImpl(void *Object); - static void checkForGarbageImpl(const std::string &Message); + static void checkForGarbageImpl(LLVMContext &C, const std::string &Message); }; } // End llvm namespace diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h index 4fc6483..b8e2235 100644 --- a/include/llvm/Support/ManagedStatic.h +++ b/include/llvm/Support/ManagedStatic.h @@ -27,10 +27,12 @@ void* object_creator() { /// object_deleter - Helper method for ManagedStatic. /// -template<class C> -void object_deleter(void *Ptr) { - delete (C*)Ptr; -} +template<typename T> struct object_deleter { + static void call(void * Ptr) { delete (T*)Ptr; } +}; +template<typename T, size_t N> struct object_deleter<T[N]> { + static void call(void * Ptr) { delete[] (T*)Ptr; } +}; /// ManagedStaticBase - Common base class for ManagedStatic instances. class ManagedStaticBase { @@ -62,28 +64,28 @@ public: C &operator*() { void* tmp = Ptr; if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); return *static_cast<C*>(Ptr); } C *operator->() { void* tmp = Ptr; if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); return static_cast<C*>(Ptr); } const C &operator*() const { void* tmp = Ptr; if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); return *static_cast<C*>(Ptr); } const C *operator->() const { void* tmp = Ptr; if (llvm_is_multithreaded()) sys::MemoryFence(); - if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>); + if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); return static_cast<C*>(Ptr); } diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h index 8f672bd..03c5648 100644 --- a/include/llvm/Support/Mangler.h +++ b/include/llvm/Support/Mangler.h @@ -23,8 +23,17 @@ class Type; class Module; class Value; class GlobalValue; +template <typename T> class SmallVectorImpl; class Mangler { +public: + enum ManglerPrefixTy { + Default, ///< Emit default string before each symbol. + Private, ///< Emit "private" prefix before each symbol. + LinkerPrivate ///< Emit "linker private" prefix before each symbol. + }; + +private: /// Prefix - This string is added to each symbol that is emitted, unless the /// symbol is marked as not needing this prefix. const char *Prefix; @@ -33,48 +42,50 @@ class Mangler { /// linkage. const char *PrivatePrefix; + /// LinkerPrivatePrefix - This string is emitted before each symbol with + /// "linker_private" linkage. + const char *LinkerPrivatePrefix; + /// 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; + /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to + /// start with digits (e.g., "0x0021"). By default, this is false. + bool SymbolsCanStartWithDigit; - /// Memo - This is used to remember the name that we assign a value. + /// AnonGlobalIDs - We need to give global values the same name every time + /// they are mangled. This keeps track of the number we give to anonymous + /// ones. /// - DenseMap<const Value*, std::string> Memo; + DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs; - /// Count - This simple counter is used to unique value names. + /// NextAnonGlobalID - 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; + unsigned NextAnonGlobalID; /// AcceptableChars - This bitfield contains a one for each character that is /// allowed to be part of an unmangled name. - unsigned AcceptableChars[256/32]; -public: + 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 = ""); + Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "", + const char *linkerPrivatePrefix = ""); /// 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; } + /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true, + /// this target allows symbols to start with digits. + void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = 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. + /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'. void markCharAcceptable(unsigned char X) { AcceptableChars[X/32] |= 1 << (X&31); } @@ -85,11 +96,13 @@ public: return (AcceptableChars[X/32] & (1 << (X&31))) != 0; } - /// getValueName - Returns the mangled name of V, an LLVM Value, - /// in the current module. + /// getMangledName - Returns the mangled name of V, an LLVM Value, + /// in the current module. If 'Suffix' is specified, the name ends with the + /// specified suffix. If 'ForcePrivate' is specified, the label is specified + /// to have a private label prefix. /// - std::string getValueName(const GlobalValue *V, const char *Suffix = ""); - std::string getValueName(const Value *V); + std::string getMangledName(const GlobalValue *V, const char *Suffix = "", + bool ForcePrivate = false); /// makeNameProper - We don't want identifier names with ., space, or /// - in them, so we mangle these characters into the strings "d_", @@ -98,13 +111,14 @@ public: /// 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); + std::string makeNameProper(const std::string &x, + ManglerPrefixTy PrefixTy = Mangler::Default); + + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix + /// and the specified global variable's name. If the global variable doesn't + /// have a name, this fills in a unique name for the global. + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + bool isImplicitlyPrivate); }; } // End llvm namespace diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 85e19ac..6fa618e 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -52,6 +52,16 @@ inline bool isUInt32(int64_t Value) { return static_cast<uint32_t>(Value) == Value; } +template<unsigned N> +inline bool isInt(int64_t x) { + return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); +} + +template<unsigned N> +inline bool isUint(uint64_t x) { + return N >= 64 || x < (UINT64_C(1)<<N); +} + /// 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. @@ -108,7 +118,7 @@ inline uint16_t ByteSwap_16(uint16_t Value) { /// 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) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) return __builtin_bswap32(Value); #elif defined(_MSC_VER) && !defined(_DEBUG) return _byteswap_ulong(Value); @@ -124,7 +134,7 @@ inline uint32_t ByteSwap_32(uint32_t Value) { /// 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) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) return __builtin_bswap64(Value); #elif defined(_MSC_VER) && !defined(_DEBUG) return _byteswap_uint64(Value); @@ -425,6 +435,13 @@ inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) { return ((Value + Align - 1) / Align) * Align; } +/// OffsetToAlignment - Return the offset to 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. +inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { + return RoundUpToAlignment(Value, Align) - Value; +} + /// 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". diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 58a217f..eb4784c 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -14,6 +14,7 @@ #ifndef LLVM_SUPPORT_MEMORYBUFFER_H #define LLVM_SUPPORT_MEMORYBUFFER_H +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include <string> @@ -42,6 +43,10 @@ public: const char *getBufferEnd() const { return BufferEnd; } size_t getBufferSize() const { return BufferEnd-BufferStart; } + StringRef getBuffer() const { + return StringRef(BufferStart, getBufferSize()); + } + /// getBufferIdentifier - Return an identifier for this buffer, typically the /// filename it was read from. virtual const char *getBufferIdentifier() const { diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h new file mode 100644 index 0000000..dec0f13 --- /dev/null +++ b/include/llvm/Support/MemoryObject.h @@ -0,0 +1,70 @@ +//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef MEMORYOBJECT_H +#define MEMORYOBJECT_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +/// MemoryObject - Abstract base class for contiguous addressable memory. +/// Necessary for cases in which the memory is in another process, in a +/// file, or on a remote machine. +/// All size and offset parameters are uint64_ts, to allow 32-bit processes +/// access to 64-bit address spaces. +class MemoryObject { +public: + /// Destructor - Override as necessary. + virtual ~MemoryObject(); + + /// getBase - Returns the lowest valid address in the region. + /// + /// @result - The lowest valid address. + virtual uint64_t getBase() const = 0; + + /// getExtent - Returns the size of the region in bytes. (The region is + /// contiguous, so the highest valid address of the region + /// is getBase() + getExtent() - 1). + /// + /// @result - The size of the region. + virtual uint64_t getExtent() const = 0; + + /// readByte - Tries to read a single byte from the region. + /// + /// @param address - The address of the byte, in the same space as getBase(). + /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. + /// @result - 0 if successful; -1 if not. Failure may be due to a + /// bounds violation or an implementation-specific error. + virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; + + /// readBytes - Tries to read a contiguous range of bytes from the + /// region, up to the end of the region. + /// You should override this function if there is a quicker + /// way than going back and forth with individual bytes. + /// + /// @param address - The address of the first byte, in the same space as + /// getBase(). + /// @param size - The maximum number of bytes to copy. + /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL + /// and large enough to hold size bytes. + /// @param copied - A pointer to a nunber that is filled in with the number + /// of bytes actually read. May be NULL. + /// @result - 0 if successful; -1 if not. Failure may be due to a + /// bounds violation or an implementation-specific error. + virtual int readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied) const; +}; + +} + +#endif + diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index a49cf84..1f671c1 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -28,9 +28,12 @@ namespace llvm { +class LLVMContext; + /// NoFolder - Create "constants" (actually, values) with no folding. class NoFolder { public: + explicit NoFolder(LLVMContext &) {} //===--------------------------------------------------------------------===// // Binary Operators @@ -39,12 +42,18 @@ public: Value *CreateAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateAdd(LHS, RHS); } + Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNSWAdd(LHS, RHS); + } Value *CreateFAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFAdd(LHS, RHS); } Value *CreateSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateSub(LHS, RHS); } + Value *CreateNSWSub(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNSWSub(LHS, RHS); + } Value *CreateFSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFSub(LHS, RHS); } @@ -60,6 +69,9 @@ public: Value *CreateSDiv(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateSDiv(LHS, RHS); } + Value *CreateExactSDiv(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateExactSDiv(LHS, RHS); + } Value *CreateFDiv(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFDiv(LHS, RHS); } @@ -120,6 +132,15 @@ public: return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx); } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, + unsigned NumIdx) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + } + Value *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, + unsigned NumIdx) const { + return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx); + } + //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// @@ -143,12 +164,6 @@ public: 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 diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h index e489e0a..66ce3f2 100644 --- a/include/llvm/Support/PassNameParser.h +++ b/include/llvm/Support/PassNameParser.h @@ -24,6 +24,7 @@ #define LLVM_SUPPORT_PASS_NAME_PARSER_H #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Pass.h" #include <algorithm> #include <cstring> @@ -65,9 +66,9 @@ public: virtual void passRegistered(const PassInfo *P) { if (ignorablePass(P) || !Opt) return; if (findOption(P->getPassArgument()) != getNumOptions()) { - cerr << "Two passes with the same argument (-" + errs() << "Two passes with the same argument (-" << P->getPassArgument() << ") attempted to be registered!\n"; - abort(); + llvm_unreachable(0); } addLiteralOption(P->getPassArgument(), P, P->getPassName()); } diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index fda925f..c0b6a6b 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -58,7 +58,7 @@ struct constantint_ty { if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { const APInt &CIV = CI->getValue(); if (Val >= 0) - return CIV == Val; + return CIV == static_cast<uint64_t>(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. @@ -87,6 +87,18 @@ struct zero_ty { /// m_Zero() - Match an arbitrary zero/null constant. inline zero_ty m_Zero() { return zero_ty(); } +struct one_ty { + template<typename ITy> + bool match(ITy *V) { + if (const ConstantInt *C = dyn_cast<ConstantInt>(V)) + return C->isOne(); + return false; + } +}; + +/// m_One() - Match a an integer 1. +inline one_ty m_One() { return one_ty(); } + template<typename Class> struct bind_ty { @@ -311,7 +323,8 @@ struct BinaryOpClass_match { 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 (L.match(I->getOperand(0)) && + R.match(I->getOperand(1))) { if (Opcode) *Opcode = I->getOpcode(); return true; @@ -356,7 +369,8 @@ struct CmpClass_match { 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 (L.match(I->getOperand(0)) && + R.match(I->getOperand(1))) { Predicate = I->getPredicate(); return true; } @@ -403,7 +417,7 @@ struct SelectClass_match { }; template<typename Cond, typename LHS, typename RHS> -inline SelectClass_match<Cond, RHS, LHS> +inline SelectClass_match<Cond, LHS, RHS> m_Select(const Cond &C, const LHS &L, const RHS &R) { return SelectClass_match<Cond, LHS, RHS>(C, L, R); } @@ -503,7 +517,7 @@ struct neg_match { } private: bool matchIfNeg(Value *LHS, Value *RHS) { - return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) && + return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) && L.match(RHS); } }; @@ -532,7 +546,7 @@ struct fneg_match { } private: bool matchIfFNeg(Value *LHS, Value *RHS) { - return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) && + return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) && L.match(RHS); } }; diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h index b0edd3b..d64993f 100644 --- a/include/llvm/Support/PointerLikeTypeTraits.h +++ b/include/llvm/Support/PointerLikeTypeTraits.h @@ -50,12 +50,16 @@ public: // Provide PointerLikeTypeTraits for const pointers. template<typename T> class PointerLikeTypeTraits<const T*> { + typedef PointerLikeTypeTraits<T*> NonConst; + public: - static inline const void *getAsVoidPointer(const T* P) { return P; } + static inline const void *getAsVoidPointer(const T* P) { + return NonConst::getAsVoidPointer(const_cast<T*>(P)); + } static inline const T *getFromVoidPointer(const void *P) { - return static_cast<const T*>(P); + return NonConst::getFromVoidPointer(const_cast<void*>(P)); } - enum { NumLowBitsAvailable = 2 }; + enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable }; }; // Provide PointerLikeTypeTraits for uintptr_t. diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h index 909d286..0db84e1 100644 --- a/include/llvm/Support/PrettyStackTrace.h +++ b/include/llvm/Support/PrettyStackTrace.h @@ -18,6 +18,12 @@ namespace llvm { class raw_ostream; + + /// DisablePrettyStackTrace - Set this to true to disable this module. This + /// might be neccessary if the host application installs its own signal + /// handlers which conflict with the ones installed by this module. + /// Defaults to false. + extern bool DisablePrettyStackTrace; /// PrettyStackTraceEntry - This class is used to represent a frame of the /// "pretty" stack trace that is dumped when a program crashes. You can define diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h index 2fa0365..d8f8c78 100644 --- a/include/llvm/Support/Recycler.h +++ b/include/llvm/Support/Recycler.h @@ -34,7 +34,8 @@ struct RecyclerStruct { }; template<> -struct ilist_traits<RecyclerStruct> : ilist_default_traits<RecyclerStruct> { +struct ilist_traits<RecyclerStruct> : + public 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; } diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h new file mode 100644 index 0000000..c954c0d --- /dev/null +++ b/include/llvm/Support/Regex.h @@ -0,0 +1,63 @@ +//===-- Regex.h - Regular Expression matcher implementation -*- 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 POSIX regular expression matcher. +// +//===----------------------------------------------------------------------===// + +#include <string> + +struct llvm_regex; + +namespace llvm { + class StringRef; + template<typename T> class SmallVectorImpl; + + class Regex { + public: + enum { + NoFlags=0, + /// Compile for matching that ignores upper/lower case distinctions. + IgnoreCase=1, + /// Compile for newline-sensitive matching. With this flag '[^' bracket + /// expressions and '.' never match newline. A ^ anchor matches the + /// null string after any newline in the string in addition to its normal + /// function, and the $ anchor matches the null string before any + /// newline in the string in addition to its normal function. + Newline=2 + }; + + /// Compiles the given POSIX Extended Regular Expression \arg Regex. + /// This implementation supports regexes and matching strings with embedded + /// NUL characters. + Regex(const StringRef &Regex, unsigned Flags = NoFlags); + ~Regex(); + + /// isValid - returns the error encountered during regex compilation, or + /// matching, if any. + bool isValid(std::string &Error); + + /// getNumMatches - In a valid regex, return the number of parenthesized + /// matches it contains. The number filled in by match will include this + /// many entries plus one for the whole regex (as element 0). + unsigned getNumMatches() const; + + /// matches - Match the regex against a given \arg String. + /// + /// \param Matches - If given, on a succesful match this will be filled in + /// with references to the matched group expressions (inside \arg String), + /// the first group is always the entire pattern. + /// + /// This returns true on a successful match. + bool match(const StringRef &String, SmallVectorImpl<StringRef> *Matches=0); + private: + struct llvm_regex *preg; + int error; + }; +} diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h index 454679b..4db8882 100644 --- a/include/llvm/Support/Registry.h +++ b/include/llvm/Support/Registry.h @@ -77,9 +77,6 @@ namespace llvm { static listener *ListenerHead, *ListenerTail; public: - class iterator; - - /// Node in linked list of entries. /// class node { diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 7c8a139..5b6f56b 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -65,10 +65,14 @@ class SourceMgr { // include files in. std::vector<std::string> IncludeDirectories; + /// LineNoCache - This is a cache for line number queries, its implementation + /// is really private to SourceMgr.cpp. + mutable void *LineNoCache; + SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT void operator=(const SourceMgr&); // DO NOT IMPLEMENT public: - SourceMgr() {} + SourceMgr() : LineNoCache(0) {} ~SourceMgr(); void setIncludeDirs(const std::vector<std::string> &Dirs) { @@ -145,17 +149,6 @@ public: const std::string &Msg, const std::string &LineStr) : Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg), LineContents(LineStr) {} - SMDiagnostic(const SMDiagnostic &RHS) { - operator=(RHS); - } - - void operator=(const SMDiagnostic &E) { - Filename = E.Filename; - LineNo = E.LineNo; - ColumnNo = E.ColumnNo; - Message = E.Message; - LineContents = E.LineContents; - } void Print(const char *ProgName, raw_ostream &S); }; diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h index 5c63034..c71e6b9 100644 --- a/include/llvm/Support/StandardPasses.h +++ b/include/llvm/Support/StandardPasses.h @@ -80,6 +80,8 @@ namespace llvm { } } + /// createStandardModulePasses - Add the standard module passes. This is + /// expected to be run after the standard function passes. static inline void createStandardModulePasses(PassManager *PM, unsigned OptimizationLevel, bool OptimizeSize, @@ -91,71 +93,69 @@ namespace llvm { if (OptimizationLevel == 0) { if (InliningPass) PM->add(InliningPass); - } else { - if (UnitAtATime) - PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM->add(createCFGSimplificationPass()); // Clean up disgusting code - // Kill useless allocas - PM->add(createPromoteMemoryToRegisterPass()); - if (UnitAtATime) { - PM->add(createGlobalOptimizerPass()); // Optimize out global vars - PM->add(createGlobalDCEPass()); // Remove unused fns and globs - // IP Constant Propagation - PM->add(createIPConstantPropagationPass()); - PM->add(createDeadArgEliminationPass()); // Dead argument elimination - } - PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - if (UnitAtATime) { - if (HaveExceptions) - PM->add(createPruneEHPass()); // Remove dead EH info - PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs - } - if (InliningPass) - PM->add(InliningPass); - if (OptimizationLevel > 2) - PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args - if (SimplifyLibCalls) - PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM->add(createJumpThreadingPass()); // Thread jumps. - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM->add(createInstructionCombiningPass()); // Combine silly seq's - PM->add(createCondPropagationPass()); // Propagate conditionals - PM->add(createTailCallEliminationPass()); // Eliminate tail calls - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createReassociatePass()); // Reassociate expressions - PM->add(createLoopRotatePass()); // Rotate Loop - PM->add(createLICMPass()); // Hoist loop invariants - PM->add(createLoopUnswitchPass(OptimizeSize)); - PM->add(createLoopIndexSplitPass()); // Split loop index - PM->add(createInstructionCombiningPass()); - PM->add(createIndVarSimplifyPass()); // Canonicalize indvars - PM->add(createLoopDeletionPass()); // Delete dead loops - if (UnrollLoops) - PM->add(createLoopUnrollPass()); // Unroll small loops - PM->add(createInstructionCombiningPass()); // Clean up after the unroller - PM->add(createGVNPass()); // Remove redundancies - PM->add(createMemCpyOptPass()); // Remove memcpy / form memset - PM->add(createSCCPPass()); // Constant prop with SCCP + return; + } - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM->add(createInstructionCombiningPass()); - PM->add(createCondPropagationPass()); // Propagate conditionals - PM->add(createDeadStoreEliminationPass()); // Delete dead stores - PM->add(createAggressiveDCEPass()); // Delete dead instructions - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - - if (UnitAtATime) { - PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - PM->add(createDeadTypeEliminationPass()); // Eliminate dead types - } - - if (OptimizationLevel > 1 && UnitAtATime) - PM->add(createConstantMergePass()); // Merge dup global constants + if (UnitAtATime) + PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst + PM->add(createCFGSimplificationPass()); // Clean up disgusting code + if (UnitAtATime) { + PM->add(createGlobalOptimizerPass()); // Optimize out global vars + PM->add(createGlobalDCEPass()); // Remove unused fns and globs + // IP Constant Propagation + PM->add(createIPConstantPropagationPass()); + PM->add(createDeadArgEliminationPass()); // Dead argument elimination } + PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + if (UnitAtATime) { + if (HaveExceptions) + PM->add(createPruneEHPass()); // Remove dead EH info + PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs + } + if (InliningPass) + PM->add(InliningPass); + if (OptimizationLevel > 2) + PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args + if (SimplifyLibCalls) + PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. + PM->add(createJumpThreadingPass()); // Thread jumps. + PM->add(createCFGSimplificationPass()); // Merge & remove BBs + PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM->add(createInstructionCombiningPass()); // Combine silly seq's + PM->add(createCondPropagationPass()); // Propagate conditionals + PM->add(createTailCallEliminationPass()); // Eliminate tail calls + PM->add(createCFGSimplificationPass()); // Merge & remove BBs + PM->add(createReassociatePass()); // Reassociate expressions + PM->add(createLoopRotatePass()); // Rotate Loop + PM->add(createLICMPass()); // Hoist loop invariants + PM->add(createLoopUnswitchPass(OptimizeSize)); + PM->add(createInstructionCombiningPass()); + PM->add(createIndVarSimplifyPass()); // Canonicalize indvars + PM->add(createLoopDeletionPass()); // Delete dead loops + if (UnrollLoops) + PM->add(createLoopUnrollPass()); // Unroll small loops + PM->add(createInstructionCombiningPass()); // Clean up after the unroller + PM->add(createGVNPass()); // Remove redundancies + PM->add(createMemCpyOptPass()); // Remove memcpy / form memset + PM->add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + PM->add(createInstructionCombiningPass()); + PM->add(createCondPropagationPass()); // Propagate conditionals + PM->add(createDeadStoreEliminationPass()); // Delete dead stores + PM->add(createAggressiveDCEPass()); // Delete dead instructions + PM->add(createCFGSimplificationPass()); // Merge & remove BBs + + if (UnitAtATime) { + PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes + PM->add(createDeadTypeEliminationPass()); // Eliminate dead types + } + + if (OptimizationLevel > 1 && UnitAtATime) + PM->add(createConstantMergePass()); // Merge dup global constants } static inline void addOnePass(PassManager *PM, Pass *P, bool AndVerify) { @@ -230,10 +230,8 @@ namespace llvm { addOnePass(PM, createInstructionCombiningPass(), VerifyEach); addOnePass(PM, createJumpThreadingPass(), VerifyEach); - // Cleanup jump threading. - addOnePass(PM, createPromoteMemoryToRegisterPass(), VerifyEach); - // Delete basic blocks, which optimization passes may have killed... + // Delete basic blocks, which optimization passes may have killed. addOnePass(PM, createCFGSimplificationPass(), VerifyEach); // Now that we have optimized the program, discard unreachable functions. diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h index 98db8e2..82e46d4 100644 --- a/include/llvm/Support/StringPool.h +++ b/include/llvm/Support/StringPool.h @@ -1,4 +1,4 @@ -//===-- StringPool.h - Interned string pool -------------------------------===// +//===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -64,12 +64,7 @@ namespace llvm { /// 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); + PooledStringPtr intern(const StringRef &Str); /// empty - Checks whether the pool is empty. Returns true if so. /// @@ -139,10 +134,6 @@ namespace llvm { 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 index 9a33fa3..b3d83fc 100644 --- a/include/llvm/Support/SystemUtils.h +++ b/include/llvm/Support/SystemUtils.h @@ -15,27 +15,29 @@ #ifndef LLVM_SUPPORT_SYSTEMUTILS_H #define LLVM_SUPPORT_SYSTEMUTILS_H -#include "llvm/System/Program.h" +#include <string> namespace llvm { + class raw_ostream; + namespace sys { class Path; } -/// Determine if the ostream provided is connected to the std::cout and +/// Determine if the raw_ostream provided is connected to the outs() 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 + raw_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. +/// being executed. This allows us to find another LLVM tool if it is built in +/// the same directory. 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); + const char *Argv0, void *MainAddr); } // End llvm namespace diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index b0700c1..8e28632 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -25,21 +25,24 @@ namespace llvm { class TargetData; +class LLVMContext; /// TargetFolder - Create constants with target dependent folding. class TargetFolder { const TargetData *TD; + LLVMContext &Context; /// 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)) + if (Constant *CF = ConstantFoldConstantExpression(CE, Context, TD)) return CF; return C; } public: - explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {} + explicit TargetFolder(const TargetData *TheTD, LLVMContext &C) : + TD(TheTD), Context(C) {} //===--------------------------------------------------------------------===// // Binary Operators @@ -48,12 +51,18 @@ public: Constant *CreateAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getAdd(LHS, RHS)); } + Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNSWAdd(LHS, RHS)); + } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFAdd(LHS, RHS)); } Constant *CreateSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getSub(LHS, RHS)); } + Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNSWSub(LHS, RHS)); + } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFSub(LHS, RHS)); } @@ -69,6 +78,9 @@ public: Constant *CreateSDiv(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getSDiv(LHS, RHS)); } + Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getExactSDiv(LHS, RHS)); + } Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFDiv(LHS, RHS)); } @@ -132,6 +144,15 @@ public: return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx)); } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, + unsigned NumIdx) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, + unsigned NumIdx) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + } + //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// @@ -176,14 +197,6 @@ public: 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 diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 71b7ee5..54f1da9 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -19,15 +19,15 @@ #include "llvm/System/Mutex.h" #include <string> #include <vector> -#include <iosfwd> #include <cassert> namespace llvm { class TimerGroup; +class raw_ostream; /// Timer - This class is used to track the amount of time spent between -/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS +/// invocations of its 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 @@ -112,7 +112,7 @@ public: /// print - Print the current timer to standard error, and reset the "Started" /// flag. - void print(const Timer &Total, std::ostream &OS); + void print(const Timer &Total, raw_ostream &OS); private: friend class TimerGroup; diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index b0ae516..fb22e3f 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -16,6 +16,7 @@ #define LLVM_SUPPORT_TYPEBUILDER_H #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include <limits.h> namespace llvm { @@ -49,15 +50,14 @@ namespace llvm { /// 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(), +/// static const StructType *get(LLVMContext &Context) { +/// // If you cache this result, be sure to cache it separately +/// // for each LLVMContext. +/// return StructType::get( +/// TypeBuilder<types::i<32>, xcompile>::get(Context), +/// TypeBuilder<types::i<32>*, xcompile>::get(Context), +/// TypeBuilder<types::i<8>*[], xcompile>::get(Context), /// NULL); -/// return result; /// } /// /// // You may find this a convenient place to put some constants @@ -71,9 +71,6 @@ namespace llvm { /// } /// } // 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. @@ -104,10 +101,8 @@ template<typename T, bool cross> class TypeBuilder<const volatile 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; + static const PointerType *get(LLVMContext &Context) { + return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); } }; @@ -117,19 +112,15 @@ 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; + static const ArrayType *get(LLVMContext &Context) { + return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); } }; /// 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; + static const ArrayType *get(LLVMContext &Context) { + return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); } }; @@ -158,10 +149,8 @@ public: #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; \ + static const IntegerType *get(LLVMContext &Context) { \ + return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ } \ }; \ template<> class TypeBuilder<T, true> { \ @@ -189,53 +178,52 @@ DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); 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; + static const IntegerType *get(LLVMContext &C) { + return IntegerType::get(C, num_bits); } }; template<> class TypeBuilder<float, false> { public: - static const Type *get() { - return Type::FloatTy; + static const Type *get(LLVMContext& C) { + return Type::getFloatTy(C); } }; template<> class TypeBuilder<float, true> {}; template<> class TypeBuilder<double, false> { public: - static const Type *get() { - return Type::DoubleTy; + static const Type *get(LLVMContext& C) { + return Type::getDoubleTy(C); } }; template<> class TypeBuilder<double, true> {}; template<bool cross> class TypeBuilder<types::ieee_float, cross> { public: - static const Type *get() { return Type::FloatTy; } + static const Type *get(LLVMContext& C) { return Type::getFloatTy(C); } }; template<bool cross> class TypeBuilder<types::ieee_double, cross> { public: - static const Type *get() { return Type::DoubleTy; } + static const Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } }; template<bool cross> class TypeBuilder<types::x86_fp80, cross> { public: - static const Type *get() { return Type::X86_FP80Ty; } + static const Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } }; template<bool cross> class TypeBuilder<types::fp128, cross> { public: - static const Type *get() { return Type::FP128Ty; } + static const Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } }; template<bool cross> class TypeBuilder<types::ppc_fp128, cross> { public: - static const Type *get() { return Type::PPC_FP128Ty; } + static const Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } }; template<bool cross> class TypeBuilder<void, cross> { public: - static const Type *get() { - return Type::VoidTy; + static const Type *get(LLVMContext &C) { + return Type::getVoidTy(C); } }; @@ -246,64 +234,43 @@ template<> class TypeBuilder<void*, 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() { - return FunctionType::get(TypeBuilder<R, cross>::get(), false); + static const FunctionType *get(LLVMContext &Context) { + return FunctionType::get(TypeBuilder<R, cross>::get(Context), 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() { + static const FunctionType *get(LLVMContext &Context) { std::vector<const Type*> params; params.reserve(1); - params.push_back(TypeBuilder<A1, cross>::get()); - return FunctionType::get(TypeBuilder<R, cross>::get(), params, false); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + params, false); } }; @@ -311,20 +278,15 @@ 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + params.push_back(TypeBuilder<A4, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + params, false); } }; @@ -332,85 +294,58 @@ 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + params.push_back(TypeBuilder<A4, cross>::get(Context)); + params.push_back(TypeBuilder<A5, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + 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() { - return FunctionType::get(TypeBuilder<R, cross>::get(), true); + static const FunctionType *get(LLVMContext &Context) { + return FunctionType::get(TypeBuilder<R, cross>::get(Context), 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() { + static const FunctionType *get(LLVMContext &Context) { std::vector<const Type*> params; params.reserve(1); - params.push_back(TypeBuilder<A1, cross>::get()); - return FunctionType::get(TypeBuilder<R, cross>::get(), params, true); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + params, true); } }; @@ -418,20 +353,15 @@ 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + params.push_back(TypeBuilder<A4, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + params, true); } }; @@ -439,21 +369,16 @@ 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() { + static const FunctionType *get(LLVMContext &Context) { 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); + params.push_back(TypeBuilder<A1, cross>::get(Context)); + params.push_back(TypeBuilder<A2, cross>::get(Context)); + params.push_back(TypeBuilder<A3, cross>::get(Context)); + params.push_back(TypeBuilder<A4, cross>::get(Context)); + params.push_back(TypeBuilder<A5, cross>::get(Context)); + return FunctionType::get(TypeBuilder<R, cross>::get(Context), + params, true); } }; diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index a97a5e8..e6363ff 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -14,6 +14,7 @@ #ifndef LLVM_SUPPORT_VALUEHANDLE_H #define LLVM_SUPPORT_VALUEHANDLE_H +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Value.h" @@ -44,73 +45,87 @@ protected: /// fully general Callback version does have a vtable. enum HandleBaseKind { Assert, - Weak, - Callback + Callback, + Tracking, + Weak }; private: - + PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; ValueHandleBase *Next; Value *VP; + + explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT. 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) + if (isValid(VP)) AddToUseList(); } ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) : PrevPair(0, Kind), Next(0), VP(RHS.VP) { - if (VP) + if (isValid(VP)) AddToExistingUseList(RHS.getPrevPtr()); } ~ValueHandleBase() { - if (VP) - RemoveFromUseList(); + if (isValid(VP)) + RemoveFromUseList(); } - + Value *operator=(Value *RHS) { if (VP == RHS) return RHS; - if (VP) RemoveFromUseList(); + if (isValid(VP)) RemoveFromUseList(); VP = RHS; - if (VP) AddToUseList(); + if (isValid(VP)) AddToUseList(); return RHS; } Value *operator=(const ValueHandleBase &RHS) { if (VP == RHS.VP) return RHS.VP; - if (VP) RemoveFromUseList(); + if (isValid(VP)) RemoveFromUseList(); VP = RHS.VP; - if (VP) AddToExistingUseList(RHS.getPrevPtr()); + if (isValid(VP)) AddToExistingUseList(RHS.getPrevPtr()); return VP; } - + Value *operator->() const { return getValPtr(); } Value &operator*() const { return *getValPtr(); } protected: Value *getValPtr() const { return VP; } + static bool isValid(Value *V) { + return V && + V != DenseMapInfo<Value *>::getEmptyKey() && + V != DenseMapInfo<Value *>::getTombstoneKey(); + } + 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. + + /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where + /// List is the address of either the head of the list or a Next node within + /// the existing use list. void AddToExistingUseList(ValueHandleBase **List); - + + /// AddToExistingUseListAfter - Add this ValueHandle to the use list after + /// Node. + void AddToExistingUseListAfter(ValueHandleBase *Node); + /// 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 @@ -123,6 +138,13 @@ public: WeakVH(const WeakVH &RHS) : ValueHandleBase(Weak, RHS) {} + Value *operator=(Value *RHS) { + return ValueHandleBase::operator=(RHS); + } + Value *operator=(const ValueHandleBase &RHS) { + return ValueHandleBase::operator=(RHS); + } + operator Value*() const { return getValPtr(); } @@ -153,7 +175,7 @@ template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {}; /// 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 +class AssertingVH #ifndef NDEBUG : public ValueHandleBase #endif @@ -164,7 +186,7 @@ class AssertingVH return static_cast<ValueTy*>(ValueHandleBase::getValPtr()); } void setValPtr(ValueTy *P) { - ValueHandleBase::operator=(P); + ValueHandleBase::operator=(GetAsValue(P)); } #else ValueTy *ThePtr; @@ -172,10 +194,15 @@ class AssertingVH void setValPtr(ValueTy *P) { ThePtr = P; } #endif + // Convert a ValueTy*, which may be const, to the type the base + // class expects. + static Value *GetAsValue(Value *V) { return V; } + static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } + public: #ifndef NDEBUG AssertingVH() : ValueHandleBase(Assert) {} - AssertingVH(ValueTy *P) : ValueHandleBase(Assert, P) {} + AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {} AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {} #else AssertingVH() : ThePtr(0) {} @@ -190,7 +217,7 @@ public: setValPtr(RHS); return getValPtr(); } - ValueTy *operator=(AssertingVH<ValueTy> &RHS) { + ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { setValPtr(RHS.getValPtr()); return getValPtr(); } @@ -211,6 +238,88 @@ template<> struct simplify_type<const AssertingVH<Value> > { template<> struct simplify_type<AssertingVH<Value> > : public simplify_type<const AssertingVH<Value> > {}; +/// TrackingVH - This is a value handle that tracks a Value (or Value subclass), +/// even across RAUW operations. +/// +/// TrackingVH is designed for situations where a client needs to hold a handle +/// to a Value (or subclass) across some operations which may move that value, +/// but should never destroy it or replace it with some unacceptable type. +/// +/// It is an error to do anything with a TrackingVH whose value has been +/// destroyed, except to destruct it. +/// +/// It is an error to attempt to replace a value with one of a type which is +/// incompatible with any of its outstanding TrackingVHs. +template<typename ValueTy> +class TrackingVH : public ValueHandleBase { + void CheckValidity() const { + Value *VP = ValueHandleBase::getValPtr(); + + // Null is always ok. + if (!VP) + return; + + // Check that this value is valid (i.e., it hasn't been deleted). We + // explicitly delay this check until access to avoid requiring clients to be + // unnecessarily careful w.r.t. destruction. + assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!"); + + // Check that the value is a member of the correct subclass. We would like + // to check this property on assignment for better debugging, but we don't + // want to require a virtual interface on this VH. Instead we allow RAUW to + // replace this value with a value of an invalid type, and check it here. + assert(isa<ValueTy>(VP) && + "Tracked Value was replaced by one with an invalid type!"); + } + + ValueTy *getValPtr() const { + CheckValidity(); + return static_cast<ValueTy*>(ValueHandleBase::getValPtr()); + } + void setValPtr(ValueTy *P) { + CheckValidity(); + ValueHandleBase::operator=(GetAsValue(P)); + } + + // Convert a ValueTy*, which may be const, to the type the base + // class expects. + static Value *GetAsValue(Value *V) { return V; } + static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } + +public: + TrackingVH() : ValueHandleBase(Tracking) {} + TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, P) {} + TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {} + + operator ValueTy*() const { + return getValPtr(); + } + + ValueTy *operator=(ValueTy *RHS) { + setValPtr(RHS); + return getValPtr(); + } + ValueTy *operator=(const TrackingVH<ValueTy> &RHS) { + setValPtr(RHS.getValPtr()); + return getValPtr(); + } + + ValueTy *operator->() const { return getValPtr(); } + ValueTy &operator*() const { return *getValPtr(); } +}; + +// Specialize simplify_type to allow TrackingVH to participate in +// dyn_cast, isa, etc. +template<typename From> struct simplify_type; +template<> struct simplify_type<const TrackingVH<Value> > { + typedef Value* SimpleType; + static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) { + return static_cast<Value *>(AVH); + } +}; +template<> struct simplify_type<TrackingVH<Value> > + : public simplify_type<const TrackingVH<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 diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h new file mode 100644 index 0000000..e0978b2 --- /dev/null +++ b/include/llvm/Support/raw_os_ostream.h @@ -0,0 +1,42 @@ +//===- raw_os_ostream.h - std::ostream adaptor for raw_ostream --*- 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_os_ostream class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_RAW_OS_OSTREAM_H +#define LLVM_SUPPORT_RAW_OS_OSTREAM_H + +#include "llvm/Support/raw_ostream.h" +#include <iosfwd> + +namespace llvm { + +/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a +/// simple adaptor class. It does not check for output errors; clients should +/// use the underlying stream to detect errors. +class raw_os_ostream : public raw_ostream { + std::ostream &OS; + + /// write_impl - See raw_ostream::write_impl. + virtual void write_impl(const char *Ptr, size_t 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(); +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 8242f04..7827dd8 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -14,11 +14,8 @@ #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> +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class format_object_base; @@ -31,18 +28,39 @@ namespace llvm { /// a chunk at a time. class raw_ostream { private: + // Do not implement. raw_ostream is noncopyable. + void operator=(const raw_ostream &); + raw_ostream(const raw_ostream &); + /// 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). + /// 1. Unbuffered (BufferMode == Unbuffered) + /// 1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0). + /// 2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 && + /// OutBufEnd - OutBufStart >= 1). + /// + /// If buffered, then the raw_ostream owns the buffer if (BufferMode == + /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is + /// managed by the subclass. + /// + /// If a subclass installs an external buffer using SetBuffer then it can wait + /// for a \see write_impl() call to handle the data which has been put into + /// this buffer. char *OutBufStart, *OutBufEnd, *OutBufCur; - bool Unbuffered; + + enum BufferKind { + Unbuffered = 0, + InternalBuffer, + ExternalBuffer + } BufferMode; + + /// Error This flag is true if an error of any kind has been detected. + /// + bool Error; public: // color order matches ANSI escape sequence, don't change @@ -58,49 +76,66 @@ public: SAVEDCOLOR }; - explicit raw_ostream(bool unbuffered=false) : Unbuffered(unbuffered) { + explicit raw_ostream(bool unbuffered=false) + : BufferMode(unbuffered ? Unbuffered : InternalBuffer), Error(false) { // Start out ready to flush. OutBufStart = OutBufEnd = OutBufCur = 0; } - virtual ~raw_ostream() { - delete [] OutBufStart; - } + virtual ~raw_ostream(); /// tell - Return the current offset with the file. uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); } + /// has_error - Return the value of the flag in this raw_ostream indicating + /// whether an output error has been encountered. + bool has_error() const { + return Error; + } + + /// clear_error - Set the flag read by has_error() to false. If the error + /// flag is set at the time when this raw_ostream's destructor is called, + /// llvm_report_error is called to report the error. Use clear_error() + /// after handling the error to avoid this behavior. + void clear_error() { + Error = false; + } + //===--------------------------------------------------------------------===// // 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"); + /// SetBuffered - Set the stream to be buffered, with an automatically + /// determined buffer size. + void SetBuffered(); + + /// SetBufferSize - Set the stream to be buffered, using the + /// specified buffer size. + void SetBufferSize(size_t Size) { flush(); + SetBufferAndMode(new char[Size], Size, InternalBuffer); + } - delete [] OutBufStart; - OutBufStart = new char[Size]; - OutBufEnd = OutBufStart+Size; - OutBufCur = OutBufStart; - Unbuffered = false; + size_t GetBufferSize() { + // If we're supposed to be buffered but haven't actually gotten around + // to allocating the buffer yet, return the value that would be used. + if (BufferMode != Unbuffered && OutBufStart == 0) + return preferred_buffer_size(); + + // Otherwise just return the size of the allocated buffer. + return OutBufEnd - OutBufStart; } - /// SetUnbuffered - Set the streams buffering status. When - /// unbuffered the stream will flush after every write. This routine + /// SetUnbuffered - Set the stream to be unbuffered. 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; + SetBufferAndMode(0, 0, Unbuffered); } - unsigned GetNumBytesInBuffer() const { + size_t GetNumBytesInBuffer() const { return OutBufCur - OutBufStart; } @@ -134,22 +169,29 @@ public: 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); + raw_ostream &operator<<(const StringRef &Str) { + // Inline fast path, particularly for strings with a known length. + size_t Size = Str.size(); // Make sure we can use the fast path. if (OutBufCur+Size > OutBufEnd) - return write(Str, Size); + return write(Str.data(), Size); - memcpy(OutBufCur, Str, Size); + memcpy(OutBufCur, Str.data(), Size); OutBufCur += Size; return *this; } - raw_ostream &operator<<(const std::string& Str) { + raw_ostream &operator<<(const char *Str) { + // Inline fast path, particulary for constant strings where a sufficiently + // smart compiler will simplify strlen. + + this->operator<<(StringRef(Str)); + return *this; + } + + raw_ostream &operator<<(const std::string &Str) { + // Avoid the fast path, it would only increase code size for a marginal win. write(Str.data(), Str.length()); return *this; } @@ -169,17 +211,21 @@ public: return *this; } - raw_ostream &operator<<(double N) { - this->operator<<(ftostr(N)); - return *this; - } + raw_ostream &operator<<(double N); + + /// write_hex - Output \arg N in hexadecimal, without any prefix or padding. + raw_ostream &write_hex(unsigned long long N); raw_ostream &write(unsigned char C); - raw_ostream &write(const char *Ptr, unsigned Size); + raw_ostream &write(const char *Ptr, size_t Size); // Formatted output, see the format() function in Support/Format.h. raw_ostream &operator<<(const format_object_base &Fmt); + /// indent - Insert 'NumSpaces' spaces. + raw_ostream &indent(unsigned NumSpaces); + + /// Changes the foreground color of text that will be output from this point /// forward. /// @param colors ANSI color to use, the special SAVEDCOLOR can be used to @@ -194,6 +240,11 @@ public: /// outputting colored text, or before program exit. virtual raw_ostream &resetColor() { return *this; } + /// This function determines if this stream is connected to a "tty" or + /// "console" window. That is, the output would be displayed to the user + /// rather than being put on a pipe or stored in a file. + virtual bool is_displayed() const { return false; } + //===--------------------------------------------------------------------===// // Subclass Interface //===--------------------------------------------------------------------===// @@ -203,8 +254,15 @@ private: /// by subclasses. This writes the \args Size bytes starting at /// \arg Ptr to the underlying stream. /// + /// This function is guaranteed to only be called at a point at which it is + /// safe for the subclass to install a new buffer via SetBuffer. + /// + /// \arg Ptr - The start of the data to be written. For buffered streams this + /// is guaranteed to be the start of the buffer. + /// \arg Size - The number of bytes to be written. + /// /// \invariant { Size > 0 } - virtual void write_impl(const char *Ptr, unsigned Size) = 0; + virtual void write_impl(const char *Ptr, size_t Size) = 0; // An out of line virtual method to provide a home for the class vtable. virtual void handle(); @@ -213,14 +271,42 @@ private: /// counting the bytes currently in the buffer. virtual uint64_t current_pos() = 0; +protected: + /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is + /// intended for use only by subclasses which can arrange for the output to go + /// directly into the desired output buffer, instead of being copied on each + /// flush. + void SetBuffer(char *BufferStart, size_t Size) { + SetBufferAndMode(BufferStart, Size, ExternalBuffer); + } + + /// preferred_buffer_size - Return an efficient buffer size for the + /// underlying output mechanism. + virtual size_t preferred_buffer_size(); + + /// error_detected - Set the flag indicating that an output error has + /// been encountered. + void error_detected() { Error = true; } + + /// getBufferStart - Return the beginning of the current stream buffer, or 0 + /// if the stream is unbuffered. + const char *getBufferStart() const { return OutBufStart; } + //===--------------------------------------------------------------------===// // Private Interface //===--------------------------------------------------------------------===// private: + /// SetBufferAndMode - Install the given buffer and mode. + void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode); + /// 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(); + + /// copy_to_buffer - Copy data into the buffer. Size must not be + /// greater than the number of unused bytes in the buffer. + void copy_to_buffer(const char *Ptr, size_t Size); }; //===----------------------------------------------------------------------===// @@ -235,23 +321,41 @@ class raw_fd_ostream : public raw_ostream { uint64_t pos; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, unsigned Size); + virtual void write_impl(const char *Ptr, size_t 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; } + /// preferred_buffer_size - Determine an efficient buffer size. + virtual size_t preferred_buffer_size(); + 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. + + enum { + /// F_Excl - When opening a file, this flag makes raw_fd_ostream + /// report an error if the file already exists. + F_Excl = 1, + + /// F_Append - When opening a file, if it already exists append to the + /// existing file instead of returning an error. This may not be specified + /// with F_Excl. + F_Append = 2, + + /// F_Binary - The file should be opened in binary mode on platforms that + /// make this distinction. + F_Binary = 4 + }; + + /// 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. + /// This allows optional flags to control how the file will be opened. /// /// \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(const char *Filename, std::string &ErrorInfo, + unsigned Flags = 0); /// 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. @@ -264,9 +368,6 @@ public: /// 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); @@ -274,6 +375,8 @@ public: virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, bool bg=false); virtual raw_ostream &resetColor(); + + virtual bool is_displayed() const; }; /// raw_stdout_ostream - This is a stream that always prints to stdout. @@ -302,49 +405,29 @@ raw_ostream &outs(); /// Use it like: errs() << "foo" << "bar"; raw_ostream &errs(); +/// nulls() - This returns a reference to a raw_ostream which simply discards +/// output. +raw_ostream &nulls(); //===----------------------------------------------------------------------===// // 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. +/// simple adaptor class. This class does not encounter output errors. 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); + virtual void write_impl(const char *Ptr, size_t 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) {} + explicit 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() { @@ -354,22 +437,42 @@ public: }; /// raw_svector_ostream - A raw_ostream that writes to an SmallVector or -/// SmallString. This is a simple adaptor class. +/// SmallString. This is a simple adaptor class. This class does not +/// encounter output errors. 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); + virtual void write_impl(const char *Ptr, size_t 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) {} + /// Construct a new raw_svector_ostream. + /// + /// \arg O - The vector to write to; this should generally have at least 128 + /// bytes free to avoid any extraneous memory overhead. + explicit raw_svector_ostream(SmallVectorImpl<char> &O); ~raw_svector_ostream(); - /// tell - Return the current offset with the stream. - uint64_t tell(); + /// str - Flushes the stream contents to the target vector and return a + /// StringRef for the vector contents. + StringRef str(); +}; + +/// raw_null_ostream - A raw_ostream that discards all output. +class raw_null_ostream : public raw_ostream { + /// write_impl - See raw_ostream::write_impl. + virtual void write_impl(const char *Ptr, size_t size); + + /// current_pos - Return the current position within the stream, not + /// counting the bytes currently in the buffer. + virtual uint64_t current_pos(); + +public: + explicit raw_null_ostream() {} + ~raw_null_ostream(); }; } // end llvm namespace diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 5000a8b..5f799b8 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -35,7 +35,7 @@ namespace dont_use // 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> char is_class_helper(void(T::*)()); template<typename T> double is_class_helper(...); } @@ -49,6 +49,44 @@ struct is_class enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) }; }; +/// \brief Metafunction that determines whether the two given types are +/// equivalent. +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +// enable_if_c - Enable/disable a template based on a metafunction +template<bool Cond, typename T = void> +struct enable_if_c { + typedef T type; +}; + +template<typename T> struct enable_if_c<false, T> { }; + +// enable_if - Enable/disable a template based on a metafunction +template<typename Cond, typename T = void> +struct enable_if : public enable_if_c<Cond::value, T> { }; + +namespace dont_use { + template<typename Base> char base_of_helper(const volatile Base*); + template<typename Base> double base_of_helper(...); +} + +/// is_base_of - Metafunction to determine whether one type is a base class of +/// (or identical to) another type. +template<typename Base, typename Derived> +struct is_base_of { + static const bool value + = is_class<Base>::value && is_class<Derived>::value && + sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0)); +}; + } #endif |