diff options
| author | Derek Schuff <dschuff@chromium.org> | 2013-01-09 16:55:43 -0800 |
|---|---|---|
| committer | Derek Schuff <dschuff@chromium.org> | 2013-01-11 13:47:37 -0800 |
| commit | b770d0e0636a4b5ad61b1ca661caee67576c05fc (patch) | |
| tree | c486ce032d41f97313c50629bd5b879f53e6ccbf /include | |
| parent | b835840cf112a6178506d834b58aa625f59a8994 (diff) | |
| parent | 1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410 (diff) | |
Merge commit '1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410'
deplib features commented out due to removal upstream;
will add back as a localmod
Conflicts:
include/llvm/ADT/Triple.h
include/llvm/MC/MCAssembler.h
include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/BranchFolding.cpp
lib/LLVMBuild.txt
lib/Linker/LinkArchives.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/Makefile
lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMFrameLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/ARMTargetObjectFile.cpp
lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
lib/Target/Mips/MipsInstrFPU.td
lib/Target/Mips/MipsInstrInfo.td
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86Subtarget.h
lib/VMCore/Module.cpp
test/MC/MachO/ARM/nop-armv4-padding.s
tools/Makefile
tools/llc/llc.cpp
tools/lto/LTOModule.cpp
tools/lto/lto.cpp
Diffstat (limited to 'include')
239 files changed, 3675 insertions, 1083 deletions
diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index b8c4ad9ad7..f0872c1436 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -139,13 +139,26 @@ extern "C" { * by passing a block of information in the DisInfo parameter and specifying the * TagType and callback functions as described above. These can all be passed * as NULL. If successful, this returns a disassembler context. If not, it - * returns NULL. + * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU() + * with an empty CPU name. */ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp); /** + * Create a disassembler for the TripleName and a specific CPU. Symbolic + * disassembly is supported by passing a block of information in the DisInfo + * parameter and specifying the TagType and callback functions as described + * above. These can all be passed * as NULL. If successful, this returns a + * disassembler context. If not, it returns NULL. + */ +LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, + void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); + +/** * Set the disassembler's options. Returns 1 if it can set the Options and 0 * otherwise. */ @@ -153,6 +166,8 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options); /* The option to produce marked up assembly. */ #define LLVMDisassembler_Option_UseMarkup 1 +/* The option to print immediates as hex. */ +#define LLVMDisassembler_Option_PrintImmHex 2 /** * Dispose of a disassembler context. diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h index 29668de465..691abdfcb4 100644 --- a/include/llvm-c/TargetMachine.h +++ b/include/llvm-c/TargetMachine.h @@ -20,6 +20,7 @@ #define LLVM_C_TARGETMACHINE_H #include "llvm-c/Core.h" +#include "llvm-c/Target.h" #ifdef __cplusplus extern "C" { diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index c7c8016b83..95cd23d2ce 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -274,7 +274,7 @@ public: initSlowCase(that); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES /// @brief Move Constructor. APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) { that.BitWidth = 0; @@ -601,7 +601,7 @@ public: return AssignSlowCase(RHS); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES /// @brief Move assignment operator. APInt& operator=(APInt&& that) { if (!isSingleWord()) diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 9d6388f7ee..82cfdf437d 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -98,7 +98,7 @@ public: std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { RHS.Bits = 0; @@ -452,7 +452,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES const BitVector &operator=(BitVector &&RHS) { if (this == &RHS) return *this; diff --git a/include/llvm/ADT/DAGDeltaAlgorithm.h b/include/llvm/ADT/DAGDeltaAlgorithm.h index 2dfed075de..3dd862c8b2 100644 --- a/include/llvm/ADT/DAGDeltaAlgorithm.h +++ b/include/llvm/ADT/DAGDeltaAlgorithm.h @@ -9,8 +9,8 @@ #ifndef LLVM_ADT_DAGDELTAALGORITHM_H #define LLVM_ADT_DAGDELTAALGORITHM_H -#include <vector> #include <set> +#include <vector> namespace llvm { diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h index 7bf7960c63..4d07e04478 100644 --- a/include/llvm/ADT/DeltaAlgorithm.h +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -9,8 +9,8 @@ #ifndef LLVM_ADT_DELTAALGORITHM_H #define LLVM_ADT_DELTAALGORITHM_H -#include <vector> #include <set> +#include <vector> namespace llvm { diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index ac4bdbd126..31e685f96f 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -14,20 +14,20 @@ #ifndef LLVM_ADT_DENSEMAP_H #define LLVM_ADT_DENSEMAP_H -#include "llvm/Support/Compiler.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/AlignOf.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/type_traits.h" -#include "llvm/ADT/DenseMapInfo.h" #include <algorithm> -#include <iterator> -#include <new> -#include <utility> #include <cassert> #include <climits> #include <cstddef> #include <cstring> +#include <iterator> +#include <new> +#include <utility> namespace llvm { @@ -198,7 +198,7 @@ public: return FindAndConstruct(Key).second; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES value_type& FindAndConstruct(KeyT &&Key) { BucketT *TheBucket; if (LookupBucketFor(Key, TheBucket)) @@ -383,7 +383,7 @@ private: return TheBucket; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, BucketT *TheBucket) { TheBucket = InsertIntoBucketImpl(Key, TheBucket); @@ -536,7 +536,7 @@ public: copyFrom(other); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES DenseMap(DenseMap &&other) { init(0); swap(other); @@ -566,7 +566,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES DenseMap& operator=(DenseMap &&other) { this->destroyAll(); operator delete(Buckets); @@ -700,7 +700,7 @@ public: copyFrom(other); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap(SmallDenseMap &&other) { init(0); swap(other); @@ -795,7 +795,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap& operator=(SmallDenseMap &&other) { this->destroyAll(); deallocateBuckets(); diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index 8ab9a33200..776863a4c0 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -32,6 +32,7 @@ public: bool empty() const { return TheMap.empty(); } unsigned size() const { return TheMap.size(); } + size_t getMemorySize() const { return TheMap.getMemorySize(); } /// Grow the denseset so that it has at least Size buckets. Does not shrink void resize(size_t Size) { TheMap.resize(Size); } diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index 519b18052b..644544253a 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -34,8 +34,8 @@ #define LLVM_ADT_DEPTHFIRSTITERATOR_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" #include <set> #include <vector> diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 375d84abeb..91794dea69 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -16,9 +16,9 @@ #ifndef LLVM_ADT_FOLDINGSET_H #define LLVM_ADT_FOLDINGSET_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class APFloat; diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index 20bdd903f7..998d785dd7 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_IMLIST_H #define LLVM_ADT_IMLIST_H -#include "llvm/Support/Allocator.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" #include <cassert> diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index 4883c5ba0a..f9baec213a 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -288,6 +288,13 @@ public: Factory(F) { if (Root) { Root->retain(); } } + + explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X, + typename ImmutableMap<KeyT, ValT>::Factory &F) + : Root(X.getRootWithoutRetain()), + Factory(F.getTreeFactory()) { + if (Root) { Root->retain(); } + } ImmutableMapRef(const ImmutableMapRef &X) : Root(X.Root), @@ -318,12 +325,20 @@ public: return ImmutableMapRef(0, F); } - ImmutableMapRef add(key_type_ref K, data_type_ref D) { + void manualRetain() { + if (Root) Root->retain(); + } + + void manualRelease() { + if (Root) Root->release(); + } + + ImmutableMapRef add(key_type_ref K, data_type_ref D) const { TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D)); return ImmutableMapRef(NewT, Factory); } - ImmutableMapRef remove(key_type_ref K) { + ImmutableMapRef remove(key_type_ref K) const { TreeTy *NewT = Factory->remove(Root, K); return ImmutableMapRef(NewT, Factory); } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 3900f96be1..0982657ccf 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -14,9 +14,9 @@ #ifndef LLVM_ADT_IMSET_H #define LLVM_ADT_IMSET_H -#include "llvm/Support/Allocator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 931b67e409..da6ee4297e 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -99,8 +99,8 @@ #ifndef LLVM_ADT_INTERVALMAP_H #define LLVM_ADT_INTERVALMAP_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/RecyclingAllocator.h" #include <iterator> diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index a9724ee154..58495035c4 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -123,7 +123,7 @@ namespace llvm { retain(); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { S.Obj = 0; } diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index f43aeb1bc4..aa43f552d5 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -19,7 +19,7 @@ #include "llvm/Support/Compiler.h" #include <cassert> -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES #include <utility> #endif @@ -33,7 +33,7 @@ public: explicit Optional() : x(), hasVal(false) {} Optional(const T &y) : x(y), hasVal(true) {} -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {} #endif @@ -48,12 +48,17 @@ public: } const T* getPointer() const { assert(hasVal); return &x; } - const T& getValue() const { assert(hasVal); return x; } + const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; } operator bool() const { return hasVal; } bool hasValue() const { return hasVal; } const T* operator->() const { return getPointer(); } - const T& operator*() const { assert(hasVal); return x; } + const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; } + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + T&& getValue() && { assert(hasVal); return std::move(x); } + T&& operator*() && { assert(hasVal); return std::move(x); } +#endif }; template<typename T> struct simplify_type; diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h index 05bcd40d08..ea229916f9 100644 --- a/include/llvm/ADT/OwningPtr.h +++ b/include/llvm/ADT/OwningPtr.h @@ -32,7 +32,7 @@ class OwningPtr { public: explicit OwningPtr(T *P = 0) : Ptr(P) {} -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} OwningPtr &operator=(OwningPtr &&Other) { @@ -95,7 +95,7 @@ class OwningArrayPtr { public: explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} OwningArrayPtr &operator=(OwningArrayPtr &&Other) { diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 71c379bad5..cce2efb6ac 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -57,11 +57,13 @@ class PointerIntPair { }; public: PointerIntPair() : Value(0) {} - PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { + PointerIntPair(PointerTy Ptr, IntType Int) { assert(IntBits <= PtrTraits::NumLowBitsAvailable && "PointerIntPair formed with integer size too large for pointer"); - setPointer(Ptr); - setInt(Int); + setPointerAndInt(Ptr, Int); + } + explicit PointerIntPair(PointerTy Ptr) { + initWithPointer(Ptr); } PointerTy getPointer() const { @@ -91,6 +93,25 @@ public: Value |= IntVal << IntShift; // Set new integer. } + void initWithPointer(PointerTy Ptr) { + intptr_t PtrVal + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); + assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + Value = PtrVal; + } + + void setPointerAndInt(PointerTy Ptr, IntType Int) { + intptr_t PtrVal + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); + assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + intptr_t IntVal = Int; + assert(IntVal < (1 << IntBits) && "Integer too large for field"); + + Value = PtrVal | (IntVal << IntShift); + } + PointerTy const *getAddrOfPointer() const { return const_cast<PointerIntPair *>(this)->getAddrOfPointer(); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index a9e86d2200..f42515ac77 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -95,15 +95,11 @@ namespace llvm { public: PointerUnion() {} - PointerUnion(PT1 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))); - Val.setInt(0); + PointerUnion(PT1 V) : Val( + const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) { } - PointerUnion(PT2 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V))); - Val.setInt(1); + PointerUnion(PT2 V) : Val( + const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) { } /// isNull - Return true if the pointer held in the union is null, @@ -160,15 +156,14 @@ namespace llvm { /// Assignment operators - Allow assigning into this union from either /// pointer type, setting the discriminator to remember what it came from. const PointerUnion &operator=(const PT1 &RHS) { - Val.setPointer( + Val.initWithPointer( const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS))); - Val.setInt(0); return *this; } const PointerUnion &operator=(const PT2 &RHS) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS))); - Val.setInt(1); + Val.setPointerAndInt( + const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)), + 1); return *this; } diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index 48436c6674..8ce4fd53ba 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -21,8 +21,8 @@ #ifndef LLVM_ADT_SCCITERATOR_H #define LLVM_ADT_SCCITERATOR_H -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" #include <vector> namespace llvm { diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index a9cd54e13b..62620fa267 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -153,7 +153,7 @@ public: switchToLarge(new BitVector(*RHS.getPointer())); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { RHS.X = 1; } @@ -472,7 +472,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES const SmallBitVector &operator=(SmallBitVector &&RHS) { if (this != &RHS) { clear(); diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h index cd117f59ba..4eb7de895a 100644 --- a/include/llvm/ADT/SmallSet.h +++ b/include/llvm/ADT/SmallSet.h @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_SMALLSET_H #define LLVM_ADT_SMALLSET_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include <set> namespace llvm { diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index e508f9df90..951e5741ff 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -178,7 +178,7 @@ protected: /// std::move, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) *Dest = ::std::move(*I); return Dest; @@ -193,7 +193,7 @@ protected: /// std::move_backward, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move_backward(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES while (I != E) *--Dest = ::std::move(*--E); return Dest; @@ -206,7 +206,7 @@ protected: /// memory starting with "Dest", constructing elements as needed. template<typename It1, typename It2> static void uninitialized_move(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) ::new ((void*) &*Dest) T(::std::move(*I)); #else @@ -239,7 +239,7 @@ public: goto Retry; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES void push_back(T &&Elt) { if (this->EndX < this->CapacityX) { Retry: @@ -422,7 +422,7 @@ public: } T pop_back_val() { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES T Result = ::std::move(this->back()); #else T Result = this->back(); @@ -495,7 +495,7 @@ public: return(N); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES iterator insert(iterator I, T &&Elt) { if (I == this->end()) { // Important special case for empty vector. this->push_back(::std::move(Elt)); @@ -667,7 +667,7 @@ public: SmallVectorImpl &operator=(const SmallVectorImpl &RHS); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallVectorImpl &operator=(SmallVectorImpl &&RHS); #endif @@ -787,7 +787,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>:: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES template <typename T> SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { // Avoid self-assignment. @@ -898,7 +898,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS)); diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h index 063c6755c6..267a340a75 100644 --- a/include/llvm/ADT/SparseSet.h +++ b/include/llvm/ADT/SparseSet.h @@ -20,8 +20,8 @@ #ifndef LLVM_ADT_SPARSESET_H #define LLVM_ADT_SPARSESET_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include <limits> diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index bf27c4313f..9503e0f805 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { template<typename T> class SmallVectorImpl; diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 292bde0cd9..0e93f51ef0 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -11,7 +11,6 @@ #define LLVM_ADT_STRINGREF_H #include "llvm/Support/type_traits.h" - #include <algorithm> #include <cassert> #include <cstring> diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index d3d33b8add..cc0e7b6381 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -70,7 +70,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { RHS.Val = (EltTy)0; } diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index f317c190b0..49d9f68404 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -100,8 +100,8 @@ public: Haiku, Minix, RTEMS, - NativeClient, - CNK, // BG/P Compute-Node Kernel + NaCl, // Native Client + CNK, // BG/P Compute-Node Kernel Bitrig, AIX }; @@ -310,9 +310,9 @@ public: return getOS() == Triple::Win32 || isOSCygMing(); } - /// \brief isOSNaCl - Is this the Native Client OS. + /// \brief Tests whether the OS is NaCl (Native Client) bool isOSNaCl() const { - return getOS() == Triple::NativeClient; + return getOS() == Triple::NaCl; } /// \brief Tests whether the OS uses the ELF binary format. diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h index d23fccf3e8..b4fed7a0eb 100644 --- a/include/llvm/ADT/ValueMap.h +++ b/include/llvm/ADT/ValueMap.h @@ -27,10 +27,9 @@ #define LLVM_ADT_VALUEMAP_H #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Mutex.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/type_traits.h" -#include "llvm/Support/Mutex.h" - #include <iterator> namespace llvm { diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index be274afd15..3ce4732eca 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -37,8 +37,8 @@ #ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H -#include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/CallSite.h" namespace llvm { @@ -373,7 +373,7 @@ public: return getModRefInfo(I, Location(P, Size)); } - /// getModRefInfo (for call sites) - Return whether information about whether + /// getModRefInfo (for call sites) - Return information about whether /// a particular call site modifies or reads the specified memory location. virtual ModRefResult getModRefInfo(ImmutableCallSite CS, const Location &Loc); @@ -384,7 +384,7 @@ public: return getModRefInfo(CS, Location(P, Size)); } - /// getModRefInfo (for calls) - Return whether information about whether + /// getModRefInfo (for calls) - Return information about whether /// a particular call modifies or reads the specified memory location. ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) { return getModRefInfo(ImmutableCallSite(C), Loc); @@ -395,7 +395,7 @@ public: return getModRefInfo(C, Location(P, Size)); } - /// getModRefInfo (for invokes) - Return whether information about whether + /// getModRefInfo (for invokes) - Return information about whether /// a particular invoke modifies or reads the specified memory location. ModRefResult getModRefInfo(const InvokeInst *I, const Location &Loc) { @@ -408,7 +408,7 @@ public: return getModRefInfo(I, Location(P, Size)); } - /// getModRefInfo (for loads) - Return whether information about whether + /// getModRefInfo (for loads) - Return information about whether /// a particular load modifies or reads the specified memory location. ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc); @@ -417,7 +417,7 @@ public: return getModRefInfo(L, Location(P, Size)); } - /// getModRefInfo (for stores) - Return whether information about whether + /// getModRefInfo (for stores) - Return information about whether /// a particular store modifies or reads the specified memory location. ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc); @@ -426,7 +426,7 @@ public: return getModRefInfo(S, Location(P, Size)); } - /// getModRefInfo (for fences) - Return whether information about whether + /// getModRefInfo (for fences) - Return information about whether /// a particular store modifies or reads the specified memory location. ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) { // Conservatively correct. (We could possibly be a bit smarter if @@ -439,7 +439,7 @@ public: return getModRefInfo(S, Location(P, Size)); } - /// getModRefInfo (for cmpxchges) - Return whether information about whether + /// getModRefInfo (for cmpxchges) - Return information about whether /// a particular cmpxchg modifies or reads the specified memory location. ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc); @@ -449,7 +449,7 @@ public: return getModRefInfo(CX, Location(P, Size)); } - /// getModRefInfo (for atomicrmws) - Return whether information about whether + /// getModRefInfo (for atomicrmws) - Return information about whether /// a particular atomicrmw modifies or reads the specified memory location. ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc); @@ -459,7 +459,7 @@ public: return getModRefInfo(RMW, Location(P, Size)); } - /// getModRefInfo (for va_args) - Return whether information about whether + /// getModRefInfo (for va_args) - Return information about whether /// a particular va_arg modifies or reads the specified memory location. ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); @@ -587,9 +587,9 @@ bool isNoAliasCall(const Value *V); /// isIdentifiedObject - Return true if this pointer refers to a distinct and /// identifiable object. This returns true for: /// Global Variables and Functions (but not Global Aliases) -/// Allocas and Mallocs +/// Allocas /// ByVal and NoAlias Arguments -/// NoAlias returns +/// NoAlias returns (e.g. calls to malloc) /// bool isIdentifiedObject(const Value *V); diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 1e606c81d9..163331c262 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -17,11 +17,11 @@ #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H #define LLVM_ANALYSIS_ALIASSETTRACKER_H -#include "llvm/Support/CallSite.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Support/CallSite.h" +#include "llvm/Support/ValueHandle.h" #include <vector> namespace llvm { diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h index 5168ab7872..c7b36846dd 100644 --- a/include/llvm/Analysis/BlockFrequencyImpl.h +++ b/include/llvm/Analysis/BlockFrequencyImpl.h @@ -14,17 +14,17 @@ #ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H #define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H -#include "llvm/BasicBlock.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/BasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include <vector> #include <string> +#include <vector> namespace llvm { diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index c0567daa3a..6c23f7c3ae 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -14,10 +14,10 @@ #ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H -#include "llvm/InitializePasses.h" -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" namespace llvm { diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h index 4704a929ac..2af7a0253e 100644 --- a/include/llvm/Analysis/CFGPrinter.h +++ b/include/llvm/Analysis/CFGPrinter.h @@ -15,10 +15,10 @@ #ifndef LLVM_ANALYSIS_CFGPRINTER_H #define LLVM_ANALYSIS_CFGPRINTER_H +#include "llvm/Assembly/Writer.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/GraphWriter.h" diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 6a9ed31037..d8b80df8fc 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -51,13 +51,13 @@ #ifndef LLVM_ANALYSIS_CALLGRAPH_H #define LLVM_ANALYSIS_CALLGRAPH_H -#include "llvm/Function.h" -#include "llvm/Pass.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Function.h" +#include "llvm/Pass.h" #include "llvm/Support/CallSite.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/IncludeFile.h" +#include "llvm/Support/ValueHandle.h" #include <map> namespace llvm { diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h index 2889269b95..6ebe2d77be 100644 --- a/include/llvm/Analysis/CaptureTracking.h +++ b/include/llvm/Analysis/CaptureTracking.h @@ -14,9 +14,9 @@ #ifndef LLVM_ANALYSIS_CAPTURETRACKING_H #define LLVM_ANALYSIS_CAPTURETRACKING_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Support/CallSite.h" namespace llvm { diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h index b701b8fca5..bd8c4a100f 100644 --- a/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -14,8 +14,8 @@ #ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H #define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H -#include "llvm/Pass.h" #include "llvm/Analysis/CFGPrinter.h" +#include "llvm/Pass.h" namespace llvm { template <class Analysis, bool Simple> diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h index 1983c00c57..850413faf3 100644 --- a/include/llvm/Analysis/DependenceAnalysis.h +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -40,9 +40,9 @@ #ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H +#include "llvm/ADT/SmallBitVector.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" -#include "llvm/ADT/SmallBitVector.h" namespace llvm { class AliasAnalysis; diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h index 0c29236dde..c0f95cbd9b 100644 --- a/include/llvm/Analysis/DominatorInternals.h +++ b/include/llvm/Analysis/DominatorInternals.h @@ -10,8 +10,8 @@ #ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H #define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H -#include "llvm/Analysis/Dominators.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/Dominators.h" //===----------------------------------------------------------------------===// // diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 8940971558..c69b1edec7 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -15,13 +15,13 @@ #ifndef LLVM_ANALYSIS_DOMINATORS_H #define LLVM_ANALYSIS_DOMINATORS_H -#include "llvm/Pass.h" -#include "llvm/Function.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Function.h" +#include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 82a3a566c9..515cbce345 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -14,11 +14,11 @@ #ifndef LLVM_ANALYSIS_INLINECOST_H #define LLVM_ANALYSIS_INLINECOST_H -#include "llvm/Function.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/ValueMap.h" #include "llvm/Analysis/CodeMetrics.h" +#include "llvm/Function.h" #include <cassert> #include <climits> #include <vector> diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 6db400c563..e9b72a2fa7 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -25,6 +25,7 @@ namespace llvm { class DominatorTree; class Instruction; class DataLayout; + class FastMathFlags; class TargetLibraryInfo; class Type; class Value; @@ -43,6 +44,14 @@ namespace llvm { const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); + /// Given operands for an FMul, see if we can fold the result. If not, this + /// returns null. + Value *SimplifyFMulInst(Value *LHS, Value *RHS, + FastMathFlags FMF, + const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + /// SimplifyMulInst - Given operands for a Mul, see if we can /// fold the result. If not, this returns null. Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index c5d7b0128e..830754ded1 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -30,14 +30,14 @@ #ifndef LLVM_ANALYSIS_LOOP_INFO_H #define LLVM_ANALYSIS_LOOP_INFO_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 3bb96f96bf..4b8e4c9f82 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -15,8 +15,8 @@ #ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H #define LLVM_ANALYSIS_LOOP_INFO_IMPL_H -#include "llvm/Analysis/LoopInfo.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/Analysis/LoopInfo.h" namespace llvm { diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index e6ed9bccee..4c16daffc0 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -16,9 +16,9 @@ #define LLVM_LOOP_PASS_H #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/PassManagers.h" -#include "llvm/Function.h" #include <deque> namespace llvm { @@ -39,6 +39,9 @@ public: // whatever action is necessary for the specified Loop. virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + // Initialization and finalization hooks. virtual bool doInitialization(Loop *L, LPPassManager &LPM) { return false; diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index a842898e41..a797374a59 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -15,12 +15,12 @@ #ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H #define LLVM_ANALYSIS_MEMORYBUILTINS_H -#include "llvm/IRBuilder.h" -#include "llvm/Operator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IRBuilder.h" +#include "llvm/InstVisitor.h" +#include "llvm/Operator.h" #include "llvm/Support/DataTypes.h" -#include "llvm/Support/InstVisitor.h" #include "llvm/Support/TargetFolder.h" #include "llvm/Support/ValueHandle.h" diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index a715eaeee1..121eede1c0 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -14,14 +14,14 @@ #ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H #define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H -#include "llvm/BasicBlock.h" -#include "llvm/Pass.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/BasicBlock.h" +#include "llvm/Pass.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { class Function; diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index 5a77fcebaf..781ac07114 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -14,8 +14,8 @@ #ifndef LLVM_ANALYSIS_PHITRANSADDR_H #define LLVM_ANALYSIS_PHITRANSADDR_H -#include "llvm/Instruction.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Instruction.h" namespace llvm { class DominatorTree; diff --git a/include/llvm/Analysis/PathNumbering.h b/include/llvm/Analysis/PathNumbering.h index 7025e28484..a9f76219f4 100644 --- a/include/llvm/Analysis/PathNumbering.h +++ b/include/llvm/Analysis/PathNumbering.h @@ -26,11 +26,11 @@ #ifndef LLVM_PATH_NUMBERING_H #define LLVM_PATH_NUMBERING_H +#include "llvm/Analysis/ProfileInfoTypes.h" #include "llvm/BasicBlock.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" -#include "llvm/Analysis/ProfileInfoTypes.h" #include <map> #include <stack> #include <vector> diff --git a/include/llvm/Analysis/PathProfileInfo.h b/include/llvm/Analysis/PathProfileInfo.h index cef6d2d2a6..53880694f0 100644 --- a/include/llvm/Analysis/PathProfileInfo.h +++ b/include/llvm/Analysis/PathProfileInfo.h @@ -14,8 +14,8 @@ #ifndef LLVM_PATHPROFILEINFO_H #define LLVM_PATHPROFILEINFO_H -#include "llvm/BasicBlock.h" #include "llvm/Analysis/PathNumbering.h" +#include "llvm/BasicBlock.h" namespace llvm { diff --git a/include/llvm/Analysis/ProfileDataLoader.h b/include/llvm/Analysis/ProfileDataLoader.h index 9efbafcef4..90097f7995 100644 --- a/include/llvm/Analysis/ProfileDataLoader.h +++ b/include/llvm/Analysis/ProfileDataLoader.h @@ -16,6 +16,7 @@ #ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H #define LLVM_ANALYSIS_PROFILEDATALOADER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h index 6c2e2732d3..5d17fa1220 100644 --- a/include/llvm/Analysis/ProfileInfo.h +++ b/include/llvm/Analysis/ProfileInfo.h @@ -26,9 +26,9 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <cassert> -#include <string> #include <map> #include <set> +#include <string> namespace llvm { class Pass; diff --git a/include/llvm/Analysis/ProfileInfoLoader.h b/include/llvm/Analysis/ProfileInfoLoader.h index dcf3b38ddc..e0f49f3179 100644 --- a/include/llvm/Analysis/ProfileInfoLoader.h +++ b/include/llvm/Analysis/ProfileInfoLoader.h @@ -16,9 +16,9 @@ #ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H #define LLVM_ANALYSIS_PROFILEINFOLOADER_H -#include <vector> #include <string> #include <utility> +#include <vector> namespace llvm { diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h new file mode 100644 index 0000000000..e15f2b45a8 --- /dev/null +++ b/include/llvm/Analysis/PtrUseVisitor.h @@ -0,0 +1,286 @@ +//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides a collection of visitors which walk the (instruction) +/// uses of a pointer. These visitors all provide the same essential behavior +/// as an InstVisitor with similar template-based flexibility and +/// implementation strategies. +/// +/// These can be used, for example, to quickly analyze the uses of an alloca, +/// global variable, or function argument. +/// +/// FIXME: Provide a variant which doesn't track offsets and is cheaper. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H +#define LLVM_ANALYSIS_PTRUSEVISITOR_H + +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/DataLayout.h" +#include "llvm/InstVisitor.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" + +namespace llvm { + +namespace detail { +/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor. +/// +/// See \c PtrUseVisitor for the public interface and detailed comments about +/// usage. This class is just a helper base class which is not templated and +/// contains all common code to be shared between different instantiations of +/// PtrUseVisitor. +class PtrUseVisitorBase { +public: + /// \brief This class provides information about the result of a visit. + /// + /// After walking all the users (recursively) of a pointer, the basic + /// infrastructure records some commonly useful information such as escape + /// analysis and whether the visit completed or aborted early. + class PtrInfo { + public: + PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {} + + /// \brief Reset the pointer info, clearing all state. + void reset() { + AbortedInfo.setPointer(0); + AbortedInfo.setInt(false); + EscapedInfo.setPointer(0); + EscapedInfo.setInt(false); + } + + /// \brief Did we abort the visit early? + bool isAborted() const { return AbortedInfo.getInt(); } + + /// \brief Is the pointer escaped at some point? + bool isEscaped() const { return EscapedInfo.getInt(); } + + /// \brief Get the instruction causing the visit to abort. + /// \returns a pointer to the instruction causing the abort if one is + /// available; otherwise returns null. + Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); } + + /// \brief Get the instruction causing the pointer to escape. + /// \returns a pointer to the instruction which escapes the pointer if one + /// is available; otherwise returns null. + Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); } + + /// \brief Mark the visit as aborted. Intended for use in a void return. + /// \param I The instruction which caused the visit to abort, if available. + void setAborted(Instruction *I = 0) { + AbortedInfo.setInt(true); + AbortedInfo.setPointer(I); + } + + /// \brief Mark the pointer as escaped. Intended for use in a void return. + /// \param I The instruction which escapes the pointer, if available. + void setEscaped(Instruction *I = 0) { + EscapedInfo.setInt(true); + EscapedInfo.setPointer(I); + } + + /// \brief Mark the pointer as escaped, and the visit as aborted. Intended + /// for use in a void return. + /// \param I The instruction which both escapes the pointer and aborts the + /// visit, if available. + void setEscapedAndAborted(Instruction *I = 0) { + setEscaped(I); + setAborted(I); + } + + private: + PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo; + }; + +protected: + const DataLayout &DL; + + /// \name Visitation infrastructure + /// @{ + + /// \brief The info collected about the pointer being visited thus far. + PtrInfo PI; + + /// \brief A struct of the data needed to visit a particular use. + /// + /// This is used to maintain a worklist fo to-visit uses. This is used to + /// make the visit be iterative rather than recursive. + struct UseToVisit { + typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair; + UseAndIsOffsetKnownPair UseAndIsOffsetKnown; + APInt Offset; + }; + + /// \brief The worklist of to-visit uses. + SmallVector<UseToVisit, 8> Worklist; + + /// \brief A set of visited uses to break cycles in unreachable code. + SmallPtrSet<Use *, 8> VisitedUses; + + /// @} + + + /// \name Per-visit state + /// This state is reset for each instruction visited. + /// @{ + + /// \brief The use currently being visited. + Use *U; + + /// \brief True if we have a known constant offset for the use currently + /// being visited. + bool IsOffsetKnown; + + /// \brief The constant offset of the use if that is known. + APInt Offset; + + /// @} + + + /// Note that the constructor is protected because this class must be a base + /// class, we can't create instances directly of this class. + PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} + + /// \brief Enqueue the users of this instruction in the visit worklist. + /// + /// This will visit the users with the same offset of the current visit + /// (including an unknown offset if that is the current state). + void enqueueUsers(Instruction &I); + + /// \brief Walk the operands of a GEP and adjust the offset as appropriate. + /// + /// This routine does the heavy lifting of the pointer walk by computing + /// offsets and looking through GEPs. + bool adjustOffsetForGEP(GetElementPtrInst &GEPI); +}; +} // end namespace detail + +/// \brief A base class for visitors over the uses of a pointer value. +/// +/// Once constructed, a user can call \c visit on a pointer value, and this +/// will walk its uses and visit each instruction using an InstVisitor. It also +/// provides visit methods which will recurse through any pointer-to-pointer +/// transformations such as GEPs and bitcasts. +/// +/// During the visit, the current Use* being visited is available to the +/// subclass, as well as the current offset from the original base pointer if +/// known. +/// +/// The recursive visit of uses is accomplished with a worklist, so the only +/// ordering guarantee is that an instruction is visited before any uses of it +/// are visited. Note that this does *not* mean before any of its users are +/// visited! This is because users can be visited multiple times due to +/// multiple, different uses of pointers derived from the same base. +/// +/// A particular Use will only be visited once, but a User may be visited +/// multiple times, once per Use. This visits may notably have different +/// offsets. +/// +/// All visit methods on the underlying InstVisitor return a boolean. This +/// return short-circuits the visit, stopping it immediately. +/// +/// FIXME: Generalize this for all values rather than just instructions. +template <typename DerivedT> +class PtrUseVisitor : protected InstVisitor<DerivedT>, + public detail::PtrUseVisitorBase { + friend class InstVisitor<DerivedT>; + typedef InstVisitor<DerivedT> Base; + +public: + PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {} + + /// \brief Recursively visit the uses of the given pointer. + /// \returns An info struct about the pointer. See \c PtrInfo for details. + PtrInfo visitPtr(Instruction &I) { + // This must be a pointer type. Get an integer type suitable to hold + // offsets on this pointer. + // FIXME: Support a vector of pointers. + assert(I.getType()->isPointerTy()); + IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType())); + IsOffsetKnown = true; + Offset = APInt(IntPtrTy->getBitWidth(), 0); + PI.reset(); + + // Enqueue the uses of this pointer. + enqueueUsers(I); + + // Visit all the uses off the worklist until it is empty. + while (!Worklist.empty()) { + UseToVisit ToVisit = Worklist.pop_back_val(); + U = ToVisit.UseAndIsOffsetKnown.getPointer(); + IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt(); + if (IsOffsetKnown) + Offset = llvm_move(ToVisit.Offset); + + Instruction *I = cast<Instruction>(U->getUser()); + static_cast<DerivedT*>(this)->visit(I); + if (PI.isAborted()) + break; + } + return PI; + } + +protected: + void visitStoreInst(StoreInst &SI) { + if (SI.getValueOperand() == U->get()) + PI.setEscaped(&SI); + } + + void visitBitCastInst(BitCastInst &BC) { + enqueueUsers(BC); + } + + void visitPtrToIntInst(PtrToIntInst &I) { + PI.setEscaped(&I); + } + + void visitGetElementPtrInst(GetElementPtrInst &GEPI) { + if (GEPI.use_empty()) + return; + + // If we can't walk the GEP, clear the offset. + if (!adjustOffsetForGEP(GEPI)) { + IsOffsetKnown = false; + Offset = APInt(); + } + + // Enqueue the users now that the offset has been adjusted. + enqueueUsers(GEPI); + } + + // No-op intrinsics which we know don't escape the pointer to to logic in + // some other function. + void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {} + void visitMemIntrinsic(MemIntrinsic &I) {} + void visitIntrinsicInst(IntrinsicInst &II) { + switch (II.getIntrinsicID()) { + default: + return Base::visitIntrinsicInst(II); + + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + return; // No-op intrinsics. + } + } + + // Generically, arguments to calls and invokes escape the pointer to some + // other function. Mark that. + void visitCallSite(CallSite CS) { + PI.setEscaped(CS.getInstruction()); + Base::visitCallSite(CS); + } +}; + +} + +#endif diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h index 7adc71ca82..bcff2276d0 100644 --- a/include/llvm/Analysis/RegionIterator.h +++ b/include/llvm/Analysis/RegionIterator.h @@ -12,8 +12,8 @@ #define LLVM_ANALYSIS_REGION_ITERATOR_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index 68f12012bc..7d450887f0 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -17,11 +17,9 @@ #define LLVM_REGION_PASS_H #include "llvm/Analysis/RegionInfo.h" - +#include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/PassManagers.h" -#include "llvm/Function.h" - #include <deque> namespace llvm { @@ -59,6 +57,9 @@ public: /// @return The pass to print the LLVM IR in the region. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; } virtual bool doFinalization() { return false; } //@} diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 235adca021..dcefaa04e0 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -21,16 +21,16 @@ #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H #define LLVM_ANALYSIS_SCALAREVOLUTION_H -#include "llvm/Pass.h" -#include "llvm/Instructions.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/Function.h" +#include "llvm/Instructions.h" #include "llvm/Operator.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/ValueHandle.h" +#include "llvm/Pass.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ConstantRange.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/ValueHandle.h" #include <map> namespace llvm { diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 3f8f149cb4..95772a887f 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -14,9 +14,9 @@ #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H -#include "llvm/IRBuilder.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionNormalization.h" +#include "llvm/IRBuilder.h" #include "llvm/Support/TargetFolder.h" #include "llvm/Support/ValueHandle.h" #include <set> diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 54db7d6bcf..b74cb33285 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -14,8 +14,8 @@ #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H -#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h index b758eca42e..604e30666e 100644 --- a/include/llvm/Analysis/SparsePropagation.h +++ b/include/llvm/Analysis/SparsePropagation.h @@ -17,8 +17,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" -#include <vector> #include <set> +#include <vector> namespace llvm { class Value; diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h index 99651e192d..26947fe34f 100644 --- a/include/llvm/Analysis/Trace.h +++ b/include/llvm/Analysis/Trace.h @@ -18,8 +18,8 @@ #ifndef LLVM_ANALYSIS_TRACE_H #define LLVM_ANALYSIS_TRACE_H -#include <vector> #include <cassert> +#include <vector> namespace llvm { class BasicBlock; diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index b1c2218519..dc9df34c60 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -14,10 +14,10 @@ #ifndef LLVM_ARGUMENT_H #define LLVM_ARGUMENT_H -#include "llvm/Value.h" -#include "llvm/Attributes.h" -#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/Attributes.h" +#include "llvm/Value.h" namespace llvm { diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 6c352de2a9..ed18ca4c40 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -15,8 +15,8 @@ #ifndef LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H -#include "llvm/Support/MathExtras.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/MathExtras.h" #include <cassert> #include <string> @@ -298,14 +298,14 @@ struct AttributeWithIndex { }; //===----------------------------------------------------------------------===// -// AttrListPtr Smart Pointer +// AttributeSet Smart Pointer //===----------------------------------------------------------------------===// class AttributeListImpl; -/// AttrListPtr - This class manages the ref count for the opaque +/// AttributeSet - This class manages the ref count for the opaque /// AttributeListImpl object and provides accessors for it. -class AttrListPtr { +class AttributeSet { public: enum AttrIndex { ReturnIndex = 0U, @@ -320,28 +320,28 @@ private: /// for the result are denoted with Idx = 0. Attributes getAttributes(unsigned Idx) const; - explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {} + explicit AttributeSet(AttributeListImpl *LI) : AttrList(LI) {} public: - AttrListPtr() : AttrList(0) {} - AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {} - const AttrListPtr &operator=(const AttrListPtr &RHS); + AttributeSet() : AttrList(0) {} + AttributeSet(const AttributeSet &P) : AttrList(P.AttrList) {} + const AttributeSet &operator=(const AttributeSet &RHS); //===--------------------------------------------------------------------===// // Attribute List Construction and Mutation //===--------------------------------------------------------------------===// /// get - Return a Attributes list with the specified parameters in it. - static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs); + static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs); /// addAttr - Add the specified attribute at the specified index to this /// attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; + AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; /// removeAttr - Remove the specified attribute at the specified index from /// this attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; + AttributeSet removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; //===--------------------------------------------------------------------===// // Attribute List Accessors @@ -383,9 +383,9 @@ public: Attributes &getAttributesAtIndex(unsigned i) const; /// operator==/!= - Provide equality predicates. - bool operator==(const AttrListPtr &RHS) const + bool operator==(const AttributeSet &RHS) const { return AttrList == RHS.AttrList; } - bool operator!=(const AttrListPtr &RHS) const + bool operator!=(const AttributeSet &RHS) const { return AttrList != RHS.AttrList; } //===--------------------------------------------------------------------===// diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 02c2a96b6c..ba8406e397 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -14,11 +14,11 @@ #ifndef LLVM_BASICBLOCK_H #define LLVM_BASICBLOCK_H -#include "llvm/Instruction.h" -#include "llvm/SymbolTableListTraits.h" -#include "llvm/ADT/ilist.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist.h" +#include "llvm/Instruction.h" #include "llvm/Support/DataTypes.h" +#include "llvm/SymbolTableListTraits.h" namespace llvm { diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 2e8c9f46b8..1021fbd0dc 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -15,8 +15,8 @@ #ifndef BITSTREAM_WRITER_H #define BITSTREAM_WRITER_H -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitCodes.h" #include <vector> diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 511e3a377a..601777d11a 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -54,6 +54,8 @@ namespace bitc { MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] MODULE_CODE_ASM = 4, // ASM: [strchr x N] MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] + + // FIXME: Remove DEPLIB in 4.0. MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] // GLOBALVAR: [pointer type, isconst, initid, diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/CallGraphSCCPass.h index 7154aa3259..4446777669 100644 --- a/include/llvm/CallGraphSCCPass.h +++ b/include/llvm/CallGraphSCCPass.h @@ -21,8 +21,8 @@ #ifndef LLVM_CALL_GRAPH_SCC_PASS_H #define LLVM_CALL_GRAPH_SCC_PASS_H -#include "llvm/Pass.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Pass.h" namespace llvm { @@ -39,6 +39,9 @@ public: /// corresponding to a CallGraph. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + /// doInitialization - This method is called before the SCC's of the program /// has been processed, allowing the pass to do initialization as necessary. virtual bool doInitialization(CallGraph &CG) { diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index 0b609ed658..4ff0be758a 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -14,12 +14,12 @@ #ifndef LLVM_CODEGEN_ANALYSIS_H #define LLVM_CODEGEN_ANALYSIS_H -#include "llvm/Instructions.h" -#include "llvm/InlineAsm.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" #include "llvm/Support/CallSite.h" namespace llvm { diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 2f76a6cc55..9cd2decfac 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -11,8 +11,8 @@ #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H -#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/SlotIndexes.h" namespace llvm { diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index c1bc3aba5e..064a92ef36 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -16,11 +16,11 @@ #define LLVM_CODEGEN_CALLINGCONVLOWER_H #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CallingConv.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Target/TargetCallingConv.h" -#include "llvm/CallingConv.h" namespace llvm { class TargetRegisterInfo; diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index 90ee234244..e7a654b423 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -16,10 +16,9 @@ #ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H #define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H -#include "llvm/Support/CommandLine.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetMachine.h" - #include <string> using namespace llvm; diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h index e4386fc8e2..9d25fd377b 100644 --- a/include/llvm/CodeGen/DFAPacketizer.h +++ b/include/llvm/CodeGen/DFAPacketizer.h @@ -26,8 +26,8 @@ #ifndef LLVM_CODEGEN_DFAPACKETIZER_H #define LLVM_CODEGEN_DFAPACKETIZER_H -#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include <map> namespace llvm { diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 7c24e36092..05619050a3 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -15,8 +15,8 @@ #define LLVM_CODEGEN_FASTISEL_H #include "llvm/ADT/DenseMap.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/ValueTypes.h" namespace llvm { @@ -131,6 +131,10 @@ public: /// into the current block. void recomputeInsertPt(); + /// removeDeadCode - Remove all dead instructions between the I and E. + void removeDeadCode(MachineBasicBlock::iterator I, + MachineBasicBlock::iterator E); + struct SavePoint { MachineBasicBlock::iterator InsertPt; DebugLoc DL; @@ -395,10 +399,6 @@ private: /// hasTrivialKill - Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V) const; - - /// removeDeadCode - Remove all dead instructions between the I and E. - void removeDeadCode(MachineBasicBlock::iterator I, - MachineBasicBlock::iterator E); }; } diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 8cf22eca4f..789f77f26e 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -15,8 +15,6 @@ #ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H #define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -24,9 +22,11 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/BranchProbabilityInfo.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" #include "llvm/Support/CallSite.h" #include "llvm/Target/TargetRegisterInfo.h" #include <vector> diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 076f6f39fe..fa40049dbd 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -33,9 +33,9 @@ #ifndef LLVM_CODEGEN_GCMETADATA_H #define LLVM_CODEGEN_GCMETADATA_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Pass.h" #include "llvm/Support/DebugLoc.h" namespace llvm { diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index f95b8b6b84..e14d04e422 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -17,11 +17,11 @@ #ifndef LLVM_CODEGEN_JITCODEEMITTER_H #define LLVM_CODEGEN_JITCODEEMITTER_H -#include <string> +#include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MathExtras.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include "llvm/ADT/DenseMap.h" +#include <string> namespace llvm { diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index e1911cfd82..bb22cb74c5 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -17,11 +17,11 @@ #ifndef LLVM_CODEGEN_LEXICALSCOPES_H #define LLVM_CODEGEN_LEXICALSCOPES_H -#include "llvm/Metadata.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Metadata.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Support/ValueHandle.h" #include <utility> diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 46dd004609..2145eb80bd 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -15,9 +15,9 @@ #ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H +#include "llvm/CodeGen/GCs.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/CodeGen/GCs.h" #include "llvm/Target/TargetMachine.h" #include <cstdlib> diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 185e414ae2..95760758de 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -22,9 +22,9 @@ #define LLVM_CODEGEN_LIVEINTERVAL_H #include "llvm/ADT/IntEqClasses.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/AlignOf.h" #include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/Allocator.h" #include <cassert> #include <climits> diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index b421753dd5..9e89519b28 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -20,16 +20,16 @@ #ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H #define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <cmath> #include <iterator> @@ -347,6 +347,10 @@ namespace llvm { return RegUnitIntervals[Unit]; } + const LiveInterval *getCachedRegUnit(unsigned Unit) const { + return RegUnitIntervals[Unit]; + } + private: /// computeIntervals - Compute live intervals. void computeIntervals(); diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h new file mode 100644 index 0000000000..6a61614df4 --- /dev/null +++ b/include/llvm/CodeGen/LiveIntervalUnion.h @@ -0,0 +1,205 @@ +//===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// LiveIntervalUnion is a union of live segments across multiple live virtual +// registers. This may be used during coalescing to represent a congruence +// class, or during register allocation to model liveness of a physical +// register. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVEINTERVALUNION +#define LLVM_CODEGEN_LIVEINTERVALUNION + +#include "llvm/ADT/IntervalMap.h" +#include "llvm/CodeGen/LiveInterval.h" + +namespace llvm { + +class TargetRegisterInfo; + +#ifndef NDEBUG +// forward declaration +template <unsigned Element> class SparseBitVector; +typedef SparseBitVector<128> LiveVirtRegBitSet; +#endif + +/// Compare a live virtual register segment to a LiveIntervalUnion segment. +inline bool +overlap(const LiveRange &VRSeg, + const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) { + return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end; +} + +/// Union of live intervals that are strong candidates for coalescing into a +/// single register (either physical or virtual depending on the context). We +/// expect the constituent live intervals to be disjoint, although we may +/// eventually make exceptions to handle value-based interference. +class LiveIntervalUnion { + // A set of live virtual register segments that supports fast insertion, + // intersection, and removal. + // Mapping SlotIndex intervals to virtual register numbers. + typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments; + +public: + // SegmentIter can advance to the next segment ordered by starting position + // which may belong to a different live virtual register. We also must be able + // to reach the current segment's containing virtual register. + typedef LiveSegments::iterator SegmentIter; + + // LiveIntervalUnions share an external allocator. + typedef LiveSegments::Allocator Allocator; + + class Query; + +private: + unsigned Tag; // unique tag for current contents. + LiveSegments Segments; // union of virtual reg segments + +public: + explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {} + + // Iterate over all segments in the union of live virtual registers ordered + // by their starting position. + SegmentIter begin() { return Segments.begin(); } + SegmentIter end() { return Segments.end(); } + SegmentIter find(SlotIndex x) { return Segments.find(x); } + bool empty() const { return Segments.empty(); } + SlotIndex startIndex() const { return Segments.start(); } + + // Provide public access to the underlying map to allow overlap iteration. + typedef LiveSegments Map; + const Map &getMap() { return Segments; } + + /// getTag - Return an opaque tag representing the current state of the union. + unsigned getTag() const { return Tag; } + + /// changedSince - Return true if the union change since getTag returned tag. + bool changedSince(unsigned tag) const { return tag != Tag; } + + // Add a live virtual register to this union and merge its segments. + void unify(LiveInterval &VirtReg); + + // Remove a live virtual register's segments from this union. + void extract(LiveInterval &VirtReg); + + // Remove all inserted virtual registers. + void clear() { Segments.clear(); ++Tag; } + + // Print union, using TRI to translate register names + void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const; + +#ifndef NDEBUG + // Verify the live intervals in this union and add them to the visited set. + void verify(LiveVirtRegBitSet& VisitedVRegs); +#endif + + /// Query interferences between a single live virtual register and a live + /// interval union. + class Query { + LiveIntervalUnion *LiveUnion; + LiveInterval *VirtReg; + LiveInterval::iterator VirtRegI; // current position in VirtReg + SegmentIter LiveUnionI; // current position in LiveUnion + SmallVector<LiveInterval*,4> InterferingVRegs; + bool CheckedFirstInterference; + bool SeenAllInterferences; + bool SeenUnspillableVReg; + unsigned Tag, UserTag; + + public: + Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {} + + Query(LiveInterval *VReg, LiveIntervalUnion *LIU): + LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false), + SeenAllInterferences(false), SeenUnspillableVReg(false) + {} + + void clear() { + LiveUnion = NULL; + VirtReg = NULL; + InterferingVRegs.clear(); + CheckedFirstInterference = false; + SeenAllInterferences = false; + SeenUnspillableVReg = false; + Tag = 0; + UserTag = 0; + } + + void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) { + assert(VReg && LIU && "Invalid arguments"); + if (UserTag == UTag && VirtReg == VReg && + LiveUnion == LIU && !LIU->changedSince(Tag)) { + // Retain cached results, e.g. firstInterference. + return; + } + clear(); + LiveUnion = LIU; + VirtReg = VReg; + Tag = LIU->getTag(); + UserTag = UTag; + } + + LiveInterval &virtReg() const { + assert(VirtReg && "uninitialized"); + return *VirtReg; + } + + // Does this live virtual register interfere with the union? + bool checkInterference() { return collectInterferingVRegs(1); } + + // Count the virtual registers in this union that interfere with this + // query's live virtual register, up to maxInterferingRegs. + unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX); + + // Was this virtual register visited during collectInterferingVRegs? + bool isSeenInterference(LiveInterval *VReg) const; + + // Did collectInterferingVRegs collect all interferences? + bool seenAllInterferences() const { return SeenAllInterferences; } + + // Did collectInterferingVRegs encounter an unspillable vreg? + bool seenUnspillableVReg() const { return SeenUnspillableVReg; } + + // Vector generated by collectInterferingVRegs. + const SmallVectorImpl<LiveInterval*> &interferingVRegs() const { + return InterferingVRegs; + } + + private: + Query(const Query&) LLVM_DELETED_FUNCTION; + void operator=(const Query&) LLVM_DELETED_FUNCTION; + }; + + // Array of LiveIntervalUnions. + class Array { + unsigned Size; + LiveIntervalUnion *LIUs; + public: + Array() : Size(0), LIUs(0) {} + ~Array() { clear(); } + + // Initialize the array to have Size entries. + // Reuse an existing allocation if the size matches. + void init(LiveIntervalUnion::Allocator&, unsigned Size); + + unsigned size() const { return Size; } + + void clear(); + + LiveIntervalUnion& operator[](unsigned idx) { + assert(idx < Size && "idx out of bounds"); + return LIUs[idx]; + } + }; +}; + +} // end namespace llvm + +#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION) diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h new file mode 100644 index 0000000000..7a3e9e8347 --- /dev/null +++ b/include/llvm/CodeGen/LiveRegMatrix.h @@ -0,0 +1,148 @@ +//===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRegMatrix analysis pass keeps track of virtual register interference +// along two dimensions: Slot indexes and register units. The matrix is used by +// register allocators to ensure that no interfering virtual registers get +// assigned to overlapping physical registers. +// +// Register units are defined in MCRegisterInfo.h, they represent the smallest +// unit of interference when dealing with overlapping physical registers. The +// LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When +// a virtual register is assigned to a physical register, the live range for +// the virtual register is inserted into the LiveIntervalUnion for each regunit +// in the physreg. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVEREGMATRIX_H +#define LLVM_CODEGEN_LIVEREGMATRIX_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/CodeGen/LiveIntervalUnion.h" +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + +class LiveInterval; +class LiveIntervalAnalysis; +class MachineRegisterInfo; +class TargetRegisterInfo; +class VirtRegMap; + +class LiveRegMatrix : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + LiveIntervals *LIS; + VirtRegMap *VRM; + + // UserTag changes whenever virtual registers have been modified. + unsigned UserTag; + + // The matrix is represented as a LiveIntervalUnion per register unit. + LiveIntervalUnion::Allocator LIUAlloc; + LiveIntervalUnion::Array Matrix; + + // Cached queries per register unit. + OwningArrayPtr<LiveIntervalUnion::Query> Queries; + + // Cached register mask interference info. + unsigned RegMaskTag; + unsigned RegMaskVirtReg; + BitVector RegMaskUsable; + + // MachineFunctionPass boilerplate. + virtual void getAnalysisUsage(AnalysisUsage&) const; + virtual bool runOnMachineFunction(MachineFunction&); + virtual void releaseMemory(); +public: + static char ID; + LiveRegMatrix(); + + //===--------------------------------------------------------------------===// + // High-level interface. + //===--------------------------------------------------------------------===// + // + // Check for interference before assigning virtual registers to physical + // registers. + // + + /// Invalidate cached interference queries after modifying virtual register + /// live ranges. Interference checks may return stale information unless + /// caches are invalidated. + void invalidateVirtRegs() { ++UserTag; } + + enum InterferenceKind { + /// No interference, go ahead and assign. + IK_Free = 0, + + /// Virtual register interference. There are interfering virtual registers + /// assigned to PhysReg or its aliases. This interference could be resolved + /// by unassigning those other virtual registers. + IK_VirtReg, + + /// Register unit interference. A fixed live range is in the way, typically + /// argument registers for a call. This can't be resolved by unassigning + /// other virtual registers. + IK_RegUnit, + + /// RegMask interference. The live range is crossing an instruction with a + /// regmask operand that doesn't preserve PhysReg. This typically means + /// VirtReg is live across a call, and PhysReg isn't call-preserved. + IK_RegMask + }; + + /// Check for interference before assigning VirtReg to PhysReg. + /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg). + /// When there is more than one kind of interference, the InterferenceKind + /// with the highest enum value is returned. + InterferenceKind checkInterference(LiveInterval &VirtReg, unsigned PhysReg); + + /// Assign VirtReg to PhysReg. + /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and + /// update VirtRegMap. The live range is expected to be available in PhysReg. + void assign(LiveInterval &VirtReg, unsigned PhysReg); + + /// Unassign VirtReg from its PhysReg. + /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes + /// the assignment and updates VirtRegMap accordingly. + void unassign(LiveInterval &VirtReg); + + //===--------------------------------------------------------------------===// + // Low-level interface. + //===--------------------------------------------------------------------===// + // + // Provide access to the underlying LiveIntervalUnions. + // + + /// Check for regmask interference only. + /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg. + /// If PhysReg is null, check if VirtReg crosses any regmask operands. + bool checkRegMaskInterference(LiveInterval &VirtReg, unsigned PhysReg = 0); + + /// Check for regunit interference only. + /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's + /// register units. + bool checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg); + + /// Query a line of the assigned virtual register matrix directly. + /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg. + /// This returns a reference to an internal Query data structure that is only + /// valid until the next query() call. + LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit); + + /// Directly access the live interval unions per regunit. + /// This returns an array indexed by the regunit number. + LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; } +}; + +} // end namespace llvm + +#endif // LLVM_CODEGEN_LIVEREGMATRIX_H diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index 86c4d7c110..a3b1855bbc 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -16,10 +16,10 @@ #ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H #define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/LiveInterval.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <map> namespace llvm { diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 3bb134b8fb..3c5ed9297e 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -29,16 +29,16 @@ #ifndef LLVM_CODEGEN_LIVEVARIABLES_H #define LLVM_CODEGEN_LIVEVARIABLES_H -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SparseBitVector.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetRegisterInfo.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 97c39458d9..81912742fa 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -14,8 +14,8 @@ #ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H #define LLVM_CODEGEN_MACHINEBASICBLOCK_H -#include "llvm/CodeGen/MachineInstr.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/Support/DataTypes.h" #include <functional> diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index 12189ceb7f..1c9bdd954c 100644 --- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -15,8 +15,8 @@ #ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H #define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H -#include "llvm/Pass.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" #include <climits> diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 86e8f27877..9e41e6e9c1 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -19,7 +19,6 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" - #include <string> namespace llvm { diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index 82a4ac821b..40b2542fd6 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -15,11 +15,11 @@ #ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H #define LLVM_CODEGEN_MACHINEDOMINATORS_H +#include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/Analysis/DominatorInternals.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 0e4e132e40..93d77287d7 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -221,8 +221,11 @@ class MachineFrameInfo { /// just allocate them normally. bool UseLocalStackAllocationBlock; + /// Whether the "realign-stack" option is on. + bool RealignOption; public: - explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) { + explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt) + : TFI(tfi), RealignOption(RealignOpt) { StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; HasVarSizedObjects = false; FrameAddressTaken = false; @@ -432,9 +435,7 @@ public: /// ensureMaxAlignment - Make sure the function is at least Align bytes /// aligned. - void ensureMaxAlignment(unsigned Align) { - if (MaxAlignment < Align) MaxAlignment = Align; - } + void ensureMaxAlignment(unsigned Align); /// AdjustsStack - Return true if this function adjusts the stack -- e.g., /// when calling another function. This is only valid during and after @@ -496,26 +497,13 @@ public: /// a nonnegative identifier to represent it. /// int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, - bool MayNeedSP = false, const AllocaInst *Alloca = 0) { - assert(Size != 0 && "Cannot allocate zero size stack objects!"); - Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP, - Alloca)); - int Index = (int)Objects.size() - NumFixedObjects - 1; - assert(Index >= 0 && "Bad frame index!"); - ensureMaxAlignment(Alignment); - return Index; - } + bool MayNeedSP = false, const AllocaInst *Alloca = 0); /// CreateSpillStackObject - Create a new statically sized stack object that /// represents a spill slot, returning a nonnegative identifier to represent /// it. /// - int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { - CreateStackObject(Size, Alignment, true, false); - int Index = (int)Objects.size() - NumFixedObjects - 1; - ensureMaxAlignment(Alignment); - return Index; - } + int CreateSpillStackObject(uint64_t Size, unsigned Alignment); /// RemoveStackObject - Remove or mark dead a statically sized stack object. /// @@ -529,12 +517,7 @@ public: /// variable sized object is created, whether or not the index returned is /// actually used. /// - int CreateVariableSizedObject(unsigned Alignment) { - HasVarSizedObjects = true; - Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); - ensureMaxAlignment(Alignment); - return (int)Objects.size()-NumFixedObjects-1; - } + int CreateVariableSizedObject(unsigned Alignment); /// getCalleeSavedInfo - Returns a reference to call saved info vector for the /// current function. diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 025e18a9dd..bb5b23b00c 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -18,10 +18,10 @@ #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H #define LLVM_CODEGEN_MACHINEFUNCTION_H -#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/ilist.h" -#include "llvm/Support/DebugLoc.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/DebugLoc.h" #include "llvm/Support/Recycler.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 7eb03a9301..57da779ca1 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -16,17 +16,17 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/Target/TargetOpcodes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/ilist.h" -#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/InlineAsm.h" +#include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Target/TargetOpcodes.h" #include <vector> namespace llvm { @@ -58,8 +58,8 @@ public: NoFlags = 0, FrameSetup = 1 << 0, // Instruction is used as a part of // function frame setup code. - InsideBundle = 1 << 1 // Instruction is inside a bundle (not - // the first MI in a bundle) + BundledPred = 1 << 1, // Instruction has bundled predecessors. + BundledSucc = 1 << 2 // Instruction has bundled successors. }; private: const MCInstrDesc *MCID; // Instruction descriptor. @@ -94,21 +94,11 @@ private: /// MachineInstr in the given MachineFunction. MachineInstr(MachineFunction &, const MachineInstr &); - /// MachineInstr ctor - This constructor creates a dummy MachineInstr with - /// MCID NULL and no operands. - MachineInstr(); - /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// MCInstrDesc. An explicit DebugLoc is supplied. MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl, bool NoImp = false); - /// MachineInstr ctor - Work exactly the same as the ctor above, except that - /// the MachineInstr is created and added to the end of the specified basic - /// block. - MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, - const MCInstrDesc &MCID); - ~MachineInstr(); // MachineInstrs are pool-allocated and owned by MachineFunction. @@ -205,22 +195,44 @@ public: /// The first instruction has the special opcode "BUNDLE". It's not "inside" /// a bundle, but the next three MIs are. bool isInsideBundle() const { - return getFlag(InsideBundle); + return getFlag(BundledPred); } /// setIsInsideBundle - Set InsideBundle bit. /// void setIsInsideBundle(bool Val = true) { if (Val) - setFlag(InsideBundle); + setFlag(BundledPred); else - clearFlag(InsideBundle); + clearFlag(BundledPred); } /// isBundled - Return true if this instruction part of a bundle. This is true /// if either itself or its following instruction is marked "InsideBundle". bool isBundled() const; + /// Return true if this instruction is part of a bundle, and it is not the + /// first instruction in the bundle. + bool isBundledWithPred() const { return getFlag(BundledPred); } + + /// Return true if this instruction is part of a bundle, and it is not the + /// last instruction in the bundle. + bool isBundledWithSucc() const { return getFlag(BundledSucc); } + + /// Bundle this instruction with its predecessor. This can be an unbundled + /// instruction, or it can be the first instruction in a bundle. + void bundleWithPred(); + + /// Bundle this instruction with its successor. This can be an unbundled + /// instruction, or it can be the last instruction in a bundle. + void bundleWithSucc(); + + /// Break bundle above this instruction. + void unbundleFromPred(); + + /// Break bundle below this instruction. + void unbundleFromSucc(); + /// getDebugLoc - Returns the debug location id of this MachineInstr. /// DebugLoc getDebugLoc() const { return debugLoc; } diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 01291e43c8..333ab87d87 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -346,6 +346,70 @@ inline unsigned getInternalReadRegState(bool B) { return B ? RegState::InternalRead : 0; } + +/// Helper class for constructing bundles of MachineInstrs. +/// +/// MIBundleBuilder can create a bundle from scratch by inserting new +/// MachineInstrs one at a time, or it can create a bundle from a sequence of +/// existing MachineInstrs in a basic block. +class MIBundleBuilder { + MachineBasicBlock &MBB; + MachineBasicBlock::instr_iterator Begin; + MachineBasicBlock::instr_iterator End; + +public: + /// Create an MIBundleBuilder that inserts instructions into a new bundle in + /// BB above the bundle or instruction at Pos. + MIBundleBuilder(MachineBasicBlock &BB, + MachineBasicBlock::iterator Pos) + : MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {} + + /// Create a bundle from the sequence of instructions between B and E. + MIBundleBuilder(MachineBasicBlock &BB, + MachineBasicBlock::iterator B, + MachineBasicBlock::iterator E) + : MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) { + assert(B != E && "No instructions to bundle"); + ++B; + while (B != E) { + MachineInstr *MI = B; + ++B; + MI->bundleWithPred(); + } + } + + /// Return true if no instructions have been inserted in this bundle yet. + /// Empty bundles aren't representable in a MachineBasicBlock. + bool empty() const { return Begin == End; } + + /// Return an iterator to the first bundled instruction. + MachineBasicBlock::instr_iterator begin() const { return Begin; } + + /// Return an iterator beyond the last bundled instruction. + MachineBasicBlock::instr_iterator end() const { return End; } + + /// Insert MI into MBB by prepending it to the instructions in the bundle. + /// MI will become the first instruction in the bundle. + MIBundleBuilder &prepend(MachineInstr *MI) { + MBB.insert(Begin, MI); + if (!empty()) + MI->bundleWithSucc(); + Begin = MI; + return *this; + } + + /// Insert MI into MBB by appending it to the instructions in the bundle. + /// MI will become the last instruction in the bundle. + MIBundleBuilder &append(MachineInstr *MI) { + MBB.insert(End, MI); + if (empty()) + Begin = MI; + else + MI->bundleWithPred(); + return *this; + } +}; + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index 928145d279..adcd1d0de6 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -20,8 +20,8 @@ #ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H #define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H -#include <vector> #include <cassert> +#include <vector> namespace llvm { diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index d53f041128..99da6b2745 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -30,8 +30,8 @@ #ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H #define LLVM_CODEGEN_MACHINE_LOOP_INFO_H -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachineLoopRanges.h b/include/llvm/CodeGen/MachineLoopRanges.h deleted file mode 100644 index 6a30e8b53c..0000000000 --- a/include/llvm/CodeGen/MachineLoopRanges.h +++ /dev/null @@ -1,112 +0,0 @@ -//===- MachineLoopRanges.h - Ranges of machine loops -----------*- c++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the interface to the MachineLoopRanges analysis. -// -// Provide on-demand information about the ranges of machine instructions -// covered by a loop. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_MACHINELOOPRANGES_H -#define LLVM_CODEGEN_MACHINELOOPRANGES_H - -#include "llvm/ADT/IntervalMap.h" -#include "llvm/CodeGen/SlotIndexes.h" - -namespace llvm { - -class MachineLoop; -class MachineLoopInfo; -class raw_ostream; - -/// MachineLoopRange - Range information for a single loop. -class MachineLoopRange { - friend class MachineLoopRanges; - -public: - typedef IntervalMap<SlotIndex, unsigned, 4> Map; - typedef Map::Allocator Allocator; - -private: - /// The mapped loop. - const MachineLoop *const Loop; - - /// Map intervals to a bit mask. - /// Bit 0 = inside loop block. - Map Intervals; - - /// Loop area as measured by SlotIndex::distance. - unsigned Area; - - /// Create a MachineLoopRange, only accessible to MachineLoopRanges. - MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&); - -public: - /// getLoop - Return the mapped machine loop. - const MachineLoop *getLoop() const { return Loop; } - - /// overlaps - Return true if this loop overlaps the given range of machine - /// inteructions. - bool overlaps(SlotIndex Start, SlotIndex Stop); - - /// getNumber - Return the loop number. This is the same as the number of the - /// header block. - unsigned getNumber() const; - - /// getArea - Return the loop area. This number is approximately proportional - /// to the number of instructions in the loop. - unsigned getArea() const { return Area; } - - /// getMap - Allow public read-only access for IntervalMapOverlaps. - const Map &getMap() { return Intervals; } - - /// print - Print loop ranges on OS. - void print(raw_ostream&) const; - - /// byNumber - Comparator for array_pod_sort that sorts a list of - /// MachineLoopRange pointers by number. - static int byNumber(const void*, const void*); - - /// byAreaDesc - Comparator for array_pod_sort that sorts a list of - /// MachineLoopRange pointers by descending area, then by number. - static int byAreaDesc(const void*, const void*); -}; - -raw_ostream &operator<<(raw_ostream&, const MachineLoopRange&); - -/// MachineLoopRanges - Analysis pass that provides on-demand per-loop range -/// information. -class MachineLoopRanges : public MachineFunctionPass { - typedef DenseMap<const MachineLoop*, MachineLoopRange*> CacheMap; - typedef MachineLoopRange::Allocator MapAllocator; - - MapAllocator Allocator; - SlotIndexes *Indexes; - CacheMap Cache; - -public: - static char ID; // Pass identification, replacement for typeid - - MachineLoopRanges() : MachineFunctionPass(ID), Indexes(0) {} - ~MachineLoopRanges() { releaseMemory(); } - - /// getLoopRange - Return the range of loop. - MachineLoopRange *getLoopRange(const MachineLoop *Loop); - -private: - virtual bool runOnMachineFunction(MachineFunction&); - virtual void releaseMemory(); - virtual void getAnalysisUsage(AnalysisUsage&) const; -}; - - -} // end namespace llvm - -#endif // LLVM_CODEGEN_MACHINELOOPRANGES_H diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index fc73a3d609..cf9e8b61ef 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -31,19 +31,19 @@ #ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H #define LLVM_CODEGEN_MACHINEMODULEINFO_H -#include "llvm/Pass.h" -#include "llvm/GlobalValue.h" -#include "llvm/Metadata.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/DebugLoc.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/GlobalValue.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MachineLocation.h" +#include "llvm/Metadata.h" +#include "llvm/Pass.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/DebugLoc.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { @@ -180,8 +180,9 @@ public: const MCObjectFileInfo *MOFI); ~MachineModuleInfo(); - bool doInitialization(); - bool doFinalization(); + // Initialization and Finalization + virtual bool doInitialization(Module &); + virtual bool doFinalization(Module &); /// EndFunction - Discard function meta information. /// diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h index a9fc8434ab..00a60cb1cc 100644 --- a/include/llvm/CodeGen/MachinePostDominators.h +++ b/include/llvm/CodeGen/MachinePostDominators.h @@ -15,10 +15,10 @@ #ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H #define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" namespace llvm { diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 4e86363f07..0cf584fd71 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -14,10 +14,10 @@ #ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H #define LLVM_CODEGEN_MACHINEREGISTERINFO_H -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/MachineInstrBundle.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <vector> namespace llvm { diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index 83c379b48c..85bf511d60 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -16,10 +16,10 @@ #define LLVM_CODEGEN_PBQP_GRAPH_H #include "Math.h" - +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" #include <list> #include <map> -#include <llvm/ADT/ilist.h> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/HeuristicSolver.h b/include/llvm/CodeGen/PBQP/HeuristicSolver.h index 35514f9674..47e15b27e7 100644 --- a/include/llvm/CodeGen/PBQP/HeuristicSolver.h +++ b/include/llvm/CodeGen/PBQP/HeuristicSolver.h @@ -18,8 +18,8 @@ #include "Graph.h" #include "Solution.h" -#include <vector> #include <limits> +#include <vector> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index a859e5899f..307d81e1d1 100644 --- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -18,9 +18,8 @@ #ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H #define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H -#include "../HeuristicSolver.h" #include "../HeuristicBase.h" - +#include "../HeuristicSolver.h" #include <limits> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h index e7598bf3e3..4e51913eba 100644 --- a/include/llvm/CodeGen/PBQP/Math.h +++ b/include/llvm/CodeGen/PBQP/Math.h @@ -10,8 +10,8 @@ #ifndef LLVM_CODEGEN_PBQP_MATH_H #define LLVM_CODEGEN_PBQP_MATH_H -#include <cassert> #include <algorithm> +#include <cassert> #include <functional> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h index 57d9b95fc3..b9f288bbee 100644 --- a/include/llvm/CodeGen/PBQP/Solution.h +++ b/include/llvm/CodeGen/PBQP/Solution.h @@ -14,9 +14,8 @@ #ifndef LLVM_CODEGEN_PBQP_SOLUTION_H #define LLVM_CODEGEN_PBQP_SOLUTION_H -#include "Math.h" #include "Graph.h" - +#include "Math.h" #include <map> namespace PBQP { diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7bd576494e..282e4edcfb 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -141,6 +141,10 @@ public: /// Add passes to lower exception handling for the code generator. void addPassesToHandleExceptions(); + /// Add pass to prepare the LLVM IR for code generation. This should be done + /// before exception handling preparation passes. + virtual void addCodeGenPrepare(); + /// Add common passes that perform LLVM IR to IR transforms in preparation for /// instruction selection. virtual void addISelPrepare(); @@ -288,9 +292,6 @@ namespace llvm { /// MachineLoopInfo - This pass is a loop analysis pass. extern char &MachineLoopInfoID; - /// MachineLoopRanges - This pass is an on-demand loop coverage analysis. - extern char &MachineLoopRangesID; - /// MachineDominators - This pass is a machine dominators analysis pass. extern char &MachineDominatorsID; diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index acfc07dd31..b617c14558 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -20,7 +20,6 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/PBQP/Graph.h" #include "llvm/CodeGen/PBQP/Solution.h" - #include <map> #include <set> @@ -29,6 +28,7 @@ namespace llvm { class LiveIntervals; class MachineFunction; class MachineLoopInfo; + class TargetRegisterInfo; /// This class wraps up a PBQP instance representing a register allocation /// problem, plus the structures necessary to map back from the PBQP solution diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h index 4467b62f23..12bd1c61d2 100644 --- a/include/llvm/CodeGen/RegisterClassInfo.h +++ b/include/llvm/CodeGen/RegisterClassInfo.h @@ -29,10 +29,10 @@ class RegisterClassInfo { unsigned Tag; unsigned NumRegs; bool ProperSubClass; - OwningArrayPtr<unsigned> Order; + OwningArrayPtr<MCPhysReg> Order; RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {} - operator ArrayRef<unsigned>() const { + operator ArrayRef<MCPhysReg>() const { return makeArrayRef(Order.get(), NumRegs); } }; @@ -84,7 +84,7 @@ public: /// getOrder - Returns the preferred allocation order for RC. The order /// contains no reserved registers, and registers that alias callee saved /// registers come last. - ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const { + ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const { return get(RC); } diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h index 30326d05df..2670180746 100644 --- a/include/llvm/CodeGen/RegisterPressure.h +++ b/include/llvm/CodeGen/RegisterPressure.h @@ -15,13 +15,14 @@ #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H #define LLVM_CODEGEN_REGISTERPRESSURE_H +#include "llvm/ADT/SparseSet.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/SparseSet.h" namespace llvm { class LiveIntervals; +class LiveInterval; class RegisterClassInfo; class MachineInstr; @@ -30,18 +31,24 @@ struct RegisterPressure { /// Map of max reg pressure indexed by pressure set ID, not class ID. std::vector<unsigned> MaxSetPressure; - /// List of live in registers. + /// List of live in virtual registers or physical register units. SmallVector<unsigned,8> LiveInRegs; SmallVector<unsigned,8> LiveOutRegs; /// Increase register pressure for each pressure set impacted by this register /// class. Normally called by RegPressureTracker, but may be called manually /// to account for live through (global liveness). - void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI); + /// + /// \param Reg is either a virtual register number or register unit number. + void increase(unsigned Reg, const TargetRegisterInfo *TRI, + const MachineRegisterInfo *MRI); /// Decrease register pressure for each pressure set impacted by this register /// class. This is only useful to account for spilling or rematerialization. - void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI); + /// + /// \param Reg is either a virtual register number or register unit number. + void decrease(unsigned Reg, const TargetRegisterInfo *TRI, + const MachineRegisterInfo *MRI); void dump(const TargetRegisterInfo *TRI) const; }; @@ -116,6 +123,33 @@ struct RegPressureDelta { RegPressureDelta() {} }; +/// \brief A set of live virtual registers and physical register units. +/// +/// Virtual and physical register numbers require separate sparse sets, but most +/// of the RegisterPressureTracker handles them uniformly. +struct LiveRegSet { + SparseSet<unsigned> PhysRegs; + SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs; + + bool contains(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.count(Reg); + return PhysRegs.count(Reg); + } + + bool insert(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.insert(Reg).second; + return PhysRegs.insert(Reg).second; + } + + bool erase(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.erase(Reg); + return PhysRegs.erase(Reg); + } +}; + /// Track the current register pressure at some position in the instruction /// stream, and remember the high water mark within the region traversed. This /// does not automatically consider live-through ranges. The client may @@ -150,15 +184,15 @@ class RegPressureTracker { bool RequireIntervals; /// Register pressure corresponds to liveness before this instruction - /// iterator. It may point to the end of the block rather than an instruction. + /// iterator. It may point to the end of the block or a DebugValue rather than + /// an instruction. MachineBasicBlock::const_iterator CurrPos; /// Pressure map indexed by pressure set ID, not class ID. std::vector<unsigned> CurrSetPressure; - /// List of live registers. - SparseSet<unsigned> LivePhysRegs; - SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs; + /// Set of live registers. + LiveRegSet LiveRegs; public: RegPressureTracker(IntervalPressure &rp) : @@ -171,8 +205,9 @@ public: const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos); - /// Force liveness of registers. Particularly useful to initialize the - /// livein/out state of the tracker before the first call to advance/recede. + /// Force liveness of virtual registers or physical register + /// units. Particularly useful to initialize the livein/out state of the + /// tracker before the first call to advance/recede. void addLiveRegs(ArrayRef<unsigned> Regs); /// Get the MI position corresponding to this register pressure. @@ -184,6 +219,10 @@ public: // position changes while pressure does not. void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } + /// \brief Get the SlotIndex for the first nondebug instruction including or + /// after the current position. + SlotIndex getCurrSlot() const; + /// Recede across the previous instruction. bool recede(); @@ -203,11 +242,8 @@ public: /// than the pressure across the traversed region. std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } - void discoverPhysLiveIn(unsigned Reg); - void discoverPhysLiveOut(unsigned Reg); - - void discoverVirtLiveIn(unsigned Reg); - void discoverVirtLiveOut(unsigned Reg); + void discoverLiveOut(unsigned Reg); + void discoverLiveIn(unsigned Reg); bool isTopClosed() const; bool isBottomClosed() const; @@ -268,12 +304,13 @@ public: return getDownwardPressure(MI, PressureResult, MaxPressureResult); } + void dump() const; + protected: - void increasePhysRegPressure(ArrayRef<unsigned> Regs); - void decreasePhysRegPressure(ArrayRef<unsigned> Regs); + const LiveInterval *getInterval(unsigned Reg) const; - void increaseVirtRegPressure(ArrayRef<unsigned> Regs); - void decreaseVirtRegPressure(ArrayRef<unsigned> Regs); + void increaseRegPressure(ArrayRef<unsigned> Regs); + void decreaseRegPressure(ArrayRef<unsigned> Regs); void bumpUpwardPressure(const MachineInstr *MI); void bumpDownwardPressure(const MachineInstr *MI); diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 8752e67a79..6604d4cdda 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -17,9 +17,9 @@ #ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H #define LLVM_CODEGEN_REGISTER_SCAVENGING_H +#include "llvm/ADT/BitVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/ADT/BitVector.h" namespace llvm { diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h index 56b5855c01..66a6039668 100644 --- a/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -18,8 +18,8 @@ #define RESOURCE_PRIORITY_QUEUE_H #include "llvm/CodeGen/DFAPacketizer.h" -#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 016722e7f4..aa91b0300a 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -16,13 +16,13 @@ #ifndef LLVM_CODEGEN_SCHEDULEDAG_H #define LLVM_CODEGEN_SCHEDULEDAG_H -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetLowering.h" namespace llvm { class AliasAnalysis; diff --git a/include/llvm/CodeGen/ScheduleDAGILP.h b/include/llvm/CodeGen/ScheduleDAGILP.h deleted file mode 100644 index 1aa4058421..0000000000 --- a/include/llvm/CodeGen/ScheduleDAGILP.h +++ /dev/null @@ -1,86 +0,0 @@ -//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Definition of an ILP metric for machine level instruction scheduling. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H -#define LLVM_CODEGEN_SCHEDULEDAGILP_H - -#include "llvm/Support/DataTypes.h" -#include <vector> - -namespace llvm { - -class raw_ostream; -class ScheduleDAGInstrs; -class SUnit; - -/// \brief Represent the ILP of the subDAG rooted at a DAG node. -struct ILPValue { - unsigned InstrCount; - unsigned Cycles; - - ILPValue(): InstrCount(0), Cycles(0) {} - - ILPValue(unsigned count, unsigned cycles): - InstrCount(count), Cycles(cycles) {} - - bool isValid() const { return Cycles > 0; } - - // Order by the ILP metric's value. - bool operator<(ILPValue RHS) const { - return (uint64_t)InstrCount * RHS.Cycles - < (uint64_t)Cycles * RHS.InstrCount; - } - bool operator>(ILPValue RHS) const { - return RHS < *this; - } - bool operator<=(ILPValue RHS) const { - return (uint64_t)InstrCount * RHS.Cycles - <= (uint64_t)Cycles * RHS.InstrCount; - } - bool operator>=(ILPValue RHS) const { - return RHS <= *this; - } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void print(raw_ostream &OS) const; - - void dump() const; -#endif -}; - -/// \brief Compute the values of each DAG node for an ILP metric. -/// -/// This metric assumes that the DAG is a forest of trees with roots at the -/// bottom of the schedule. -class ScheduleDAGILP { - bool IsBottomUp; - std::vector<ILPValue> ILPValues; - -public: - ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {} - - /// \brief Initialize the result data with the size of the DAG. - void resize(unsigned NumSUnits); - - /// \brief Compute the ILP metric for the subDAG at this root. - void computeILP(const SUnit *Root); - - /// \brief Get the ILP value for a DAG node. - ILPValue getILP(const SUnit *SU); -}; - -raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); - -} // namespace llvm - -#endif diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index 4bcd35a834..ffc442e3b8 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -15,14 +15,14 @@ #ifndef SCHEDULEDAGINSTRS_H #define SCHEDULEDAGINSTRS_H +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SparseSet.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/TargetSchedule.h" #include "llvm/Support/Compiler.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/SparseSet.h" #include <map> namespace llvm { diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h new file mode 100644 index 0000000000..fbbadd95ad --- /dev/null +++ b/include/llvm/CodeGen/ScheduleDFS.h @@ -0,0 +1,152 @@ +//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of an ILP metric for machine level instruction scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H +#define LLVM_CODEGEN_SCHEDULEDAGILP_H + +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { + +class raw_ostream; +class IntEqClasses; +class ScheduleDAGInstrs; +class SUnit; + +/// \brief Represent the ILP of the subDAG rooted at a DAG node. +/// +/// When computed using bottom-up DFS, this metric assumes that the DAG is a +/// forest of trees with roots at the bottom of the schedule branching upward. +struct ILPValue { + unsigned InstrCount; + /// Length may either correspond to depth or height, depending on direction, + /// and cycles or nodes depending on context. + unsigned Length; + + ILPValue(unsigned count, unsigned length): + InstrCount(count), Length(length) {} + + // Order by the ILP metric's value. + bool operator<(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Length + < (uint64_t)Length * RHS.InstrCount; + } + bool operator>(ILPValue RHS) const { + return RHS < *this; + } + bool operator<=(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Length + <= (uint64_t)Length * RHS.InstrCount; + } + bool operator>=(ILPValue RHS) const { + return RHS <= *this; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + void print(raw_ostream &OS) const; + + void dump() const; +#endif +}; + +/// \brief Compute the values of each DAG node for various metrics during DFS. +/// +/// ILPValues summarize the DAG subtree rooted at each node up to +/// SubtreeLimit. ILPValues are also valid for interior nodes of a subtree, not +/// just the root. +class SchedDFSResult { + friend class SchedDFSImpl; + + /// \brief Per-SUnit data computed during DFS for various metrics. + struct NodeData { + unsigned InstrCount; + unsigned SubtreeID; + + NodeData(): InstrCount(0), SubtreeID(0) {} + }; + + /// \brief Record a connection between subtrees and the connection level. + struct Connection { + unsigned TreeID; + unsigned Level; + + Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {} + }; + + bool IsBottomUp; + unsigned SubtreeLimit; + /// DFS results for each SUnit in this DAG. + std::vector<NodeData> DFSData; + + // For each subtree discovered during DFS, record its connections to other + // subtrees. + std::vector<SmallVector<Connection, 4> > SubtreeConnections; + + /// Cache the current connection level of each subtree. + /// This mutable array is updated during scheduling. + std::vector<unsigned> SubtreeConnectLevels; + +public: + SchedDFSResult(bool IsBU, unsigned lim) + : IsBottomUp(IsBU), SubtreeLimit(lim) {} + + /// \brief Clear the results. + void clear() { + DFSData.clear(); + SubtreeConnections.clear(); + SubtreeConnectLevels.clear(); + } + + /// \brief Initialize the result data with the size of the DAG. + void resize(unsigned NumSUnits) { + DFSData.resize(NumSUnits); + } + + /// \brief Compute various metrics for the DAG with given roots. + void compute(ArrayRef<SUnit *> Roots); + + /// \brief Get the ILP value for a DAG node. + /// + /// A leaf node has an ILP of 1/1. + ILPValue getILP(const SUnit *SU) { + return ILPValue(DFSData[SU->NodeNum].InstrCount, 1 + SU->getDepth()); + } + + /// \brief The number of subtrees detected in this DAG. + unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); } + + /// \brief Get the ID of the subtree the given DAG node belongs to. + unsigned getSubtreeID(const SUnit *SU) { + return DFSData[SU->NodeNum].SubtreeID; + } + + /// \brief Get the connection level of a subtree. + /// + /// For bottom-up trees, the connection level is the latency depth (in cycles) + /// of the deepest connection to another subtree. + unsigned getSubtreeLevel(unsigned SubtreeID) { + return SubtreeConnectLevels[SubtreeID]; + } + + /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is + /// initially scheduled. + void scheduleTree(unsigned SubtreeID); +}; + +raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); + +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 060e89a3fd..c2103fb233 100644 --- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -18,7 +18,6 @@ #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/Support/DataTypes.h" - #include <cassert> #include <cstring> diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 619ee69943..b150c29d0f 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -15,16 +15,16 @@ #ifndef LLVM_CODEGEN_SELECTIONDAG_H #define LLVM_CODEGEN_SELECTIONDAG_H -#include "llvm/ADT/ilist.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/ilist.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Support/RecyclingAllocator.h" #include "llvm/Target/TargetMachine.h" #include <cassert> -#include <vector> #include <map> #include <string> +#include <vector> namespace llvm { diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index c42f655800..95d4c37a56 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -16,9 +16,9 @@ #define LLVM_CODEGEN_SELECTIONDAG_ISEL_H #include "llvm/BasicBlock.h" -#include "llvm/Pass.h" -#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Pass.h" namespace llvm { class FastISel; diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 362e9afd22..252d9ca173 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -19,20 +19,20 @@ #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H #define LLVM_CODEGEN_SELECTIONDAGNODES_H -#include "llvm/Constants.h" -#include "llvm/Instructions.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/CodeGen/ISDOpcodes.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineMemOperand.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Support/MathExtras.h" #include <cassert> namespace llvm { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index c52599b0f6..4d66793e80 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -19,13 +19,13 @@ #ifndef LLVM_CODEGEN_SLOTINDEXES_H #define LLVM_CODEGEN_SLOTINDEXES_H -#include "llvm/CodeGen/MachineInstrBundle.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/ilist.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ilist.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/Support/Allocator.h" namespace llvm { diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index f1b3065e7c..e7098e48bf 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -15,9 +15,9 @@ #ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H #define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/ADT/StringRef.h" namespace llvm { class MachineModuleInfo; diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h index 88e6105a7d..4c4a2a8b95 100644 --- a/include/llvm/CodeGen/TargetSchedule.h +++ b/include/llvm/CodeGen/TargetSchedule.h @@ -16,10 +16,10 @@ #ifndef LLVM_TARGET_TARGETSCHEDMODEL_H #define LLVM_TARGET_TARGETSCHEDMODEL_H -#include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/MC/MCSchedule.h" -#include "llvm/MC/MCInstrItineraries.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/MCSchedule.h" +#include "llvm/Target/TargetSubtargetInfo.h" namespace llvm { diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h new file mode 100644 index 0000000000..3bc6ebd563 --- /dev/null +++ b/include/llvm/CodeGen/VirtRegMap.h @@ -0,0 +1,190 @@ +//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- 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 virtual register map. This maps virtual registers to +// physical registers and virtual registers to stack slots. It is created and +// updated by a register allocator and then used by a machine code rewriter that +// adds spill code and rewrites virtual into physical register references. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_VIRTREGMAP_H +#define LLVM_CODEGEN_VIRTREGMAP_H + +#include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetRegisterInfo.h" + +namespace llvm { + class MachineInstr; + class MachineFunction; + class MachineRegisterInfo; + class TargetInstrInfo; + class raw_ostream; + class SlotIndexes; + + class VirtRegMap : public MachineFunctionPass { + public: + enum { + NO_PHYS_REG = 0, + NO_STACK_SLOT = (1L << 30)-1, + MAX_STACK_SLOT = (1L << 18)-1 + }; + + private: + MachineRegisterInfo *MRI; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineFunction *MF; + + /// Virt2PhysMap - This is a virtual to physical register + /// mapping. Each virtual register is required to have an entry in + /// it; even spilled virtual registers (the register mapped to a + /// spilled register is the temporary used to load it from the + /// stack). + IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap; + + /// Virt2StackSlotMap - This is virtual register to stack slot + /// mapping. Each spilled virtual register has an entry in it + /// which corresponds to the stack slot this register is spilled + /// at. + IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; + + /// Virt2SplitMap - This is virtual register to splitted virtual register + /// mapping. + IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap; + + /// createSpillSlot - Allocate a spill slot for RC from MFI. + unsigned createSpillSlot(const TargetRegisterClass *RC); + + VirtRegMap(const VirtRegMap&) LLVM_DELETED_FUNCTION; + void operator=(const VirtRegMap&) LLVM_DELETED_FUNCTION; + + public: + static char ID; + VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), + Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { } + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + MachineFunction &getMachineFunction() const { + assert(MF && "getMachineFunction called before runOnMachineFunction"); + return *MF; + } + + MachineRegisterInfo &getRegInfo() const { return *MRI; } + const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } + + void grow(); + + /// @brief returns true if the specified virtual register is + /// mapped to a physical register + bool hasPhys(unsigned virtReg) const { + return getPhys(virtReg) != NO_PHYS_REG; + } + + /// @brief returns the physical register mapped to the specified + /// virtual register + unsigned getPhys(unsigned virtReg) const { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2PhysMap[virtReg]; + } + + /// @brief creates a mapping for the specified virtual register to + /// the specified physical register + void assignVirt2Phys(unsigned virtReg, unsigned physReg) { + assert(TargetRegisterInfo::isVirtualRegister(virtReg) && + TargetRegisterInfo::isPhysicalRegister(physReg)); + assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && + "attempt to assign physical register to already mapped " + "virtual register"); + Virt2PhysMap[virtReg] = physReg; + } + + /// @brief clears the specified virtual register's, physical + /// register mapping + void clearVirt(unsigned virtReg) { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && + "attempt to clear a not assigned virtual register"); + Virt2PhysMap[virtReg] = NO_PHYS_REG; + } + + /// @brief clears all virtual to physical register mappings + void clearAllVirt() { + Virt2PhysMap.clear(); + grow(); + } + + /// @brief returns true if VirtReg is assigned to its preferred physreg. + bool hasPreferredPhys(unsigned VirtReg); + + /// @brief returns true if VirtReg has a known preferred register. + /// This returns false if VirtReg has a preference that is a virtual + /// register that hasn't been assigned yet. + bool hasKnownPreference(unsigned VirtReg); + + /// @brief records virtReg is a split live interval from SReg. + void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { + Virt2SplitMap[virtReg] = SReg; + } + + /// @brief returns the live interval virtReg is split from. + unsigned getPreSplitReg(unsigned virtReg) const { + return Virt2SplitMap[virtReg]; + } + + /// getOriginal - Return the original virtual register that VirtReg descends + /// from through splitting. + /// A register that was not created by splitting is its own original. + /// This operation is idempotent. + unsigned getOriginal(unsigned VirtReg) const { + unsigned Orig = getPreSplitReg(VirtReg); + return Orig ? Orig : VirtReg; + } + + /// @brief returns true if the specified virtual register is not + /// mapped to a stack slot or rematerialized. + bool isAssignedReg(unsigned virtReg) const { + if (getStackSlot(virtReg) == NO_STACK_SLOT) + return true; + // Split register can be assigned a physical register as well as a + // stack slot or remat id. + return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG); + } + + /// @brief returns the stack slot mapped to the specified virtual + /// register + int getStackSlot(unsigned virtReg) const { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2StackSlotMap[virtReg]; + } + + /// @brief create a mapping for the specifed virtual register to + /// the next available stack slot + int assignVirt2StackSlot(unsigned virtReg); + /// @brief create a mapping for the specified virtual register to + /// the specified stack slot + void assignVirt2StackSlot(unsigned virtReg, int frameIndex); + + void print(raw_ostream &OS, const Module* M = 0) const; + void dump() const; + }; + + inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { + VRM.print(OS); + return OS; + } +} // End llvm namespace + +#endif diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 456c814596..23e548ae30 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -21,11 +21,11 @@ #ifndef LLVM_CONSTANTS_H #define LLVM_CONSTANTS_H -#include "llvm/Constant.h" -#include "llvm/OperandTraits.h" -#include "llvm/ADT/APInt.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Constant.h" +#include "llvm/OperandTraits.h" namespace llvm { @@ -1082,8 +1082,7 @@ public: /// A better approach to this could be to have a constructor for Instruction /// which would take a ConstantExpr parameter, but that would have spread /// implementation details of ConstantExpr outside of Constants.cpp, which - /// would make it harder to remove ConstantExprs altogether - /// (http://llvm.org/bugs/show_bug.cgi?id=10368). + /// would make it harder to remove ConstantExprs altogether. Instruction *getAsInstruction(); virtual void destroyConstant(); diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h index 2f07800680..f6bc7b12ec 100644 --- a/include/llvm/DIBuilder.h +++ b/include/llvm/DIBuilder.h @@ -15,9 +15,9 @@ #ifndef LLVM_ANALYSIS_DIBUILDER_H #define LLVM_ANALYSIS_DIBUILDER_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class BasicBlock; @@ -371,7 +371,7 @@ namespace llvm { /// getOrCreateSubrange - Create a descriptor for a value range. This /// implicitly uniques the values returned. - DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi); + DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count); /// createGlobalVariable - Create a new descriptor for the specified global. /// @param Name Name of the variable. diff --git a/include/llvm/DataLayout.h b/include/llvm/DataLayout.h index e10f9c74c9..4cb7766387 100644 --- a/include/llvm/DataLayout.h +++ b/include/llvm/DataLayout.h @@ -20,9 +20,9 @@ #ifndef LLVM_DATALAYOUT_H #define LLVM_DATALAYOUT_H -#include "llvm/Pass.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -148,9 +148,9 @@ private: return &align != &InvalidPointerElem; } - /// Parses a target data specification string. Returns an error message - /// if the string is malformed, or the empty string on success. - std::string parseSpecifier(StringRef LayoutDescription); + /// Parses a target data specification string. Assert if the string is + /// malformed. + void parseSpecifier(StringRef LayoutDescription); public: /// Default ctor. diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h index 8520ebaba5..43af6ed080 100644 --- a/include/llvm/DebugInfo.h +++ b/include/llvm/DebugInfo.h @@ -17,8 +17,8 @@ #ifndef LLVM_ANALYSIS_DEBUGINFO_H #define LLVM_ANALYSIS_DEBUGINFO_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Dwarf.h" @@ -71,6 +71,7 @@ namespace llvm { return (unsigned)getUInt64Field(Elt); } uint64_t getUInt64Field(unsigned Elt) const; + int64_t getInt64Field(unsigned Elt) const; DIDescriptor getDescriptorField(unsigned Elt) const; template <typename DescTy> @@ -141,8 +142,8 @@ namespace llvm { public: explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} - uint64_t getLo() const { return getUInt64Field(1); } - uint64_t getHi() const { return getUInt64Field(2); } + int64_t getLo() const { return getInt64Field(1); } + int64_t getCount() const { return getInt64Field(2); } }; /// DIArray - This descriptor holds an array of descriptors. diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 9bfb19d693..5ebf4b0939 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -16,8 +16,8 @@ #define LLVM_DEBUGINFO_DICONTEXT_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/RelocVisitor.h" diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index c862c2c8bb..6068b8c337 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -18,9 +18,9 @@ #ifndef LLVM_DERIVED_TYPES_H #define LLVM_DERIVED_TYPES_H -#include "llvm/Type.h" -#include "llvm/Support/DataTypes.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Type.h" namespace llvm { diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 8073d8f92c..2d60c362cc 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -15,19 +15,19 @@ #ifndef LLVM_EXECUTION_ENGINE_H #define LLVM_EXECUTION_ENGINE_H -#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include <vector> #include <map> #include <string> +#include <vector> namespace llvm { diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index e6586e778c..7bd1fad934 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -18,7 +18,6 @@ #include "llvm/Config/config.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" - #include <vector> namespace llvm { diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 9089646501..29e01aa7ae 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -12,7 +12,6 @@ #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Support/DataTypes.h" - #include <string> namespace llvm { diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h index 3045fbd60d..96a48b28b8 100644 --- a/include/llvm/ExecutionEngine/ObjectBuffer.h +++ b/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -15,10 +15,10 @@ #ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H #define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h index a92d1d55df..d09e4deb1a 100644 --- a/include/llvm/ExecutionEngine/ObjectImage.h +++ b/include/llvm/ExecutionEngine/ObjectImage.h @@ -14,8 +14,8 @@ #ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H #define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H -#include "llvm/Object/ObjectFile.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/Object/ObjectFile.h" namespace llvm { diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index c3d160f012..e2905e37cf 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -36,23 +36,21 @@ public: RTDyldMemoryManager() {} virtual ~RTDyldMemoryManager(); - /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. The SectionID is a unique identifier - /// assigned by the JIT engine, and optionally recorded by the memory manager - /// to access a loaded section. + /// Allocate a memory block of (at least) the given size suitable for + /// executable code. The SectionID is a unique identifier assigned by the JIT + /// engine, and optionally recorded by the memory manager to access a loaded + /// section. virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; - /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. The SectionID is a unique identifier - /// assigned by the JIT engine, and optionally recorded by the memory manager - /// to access a loaded section. + /// Allocate a memory block of (at least) the given size suitable for data. + /// The SectionID is a unique identifier assigned by the JIT engine, and + /// optionally recorded by the memory manager to access a loaded section. virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly) = 0; - /// getPointerToNamedFunction - This method returns the address of the - /// specified function. As such it is only useful for resolving library - /// symbols, not code generated symbols. + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. /// /// If AbortOnFailure is false and no function with the given name is /// found, this function returns a null pointer. Otherwise, it prints a @@ -60,13 +58,13 @@ public: virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; - /// applyPermissions - This method is called when object loading is - /// complete and section page permissions can be applied. It is up to - /// the memory manager implementation to decide whether or not to act - /// on this method. The memory manager will typically allocate all - /// sections as read-write and then apply specific permissions when - /// this method is called. Returns true if an error occurred, false - /// otherwise. + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. + /// + /// Returns true if an error occurred, false otherwise. virtual bool applyPermissions(std::string *ErrMsg = 0) = 0; }; @@ -86,10 +84,10 @@ public: RuntimeDyld(RTDyldMemoryManager *); ~RuntimeDyld(); - /// loadObject - prepare the object contained in the input buffer for - /// execution. Ownership of the input buffer is transferred to the - /// ObjectImage instance returned from this function if successful. - /// In the case of load failure, the input buffer will be deleted. + /// Prepare the object contained in the input buffer for execution. + /// Ownership of the input buffer is transferred to the ObjectImage + /// instance returned from this function if successful. In the case of load + /// failure, the input buffer will be deleted. ObjectImage *loadObject(ObjectBuffer *InputBuffer); /// Get the address of our local copy of the symbol. This may or may not @@ -104,7 +102,7 @@ public: /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); - /// mapSectionAddress - map a section to its target address space value. + /// Map a section to its target address space value. /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h new file mode 100644 index 0000000000..ba4ba8d07c --- /dev/null +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -0,0 +1,176 @@ +//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of a section-based memory manager used by +// the MCJIT execution engine and RuntimeDyld. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H +#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Memory.h" + +namespace llvm { + +/// This is a simple memory manager which implements the methods called by +/// the RuntimeDyld class to allocate memory for section-based loading of +/// objects, usually those generated by the MCJIT execution engine. +/// +/// This memory manager allocates all section memory as read-write. The +/// RuntimeDyld will copy JITed section memory into these allocated blocks +/// and perform any necessary linking and relocations. +/// +/// Any client using this memory manager MUST ensure that section-specific +/// page permissions have been applied before attempting to execute functions +/// in the JITed object. Permissions can be applied either by calling +/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions +/// directly. Clients of MCJIT should call MCJIT::finalizeObject. +class SectionMemoryManager : public JITMemoryManager { + SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + +public: + SectionMemoryManager() { } + virtual ~SectionMemoryManager(); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + bool isReadOnly); + + /// \brief Applies section-specific memory permissions. + /// + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. Code sections cannot be executed + /// until this function has been called. + /// + /// \returns true if an error occurred, false otherwise. + virtual bool applyPermissions(std::string *ErrMsg = 0); + + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. + /// + /// If \p AbortOnFailure is false and no function with the given name is + /// found, this function returns a null pointer. Otherwise, it prints a + /// message to stderr and aborts. + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true); + + /// \brief Invalidate instruction cache for code sections. + /// + /// Some platforms with separate data cache and instruction cache require + /// explicit cache flush, otherwise JIT code manipulations (like resolved + /// relocations) will get to the data cache but not to the instruction cache. + /// + /// This method is not called by RuntimeDyld or MCJIT during the load + /// process. Clients may call this function when needed. See the lli + /// tool for example use. + virtual void invalidateInstructionCache(); + +private: + struct MemoryGroup { + SmallVector<sys::MemoryBlock, 16> AllocatedMem; + SmallVector<sys::MemoryBlock, 16> FreeMem; + sys::MemoryBlock Near; + }; + + uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, + unsigned Alignment); + + error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); + + MemoryGroup CodeMem; + MemoryGroup RWDataMem; + MemoryGroup RODataMem; + +public: + /// + /// Functions below are not used by MCJIT or RuntimeDyld, but must be + /// implemented because they are declared as pure virtuals in the base class. + /// + + virtual void setMemoryWritable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setMemoryExecutable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setPoisonMemory(bool poison) { + llvm_unreachable("Unexpected call!"); + } + virtual void AllocateGOT() { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *getGOTBase() const { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *startFunctionBody(const Function *F, + uintptr_t &ActualSize){ + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, + unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void deallocateFunctionBody(void *Body) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *startExceptionTable(const Function *F, + uintptr_t &ActualSize) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endExceptionTable(const Function *F, uint8_t *TableStart, + uint8_t *TableEnd, uint8_t *FrameRegister) { + llvm_unreachable("Unexpected call!"); + } + virtual void deallocateExceptionTable(void *ET) { + llvm_unreachable("Unexpected call!"); + } +}; + +} + +#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + diff --git a/include/llvm/Function.h b/include/llvm/Function.h index e211e9ab52..b49b8c1457 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -18,11 +18,11 @@ #ifndef LLVM_FUNCTION_H #define LLVM_FUNCTION_H -#include "llvm/GlobalValue.h" -#include "llvm/CallingConv.h" -#include "llvm/BasicBlock.h" #include "llvm/Argument.h" #include "llvm/Attributes.h" +#include "llvm/BasicBlock.h" +#include "llvm/CallingConv.h" +#include "llvm/GlobalValue.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -85,7 +85,7 @@ private: BasicBlockListType BasicBlocks; ///< The basic blocks mutable ArgumentListType ArgumentList; ///< The formal arguments ValueSymbolTable *SymTab; ///< Symbol table of args/instructions - AttrListPtr AttributeList; ///< Parameter attributes + AttributeSet AttributeList; ///< Parameter attributes // HasLazyArguments is stored in Value::SubclassData. /*bool HasLazyArguments;*/ @@ -162,11 +162,11 @@ public: /// getAttributes - Return the attribute list for this Function. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + const AttributeSet &getAttributes() const { return AttributeList; } /// setAttributes - Set the attribute list for this Function. /// - void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; } + void setAttributes(const AttributeSet &attrs) { AttributeList = attrs; } /// getFnAttributes - Return the function attributes for querying. /// @@ -178,7 +178,7 @@ public: /// void addFnAttr(Attributes::AttrVal N) { // Function Attributes are stored at ~0 index - addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), N)); + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), N)); } /// removeFnAttr - Remove function attributes from this function. diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index d0f014733f..ff0c1b17f9 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -15,10 +15,10 @@ #ifndef LLVM_GLOBAL_ALIAS_H #define LLVM_GLOBAL_ALIAS_H +#include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/GlobalValue.h" #include "llvm/OperandTraits.h" -#include "llvm/ADT/ilist_node.h" -#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index b9d3f68642..79463fbdf0 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -20,10 +20,10 @@ #ifndef LLVM_GLOBAL_VARIABLE_H #define LLVM_GLOBAL_VARIABLE_H +#include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/GlobalValue.h" #include "llvm/OperandTraits.h" -#include "llvm/ADT/ilist_node.h" -#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/IRBuilder.h b/include/llvm/IRBuilder.h index f63a16051e..bb86875828 100644 --- a/include/llvm/IRBuilder.h +++ b/include/llvm/IRBuilder.h @@ -15,13 +15,14 @@ #ifndef LLVM_IRBUILDER_H #define LLVM_IRBUILDER_H -#include "llvm/Instructions.h" -#include "llvm/BasicBlock.h" -#include "llvm/DataLayout.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/BasicBlock.h" +#include "llvm/DataLayout.h" +#include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" +#include "llvm/Operator.h" #include "llvm/Support/ConstantFolder.h" namespace llvm { @@ -238,7 +239,7 @@ public: return Type::getInt16Ty(Context); } - /// getInt32Ty - Fetch the type resepresenting a 32-bit integer. + /// getInt32Ty - Fetch the type representing a 32-bit integer. IntegerType *getInt32Ty() { return Type::getInt32Ty(Context); } @@ -329,7 +330,10 @@ private: /// /// Note that the builder does not expose the full generality of LLVM /// instructions. For access to extra instruction properties, use the mutators -/// (e.g. setVolatile) on the instructions after they have been created. +/// (e.g. setVolatile) on the instructions after they have been +/// created. Convenience state exists to specify fast-math flags and fp-math +/// tags. +/// /// 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 @@ -341,36 +345,40 @@ template<bool preserveNames = true, typename T = ConstantFolder, class IRBuilder : public IRBuilderBase, public Inserter { T Folder; MDNode *DefaultFPMathTag; + FastMathFlags FMF; public: IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), MDNode *FPMathTag = 0) - : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag), + FMF() { } - explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C), - Folder(), DefaultFPMathTag(FPMathTag) { + explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) + : IRBuilderBase(C), Folder(), DefaultFPMathTag(FPMathTag), FMF() { } explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(F), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB); } explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB); } explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) - : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag), + FMF() { SetInsertPoint(IP); SetCurrentDebugLocation(IP->getDebugLoc()); } explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) - : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag), + FMF() { SetInsertPoint(U); SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); } @@ -378,13 +386,13 @@ public: IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(F), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB, IP); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB, IP); } @@ -394,9 +402,18 @@ public: /// getDefaultFPMathTag - Get the floating point math metadata being used. MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } + /// Get the flags to be applied to created floating point ops + FastMathFlags getFastMathFlags() const { return FMF; } + + /// Clear the fast-math flags. + void clearFastMathFlags() { FMF.clear(); } + /// SetDefaultFPMathTag - Set the floating point math metadata to be used. void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } + /// Set the fast-math flags to be used with generated fp-math operators + void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } + /// isNamePreserving - Return true if this builder is configured to actually /// add the requested names to IR created through it. bool isNamePreserving() const { return preserveNames; } @@ -535,11 +552,14 @@ private: return BO; } - Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const { + Instruction *AddFPMathAttributes(Instruction *I, + MDNode *FPMathTag, + FastMathFlags FMF) const { if (!FPMathTag) FPMathTag = DefaultFPMathTag; if (FPMathTag) I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); + I->setFastMathFlags(FMF); return I; } public: @@ -562,8 +582,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFAdd(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -584,8 +604,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFSub(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -606,8 +626,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFMul(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { @@ -638,8 +658,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFDiv(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) @@ -658,8 +678,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFRem(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", @@ -788,7 +808,8 @@ public: Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) { if (Constant *VC = dyn_cast<Constant>(V)) return Insert(Folder.CreateFNeg(VC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V), + FPMathTag, FMF), Name); } Value *CreateNot(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index c794308f73..d0b6acff5a 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -110,6 +110,8 @@ void initializeExpandPostRAPass(PassRegistry&); void initializePathProfilerPass(PassRegistry&); void initializeGCOVProfilerPass(PassRegistry&); void initializeAddressSanitizerPass(PassRegistry&); +void initializeAddressSanitizerModulePass(PassRegistry&); +void initializeMemorySanitizerPass(PassRegistry&); void initializeThreadSanitizerPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); @@ -172,7 +174,6 @@ void initializeMachineDominatorTreePass(PassRegistry&); void initializeMachinePostDominatorTreePass(PassRegistry&); void initializeMachineLICMPass(PassRegistry&); void initializeMachineLoopInfoPass(PassRegistry&); -void initializeMachineLoopRangesPass(PassRegistry&); void initializeMachineModuleInfoPass(PassRegistry&); void initializeMachineSchedulerPass(PassRegistry&); void initializeMachineSinkingPass(PassRegistry&); diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index b5e0fd4eff..701134d526 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -16,8 +16,8 @@ #ifndef LLVM_INLINEASM_H #define LLVM_INLINEASM_H -#include "llvm/Value.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Value.h" #include <vector> namespace llvm { diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/InstVisitor.h index 6dfb4dec0e..c2d943b902 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/InstVisitor.h @@ -1,4 +1,4 @@ -//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===// +//===- llvm/InstVisitor.h - Instruction visitor templates -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_INSTVISITOR_H -#define LLVM_SUPPORT_INSTVISITOR_H +#ifndef LLVM_INSTVISITOR_H +#define LLVM_INSTVISITOR_H #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Intrinsics.h" #include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index da17f3b80d..31a3dc8f01 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -16,10 +16,10 @@ #ifndef LLVM_INSTRUCTION_TYPES_H #define LLVM_INSTRUCTION_TYPES_H +#include "llvm/ADT/Twine.h" +#include "llvm/DerivedTypes.h" #include "llvm/Instruction.h" #include "llvm/OperandTraits.h" -#include "llvm/DerivedTypes.h" -#include "llvm/ADT/Twine.h" namespace llvm { diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 0768df1684..595ad179e0 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -15,12 +15,13 @@ #ifndef LLVM_INSTRUCTION_H #define LLVM_INSTRUCTION_H -#include "llvm/User.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/User.h" namespace llvm { +class FastMathFlags; class LLVMContext; class MDNode; @@ -176,6 +177,59 @@ public: /// getDebugLoc - Return the debug location for this node as a DebugLoc. const DebugLoc &getDebugLoc() const { return DbgLoc; } + /// Set or clear the unsafe-algebra flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasUnsafeAlgebra(bool B); + + /// Set or clear the no-nans flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoNaNs(bool B); + + /// Set or clear the no-infs flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoInfs(bool B); + + /// Set or clear the no-signed-zeros flag on this instruction, which must be + /// an operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoSignedZeros(bool B); + + /// Set or clear the allow-reciprocal flag on this instruction, which must be + /// an operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasAllowReciprocal(bool B); + + /// Convenience function for setting all the fast-math flags on this + /// instruction, which must be an operator which supports these flags. See + /// LangRef.html for the meaning of these flats. + void setFastMathFlags(FastMathFlags FMF); + + /// Determine whether the unsafe-algebra flag is set. + bool hasUnsafeAlgebra() const; + + /// Determine whether the no-NaNs flag is set. + bool hasNoNaNs() const; + + /// Determine whether the no-infs flag is set. + bool hasNoInfs() const; + + /// Determine whether the no-signed-zeros flag is set. + bool hasNoSignedZeros() const; + + /// Determine whether the allow-reciprocal flag is set. + bool hasAllowReciprocal() const; + + /// Convenience function for getting all the fast-math flags, which must be an + /// operator which supports these flags. See LangRef.html for the meaning of + /// these flats. + FastMathFlags getFastMathFlags() const; + + /// Copy I's fast-math flags + void copyFastMathFlags(const Instruction *I); + private: /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side /// metadata hash. @@ -202,7 +256,7 @@ public: /// /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// - bool isAssociative() const { return isAssociative(getOpcode()); } + bool isAssociative() const; static bool isAssociative(unsigned op); /// isCommutative - Return true if the instruction is commutative: diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 69593b48c1..9c5a2db2fe 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -16,15 +16,15 @@ #ifndef LLVM_INSTRUCTIONS_H #define LLVM_INSTRUCTIONS_H -#include "llvm/InstrTypes.h" -#include "llvm/DerivedTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Attributes.h" #include "llvm/CallingConv.h" +#include "llvm/DerivedTypes.h" +#include "llvm/InstrTypes.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/IntegersSubset.h" #include "llvm/Support/IntegersSubsetMapping.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/ErrorHandling.h" #include <iterator> namespace llvm { @@ -1156,7 +1156,7 @@ public: /// hold the calling convention of the call. /// class CallInst : public Instruction { - AttrListPtr AttributeList; ///< parameter attributes for call + AttributeSet AttributeList; ///< parameter attributes for call CallInst(const CallInst &CI); void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr); void init(Value *Func, const Twine &NameStr); @@ -1254,11 +1254,11 @@ public: /// getAttributes - Return the parameter attributes for this call. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + const AttributeSet &getAttributes() const { return AttributeList; } /// setAttributes - Set the parameter attributes for this call. /// - void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, Attributes attr); @@ -1280,7 +1280,7 @@ public: /// \brief Return true if the call should not be inlined. bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } void setIsNoInline() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoInline)); } @@ -1289,7 +1289,7 @@ public: return hasFnAttr(Attributes::ReturnsTwice); } void setCanReturnTwice() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::ReturnsTwice)); } @@ -1298,7 +1298,7 @@ public: return hasFnAttr(Attributes::ReadNone); } void setDoesNotAccessMemory() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::ReadNone)); } @@ -1307,21 +1307,21 @@ public: return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } void setOnlyReadsMemory() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::ReadOnly)); } /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } void setDoesNotReturn() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoReturn)); } /// \brief Determine if the call cannot unwind. bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } void setDoesNotThrow() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoUnwind)); } @@ -2942,7 +2942,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// calling convention of the call. /// class InvokeInst : public TerminatorInst { - AttrListPtr AttributeList; + AttributeSet AttributeList; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr); @@ -3003,11 +3003,11 @@ public: /// getAttributes - Return the parameter attributes for this invoke. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + const AttributeSet &getAttributes() const { return AttributeList; } /// setAttributes - Set the parameter attributes for this invoke. /// - void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, Attributes attr); @@ -3029,7 +3029,7 @@ public: /// \brief Return true if the call should not be inlined. bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } void setIsNoInline() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoInline)); } @@ -3038,7 +3038,7 @@ public: return hasFnAttr(Attributes::ReadNone); } void setDoesNotAccessMemory() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::ReadNone)); } @@ -3047,21 +3047,21 @@ public: return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } void setOnlyReadsMemory() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::ReadOnly)); } /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } void setDoesNotReturn() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoReturn)); } /// \brief Determine if the call cannot unwind. bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } void setDoesNotThrow() { - addAttribute(AttrListPtr::FunctionIndex, + addAttribute(AttributeSet::FunctionIndex, Attributes::get(getContext(), Attributes::NoUnwind)); } diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index 3108a8e525..c1fe4c67c4 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -26,7 +26,7 @@ class FunctionType; class Function; class LLVMContext; class Module; -class AttrListPtr; +class AttributeSet; /// Intrinsic Namespace - This namespace contains an enum with a value for /// every intrinsic/builtin function known by LLVM. These enum values are @@ -58,7 +58,7 @@ namespace Intrinsic { /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic. /// - AttrListPtr getAttributes(LLVMContext &C, ID id); + AttributeSet getAttributes(LLVMContext &C, ID id); /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function /// declaration for an intrinsic, and return it. diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 806e4b37b7..baf8550edc 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -19,20 +19,20 @@ #include "llvm/Analysis/DomPrinter.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/IntervalPartition.h" +#include "llvm/Analysis/Lint.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/RegionPass.h" #include "llvm/Analysis/RegionPrinter.h" #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/Lint.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Vectorize.h" #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" +#include "llvm/Transforms/Vectorize.h" #include <cstdlib> namespace { diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h index 83684c0fb6..5a85c04a18 100644 --- a/include/llvm/LinkAllVMCore.h +++ b/include/llvm/LinkAllVMCore.h @@ -16,13 +16,15 @@ #ifndef LLVM_LINKALLVMCORE_H #define LLVM_LINKALLVMCORE_H -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" -#include "llvm/InlineAsm.h" -#include "llvm/Analysis/Verifier.h" +#include "llvm/LLVMContext.h" +#include "llvm/Module.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Memory.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Path.h" @@ -30,8 +32,6 @@ #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TimeValue.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/MathExtras.h" #include <cstdlib> namespace { diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 29ec1020c3..44087650c2 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -16,8 +16,8 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H -#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MachineLocation.h" #include <cassert> #include <vector> diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 5a8830cb66..111ad484ff 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -10,10 +10,10 @@ #ifndef LLVM_MC_MCCONTEXT_H #define LLVM_MC_MCCONTEXT_H -#include "llvm/MC/SectionKind.h" -#include "llvm/MC/MCDwarf.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -137,11 +137,16 @@ namespace llvm { void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + /// Do automatic initialization in constructor and finalization in + /// destructor + bool AutoInitializationFinalization; + MCSymbol *CreateSymbol(StringRef Name); public: explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, - const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0); + const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0, + bool AutoInitializationFinalization = true); ~MCContext(); const SourceMgr *getSourceManager() const { return SrcMgr; } @@ -154,6 +159,17 @@ namespace llvm { void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } + /// @name Module Lifetime Management + /// @{ + + /// doInitialization - prepare to process a new module + void doInitialization(); + + /// doFinalization - clean up state from the current module + void doFinalization(); + + /// @} + /// @name Symbol Management /// @{ diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 53a9ce0a36..392d01592c 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -9,8 +9,8 @@ #ifndef MCDISASSEMBLER_H #define MCDISASSEMBLER_H -#include "llvm/Support/DataTypes.h" #include "llvm-c/Disassembler.h" +#include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 92e76121c0..3160b616f7 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,9 +16,9 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Dwarf.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/raw_ostream.h" #include <vector> namespace llvm { diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 8b0f191792..9842f8aa45 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -72,7 +72,7 @@ public: // @LOCALMOD-BEGIN // This shouldn't be needed anymore (sel_ldr doesn't check for it), // but removing it may require some changes in binutils also. - case Triple::NativeClient: + case Triple::NaCl: return ELF::ELFOSABI_NACL; // @LOCALMOD-END default: diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h new file mode 100644 index 0000000000..abe0f1f924 --- /dev/null +++ b/include/llvm/MC/MCELFStreamer.h @@ -0,0 +1,109 @@ +//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELFSTREAMER_H +#define LLVM_MC_MCELFSTREAMER_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Support/DataTypes.h" + +#include <vector> + +namespace llvm { +class MCAsmBackend; +class MCAssembler; +class MCCodeEmitter; +class MCExpr; +class MCInst; +class MCSymbol; +class MCSymbolData; +class raw_ostream; + +class MCELFStreamer : public MCObjectStreamer { +public: + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter) + : MCObjectStreamer(Context, TAB, OS, Emitter) {} + + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + MCAssembler *Assembler) + : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} + + virtual ~MCELFStreamer(); + + /// @name MCStreamer Interface + /// @{ + + virtual void InitSections(); + virtual void ChangeSection(const MCSection *Section); + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitThumbFunc(MCSymbol *Func); + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); + virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); + virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); + virtual void EmitCOFFSymbolStorageClass(int StorageClass); + virtual void EmitCOFFSymbolType(int Type); + virtual void EndCOFFSymbolDef(); + + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + + virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + uint64_t Size = 0, unsigned ByteAlignment = 0); + virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + unsigned AddrSpace); + + virtual void EmitFileDirective(StringRef Filename); + + virtual void EmitTCEntry(const MCSymbol &S); + + virtual void FinishImpl(); + //TEMP LOCALMOD until we go to upstream bundling + virtual void EmitAssignment(llvm::MCSymbol*, const llvm::MCExpr*); + /// @} + +private: + virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitInstToData(const MCInst &Inst); + + void fixSymbolsInTLSFixups(const MCExpr *expr); + + struct LocalCommon { + MCSymbolData *SD; + uint64_t Size; + unsigned ByteAlignment; + }; + + std::vector<LocalCommon> LocalCommons; + + SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; + + + void SetSection(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); + void SetSectionData(); + void SetSectionText(); + void SetSectionBss(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 1007aa5264..93872edf2f 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -174,9 +174,13 @@ public: VK_PPC_DARWIN_HA16, // ha16(symbol) VK_PPC_DARWIN_LO16, // lo16(symbol) VK_PPC_GAS_HA16, // symbol@ha - VK_PPC_GAS_LO16, // symbol@l + VK_PPC_GAS_LO16, // symbol@l VK_PPC_TPREL16_HA, // symbol@tprel@ha VK_PPC_TPREL16_LO, // symbol@tprel@l + VK_PPC_TOC16_HA, // symbol@toc@ha + VK_PPC_TOC16_LO, // symbol@toc@l + VK_PPC_GOT_TPREL16_DS, // symbol@got@tprel + VK_PPC_TLS, // symbol@tls VK_Mips_GPREL, VK_Mips_GOT_CALL, diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 3b9420a403..a18cbd94bb 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,9 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Format.h" + namespace llvm { class MCInst; class raw_ostream; @@ -36,13 +39,16 @@ protected: /// True if we are printing marked up assembly. bool UseMarkup; + /// True if we are printing immediates as hex. + bool PrintImmHex; + /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), - UseMarkup(0) {} + UseMarkup(0), PrintImmHex(0) {} virtual ~MCInstPrinter(); @@ -70,6 +76,12 @@ public: /// Utility functions to make adding mark ups simpler. StringRef markup(StringRef s) const; StringRef markup(StringRef a, StringRef b) const; + + bool getPrintImmHex() const { return PrintImmHex; } + void setPrintImmHex(bool Value) { PrintImmHex = Value; } + + /// Utility function to print immediates in decimal or hex. + format_object1<int64_t> formatImm(const int64_t Value) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 23e5513ae3..dcde9d9049 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -84,15 +84,6 @@ protected: /// this is the section to emit them into. const MCSection *CompactUnwindSection; - /// DwarfAccelNamesSection, DwarfAccelObjCSection, - /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - - /// If we use the DWARF accelerated hash tables then we want toe emit these - /// sections. - const MCSection *DwarfAccelNamesSection; - const MCSection *DwarfAccelObjCSection; - const MCSection *DwarfAccelNamespaceSection; - const MCSection *DwarfAccelTypesSection; - // Dwarf sections for debug info. If a target supports debug info, these must // be set. const MCSection *DwarfAbbrevSection; @@ -107,6 +98,23 @@ protected: const MCSection *DwarfRangesSection; const MCSection *DwarfMacroInfoSection; + // DWARF5 Experimental Debug Info Sections + /// DwarfAccelNamesSection, DwarfAccelObjCSection, + /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - + /// If we use the DWARF accelerated hash tables then we want to emit these + /// sections. + const MCSection *DwarfAccelNamesSection; + const MCSection *DwarfAccelObjCSection; + const MCSection *DwarfAccelNamespaceSection; + const MCSection *DwarfAccelTypesSection; + + /// These are used for the Fission separate debug information files. + const MCSection *DwarfInfoDWOSection; + const MCSection *DwarfAbbrevDWOSection; + const MCSection *DwarfStrDWOSection; + const MCSection *DwarfLineDWOSection; + const MCSection *DwarfLocDWOSection; + // Extra TLS Variable Data section. If the target needs to put additional // information for a TLS variable, it'll go here. const MCSection *TLSExtraDataSection; @@ -195,18 +203,6 @@ public: const MCSection *getCompactUnwindSection() const{ return CompactUnwindSection; } - const MCSection *getDwarfAccelNamesSection() const { - return DwarfAccelNamesSection; - } - const MCSection *getDwarfAccelObjCSection() const { - return DwarfAccelObjCSection; - } - const MCSection *getDwarfAccelNamespaceSection() const { - return DwarfAccelNamespaceSection; - } - const MCSection *getDwarfAccelTypesSection() const { - return DwarfAccelTypesSection; - } const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } const MCSection *getDwarfLineSection() const { return DwarfLineSection; } @@ -222,6 +218,36 @@ public: const MCSection *getDwarfMacroInfoSection() const { return DwarfMacroInfoSection; } + + // DWARF5 Experimental Debug Info Sections + const MCSection *getDwarfAccelNamesSection() const { + return DwarfAccelNamesSection; + } + const MCSection *getDwarfAccelObjCSection() const { + return DwarfAccelObjCSection; + } + const MCSection *getDwarfAccelNamespaceSection() const { + return DwarfAccelNamespaceSection; + } + const MCSection *getDwarfAccelTypesSection() const { + return DwarfAccelTypesSection; + } + const MCSection *getDwarfInfoDWOSection() const { + return DwarfInfoDWOSection; + } + const MCSection *getDwarfAbbrevDWOSection() const { + return DwarfAbbrevDWOSection; + } + const MCSection *getDwarfStrDWOSection() const { + return DwarfStrDWOSection; + } + const MCSection *getDwarfLineDWOSection() const { + return DwarfLineDWOSection; + } + const MCSection *getDwarfLocDWOSection() const { + return DwarfLocDWOSection; + } + const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 14fe75fd4c..f77b7d853d 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,9 +10,9 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> namespace llvm { @@ -173,7 +173,13 @@ public: OS << StringRef(Zeros, N % 16); } + void WriteBytes(SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { + WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + } + void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + // TODO: this version may need to go away once all fragment contents are + // converted to SmallVector<char, N> assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && "data size greater than fill size, unexpected large write will occur"); OS << Str; diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index a71d3c3217..b9490fab60 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -10,8 +10,8 @@ #ifndef LLVM_MC_MCASMPARSER_H #define LLVM_MC_MCASMPARSER_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class AsmToken; diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 0918c93bdf..84b33b59cd 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -10,8 +10,8 @@ #ifndef LLVM_MC_MCASMPARSEREXTENSION_H #define LLVM_MC_MCASMPARSEREXTENSION_H -#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/Support/SMLoc.h" namespace llvm { diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index f05baeaaf6..7118127e5f 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -22,11 +22,15 @@ namespace llvm { +/// An unsigned integer type large enough to represent all physical registers, +/// but not necessarily virtual registers. +typedef uint16_t MCPhysReg; + /// MCRegisterClass - Base class of TargetRegisterClass. class MCRegisterClass { public: - typedef const uint16_t* iterator; - typedef const uint16_t* const_iterator; + typedef const MCPhysReg* iterator; + typedef const MCPhysReg* const_iterator; const char *Name; const iterator RegsBegin; @@ -152,7 +156,7 @@ private: unsigned NumClasses; // Number of entries in the array unsigned NumRegUnits; // Number of regunits. const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table. - const uint16_t *DiffLists; // Pointer to the difflists array + const MCPhysReg *DiffLists; // Pointer to the difflists array const char *RegStrings; // Pointer to the string table. const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. @@ -177,7 +181,7 @@ public: /// defined below. class DiffListIterator { uint16_t Val; - const uint16_t *List; + const MCPhysReg *List; protected: /// Create an invalid iterator. Call init() to point to something useful. @@ -186,7 +190,7 @@ public: /// init - Point the iterator to InitVal, decoding subsequent values from /// DiffList. The iterator will initially point to InitVal, sub-classes are /// responsible for skipping the seed value if it is not part of the list. - void init(uint16_t InitVal, const uint16_t *DiffList) { + void init(MCPhysReg InitVal, const MCPhysReg *DiffList) { Val = InitVal; List = DiffList; } @@ -196,7 +200,7 @@ public: /// is the caller's responsibility (by checking for a 0 return value). unsigned advance() { assert(isValid() && "Cannot move off the end of the list."); - uint16_t D = *List++; + MCPhysReg D = *List++; Val += D; return D; } @@ -231,7 +235,7 @@ public: const MCRegisterClass *C, unsigned NC, const uint16_t (*RURoots)[2], unsigned NRU, - const uint16_t *DL, + const MCPhysReg *DL, const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index b050c0f442..83bc63e652 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -14,9 +14,9 @@ #ifndef LLVM_MC_MCSECTIONCOFF_H #define LLVM_MC_MCSECTIONCOFF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/COFF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 4d54465760..329c75cb1d 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -14,9 +14,9 @@ #ifndef LLVM_MC_MCSECTIONELF_H #define LLVM_MC_MCSECTIONELF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/ELF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 71ea8f3e90..65ad7961b3 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSECTIONMACHO_H #define LLVM_MC_MCSECTIONMACHO_H -#include "llvm/MC/MCSection.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCSection.h" namespace llvm { diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 10cb5580fe..4bd05a5e73 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,12 +14,12 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class MCAsmBackend; @@ -70,6 +70,8 @@ namespace llvm { SmallVector<std::pair<const MCSection *, const MCSection *>, 4> SectionStack; + bool AutoInitSections; + protected: MCStreamer(MCContext &Ctx); @@ -214,6 +216,17 @@ namespace llvm { SectionStack.back().first = Section; } + /// Initialize the streamer. + void InitStreamer() { + if (AutoInitSections) + InitSections(); + } + + /// Tell this MCStreamer to call InitSections upon initialization. + void setAutoInitSections(bool AutoInitSections) { + this->AutoInitSections = AutoInitSections; + } + /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 69213cd77d..346fb2df0f 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSUBTARGET_H #define LLVM_MC_MCSUBTARGET_H -#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/SubtargetFeature.h" #include <string> namespace llvm { diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index f9af8bcfbf..a4e7301114 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCVALUE_H #define LLVM_MC_MCVALUE_H -#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 7a0b1ffaf0..11df5749d4 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -11,6 +11,9 @@ #define LLVM_MC_MCWINCOFFOBJECTWRITER_H namespace llvm { + class MCObjectWriter; + class raw_ostream; + class MCWinCOFFObjectTargetWriter { const unsigned Machine; diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 57f0518cbf..37ae03b45c 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -18,9 +18,9 @@ #ifndef LLVM_MC_SUBTARGETFEATURE_H #define LLVM_MC_SUBTARGETFEATURE_H -#include <vector> #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" +#include <vector> namespace llvm { class raw_ostream; diff --git a/include/llvm/MDBuilder.h b/include/llvm/MDBuilder.h index 1867a63923..c0f0ae67d9 100644 --- a/include/llvm/MDBuilder.h +++ b/include/llvm/MDBuilder.h @@ -15,11 +15,11 @@ #ifndef LLVM_MDBUILDER_H #define LLVM_MDBUILDER_H +#include "llvm/ADT/APInt.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" #include "llvm/Metadata.h" -#include "llvm/ADT/APInt.h" namespace llvm { diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 0fbbb95988..b2dbcfdc96 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -16,10 +16,10 @@ #ifndef LLVM_METADATA_H #define LLVM_METADATA_H -#include "llvm/Value.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Value.h" namespace llvm { class Constant; diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 13b56433dc..bf9ac51693 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -15,13 +15,12 @@ #ifndef LLVM_MODULE_H #define LLVM_MODULE_H +#include "llvm/ADT/OwningPtr.h" #include "llvm/Function.h" -#include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" +#include "llvm/GlobalVariable.h" #include "llvm/Metadata.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/DataTypes.h" -#include <vector> namespace llvm { @@ -122,9 +121,6 @@ public: /// The type for the list of named metadata. typedef ilist<NamedMDNode> NamedMDListType; - /// The type for the list of dependent libraries. - typedef std::vector<std::string> LibraryListType; - /// The Global Variable iterator. typedef GlobalListType::iterator global_iterator; /// The Global Variable constant iterator. @@ -144,8 +140,6 @@ public: typedef NamedMDListType::iterator named_metadata_iterator; /// The named metadata constant interators. typedef NamedMDListType::const_iterator const_named_metadata_iterator; - /// The Library list iterator. - typedef LibraryListType::const_iterator lib_iterator; /// An enumeration for describing the endianess of the target machine. enum Endianness { AnyEndianness, LittleEndian, BigEndian }; @@ -211,7 +205,6 @@ private: GlobalListType GlobalList; ///< The Global Variables in the module FunctionListType FunctionList; ///< The Functions in the module AliasListType AliasList; ///< The Aliases in the module - LibraryListType LibraryList; ///< The Libraries needed by the module NamedMDListType NamedMDList; ///< The named metadata in the module std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values @@ -368,7 +361,7 @@ public: /// 4. Finally, the function exists but has the wrong prototype: return the /// function with a constantexpr cast to the right prototype. Constant *getOrInsertFunction(StringRef Name, FunctionType *T, - AttrListPtr AttributeList); + AttributeSet AttributeList); Constant *getOrInsertFunction(StringRef Name, FunctionType *T); @@ -380,7 +373,7 @@ public: /// null terminated list of function arguments, which makes it easier for /// clients to use. Constant *getOrInsertFunction(StringRef Name, - AttrListPtr AttributeList, + AttributeSet AttributeList, Type *RetTy, ...) END_WITH_NULL; /// getOrInsertFunction - Same as above, but without the attributes. @@ -389,7 +382,7 @@ public: Constant *getOrInsertTargetIntrinsic(StringRef Name, FunctionType *Ty, - AttrListPtr AttributeList); + AttributeSet AttributeList); /// getFunction - Look up the specified function in the module symbol table. /// If it does not exist, return null. @@ -576,23 +569,6 @@ public: bool empty() const { return FunctionList.empty(); } /// @} -/// @name Dependent Library Iteration -/// @{ - - /// @brief Get a constant iterator to beginning of dependent library list. - inline lib_iterator lib_begin() const { return LibraryList.begin(); } - /// @brief Get a constant iterator to end of dependent library list. - inline lib_iterator lib_end() const { return LibraryList.end(); } - /// @brief Returns the number of items in the list of libraries. - inline size_t lib_size() const { return LibraryList.size(); } - /// @brief Add a library to the list of dependent libraries - void addLibrary(StringRef Lib); - /// @brief Remove a library from the list of dependent libraries - void removeLibrary(StringRef Lib); - /// @brief Get all the libraries - inline const LibraryListType& getLibraries() const { return LibraryList; } - -/// @} /// @name Alias Iteration /// @{ diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 9cd587195a..8046efda8e 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -14,8 +14,8 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H -#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index a2723c77e9..1634789809 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -14,11 +14,11 @@ #ifndef LLVM_OBJECT_ELF_H #define LLVM_OBJECT_ELF_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerIntPair.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 4e03daab16..da972a2433 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -15,11 +15,11 @@ #ifndef LLVM_OBJECT_MACHO_H #define LLVM_OBJECT_MACHO_H -#include "llvm/Object/ObjectFile.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Object/MachOObject.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallVector.h" namespace llvm { namespace object { @@ -44,7 +44,7 @@ public: virtual unsigned getArch() const; virtual StringRef getLoadName() const; - MachOObject *getObject() { return MachOObj; } + MachOObject *getObject() { return MachOObj.get(); } static inline bool classof(const Binary *v) { return v->isMachO(); @@ -104,7 +104,7 @@ protected: virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const; private: - MachOObject *MachOObj; + OwningPtr<MachOObject> MachOObj; mutable uint32_t RegisteredStringTable; typedef SmallVector<DataRefImpl, 1> SectionList; SectionList Sections; diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h index 86f150a294..e32a85d140 100644 --- a/include/llvm/Object/MachOObject.h +++ b/include/llvm/Object/MachOObject.h @@ -10,11 +10,11 @@ #ifndef LLVM_OBJECT_MACHOOBJECT_H #define LLVM_OBJECT_MACHOOBJECT_H -#include <string> #include "llvm/ADT/InMemoryStruct.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/MachOFormat.h" +#include <string> namespace llvm { diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 1a3120ab8b..e63f554d91 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -14,8 +14,8 @@ #ifndef LLVM_OBJECT_OBJECT_FILE_H #define LLVM_OBJECT_OBJECT_FILE_H -#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 1370c71a7d..9b12946c3a 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -16,11 +16,11 @@ #ifndef _LLVM_OBJECT_RELOCVISITOR #define _LLVM_OBJECT_RELOCVISITOR +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/ELF.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Object/ELF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { namespace object { diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 4f89377a89..d31e09e2b4 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -164,10 +164,133 @@ public: } }; +/// Convenience struct for specifying and reasoning about fast-math flags. +class FastMathFlags { +private: + friend class FPMathOperator; + unsigned Flags; + FastMathFlags(unsigned F) : Flags(F) { } + +public: + enum { + UnsafeAlgebra = (1 << 0), + NoNaNs = (1 << 1), + NoInfs = (1 << 2), + NoSignedZeros = (1 << 3), + AllowReciprocal = (1 << 4) + }; + + FastMathFlags() : Flags(0) + { } + + /// Whether any flag is set + bool any() { return Flags != 0; } + + /// Set all the flags to false + void clear() { Flags = 0; } + + /// Flag queries + bool noNaNs() { return 0 != (Flags & NoNaNs); } + bool noInfs() { return 0 != (Flags & NoInfs); } + bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); } + bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); } + bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); } + + /// Flag setters + void setNoNaNs() { Flags |= NoNaNs; } + void setNoInfs() { Flags |= NoInfs; } + void setNoSignedZeros() { Flags |= NoSignedZeros; } + void setAllowReciprocal() { Flags |= AllowReciprocal; } + void setUnsafeAlgebra() { + Flags |= UnsafeAlgebra; + setNoNaNs(); + setNoInfs(); + setNoSignedZeros(); + setAllowReciprocal(); + } +}; + + /// FPMathOperator - Utility class for floating point operations which can have /// information about relaxed accuracy requirements attached to them. class FPMathOperator : public Operator { +private: + friend class Instruction; + + void setHasUnsafeAlgebra(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) | + (B * FastMathFlags::UnsafeAlgebra); + + // Unsafe algebra implies all the others + if (B) { + setHasNoNaNs(true); + setHasNoInfs(true); + setHasNoSignedZeros(true); + setHasAllowReciprocal(true); + } + } + void setHasNoNaNs(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoNaNs) | + (B * FastMathFlags::NoNaNs); + } + void setHasNoInfs(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoInfs) | + (B * FastMathFlags::NoInfs); + } + void setHasNoSignedZeros(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | + (B * FastMathFlags::NoSignedZeros); + } + void setHasAllowReciprocal(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | + (B * FastMathFlags::AllowReciprocal); + } + + /// Convenience function for setting all the fast-math flags + void setFastMathFlags(FastMathFlags FMF) { + SubclassOptionalData |= FMF.Flags; + } + public: + /// Test whether this operation is permitted to be + /// algebraically transformed, aka the 'A' fast-math property. + bool hasUnsafeAlgebra() const { + return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0; + } + + /// Test whether this operation's arguments and results are to be + /// treated as non-NaN, aka the 'N' fast-math property. + bool hasNoNaNs() const { + return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; + } + + /// Test whether this operation's arguments and results are to be + /// treated as NoN-Inf, aka the 'I' fast-math property. + bool hasNoInfs() const { + return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; + } + + /// Test whether this operation can treat the sign of zero + /// as insignificant, aka the 'S' fast-math property. + bool hasNoSignedZeros() const { + return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; + } + + /// Test whether this operation is permitted to use + /// reciprocal instead of division, aka the 'R' fast-math property. + bool hasAllowReciprocal() const { + return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; + } + + /// Convenience function for getting all the fast-math flags + FastMathFlags getFastMathFlags() const { + return FastMathFlags(SubclassOptionalData); + } /// \brief Get the maximum error permitted by this operation in ULPs. An /// accuracy of 0.0 means that the operation should be performed with the diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h new file mode 100644 index 0000000000..baa4b6a100 --- /dev/null +++ b/include/llvm/Option/Arg.h @@ -0,0 +1,132 @@ +//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines the llvm::Arg class for parsed arguments. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARG_H_ +#define LLVM_SUPPORT_ARG_H_ + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" +#include <string> + +namespace llvm { +namespace opt { +class ArgList; + +/// \brief A concrete instance of a particular driver option. +/// +/// The Arg class encodes just enough information to be able to +/// derive the argument values efficiently. In addition, Arg +/// instances have an intrusive double linked list which is used by +/// ArgList to provide efficient iteration over all instances of a +/// particular option. +class Arg { + Arg(const Arg &) LLVM_DELETED_FUNCTION; + void operator=(const Arg &) LLVM_DELETED_FUNCTION; + +private: + /// \brief The option this argument is an instance of. + const Option Opt; + + /// \brief The argument this argument was derived from (during tool chain + /// argument translation), if any. + const Arg *BaseArg; + + /// \brief How this instance of the option was spelled. + StringRef Spelling; + + /// \brief The index at which this argument appears in the containing + /// ArgList. + unsigned Index; + + /// \brief Was this argument used to effect compilation? + /// + /// This is used for generating "argument unused" diagnostics. + mutable unsigned Claimed : 1; + + /// \brief Does this argument own its values? + mutable unsigned OwnsValues : 1; + + /// \brief The argument values, as C strings. + SmallVector<const char *, 2> Values; + +public: + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const Arg *BaseArg = 0); + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const char *Value0, const Arg *BaseArg = 0); + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const char *Value0, const char *Value1, const Arg *BaseArg = 0); + ~Arg(); + + const Option getOption() const { return Opt; } + StringRef getSpelling() const { return Spelling; } + unsigned getIndex() const { return Index; } + + /// \brief Return the base argument which generated this arg. + /// + /// This is either the argument itself or the argument it was + /// derived from during tool chain specific argument translation. + const Arg &getBaseArg() const { + return BaseArg ? *BaseArg : *this; + } + void setBaseArg(const Arg *_BaseArg) { + BaseArg = _BaseArg; + } + + bool getOwnsValues() const { return OwnsValues; } + void setOwnsValues(bool Value) const { OwnsValues = Value; } + + bool isClaimed() const { return getBaseArg().Claimed; } + + /// \brief Set the Arg claimed bit. + void claim() const { getBaseArg().Claimed = true; } + + unsigned getNumValues() const { return Values.size(); } + const char *getValue(unsigned N = 0) const { + return Values[N]; + } + + SmallVectorImpl<const char*> &getValues() { + return Values; + } + + bool containsValue(StringRef Value) const { + for (unsigned i = 0, e = getNumValues(); i != e; ++i) + if (Values[i] == Value) + return true; + return false; + } + + /// \brief Append the argument onto the given array as strings. + void render(const ArgList &Args, ArgStringList &Output) const; + + /// \brief Append the argument, render as an input, onto the given + /// array as strings. + /// + /// The distinction is that some options only render their values + /// when rendered as a input (e.g., Xlinker). + void renderAsInput(const ArgList &Args, ArgStringList &Output) const; + + void dump() const; + + /// \brief Return a formatted version of the argument and + /// its values, for debugging and diagnostics. + std::string getAsString(const ArgList &Args) const; +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h new file mode 100644 index 0000000000..7d09f8e6cc --- /dev/null +++ b/include/llvm/Option/ArgList.h @@ -0,0 +1,415 @@ +//===--- ArgList.h - Argument List Management -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARGLIST_H_ +#define LLVM_SUPPORT_ARGLIST_H_ + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" +#include "llvm/Option/OptSpecifier.h" + +#include <list> +#include <string> +#include <vector> + +namespace llvm { +namespace opt { +class Arg; +class ArgList; +class Option; + +/// arg_iterator - Iterates through arguments stored inside an ArgList. +class arg_iterator { + /// The current argument. + SmallVectorImpl<Arg*>::const_iterator Current; + + /// The argument list we are iterating over. + const ArgList &Args; + + /// Optional filters on the arguments which will be match. Most clients + /// should never want to iterate over arguments without filters, so we won't + /// bother to factor this into two separate iterator implementations. + // + // FIXME: Make efficient; the idea is to provide efficient iteration over + // all arguments which match a particular id and then just provide an + // iterator combinator which takes multiple iterators which can be + // efficiently compared and returns them in order. + OptSpecifier Id0, Id1, Id2; + + void SkipToNextArg(); + +public: + typedef Arg * const * value_type; + typedef Arg * const & reference; + typedef Arg * const * pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, + const ArgList &_Args, OptSpecifier _Id0 = 0U, + OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) + : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { + SkipToNextArg(); + } + + operator const Arg*() { return *Current; } + reference operator*() const { return *Current; } + pointer operator->() const { return Current; } + + arg_iterator &operator++() { + ++Current; + SkipToNextArg(); + return *this; + } + + arg_iterator operator++(int) { + arg_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool operator==(arg_iterator LHS, arg_iterator RHS) { + return LHS.Current == RHS.Current; + } + friend bool operator!=(arg_iterator LHS, arg_iterator RHS) { + return !(LHS == RHS); + } +}; + +/// ArgList - Ordered collection of driver arguments. +/// +/// The ArgList class manages a list of Arg instances as well as +/// auxiliary data and convenience methods to allow Tools to quickly +/// check for the presence of Arg instances for a particular Option +/// and to iterate over groups of arguments. +class ArgList { +private: + ArgList(const ArgList &) LLVM_DELETED_FUNCTION; + void operator=(const ArgList &) LLVM_DELETED_FUNCTION; + +public: + typedef SmallVector<Arg*, 16> arglist_type; + typedef arglist_type::iterator iterator; + typedef arglist_type::const_iterator const_iterator; + typedef arglist_type::reverse_iterator reverse_iterator; + typedef arglist_type::const_reverse_iterator const_reverse_iterator; + +private: + /// The internal list of arguments. + arglist_type Args; + +protected: + ArgList(); + +public: + virtual ~ArgList(); + + /// @name Arg Access + /// @{ + + /// append - Append \p A to the arg list. + void append(Arg *A); + + arglist_type &getArgs() { return Args; } + const arglist_type &getArgs() const { return Args; } + + unsigned size() const { return Args.size(); } + + /// @} + /// @name Arg Iteration + /// @{ + + iterator begin() { return Args.begin(); } + iterator end() { return Args.end(); } + + reverse_iterator rbegin() { return Args.rbegin(); } + reverse_iterator rend() { return Args.rend(); } + + const_iterator begin() const { return Args.begin(); } + const_iterator end() const { return Args.end(); } + + const_reverse_iterator rbegin() const { return Args.rbegin(); } + const_reverse_iterator rend() const { return Args.rend(); } + + arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U, + OptSpecifier Id2 = 0U) const { + return arg_iterator(Args.begin(), *this, Id0, Id1, Id2); + } + arg_iterator filtered_end() const { + return arg_iterator(Args.end(), *this); + } + + /// @} + /// @name Arg Removal + /// @{ + + /// eraseArg - Remove any option matching \p Id. + void eraseArg(OptSpecifier Id); + + /// @} + /// @name Arg Access + /// @{ + + /// hasArg - Does the arg list contain any option matching \p Id. + /// + /// \p Claim Whether the argument should be claimed, if it exists. + bool hasArgNoClaim(OptSpecifier Id) const { + return getLastArgNoClaim(Id) != 0; + } + bool hasArg(OptSpecifier Id) const { + return getLastArg(Id) != 0; + } + bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { + return getLastArg(Id0, Id1) != 0; + } + bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { + return getLastArg(Id0, Id1, Id2) != 0; + } + + /// getLastArg - Return the last argument matching \p Id, or null. + /// + /// \p Claim Whether the argument should be claimed, if it exists. + Arg *getLastArgNoClaim(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, + OptSpecifier Id6) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, + OptSpecifier Id6, OptSpecifier Id7) const; + + /// getArgString - Return the input argument string at \p Index. + virtual const char *getArgString(unsigned Index) const = 0; + + /// getNumInputArgStrings - Return the number of original argument strings, + /// which are guaranteed to be the first strings in the argument string + /// list. + virtual unsigned getNumInputArgStrings() const = 0; + + /// @} + /// @name Argument Lookup Utilities + /// @{ + + /// getLastArgValue - Return the value of the last argument, or a default. + StringRef getLastArgValue(OptSpecifier Id, + StringRef Default = "") const; + + /// getAllArgValues - Get the values of all instances of the given argument + /// as strings. + std::vector<std::string> getAllArgValues(OptSpecifier Id) const; + + /// @} + /// @name Translation Utilities + /// @{ + + /// hasFlag - Given an option \p Pos and its negative form \p Neg, return + /// true if the option is present, false if the negation is present, and + /// \p Default if neither option is given. If both the option and its + /// negation are present, the last one wins. + bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; + + /// AddLastArg - Render only the last argument match \p Id0, if present. + void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; + + /// AddAllArgs - Render all arguments matching the given ids. + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; + + /// AddAllArgValues - Render the argument values of all arguments + /// matching the given ids. + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; + + /// AddAllArgsTranslated - Render all the arguments matching the + /// given ids, but forced to separate args and using the provided + /// name instead of the first option value. + /// + /// \param Joined - If true, render the argument as joined with + /// the option specifier. + void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, + const char *Translation, + bool Joined = false) const; + + /// ClaimAllArgs - Claim all arguments which match the given + /// option id. + void ClaimAllArgs(OptSpecifier Id0) const; + + /// ClaimAllArgs - Claim all arguments. + /// + void ClaimAllArgs() const; + + /// @} + /// @name Arg Synthesis + /// @{ + + /// MakeArgString - Construct a constant string pointer whose + /// lifetime will match that of the ArgList. + virtual const char *MakeArgString(StringRef Str) const = 0; + const char *MakeArgString(const char *Str) const { + return MakeArgString(StringRef(Str)); + } + const char *MakeArgString(std::string Str) const { + return MakeArgString(StringRef(Str)); + } + const char *MakeArgString(const Twine &Str) const; + + /// \brief Create an arg string for (\p LHS + \p RHS), reusing the + /// string at \p Index if possible. + const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, + StringRef RHS) const; + + /// @} +}; + +class InputArgList : public ArgList { +private: + /// List of argument strings used by the contained Args. + /// + /// This is mutable since we treat the ArgList as being the list + /// of Args, and allow routines to add new strings (to have a + /// convenient place to store the memory) via MakeIndex. + mutable ArgStringList ArgStrings; + + /// Strings for synthesized arguments. + /// + /// This is mutable since we treat the ArgList as being the list + /// of Args, and allow routines to add new strings (to have a + /// convenient place to store the memory) via MakeIndex. + mutable std::list<std::string> SynthesizedStrings; + + /// The number of original input argument strings. + unsigned NumInputArgStrings; + +public: + InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); + ~InputArgList(); + + virtual const char *getArgString(unsigned Index) const { + return ArgStrings[Index]; + } + + virtual unsigned getNumInputArgStrings() const { + return NumInputArgStrings; + } + + /// @name Arg Synthesis + /// @{ + +public: + /// MakeIndex - Get an index for the given string(s). + unsigned MakeIndex(StringRef String0) const; + unsigned MakeIndex(StringRef String0, StringRef String1) const; + + virtual const char *MakeArgString(StringRef Str) const; + + /// @} +}; + +/// DerivedArgList - An ordered collection of driver arguments, +/// whose storage may be in another argument list. +class DerivedArgList : public ArgList { + const InputArgList &BaseArgs; + + /// The list of arguments we synthesized. + mutable arglist_type SynthesizedArgs; + +public: + /// Construct a new derived arg list from \p BaseArgs. + DerivedArgList(const InputArgList &BaseArgs); + ~DerivedArgList(); + + virtual const char *getArgString(unsigned Index) const { + return BaseArgs.getArgString(Index); + } + + virtual unsigned getNumInputArgStrings() const { + return BaseArgs.getNumInputArgStrings(); + } + + const InputArgList &getBaseArgs() const { + return BaseArgs; + } + + /// @name Arg Synthesis + /// @{ + + /// AddSynthesizedArg - Add a argument to the list of synthesized arguments + /// (to be freed). + void AddSynthesizedArg(Arg *A) { + SynthesizedArgs.push_back(A); + } + + virtual const char *MakeArgString(StringRef Str) const; + + /// AddFlagArg - Construct a new FlagArg for the given option \p Id and + /// append it to the argument list. + void AddFlagArg(const Arg *BaseArg, const Option Opt) { + append(MakeFlagArg(BaseArg, Opt)); + } + + /// AddPositionalArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument + /// list. + void AddPositionalArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakePositionalArg(BaseArg, Opt, Value)); + } + + + /// AddSeparateArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument + /// list. + void AddSeparateArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakeSeparateArg(BaseArg, Opt, Value)); + } + + + /// AddJoinedArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument list. + void AddJoinedArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakeJoinedArg(BaseArg, Opt, Value)); + } + + + /// MakeFlagArg - Construct a new FlagArg for the given option \p Id. + Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; + + /// MakePositionalArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// MakeSeparateArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// MakeJoinedArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// @} +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td new file mode 100644 index 0000000000..e781fa02d7 --- /dev/null +++ b/include/llvm/Option/OptParser.td @@ -0,0 +1,127 @@ +//===--- OptParser.td - Common Option Parsing Interfaces ------------------===// +// +// 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 common interfaces used by the option parsing TableGen +// backend. +// +//===----------------------------------------------------------------------===// + +// Define the kinds of options. + +class OptionKind<string name, int predecence = 0, bit sentinel = 0> { + string Name = name; + // The kind precedence, kinds with lower precedence are matched first. + int Precedence = predecence; + // Indicate a sentinel option. + bit Sentinel = sentinel; +} + +// An option group. +def KIND_GROUP : OptionKind<"Group">; +// The input option kind. +def KIND_INPUT : OptionKind<"Input", 1, 1>; +// The unknown option kind. +def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>; +// A flag with no values. +def KIND_FLAG : OptionKind<"Flag">; +// An option which prefixes its (single) value. +def KIND_JOINED : OptionKind<"Joined", 1>; +// An option which is followed by its value. +def KIND_SEPARATE : OptionKind<"Separate">; +// An option followed by its values, which are separated by commas. +def KIND_COMMAJOINED : OptionKind<"CommaJoined">; +// An option which is which takes multiple (separate) arguments. +def KIND_MULTIARG : OptionKind<"MultiArg">; +// An option which is either joined to its (non-empty) value, or followed by its +// value. +def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">; +// An option which is both joined to its (first) value, and followed by its +// (second) value. +def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">; + +// Define the option flags. + +class OptionFlag {} + +// HelpHidden - The option should not be displayed in --help, even if it has +// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp +// arguments to implement hidden help groups. +def HelpHidden : OptionFlag; + +// RenderAsInput - The option should not render the name when rendered as an +// input (i.e., the option is rendered as values). +def RenderAsInput : OptionFlag; + +// RenderJoined - The option should be rendered joined, even if separate (only +// sensible on single value separate options). +def RenderJoined : OptionFlag; + +// RenderSeparate - The option should be rendered separately, even if joined +// (only sensible on joined options). +def RenderSeparate : OptionFlag; + +// Define the option group class. + +class OptionGroup<string name> { + string EnumName = ?; // Uses the def name if undefined. + string Name = name; + string HelpText = ?; + OptionGroup Group = ?; +} + +// Define the option class. + +class Option<list<string> prefixes, string name, OptionKind kind> { + string EnumName = ?; // Uses the def name if undefined. + list<string> Prefixes = prefixes; + string Name = name; + OptionKind Kind = kind; + // Used by MultiArg option kind. + int NumArgs = 0; + string HelpText = ?; + string MetaVarName = ?; + list<OptionFlag> Flags = []; + OptionGroup Group = ?; + Option Alias = ?; +} + +// Helpers for defining options. + +class Flag<list<string> prefixes, string name> + : Option<prefixes, name, KIND_FLAG>; +class Joined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED>; +class Separate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_SEPARATE>; +class CommaJoined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_COMMAJOINED>; +class MultiArg<list<string> prefixes, string name, int numargs> + : Option<prefixes, name, KIND_MULTIARG> { + int NumArgs = numargs; +} +class JoinedOrSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>; +class JoinedAndSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>; + +// Mix-ins for adding optional attributes. + +class Alias<Option alias> { Option Alias = alias; } +class EnumName<string name> { string EnumName = name; } +class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } +class Group<OptionGroup group> { OptionGroup Group = group; } +class HelpText<string text> { string HelpText = text; } +class MetaVarName<string name> { string MetaVarName = name; } + +// Predefined options. + +// FIXME: Have generator validate that these appear in correct position (and +// aren't duplicated). +def INPUT : Option<[], "<input>", KIND_INPUT>; +def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>; diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h new file mode 100644 index 0000000000..3bc9bb24ed --- /dev/null +++ b/include/llvm/Option/OptSpecifier.h @@ -0,0 +1,39 @@ +//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_OPTSPECIFIER_H +#define LLVM_SUPPORT_OPTSPECIFIER_H + +namespace llvm { +namespace opt { + class Option; + + /// OptSpecifier - Wrapper class for abstracting references to option IDs. + class OptSpecifier { + unsigned ID; + + private: + explicit OptSpecifier(bool); // DO NOT IMPLEMENT + + public: + OptSpecifier() : ID(0) {} + /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} + /*implicit*/ OptSpecifier(const Option *Opt); + + bool isValid() const { return ID != 0; } + + unsigned getID() const { return ID; } + + bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } + bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } + }; +} +} + +#endif diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h new file mode 100644 index 0000000000..930549fbd3 --- /dev/null +++ b/include/llvm/Option/OptTable.h @@ -0,0 +1,161 @@ +//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_OPTTABLE_H +#define LLVM_SUPPORT_OPTTABLE_H + +#include "llvm/ADT/StringSet.h" +#include "llvm/Option/OptSpecifier.h" + +namespace llvm { +class raw_ostream; +namespace opt { +class Arg; +class ArgList; +class InputArgList; +class Option; + +/// \brief Provide access to the Option info table. +/// +/// The OptTable class provides a layer of indirection which allows Option +/// instance to be created lazily. In the common case, only a few options will +/// be needed at runtime; the OptTable class maintains enough information to +/// parse command lines without instantiating Options, while letting other +/// parts of the driver still use Option instances where convenient. +class OptTable { +public: + /// \brief Entry for a single option instance in the option data table. + struct Info { + /// A null terminated array of prefix strings to apply to name while + /// matching. + const char *const *Prefixes; + const char *Name; + const char *HelpText; + const char *MetaVar; + unsigned ID; + unsigned char Kind; + unsigned char Param; + unsigned short Flags; + unsigned short GroupID; + unsigned short AliasID; + }; + +private: + /// \brief The static option information table. + const Info *OptionInfos; + unsigned NumOptionInfos; + + unsigned TheInputOptionID; + unsigned TheUnknownOptionID; + + /// The index of the first option which can be parsed (i.e., is not a + /// special option like 'input' or 'unknown', and is not an option group). + unsigned FirstSearchableIndex; + + /// The union of all option prefixes. If an argument does not begin with + /// one of these, it is an input. + StringSet<> PrefixesUnion; + std::string PrefixChars; + +private: + const Info &getInfo(OptSpecifier Opt) const { + unsigned id = Opt.getID(); + assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID."); + return OptionInfos[id - 1]; + } + +protected: + OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); +public: + ~OptTable(); + + /// \brief Return the total number of option classes. + unsigned getNumOptions() const { return NumOptionInfos; } + + /// \brief Get the given Opt's Option instance, lazily creating it + /// if necessary. + /// + /// \return The option, or null for the INVALID option id. + const Option getOption(OptSpecifier Opt) const; + + /// \brief Lookup the name of the given option. + const char *getOptionName(OptSpecifier id) const { + return getInfo(id).Name; + } + + /// \brief Get the kind of the given option. + unsigned getOptionKind(OptSpecifier id) const { + return getInfo(id).Kind; + } + + /// \brief Get the group id for the given option. + unsigned getOptionGroupID(OptSpecifier id) const { + return getInfo(id).GroupID; + } + + /// \brief Should the help for the given option be hidden by default. + bool isOptionHelpHidden(OptSpecifier id) const; + + /// \brief Get the help text to use to describe this option. + const char *getOptionHelpText(OptSpecifier id) const { + return getInfo(id).HelpText; + } + + /// \brief Get the meta-variable name to use when describing + /// this options values in the help text. + const char *getOptionMetaVar(OptSpecifier id) const { + return getInfo(id).MetaVar; + } + + /// \brief Parse a single argument; returning the new argument and + /// updating Index. + /// + /// \param [in,out] Index - The current parsing position in the argument + /// string list; on return this will be the index of the next argument + /// string to parse. + /// + /// \return The parsed argument, or 0 if the argument is missing values + /// (in which case Index still points at the conceptual next argument string + /// to parse). + Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const; + + /// \brief Parse an list of arguments into an InputArgList. + /// + /// The resulting InputArgList will reference the strings in [\p ArgBegin, + /// \p ArgEnd), and their lifetime should extend past that of the returned + /// InputArgList. + /// + /// The only error that can occur in this routine is if an argument is + /// missing values; in this case \p MissingArgCount will be non-zero. + /// + /// \param ArgBegin - The beginning of the argument vector. + /// \param ArgEnd - The end of the argument vector. + /// \param MissingArgIndex - On error, the index of the option which could + /// not be parsed. + /// \param MissingArgCount - On error, the number of missing options. + /// \return An InputArgList; on error this will contain all the options + /// which could be parsed. + InputArgList *ParseArgs(const char* const *ArgBegin, + const char* const *ArgEnd, + unsigned &MissingArgIndex, + unsigned &MissingArgCount) const; + + /// \brief Render the help text for an option table. + /// + /// \param OS - The stream to write the help text to. + /// \param Name - The name to use in the usage line. + /// \param Title - The title to use in the usage line. + /// \param ShowHidden - Whether help-hidden arguments should be shown. + void PrintHelp(raw_ostream &OS, const char *Name, + const char *Title, bool ShowHidden = false) const; +}; +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h new file mode 100644 index 0000000000..d0e46112a3 --- /dev/null +++ b/include/llvm/Option/Option.h @@ -0,0 +1,193 @@ +//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_OPTION_H_ +#define LLVM_SUPPORT_OPTION_H_ + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Option/OptTable.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { +namespace opt { +class Arg; +class ArgList; +/// ArgStringList - Type used for constructing argv lists for subprocesses. +typedef SmallVector<const char*, 16> ArgStringList; + +/// Base flags for all options. Custom flags may be added after. +enum DriverFlag { + HelpHidden = (1 << 0), + RenderAsInput = (1 << 1), + RenderJoined = (1 << 2), + RenderSeparate = (1 << 3) +}; + +/// Option - Abstract representation for a single form of driver +/// argument. +/// +/// An Option class represents a form of option that the driver +/// takes, for example how many arguments the option has and how +/// they can be provided. Individual option instances store +/// additional information about what group the option is a member +/// of (if any), if the option is an alias, and a number of +/// flags. At runtime the driver parses the command line into +/// concrete Arg instances, each of which corresponds to a +/// particular Option instance. +class Option { +public: + enum OptionClass { + GroupClass = 0, + InputClass, + UnknownClass, + FlagClass, + JoinedClass, + SeparateClass, + CommaJoinedClass, + MultiArgClass, + JoinedOrSeparateClass, + JoinedAndSeparateClass + }; + + enum RenderStyleKind { + RenderCommaJoinedStyle, + RenderJoinedStyle, + RenderSeparateStyle, + RenderValuesStyle + }; + +protected: + const OptTable::Info *Info; + const OptTable *Owner; + +public: + Option(const OptTable::Info *Info, const OptTable *Owner); + ~Option(); + + bool isValid() const { + return Info != 0; + } + + unsigned getID() const { + assert(Info && "Must have a valid info!"); + return Info->ID; + } + + OptionClass getKind() const { + assert(Info && "Must have a valid info!"); + return OptionClass(Info->Kind); + } + + /// \brief Get the name of this option without any prefix. + StringRef getName() const { + assert(Info && "Must have a valid info!"); + return Info->Name; + } + + const Option getGroup() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->GroupID); + } + + const Option getAlias() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->AliasID); + } + + /// \brief Get the default prefix for this option. + StringRef getPrefix() const { + const char *Prefix = *Info->Prefixes; + return Prefix ? Prefix : StringRef(); + } + + /// \brief Get the name of this option with the default prefix. + std::string getPrefixedName() const { + std::string Ret = getPrefix(); + Ret += getName(); + return Ret; + } + + unsigned getNumArgs() const { return Info->Param; } + + bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} + + RenderStyleKind getRenderStyle() const { + if (Info->Flags & RenderJoined) + return RenderJoinedStyle; + if (Info->Flags & RenderSeparate) + return RenderSeparateStyle; + switch (getKind()) { + case GroupClass: + case InputClass: + case UnknownClass: + return RenderValuesStyle; + case JoinedClass: + case JoinedAndSeparateClass: + return RenderJoinedStyle; + case CommaJoinedClass: + return RenderCommaJoinedStyle; + case FlagClass: + case SeparateClass: + case MultiArgClass: + case JoinedOrSeparateClass: + return RenderSeparateStyle; + } + llvm_unreachable("Unexpected kind!"); + } + + /// Test if this option has the flag \a Val. + bool hasFlag(unsigned Val) const { + return Info->Flags & Val; + } + + /// getUnaliasedOption - Return the final option this option + /// aliases (itself, if the option has no alias). + const Option getUnaliasedOption() const { + const Option Alias = getAlias(); + if (Alias.isValid()) return Alias.getUnaliasedOption(); + return *this; + } + + /// getRenderName - Return the name to use when rendering this + /// option. + StringRef getRenderName() const { + return getUnaliasedOption().getName(); + } + + /// matches - Predicate for whether this option is part of the + /// given option (which may be a group). + /// + /// Note that matches against options which are an alias should never be + /// done -- aliases do not participate in matching and so such a query will + /// always be false. + bool matches(OptSpecifier ID) const; + + /// accept - Potentially accept the current argument, returning a + /// new Arg instance, or 0 if the option does not accept this + /// argument (or the argument is missing values). + /// + /// If the option accepts the current argument, accept() sets + /// Index to the position where argument parsing should resume + /// (even if the argument is missing values). + /// + /// \parm ArgSize The number of bytes taken up by the matched Option prefix + /// and name. This is used to determine where joined values + /// start. + Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; + + void dump() const; +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 7b6f169666..35ec022516 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -104,6 +104,16 @@ public: return PassID; } + /// doInitialization - Virtual method overridden by subclasses to do + /// any necessary initialization before any pass is run. + /// + virtual bool doInitialization(Module &) { return false; } + + /// doFinalization - Virtual method overriden by subclasses to do any + /// necessary clean up after all passes have run. + /// + virtual bool doFinalization(Module &) { return false; } + /// print - Print out the internal state of the pass. This is called by /// Analyze to print out the contents of an analysis. Otherwise it is not /// necessary to implement this method. Beware that the module pointer MAY be @@ -227,20 +237,10 @@ public: /// createPrinterPass - Get a module printer pass. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; - /// doInitialization - Virtual method overridden by subclasses to do - /// any necessary initialization. - /// - virtual bool doInitialization() { return false; } - /// runOnModule - Virtual method overriden by subclasses to process the module /// being operated on. virtual bool runOnModule(Module &M) = 0; - /// doFinalization - Virtual method overriden by subclasses to do any post - /// processing needed after all passes have run. - /// - virtual bool doFinalization() { return false; } - virtual void assignPassManager(PMStack &PMS, PassManagerType T); @@ -297,21 +297,11 @@ public: /// createPrinterPass - Get a function printer pass. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; - /// doInitialization - Virtual method overridden by subclasses to do - /// any necessary per-module initialization. - /// - virtual bool doInitialization(Module &); - /// runOnFunction - Virtual method overriden by subclasses to do the /// per-function processing of the pass. /// virtual bool runOnFunction(Function &F) = 0; - /// doFinalization - Virtual method overriden by subclasses to do any post - /// processing needed after all passes have run. - /// - virtual bool doFinalization(Module &); - virtual void assignPassManager(PMStack &PMS, PassManagerType T); @@ -338,10 +328,8 @@ public: /// createPrinterPass - Get a basic block printer pass. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; - /// doInitialization - Virtual method overridden by subclasses to do - /// any necessary per-module initialization. - /// - virtual bool doInitialization(Module &); + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; /// doInitialization - Virtual method overridden by BasicBlockPass subclasses /// to do any necessary per-function initialization. @@ -358,11 +346,6 @@ public: /// virtual bool doFinalization(Function &); - /// doFinalization - Virtual method overriden by subclasses to do any post - /// processing needed after all passes have run. - /// - virtual bool doFinalization(Module &); - virtual void assignPassManager(PMStack &PMS, PassManagerType T); diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index d14d73b1b1..1cc574134f 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -19,9 +19,9 @@ #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H #define LLVM_PASS_ANALYSIS_SUPPORT_H -#include "llvm/Pass.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Pass.h" #include <vector> namespace llvm { diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h index 1d5e800b4d..ce5fda79f9 100644 --- a/include/llvm/PassManager.h +++ b/include/llvm/PassManager.h @@ -58,14 +58,6 @@ public: /// whether any of the passes modifies the module, and if so, return true. bool run(Module &M); - /// doInitialization - Run all of the initializers for the module passes. - /// - bool doInitialization(); - - /// doFinalization - Run all of the finalizers for the module passes. - /// - bool doFinalization(); - private: /// PassManagerImpl_New is the actual class. PassManager is just the /// wraper to publish simple pass manager interface diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index b0450f3e00..fac792824f 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -14,13 +14,13 @@ #ifndef LLVM_PASSMANAGERS_H #define LLVM_PASSMANAGERS_H -#include "llvm/Pass.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/DenseMap.h" -#include <vector> +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Pass.h" #include <map> +#include <vector> //===----------------------------------------------------------------------===// // Overview: diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index c6ad44f5f4..81b3ce153c 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -22,8 +22,8 @@ #define LLVM_PASS_SUPPORT_H #include "Pass.h" -#include "llvm/PassRegistry.h" #include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" #include "llvm/Support/Atomic.h" #include "llvm/Support/Valgrind.h" #include <vector> diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index a644b13366..3243fd9cea 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -15,12 +15,12 @@ #define LLVM_SUPPORT_ALLOCATOR_H #include "llvm/Support/AlignOf.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/MathExtras.h" #include <algorithm> #include <cassert> -#include <cstdlib> #include <cstddef> +#include <cstdlib> namespace llvm { template <typename T> struct ReferenceAdder { typedef T& result; }; diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index ad8d6d41fc..7a0b8db9bb 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -26,8 +26,8 @@ #ifndef LLVM_SUPPORT_CALLSITE_H #define LLVM_SUPPORT_CALLSITE_H -#include "llvm/Attributes.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Attributes.h" #include "llvm/BasicBlock.h" #include "llvm/CallingConv.h" #include "llvm/Instructions.h" @@ -177,10 +177,10 @@ public: /// getAttributes/setAttributes - get or set the parameter attributes of /// the call. - const AttrListPtr &getAttributes() const { + const AttributeSet &getAttributes() const { CALLSITE_DELEGATE_GETTER(getAttributes()); } - void setAttributes(const AttrListPtr &PAL) { + void setAttributes(const AttributeSet &PAL) { CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); } diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 872c57998c..0ab39fca38 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -20,10 +20,10 @@ #ifndef LLVM_SUPPORT_COMMANDLINE_H #define LLVM_SUPPORT_COMMANDLINE_H -#include "llvm/Support/type_traits.h" -#include "llvm/Support/Compiler.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/type_traits.h" #include <cassert> #include <climits> #include <cstdarg> diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 5acc7160ab..fce30e8b7d 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -19,25 +19,47 @@ # define __has_feature(x) 0 #endif -/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references? +/// \brief Does the compiler support r-value references? /// This implies that <utility> provides the one-argument std::move; it /// does not imply the existence of any other C++ library features. #if (__has_feature(cxx_rvalue_references) \ || defined(__GXX_EXPERIMENTAL_CXX0X__) \ || (defined(_MSC_VER) && _MSC_VER >= 1600)) -#define LLVM_USE_RVALUE_REFERENCES 1 +#define LLVM_HAS_RVALUE_REFERENCES 1 #else -#define LLVM_USE_RVALUE_REFERENCES 0 +#define LLVM_HAS_RVALUE_REFERENCES 0 +#endif + +/// \brief Does the compiler support r-value reference *this? +/// +/// Sadly, this is separate from just r-value reference support because GCC +/// implemented everything but this thus far. No release of GCC yet has support +/// for this feature so it is enabled with Clang only. +/// FIXME: This should change to a version check when GCC grows support for it. +#if __has_feature(cxx_rvalue_references) +#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 +#else +#define LLVM_HAS_RVALUE_REFERENCE_THIS 0 #endif /// llvm_move - Expands to ::std::move if the compiler supports /// r-value references; otherwise, expands to the argument. -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES #define llvm_move(value) (::std::move(value)) #else #define llvm_move(value) (value) #endif +/// Expands to '&' if r-value references are supported. +/// +/// This can be used to provide l-value/r-value overrides of member functions. +/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS +#if LLVM_HAS_RVALUE_REFERENCE_THIS +#define LLVM_LVALUE_FUNCTION & +#else +#define LLVM_LVALUE_FUNCTION +#endif + /// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it. /// Use to mark functions as uncallable. Member functions with this should /// be declared private so that some behavior is kept in C++03 mode. diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h index 355c402f54..cc3ff0da5c 100644 --- a/include/llvm/Support/DataFlow.h +++ b/include/llvm/Support/DataFlow.h @@ -14,8 +14,8 @@ #ifndef LLVM_SUPPORT_DATAFLOW_H #define LLVM_SUPPORT_DATAFLOW_H -#include "llvm/User.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/User.h" namespace llvm { diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 0b60150168..54df4ebabc 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -473,8 +473,13 @@ enum { R_PPC64_ADDR16_HIGHER = 39, R_PPC64_ADDR16_HIGHEST = 41, R_PPC64_TOC16 = 47, + R_PPC64_TOC16_LO = 48, + R_PPC64_TOC16_HA = 50, R_PPC64_TOC = 51, - R_PPC64_TOC16_DS = 63 + R_PPC64_TOC16_DS = 63, + R_PPC64_TOC16_LO_DS = 64, + R_PPC64_TLS = 67, + R_PPC64_GOT_TPREL16_DS = 87 }; // ARM Specific e_flags diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h index 95b01095c1..ca5dec0173 100644 --- a/include/llvm/Support/ErrorHandling.h +++ b/include/llvm/Support/ErrorHandling.h @@ -15,8 +15,8 @@ #ifndef LLVM_SUPPORT_ERRORHANDLING_H #define LLVM_SUPPORT_ERRORHANDLING_H -#include "llvm/Support/Compiler.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include <string> namespace llvm { diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h index bcd35e3c1e..cbc9c467d2 100644 --- a/include/llvm/Support/FileOutputBuffer.h +++ b/include/llvm/Support/FileOutputBuffer.h @@ -14,85 +14,79 @@ #ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H #define LLVM_SUPPORT_FILEOUTPUTBUFFER_H +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/FileSystem.h" namespace llvm { - class error_code; -template<class T> class OwningPtr; /// FileOutputBuffer - This interface provides simple way to create an in-memory -/// buffer which will be written to a file. During the lifetime of these +/// buffer which will be written to a file. During the lifetime of these /// objects, the content or existence of the specified file is undefined. That /// is, creating an OutputBuffer for a file may immediately remove the file. -/// If the FileOutputBuffer is committed, the target file's content will become -/// the buffer content at the time of the commit. If the FileOutputBuffer is +/// If the FileOutputBuffer is committed, the target file's content will become +/// the buffer content at the time of the commit. If the FileOutputBuffer is /// not committed, the file will be deleted in the FileOutputBuffer destructor. class FileOutputBuffer { public: enum { F_executable = 1 /// set the 'x' bit on the resulting file - }; + }; /// Factory method to create an OutputBuffer object which manages a read/write /// buffer of the specified size. When committed, the buffer will be written - /// to the file at the specified path. - static error_code create(StringRef FilePath, size_t Size, - OwningPtr<FileOutputBuffer> &Result, - unsigned Flags=0); - + /// to the file at the specified path. + static error_code create(StringRef FilePath, size_t Size, + OwningPtr<FileOutputBuffer> &Result, + unsigned Flags = 0); /// Returns a pointer to the start of the buffer. - uint8_t *getBufferStart() const { - return BufferStart; + uint8_t *getBufferStart() { + return (uint8_t*)Region->data(); } - + /// Returns a pointer to the end of the buffer. - uint8_t *getBufferEnd() const { - return BufferEnd; + uint8_t *getBufferEnd() { + return (uint8_t*)Region->data() + Region->size(); } - + /// Returns size of the buffer. size_t getBufferSize() const { - return BufferEnd - BufferStart; + return Region->size(); } - + /// Returns path where file will show up if buffer is committed. StringRef getPath() const { return FinalPath; } - - /// Flushes the content of the buffer to its file and deallocates the + + /// Flushes the content of the buffer to its file and deallocates the /// buffer. If commit() is not called before this object's destructor /// is called, the file is deleted in the destructor. The optional parameter /// is used if it turns out you want the file size to be smaller than /// initially requested. error_code commit(int64_t NewSmallerSize = -1); - + /// If this object was previously committed, the destructor just deletes /// this object. If this object was not committed, the destructor /// deallocates the buffer and the target file is never written. ~FileOutputBuffer(); - private: FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; -protected: - FileOutputBuffer(uint8_t *Start, uint8_t *End, - StringRef Path, StringRef TempPath); - - uint8_t *BufferStart; - uint8_t *BufferEnd; + + FileOutputBuffer(llvm::sys::fs::mapped_file_region *R, + StringRef Path, StringRef TempPath); + + OwningPtr<llvm::sys::fs::mapped_file_region> Region; SmallString<128> FinalPath; SmallString<128> TempPath; }; - - - } // end namespace llvm #endif diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index b455b28b81..f1cbe978c1 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -607,7 +607,7 @@ private: public: typedef char char_type; -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES mapped_file_region(mapped_file_region&&); mapped_file_region &operator =(mapped_file_region&&); #endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h index 93dc41fbdc..d1519e479d 100644 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/include/llvm/Support/GetElementPtrTypeIterator.h @@ -15,8 +15,8 @@ #ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H #define LLVM_SUPPORT_GETELEMENTPTRTYPE_H -#include "llvm/User.h" #include "llvm/DerivedTypes.h" +#include "llvm/User.h" namespace llvm { template<typename ItTy = User::const_op_iterator> diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index f178b0caa8..30cfe6124b 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -23,12 +23,12 @@ #ifndef LLVM_SUPPORT_GRAPHWRITER_H #define LLVM_SUPPORT_GRAPHWRITER_H -#include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/Support/DOTGraphTraits.h" #include "llvm/Support/Path.h" -#include <vector> +#include "llvm/Support/raw_ostream.h" #include <cassert> +#include <vector> namespace llvm { diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h index 03039fd645..d6a3b2f541 100644 --- a/include/llvm/Support/IntegersSubset.h +++ b/include/llvm/Support/IntegersSubset.h @@ -18,11 +18,10 @@ #ifndef CONSTANTRANGESSET_H_ #define CONSTANTRANGESSET_H_ -#include <list> - #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" +#include <list> namespace llvm { diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h index a24a6f0c5e..bdfab390b3 100644 --- a/include/llvm/Support/PassNameParser.h +++ b/include/llvm/Support/PassNameParser.h @@ -23,8 +23,8 @@ #ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H #define LLVM_SUPPORT_PASS_NAME_PARSER_H -#include "llvm/Pass.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 221fa8b3eb..36b6db7a72 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -41,13 +41,13 @@ bool match(Val *V, const Pattern &P) { return const_cast<Pattern&>(P).match(V); } - + template<typename SubPattern_t> struct OneUse_match { SubPattern_t SubPattern; - + OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {} - + template<typename OpTy> bool match(OpTy *V) { return V->hasOneUse() && SubPattern.match(V); @@ -56,8 +56,8 @@ struct OneUse_match { template<typename T> inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; } - - + + template<typename Class> struct class_match { template<typename ITy> @@ -74,7 +74,7 @@ inline class_match<ConstantInt> m_ConstantInt() { inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } inline class_match<Constant> m_Constant() { return class_match<Constant>(); } - + struct match_zero { template<typename ITy> bool match(ITy *V) { @@ -83,12 +83,12 @@ struct match_zero { return false; } }; - + /// m_Zero() - Match an arbitrary zero/null constant. This includes /// zero_initializer for vectors and ConstantPointerNull for pointers. inline match_zero m_Zero() { return match_zero(); } - - + + struct apint_match { const APInt *&Res; apint_match(const APInt *&R) : Res(R) {} @@ -114,12 +114,12 @@ struct apint_match { return false; } }; - + /// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the /// specified pointer to the contained APInt. inline apint_match m_APInt(const APInt *&Res) { return Res; } - + template<int64_t Val> struct constantint_match { template<typename ITy> @@ -161,7 +161,7 @@ struct cst_pred_ty : public Predicate { return false; } }; - + /// api_pred_ty - This helper class is used to match scalar and vector constants /// that satisfy a specified predicate, and bind them to an APInt. template<typename Predicate> @@ -175,7 +175,7 @@ struct api_pred_ty : public Predicate { Res = &CI->getValue(); return true; } - + // FIXME: remove. if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) @@ -183,7 +183,7 @@ struct api_pred_ty : public Predicate { Res = &CI->getValue(); return true; } - + if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) if (this->isValue(CI->getValue())) { @@ -194,8 +194,8 @@ struct api_pred_ty : public Predicate { return false; } }; - - + + struct is_one { bool isValue(const APInt &C) { return C == 1; } }; @@ -203,11 +203,11 @@ struct is_one { /// m_One() - Match an integer 1 or a vector with all elements equal to 1. inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); } inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; } - + struct is_all_ones { bool isValue(const APInt &C) { return C.isAllOnesValue(); } }; - + /// m_AllOnes() - Match an integer or vector with all bits set to true. inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();} inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; } @@ -269,7 +269,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; } struct bind_const_intval_ty { uint64_t &VR; bind_const_intval_ty(uint64_t &V) : VR(V) {} - + template<typename ITy> bool match(ITy *V) { if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) @@ -284,7 +284,7 @@ struct bind_const_intval_ty { /// m_ConstantInt - Match a ConstantInt and bind to its value. This does not /// match ConstantInts wider than 64-bits. inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } - + //===----------------------------------------------------------------------===// // Matchers for specific binary operators. // @@ -583,7 +583,7 @@ inline CastClass_match<OpTy, Instruction::BitCast> m_BitCast(const OpTy &Op) { return CastClass_match<OpTy, Instruction::BitCast>(Op); } - + /// m_PtrToInt template<typename OpTy> inline CastClass_match<OpTy, Instruction::PtrToInt> @@ -611,7 +611,7 @@ inline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) { return CastClass_match<OpTy, Instruction::ZExt>(Op); } - + //===----------------------------------------------------------------------===// // Matchers for unary operators diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h index bb66a8ed58..c5fb780501 100644 --- a/include/llvm/Support/PredIteratorCache.h +++ b/include/llvm/Support/PredIteratorCache.h @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Allocator.h" -#include "llvm/Support/CFG.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/CFG.h" #ifndef LLVM_SUPPORT_PREDITERATORCACHE_H #define LLVM_SUPPORT_PREDITERATORCACHE_H diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index ffe09b19b6..82df2c67bd 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// // -// This file implements a POSIX regular expression matcher. +// This file implements a POSIX regular expression matcher. Both Basic and +// Extended POSIX regular expressions (ERE) are supported. EREs were extended +// to support backreferences in matches. +// This implementation also supports matching strings with embedded NUL chars. // //===----------------------------------------------------------------------===// @@ -33,12 +36,14 @@ namespace llvm { /// 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 + Newline=2, + /// By default, the POSIX extended regular expression (ERE) syntax is + /// assumed. Pass this flag to turn on basic regular expressions (BRE) + /// instead. + BasicRegex=4 }; - /// Compiles the given POSIX Extended Regular Expression \p Regex. - /// This implementation supports regexes and matching strings with embedded - /// NUL characters. + /// Compiles the given regular expression \p Regex. Regex(StringRef Regex, unsigned Flags = NoFlags); ~Regex(); diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index bcf95f2f6e..bc832e0c9e 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -16,8 +16,8 @@ #ifndef SUPPORT_SOURCEMGR_H #define SUPPORT_SOURCEMGR_H -#include "llvm/Support/SMLoc.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/SMLoc.h" #include <string> namespace llvm { diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h index a2b4bcb9aa..2e1163f2d8 100644 --- a/include/llvm/Support/StreamableMemoryObject.h +++ b/include/llvm/Support/StreamableMemoryObject.h @@ -13,8 +13,8 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryObject.h" #include "llvm/Support/DataStream.h" +#include "llvm/Support/MemoryObject.h" #include <vector> namespace llvm { diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h index de05e0b547..71adbc5342 100644 --- a/include/llvm/Support/StringPool.h +++ b/include/llvm/Support/StringPool.h @@ -30,8 +30,8 @@ #define LLVM_SUPPORT_STRINGPOOL_H #include "llvm/ADT/StringMap.h" -#include <new> #include <cassert> +#include <new> namespace llvm { diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 45f7816336..f2d83a4565 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -19,10 +19,10 @@ #ifndef LLVM_SUPPORT_TARGETFOLDER_H #define LLVM_SUPPORT_TARGETFOLDER_H -#include "llvm/Constants.h" -#include "llvm/InstrTypes.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Constants.h" +#include "llvm/InstrTypes.h" namespace llvm { diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index ca58bfb0d7..701e6a9575 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -19,10 +19,10 @@ #ifndef LLVM_SUPPORT_TARGETREGISTRY_H #define LLVM_SUPPORT_TARGETREGISTRY_H -#include "llvm/Support/CodeGen.h" #include "llvm/ADT/Triple.h" -#include <string> +#include "llvm/Support/CodeGen.h" #include <cassert> +#include <string> namespace llvm { class AsmPrinter; diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h index 62ec90ad24..01f735c921 100644 --- a/include/llvm/Support/ThreadLocal.h +++ b/include/llvm/Support/ThreadLocal.h @@ -14,8 +14,8 @@ #ifndef LLVM_SYSTEM_THREAD_LOCAL_H #define LLVM_SYSTEM_THREAD_LOCAL_H -#include "llvm/Support/Threading.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Threading.h" #include <cassert> namespace llvm { diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index a7418827ca..789c05f44f 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -15,13 +15,13 @@ #ifndef LLVM_SUPPORT_TIMER_H #define LLVM_SUPPORT_TIMER_H +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" -#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> -#include <vector> #include <utility> +#include <vector> namespace llvm { diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h index e147647039..a1397db8eb 100644 --- a/include/llvm/Support/Valgrind.h +++ b/include/llvm/Support/Valgrind.h @@ -16,8 +16,8 @@ #ifndef LLVM_SYSTEM_VALGRIND_H #define LLVM_SYSTEM_VALGRIND_H -#include "llvm/Support/Compiler.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Compiler.h" #include <stddef.h> #if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h index 8d74e10be0..164aca16bf 100644 --- a/include/llvm/Support/Win64EH.h +++ b/include/llvm/Support/Win64EH.h @@ -17,6 +17,7 @@ #define LLVM_SUPPORT_WIN64EH_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" namespace llvm { namespace Win64EH { @@ -39,11 +40,17 @@ enum UnwindOpcodes { /// or part thereof. union UnwindCode { struct { - uint8_t codeOffset; - uint8_t unwindOp:4, - opInfo:4; + support::ulittle8_t CodeOffset; + support::ulittle8_t UnwindOpAndOpInfo; } u; - uint16_t frameOffset; + support::ulittle16_t FrameOffset; + + uint8_t getUnwindOp() const { + return u.UnwindOpAndOpInfo & 0x0F; + } + uint8_t getOpInfo() const { + return (u.UnwindOpAndOpInfo >> 4) & 0x0F; + } }; enum { @@ -60,37 +67,65 @@ enum { /// RuntimeFunction - An entry in the table of functions with unwind info. struct RuntimeFunction { - uint64_t startAddress; - uint64_t endAddress; - uint64_t unwindInfoOffset; + support::ulittle32_t StartAddress; + support::ulittle32_t EndAddress; + support::ulittle32_t UnwindInfoOffset; }; /// UnwindInfo - An entry in the exception table. struct UnwindInfo { - uint8_t version:3, - flags:5; - uint8_t prologSize; - uint8_t numCodes; - uint8_t frameRegister:4, - frameOffset:4; - UnwindCode unwindCodes[1]; + support::ulittle8_t VersionAndFlags; + support::ulittle8_t PrologSize; + support::ulittle8_t NumCodes; + support::ulittle8_t FrameRegisterAndOffset; + UnwindCode UnwindCodes[1]; - void *getLanguageSpecificData() { - return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]); + uint8_t getVersion() const { + return VersionAndFlags & 0x07; } - uint64_t getLanguageSpecificHandlerOffset() { - return *reinterpret_cast<uint64_t *>(getLanguageSpecificData()); + uint8_t getFlags() const { + return (VersionAndFlags >> 3) & 0x1f; } - void setLanguageSpecificHandlerOffset(uint64_t offset) { - *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset; + uint8_t getFrameRegister() const { + return FrameRegisterAndOffset & 0x0f; } - RuntimeFunction *getChainedFunctionEntry() { - return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); + uint8_t getFrameOffset() const { + return (FrameRegisterAndOffset >> 4) & 0x0f; + } + + // The data after unwindCodes depends on flags. + // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows + // the address of the language-specific exception handler. + // If UNW_ChainInfo is set then follows a RuntimeFunction which defines + // the chained unwind info. + // For more information please see MSDN at: + // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx + + /// \brief Return pointer to language specific data part of UnwindInfo. + void *getLanguageSpecificData() { + return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]); } + + /// \brief Return image-relativ offset of language-specific exception handler. + uint32_t getLanguageSpecificHandlerOffset() { + return *reinterpret_cast<uint32_t *>(getLanguageSpecificData()); + } + + /// \brief Set image-relativ offset of language-specific exception handler. + void setLanguageSpecificHandlerOffset(uint32_t offset) { + *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset; + } + + /// \brief Return pointer to exception-specific data. void *getExceptionData() { - return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>( + return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>( getLanguageSpecificData())+1); } + + /// \brief Return pointer to chained unwind info. + RuntimeFunction *getChainedFunctionEntry() { + return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); + } }; diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index e3f4f00388..03cbe33882 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -43,7 +43,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/SMLoc.h" - #include <limits> #include <utility> diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 319298c132..647c47f27c 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -19,9 +19,9 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <map> diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h index 1dadc76200..1b0572faa2 100644 --- a/include/llvm/TableGen/StringMatcher.h +++ b/include/llvm/TableGen/StringMatcher.h @@ -14,10 +14,10 @@ #ifndef STRINGMATCHER_H #define STRINGMATCHER_H -#include <vector> +#include "llvm/ADT/StringRef.h" #include <string> #include <utility> -#include "llvm/ADT/StringRef.h" +#include <vector> namespace llvm { class raw_ostream; diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 7df3bfa473..6a35fdef7d 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -15,7 +15,6 @@ #define LLVM_TARGET_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" - #include <utility> #include <vector> @@ -48,19 +47,19 @@ private: unsigned StackAlignment; unsigned TransientStackAlignment; int LocalAreaOffset; - + bool StackRealignable; + // @LOCALMOD-BEGIN // TODO(pdox): Refactor this and upstream it, to get rid of the // assumption that StackSlotSize == PointerSize. unsigned StackSlotSize; // @LOCALMOD-END public: - TargetFrameLowering(StackDirection D, - unsigned StackAl, int LAO, - unsigned TransAl = 1, + TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO, + unsigned TransAl = 1, bool StackReal = true, unsigned SlotSize = 0) // @LOCALMOD : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl), - LocalAreaOffset(LAO), StackSlotSize(SlotSize) {} + LocalAreaOffset(LAO), StackRealignable(StackReal), StackSlotSize(SlotSize) {} virtual ~TargetFrameLowering(); @@ -90,6 +89,12 @@ public: return TransientStackAlignment; } + /// isStackRealignable - This method returns whether the stack can be + /// realigned. + bool isStackRealignable() const { + return StackRealignable; + } + /// getOffsetOfLocalArea - This method returns the offset of the local area /// from the stack pointer on entrance to a function. /// diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index d2e06114d8..fb311d8508 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -15,9 +15,9 @@ #define LLVM_TARGET_TARGETINSTRINFO_H #include "llvm/ADT/SmallSet.h" -#include "llvm/MC/MCInstrInfo.h" #include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/MC/MCInstrInfo.h" namespace llvm { @@ -143,9 +143,7 @@ public: /// missed. virtual bool hasLoadFromStackSlot(const MachineInstr *MI, const MachineMemOperand *&MMO, - int &FrameIndex) const { - return 0; - } + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of @@ -173,9 +171,7 @@ public: /// stack. This is just a hint, as some cases may be missed. virtual bool hasStoreToStackSlot(const MachineInstr *MI, const MachineMemOperand *&MMO, - int &FrameIndex) const { - return 0; - } + int &FrameIndex) const; /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. @@ -186,7 +182,7 @@ public: MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, - const TargetRegisterInfo &TRI) const = 0; + const TargetRegisterInfo &TRI) const; /// duplicate - Create a duplicate of the Orig instruction in MF. This is like /// MachineFunction::CloneMachineInstr(), but the target may update operands @@ -194,7 +190,7 @@ public: /// /// The instruction must be duplicable as indicated by isNotDuplicable(). virtual MachineInstr *duplicate(MachineInstr *Orig, - MachineFunction &MF) const = 0; + MachineFunction &MF) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target @@ -221,13 +217,13 @@ public: /// method for a non-commutable instruction, but there may be some cases /// where this method fails and returns null. virtual MachineInstr *commuteInstruction(MachineInstr *MI, - bool NewMI = false) const = 0; + bool NewMI = false) const; /// findCommutedOpIndices - If specified MI is commutable, return the two /// operand indices that would swap value. Return false if the instruction /// is not in a form which this routine understands. virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, - unsigned &SrcOpIdx2) const = 0; + unsigned &SrcOpIdx2) const; /// produceSameValue - Return true if two machine instructions would produce /// identical values. By default, this is only true when the two instructions @@ -236,7 +232,7 @@ public: /// aggressive checks. virtual bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1, - const MachineRegisterInfo *MRI = 0) const = 0; + const MachineRegisterInfo *MRI = 0) const; /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't @@ -298,7 +294,7 @@ public: /// after it, replacing it with an unconditional branch to NewDest. This is /// used by the tail merging pass. virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, - MachineBasicBlock *NewDest) const = 0; + MachineBasicBlock *NewDest) const; /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic /// block at the specified instruction (i.e. instruction would be the start @@ -569,7 +565,7 @@ public: /// folding is possible. virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const =0; + const SmallVectorImpl<unsigned> &Ops) const; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is @@ -669,13 +665,13 @@ public: /// isUnpredicatedTerminator - Returns true if the instruction is a /// terminator instruction that has not been predicated. - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0; + virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; /// PredicateInstruction - Convert the instruction into a predicated /// instruction. It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr *MI, - const SmallVectorImpl<MachineOperand> &Pred) const = 0; + const SmallVectorImpl<MachineOperand> &Pred) const; /// SubsumesPredicate - Returns true if the first specified predicate /// subsumes the second, e.g. GE subsumes GT. @@ -711,7 +707,7 @@ public: /// terminators. virtual bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, - const MachineFunction &MF) const = 0; + const MachineFunction &MF) const; /// Measure the specified inline asm to determine an approximation of its /// length. @@ -723,21 +719,25 @@ public: /// register allocation. virtual ScheduleHazardRecognizer* CreateTargetHazardRecognizer(const TargetMachine *TM, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; /// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer /// to use for this target when scheduling the machine instructions before /// register allocation. virtual ScheduleHazardRecognizer* CreateTargetMIHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard /// recognizer to use for this target when scheduling the machine instructions /// after register allocation. virtual ScheduleHazardRecognizer* CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; + + /// Provide a global flag for disabling the PreRA hazard recognizer that + /// targets may choose to honor. + bool usePreRAHazardRecognizer() const; /// analyzeCompare - For a comparison instruction, return the source registers /// in SrcReg and SrcReg2 if having two register operands, and the value it @@ -785,7 +785,7 @@ public: /// IssueWidth is the number of microops that can be dispatched each /// cycle. An instruction with zero microops takes no dispatch resources. virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, - const MachineInstr *MI) const = 0; + const MachineInstr *MI) const; /// isZeroCost - Return true for pseudo instructions that don't consume any /// machine resources in their current form. These are common cases that the @@ -797,7 +797,7 @@ public: virtual int getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, - SDNode *UseNode, unsigned UseIdx) const = 0; + SDNode *UseNode, unsigned UseIdx) const; /// getOperandLatency - Compute and return the use operand latency of a given /// pair of def and use. @@ -810,7 +810,7 @@ public: virtual int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, - unsigned UseIdx) const = 0; + unsigned UseIdx) const; /// computeOperandLatency - Compute and return the latency of the given data /// dependent def and use when the operand indices are already known. @@ -826,10 +826,10 @@ public: /// PredCost. virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr *MI, - unsigned *PredCost = 0) const = 0; + unsigned *PredCost = 0) const; virtual int getInstrLatency(const InstrItineraryData *ItinData, - SDNode *Node) const = 0; + SDNode *Node) const; /// Return the default expected latency for a def based on it's opcode. unsigned defaultDefLatency(const MCSchedModel *SchedModel, @@ -859,7 +859,7 @@ public: /// if the target considered it 'low'. virtual bool hasLowDefLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx) const = 0; + const MachineInstr *DefMI, unsigned DefIdx) const; /// verifyInstruction - Perform target specific instruction verification. virtual @@ -976,84 +976,6 @@ private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; -/// TargetInstrInfoImpl - This is the default implementation of -/// TargetInstrInfo, which just provides a couple of default implementations -/// for various methods. This separated out because it is implemented in -/// libcodegen, not in libtarget. -class TargetInstrInfoImpl : public TargetInstrInfo { -protected: - TargetInstrInfoImpl(int CallFrameSetupOpcode = -1, - int CallFrameDestroyOpcode = -1) - : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {} -public: - virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, - MachineBasicBlock *NewDest) const; - virtual MachineInstr *commuteInstruction(MachineInstr *MI, - bool NewMI = false) const; - virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, - unsigned &SrcOpIdx2) const; - virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const; - virtual bool hasLoadFromStackSlot(const MachineInstr *MI, - const MachineMemOperand *&MMO, - int &FrameIndex) const; - virtual bool hasStoreToStackSlot(const MachineInstr *MI, - const MachineMemOperand *&MMO, - int &FrameIndex) const; - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; - virtual bool PredicateInstruction(MachineInstr *MI, - const SmallVectorImpl<MachineOperand> &Pred) const; - virtual void reMaterialize(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SubReg, - const MachineInstr *Orig, - const TargetRegisterInfo &TRI) const; - virtual MachineInstr *duplicate(MachineInstr *Orig, - MachineFunction &MF) const; - virtual bool produceSameValue(const MachineInstr *MI0, - const MachineInstr *MI1, - const MachineRegisterInfo *MRI) const; - virtual bool isSchedulingBoundary(const MachineInstr *MI, - const MachineBasicBlock *MBB, - const MachineFunction &MF) const; - - virtual int getOperandLatency(const InstrItineraryData *ItinData, - SDNode *DefNode, unsigned DefIdx, - SDNode *UseNode, unsigned UseIdx) const; - - virtual int getInstrLatency(const InstrItineraryData *ItinData, - SDNode *Node) const; - - virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, - const MachineInstr *MI) const; - - virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, - const MachineInstr *MI, - unsigned *PredCost = 0) const; - - virtual - bool hasLowDefLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx) const; - - virtual int getOperandLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *UseMI, - unsigned UseIdx) const; - - bool usePreRAHazardRecognizer() const; - - virtual ScheduleHazardRecognizer * - CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const; - - virtual ScheduleHazardRecognizer * - CreateTargetMIHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG*) const; - - virtual ScheduleHazardRecognizer * - CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG*) const; -}; - } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h index c2bb376131..f46c956ea0 100644 --- a/include/llvm/Target/TargetJITInfo.h +++ b/include/llvm/Target/TargetJITInfo.h @@ -17,8 +17,8 @@ #ifndef LLVM_TARGET_TARGETJITINFO_H #define LLVM_TARGET_TARGETJITINFO_H -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> namespace llvm { diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index f1dd1f4bbe..ceeba4f6e9 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -10,8 +10,8 @@ #ifndef LLVM_TARGET_TARGETLIBRARYINFO_H #define LLVM_TARGET_TARGETLIBRARYINFO_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Pass.h" namespace llvm { class Triple; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index f8925f25a1..42f771bf5e 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -22,14 +22,14 @@ #ifndef LLVM_TARGET_TARGETLOWERING_H #define LLVM_TARGET_TARGETLOWERING_H +#include "llvm/ADT/DenseMap.h" #include "llvm/AddressingMode.h" +#include "llvm/Attributes.h" #include "llvm/CallingConv.h" +#include "llvm/CodeGen/RuntimeLibcalls.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/InlineAsm.h" -#include "llvm/Attributes.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/Support/CallSite.h" -#include "llvm/CodeGen/SelectionDAGNodes.h" -#include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Target/TargetCallingConv.h" #include "llvm/Target/TargetMachine.h" @@ -171,6 +171,11 @@ public: virtual bool isSelectSupported(SelectSupportKind kind) const { return true; } + /// shouldSplitVectorElementType - Return true if a vector of the given type + /// should be split (TypeSplitVector) instead of promoted + /// (TypePromoteInteger) during type legalization. + virtual bool shouldSplitVectorElementType(EVT VT) const { return false; } + /// isIntDivCheap() - Return true if integer divide is usually cheaper than /// a sequence of several shifts, adds, and multiplies for this target. bool isIntDivCheap() const { return IntDivIsCheap; } @@ -378,6 +383,16 @@ public: return false; } + /// isIntImmLegal - Returns true if the target can instruction select the + /// specified integer immediate natively (that is, it's materialized with one + /// instruction). The current *assumption* in isel is all of integer + /// immediates are "legal" and only the memcpy / memset expansion code is + /// making use of this. The rest of isel doesn't have proper cost model for + /// immediate materialization. + virtual bool isIntImmLegal(const APInt &/*Imm*/, EVT /*VT*/) const { + return true; + } + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values @@ -685,12 +700,14 @@ public: } /// This function returns true if the target allows unaligned memory accesses. - /// of the specified type. This is used, for example, in situations where an - /// array copy/move/set is converted to a sequence of store operations. It's - /// use helps to ensure that such replacements don't generate code that causes - /// an alignment error (trap) on the target machine. + /// of the specified type. If true, it also returns whether the unaligned + /// memory access is "fast" in the second argument by reference. This is used, + /// for example, in situations where an array copy/move/set is converted to a + /// sequence of store operations. It's use helps to ensure that such + /// replacements don't generate code that causes an alignment error (trap) on + /// the target machine. /// @brief Determine if the target supports unaligned memory accesses. - virtual bool allowsUnalignedMemoryAccesses(EVT) const { + virtual bool allowsUnalignedMemoryAccesses(EVT, bool *Fast = 0) const { return false; } @@ -1720,6 +1737,13 @@ public: return false; } + /// isZExtFree - Return true if zero-extending the specific node Val to type + /// VT2 is free (either because it's implicitly zero-extended such as ARM + /// ldrb / ldrh or because it's folded such as X86 zero-extending loads). + virtual bool isZExtFree(SDValue Val, EVT VT2) const { + return isZExtFree(Val.getValueType(), VT2); + } + /// isFNegFree - Return true if an fneg operation is free to the point where /// it is never worthwhile to replace it with a bitwise operation. virtual bool isFNegFree(EVT) const { @@ -1753,9 +1777,9 @@ public: SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, SelectionDAG &DAG) const; SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector<SDNode*>* Created) const; + std::vector<SDNode*> *Created) const; SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector<SDNode*>* Created) const; + std::vector<SDNode*> *Created) const; //===--------------------------------------------------------------------===// diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index fab63254d9..0df793dfd6 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -15,10 +15,10 @@ #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H -#include "llvm/Module.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/SectionKind.h" -#include "llvm/ADT/ArrayRef.h" +#include "llvm/Module.h" namespace llvm { class MachineModuleInfo; diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 50066473b5..a891626c37 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,12 +14,12 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H +#include "llvm/ADT/StringRef.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/TargetTransformInfo.h" #include "llvm/Target/TargetTransformImpl.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/TargetTransformInfo.h" #include <cassert> #include <string> diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 0a1b73e352..ec4f2558e6 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -24,7 +24,7 @@ namespace llvm { // Possible float ABI settings. Used with FloatABIType in TargetOptions.h. namespace FloatABI { enum ABIType { - Default, // Target-specific (either soft or hard depending on triple, etc). + Default, // Target-specific (either soft or hard depending on triple,etc). Soft, // Soft float. Hard // Hard float. }; @@ -56,7 +56,7 @@ namespace llvm { GuaranteedTailCallOpt(false), DisableTailCalls(false), StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false), PositionIndependentExecutable(false), EnableSegmentedStacks(false), - UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default), + UseInitArray(false), TrapFuncName(""),FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard) {} @@ -208,10 +208,10 @@ namespace llvm { /// Strict mode - allow fusion only if/when it can be proven that the excess /// precision won't effect the result. /// - /// Note: This option only controls formation of fused ops by the optimizers. - /// Fused operations that are explicitly specified (e.g. FMA via the - /// llvm.fma.* intrinsic) will always be honored, regardless of the value of - /// this option. + /// Note: This option only controls formation of fused ops by the + /// optimizers. Fused operations that are explicitly specified (e.g. FMA + /// via the llvm.fma.* intrinsic) will always be honored, regardless of + /// the value of this option. FPOpFusion::FPOpFusionMode AllowFPOpFusion; }; diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index afa2ee2744..40a7505f67 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -16,11 +16,11 @@ #ifndef LLVM_TARGET_TARGETREGISTERINFO_H #define LLVM_TARGET_TARGETREGISTERINFO_H -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/CallingConv.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/MC/MCRegisterInfo.h" #include <cassert> #include <functional> @@ -30,12 +30,13 @@ class BitVector; class MachineFunction; class RegScavenger; template<class T> class SmallVectorImpl; +class VirtRegMap; class raw_ostream; class TargetRegisterClass { public: - typedef const uint16_t* iterator; - typedef const uint16_t* const_iterator; + typedef const MCPhysReg* iterator; + typedef const MCPhysReg* const_iterator; typedef const MVT::SimpleValueType* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; @@ -45,7 +46,7 @@ public: const uint32_t *SubClassMask; const uint16_t *SuperRegIndices; const sc_iterator SuperClasses; - ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&); + ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&); /// getID() - Return the register class ID number. /// @@ -190,7 +191,7 @@ public: /// /// By default, this method returns all registers in the class. /// - ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const { + ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const { return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs()); } }; @@ -407,7 +408,7 @@ public: /// order of desired callee-save stack frame offset. The first register is /// closest to the incoming stack pointer if stack grows down, and vice versa. /// - virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0) + virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0) const = 0; /// getCallPreservedMask - Return a mask of call-preserved registers for the @@ -594,10 +595,13 @@ public: return 0; } -// Get the weight in units of pressure for this register class. + /// Get the weight in units of pressure for this register class. virtual const RegClassWeight &getRegClassWeight( const TargetRegisterClass *RC) const = 0; + /// Get the weight in units of pressure for this register unit. + virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0; + /// Get the number of dimensions of register pressure. virtual unsigned getNumRegPressureSets() const = 0; @@ -613,27 +617,29 @@ public: virtual const int *getRegClassPressureSets( const TargetRegisterClass *RC) const = 0; - /// getRawAllocationOrder - Returns the register allocation order for a - /// specified register class with a target-dependent hint. The returned list - /// may contain reserved registers that cannot be allocated. - /// - /// Register allocators need only call this function to resolve - /// target-dependent hints, but it should work without hinting as well. - virtual ArrayRef<uint16_t> - getRawAllocationOrder(const TargetRegisterClass *RC, - unsigned HintType, unsigned HintReg, - const MachineFunction &MF) const { - return RC->getRawAllocationOrder(MF); - } - - /// ResolveRegAllocHint - Resolves the specified register allocation hint - /// to a physical register. Returns the physical register if it is successful. - virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, - const MachineFunction &MF) const { - if (Type == 0 && Reg && isPhysicalRegister(Reg)) - return Reg; - return 0; - } + /// Get the dimensions of register pressure impacted by this register unit. + /// Returns a -1 terminated array of pressure set IDs. + virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0; + + /// Get a list of 'hint' registers that the register allocator should try + /// first when allocating a physical register for the virtual register + /// VirtReg. These registers are effectively moved to the front of the + /// allocation order. + /// + /// The Order argument is the allocation order for VirtReg's register class + /// as returned from RegisterClassInfo::getOrder(). The hint registers must + /// come from Order, and they must not be reserved. + /// + /// The default implementation of this function can resolve + /// target-independent hints provided to MRI::setRegAllocationHint with + /// HintType == 0. Targets that override this function should defer to the + /// default implementation if they have no reason to change the allocation + /// order for VirtReg. There may be target-independent hints. + virtual void getRegAllocationHints(unsigned VirtReg, + ArrayRef<MCPhysReg> Order, + SmallVectorImpl<MCPhysReg> &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM = 0) const; /// avoidWriteAfterWrite - Return true if the register allocator should avoid /// writing a register from RC in two consecutive instructions. @@ -876,7 +882,8 @@ class PrintReg { unsigned Reg; unsigned SubIdx; public: - PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0) + explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, + unsigned subidx = 0) : TRI(tri), Reg(reg), SubIdx(subidx) {} void print(raw_ostream&) const; }; diff --git a/include/llvm/Target/TargetTransformImpl.h b/include/llvm/Target/TargetTransformImpl.h index 7ea2396076..a94278cfa3 100644 --- a/include/llvm/Target/TargetTransformImpl.h +++ b/include/llvm/Target/TargetTransformImpl.h @@ -15,8 +15,8 @@ #ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H #define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H -#include "llvm/TargetTransformInfo.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/TargetTransformInfo.h" namespace llvm { @@ -26,7 +26,7 @@ class TargetLowering; /// ScalarTargetTransformInfo interface. Different targets can implement /// this interface differently. class ScalarTargetTransformImpl : public ScalarTargetTransformInfo { -private: +protected: const TargetLowering *TLI; public: @@ -90,6 +90,9 @@ public: unsigned Alignment, unsigned AddressSpace) const; + virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, Type *RetTy, + ArrayRef<Type*> Tys) const; + virtual unsigned getNumberOfParts(Type *Tp) const; }; diff --git a/include/llvm/TargetTransformInfo.h b/include/llvm/TargetTransformInfo.h index 94db490443..519ccb9263 100644 --- a/include/llvm/TargetTransformInfo.h +++ b/include/llvm/TargetTransformInfo.h @@ -22,8 +22,9 @@ #ifndef LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE #define LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE -#include "llvm/Pass.h" #include "llvm/AddressingMode.h" +#include "llvm/Intrinsics.h" +#include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" #include "llvm/Type.h" @@ -75,6 +76,18 @@ public: /// LSR, and LowerInvoke use this interface. class ScalarTargetTransformInfo { public: + /// PopcntHwSupport - Hardware support for population count. Compared to the + /// SW implementation, HW support is supposed to significantly boost the + /// performance when the population is dense, and it may or not may degrade + /// performance if the population is sparse. A HW support is considered as + /// "Fast" if it can outperform, or is on a par with, SW implementaion when + /// the population is sparse; otherwise, it is considered as "Slow". + enum PopcntHwSupport { + None, + Fast, + Slow + }; + virtual ~ScalarTargetTransformInfo() {} /// isLegalAddImmediate - Return true if the specified immediate is legal @@ -122,6 +135,11 @@ public: virtual bool shouldBuildLookupTables() const { return true; } + + /// getPopcntHwSupport - Return hardware support for population count. + virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const { + return None; + } }; /// VectorTargetTransformInfo - This interface is used by the vectorizers @@ -192,6 +210,13 @@ public: return 1; } + /// Returns the cost of Intrinsic instructions. + virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, + Type *RetTy, + ArrayRef<Type*> Tys) const { + return 1; + } + /// Returns the number of pieces into which the provided type must be /// split during legalization. Zero is returned when the answer is unknown. virtual unsigned getNumberOfParts(Type *Tp) const { diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index b036040f51..99232de076 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -42,6 +42,7 @@ struct Inliner : public CallGraphSCCPass { // Pass class. virtual bool runOnSCC(CallGraphSCC &SCC); + using llvm::Pass::doFinalization; // doFinalization - Remove now-dead linkonce functions at the end of // processing to avoid breaking the SCC traversal. virtual bool doFinalization(CallGraph &CG); diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 3558251a43..cdd1e03cde 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -14,6 +14,8 @@ #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H #define LLVM_TRANSFORMS_INSTRUMENTATION_H +#include "llvm/ADT/StringRef.h" + namespace llvm { class ModulePass; @@ -31,10 +33,19 @@ ModulePass *createPathProfilerPass(); // Insert GCOV profiling instrumentation ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, bool Use402Format = false, - bool UseExtraChecksum = false); + bool UseExtraChecksum = false, + bool NoRedZone = false); // Insert AddressSanitizer (address sanity checking) instrumentation -FunctionPass *createAddressSanitizerPass(); +FunctionPass *createAddressSanitizerFunctionPass( + bool CheckInitOrder = false, bool CheckUseAfterReturn = false, + bool CheckLifetime = false, StringRef BlacklistFile = StringRef()); +ModulePass *createAddressSanitizerModulePass( + bool CheckInitOrder = false, StringRef BlacklistFile = StringRef()); + +// Insert MemorySanitizer instrumentation (detection of uninitialized reads) +FunctionPass *createMemorySanitizerPass(); + // Insert ThreadSanitizer (race detection) instrumentation FunctionPass *createThreadSanitizerPass(); diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h index 7d672839a6..1f708f27af 100644 --- a/include/llvm/Transforms/Utils/AddrModeMatcher.h +++ b/include/llvm/Transforms/Utils/AddrModeMatcher.h @@ -19,8 +19,8 @@ #ifndef LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H #define LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H -#include "llvm/AddressingMode.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/AddressingMode.h" #include "llvm/Target/TargetLowering.h" namespace llvm { diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h index ab9fc475fa..d5e7e87839 100644 --- a/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -81,7 +81,7 @@ namespace llvm { /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' /// suffix. Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, - const AttrListPtr &Attrs); + const AttributeSet &Attrs); /// EmitPutChar - Emit a call to the putchar function. This assumes that Char /// is an integer. diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h index ac8af122f0..3567ac254b 100644 --- a/include/llvm/Transforms/Utils/BypassSlowDivision.h +++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h @@ -18,6 +18,7 @@ #ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H #define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H +#include "llvm/ADT/DenseMap.h" #include "llvm/Function.h" namespace llvm { diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 1780025a27..14212f622b 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -18,9 +18,9 @@ #ifndef LLVM_TRANSFORMS_UTILS_CLONING_H #define LLVM_TRANSFORMS_UTILS_CLONING_H -#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ValueMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Transforms/Utils/ValueMapper.h" diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index be3029e545..702628d7cd 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -15,10 +15,10 @@ #ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H #define LLVM_TRANSFORMS_UTILS_LOCAL_H +#include "llvm/DataLayout.h" #include "llvm/IRBuilder.h" #include "llvm/Operator.h" #include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/DataLayout.h" namespace llvm { diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index db65a47e97..cd048936e0 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -15,6 +15,7 @@ #define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" namespace llvm { class BasicBlock; diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h index 41e53a83e2..1ba4d22d5f 100644 --- a/include/llvm/Transforms/Vectorize.h +++ b/include/llvm/Transforms/Vectorize.h @@ -18,6 +18,7 @@ namespace llvm { class BasicBlock; class BasicBlockPass; +class Pass; //===----------------------------------------------------------------------===// /// @brief Vectorize configuration. @@ -110,7 +111,7 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); // // LoopVectorize - Create a loop vectorization pass. // -Pass * createLoopVectorizePass(); +Pass *createLoopVectorizePass(); //===----------------------------------------------------------------------===// /// @brief Vectorize the BasicBlock. diff --git a/include/llvm/Value.h b/include/llvm/Value.h index be218183e5..7adf54209c 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -14,9 +14,9 @@ #ifndef LLVM_VALUE_H #define LLVM_VALUE_H -#include "llvm/Use.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Use.h" namespace llvm { diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h index 1738cc4a7a..7493736fee 100644 --- a/include/llvm/ValueSymbolTable.h +++ b/include/llvm/ValueSymbolTable.h @@ -14,9 +14,9 @@ #ifndef LLVM_VALUE_SYMBOL_TABLE_H #define LLVM_VALUE_SYMBOL_TABLE_H -#include "llvm/Value.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Value.h" namespace llvm { template<typename ValueSubClass, typename ItemParentClass> |
