diff options
Diffstat (limited to 'include/llvm')
122 files changed, 3275 insertions, 2587 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 21b8c86..d2566a4 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -109,6 +109,7 @@ namespace llvm { typedef signed short exponent_t; struct fltSemantics; + class APSInt; class StringRef; /* When bits of a floating point number are truncated, this enum is @@ -283,6 +284,7 @@ namespace llvm { opStatus convert(const fltSemantics &, roundingMode, bool *); opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode, bool *) const; + opStatus convertToInteger(APSInt&, roundingMode, bool *) const; opStatus convertFromAPInt(const APInt &, bool, roundingMode); opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int, diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 2feef07..e68e579 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1241,18 +1241,19 @@ public: /// toString - Converts an APInt to a string and append it to Str. Str is /// commonly a SmallString. - void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const; + void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed, + bool formatAsCLiteral = false) const; /// Considers the APInt to be unsigned and converts it into a string in the /// radix given. The radix can be 2, 8, 10 or 16. void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { - toString(Str, Radix, false); + toString(Str, Radix, false, false); } /// Considers the APInt to be signed and converts it into a string in the /// radix given. The radix can be 2, 8, 10 or 16. void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { - toString(Str, Radix, true); + toString(Str, Radix, true, false); } /// toString - This returns the APInt as a std::string. Note that this is an diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 97e42cb..6db866e 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -39,7 +39,7 @@ namespace llvm { const T *Data; /// The number of elements. - size_t Length; + size_type Length; public: /// @name Constructors @@ -56,6 +56,10 @@ namespace llvm { /*implicit*/ ArrayRef(const T *data, size_t length) : Data(data), Length(length) {} + /// Construct an ArrayRef from a range. + ArrayRef(const T *begin, const T *end) + : Data(begin), Length(end - begin) {} + /// Construct an ArrayRef from a SmallVector. /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec) : Data(Vec.data()), Length(Vec.size()) {} @@ -96,6 +100,16 @@ namespace llvm { return Data[Length-1]; } + /// equals - Check for element-wise equality. + bool equals(ArrayRef RHS) const { + if (Length != RHS.Length) + return false; + for (size_type i = 0; i != Length; i++) + if (Data[i] != RHS.Data[i]) + return false; + return true; + } + /// slice(n) - Chop off the first N elements of the array. ArrayRef<T> slice(unsigned N) { assert(N <= size() && "Invalid specifier"); @@ -125,8 +139,30 @@ namespace llvm { } /// @} + /// @name Conversion operators + /// @{ + operator std::vector<T>() const { + return std::vector<T>(Data, Data+Length); + } + + /// @} }; + /// @name ArrayRef Comparison Operators + /// @{ + + template<typename T> + inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) { + return LHS.equals(RHS); + } + + template<typename T> + inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) { + return !(LHS == RHS); + } + + /// @} + // ArrayRefs can be treated like a POD type. template <typename T> struct isPodLike; template <typename T> struct isPodLike<ArrayRef<T> > { diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index 714355b..d7c0074 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -103,6 +103,14 @@ public: /// isEmpty - Returns true if the list is empty. bool isEmpty() const { return !X; } + bool contains(const T& V) const { + for (iterator I = begin(), E = end(); I != E; ++I) { + if (*I == V) + return true; + } + return false; + } + /// isEqual - Returns true if two lists are equal. Because all lists created /// from the same ImmutableListFactory are uniqued, this has O(1) complexity /// because it the contents of the list do not need to be compared. Note diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h index 272322a..2eaddc2 100644 --- a/include/llvm/ADT/PackedVector.h +++ b/include/llvm/ADT/PackedVector.h @@ -90,7 +90,7 @@ public: Vec.setValue(Vec.Bits, Idx, val); return *this; } - operator T() { + operator T() const { return Vec.getValue(Vec.Bits, Idx); } }; diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 8b0a13d..5f0a55b 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -410,7 +410,14 @@ public: this->setEnd(this->end()+1); // Push everything else over. std::copy_backward(I, this->end()-1, this->end()); - *I = Elt; + + // If we just moved the element we're inserting, be sure to update + // the reference. + const T *EltPtr = &Elt; + if (I <= EltPtr && EltPtr < this->EndX) + ++EltPtr; + + *I = *EltPtr; return I; } size_t EltNo = I-this->begin(); diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 934cacc..3507787 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -140,7 +140,7 @@ public: /// StringMapEntry object. const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);} - const char *first() const { return getKeyData(); } + StringRef first() const { return StringRef(getKeyData(), getKeyLength()); } /// Create - Create a StringMapEntry for the specified key and default /// construct the value. @@ -307,7 +307,7 @@ public: return ValueTy(); } - ValueTy& operator[](StringRef Key) { + ValueTy &operator[](StringRef Key) { return GetOrCreateValue(Key).getValue(); } @@ -355,8 +355,7 @@ public: /// exists, return it. Otherwise, default construct a value, insert it, and /// return. template <typename InitTy> - StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key, - InitTy Val) { + MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) { unsigned BucketNo = LookupBucketFor(Key); ItemBucket &Bucket = TheTable[BucketNo]; if (Bucket.Item && Bucket.Item != getTombstoneVal()) @@ -378,22 +377,10 @@ public: return *NewItem; } - StringMapEntry<ValueTy> &GetOrCreateValue(StringRef Key) { + MapEntryTy &GetOrCreateValue(StringRef Key) { return GetOrCreateValue(Key, ValueTy()); } - template <typename InitTy> - StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart, - const char *KeyEnd, - InitTy Val) { - return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart), Val); - } - - StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart, - const char *KeyEnd) { - return GetOrCreateValue(StringRef(KeyStart, KeyEnd - KeyStart)); - } - /// remove - Remove the specified key/value pair from the map, but do not /// erase it. This aborts if the key is not in the map. void remove(MapEntryTy *KeyValue) { diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 078033d..fd23608 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -95,7 +95,8 @@ public: Solaris, Win32, Haiku, - Minix + Minix, + RTEMS }; enum EnvironmentType { UnknownEnvironment, @@ -237,19 +238,10 @@ public: /// specialized because it is a common query. unsigned getOSMajorVersion() const { unsigned Maj, Min, Micro; - getDarwinNumber(Maj, Min, Micro); + getOSVersion(Maj, Min, Micro); return Maj; } - void getDarwinNumber(unsigned &Major, unsigned &Minor, - unsigned &Micro) const { - return getOSVersion(Major, Minor, Micro); - } - - unsigned getDarwinMajorNumber() const { - return getOSMajorVersion(); - } - /// isOSVersionLT - Helper function for doing comparisons against version /// numbers included in the target triple. bool isOSVersionLT(unsigned Major, unsigned Minor = 0, @@ -275,7 +267,7 @@ public: /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). bool isOSDarwin() const { - return isMacOSX() ||getOS() == Triple::IOS; + return isMacOSX() || getOS() == Triple::IOS; } /// isOSWindows - Is this a "Windows" OS. @@ -288,7 +280,7 @@ public: /// compatibility, which handles supporting skewed version numbering schemes /// used by the "darwin" triples. unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0, - unsigned Micro = 0) const { + unsigned Micro = 0) const { assert(isMacOSX() && "Not an OS X triple!"); // If this is OS X, expect a sane version number. @@ -299,7 +291,7 @@ public: assert(Major == 10 && "Unexpected major version"); return isOSVersionLT(Minor + 4, Micro, 0); } - + /// @} /// @name Mutators /// @{ diff --git a/include/llvm/AbstractTypeUser.h b/include/llvm/AbstractTypeUser.h deleted file mode 100644 index 81f5c5c..0000000 --- a/include/llvm/AbstractTypeUser.h +++ /dev/null @@ -1,205 +0,0 @@ -//===-- llvm/AbstractTypeUser.h - AbstractTypeUser Interface ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the AbstractTypeUser class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ABSTRACT_TYPE_USER_H -#define LLVM_ABSTRACT_TYPE_USER_H - -#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H) -#error Do not include this file directly. Include Type.h instead. -#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method -#error PATypeHolder::dropRef() correctly otherwise. -#endif - -// This is the "master" include for <cassert> Whether this file needs it or not, -// it must always include <cassert> for the files which include -// llvm/AbstractTypeUser.h -// -// In this way, most every LLVM source file will have access to the assert() -// macro without having to #include <cassert> directly. -// -#include <cassert> - -namespace llvm { - -class Value; -class Type; -class DerivedType; -template<typename T> struct simplify_type; - -/// The AbstractTypeUser class is an interface to be implemented by classes who -/// could possibly use an abstract type. Abstract types are denoted by the -/// isAbstract flag set to true in the Type class. These are classes that -/// contain an Opaque type in their structure somewhere. -/// -/// Classes must implement this interface so that they may be notified when an -/// abstract type is resolved. Abstract types may be resolved into more -/// concrete types through: linking, parsing, and bitcode reading. When this -/// happens, all of the users of the type must be updated to reference the new, -/// more concrete type. They are notified through the AbstractTypeUser -/// interface. -/// -/// In addition to this, AbstractTypeUsers must keep the use list of the -/// potentially abstract type that they reference up-to-date. To do this in a -/// nice, transparent way, the PATypeHandle class is used to hold "Potentially -/// Abstract Types", and keep the use list of the abstract types up-to-date. -/// @brief LLVM Abstract Type User Representation -class AbstractTypeUser { -protected: - virtual ~AbstractTypeUser(); // Derive from me - - /// setType - It's normally not possible to change a Value's type in place, - /// but an AbstractTypeUser subclass that knows what its doing can be - /// permitted to do so with care. - void setType(Value *V, const Type *NewTy); - -public: - - /// refineAbstractType - The callback method invoked when an abstract type is - /// resolved to another type. An object must override this method to update - /// its internal state to reference NewType instead of OldType. - /// - virtual void refineAbstractType(const DerivedType *OldTy, - const Type *NewTy) = 0; - - /// The other case which AbstractTypeUsers must be aware of is when a type - /// makes the transition from being abstract (where it has clients on its - /// AbstractTypeUsers list) to concrete (where it does not). This method - /// notifies ATU's when this occurs for a type. - /// - virtual void typeBecameConcrete(const DerivedType *AbsTy) = 0; - - // for debugging... - virtual void dump() const = 0; -}; - - -/// PATypeHandle - Handle to a Type subclass. This class is used to keep the -/// use list of abstract types up-to-date. -/// -class PATypeHandle { - const Type *Ty; - AbstractTypeUser * const User; - - // These functions are defined at the bottom of Type.h. See the comment there - // for justification. - void addUser(); - void removeUser(); -public: - // ctor - Add use to type if abstract. Note that Ty must not be null - inline PATypeHandle(const Type *ty, AbstractTypeUser *user) - : Ty(ty), User(user) { - addUser(); - } - - // ctor - Add use to type if abstract. - inline PATypeHandle(const PATypeHandle &T) : Ty(T.Ty), User(T.User) { - addUser(); - } - - // dtor - Remove reference to type... - inline ~PATypeHandle() { removeUser(); } - - // Automatic casting operator so that the handle may be used naturally - inline operator Type *() const { return const_cast<Type*>(Ty); } - inline Type *get() const { return const_cast<Type*>(Ty); } - - // operator= - Allow assignment to handle - inline Type *operator=(const Type *ty) { - if (Ty != ty) { // Ensure we don't accidentally drop last ref to Ty - removeUser(); - Ty = ty; - addUser(); - } - return get(); - } - - // operator= - Allow assignment to handle - inline const Type *operator=(const PATypeHandle &T) { - return operator=(T.Ty); - } - - inline bool operator==(const Type *ty) { - return Ty == ty; - } - - // operator-> - Allow user to dereference handle naturally... - inline const Type *operator->() const { return Ty; } -}; - - -/// PATypeHolder - Holder class for a potentially abstract type. This uses -/// efficient union-find techniques to handle dynamic type resolution. Unless -/// you need to do custom processing when types are resolved, you should always -/// use PATypeHolders in preference to PATypeHandles. -/// -class PATypeHolder { - mutable const Type *Ty; - void destroy(); -public: - PATypeHolder() : Ty(0) {} - PATypeHolder(const Type *ty) : Ty(ty) { - addRef(); - } - PATypeHolder(const PATypeHolder &T) : Ty(T.Ty) { - addRef(); - } - - ~PATypeHolder() { dropRef(); } - - operator Type *() const { return get(); } - Type *get() const; - - // operator-> - Allow user to dereference handle naturally... - Type *operator->() const { return get(); } - - // operator= - Allow assignment to handle - Type *operator=(const Type *ty) { - if (Ty != ty) { // Don't accidentally drop last ref to Ty. - dropRef(); - Ty = ty; - addRef(); - } - return get(); - } - Type *operator=(const PATypeHolder &H) { - return operator=(H.Ty); - } - - /// getRawType - This should only be used to implement the vmcore library. - /// - const Type *getRawType() const { return Ty; } - -private: - void addRef(); - void dropRef(); - friend class TypeMapBase; -}; - -// simplify_type - Allow clients to treat uses just like values when using -// casting operators. -template<> struct simplify_type<PATypeHolder> { - typedef const Type* SimpleType; - static SimpleType getSimplifiedValue(const PATypeHolder &Val) { - return static_cast<SimpleType>(Val.get()); - } -}; -template<> struct simplify_type<const PATypeHolder> { - typedef const Type* SimpleType; - static SimpleType getSimplifiedValue(const PATypeHolder &Val) { - return static_cast<SimpleType>(Val.get()); - } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Analysis/BlockFrequency.h b/include/llvm/Analysis/BlockFrequency.h new file mode 100644 index 0000000..c4b1e08 --- /dev/null +++ b/include/llvm/Analysis/BlockFrequency.h @@ -0,0 +1,53 @@ +//========-------- BlockFrequency.h - Block Frequency Analysis -------========// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Loops should be simplified before this analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H +#define LLVM_ANALYSIS_BLOCKFREQUENCY_H + +#include "llvm/Pass.h" +#include <climits> + +namespace llvm { + +class BranchProbabilityInfo; +template<class BlockT, class FunctionT, class BranchProbInfoT> +class BlockFrequencyImpl; + +/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate +/// IR basic block frequencies. +class BlockFrequency : public FunctionPass { + + BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI; + +public: + static char ID; + + BlockFrequency(); + + ~BlockFrequency(); + + void getAnalysisUsage(AnalysisUsage &AU) const; + + bool runOnFunction(Function &F); + + /// getblockFreq - Return block frequency. Never return 0, value must be + /// positive. Please note that initial frequency is equal to 1024. It means + /// that we should not rely on the value itself, but only on the comparison to + /// the other block frequencies. We do this to avoid using of the floating + /// points. + uint32_t getBlockFreq(BasicBlock *BB); +}; + +} + +#endif diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h new file mode 100644 index 0000000..6580fd1 --- /dev/null +++ b/include/llvm/Analysis/BlockFrequencyImpl.h @@ -0,0 +1,349 @@ +//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Shared implementation of BlockFrequency for IR and Machine Instructions. +// +//===----------------------------------------------------------------------===// + +#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/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Support/BranchProbability.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include <vector> +#include <sstream> +#include <string> + +namespace llvm { + + +class BlockFrequency; +class MachineBlockFrequency; + +/// BlockFrequencyImpl implements block frequency algorithm for IR and +/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ) +/// for the entry block and then propagates frequencies using branch weights +/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because +/// algorithm can find "backedges" by itself. +template<class BlockT, class FunctionT, class BlockProbInfoT> +class BlockFrequencyImpl { + + DenseMap<BlockT *, uint32_t> Freqs; + + BlockProbInfoT *BPI; + + FunctionT *Fn; + + typedef GraphTraits< Inverse<BlockT *> > GT; + + static const uint32_t START_FREQ = 1024; + + std::string getBlockName(BasicBlock *BB) const { + return BB->getNameStr(); + } + + std::string getBlockName(MachineBasicBlock *MBB) const { + std::stringstream ss; + ss << "BB#" << MBB->getNumber(); + + if (const BasicBlock *BB = MBB->getBasicBlock()) + ss << " derived from LLVM BB " << BB->getNameStr(); + + return ss.str(); + } + + void setBlockFreq(BlockT *BB, uint32_t Freq) { + Freqs[BB] = Freq; + DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n"); + } + + /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst + /// edge probability. + uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const { + BranchProbability Prob = BPI->getEdgeProbability(Src, Dst); + uint64_t N = Prob.getNumerator(); + uint64_t D = Prob.getDenominator(); + uint64_t Res = (N * getBlockFreq(Src)) / D; + + assert(Res <= UINT32_MAX); + return (uint32_t) Res; + } + + /// incBlockFreq - Increase BB block frequency by FREQ. + /// + void incBlockFreq(BlockT *BB, uint32_t Freq) { + Freqs[BB] += Freq; + DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq + << " --> " << Freqs[BB] << "\n"); + } + + /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing. + /// + void divBlockFreq(BlockT *BB, BranchProbability Prob) { + uint64_t N = Prob.getNumerator(); + assert(N && "Illegal division by zero!"); + uint64_t D = Prob.getDenominator(); + uint64_t Freq = (Freqs[BB] * D) / N; + + // Should we assert it? + if (Freq > UINT32_MAX) + Freq = UINT32_MAX; + + Freqs[BB] = (uint32_t) Freq; + DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob + << ") --> " << Freqs[BB] << "\n"); + } + + // All blocks in postorder. + std::vector<BlockT *> POT; + + // Map Block -> Position in reverse-postorder list. + DenseMap<BlockT *, unsigned> RPO; + + // Cycle Probability for each bloch. + DenseMap<BlockT *, uint32_t> CycleProb; + + // (reverse-)postorder traversal iterators. + typedef typename std::vector<BlockT *>::iterator pot_iterator; + typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator; + + pot_iterator pot_begin() { return POT.begin(); } + pot_iterator pot_end() { return POT.end(); } + + rpot_iterator rpot_begin() { return POT.rbegin(); } + rpot_iterator rpot_end() { return POT.rend(); } + + rpot_iterator rpot_at(BlockT *BB) { + rpot_iterator I = rpot_begin(); + unsigned idx = RPO[BB]; + assert(idx); + std::advance(I, idx - 1); + + assert(*I == BB); + return I; + } + + + /// Return a probability of getting to the DST block through SRC->DST edge. + /// + BranchProbability getBackEdgeProbability(BlockT *Src, BlockT *Dst) const { + uint32_t N = getEdgeFreq(Src, Dst); + uint32_t D = getBlockFreq(Dst); + + return BranchProbability(N, D); + } + + /// isReachable - Returns if BB block is reachable from the entry. + /// + bool isReachable(BlockT *BB) { + return RPO.count(BB); + } + + /// isBackedge - Return if edge Src -> Dst is a backedge. + /// + bool isBackedge(BlockT *Src, BlockT *Dst) { + assert(isReachable(Src)); + assert(isReachable(Dst)); + + unsigned a = RPO[Src]; + unsigned b = RPO[Dst]; + + return a > b; + } + + /// getSingleBlockPred - return single BB block predecessor or NULL if + /// BB has none or more predecessors. + BlockT *getSingleBlockPred(BlockT *BB) { + typename GT::ChildIteratorType + PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB), + PE = GraphTraits< Inverse<BlockT *> >::child_end(BB); + + if (PI == PE) + return 0; + + BlockT *Pred = *PI; + + ++PI; + if (PI != PE) + return 0; + + return Pred; + } + + void doBlock(BlockT *BB, BlockT *LoopHead, + SmallPtrSet<BlockT *, 8> &BlocksInLoop) { + + DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n"); + setBlockFreq(BB, 0); + + if (BB == LoopHead) { + setBlockFreq(BB, START_FREQ); + return; + } + + if(BlockT *Pred = getSingleBlockPred(BB)) { + if (BlocksInLoop.count(Pred)) + setBlockFreq(BB, getEdgeFreq(Pred, BB)); + // TODO: else? irreducible, ignore it for now. + return; + } + + bool isInLoop = false; + bool isLoopHead = false; + + for (typename GT::ChildIteratorType + PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB), + PE = GraphTraits< Inverse<BlockT *> >::child_end(BB); + PI != PE; ++PI) { + BlockT *Pred = *PI; + + if (isReachable(Pred) && isBackedge(Pred, BB)) { + isLoopHead = true; + } else if (BlocksInLoop.count(Pred)) { + incBlockFreq(BB, getEdgeFreq(Pred, BB)); + isInLoop = true; + } + // TODO: else? irreducible. + } + + if (!isInLoop) + return; + + if (!isLoopHead) + return; + + assert(START_FREQ >= CycleProb[BB]); + uint32_t CProb = CycleProb[BB]; + uint32_t Numerator = START_FREQ - CProb ? START_FREQ - CProb : 1; + divBlockFreq(BB, BranchProbability(Numerator, START_FREQ)); + } + + /// doLoop - Propagate block frequency down throught the loop. + void doLoop(BlockT *Head, BlockT *Tail) { + DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", " + << getBlockName(Tail) << ")\n"); + + SmallPtrSet<BlockT *, 8> BlocksInLoop; + + for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) { + BlockT *BB = *I; + doBlock(BB, Head, BlocksInLoop); + + BlocksInLoop.insert(BB); + } + + // Compute loop's cyclic probability using backedges probabilities. + for (typename GT::ChildIteratorType + PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head), + PE = GraphTraits< Inverse<BlockT *> >::child_end(Head); + PI != PE; ++PI) { + BlockT *Pred = *PI; + assert(Pred); + if (isReachable(Pred) && isBackedge(Pred, Head)) { + BranchProbability Prob = getBackEdgeProbability(Pred, Head); + uint64_t N = Prob.getNumerator(); + uint64_t D = Prob.getDenominator(); + uint64_t Res = (N * START_FREQ) / D; + + assert(Res <= UINT32_MAX); + CycleProb[Head] += (uint32_t) Res; + } + } + } + + friend class BlockFrequency; + friend class MachineBlockFrequency; + + void doFunction(FunctionT *fn, BlockProbInfoT *bpi) { + Fn = fn; + BPI = bpi; + + // Clear everything. + RPO.clear(); + POT.clear(); + CycleProb.clear(); + Freqs.clear(); + + BlockT *EntryBlock = fn->begin(); + + copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT)); + + unsigned RPOidx = 0; + for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) { + BlockT *BB = *I; + RPO[BB] = ++RPOidx; + DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n"); + } + + // Travel over all blocks in postorder. + for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) { + BlockT *BB = *I; + BlockT *LastTail = 0; + DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n"); + + for (typename GT::ChildIteratorType + PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB), + PE = GraphTraits< Inverse<BlockT *> >::child_end(BB); + PI != PE; ++PI) { + + BlockT *Pred = *PI; + if (isReachable(Pred) && isBackedge(Pred, BB) + && (!LastTail || RPO[Pred] > RPO[LastTail])) + LastTail = Pred; + } + + if (LastTail) + doLoop(BB, LastTail); + } + + // At the end assume the whole function as a loop, and travel over it once + // again. + doLoop(*(rpot_begin()), *(pot_begin())); + } + +public: + /// getBlockFreq - Return block frequency. Never return 0, value must be + /// positive. + uint32_t getBlockFreq(BlockT *BB) const { + typename DenseMap<BlockT *, uint32_t>::const_iterator I = Freqs.find(BB); + if (I != Freqs.end()) + return I->second ? I->second : 1; + return 1; + } + + void print(raw_ostream &OS) const { + OS << "\n\n---- Block Freqs ----\n"; + for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) { + BlockT *BB = I++; + OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n"; + + for (typename GraphTraits<BlockT *>::ChildIteratorType + SI = GraphTraits<BlockT *>::child_begin(BB), + SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) { + BlockT *Succ = *SI; + OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ) + << " = " << getEdgeFreq(BB, Succ) << "\n"; + } + } + } + + void dump() const { + print(dbgs()); + } +}; + +} + +#endif diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 91f289d..02ead98 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -15,8 +15,9 @@ #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H #include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/BranchProbability.h" -#include "llvm/Analysis/LoopInfo.h" namespace llvm { @@ -25,6 +26,11 @@ class raw_ostream; class BranchProbabilityInfo : public FunctionPass { // Default weight value. Used when we don't have information about the edge. + // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of + // the successors have a weight yet. But it doesn't make sense when providing + // weight to an edge that may have siblings with non-zero weights. This can + // be handled various ways, but it's probably fine for an edge with unknown + // weight to just "inherit" the non-zero weight of an adjacent successor. static const uint32_t DEFAULT_WEIGHT = 16; typedef std::pair<BasicBlock *, BasicBlock *> Edge; @@ -41,10 +47,7 @@ public: initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry()); } - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<LoopInfo>(); - AU.setPreservesAll(); - } + void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnFunction(Function &F); diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 96c6587..a706cc8 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -135,6 +135,7 @@ namespace llvm { unsigned Flags); /// createMemberType - Create debugging information entry for a member. + /// @param Scope Member scope. /// @param Name Member name. /// @param File File where this member is defined. /// @param LineNo Line number. @@ -143,7 +144,7 @@ namespace llvm { /// @param OffsetInBits Member offset. /// @param Flags Flags to encode member attribute, e.g. private /// @param Ty Parent type. - DIType createMemberType(StringRef Name, DIFile File, + DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty); diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 1b78fe4..e56d24d 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -37,8 +37,8 @@ class TargetData; class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { friend class IVUsers; public: - IVStrideUse(IVUsers *P, Instruction* U, Value *O, Value *PN) - : CallbackVH(U), Parent(P), OperandValToReplace(O), Phi(PN) { + IVStrideUse(IVUsers *P, Instruction* U, Value *O) + : CallbackVH(U), Parent(P), OperandValToReplace(O) { } /// getUser - Return the user instruction for this use. @@ -51,11 +51,6 @@ public: setValPtr(NewUser); } - /// getPhi - Return the phi node that represents this IV. - PHINode *getPhi() const { - return cast<PHINode>(Phi); - } - /// getOperandValToReplace - Return the Value of the operand in the user /// instruction that this IVStrideUse is representing. Value *getOperandValToReplace() const { @@ -86,9 +81,6 @@ private: /// that this IVStrideUse is representing. WeakVH OperandValToReplace; - /// Phi - The loop header phi that represents this IV. - WeakVH Phi; - /// PostIncLoops - The set of loops for which Expr has been adjusted to /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. PostIncLoopSet PostIncLoops; @@ -151,9 +143,9 @@ public: /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. - bool AddUsersIfInteresting(Instruction *I, PHINode *Phi); + bool AddUsersIfInteresting(Instruction *I); - IVStrideUse &AddUser(Instruction *User, Value *Operand, PHINode *Phi); + IVStrideUse &AddUser(Instruction *User, Value *Operand); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index b56fe08..34860e7 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -90,18 +90,27 @@ namespace llvm { /// get methods: These are static ctor methods for creating various /// MemDepResult kinds. static MemDepResult getDef(Instruction *Inst) { + assert(Inst && "Def requires inst"); return MemDepResult(PairTy(Inst, Def)); } static MemDepResult getClobber(Instruction *Inst) { + assert(Inst && "Clobber requires inst"); return MemDepResult(PairTy(Inst, Clobber)); } static MemDepResult getNonLocal() { return MemDepResult(PairTy(0, NonLocal)); } + static MemDepResult getUnknown() { + return MemDepResult(PairTy(0, Clobber)); + } /// isClobber - Return true if this MemDepResult represents a query that is /// a instruction clobber dependency. - bool isClobber() const { return Value.getInt() == Clobber; } + bool isClobber() const { return Value.getInt() == Clobber && getInst(); } + + /// isUnknown - Return true if this MemDepResult represents a query which + /// cannot and/or will not be computed. + bool isUnknown() const { return Value.getInt() == Clobber && !getInst(); } /// isDef - Return true if this MemDepResult represents a query that is /// a instruction definition dependency. diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index 0eff75f..a22bd12 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -88,6 +88,13 @@ namespace llvm { //===--------------------------------------------------------------------===// // + // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based + // alias analysis. + // + ImmutablePass *createObjCARCAliasAnalysisPass(); + + //===--------------------------------------------------------------------===// + // // createProfileLoaderPass - This pass loads information from a profile dump // file. // diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 39d378e..a8c03b2 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -30,6 +30,10 @@ namespace llvm { /// memory. class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { ScalarEvolution &SE; + + // New instructions receive a name to identifies them with the current pass. + const char* IVName; + std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > InsertedExpressions; std::set<AssertingVH<Value> > InsertedValues; @@ -67,9 +71,9 @@ namespace llvm { public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. - explicit SCEVExpander(ScalarEvolution &se) - : SE(se), IVIncInsertLoop(0), CanonicalMode(true), - Builder(se.getContext(), TargetFolder(se.TD)) {} + explicit SCEVExpander(ScalarEvolution &se, const char *name) + : SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0), + CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {} /// clear - Erase the contents of the InsertedExpressions map so that users /// trying to expand the same expression into multiple BasicBlocks or diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 6df1693..6826330 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -15,6 +15,7 @@ #ifndef LLVM_ANALYSIS_VALUETRACKING_H #define LLVM_ANALYSIS_VALUETRACKING_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" #include <string> @@ -108,18 +109,9 @@ namespace llvm { /// If InsertBefore is not null, this function will duplicate (modified) /// insertvalues when a part of a nested struct is extracted. Value *FindInsertedValue(Value *V, - const unsigned *idx_begin, - const unsigned *idx_end, + ArrayRef<unsigned> idx_range, Instruction *InsertBefore = 0); - /// This is a convenience wrapper for finding values indexed by a single index - /// only. - inline Value *FindInsertedValue(Value *V, const unsigned Idx, - Instruction *InsertBefore = 0) { - const unsigned Idxs[1] = { Idx }; - return FindInsertedValue(V, &Idxs[0], &Idxs[1], InsertBefore); - } - /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if /// it can be expressed as a base pointer plus a constant offset. Return the /// base and offset to the caller. @@ -158,6 +150,10 @@ namespace llvm { return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup); } + /// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer + /// are lifetime markers. + bool onlyUsedByLifetimeMarkers(const Value *V); + } // end namespace llvm #endif diff --git a/include/llvm/Assembly/Writer.h b/include/llvm/Assembly/Writer.h index c5b2390..8d8befd 100644 --- a/include/llvm/Assembly/Writer.h +++ b/include/llvm/Assembly/Writer.h @@ -17,52 +17,12 @@ #ifndef LLVM_ASSEMBLY_WRITER_H #define LLVM_ASSEMBLY_WRITER_H -#include <string> - namespace llvm { class Type; class Module; class Value; class raw_ostream; -template <typename T> class SmallVectorImpl; - -/// TypePrinting - Type printing machinery. -class TypePrinting { - void *TypeNames; // A map to remember type names. - TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT - void operator=(const TypePrinting&); // DO NOT IMPLEMENT -public: - TypePrinting(); - ~TypePrinting(); - - void clear(); - - void print(const Type *Ty, raw_ostream &OS, bool IgnoreTopLevelName = false); - - void printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) { - print(Ty, OS, true); - } - - /// hasTypeName - Return true if the type has a name in TypeNames, false - /// otherwise. - bool hasTypeName(const Type *Ty) const; - - /// addTypeName - Add a name for the specified type if it doesn't already have - /// one. This name will be printed instead of the structural version of the - /// type in order to make the output more concise. - void addTypeName(const Type *Ty, const std::string &N); - -private: - void CalcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack, - raw_ostream &OS, bool IgnoreTopLevelName = false); -}; - -// WriteTypeSymbolic - This attempts to write the specified type as a symbolic -// type, if there is an entry in the Module's symbol table for the specified -// type or one of its component types. -// -void WriteTypeSymbolic(raw_ostream &, const Type *, const Module *M); // WriteAsOperand - Write the name of the specified value out to the specified // ostream. This can be useful when you just want to print int %reg126, not the diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 8b69d6e..233eab8 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -69,6 +69,9 @@ const Attributes Hotpatch = 1<<29; ///< Function should have special ///'hotpatch' sequence in prologue const Attributes UWTable = 1<<30; ///< Function must be in a unwind ///table +const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or + /// often, so lazy binding isn't + /// worthwhile. /// Note that uwtable is about the ABI or the user mandating an entry in the /// unwind table. The nounwind attribute is about an exception passing by the @@ -90,7 +93,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | - Hotpatch | UWTable; + Hotpatch | UWTable | NonLazyBind; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 7e7c9e7..3b953c0 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -110,7 +110,7 @@ public: Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, + /// BasicBlock can only be used by Users (specifically terminators /// and BlockAddress's). User *use_back() { return cast<User>(*use_begin());} const User *use_back() const { return cast<User>(*use_begin());} @@ -138,6 +138,12 @@ public: return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg(); } + // Same as above, but also skip lifetime intrinsics. + Instruction* getFirstNonPHIOrDbgOrLifetime(); + const Instruction* getFirstNonPHIOrDbgOrLifetime() const { + return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime(); + } + /// removeFromParent - This method unlinks 'this' from the containing /// function, but does not delete it. /// @@ -248,6 +254,10 @@ public: /// other than direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } + /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors + /// to refer to basic block New instead of to us. + void replaceSuccessorsPhiUsesWith(BasicBlock *New); + private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 779ef5f..0437f53 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -194,6 +194,7 @@ public: CurAbbrevs[i]->addRef(); // Copy block scope and bump ref counts. + BlockScope = RHS.BlockScope; for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); S != e; ++S) { std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; @@ -375,10 +376,12 @@ public: // Check that the block wasn't partially defined, and that the offset isn't // bogus. - if (AtEndOfStream() || NextChar+NumWords*4 > BitStream->getLastChar()) + const unsigned char *const SkipTo = NextChar + NumWords*4; + if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || + SkipTo < BitStream->getFirstChar()) return true; - NextChar += NumWords*4; + NextChar = SkipTo; return false; } diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 7692bd2..df68bd5 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -29,13 +29,23 @@ namespace bitc { // Module sub-block id's. PARAMATTR_BLOCK_ID, - TYPE_BLOCK_ID, + + /// TYPE_BLOCK_ID_OLD - This is the type descriptor block in LLVM 2.9 and + /// earlier, replaced with TYPE_BLOCK_ID2. FIXME: Remove in LLVM 3.1. + TYPE_BLOCK_ID_OLD, + CONSTANTS_BLOCK_ID, FUNCTION_BLOCK_ID, - TYPE_SYMTAB_BLOCK_ID, + + /// TYPE_SYMTAB_BLOCK_ID_OLD - This type descriptor is from LLVM 2.9 and + /// earlier bitcode files. FIXME: Remove in LLVM 3.1 + TYPE_SYMTAB_BLOCK_ID_OLD, + VALUE_SYMTAB_BLOCK_ID, METADATA_BLOCK_ID, - METADATA_ATTACHMENT_ID + METADATA_ATTACHMENT_ID, + + TYPE_BLOCK_ID_NEW }; @@ -72,31 +82,38 @@ namespace bitc { /// TYPE blocks have codes for each type primitive they use. enum TypeCodes { - TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] + TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] // Type Codes - TYPE_CODE_VOID = 2, // VOID - TYPE_CODE_FLOAT = 3, // FLOAT - TYPE_CODE_DOUBLE = 4, // DOUBLE - TYPE_CODE_LABEL = 5, // LABEL - TYPE_CODE_OPAQUE = 6, // OPAQUE - TYPE_CODE_INTEGER = 7, // INTEGER: [width] - TYPE_CODE_POINTER = 8, // POINTER: [pointee type] - TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N] - TYPE_CODE_STRUCT = 10, // STRUCT: [ispacked, eltty x N] - TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] - TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] + TYPE_CODE_VOID = 2, // VOID + TYPE_CODE_FLOAT = 3, // FLOAT + TYPE_CODE_DOUBLE = 4, // DOUBLE + TYPE_CODE_LABEL = 5, // LABEL + TYPE_CODE_OPAQUE = 6, // OPAQUE + TYPE_CODE_INTEGER = 7, // INTEGER: [width] + TYPE_CODE_POINTER = 8, // POINTER: [pointee type] + TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N] + + // FIXME: This is the encoding used for structs in LLVM 2.9 and earlier. + // REMOVE this in LLVM 3.1 + TYPE_CODE_STRUCT_OLD = 10, // STRUCT: [ispacked, eltty x N] + TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] + TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] // These are not with the other floating point types because they're // a late addition, and putting them in the right place breaks // binary compatibility. - TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE - TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) - TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) + TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE + TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) + TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) - TYPE_CODE_METADATA = 16, // METADATA + TYPE_CODE_METADATA = 16, // METADATA - TYPE_CODE_X86_MMX = 17 // X86 MMX + TYPE_CODE_X86_MMX = 17, // X86 MMX + + TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N] + TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N] + TYPE_CODE_STRUCT_NAMED = 20 // STRUCT_NAMED: [ispacked, eltty x N] }; // The type symbol table only has one code (TST_ENTRY_CODE). @@ -112,20 +129,16 @@ namespace bitc { enum MetadataCodes { METADATA_STRING = 1, // MDSTRING: [values] - // FIXME: Remove NODE in favor of NODE2 in LLVM 3.0 - METADATA_NODE = 2, // NODE with potentially invalid metadata - // FIXME: Remove FN_NODE in favor of FN_NODE2 in LLVM 3.0 - METADATA_FN_NODE = 3, // FN_NODE with potentially invalid metadata + // 2 is unused. + // 3 is unused. METADATA_NAME = 4, // STRING: [values] - // FIXME: Remove NAMED_NODE in favor of NAMED_NODE2 in LLVM 3.0 - METADATA_NAMED_NODE = 5, // NAMED_NODE with potentially invalid metadata + // 5 is unused. METADATA_KIND = 6, // [n x [id, name]] - // FIXME: Remove ATTACHMENT in favor of ATTACHMENT2 in LLVM 3.0 - METADATA_ATTACHMENT = 7, // ATTACHMENT with potentially invalid metadata - METADATA_NODE2 = 8, // NODE2: [n x (type num, value num)] - METADATA_FN_NODE2 = 9, // FN_NODE2: [n x (type num, value num)] - METADATA_NAMED_NODE2 = 10, // NAMED_NODE2: [n x mdnodes] - METADATA_ATTACHMENT2 = 11 // [m x [value, [n x [id, mdnode]]] + // 7 is unused. + METADATA_NODE = 8, // NODE: [n x (type num, value num)] + METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)] + METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] + METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each // constant and maintains an implicit current type value. @@ -227,21 +240,18 @@ namespace bitc { FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] - FUNC_CODE_INST_MALLOC = 17, // MALLOC: [instty, op, align] - FUNC_CODE_INST_FREE = 18, // FREE: [opty, op] + // 17 is unused. + // 18 is unused. FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align] FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] - // FIXME: Remove STORE in favor of STORE2 in LLVM 3.0 - FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol] - // FIXME: Remove CALL in favor of CALL2 in LLVM 3.0 - FUNC_CODE_INST_CALL = 22, // CALL with potentially invalid metadata + // 21 is unused. + // 22 is unused. FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty] // This store code encodes the pointer type, rather than the value type // this is so information only available in the pointer type (e.g. address // spaces) is retained. - FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol] - // FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0 - FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n] + FUNC_CODE_INST_STORE = 24, // STORE: [ptrty,ptr,val, align, vol] + // 25 is unused. FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands] FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands] // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to @@ -251,14 +261,12 @@ namespace bitc { FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...] - - // FIXME: Remove DEBUG_LOC in favor of DEBUG_LOC2 in LLVM 3.0 - FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC with potentially invalid metadata + // 32 is unused. FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN - FUNC_CODE_INST_CALL2 = 34, // CALL2: [attr, fnty, fnid, args...] + FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...] - FUNC_CODE_DEBUG_LOC2 = 35 // DEBUG_LOC2: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_DEBUG_LOC = 35 // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] }; } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index 78bf9fc..f8a7029 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -16,6 +16,7 @@ #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" @@ -37,6 +38,12 @@ unsigned ComputeLinearIndex(const Type *Ty, const unsigned *IndicesEnd, unsigned CurIndex = 0); +inline unsigned ComputeLinearIndex(const Type *Ty, + ArrayRef<unsigned> Indices, + unsigned CurIndex = 0) { + return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex); +} + /// ComputeValueVTs - Given an LLVM IR type, compute a sequence of /// EVTs that represent all the individual underlying /// non-aggregate types that comprise it. diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 5eea099..06c5c83 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -465,8 +465,8 @@ namespace llvm { void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid) const; - void EmitLLVMUsedList(Constant *List); - void EmitXXStructorList(Constant *List); + void EmitLLVMUsedList(const Constant *List); + void EmitXXStructorList(const Constant *List); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; } diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 4421cc0..84bbf48 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -24,6 +24,7 @@ #ifndef NDEBUG #include "llvm/ADT/SmallSet.h" #endif +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -57,7 +58,7 @@ public: const Function *Fn; MachineFunction *MF; MachineRegisterInfo *RegInfo; - + BranchProbabilityInfo *BPI; /// CanLowerReturn - true iff the function's return value can be lowered to /// registers. bool CanLowerReturn; diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index e765cad..459cecd 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -232,7 +232,7 @@ namespace ISD { SMULO, UMULO, // Simple binary floating point operators. - FADD, FSUB, FMUL, FDIV, FREM, + FADD, FSUB, FMUL, FMA, FDIV, FREM, // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This // DAG node does not require that X and Y have the same type, just that they @@ -580,7 +580,8 @@ namespace ISD { // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are // their first operand. The other operands are the address to prefetch, - // read / write specifier, and locality specifier. + // read / write specifier, locality specifier and instruction / data cache + // specifier. PREFETCH, // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index c931261..098dd0b 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -39,8 +39,6 @@ namespace { (void) llvm::createGreedyRegisterAllocator(); (void) llvm::createDefaultPBQPRegisterAllocator(); - (void) llvm::createSimpleRegisterCoalescer(); - llvm::linkOcamlGC(); llvm::linkShadowStackGC(); diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index ad12157..397e59e 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/Support/DataTypes.h" #include <functional> namespace llvm { @@ -27,6 +28,7 @@ class MCSymbol; class SlotIndexes; class StringRef; class raw_ostream; +class MachineBranchProbabilityInfo; template <> struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> { @@ -63,12 +65,19 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> { const BasicBlock *BB; int Number; MachineFunction *xParent; - + /// Predecessors/Successors - Keep track of the predecessor / successor /// basicblocks. std::vector<MachineBasicBlock *> Predecessors; std::vector<MachineBasicBlock *> Successors; + + /// Weights - Keep track of the weights to the successors. This vector + /// has the same order as Successors, or it is empty if we don't use it + /// (disable optimization). + std::vector<uint32_t> Weights; + typedef std::vector<uint32_t>::iterator weight_iterator; + /// LiveIns - Keep track of the physical registers that are livein of /// the basicblock. std::vector<unsigned> LiveIns; @@ -244,11 +253,13 @@ public: void updateTerminator(); // Machine-CFG mutators - + /// addSuccessor - Add succ as a successor of this MachineBasicBlock. - /// The Predecessors list of succ is automatically updated. + /// The Predecessors list of succ is automatically updated. WEIGHT + /// parameter is stored in Weights list and it may be used by + /// MachineBranchProbabilityInfo analysis to calculate branch probability. /// - void addSuccessor(MachineBasicBlock *succ); + void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0); /// removeSuccessor - Remove successor from the successors list of this /// MachineBasicBlock. The Predecessors list of succ is automatically updated. @@ -260,7 +271,12 @@ public: /// updated. Return the iterator to the element after the one removed. /// succ_iterator removeSuccessor(succ_iterator I); - + + /// replaceSuccessor - Replace successor OLD with NEW and update weight info. + /// + void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New); + + /// transferSuccessors - Transfers all the successors from MBB to this /// machine basic block (i.e., copies all the successors fromMBB and /// remove all the successors from fromMBB). @@ -396,8 +412,22 @@ public: /// getSymbol - Return the MCSymbol for this basic block. /// MCSymbol *getSymbol() const; - -private: // Methods used to maintain doubly linked list of blocks... + + +private: + /// getWeightIterator - Return weight iterator corresponding to the I + /// successor iterator. + weight_iterator getWeightIterator(succ_iterator I); + + friend class MachineBranchProbabilityInfo; + + /// getSuccWeight - Return weight of the edge from this block to MBB. This + /// method should NOT be called directly, but by using getEdgeWeight method + /// from MachineBranchProbabilityInfo class. + uint32_t getSuccWeight(MachineBasicBlock *succ); + + + // Methods used to maintain doubly linked list of blocks... friend struct ilist_traits<MachineBasicBlock>; // Machine-CFG mutators diff --git a/include/llvm/CodeGen/MachineBlockFrequency.h b/include/llvm/CodeGen/MachineBlockFrequency.h new file mode 100644 index 0000000..25bf1f0 --- /dev/null +++ b/include/llvm/CodeGen/MachineBlockFrequency.h @@ -0,0 +1,53 @@ +//====----- MachineBlockFrequency.h - MachineBlock Frequency Analysis ----====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Loops should be simplified before this analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H +#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H + +#include "llvm/CodeGen/MachineFunctionPass.h" +#include <climits> + +namespace llvm { + +class MachineBranchProbabilityInfo; +template<class BlockT, class FunctionT, class BranchProbInfoT> +class BlockFrequencyImpl; + +/// MachineBlockFrequency pass uses BlockFrequencyImpl implementation to estimate +/// machine basic block frequencies. +class MachineBlockFrequency : public MachineFunctionPass { + + BlockFrequencyImpl<MachineBasicBlock, MachineFunction, MachineBranchProbabilityInfo> *MBFI; + +public: + static char ID; + + MachineBlockFrequency(); + + ~MachineBlockFrequency(); + + void getAnalysisUsage(AnalysisUsage &AU) const; + + bool runOnMachineFunction(MachineFunction &F); + + /// getblockFreq - Return block frequency. Never return 0, value must be + /// positive. Please note that initial frequency is equal to 1024. It means + /// that we should not rely on the value itself, but only on the comparison to + /// the other block frequencies. We do this to avoid using of the floating + /// points. + uint32_t getBlockFreq(MachineBasicBlock *MBB); +}; + +} + +#endif diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h new file mode 100644 index 0000000..d9673e2 --- /dev/null +++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -0,0 +1,78 @@ + +//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass is used to evaluate branch probabilties on machine basic blocks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H +#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H + +#include "llvm/Pass.h" +#include "llvm/Support/BranchProbability.h" +#include <climits> + +namespace llvm { + +class raw_ostream; +class MachineBasicBlock; + +class MachineBranchProbabilityInfo : public ImmutablePass { + + // Default weight value. Used when we don't have information about the edge. + // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of + // the successors have a weight yet. But it doesn't make sense when providing + // weight to an edge that may have siblings with non-zero weights. This can + // be handled various ways, but it's probably fine for an edge with unknown + // weight to just "inherit" the non-zero weight of an adjacent successor. + static const uint32_t DEFAULT_WEIGHT = 16; + + // Get sum of the block successors' weights. + uint32_t getSumForBlock(MachineBasicBlock *MBB) const; + +public: + static char ID; + + MachineBranchProbabilityInfo() : ImmutablePass(ID) { + PassRegistry &Registry = *PassRegistry::getPassRegistry(); + initializeMachineBranchProbabilityInfoPass(Registry); + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + + // Return edge weight. If we don't have any informations about it - return + // DEFAULT_WEIGHT. + uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst) const; + + // A 'Hot' edge is an edge which probability is >= 80%. + bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const; + + // Return a hot successor for the block BB or null if there isn't one. + MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const; + + // Return a probability as a fraction between 0 (0% probability) and + // 1 (100% probability), however the value is never equal to 0, and can be 1 + // only iff SRC block has only one successor. + BranchProbability getEdgeProbability(MachineBasicBlock *Src, + MachineBasicBlock *Dst) const; + + // Print value between 0 (0% probability) and 1 (100% probability), + // however the value is never equal to 0, and can be 1 only iff SRC block + // has only one successor. + raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src, + MachineBasicBlock *Dst) const; +}; + +} + + +#endif diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index f56c053..6e08f7b 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -345,7 +345,7 @@ public: /// CreateMachineInstr - Allocate a new MachineInstr. Use this instead /// of `new MachineInstr'. /// - MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID, + MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImp = false); diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index c36dd69..5b3d3ea 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -17,11 +17,12 @@ #define LLVM_CODEGEN_MACHINEINSTR_H #include "llvm/CodeGen/MachineOperand.h" -#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/MC/MCInstrDesc.h" #include "llvm/Target/TargetOpcodes.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/DebugLoc.h" #include <vector> @@ -30,7 +31,6 @@ namespace llvm { template <typename T> class SmallVectorImpl; class AliasAnalysis; -class TargetInstrDesc; class TargetInstrInfo; class TargetRegisterInfo; class MachineFunction; @@ -57,7 +57,7 @@ public: // function frame setup code. }; private: - const TargetInstrDesc *TID; // Instruction descriptor. + const MCInstrDesc *MCID; // Instruction descriptor. uint16_t NumImplicitOps; // Number of implicit operands (which // are determined at construction time). @@ -94,7 +94,7 @@ private: MachineInstr(MachineFunction &, const MachineInstr &); /// MachineInstr ctor - This constructor creates a dummy MachineInstr with - /// TID NULL and no operands. + /// MCID NULL and no operands. MachineInstr(); // The next two constructors have DebugLoc and non-DebugLoc versions; @@ -103,25 +103,25 @@ private: /// MachineInstr ctor - This constructor creates a MachineInstr and adds the /// implicit operands. It reserves space for the number of operands specified - /// by the TargetInstrDesc. The version with a DebugLoc should be preferred. - explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false); + /// by the MCInstrDesc. The version with a DebugLoc should be preferred. + explicit MachineInstr(const MCInstrDesc &MCID, 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. The version with a DebugLoc should be preferred. - MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); + MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID); /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by - /// TargetInstrDesc. An explicit DebugLoc is supplied. - explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, + /// MCInstrDesc. An explicit DebugLoc is supplied. + explicit 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 TargetInstrDesc &TID); + const MCInstrDesc &MCID); ~MachineInstr(); @@ -181,13 +181,22 @@ public: /// DebugLoc getDebugLoc() const { return debugLoc; } + /// emitError - Emit an error referring to the source location of this + /// instruction. This should only be used for inline assembly that is somehow + /// impossible to compile. Other errors should have been handled much + /// earlier. + /// + /// If this method returns, the caller should try to recover from the error. + /// + void emitError(StringRef Msg) const; + /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. - const TargetInstrDesc &getDesc() const { return *TID; } + const MCInstrDesc &getDesc() const { return *MCID; } /// getOpcode - Returns the opcode of this MachineInstr. /// - int getOpcode() const { return TID->Opcode; } + int getOpcode() const { return MCID->Opcode; } /// Access to explicit operands of the instruction. /// @@ -279,6 +288,9 @@ public: bool isCopy() const { return getOpcode() == TargetOpcode::COPY; } + bool isFullCopy() const { + return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg(); + } /// isCopyLike - Return true if the instruction behaves like a copy. /// This does not include native copy instructions. @@ -464,8 +476,8 @@ public: /// hasUnmodeledSideEffects - Return true if this instruction has side /// effects that are not modeled by mayLoad / mayStore, etc. - /// For all instructions, the property is encoded in TargetInstrDesc::Flags - /// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is + /// For all instructions, the property is encoded in MCInstrDesc::Flags + /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is /// INLINEASM instruction, in which case the side effect property is encoded /// in one of its operands (see InlineAsm::Extra_HasSideEffect). /// @@ -497,7 +509,7 @@ public: /// setDesc - Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. /// - void setDesc(const TargetInstrDesc &tid) { TID = &tid; } + void setDesc(const MCInstrDesc &tid) { MCID = &tid; } /// setDebugLoc - Replace current source information with new such. /// Avoid using this, the constructor argument is preferable. diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index c8183a3..b989027 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -22,7 +22,7 @@ namespace llvm { -class TargetInstrDesc; +class MCInstrDesc; class MDNode; namespace RegState { @@ -77,6 +77,11 @@ public: return *this; } + const MachineInstrBuilder &addCImm(const ConstantInt *Val) const { + MI->addOperand(MachineOperand::CreateCImm(Val)); + return *this; + } + const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const { MI->addOperand(MachineOperand::CreateFPImm(Val)); return *this; @@ -175,8 +180,8 @@ public: /// inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, - const TargetInstrDesc &TID) { - return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)); + const MCInstrDesc &MCID) { + return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)); } /// BuildMI - This version of the builder sets up the first operand as a @@ -184,9 +189,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, /// inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, - const TargetInstrDesc &TID, + const MCInstrDesc &MCID, unsigned DestReg) { - return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)) + return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)) .addReg(DestReg, RegState::Define); } @@ -197,9 +202,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, - const TargetInstrDesc &TID, + const MCInstrDesc &MCID, unsigned DestReg) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); + MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); BB.insert(I, MI); return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); } @@ -211,8 +216,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, - const TargetInstrDesc &TID) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); + const MCInstrDesc &MCID) { + MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); BB.insert(I, MI); return MachineInstrBuilder(MI); } @@ -223,8 +228,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, /// inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, DebugLoc DL, - const TargetInstrDesc &TID) { - return BuildMI(*BB, BB->end(), DL, TID); + const MCInstrDesc &MCID) { + return BuildMI(*BB, BB->end(), DL, MCID); } /// BuildMI - This version of the builder inserts the newly-built @@ -233,9 +238,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, /// inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, DebugLoc DL, - const TargetInstrDesc &TID, + const MCInstrDesc &MCID, unsigned DestReg) { - return BuildMI(*BB, BB->end(), DL, TID, DestReg); + return BuildMI(*BB, BB->end(), DL, MCID, DestReg); } inline unsigned getDefRegState(bool B) { diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 140c6e8..fdef574 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -21,6 +21,7 @@ namespace llvm { class BlockAddress; class ConstantFP; +class ConstantInt; class GlobalValue; class MachineBasicBlock; class MachineInstr; @@ -38,6 +39,7 @@ public: enum MachineOperandType { MO_Register, ///< Register operand. MO_Immediate, ///< Immediate operand + MO_CImmediate, ///< Immediate >64bit operand MO_FPImmediate, ///< Floating-point immediate operand MO_MachineBasicBlock, ///< MachineBasicBlock reference MO_FrameIndex, ///< Abstract Stack Frame Index @@ -111,6 +113,7 @@ private: union { MachineBasicBlock *MBB; // For MO_MachineBasicBlock. const ConstantFP *CFP; // For MO_FPImmediate. + const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit. int64_t ImmVal; // For MO_Immediate. const MDNode *MD; // For MO_Metadata. MCSymbol *Sym; // For MO_MCSymbol @@ -173,6 +176,8 @@ public: bool isReg() const { return OpKind == MO_Register; } /// isImm - Tests if this is a MO_Immediate operand. bool isImm() const { return OpKind == MO_Immediate; } + /// isCImm - Test if t his is a MO_CImmediate operand. + bool isCImm() const { return OpKind == MO_CImmediate; } /// isFPImm - Tests if this is a MO_FPImmediate operand. bool isFPImm() const { return OpKind == MO_FPImmediate; } /// isMBB - Tests if this is a MO_MachineBasicBlock operand. @@ -333,6 +338,11 @@ public: return Contents.ImmVal; } + const ConstantInt *getCImm() const { + assert(isCImm() && "Wrong MachineOperand accessor"); + return Contents.CI; + } + const ConstantFP *getFPImm() const { assert(isFPImm() && "Wrong MachineOperand accessor"); return Contents.CFP; @@ -440,6 +450,12 @@ public: return Op; } + static MachineOperand CreateCImm(const ConstantInt *CI) { + MachineOperand Op(MachineOperand::MO_CImmediate); + Op.Contents.CI = CI; + return Op; + } + static MachineOperand CreateFPImm(const ConstantFP *CFP) { MachineOperand Op(MachineOperand::MO_FPImmediate); Op.Contents.CFP = CFP; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 74df8da..1079726 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -32,11 +32,6 @@ class MachineRegisterInfo { IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>, VirtReg2IndexFunctor> VRegInfo; - /// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to - /// virtual registers. For each target register class, it keeps a list of - /// virtual registers belonging to the class. - std::vector<unsigned> *RegClass2VRegMap; - /// RegAllocHints - This vector records register allocation hints for virtual /// registers. For each virtual register, it keeps a register and hint type /// pair making up the allocation hint. Hint type is target specific except @@ -216,13 +211,6 @@ public: /// unsigned getNumVirtRegs() const { return VRegInfo.size(); } - /// getRegClassVirtRegs - Return the list of virtual registers of the given - /// target register class. - const std::vector<unsigned> & - getRegClassVirtRegs(const TargetRegisterClass *RC) const { - return RegClass2VRegMap[RC->getID()]; - } - /// setRegAllocationHint - Specify a register allocation hint for the /// specified virtual register. void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) { @@ -237,6 +225,14 @@ public: return RegAllocHints[Reg]; } + /// getSimpleHint - Return the preferred register allocation hint, or 0 if a + /// standard simple hint (Type == 0) is not set. + unsigned getSimpleHint(unsigned Reg) const { + std::pair<unsigned, unsigned> Hint = getRegAllocationHint(Reg); + return Hint.first ? 0 : Hint.second; + } + + //===--------------------------------------------------------------------===// // Physical Register Use Info //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 53aee7a..e7928cb 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -73,16 +73,9 @@ namespace llvm { /// This pass is still in development extern char &StrongPHIEliminationID; - extern char &PreAllocSplittingID; - /// LiveStacks pass. An analysis keeping track of the liveness of stack slots. extern char &LiveStacksID; - /// SimpleRegisterCoalescing pass. Aggressively coalesces every register - /// copy it can. - /// - extern char &SimpleRegisterCoalescingID; - /// TwoAddressInstruction pass - This pass reduces two-address instructions to /// use two operands. This destroys SSA information but it is desired by /// register allocators. @@ -132,10 +125,10 @@ namespace llvm { /// FunctionPass *createDefaultPBQPRegisterAllocator(); - /// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run + /// RegisterCoalescer Pass - Coalesce all copies possible. Can run /// independently of the register allocator. /// - RegisterCoalescer *createSimpleRegisterCoalescer(); + RegisterCoalescer *createRegisterCoalescer(); /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index 8139c65..bce3ec7 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -161,7 +161,8 @@ namespace llvm { PBQP::PBQPNum benefit); }; - FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder); + FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder, + char *customPassID=0); } #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h deleted file mode 100644 index af0b394..0000000 --- a/include/llvm/CodeGen/RegisterCoalescer.h +++ /dev/null @@ -1,244 +0,0 @@ -//===-- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the abstract interface for register coalescers, -// allowing them to interact with and query register allocators. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/IncludeFile.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/ADT/SmallPtrSet.h" - -#ifndef LLVM_CODEGEN_REGISTER_COALESCER_H -#define LLVM_CODEGEN_REGISTER_COALESCER_H - -namespace llvm { - - class MachineFunction; - class RegallocQuery; - class AnalysisUsage; - class MachineInstr; - class TargetRegisterInfo; - class TargetRegisterClass; - class TargetInstrInfo; - - /// An abstract interface for register coalescers. Coalescers must - /// implement this interface to be part of the coalescer analysis - /// group. - class RegisterCoalescer { - public: - static char ID; // Class identification, replacement for typeinfo - RegisterCoalescer() {} - virtual ~RegisterCoalescer(); // We want to be subclassed - - /// Run the coalescer on this function, providing interference - /// data to query. Return whether we removed any copies. - virtual bool coalesceFunction(MachineFunction &mf, - RegallocQuery &ifd) = 0; - - /// Reset state. Can be used to allow a coalescer run by - /// PassManager to be run again by the register allocator. - virtual void reset(MachineFunction &mf) {} - - /// Register allocators must call this from their own - /// getAnalysisUsage to cover the case where the coalescer is not - /// a Pass in the proper sense and isn't managed by PassManager. - /// PassManager needs to know which analyses to make available and - /// which to invalidate when running the register allocator or any - /// pass that might call coalescing. The long-term solution is to - /// allow hierarchies of PassManagers. - virtual void getAnalysisUsage(AnalysisUsage &AU) const {} - }; - - /// An abstract interface for register allocators to interact with - /// coalescers - /// - /// Example: - /// - /// This is simply an example of how to use the RegallocQuery - /// interface. It is not meant to be used in production. - /// - /// class LinearScanRegallocQuery : public RegallocQuery { - /// private: - /// const LiveIntervals \&li; - /// - /// public: - /// LinearScanRegallocQuery(LiveIntervals &intervals) - /// : li(intervals) {} - /// - /// /// This is pretty slow and conservative, but since linear scan - /// /// allocation doesn't pre-compute interference information it's - /// /// the best we can do. Coalescers are always free to ignore this - /// /// and implement their own discovery strategy. See - /// /// SimpleRegisterCoalescing for an example. - /// void getInterferences(IntervalSet &interferences, - /// const LiveInterval &a) const { - /// for(LiveIntervals::const_iterator iv = li.begin(), - /// ivend = li.end(); - /// iv != ivend; - /// ++iv) { - /// if (interfere(a, iv->second)) { - /// interferences.insert(&iv->second); - /// } - /// } - /// } - /// - /// /// This is *really* slow and stupid. See above. - /// int getNumberOfInterferences(const LiveInterval &a) const { - /// IntervalSet intervals; - /// getInterferences(intervals, a); - /// return intervals.size(); - /// } - /// }; - /// - /// In the allocator: - /// - /// RegisterCoalescer &coalescer = getAnalysis<RegisterCoalescer>(); - /// - /// // We don't reset the coalescer so if it's already been run this - /// // takes almost no time. - /// LinearScanRegallocQuery ifd(*li_); - /// coalescer.coalesceFunction(fn, ifd); - /// - class RegallocQuery { - public: - typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet; - - virtual ~RegallocQuery() {} - - /// Return whether two live ranges interfere. - virtual bool interfere(const LiveInterval &a, - const LiveInterval &b) const { - // A naive test - return a.overlaps(b); - } - - /// Return the set of intervals that interfere with this one. - virtual void getInterferences(IntervalSet &interferences, - const LiveInterval &a) const = 0; - - /// This can often be cheaper than actually returning the - /// interferences. - virtual int getNumberOfInterferences(const LiveInterval &a) const = 0; - - /// Make any data structure updates necessary to reflect - /// coalescing or other modifications. - virtual void updateDataForMerge(const LiveInterval &a, - const LiveInterval &b, - const MachineInstr ©) {} - - /// Allow the register allocator to communicate when it doesn't - /// want a copy coalesced. This may be due to assumptions made by - /// the allocator about various invariants and so this question is - /// a matter of legality, not performance. Performance decisions - /// about which copies to coalesce should be made by the - /// coalescer. - virtual bool isLegalToCoalesce(const MachineInstr &inst) const { - return true; - } - }; - - - /// CoalescerPair - A helper class for register coalescers. When deciding if - /// two registers can be coalesced, CoalescerPair can determine if a copy - /// instruction would become an identity copy after coalescing. - class CoalescerPair { - const TargetInstrInfo &tii_; - const TargetRegisterInfo &tri_; - - /// dstReg_ - The register that will be left after coalescing. It can be a - /// virtual or physical register. - unsigned dstReg_; - - /// srcReg_ - the virtual register that will be coalesced into dstReg. - unsigned srcReg_; - - /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the - /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a - /// virtual register. - unsigned subIdx_; - - /// partial_ - True when the original copy was a partial subregister copy. - bool partial_; - - /// crossClass_ - True when both regs are virtual, and newRC is constrained. - bool crossClass_; - - /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy - /// instruction. - bool flipped_; - - /// newRC_ - The register class of the coalesced register, or NULL if dstReg_ - /// is a physreg. - const TargetRegisterClass *newRC_; - - /// compose - Compose subreg indices a and b, either may be 0. - unsigned compose(unsigned, unsigned) const; - - /// isMoveInstr - Return true if MI is a move or subreg instruction. - bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst, - unsigned &SrcSub, unsigned &DstSub) const; - - public: - CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri) - : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0), - partial_(false), crossClass_(false), flipped_(false), newRC_(0) {} - - /// setRegisters - set registers to match the copy instruction MI. Return - /// false if MI is not a coalescable copy instruction. - bool setRegisters(const MachineInstr*); - - /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible - /// because dstReg_ is a physical register, or subIdx_ is set. - bool flip(); - - /// isCoalescable - Return true if MI is a copy instruction that will become - /// an identity copy after coalescing. - bool isCoalescable(const MachineInstr*) const; - - /// isPhys - Return true if DstReg is a physical register. - bool isPhys() const { return !newRC_; } - - /// isPartial - Return true if the original copy instruction did not copy the - /// full register, but was a subreg operation. - bool isPartial() const { return partial_; } - - /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's. - bool isCrossClass() const { return crossClass_; } - - /// isFlipped - Return true when getSrcReg is the register being defined by - /// the original copy instruction. - bool isFlipped() const { return flipped_; } - - /// getDstReg - Return the register (virtual or physical) that will remain - /// after coalescing. - unsigned getDstReg() const { return dstReg_; } - - /// getSrcReg - Return the virtual register that will be coalesced away. - unsigned getSrcReg() const { return srcReg_; } - - /// getSubIdx - Return the subregister index in DstReg that SrcReg will be - /// coalesced into, or 0. - unsigned getSubIdx() const { return subIdx_; } - - /// getNewRC - Return the register class of the coalesced register. - const TargetRegisterClass *getNewRC() const { return newRC_; } - }; -} - -// Because of the way .a files work, we must force the SimpleRC -// implementation to be pulled in if the RegisterCoalescing header is -// included. Otherwise we run the risk of RegisterCoalescing being -// used, but the default implementation not being linked into the tool -// that uses it. -FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer) -FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing) - -#endif diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 576be82..4bfd4ab 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -22,7 +22,7 @@ namespace RTLIB { /// RTLIB::Libcall enum - This enum defines all of the runtime library calls /// the backend can emit. The various long double types cannot be merged, /// because 80-bit library functions use "xf" and 128-bit use "tf". - /// + /// /// When adding PPCF128 functions here, note that their names generally need /// to be overridden for Darwin with the xxx$LDBL128 form. See /// PPCISelLowering.cpp. @@ -46,6 +46,9 @@ namespace RTLIB { MUL_I32, MUL_I64, MUL_I128, + MULO_I32, + MULO_I64, + MULO_I128, SDIV_I8, SDIV_I16, SDIV_I32, @@ -100,6 +103,10 @@ namespace RTLIB { REM_F64, REM_F80, REM_PPCF128, + FMA_F32, + FMA_F64, + FMA_F80, + FMA_PPCF128, POWI_F32, POWI_F64, POWI_F80, diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 2f01948..1bbc6c5 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -34,7 +34,7 @@ namespace llvm { class ScheduleDAG; class SDNode; class TargetInstrInfo; - class TargetInstrDesc; + class MCInstrDesc; class TargetMachine; class TargetRegisterClass; template<class Graph> class GraphWriter; @@ -497,13 +497,19 @@ namespace llvm { SUnit EntrySU; // Special node for the region entry. SUnit ExitSU; // Special node for the region exit. +#ifdef NDEBUG + static const bool StressSched = false; +#else + bool StressSched; +#endif + explicit ScheduleDAG(MachineFunction &mf); virtual ~ScheduleDAG(); - /// getInstrDesc - Return the TargetInstrDesc of this SUnit. + /// getInstrDesc - Return the MCInstrDesc of this SUnit. /// Return NULL for SDNodes without a machine opcode. - const TargetInstrDesc *getInstrDesc(const SUnit *SU) const { + const MCInstrDesc *getInstrDesc(const SUnit *SU) const { if (SU->isInstr()) return &SU->getInstr()->getDesc(); return getNodeDesc(SU->getNode()); } @@ -573,8 +579,8 @@ namespace llvm { void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap); private: - // Return the TargetInstrDesc of this SDNode or NULL. - const TargetInstrDesc *getNodeDesc(const SDNode *Node) const; + // Return the MCInstrDesc of this SDNode or NULL. + const MCInstrDesc *getNodeDesc(const SDNode *Node) const; }; class SUnitIterator : public std::iterator<std::forward_iterator_tag, diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 118df28..060e89a 100644 --- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -25,7 +25,6 @@ namespace llvm { class InstrItineraryData; -class TargetInstrDesc; class ScheduleDAG; class SUnit; diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 1c42bef..3ec5ada 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -96,8 +96,12 @@ public: return DbgValues.empty() && ByvalParmDbgValues.empty(); } - SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) { - return DbgValMap[Node]; + ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) { + DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> >::iterator I = + DbgValMap.find(Node); + if (I != DbgValMap.end()) + return I->second; + return ArrayRef<SDDbgValue*>(); } typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator; @@ -898,7 +902,7 @@ public: void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); /// GetDbgValues - Get the debug values which reference the given SDNode. - SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { + ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) { return DbgInfo->getSDDbgValues(SD); } diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 9d265f1..a5c4201 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -23,6 +23,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/ISDOpcodes.h" @@ -496,11 +497,29 @@ public: /// bool isOperandOf(SDNode *N) const; - /// isPredecessorOf - Return true if this node is a predecessor of N. This - /// node is either an operand of N or it can be reached by recursively + /// isPredecessorOf - Return true if this node is a predecessor of N. + /// NOTE: Implemented on top of hasPredecessor and every bit as + /// expensive. Use carefully. + bool isPredecessorOf(const SDNode *N) const { return N->hasPredecessor(this); } + + /// hasPredecessor - Return true if N is a predecessor of this node. + /// N is either an operand of this node, or can be reached by recursively + /// traversing up the operands. + /// NOTE: This is an expensive method. Use it carefully. + bool hasPredecessor(const SDNode *N) const; + + /// hasPredecesorHelper - Return true if N is a predecessor of this node. + /// N is either an operand of this node, or can be reached by recursively /// traversing up the operands. - /// NOTE: this is an expensive method. Use it carefully. - bool isPredecessorOf(SDNode *N) const; + /// In this helper the Visited and worklist sets are held externally to + /// cache predecessors over multiple invocations. If you want to test for + /// multiple predecessors this method is preferable to multiple calls to + /// hasPredecessor. Be sure to clear Visited and Worklist if the DAG + /// changes. + /// NOTE: This is still very expensive. Use carefully. + bool hasPredecessorHelper(const SDNode *N, + SmallPtrSet<const SDNode *, 32> &Visited, + SmallVector<const SDNode *, 16> &Worklist) const; /// getNumOperands - Return the number of values used by this operation. /// diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 33ce675..6eb3180 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -140,6 +140,9 @@ namespace llvm { return lie.getPointer(); } + /// Return true for a valid index. + operator bool() const { return isValid(); } + /// Print this index to the given raw_ostream. void print(raw_ostream &os) const; diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 54e5751..711280e 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -52,7 +52,7 @@ protected: const MCSection *MergeableConst8Section; const MCSection *MergeableConst16Section; public: - TargetLoweringObjectFileELF() {} + TargetLoweringObjectFileELF(); ~TargetLoweringObjectFileELF() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); @@ -131,7 +131,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { const MCSection *LazySymbolPointerSection; const MCSection *NonLazySymbolPointerSection; public: - TargetLoweringObjectFileMachO() {} + TargetLoweringObjectFileMachO(); ~TargetLoweringObjectFileMachO() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); @@ -207,7 +207,7 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { const MCSection *PDataSection; const MCSection *XDataSection; public: - TargetLoweringObjectFileCOFF() {} + TargetLoweringObjectFileCOFF(); ~TargetLoweringObjectFileCOFF() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 22d1622..424721b 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -83,7 +83,11 @@ namespace llvm { isVoid = 35, // This has no value - LAST_VALUETYPE = 36, // This always remains at the end of the list. + untyped = 36, // This value takes a register, but has + // unspecified type. The register class + // will be determined by the opcode. + + LAST_VALUETYPE = 37, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index a1163f7..0cfb634 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -1,10 +1,10 @@ //===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // Value types - These values correspond to the register types defined in the @@ -58,6 +58,7 @@ def v4f64 : ValueType<256, 32>; // 4 x f64 vector value def x86mmx : ValueType<64 , 33>; // X86 MMX value def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue def isVoid : ValueType<0 , 35>; // Produces no value +def untyped: ValueType<8 , 36>; // Produces an untyped value def MetadataVT: ValueType<0, 250>; // Metadata diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 755daa6..0b8a0ad 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -557,6 +557,9 @@ /* LLVM name for the native TargetInfo init function, if available */ #cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo +/* LLVM name for the native MCAsmInfo init function, if available */ +#cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo + /* Define if this is Unixish platform */ #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} @@ -686,9 +689,6 @@ `char[]'. */ #undef YYTEXT_POINTER -/* Define to a type to use for `mode_t' if it is not otherwise available. */ -#cmakedefine mode_t ${mode_t} - /* Define to a function replacing strtoll */ #cmakedefine strtoll ${strtoll} diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 10a8935..0a716ea 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -573,6 +573,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER +/* LLVM name for the native MCAsmInfo init function, if available */ +#undef LLVM_NATIVE_MCASMINFO + /* LLVM name for the native Target init function, if available */ #undef LLVM_NATIVE_TARGET diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index ee81f7a..5f948a2 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -58,6 +58,9 @@ /* LLVM name for the native TargetInfo init function, if available */ #cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo +/* LLVM name for the native MCAsmInfo init function, if available */ +#cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo + /* LLVM name for the native AsmPrinter init function, if available */ #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in index 4766a7a..bc8ddce 100644 --- a/include/llvm/Config/llvm-config.h.in +++ b/include/llvm/Config/llvm-config.h.in @@ -58,6 +58,9 @@ /* LLVM name for the native TargetInfo init function, if available */ #undef LLVM_NATIVE_TARGETINFO +/* LLVM name for the native MCAsmInfo init function, if available */ +#undef LLVM_NATIVE_MCASMINFO + /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 5f32ce0..5e351c4 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -50,11 +50,11 @@ protected: public: /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. - virtual bool isNullValue() const = 0; + bool isNullValue() const; /// isNegativeZeroValue - Return true if the value is what would be returned /// by getZeroValueForNegation. - virtual bool isNegativeZeroValue() const { return isNullValue(); } + bool isNegativeZeroValue() const; /// canTrap - Return true if evaluation of this constant could trap. This is /// true for things like constant expressions that could divide by zero. diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index eabc3a5..01fca29 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -149,13 +149,7 @@ public: static bool isValueValidForType(const Type *Ty, uint64_t V); static bool isValueValidForType(const Type *Ty, int64_t V); - /// This function will return true iff this constant represents the "null" - /// value that would be returned by the getNullValue method. - /// @returns true if this is the null integer value. - /// @brief Determine if the value is null. - virtual bool isNullValue() const { - return Val == 0; - } + bool isNegative() const { return Val.isNegative(); } /// This is just a convenience method to make client code smaller for a /// common code. It also correctly performs the comparison without the @@ -263,22 +257,14 @@ public: /// isValueValidForType - return true if Ty is big enough to represent V. static bool isValueValidForType(const Type *Ty, const APFloat &V); - inline const APFloat& getValueAPF() const { return Val; } - - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. For ConstantFP, this is +0.0, but not -0.0. To handle the - /// two the same, use isZero(). - virtual bool isNullValue() const; - - /// isNegativeZeroValue - Return true if the value is what would be returned - /// by getZeroValueForNegation. - virtual bool isNegativeZeroValue() const { - return Val.isZero() && Val.isNegative(); - } + inline const APFloat &getValueAPF() const { return Val; } /// isZero - Return true if the value is positive or negative zero. bool isZero() const { return Val.isZero(); } + /// isNegative - Return true if the sign bit is set. + bool isNegative() const { return Val.isNegative(); } + /// isNaN - Return true if the value is a NaN. bool isNaN() const { return Val.isNaN(); } @@ -324,10 +310,6 @@ protected: public: static ConstantAggregateZero* get(const Type *Ty); - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { return true; } - virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -350,9 +332,7 @@ protected: ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val); public: // ConstantArray accessors - static Constant *get(const ArrayType *T, const std::vector<Constant*> &V); - static Constant *get(const ArrayType *T, Constant *const *Vals, - unsigned NumVals); + static Constant *get(const ArrayType *T, ArrayRef<Constant*> V); /// This method constructs a ConstantArray and initializes it with a text /// string. The default behavior (AddNull==true) causes a null terminator to @@ -389,10 +369,11 @@ public: /// std::string getAsString() const; - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. This always returns false because zero arrays are always - /// created as ConstantAggregateZero objects. - virtual bool isNullValue() const { return false; } + /// getAsCString - If this array is isCString(), then this method converts the + /// array (without the trailing null byte) to an std::string and returns it. + /// Otherwise, it asserts out. + /// + std::string getAsCString() const; virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -422,14 +403,29 @@ protected: ConstantStruct(const StructType *T, const std::vector<Constant*> &Val); public: // ConstantStruct accessors - static Constant *get(const StructType *T, const std::vector<Constant*> &V); - static Constant *get(LLVMContext &Context, - const std::vector<Constant*> &V, bool Packed); - static Constant *get(LLVMContext &Context, - Constant *const *Vals, unsigned NumVals, bool Packed); - static Constant *get(LLVMContext &Context, bool Packed, - Constant * Val, ...) END_WITH_NULL; - + static Constant *get(const StructType *T, ArrayRef<Constant*> V); + static Constant *get(const StructType *T, ...) END_WITH_NULL; + + /// getAnon - Return an anonymous struct that has the specified + /// elements. If the struct is possibly empty, then you must specify a + /// context. + static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) { + return get(getTypeForElements(V, Packed), V); + } + static Constant *getAnon(LLVMContext &Ctx, + ArrayRef<Constant*> V, bool Packed = false) { + return get(getTypeForElements(Ctx, V, Packed), V); + } + + /// getTypeForElements - Return an anonymous struct type to use for a constant + /// with the specified set of elements. The list must not be empty. + static StructType *getTypeForElements(ArrayRef<Constant*> V, + bool Packed = false); + /// getTypeForElements - This version of the method allows an empty list. + static StructType *getTypeForElements(LLVMContext &Ctx, + ArrayRef<Constant*> V, + bool Packed = false); + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -439,13 +435,6 @@ public: return reinterpret_cast<const StructType*>(Value::getType()); } - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. This always returns false because zero structs are always - /// created as ConstantAggregateZero objects. - virtual bool isNullValue() const { - return false; - } - virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -476,8 +465,6 @@ protected: public: // ConstantVector accessors static Constant *get(ArrayRef<Constant*> V); - // FIXME: Eliminate this constructor form. - static Constant *get(const VectorType *T, const std::vector<Constant*> &V); /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -489,11 +476,6 @@ public: return reinterpret_cast<const VectorType*>(Value::getType()); } - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. This always returns false because zero vectors are always - /// created as ConstantAggregateZero objects. - virtual bool isNullValue() const { return false; } - /// This function will return true iff every element in this vector constant /// is set to all ones. /// @returns true iff this constant's emements are all set to all ones. @@ -542,10 +524,6 @@ public: /// get() - Static factory methods - Return objects of the specified value static ConstantPointerNull *get(const PointerType *T); - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { return true; } - virtual void destroyConstant(); /// getType - Specialize the getType() method to always return an PointerType, @@ -582,10 +560,6 @@ public: Function *getFunction() const { return (Function*)Op<0>().get(); } BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { return false; } - virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -623,35 +597,6 @@ protected: setValueSubclassData(Opcode); } - // These private methods are used by the type resolution code to create - // ConstantExprs in intermediate forms. - static Constant *getTy(const Type *Ty, unsigned Opcode, - Constant *C1, Constant *C2, - unsigned Flags = 0); - static Constant *getCompareTy(unsigned short pred, Constant *C1, - Constant *C2); - static Constant *getSelectTy(const Type *Ty, - Constant *C1, Constant *C2, Constant *C3); - template<typename IndexTy> - static Constant *getGetElementPtrTy(const Type *Ty, Constant *C, - IndexTy const *Idxs, unsigned NumIdxs, - bool InBounds); - static Constant *getExtractElementTy(const Type *Ty, Constant *Val, - Constant *Idx); - static Constant *getInsertElementTy(const Type *Ty, Constant *Val, - Constant *Elt, Constant *Idx); - static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1, - Constant *V2, Constant *Mask); - static Constant *getExtractValueTy(const Type *Ty, Constant *Agg, - const unsigned *Idxs, unsigned NumIdxs); - static Constant *getInsertValueTy(const Type *Ty, Constant *Agg, - Constant *Val, - const unsigned *Idxs, unsigned NumIdxs); - template<typename IndexTy> - static Constant *getGetElementPtrImpl(Constant *C, - IndexTy const *IdxList, - unsigned NumIdx, bool InBounds); - public: // Static methods to construct a ConstantExpr of different kinds. Note that // these methods may return a object that is not an instance of the @@ -822,9 +767,7 @@ public: /// Select constant expr /// - static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) { - return getSelectTy(V1->getType(), C, V1, V2); - } + static Constant *getSelect(Constant *C, Constant *V1, Constant *V2); /// get - Return a binary or shift operator constant expression, /// folding if possible. @@ -846,7 +789,9 @@ public: /// static Constant *getGetElementPtr(Constant *C, Constant *const *IdxList, unsigned NumIdx, - bool InBounds = false); + bool InBounds = false) { + return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds); + } static Constant *getGetElementPtr(Constant *C, Value *const *IdxList, unsigned NumIdx, bool InBounds = false); @@ -867,14 +812,9 @@ public: static Constant *getExtractElement(Constant *Vec, Constant *Idx); static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx); static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask); - static Constant *getExtractValue(Constant *Agg, - const unsigned *IdxList, unsigned NumIdx); + static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs); static Constant *getInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx); - - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { return false; } + ArrayRef<unsigned> Idxs); /// getOpcode - Return the opcode at the root of this constant expression unsigned getOpcode() const { return getSubclassDataFromValue(); } @@ -895,10 +835,18 @@ public: Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const; /// getWithOperands - This returns the current constant expression with the - /// operands replaced with the specified values. The specified operands must - /// match count and type with the existing ones. - Constant *getWithOperands(ArrayRef<Constant*> Ops) const; - + /// operands replaced with the specified values. The specified array must + /// have the same number of operands as our current one. + Constant *getWithOperands(ArrayRef<Constant*> Ops) const { + return getWithOperands(Ops, getType()); + } + + /// getWithOperands - This returns the current constant expression with the + /// operands replaced with the specified values and with the specified result + /// type. The specified array must have the same number of operands as our + /// current one. + Constant *getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const; + virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -950,10 +898,6 @@ public: /// static UndefValue *get(const Type *T); - /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { return false; } - virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/include/llvm/DefaultPasses.h b/include/llvm/DefaultPasses.h index e2e58a5b..2e4145b 100644 --- a/include/llvm/DefaultPasses.h +++ b/include/llvm/DefaultPasses.h @@ -29,7 +29,6 @@ extern unsigned char ConstantMergeID; extern unsigned char CorrelatedValuePropagationID; extern unsigned char DeadArgEliminationID; extern unsigned char DeadStoreEliminationID; -extern unsigned char DeadTypeEliminationID; extern unsigned char EarlyCSEID; extern unsigned char FunctionAttrsID; extern unsigned char FunctionInliningID; diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index f1cb330..acb28de 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -19,76 +19,27 @@ #define LLVM_DERIVED_TYPES_H #include "llvm/Type.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" namespace llvm { class Value; -template<class ValType, class TypeClass> class TypeMap; -class FunctionValType; -class ArrayValType; -class StructValType; -class PointerValType; -class VectorValType; -class IntegerValType; class APInt; class LLVMContext; - -class DerivedType : public Type { - friend class Type; - -protected: - explicit DerivedType(LLVMContext &C, TypeID id) : Type(C, id) {} - - /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type - /// that the current type has transitioned from being abstract to being - /// concrete. - /// - void notifyUsesThatTypeBecameConcrete(); - - /// dropAllTypeUses - When this (abstract) type is resolved to be equal to - /// another (more concrete) type, we must eliminate all references to other - /// types, to avoid some circular reference problems. - /// - void dropAllTypeUses(); - -public: - - //===--------------------------------------------------------------------===// - // Abstract Type handling methods - These types have special lifetimes, which - // are managed by (add|remove)AbstractTypeUser. See comments in - // AbstractTypeUser.h for more information. - - /// refineAbstractTypeTo - This function is used to when it is discovered that - /// the 'this' abstract type is actually equivalent to the NewType specified. - /// This causes all users of 'this' to switch to reference the more concrete - /// type NewType and for 'this' to be deleted. - /// - void refineAbstractTypeTo(const Type *NewType); - - void dump() const { Type::dump(); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DerivedType *) { return true; } - static inline bool classof(const Type *T) { - return T->isDerivedType(); - } -}; +template<typename T> class ArrayRef; +class StringRef; /// Class to represent integer types. Note that this class is also used to /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and /// Int64Ty. /// @brief Integer representation type -class IntegerType : public DerivedType { +class IntegerType : public Type { friend class LLVMContextImpl; protected: - explicit IntegerType(LLVMContext &C, unsigned NumBits) : - DerivedType(C, IntegerTyID) { + explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){ setSubclassData(NumBits); } - friend class TypeMap<IntegerValType, IntegerType>; public: /// This enum is just used to hold constants we need for IntegerType. enum { @@ -103,7 +54,7 @@ public: /// that instance will be returned. Otherwise a new one will be created. Only /// one instance with a given NumBits value is ever created. /// @brief Get or create an IntegerType instance. - static const IntegerType* get(LLVMContext &C, unsigned NumBits); + static IntegerType *get(LLVMContext &C, unsigned NumBits); /// @brief Get the number of bits in this IntegerType unsigned getBitWidth() const { return getSubclassData(); } @@ -132,7 +83,7 @@ public: /// @brief Is this a power-of-2 byte-width IntegerType ? bool isPowerOf2ByteWidth() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const IntegerType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == IntegerTyID; @@ -142,34 +93,22 @@ public: /// FunctionType - Class to represent function types /// -class FunctionType : public DerivedType { - friend class TypeMap<FunctionValType, FunctionType>; - bool isVarArgs; - +class FunctionType : public Type { FunctionType(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement - FunctionType(const Type *Result, ArrayRef<const Type*> Params, - bool IsVarArgs); + FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs); public: /// FunctionType::get - This static method is the primary way of constructing /// a FunctionType. /// - static FunctionType *get( - const Type *Result, ///< The result type - ArrayRef<const Type*> Params, ///< The types of the parameters - bool isVarArg ///< Whether this is a variable argument length function - ); + static FunctionType *get(const Type *Result, + ArrayRef<Type*> Params, bool isVarArg); /// FunctionType::get - Create a FunctionType taking no parameters. /// - static FunctionType *get( - const Type *Result, ///< The result type - bool isVarArg ///< Whether this is a variable argument length function - ) { - return get(Result, ArrayRef<const Type *>(), isVarArg); - } - + static FunctionType *get(const Type *Result, bool isVarArg); + /// isValidReturnType - Return true if the specified type is valid as a return /// type. static bool isValidReturnType(const Type *RetTy); @@ -178,26 +117,22 @@ public: /// argument type. static bool isValidArgumentType(const Type *ArgTy); - inline bool isVarArg() const { return isVarArgs; } - inline const Type *getReturnType() const { return ContainedTys[0]; } + bool isVarArg() const { return getSubclassData(); } + Type *getReturnType() const { return ContainedTys[0]; } typedef Type::subtype_iterator param_iterator; param_iterator param_begin() const { return ContainedTys + 1; } param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } - // Parameter type accessors... - const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } + // Parameter type accessors. + Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } /// getNumParams - Return the number of fixed parameters this function type /// requires. This does not consider varargs. /// unsigned getNumParams() const { return NumContainedTys - 1; } - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const FunctionType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == FunctionTyID; @@ -206,22 +141,21 @@ public: /// CompositeType - Common super class of ArrayType, StructType, PointerType -/// and VectorType -class CompositeType : public DerivedType { +/// and VectorType. +class CompositeType : public Type { protected: - inline explicit CompositeType(LLVMContext &C, TypeID id) : - DerivedType(C, id) { } + explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { } public: /// getTypeAtIndex - Given an index value into the type, return the type of /// the element. /// - virtual const Type *getTypeAtIndex(const Value *V) const = 0; - virtual const Type *getTypeAtIndex(unsigned Idx) const = 0; - virtual bool indexValid(const Value *V) const = 0; - virtual bool indexValid(unsigned Idx) const = 0; + Type *getTypeAtIndex(const Value *V) const; + Type *getTypeAtIndex(unsigned Idx) const; + bool indexValid(const Value *V) const; + bool indexValid(unsigned Idx) const; - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const CompositeType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || @@ -232,69 +166,114 @@ public: }; -/// StructType - Class to represent struct types +/// StructType - Class to represent struct types, both normal and packed. +/// Besides being optionally packed, structs can be either "anonymous" or may +/// have an identity. Anonymous structs are uniqued by structural equivalence, +/// but types are each unique when created, and optionally have a name. /// class StructType : public CompositeType { - friend class TypeMap<StructValType, StructType>; StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - StructType(LLVMContext &C, ArrayRef<const Type*> Types, bool isPacked); + StructType(LLVMContext &C) + : CompositeType(C, StructTyID), SymbolTableEntry(0) {} + enum { + // This is the contents of the SubClassData field. + SCDB_HasBody = 1, + SCDB_Packed = 2, + SCDB_IsAnonymous = 4 + }; + + /// SymbolTableEntry - For a named struct that actually has a name, this is a + /// pointer to the symbol table entry (maintained by LLVMContext) for the + /// struct. This is null if the type is an anonymous struct or if it is + /// a named type that has an empty name. + /// + void *SymbolTableEntry; public: + ~StructType() { + delete [] ContainedTys; // Delete the body. + } + + /// StructType::createNamed - This creates a named struct with no body + /// specified. If the name is empty, it creates an unnamed struct, which has + /// a unique identity but no actual name. + static StructType *createNamed(LLVMContext &Context, StringRef Name); + + static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements, + bool isPacked = false); + static StructType *createNamed(LLVMContext &Context, StringRef Name, + ArrayRef<Type*> Elements, + bool isPacked = false); + static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL; + /// StructType::get - This static method is the primary way to create a /// StructType. - /// - static StructType *get(LLVMContext &Context, - ArrayRef<const Type*> Params, - bool isPacked=false); + static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements, + bool isPacked = false); /// StructType::get - Create an empty structure type. /// - static StructType *get(LLVMContext &Context, bool isPacked=false) { - return get(Context, llvm::ArrayRef<const Type*>(), isPacked); - } + static StructType *get(LLVMContext &Context, bool isPacked = false); + + /// StructType::get - This static method is a convenience method for creating + /// structure types by specifying the elements as arguments. Note that this + /// method always returns a non-packed struct, and requires at least one + /// element type. + static StructType *get(Type *elt1, ...) END_WITH_NULL; - /// StructType::get - This static method is a convenience method for - /// creating structure types by specifying the elements as arguments. - /// Note that this method always returns a non-packed struct. To get - /// an empty struct, pass NULL, NULL. - static StructType *get(LLVMContext &Context, - const Type *type, ...) END_WITH_NULL; + bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } + + /// isAnonymous - Return true if this type is uniqued by structural + /// equivalence, false if it has an identity. + bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;} + + /// isOpaque - Return true if this is a type with an identity that has no body + /// specified yet. These prints as 'opaque' in .ll files. + bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; } + + /// hasName - Return true if this is a named struct that has a non-empty name. + bool hasName() const { return SymbolTableEntry != 0; } + + /// getName - Return the name for this struct type if it has an identity. + /// This may return an empty string for an unnamed struct type. Do not call + /// this on an anonymous type. + StringRef getName() const; + + /// setName - Change the name of this type to the specified name, or to a name + /// with a suffix if there is a collision. Do not call this on an anonymous + /// type. + void setName(StringRef Name); + /// setBody - Specify a body for an opaque type. + void setBody(ArrayRef<Type*> Elements, bool isPacked = false); + void setBody(Type *elt1, ...) END_WITH_NULL; + /// isValidElementType - Return true if the specified type is valid as a /// element type. static bool isValidElementType(const Type *ElemTy); + - // Iterator access to the elements + // Iterator access to the elements. typedef Type::subtype_iterator element_iterator; element_iterator element_begin() const { return ContainedTys; } element_iterator element_end() const { return &ContainedTys[NumContainedTys];} + /// isLayoutIdentical - Return true if this is layout identical to the + /// specified struct. + bool isLayoutIdentical(const StructType *Other) const; + // Random access to the elements unsigned getNumElements() const { return NumContainedTys; } - const Type *getElementType(unsigned N) const { + Type *getElementType(unsigned N) const { assert(N < NumContainedTys && "Element number out of range!"); return ContainedTys[N]; } - /// getTypeAtIndex - Given an index value into the type, return the type of - /// the element. For a structure type, this must be a constant value... - /// - virtual const Type *getTypeAtIndex(const Value *V) const; - virtual const Type *getTypeAtIndex(unsigned Idx) const; - virtual bool indexValid(const Value *V) const; - virtual bool indexValid(unsigned Idx) const; - - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const StructType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == StructTyID; } - - bool isPacked() const { return (0 != getSubclassData()) ? true : false; } }; /// SequentialType - This is the superclass of the array, pointer and vector @@ -306,38 +285,21 @@ public: /// components out in memory identically. /// class SequentialType : public CompositeType { - PATypeHandle ContainedType; ///< Storage for the single contained type + Type *ContainedType; ///< Storage for the single contained type. SequentialType(const SequentialType &); // Do not implement! const SequentialType &operator=(const SequentialType &); // Do not implement! - // avoiding warning: 'this' : used in base member initializer list - SequentialType* this_() { return this; } protected: - SequentialType(TypeID TID, const Type *ElType) - : CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) { + SequentialType(TypeID TID, Type *ElType) + : CompositeType(ElType->getContext(), TID), ContainedType(ElType) { ContainedTys = &ContainedType; NumContainedTys = 1; } public: - inline const Type *getElementType() const { return ContainedTys[0]; } - - virtual bool indexValid(const Value *V) const; - virtual bool indexValid(unsigned) const { - return true; - } - - /// getTypeAtIndex - Given an index value into the type, return the type of - /// the element. For sequential types, there is only one subtype... - /// - virtual const Type *getTypeAtIndex(const Value *) const { - return ContainedTys[0]; - } - virtual const Type *getTypeAtIndex(unsigned) const { - return ContainedTys[0]; - } + Type *getElementType() const { return ContainedTys[0]; } - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const SequentialType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || @@ -347,15 +309,14 @@ public: }; -/// ArrayType - Class to represent array types +/// ArrayType - Class to represent array types. /// class ArrayType : public SequentialType { - friend class TypeMap<ArrayValType, ArrayType>; uint64_t NumElements; ArrayType(const ArrayType &); // Do not implement const ArrayType &operator=(const ArrayType &); // Do not implement - ArrayType(const Type *ElType, uint64_t NumEl); + ArrayType(Type *ElType, uint64_t NumEl); public: /// ArrayType::get - This static method is the primary way to construct an /// ArrayType @@ -366,31 +327,26 @@ public: /// element type. static bool isValidElementType(const Type *ElemTy); - inline uint64_t getNumElements() const { return NumElements; } + uint64_t getNumElements() const { return NumElements; } - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const ArrayType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID; } }; -/// VectorType - Class to represent vector types +/// VectorType - Class to represent vector types. /// class VectorType : public SequentialType { - friend class TypeMap<VectorValType, VectorType>; unsigned NumElements; VectorType(const VectorType &); // Do not implement const VectorType &operator=(const VectorType &); // Do not implement - VectorType(const Type *ElType, unsigned NumEl); + VectorType(Type *ElType, unsigned NumEl); public: /// VectorType::get - This static method is the primary way to construct an - /// VectorType + /// VectorType. /// static VectorType *get(const Type *ElementType, unsigned NumElements); @@ -400,7 +356,7 @@ public: /// static VectorType *getInteger(const VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -410,7 +366,7 @@ public: /// static VectorType *getExtendedElementVectorType(const VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -422,7 +378,7 @@ public: unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); assert((EltBits & 1) == 0 && "Cannot truncate vector element with odd bit-width"); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -431,18 +387,14 @@ public: static bool isValidElementType(const Type *ElemTy); /// @brief Return the number of elements in the Vector type. - inline unsigned getNumElements() const { return NumElements; } + unsigned getNumElements() const { return NumElements; } /// @brief Return the number of bits in the Vector type. - inline unsigned getBitWidth() const { + unsigned getBitWidth() const { return NumElements * getElementType()->getPrimitiveSizeInBits(); } - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - - // Methods for support type inquiry through isa, cast, and dyn_cast: + // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const VectorType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == VectorTyID; @@ -450,15 +402,12 @@ public: }; -/// PointerType - Class to represent pointers +/// PointerType - Class to represent pointers. /// class PointerType : public SequentialType { - friend class TypeMap<PointerValType, PointerType>; - unsigned AddressSpace; - PointerType(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement - explicit PointerType(const Type *ElType, unsigned AddrSpace); + explicit PointerType(Type *ElType, unsigned AddrSpace); public: /// PointerType::get - This constructs a pointer to an object of the specified /// type in a numbered address space. @@ -475,39 +424,15 @@ public: static bool isValidElementType(const Type *ElemTy); /// @brief Return the address space of the Pointer type. - inline unsigned getAddressSpace() const { return AddressSpace; } - - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); + inline unsigned getAddressSpace() const { return getSubclassData(); } - // Implement support type inquiry through isa, cast, and dyn_cast: + // Implement support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const PointerType *) { return true; } static inline bool classof(const Type *T) { return T->getTypeID() == PointerTyID; } }; - -/// OpaqueType - Class to represent abstract types -/// -class OpaqueType : public DerivedType { - friend class LLVMContextImpl; - OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT - const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT - OpaqueType(LLVMContext &C); -public: - /// OpaqueType::get - Static factory method for the OpaqueType class... - /// - static OpaqueType *get(LLVMContext &C); - - // Implement support for type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const OpaqueType *) { return true; } - static inline bool classof(const Type *T) { - return T->getTypeID() == OpaqueTyID; - } -}; - } // End llvm namespace #endif diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 3dc65e3..724b9f0 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -53,6 +53,7 @@ class RuntimeDyld { // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // interface. RuntimeDyldImpl *Dyld; + RTDyldMemoryManager *MM; public: RuntimeDyld(RTDyldMemoryManager*); ~RuntimeDyld(); diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 1edc176..0aa5b2a 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -128,8 +128,8 @@ public: ~Function(); - const Type *getReturnType() const; // Return the type of the ret val - const FunctionType *getFunctionType() const; // Return the FunctionType for me + Type *getReturnType() const; // Return the type of the ret val + FunctionType *getFunctionType() const; // Return the FunctionType for me /// getContext - Return a pointer to the LLVMContext associated with this /// function, or NULL if this function is not bound to a context yet. @@ -139,12 +139,6 @@ public: /// arguments. bool isVarArg() const; - /// isDeclaration - Is the body of this function unknown? (The basic block - /// list is empty if so.) This is true for function declarations, but not - /// true for function definitions. - /// - virtual bool isDeclaration() const { return BasicBlocks.empty(); } - /// getIntrinsicID - This method returns the ID number of the specified /// function, or Intrinsic::not_intrinsic if the function is not an /// instrinsic, or if the pointer is null. This value is always defined to be diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index f4af5b1..c3d3c38 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -47,11 +47,6 @@ public: /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// isDeclaration - Is this global variable lacking an initializer? If so, - /// the global variable is defined in some other translation unit, and is thus - /// only a declaration here. - virtual bool isDeclaration() const; - /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// @@ -63,23 +58,23 @@ public: virtual void eraseFromParent(); /// set/getAliasee - These methods retrive and set alias target. - void setAliasee(Constant* GV); - const Constant* getAliasee() const { + void setAliasee(Constant *GV); + const Constant *getAliasee() const { return cast_or_null<Constant>(getOperand(0)); } - Constant* getAliasee() { + Constant *getAliasee() { return cast_or_null<Constant>(getOperand(0)); } /// getAliasedGlobal() - Aliasee can be either global or bitcast of /// global. This method retrives the global for both aliasee flavours. - const GlobalValue* getAliasedGlobal() const; + const GlobalValue *getAliasedGlobal() const; /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias /// by going through the aliasing chain and trying to find the very last /// global. Returns NULL if a cycle was found. If stopOnWeak is false, then /// the whole chain aliasing chain is traversed, otherwise - only strong /// aliases. - const GlobalValue* resolveAliasedGlobal(bool stopOnWeak = true) const; + const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GlobalAlias *) { return true; } diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index b184b8e..d0f0888 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -106,8 +106,8 @@ public: bool use_empty_except_constants(); /// getType - Global values are always pointers. - inline const PointerType *getType() const { - return reinterpret_cast<const PointerType*>(User::getType()); + inline PointerType *getType() const { + return reinterpret_cast<PointerType*>(User::getType()); } static LinkageTypes getLinkOnceLinkage(bool ODR) { @@ -258,16 +258,12 @@ public: /// @} - /// Override from Constant class. No GlobalValue's are null values so this - /// always returns false. - virtual bool isNullValue() const { return false; } - /// Override from Constant class. virtual void destroyConstant(); /// isDeclaration - Return true if the primary definition of this global - /// value is outside of the current translation unit... - virtual bool isDeclaration() const = 0; + /// value is outside of the current translation unit. + bool isDeclaration() const; /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 442e0c0..bbc09c1 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -68,11 +68,6 @@ public: /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// isDeclaration - Is this global variable lacking an initializer? If so, - /// the global variable is defined in some other translation unit, and is thus - /// only a declaration here. - virtual bool isDeclaration() const { return getNumOperands() == 0; } - /// hasInitializer - Unless a global variable isExternal(), it has an /// initializer. The initializer for the global variable/constant is held by /// Initializer if an initializer is specified. @@ -119,7 +114,7 @@ public: /// illegal to call this method if the global is external, because we cannot /// tell what the value is initialized to! /// - inline /*const FIXME*/ Constant *getInitializer() const { + inline const Constant *getInitializer() const { assert(hasInitializer() && "GV doesn't have initializer!"); return static_cast<Constant*>(Op<0>().get()); } diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 372eaba..4caf8f1 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -65,6 +65,7 @@ void initializeArgPromotionPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); +void initializeBlockFrequencyPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); @@ -83,7 +84,6 @@ void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); -void initializeDTEPass(PassRegistry&); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); void initializeDomOnlyPrinterPass(PassRegistry&); @@ -140,10 +140,13 @@ void initializeLoopUnrollPass(PassRegistry&); void initializeLoopUnswitchPass(PassRegistry&); void initializeLoopIdiomRecognizePass(PassRegistry&); void initializeLowerAtomicPass(PassRegistry&); +void initializeLowerExpectIntrinsicPass(PassRegistry&); void initializeLowerIntrinsicsPass(PassRegistry&); void initializeLowerInvokePass(PassRegistry&); void initializeLowerSetJmpPass(PassRegistry&); void initializeLowerSwitchPass(PassRegistry&); +void initializeMachineBlockFrequencyPass(PassRegistry&); +void initializeMachineBranchProbabilityInfoPass(PassRegistry&); void initializeMachineCSEPass(PassRegistry&); void initializeMachineDominatorTreePass(PassRegistry&); void initializeMachineLICMPass(PassRegistry&); @@ -160,6 +163,10 @@ void initializeModuleDebugInfoPrinterPass(PassRegistry&); void initializeNoAAPass(PassRegistry&); void initializeNoProfileInfoPass(PassRegistry&); void initializeNoPathProfileInfoPass(PassRegistry&); +void initializeObjCARCAliasAnalysisPass(PassRegistry&); +void initializeObjCARCExpandPass(PassRegistry&); +void initializeObjCARCContractPass(PassRegistry&); +void initializeObjCARCOptPass(PassRegistry&); void initializeOptimalEdgeProfilerPass(PassRegistry&); void initializeOptimizePHIsPass(PassRegistry&); void initializePEIPass(PassRegistry&); @@ -171,7 +178,6 @@ void initializePostDomOnlyViewerPass(PassRegistry&); void initializePostDomPrinterPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&); -void initializePreAllocSplittingPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&); void initializePrintDbgInfoPass(PassRegistry&); void initializePrintFunctionPassPass(PassRegistry&); @@ -192,7 +198,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&); void initializeRegionOnlyViewerPass(PassRegistry&); void initializeRegionPrinterPass(PassRegistry&); void initializeRegionViewerPass(PassRegistry&); -void initializeRegisterCoalescerAnalysisGroup(PassRegistry&); void initializeRenderMachineFunctionPass(PassRegistry&); void initializeSCCPPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&); @@ -200,7 +205,7 @@ void initializeSROA_SSAUpPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); void initializeScalarEvolutionPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&); -void initializeSimpleRegisterCoalescingPass(PassRegistry&); +void initializeRegisterCoalescerPass(PassRegistry&); void initializeSimplifyLibCallsPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSinkingPass(PassRegistry&); diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index ed8f0f7..a98aff1 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -25,15 +25,16 @@ class PointerType; class FunctionType; class Module; struct InlineAsmKeyType; -template<class ValType, class TypeClass, class ConstantClass, bool HasLargeKey> +template<class ValType, class ValRefType, class TypeClass, class ConstantClass, + bool HasLargeKey> class ConstantUniqueMap; template<class ConstantClass, class TypeClass, class ValType> struct ConstantCreator; class InlineAsm : public Value { friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>; - friend class ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm, - false>; + friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&, + PointerType, InlineAsm, false>; InlineAsm(const InlineAsm &); // do not implement void operator=(const InlineAsm&); // do not implement @@ -63,13 +64,13 @@ public: /// getType - InlineAsm's are always pointers. /// - const PointerType *getType() const { - return reinterpret_cast<const PointerType*>(Value::getType()); + PointerType *getType() const { + return reinterpret_cast<PointerType*>(Value::getType()); } /// getFunctionType - InlineAsm's are always pointers to functions. /// - const FunctionType *getFunctionType() const; + FunctionType *getFunctionType() const; const std::string &getAsmString() const { return AsmString; } const std::string &getConstraintString() const { return Constraints; } @@ -187,25 +188,32 @@ public: // in the backend. enum { + // Fixed operands on an INLINEASM SDNode. Op_InputChain = 0, Op_AsmString = 1, Op_MDNode = 2, Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack Op_FirstOperand = 4, + // Fixed operands on an INLINEASM MachineInstr. MIOp_AsmString = 0, MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack MIOp_FirstOperand = 2, + // Interpretation of the MIOp_ExtraInfo bit field. Extra_HasSideEffects = 1, Extra_IsAlignStack = 2, - - Kind_RegUse = 1, - Kind_RegDef = 2, - Kind_Imm = 3, - Kind_Mem = 4, - Kind_RegDefEarlyClobber = 6, - + + // Inline asm operands map to multiple SDNode / MachineInstr operands. + // The first operand is an immediate describing the asm operand, the low + // bits is the kind: + Kind_RegUse = 1, // Input register, "r". + Kind_RegDef = 2, // Output register, "=r". + Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r". + Kind_Clobber = 4, // Clobbered register, "~r". + Kind_Imm = 5, // Immediate. + Kind_Mem = 6, // Memory operand, "m". + Flag_MatchingOperand = 0x80000000 }; @@ -232,7 +240,10 @@ public: static bool isRegDefEarlyClobberKind(unsigned Flag) { return getKind(Flag) == Kind_RegDefEarlyClobber; } - + static bool isClobberKind(unsigned Flag) { + return getKind(Flag) == Kind_Clobber; + } + /// getNumOperandRegisters - Extract the number of registers field from the /// inline asm operand flag. static unsigned getNumOperandRegisters(unsigned Flag) { diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 54dfe39..0bc9a3b 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -20,6 +20,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Attributes.h" #include "llvm/CallingConv.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include <iterator> @@ -76,7 +77,7 @@ public: /// getAllocatedType - Return the type that is being allocated by the /// instruction. /// - const Type *getAllocatedType() const; + Type *getAllocatedType() const; /// getAlignment - Return the alignment of the memory that is being allocated /// by the instruction. @@ -271,10 +272,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) // GetElementPtrInst Class //===----------------------------------------------------------------------===// -// checkType - Simple wrapper function to give a better assertion failure +// checkGEPType - Simple wrapper function to give a better assertion failure // message on bad indexes for a gep instruction. // -static inline const Type *checkType(const Type *Ty) { +static inline const Type *checkGEPType(const Type *Ty) { assert(Ty && "Invalid GetElementPtrInst indices for type!"); return Ty; } @@ -315,13 +316,13 @@ class GetElementPtrInst : public Instruction { /// pointer type. /// template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - // This argument ensures that we - // have an iterator we can do - // arithmetic on in constant time - std::random_access_iterator_tag) { + static Type *getIndexedType(const Type *Ptr, + RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd, + // This argument ensures that we + // have an iterator we can do + // arithmetic on in constant time + std::random_access_iterator_tag) { unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); if (NumIdx > 0) @@ -446,24 +447,22 @@ public: /// pointer type. /// template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd) { + static Type *getIndexedType(const Type *Ptr, RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd) { return getIndexedType(Ptr, IdxBegin, IdxEnd, typename std::iterator_traits<RandomAccessIterator>:: iterator_category()); } - static const Type *getIndexedType(const Type *Ptr, - Value* const *Idx, unsigned NumIdx); + // FIXME: Use ArrayRef + static Type *getIndexedType(const Type *Ptr, + Value* const *Idx, unsigned NumIdx); + static Type *getIndexedType(const Type *Ptr, + Constant* const *Idx, unsigned NumIdx); - static const Type *getIndexedType(const Type *Ptr, - Constant* const *Idx, unsigned NumIdx); - - static const Type *getIndexedType(const Type *Ptr, - uint64_t const *Idx, unsigned NumIdx); - - static const Type *getIndexedType(const Type *Ptr, Value *Idx); + static Type *getIndexedType(const Type *Ptr, + uint64_t const *Idx, unsigned NumIdx); + static Type *getIndexedType(const Type *Ptr, Value *Idx); inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } @@ -538,7 +537,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(PointerType::get(checkType( + : Instruction(PointerType::get(checkGEPType( getIndexedType(Ptr->getType(), IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) @@ -557,7 +556,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(PointerType::get(checkType( + : Instruction(PointerType::get(checkGEPType( getIndexedType(Ptr->getType(), IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) @@ -843,46 +842,17 @@ public: class CallInst : public Instruction { AttrListPtr AttributeList; ///< parameter attributes for call CallInst(const CallInst &CI); - void init(Value *Func, Value* const *Params, unsigned NumParams); - void init(Value *Func, Value *Actual1, Value *Actual2); - void init(Value *Func, Value *Actual); - void init(Value *Func); - - template<typename RandomAccessIterator> - void init(Value *Func, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, - const Twine &NameStr, - // This argument ensures that we have an iterator we can - // do arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd); - - // This requires that the iterator points to contiguous memory. - init(Func, NumArgs ? &*ArgBegin : 0, NumArgs); - setName(NameStr); - } + void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr); + void init(Value *Func, const Twine &NameStr); - /// Construct a CallInst given a range of arguments. RandomAccessIterator - /// must be a random-access iterator pointing to contiguous storage - /// (e.g. a std::vector<>::iterator). Checks are made for - /// random-accessness but not for contiguous storage as that would - /// incur runtime overhead. + /// Construct a CallInst given a range of arguments. /// @brief Construct a CallInst from a range of arguments - template<typename RandomAccessIterator> - CallInst(Value *Func, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, - const Twine &NameStr, Instruction *InsertBefore); - - /// Construct a CallInst given a range of arguments. RandomAccessIterator - /// must be a random-access iterator pointing to contiguous storage - /// (e.g. a std::vector<>::iterator). Checks are made for - /// random-accessness but not for contiguous storage as that would - /// incur runtime overhead. + inline CallInst(Value *Func, ArrayRef<Value *> Args, + const Twine &NameStr, Instruction *InsertBefore); + + /// Construct a CallInst given a range of arguments. /// @brief Construct a CallInst from a range of arguments - template<typename RandomAccessIterator> - inline CallInst(Value *Func, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, + inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd); CallInst(Value *F, Value *Actual, const Twine &NameStr, @@ -895,31 +865,18 @@ class CallInst : public Instruction { protected: virtual CallInst *clone_impl() const; public: - template<typename RandomAccessIterator> static CallInst *Create(Value *Func, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, + ArrayRef<Value *> Args, const Twine &NameStr = "", Instruction *InsertBefore = 0) { - return new(unsigned(ArgEnd - ArgBegin + 1)) - CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertBefore); + return new(unsigned(Args.size() + 1)) + CallInst(Func, Args, NameStr, InsertBefore); } - template<typename RandomAccessIterator> static CallInst *Create(Value *Func, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, + ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new(unsigned(ArgEnd - ArgBegin + 1)) - CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertAtEnd); - } - static CallInst *Create(Value *F, Value *Actual, - const Twine &NameStr = "", - Instruction *InsertBefore = 0) { - return new(2) CallInst(F, Actual, NameStr, InsertBefore); - } - static CallInst *Create(Value *F, Value *Actual, const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new(2) CallInst(F, Actual, NameStr, InsertAtEnd); + return new(unsigned(Args.size() + 1)) + CallInst(Func, Args, NameStr, InsertAtEnd); } static CallInst *Create(Value *F, const Twine &NameStr = "", Instruction *InsertBefore = 0) { @@ -1094,32 +1051,24 @@ template <> struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> { }; -template<typename RandomAccessIterator> -CallInst::CallInst(Value *Func, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, +CallInst::CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), Instruction::Call, - OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), - unsigned(ArgEnd - ArgBegin + 1), InsertAtEnd) { - init(Func, ArgBegin, ArgEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), + unsigned(Args.size() + 1), InsertAtEnd) { + init(Func, Args, NameStr); } -template<typename RandomAccessIterator> -CallInst::CallInst(Value *Func, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, +CallInst::CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr, Instruction *InsertBefore) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), Instruction::Call, - OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), - unsigned(ArgEnd - ArgBegin + 1), InsertBefore) { - init(Func, ArgBegin, ArgEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + OperandTraits<CallInst>::op_end(this) - (Args.size() + 1), + unsigned(Args.size() + 1), InsertBefore) { + init(Func, Args, NameStr); } @@ -1430,69 +1379,18 @@ class ExtractValueInst : public UnaryInstruction { SmallVector<unsigned, 4> Indices; ExtractValueInst(const ExtractValueInst &EVI); - void init(const unsigned *Idx, unsigned NumIdx, - const Twine &NameStr); - void init(unsigned Idx, const Twine &NameStr); - - template<typename RandomAccessIterator> - void init(RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - const Twine &NameStr, - // This argument ensures that we have an iterator we can - // do arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); - - // There's no fundamental reason why we require at least one index - // (other than weirdness with &*IdxBegin being invalid; see - // getelementptr's init routine for example). But there's no - // present need to support it. - assert(NumIdx > 0 && "ExtractValueInst must have at least one index"); - - // This requires that the iterator points to contiguous memory. - init(&*IdxBegin, NumIdx, NameStr); // FIXME: for the general case - // we have to build an array here - } - - /// getIndexedType - Returns the type of the element that would be extracted - /// with an extractvalue instruction with the specified parameters. - /// - /// Null is returned if the indices are invalid for the specified type. - /// - static const Type *getIndexedType(const Type *Agg, - const unsigned *Idx, unsigned NumIdx); - - template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - // This argument ensures that we - // have an iterator we can do - // arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); - - if (NumIdx > 0) - // This requires that the iterator points to contiguous memory. - return getIndexedType(Ptr, &*IdxBegin, NumIdx); - else - return getIndexedType(Ptr, (const unsigned *)0, NumIdx); - } + void init(ArrayRef<unsigned> Idxs, const Twine &NameStr); /// Constructors - Create a extractvalue instruction with a base aggregate /// value and a list of indices. The first ctor can optionally insert before /// an existing instruction, the second appends the new instruction to the /// specified BasicBlock. - template<typename RandomAccessIterator> inline ExtractValueInst(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, Instruction *InsertBefore); - template<typename RandomAccessIterator> inline ExtractValueInst(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd); // allocate space for exactly one operand @@ -1503,54 +1401,25 @@ protected: virtual ExtractValueInst *clone_impl() const; public: - template<typename RandomAccessIterator> static ExtractValueInst *Create(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr = "", Instruction *InsertBefore = 0) { return new - ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertBefore); + ExtractValueInst(Agg, Idxs, NameStr, InsertBefore); } - template<typename RandomAccessIterator> static ExtractValueInst *Create(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertAtEnd); - } - - /// Constructors - These two creators are convenience methods because one - /// index extractvalue instructions are much more common than those with - /// more than one. - static ExtractValueInst *Create(Value *Agg, unsigned Idx, - const Twine &NameStr = "", - Instruction *InsertBefore = 0) { - unsigned Idxs[1] = { Idx }; - return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertBefore); - } - static ExtractValueInst *Create(Value *Agg, unsigned Idx, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { - unsigned Idxs[1] = { Idx }; - return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd); + return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd); } /// getIndexedType - Returns the type of the element that would be extracted /// with an extractvalue instruction with the specified parameters. /// /// Null is returned if the indices are invalid for the specified type. - /// - template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd) { - return getIndexedType(Ptr, IdxBegin, IdxEnd, - typename std::iterator_traits<RandomAccessIterator>:: - iterator_category()); - } - static const Type *getIndexedType(const Type *Ptr, unsigned Idx); + static Type *getIndexedType(const Type *Agg, ArrayRef<unsigned> Idxs); typedef const unsigned* idx_iterator; inline idx_iterator idx_begin() const { return Indices.begin(); } @@ -1566,7 +1435,11 @@ public: return 0U; // get index for modifying correct operand } - unsigned getNumIndices() const { // Note: always non-negative + ArrayRef<unsigned> getIndices() const { + return Indices; + } + + unsigned getNumIndices() const { return (unsigned)Indices.size(); } @@ -1584,31 +1457,21 @@ public: } }; -template<typename RandomAccessIterator> ExtractValueInst::ExtractValueInst(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, Instruction *InsertBefore) - : UnaryInstruction(checkType(getIndexedType(Agg->getType(), - IdxBegin, IdxEnd)), + : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)), ExtractValue, Agg, InsertBefore) { - init(IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Idxs, NameStr); } -template<typename RandomAccessIterator> ExtractValueInst::ExtractValueInst(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) - : UnaryInstruction(checkType(getIndexedType(Agg->getType(), - IdxBegin, IdxEnd)), + : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)), ExtractValue, Agg, InsertAtEnd) { - init(IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Idxs, NameStr); } @@ -1624,44 +1487,19 @@ class InsertValueInst : public Instruction { void *operator new(size_t, unsigned); // Do not implement InsertValueInst(const InsertValueInst &IVI); - void init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx, + void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const Twine &NameStr); - void init(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr); - - template<typename RandomAccessIterator> - void init(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, RandomAccessIterator IdxEnd, - const Twine &NameStr, - // This argument ensures that we have an iterator we can - // do arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); - - // There's no fundamental reason why we require at least one index - // (other than weirdness with &*IdxBegin being invalid; see - // getelementptr's init routine for example). But there's no - // present need to support it. - assert(NumIdx > 0 && "InsertValueInst must have at least one index"); - - // This requires that the iterator points to contiguous memory. - init(Agg, Val, &*IdxBegin, NumIdx, NameStr); // FIXME: for the general case - // we have to build an array here - } /// Constructors - Create a insertvalue instruction with a base aggregate /// value, a value to insert, and a list of indices. The first ctor can /// optionally insert before an existing instruction, the second appends /// the new instruction to the specified BasicBlock. - template<typename RandomAccessIterator> inline InsertValueInst(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, Instruction *InsertBefore); - template<typename RandomAccessIterator> inline InsertValueInst(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd); /// Constructors - These two constructors are convenience methods because one @@ -1679,37 +1517,17 @@ public: return User::operator new(s, 2); } - template<typename RandomAccessIterator> static InsertValueInst *Create(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr = "", Instruction *InsertBefore = 0) { - return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, - NameStr, InsertBefore); + return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore); } - template<typename RandomAccessIterator> static InsertValueInst *Create(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, - NameStr, InsertAtEnd); - } - - /// Constructors - These two creators are convenience methods because one - /// index insertvalue instructions are much more common than those with - /// more than one. - static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx, - const Twine &NameStr = "", - Instruction *InsertBefore = 0) { - return new InsertValueInst(Agg, Val, Idx, NameStr, InsertBefore); - } - static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd); + return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd); } /// Transparently provide more efficient getOperand methods. @@ -1739,7 +1557,11 @@ public: return 1U; // get index for modifying correct operand } - unsigned getNumIndices() const { // Note: always non-negative + ArrayRef<unsigned> getIndices() const { + return Indices; + } + + unsigned getNumIndices() const { return (unsigned)Indices.size(); } @@ -1762,33 +1584,25 @@ struct OperandTraits<InsertValueInst> : public FixedNumOperandTraits<InsertValueInst, 2> { }; -template<typename RandomAccessIterator> InsertValueInst::InsertValueInst(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, Instruction *InsertBefore) : Instruction(Agg->getType(), InsertValue, OperandTraits<InsertValueInst>::op_begin(this), 2, InsertBefore) { - init(Agg, Val, IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Agg, Val, Idxs, NameStr); } -template<typename RandomAccessIterator> InsertValueInst::InsertValueInst(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Agg->getType(), InsertValue, OperandTraits<InsertValueInst>::op_begin(this), 2, InsertAtEnd) { - init(Agg, Val, IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Agg, Val, Idxs, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) @@ -1814,7 +1628,7 @@ class PHINode : public Instruction { explicit PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } @@ -1822,11 +1636,16 @@ class PHINode : public Instruction { PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(NumReservedValues * 2) { + ReservedSpace(NumReservedValues) { setName(NameStr); OperandList = allocHungoffUses(ReservedSpace); } protected: + // allocHungoffUses - this is more complicated than the generic + // User::allocHungoffUses, because we have to allocate Uses for the incoming + // values and pointers to the incoming blocks, all in one allocation. + Use *allocHungoffUses(unsigned) const; + virtual PHINode *clone_impl() const; public: /// Constructors - NumReservedValues is a hint for the number of incoming @@ -1845,32 +1664,55 @@ public: /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Block iterator interface. This provides access to the list of incoming + // basic blocks, which parallels the list of incoming values. + + typedef BasicBlock **block_iterator; + typedef BasicBlock * const *const_block_iterator; + + block_iterator block_begin() { + Use::UserRef *ref = + reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace); + return reinterpret_cast<block_iterator>(ref + 1); + } + + const_block_iterator block_begin() const { + const Use::UserRef *ref = + reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace); + return reinterpret_cast<const_block_iterator>(ref + 1); + } + + block_iterator block_end() { + return block_begin() + getNumOperands(); + } + + const_block_iterator block_end() const { + return block_begin() + getNumOperands(); + } + /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return getNumOperands()/2; } + unsigned getNumIncomingValues() const { return getNumOperands(); } /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { - assert(i*2 < getNumOperands() && "Invalid value number!"); - return getOperand(i*2); + return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { - assert(i*2 < getNumOperands() && "Invalid value number!"); - setOperand(i*2, V); + setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { - return i*2; + return i; } static unsigned getIncomingValueNumForOperand(unsigned i) { - assert(i % 2 == 0 && "Invalid incoming-value operand index!"); - return i/2; + return i; } /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { - return cast<BasicBlock>(getOperand(i*2+1)); + return block_begin()[i]; } /// getIncomingBlock - Return incoming basic block corresponding @@ -1878,7 +1720,7 @@ public: /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); - return cast<BasicBlock>((&U + 1)->get()); + return getIncomingBlock(unsigned(&U - op_begin())); } /// getIncomingBlock - Return incoming basic block corresponding @@ -1889,16 +1731,8 @@ public: return getIncomingBlock(I.getUse()); } - void setIncomingBlock(unsigned i, BasicBlock *BB) { - setOperand(i*2+1, (Value*)BB); - } - static unsigned getOperandNumForIncomingBlock(unsigned i) { - return i*2+1; - } - static unsigned getIncomingBlockNumForOperand(unsigned i) { - assert(i % 2 == 1 && "Invalid incoming-block operand index!"); - return i/2; + block_begin()[i] = BB; } /// addIncoming - Add an incoming value to the end of the PHI list @@ -1908,13 +1742,12 @@ public: assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - unsigned OpNo = NumOperands; - if (OpNo+2 > ReservedSpace) + if (NumOperands == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. - NumOperands = OpNo+2; - OperandList[OpNo] = V; - OperandList[OpNo+1] = (Value*)BB; + ++NumOperands; + setIncomingValue(NumOperands - 1, V); + setIncomingBlock(NumOperands - 1, BB); } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1937,14 +1770,16 @@ public: /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - Use *OL = OperandList; - for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) - if (OL[i+1].get() == (const Value*)BB) return i/2; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (block_begin()[i] == BB) + return i; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { - return getIncomingValue(getBasicBlockIndex(BB)); + int Idx = getBasicBlockIndex(BB); + assert(Idx >= 0 && "Invalid basic block argument!"); + return getIncomingValue(Idx); } /// hasConstantValue - If the specified PHI node always merges together the @@ -2397,71 +2232,39 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) class InvokeInst : public TerminatorInst { AttrListPtr AttributeList; InvokeInst(const InvokeInst &BI); - void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - Value* const *Args, unsigned NumArgs); - - template<typename RandomAccessIterator> void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, - const Twine &NameStr, - // This argument ensures that we have an iterator we can - // do arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd); - - // This requires that the iterator points to contiguous memory. - init(Func, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs); - setName(NameStr); - } + ArrayRef<Value *> Args, const Twine &NameStr); /// Construct an InvokeInst given a range of arguments. - /// RandomAccessIterator must be a random-access iterator pointing to - /// contiguous storage (e.g. a std::vector<>::iterator). Checks are - /// made for random-accessness but not for contiguous storage as - /// that would incur runtime overhead. /// /// @brief Construct an InvokeInst from a range of arguments - template<typename RandomAccessIterator> inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, - unsigned Values, + ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore); /// Construct an InvokeInst given a range of arguments. - /// RandomAccessIterator must be a random-access iterator pointing to - /// contiguous storage (e.g. a std::vector<>::iterator). Checks are - /// made for random-accessness but not for contiguous storage as - /// that would incur runtime overhead. /// /// @brief Construct an InvokeInst from a range of arguments - template<typename RandomAccessIterator> inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, - unsigned Values, + ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: virtual InvokeInst *clone_impl() const; public: - template<typename RandomAccessIterator> static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, - const Twine &NameStr = "", + ArrayRef<Value *> Args, const Twine &NameStr = "", Instruction *InsertBefore = 0) { - unsigned Values(ArgEnd - ArgBegin + 3); - return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, + unsigned Values = unsigned(Args.size()) + 3; + return new(Values) InvokeInst(Func, IfNormal, IfException, Args, Values, NameStr, InsertBefore); } - template<typename RandomAccessIterator> static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, - const Twine &NameStr, + ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - unsigned Values(ArgEnd - ArgBegin + 3); - return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, + unsigned Values = unsigned(Args.size()) + 3; + return new(Values) InvokeInst(Func, IfNormal, IfException, Args, Values, NameStr, InsertAtEnd); } @@ -2627,37 +2430,27 @@ template <> struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> { }; -template<typename RandomAccessIterator> InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, - unsigned Values, + ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), Instruction::Invoke, OperandTraits<InvokeInst>::op_end(this) - Values, Values, InsertBefore) { - init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Func, IfNormal, IfException, Args, NameStr); } -template<typename RandomAccessIterator> InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, - unsigned Values, + ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), Instruction::Invoke, OperandTraits<InvokeInst>::op_end(this) - Values, Values, InsertAtEnd) { - init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, - typename std::iterator_traits<RandomAccessIterator> - ::iterator_category()); + init(Func, IfNormal, IfException, Args, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index 5cfe551..46361ca 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -16,6 +16,7 @@ #ifndef LLVM_INTRINSICS_H #define LLVM_INTRINSICS_H +#include "llvm/ADT/ArrayRef.h" #include <string> namespace llvm { @@ -44,12 +45,12 @@ namespace Intrinsic { /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as /// "llvm.ppc.altivec.lvx". - std::string getName(ID id, const Type **Tys = 0, unsigned numTys = 0); + std::string getName(ID id, ArrayRef<Type*> Tys = ArrayRef<Type*>()); /// Intrinsic::getType(ID) - Return the function type for an intrinsic. /// const FunctionType *getType(LLVMContext &Context, ID id, - const Type **Tys = 0, unsigned numTys = 0); + ArrayRef<Type*> Tys = ArrayRef<Type*>()); /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be /// overloaded. @@ -67,8 +68,8 @@ namespace Intrinsic { /// overloaded intrinsic, Tys should point to an array of numTys pointers to /// Type, and must provide exactly one type for each overloaded type in the /// intrinsic. - Function *getDeclaration(Module *M, ID id, const Type **Tys = 0, - unsigned numTys = 0); + Function *getDeclaration(Module *M, ID id, + ArrayRef<Type*> Tys = ArrayRef<Type*>()); /// Map a GCC builtin name to an intrinsic ID. ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName); diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index d8f249a..947cf1b 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -211,7 +211,8 @@ def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>, // however it does conveniently prevent the prefetch from being reordered // with respect to nearby accesses to the same memory. def int_prefetch : Intrinsic<[], - [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], + [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty], [IntrReadWriteArgMem, NoCapture<0>]>; def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>; @@ -254,6 +255,12 @@ let Properties = [IntrReadMem] in { def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; } +let Properties = [IntrNoMem] in { + def int_fma : Intrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMMatchType<0>]>; +} + // NOTE: these are internal interfaces. def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>; @@ -265,6 +272,11 @@ def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty], [IntrNoMem]>, GCCBuiltin<"__builtin_object_size">; +//===------------------------- Expect Intrinsics --------------------------===// +// +def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, + LLVMMatchType<0>], [IntrNoMem]>; + //===-------------------- Bit Manipulation Intrinsics ---------------------===// // @@ -311,7 +323,7 @@ let Properties = [IntrNoMem] in { def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty], [IntrReadMem]>; +def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 3502ff7..65146c3 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -39,7 +39,8 @@ public: // compile-time performance optimization, not a correctness optimization. enum { MD_dbg = 0, // "dbg" - MD_tbaa = 1 // "tbaa" + MD_tbaa = 1, // "tbaa" + MD_prof = 2 // "prof" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index c02e161..8467d11 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -62,7 +62,6 @@ namespace { (void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadStoreEliminationPass(); - (void) llvm::createDeadTypeEliminationPass(); (void) llvm::createDomOnlyPrinterPass(); (void) llvm::createDomPrinterPass(); (void) llvm::createDomOnlyViewerPass(); @@ -92,11 +91,16 @@ namespace { (void) llvm::createLoopUnswitchPass(); (void) llvm::createLoopIdiomPass(); (void) llvm::createLoopRotatePass(); + (void) llvm::createLowerExpectIntrinsicPass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSwitchPass(); (void) llvm::createNoAAPass(); (void) llvm::createNoProfileInfoPass(); + (void) llvm::createObjCARCAliasAnalysisPass(); + (void) llvm::createObjCARCExpandPass(); + (void) llvm::createObjCARCContractPass(); + (void) llvm::createObjCARCOptPass(); (void) llvm::createProfileEstimatorPass(); (void) llvm::createProfileVerifierPass(); (void) llvm::createPathProfileVerifierPass(); diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 775d22b..41c1717 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -37,6 +37,18 @@ namespace llvm { //===------------------------------------------------------------------===// // Properties to be set by the target writer, used to configure asm printer. // + + /// PointerSize - Pointer size in bytes. + /// Default is 4. + unsigned PointerSize; + + /// IsLittleEndian - True if target is little endian. + /// Default is true. + bool IsLittleEndian; + + /// StackGrowsUp - True if target stack grow up. + /// Default is false. + bool StackGrowsUp; /// HasSubsectionsViaSymbols - True if this target has the MachO /// .subsections_via_symbols directive. @@ -284,6 +296,10 @@ namespace llvm { // use EmitLabelOffsetDifference. bool DwarfUsesLabelOffsetForRanges; + /// DwarfRegNumForCFI - True if dwarf register numbers are printed + /// instead of symbolic register names in .cfi_* directives. + bool DwarfRegNumForCFI; // Defaults to false; + //===--- CBE Asm Translation Table -----------------------------------===// const char *const *AsmTransCBE; // Defaults to empty @@ -296,6 +312,21 @@ namespace llvm { static unsigned getSLEB128Size(int Value); static unsigned getULEB128Size(unsigned Value); + /// getPointerSize - Get the pointer size in bytes. + unsigned getPointerSize() const { + return PointerSize; + } + + /// islittleendian - True if the target is little endian. + bool isLittleEndian() const { + return IsLittleEndian; + } + + /// isStackGrowthDirectionUp - True if target stack grow up. + bool isStackGrowthDirectionUp() const { + return StackGrowsUp; + } + bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } // Data directive accessors. @@ -475,6 +506,9 @@ namespace llvm { bool doesDwarfUsesLabelOffsetForRanges() const { return DwarfUsesLabelOffsetForRanges; } + bool useDwarfRegNumForCFI() const { + return DwarfRegNumForCFI; + } const char *const *getAsmCBE() const { return AsmTransCBE; } diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 070089e..43a9ce6 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -39,6 +39,9 @@ namespace llvm { class MCContext { MCContext(const MCContext&); // DO NOT IMPLEMENT MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT + public: + typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable; + private: /// The MCAsmInfo for this target. const MCAsmInfo &MAI; @@ -52,7 +55,7 @@ namespace llvm { BumpPtrAllocator Allocator; /// Symbols - Bindings of names to symbols. - StringMap<MCSymbol*, BumpPtrAllocator&> Symbols; + SymbolTable Symbols; /// UsedNames - Keeps tracks of names that were used both for used declared /// and artificial symbols. @@ -142,6 +145,14 @@ namespace llvm { /// LookupSymbol - Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(StringRef Name) const; + /// getSymbols - Get a reference for the symbol table for clients that + /// want to, for example, iterate over all symbols. 'const' because we + /// still want any modifications to the table itself to use the MCContext + /// APIs. + const SymbolTable &getSymbols() const { + return Symbols; + } + /// @} /// @name Section Management diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 6e20e8a..4996914 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===// +//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,26 +7,23 @@ // //===----------------------------------------------------------------------===// // -// This file defines the TargetOperandInfo and TargetInstrDesc classes, which +// This file defines the MCOperandInfo and MCInstrDesc classes, which // are used to describe target instructions and their operands. // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETINSTRDESC_H -#define LLVM_TARGET_TARGETINSTRDESC_H +#ifndef LLVM_MC_MCINSTRDESC_H +#define LLVM_MC_MCINSTRDESC_H #include "llvm/Support/DataTypes.h" namespace llvm { -class TargetRegisterClass; -class TargetRegisterInfo; - //===----------------------------------------------------------------------===// // Machine Operand Flags and Description //===----------------------------------------------------------------------===// -namespace TOI { +namespace MCOI { // Operand constraints enum OperandConstraint { TIED_TO = 0, // Must be allocated the same register as. @@ -34,54 +31,57 @@ namespace TOI { }; /// OperandFlags - These are flags set on operands, but should be considered - /// private, all access should go through the TargetOperandInfo accessors. + /// private, all access should go through the MCOperandInfo accessors. /// See the accessors for a description of what these are. enum OperandFlags { LookupPtrRegClass = 0, Predicate, OptionalDef }; + + /// Operand Type - Operands are tagged with one of the values of this enum. + enum OperandType { + OPERAND_UNKNOWN, + OPERAND_IMMEDIATE, + OPERAND_REGISTER, + OPERAND_MEMORY, + OPERAND_PCREL + }; } -/// TargetOperandInfo - This holds information about one operand of a machine +/// MCOperandInfo - This holds information about one operand of a machine /// instruction, indicating the register class for register operands, etc. /// -class TargetOperandInfo { +class MCOperandInfo { public: /// RegClass - This specifies the register class enumeration of the operand /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. - /// - /// NOTE: This member should be considered to be private, all access should go - /// through "getRegClass(TRI)" below. short RegClass; - /// Flags - These are flags from the TOI::OperandFlags enum. + /// Flags - These are flags from the MCOI::OperandFlags enum. unsigned short Flags; /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). unsigned Constraints; + + /// OperandType - Information about the type of the operand. + MCOI::OperandType OperandType; /// Currently no other information. - /// getRegClass - Get the register class for the operand, handling resolution - /// of "symbolic" pointer register classes etc. If this is not a register - /// operand, this returns null. - const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const; - - /// isLookupPtrRegClass - Set if this operand is a pointer value and it /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);} + bool isLookupPtrRegClass() const { return Flags&(1 <<MCOI::LookupPtrRegClass);} /// isPredicate - Set if this is one of the operands that made up of /// the predicate operand that controls an isPredicable() instruction. - bool isPredicate() const { return Flags & (1 << TOI::Predicate); } + bool isPredicate() const { return Flags & (1 << MCOI::Predicate); } /// isOptionalDef - Set if this operand is a optional def. /// - bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); } + bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); } }; @@ -89,11 +89,11 @@ public: // Machine Instruction Flags and Description //===----------------------------------------------------------------------===// -/// TargetInstrDesc flags - These should be considered private to the -/// implementation of the TargetInstrDesc class. Clients should use the -/// predicate methods on TargetInstrDesc, not use these directly. These -/// all correspond to bitfields in the TargetInstrDesc::Flags field. -namespace TID { +/// MCInstrDesc flags - These should be considered private to the +/// implementation of the MCInstrDesc class. Clients should use the predicate +/// methods on MCInstrDesc, not use these directly. These all correspond to +/// bitfields in the MCInstrDesc::Flags field. +namespace MCID { enum { Variadic = 0, HasOptionalDef, @@ -123,29 +123,29 @@ namespace TID { }; } -/// TargetInstrDesc - Describe properties that are true of each -/// instruction in the target description file. This captures information about -/// side effects, register use and many other things. There is one instance of -/// this struct for each target instruction class, and the MachineInstr class -/// points to this struct directly to describe itself. -class TargetInstrDesc { +/// MCInstrDesc - Describe properties that are true of each instruction in the +/// target description file. This captures information about side effects, +/// register use and many other things. There is one instance of this struct +/// for each target instruction class, and the MachineInstr class points to +/// this struct directly to describe itself. +class MCInstrDesc { public: unsigned short Opcode; // The opcode number unsigned short NumOperands; // Num of args (may be more if variable_ops) unsigned short NumDefs; // Num of args that are definitions unsigned short SchedClass; // enum identifying instr sched class + unsigned short Size; // Number of bytes in encoding. const char * Name; // Name of the instruction record in td file unsigned Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values const unsigned *ImplicitUses; // Registers implicitly read by this instr const unsigned *ImplicitDefs; // Registers implicitly defined by this instr - const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered" - const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands + const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands /// getOperandConstraint - Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. int getOperandConstraint(unsigned OpNum, - TOI::OperandConstraint Constraint) const { + MCOI::OperandConstraint Constraint) const { if (OpNum < NumOperands && (OpInfo[OpNum].Constraints & (1 << Constraint))) { unsigned Pos = 16 + Constraint * 4; @@ -154,12 +154,6 @@ public: return -1; } - /// getRegClass - Returns the register class constraint for OpNum, or NULL. - const TargetRegisterClass *getRegClass(unsigned OpNum, - const TargetRegisterInfo *TRI) const { - return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0; - } - /// getOpcode - Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; @@ -193,13 +187,13 @@ public: /// operands but before the implicit definitions and uses (if any are /// present). bool isVariadic() const { - return Flags & (1 << TID::Variadic); + return Flags & (1 << MCID::Variadic); } /// hasOptionalDef - Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. bool hasOptionalDef() const { - return Flags & (1 << TID::HasOptionalDef); + return Flags & (1 << MCID::HasOptionalDef); } /// getImplicitUses - Return a list of registers that are potentially @@ -214,7 +208,7 @@ public: const unsigned *getImplicitUses() const { return ImplicitUses; } - + /// getNumImplicitUses - Return the number of implicit uses this instruction /// has. unsigned getNumImplicitUses() const { @@ -223,8 +217,7 @@ public: for (; ImplicitUses[i]; ++i) /*empty*/; return i; } - - + /// getImplicitDefs - Return a list of registers that are potentially /// written by any instance of this machine instruction. For example, on X86, /// many instructions implicitly set the flags register. In this case, they @@ -266,17 +259,6 @@ public: return false; } - /// getRegClassBarriers - Return a list of register classes that are - /// completely clobbered by this machine instruction. For example, on X86 - /// the call instructions will completely clobber all the registers in the - /// fp stack and XMM classes. - /// - /// This method returns null if the instruction doesn't completely clobber - /// any register class. - const TargetRegisterClass **getRegClassBarriers() const { - return RCBarriers; - } - /// getSchedClass - Return the scheduling class for this instruction. The /// scheduling class is an index into the InstrItineraryData table. This /// returns zero if there is no known scheduling information for the @@ -286,19 +268,25 @@ public: return SchedClass; } + /// getSize - Return the number of bytes in the encoding of this instruction, + /// or zero if the encoding size cannot be known from the opcode. + unsigned getSize() const { + return Size; + } + bool isReturn() const { - return Flags & (1 << TID::Return); + return Flags & (1 << MCID::Return); } bool isCall() const { - return Flags & (1 << TID::Call); + return Flags & (1 << MCID::Call); } /// isBarrier - Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. bool isBarrier() const { - return Flags & (1 << TID::Barrier); + return Flags & (1 << MCID::Barrier); } /// isTerminator - Returns true if this instruction part of the terminator for @@ -308,7 +296,7 @@ public: /// Various passes use this to insert code into the bottom of a basic block, /// but before control flow occurs. bool isTerminator() const { - return Flags & (1 << TID::Terminator); + return Flags & (1 << MCID::Terminator); } /// isBranch - Returns true if this is a conditional, unconditional, or @@ -316,13 +304,13 @@ public: /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. bool isBranch() const { - return Flags & (1 << TID::Branch); + return Flags & (1 << MCID::Branch); } /// isIndirectBranch - Return true if this is an indirect branch, such as a /// branch through a register. bool isIndirectBranch() const { - return Flags & (1 << TID::IndirectBranch); + return Flags & (1 << MCID::IndirectBranch); } /// isConditionalBranch - Return true if this is a branch which may fall @@ -346,37 +334,37 @@ public: /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. bool isPredicable() const { - return Flags & (1 << TID::Predicable); + return Flags & (1 << MCID::Predicable); } /// isCompare - Return true if this instruction is a comparison. bool isCompare() const { - return Flags & (1 << TID::Compare); + return Flags & (1 << MCID::Compare); } /// isMoveImmediate - Return true if this instruction is a move immediate /// (including conditional moves) instruction. bool isMoveImmediate() const { - return Flags & (1 << TID::MoveImm); + return Flags & (1 << MCID::MoveImm); } /// isBitcast - Return true if this instruction is a bitcast instruction. /// bool isBitcast() const { - return Flags & (1 << TID::Bitcast); + return Flags & (1 << MCID::Bitcast); } /// isNotDuplicable - Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable() const { - return Flags & (1 << TID::NotDuplicable); + return Flags & (1 << MCID::NotDuplicable); } /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot() const { - return Flags & (1 << TID::DelaySlot); + return Flags & (1 << MCID::DelaySlot); } /// canFoldAsLoad - Return true for instructions that can be folded as @@ -388,7 +376,7 @@ public: /// This should only be set on instructions that return a value in their /// only virtual register definition. bool canFoldAsLoad() const { - return Flags & (1 << TID::FoldableAsLoad); + return Flags & (1 << MCID::FoldableAsLoad); } //===--------------------------------------------------------------------===// @@ -399,7 +387,7 @@ public: /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. bool mayLoad() const { - return Flags & (1 << TID::MayLoad); + return Flags & (1 << MCID::MayLoad); } @@ -408,7 +396,7 @@ public: /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. bool mayStore() const { - return Flags & (1 << TID::MayStore); + return Flags & (1 << MCID::MayStore); } /// hasUnmodeledSideEffects - Return true if this instruction has side @@ -425,7 +413,7 @@ public: /// LLVM, etc. /// bool hasUnmodeledSideEffects() const { - return Flags & (1 << TID::UnmodeledSideEffects); + return Flags & (1 << MCID::UnmodeledSideEffects); } //===--------------------------------------------------------------------===// @@ -443,7 +431,7 @@ public: /// Also note that some instructions require non-trivial modification to /// commute them. bool isCommutable() const { - return Flags & (1 << TID::Commutable); + return Flags & (1 << MCID::Commutable); } /// isConvertibleTo3Addr - Return true if this is a 2-address instruction @@ -461,7 +449,7 @@ public: /// instruction (e.g. shl reg, 4 on x86). /// bool isConvertibleTo3Addr() const { - return Flags & (1 << TID::ConvertibleTo3Addr); + return Flags & (1 << MCID::ConvertibleTo3Addr); } /// usesCustomInsertionHook - Return true if this instruction requires @@ -473,7 +461,7 @@ public: /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method /// is used to insert this into the MachineBasicBlock. bool usesCustomInsertionHook() const { - return Flags & (1 << TID::UsesCustomInserter); + return Flags & (1 << MCID::UsesCustomInserter); } /// isRematerializable - Returns true if this instruction is a candidate for @@ -481,7 +469,7 @@ public: /// flag is set, the isReallyTriviallyReMaterializable() method is called to /// verify the instruction is really rematable. bool isRematerializable() const { - return Flags & (1 << TID::Rematerializable); + return Flags & (1 << MCID::Rematerializable); } /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or @@ -491,7 +479,7 @@ public: /// more than moving the instruction into the appropriate register. Note, we /// are not marking copies from and to the same register class with this flag. bool isAsCheapAsAMove() const { - return Flags & (1 << TID::CheapAsAMove); + return Flags & (1 << MCID::CheapAsAMove); } /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands @@ -501,7 +489,7 @@ public: /// Post-register allocation passes should not attempt to change allocations /// for sources of instructions with this flag. bool hasExtraSrcRegAllocReq() const { - return Flags & (1 << TID::ExtraSrcRegAllocReq); + return Flags & (1 << MCID::ExtraSrcRegAllocReq); } /// hasExtraDefRegAllocReq - Returns true if this instruction def operands @@ -511,7 +499,7 @@ public: /// Post-register allocation passes should not attempt to change allocations /// for definitions of instructions with this flag. bool hasExtraDefRegAllocReq() const { - return Flags & (1 << TID::ExtraDefRegAllocReq); + return Flags & (1 << MCID::ExtraDefRegAllocReq); } }; diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h new file mode 100644 index 0000000..a63e5fa --- /dev/null +++ b/include/llvm/MC/MCInstrInfo.h @@ -0,0 +1,51 @@ +//===-- llvm/MC/MCInstrInfo.h - Target Instruction Info ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the target machine instruction set. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCINSTRINFO_H +#define LLVM_MC_MCINSTRINFO_H + +#include "llvm/MC/MCInstrDesc.h" +#include <cassert> + +namespace llvm { + +//--------------------------------------------------------------------------- +/// +/// MCInstrInfo - Interface to description of machine instruction set +/// +class MCInstrInfo { + const MCInstrDesc *Desc; // Raw array to allow static init'n + unsigned NumOpcodes; // Number of entries in the desc array + +public: + /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen + /// auto-generated routines. *DO NOT USE*. + void InitMCInstrInfo(const MCInstrDesc *D, unsigned NO) { + Desc = D; + NumOpcodes = NO; + } + + unsigned getNumOpcodes() const { return NumOpcodes; } + + /// get - Return the machine instruction descriptor that corresponds to the + /// specified instruction opcode. + /// + const MCInstrDesc &get(unsigned Opcode) const { + assert(Opcode < NumOpcodes && "Invalid opcode!"); + return Desc[Opcode]; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h index 6011402..e942892 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/MC/MCInstrItineraries.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===// +//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H -#define LLVM_TARGET_TARGETINSTRITINERARIES_H +#ifndef LLVM_MC_MCINSTRITINERARIES_H +#define LLVM_MC_MCINSTRITINERARIES_H #include <algorithm> diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index ec51031..9bb598f 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -10,11 +10,20 @@ #ifndef LLVM_MC_MCMACHOBJECTWRITER_H #define LLVM_MC_MCMACHOBJECTWRITER_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/Object/MachOFormat.h" #include "llvm/Support/DataTypes.h" +#include <vector> namespace llvm { +class MCSectionData; +class MachObjectWriter; + class MCMachObjectTargetWriter { const unsigned Is64Bit : 1; const uint32_t CPUType; @@ -48,8 +57,191 @@ public: } /// @} + + /// @name API + /// @{ + + virtual void RecordRelocation(MachObjectWriter *Writer, + const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) = 0; + + /// @} }; +class MachObjectWriter : public MCObjectWriter { + /// MachSymbolData - Helper struct for containing some precomputed information + /// on symbols. + struct MachSymbolData { + MCSymbolData *SymbolData; + uint64_t StringIndex; + uint8_t SectionIndex; + + // Support lexicographic sorting. + bool operator<(const MachSymbolData &RHS) const; + }; + + /// The target specific Mach-O writer instance. + llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter; + + /// @name Relocation Data + /// @{ + + llvm::DenseMap<const MCSectionData*, + std::vector<object::macho::RelocationEntry> > Relocations; + llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase; + + /// @} + /// @name Symbol Table Data + /// @{ + + SmallString<256> StringTable; + std::vector<MachSymbolData> LocalSymbolData; + std::vector<MachSymbolData> ExternalSymbolData; + std::vector<MachSymbolData> UndefinedSymbolData; + + /// @} + +public: + MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, + bool _IsLittleEndian) + : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { + } + + /// @name Utility Methods + /// @{ + + bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); + + SectionAddrMap SectionAddress; + + SectionAddrMap &getSectionAddressMap() { return SectionAddress; } + + uint64_t getSectionAddress(const MCSectionData* SD) const { + return SectionAddress.lookup(SD); + } + uint64_t getSymbolAddress(const MCSymbolData* SD, + const MCAsmLayout &Layout) const; + + uint64_t getFragmentAddress(const MCFragment *Fragment, + const MCAsmLayout &Layout) const; + + uint64_t getPaddingSize(const MCSectionData *SD, + const MCAsmLayout &Layout) const; + + bool doesSymbolRequireExternRelocation(const MCSymbolData *SD); + + /// @} + + /// @name Target Writer Proxy Accessors + /// @{ + + bool is64Bit() const { return TargetObjectWriter->is64Bit(); } + bool isARM() const { + uint32_t CPUType = TargetObjectWriter->getCPUType() & + ~object::mach::CTFM_ArchMask; + return CPUType == object::mach::CTM_ARM; + } + + /// @} + + void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, + bool SubsectionsViaSymbols); + + /// WriteSegmentLoadCommand - Write a segment load command. + /// + /// \arg NumSections - The number of sections in this segment. + /// \arg SectionDataSize - The total size of the sections. + void WriteSegmentLoadCommand(unsigned NumSections, + uint64_t VMSize, + uint64_t SectionDataStartOffset, + uint64_t SectionDataSize); + + void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCSectionData &SD, uint64_t FileOffset, + uint64_t RelocationsStart, unsigned NumRelocations); + + void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, + uint32_t StringTableOffset, + uint32_t StringTableSize); + + void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, + uint32_t NumLocalSymbols, + uint32_t FirstExternalSymbol, + uint32_t NumExternalSymbols, + uint32_t FirstUndefinedSymbol, + uint32_t NumUndefinedSymbols, + uint32_t IndirectSymbolOffset, + uint32_t NumIndirectSymbols); + + void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); + + // FIXME: We really need to improve the relocation validation. Basically, we + // want to implement a separate computation which evaluates the relocation + // entry as the linker would, and verifies that the resultant fixup value is + // exactly what the encoder wanted. This will catch several classes of + // problems: + // + // - Relocation entry bugs, the two algorithms are unlikely to have the same + // exact bug. + // + // - Relaxation issues, where we forget to relax something. + // + // - Input errors, where something cannot be correctly encoded. 'as' allows + // these through in many cases. + + void addRelocation(const MCSectionData *SD, + object::macho::RelocationEntry &MRE) { + Relocations[SD].push_back(MRE); + } + + void RecordScatteredRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + unsigned Log2Size, + uint64_t &FixedValue); + + void RecordTLVPRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + uint64_t &FixedValue); + + void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); + + void BindIndirectSymbols(MCAssembler &Asm); + + /// ComputeSymbolTable - Compute the symbol table data + /// + /// \param StringTable [out] - The string table data. + /// \param StringIndexMap [out] - Map from symbol names to offsets in the + /// string table. + void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, + std::vector<MachSymbolData> &LocalSymbolData, + std::vector<MachSymbolData> &ExternalSymbolData, + std::vector<MachSymbolData> &UndefinedSymbolData); + + void computeSectionAddresses(const MCAssembler &Asm, + const MCAsmLayout &Layout); + + void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); + + virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; + + void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); +}; + + /// \brief Construct a new Mach-O writer instance. /// /// This routine takes ownership of the target writer subclass. diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 8b0d87a..a89933b 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -73,7 +73,8 @@ public: virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label); + const MCSymbol *Label, + unsigned PointerSize); virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); virtual void Finish(); diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 91f5773..2556e5f 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -28,10 +28,20 @@ public: /// getEndLoc - Get the location of the last token of this operand. virtual SMLoc getEndLoc() const = 0; - /// dump - Print a debug representation of the operand to the given stream. - virtual void dump(raw_ostream &OS) const = 0; + /// print - Print a debug representation of the operand to the given stream. + virtual void print(raw_ostream &OS) const = 0; + /// dump - Print to the debug stream. + virtual void dump() const; }; +//===----------------------------------------------------------------------===// +// Debugging Support + +inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) { + MO.print(OS); + return OS; +} + } // end namespace llvm. #endif diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h new file mode 100644 index 0000000..caf98bb --- /dev/null +++ b/include/llvm/MC/MCRegisterInfo.h @@ -0,0 +1,129 @@ +//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes an abstract interface used to get information about a +// target machines register file. This information is used for a variety of +// purposed, especially register allocation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCREGISTERINFO_H +#define LLVM_MC_MCREGISTERINFO_H + +#include <cassert> + +namespace llvm { + +/// MCRegisterDesc - This record contains all of the information known about +/// a particular register. The Overlaps field contains a pointer to a zero +/// terminated array of registers that this register aliases, starting with +/// itself. This is needed for architectures like X86 which have AL alias AX +/// alias EAX. The SubRegs field is a zero terminated array of registers that +/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of +/// AX. The SuperRegs field is a zero terminated array of registers that are +/// super-registers of the specific register, e.g. RAX, EAX, are super-registers +/// of AX. +/// +struct MCRegisterDesc { + const char *Name; // Printable name for the reg (for debugging) + const unsigned *Overlaps; // Overlapping registers, described above + const unsigned *SubRegs; // Sub-register set, described above + const unsigned *SuperRegs; // Super-register set, described above +}; + +/// MCRegisterInfo base class - We assume that the target defines a static +/// array of MCRegisterDesc objects that represent all of the machine +/// registers that the target has. As such, we simply have to track a pointer +/// to this array so that we can turn register number into a register +/// descriptor. +/// +/// Note this class is designed to be a base class of TargetRegisterInfo, which +/// is the interface used by codegen. However, specific targets *should never* +/// specialize this class. MCRegisterInfo should only contain getters to access +/// TableGen generated physical register data. It must not be extended with +/// virtual methods. +/// +class MCRegisterInfo { +private: + const MCRegisterDesc *Desc; // Pointer to the descriptor array + unsigned NumRegs; // Number of entries in the array + +public: + /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen + /// auto-generated routines. *DO NOT USE*. + void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR) { + Desc = D; + NumRegs = NR; + } + + const MCRegisterDesc &operator[](unsigned RegNo) const { + assert(RegNo < NumRegs && + "Attempting to access record for invalid register number!"); + return Desc[RegNo]; + } + + /// Provide a get method, equivalent to [], but more useful if we have a + /// pointer to this object. + /// + const MCRegisterDesc &get(unsigned RegNo) const { + return operator[](RegNo); + } + + /// getAliasSet - Return the set of registers aliased by the specified + /// register, or a null list of there are none. The list returned is zero + /// terminated. + /// + const unsigned *getAliasSet(unsigned RegNo) const { + // The Overlaps set always begins with Reg itself. + return get(RegNo).Overlaps + 1; + } + + /// getOverlaps - Return a list of registers that overlap Reg, including + /// itself. This is the same as the alias set except Reg is included in the + /// list. + /// These are exactly the registers in { x | regsOverlap(x, Reg) }. + /// + const unsigned *getOverlaps(unsigned RegNo) const { + return get(RegNo).Overlaps; + } + + /// getSubRegisters - Return the list of registers that are sub-registers of + /// the specified register, or a null list of there are none. The list + /// returned is zero terminated and sorted according to super-sub register + /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. + /// + const unsigned *getSubRegisters(unsigned RegNo) const { + return get(RegNo).SubRegs; + } + + /// getSuperRegisters - Return the list of registers that are super-registers + /// of the specified register, or a null list of there are none. The list + /// returned is zero terminated and sorted according to super-sub register + /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX. + /// + const unsigned *getSuperRegisters(unsigned RegNo) const { + return get(RegNo).SuperRegs; + } + + /// getName - Return the human-readable symbolic target-specific name for the + /// specified physical register. + const char *getName(unsigned RegNo) const { + return get(RegNo).Name; + } + + /// getNumRegs - Return the number of registers this target has (useful for + /// sizing arrays holding per register information) + unsigned getNumRegs() const { + return NumRegs; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index c05a925..7bdba5f 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -460,7 +460,8 @@ namespace llvm { virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label) = 0; + const MCSymbol *Label, + unsigned PointerSize) = 0; virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label) { @@ -547,6 +548,9 @@ namespace llvm { /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. + /// + /// \param DecodeLSDA - If true, emit comments that translates the LSDA into a + /// human readable format. Only usable with CFI. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h new file mode 100644 index 0000000..3b53f20 --- /dev/null +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -0,0 +1,79 @@ +//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the subtarget options of a Target machine. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSUBTARGET_H +#define LLVM_MC_MCSUBTARGET_H + +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/MC/MCInstrItineraries.h" +#include <string> + +namespace llvm { + +class StringRef; + +//===----------------------------------------------------------------------===// +/// +/// MCSubtargetInfo - Generic base class for all target subtargets. +/// +class MCSubtargetInfo { + std::string TargetTriple; // Target triple + const SubtargetFeatureKV *ProcFeatures; // Processor feature list + const SubtargetFeatureKV *ProcDesc; // Processor descriptions + const SubtargetInfoKV *ProcItins; // Scheduling itineraries + const InstrStage *Stages; // Instruction stages + const unsigned *OperandCycles; // Operand cycles + const unsigned *ForwardingPathes; // Forwarding pathes + unsigned NumFeatures; // Number of processor features + unsigned NumProcs; // Number of processors + uint64_t FeatureBits; // Feature bits for current CPU + FS + +public: + void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, + const SubtargetFeatureKV *PF, + const SubtargetFeatureKV *PD, + const SubtargetInfoKV *PI, const InstrStage *IS, + const unsigned *OC, const unsigned *FP, + unsigned NF, unsigned NP); + + /// getTargetTriple - Return the target triple string. + StringRef getTargetTriple() const { + return TargetTriple; + } + + /// getFeatureBits - Return the feature bits. + /// + uint64_t getFeatureBits() const { + return FeatureBits; + } + + /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with + /// feature string), recompute and return feature bits. + uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS); + + /// ToggleFeature - Toggle a feature and returns the re-computed feature + /// bits. This version does not change the implied bits. + uint64_t ToggleFeature(uint64_t FB); + + /// ToggleFeature - Toggle a feature and returns the re-computed feature + /// bits. This version will also change all implied bits. + uint64_t ToggleFeature(StringRef FS); + + /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. + /// + InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 4213d9b..1a7dc92 100644 --- a/include/llvm/Target/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===// +//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,17 +15,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_SUBTARGETFEATURE_H -#define LLVM_TARGET_SUBTARGETFEATURE_H +#ifndef LLVM_MC_SUBTARGETFEATURE_H +#define LLVM_MC_SUBTARGETFEATURE_H -#include <string> #include <vector> -#include <cstring> #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" namespace llvm { class raw_ostream; + class StringRef; //===----------------------------------------------------------------------===// /// @@ -75,32 +74,30 @@ struct SubtargetInfoKV { class SubtargetFeatures { std::vector<std::string> Features; // Subtarget features as a vector public: - explicit SubtargetFeatures(const std::string &Initial = std::string()); + explicit SubtargetFeatures(const StringRef Initial = ""); /// Features string accessors. std::string getString() const; - void setString(const std::string &Initial); - - /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU. - void setCPU(const std::string &String); - - /// Setting CPU string only if no string is set. - void setCPUIfNone(const std::string &String); - - /// Returns current CPU string. - const std::string & getCPU() const; /// Adding Features. - void AddFeature(const std::string &String, bool IsEnabled = true); + void AddFeature(const StringRef String, bool IsEnabled = true); - /// Get feature bits. - uint64_t getBits(const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, + /// ToggleFeature - Toggle a feature and returns the newly updated feature + /// bits. + uint64_t ToggleFeature(uint64_t Bits, const StringRef String, + const SubtargetFeatureKV *FeatureTable, size_t FeatureTableSize); + + /// Get feature bits of a CPU. + uint64_t getFeatureBits(const StringRef CPU, + const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize); - /// Get info pointer - void *getInfo(const SubtargetInfoKV *Table, size_t TableSize); + /// Get scheduling itinerary of a CPU. + void *getItinerary(const StringRef CPU, + const SubtargetInfoKV *Table, size_t TableSize); /// Print feature string. void print(raw_ostream &OS) const; @@ -110,8 +107,7 @@ public: /// Retrieve a formatted string of the default features for the specified /// target triple. - void getDefaultSubtargetFeatures(const std::string &CPU, - const Triple& Triple); + void getDefaultSubtargetFeatures(const Triple& Triple); }; } // End namespace llvm diff --git a/include/llvm/Module.h b/include/llvm/Module.h index aef8eb8..47d23f3 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -28,6 +28,10 @@ namespace llvm { class FunctionType; class GVMaterializer; class LLVMContext; +class StructType; +template<typename T> struct DenseMapInfo; +template<typename KeyT, typename ValueT, + typename KeyInfoT, typename ValueInfoT> class DenseMap; template<> struct ilist_traits<Function> : public SymbolTableListTraits<Function, Module> { @@ -145,7 +149,6 @@ private: NamedMDListType NamedMDList; ///< The named metadata in the module std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values - TypeSymbolTable *TypeSymTab; ///< Symbol table for types OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues std::string ModuleID; ///< Human readable identifier for the module std::string TargetTriple; ///< Platform target triple Module compiled on @@ -231,7 +234,7 @@ public: /// @name Generic Value Accessors /// @{ - /// getNamedValue - Return the first global value in the module with + /// getNamedValue - Return the global value in the module with /// the specified name, of arbitrary type. This method returns null /// if a global with the specified name is not found. GlobalValue *getNamedValue(StringRef Name) const; @@ -244,6 +247,18 @@ public: /// custom metadata IDs registered in this LLVMContext. void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; + + typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*>, + DenseMapInfo<unsigned> > NumeredTypesMapTy; + + /// findUsedStructTypes - Walk the entire module and find all of the + /// struct types that are in use, returning them in a vector. + void findUsedStructTypes(std::vector<StructType*> &StructTypes) const; + + /// getTypeByName - Return the type with the specified name, or null if there + /// is none by that name. + StructType *getTypeByName(StringRef Name) const; + /// @} /// @name Function Accessors /// @{ @@ -296,7 +311,7 @@ public: GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal = false) const; - /// getNamedGlobal - Return the first global variable in the module with the + /// getNamedGlobal - Return the global variable in the module with the /// specified name, of arbitrary type. This method returns null if a global /// with the specified name is not found. GlobalVariable *getNamedGlobal(StringRef Name) const { @@ -316,7 +331,7 @@ public: /// @name Global Alias Accessors /// @{ - /// getNamedAlias - Return the first global alias in the module with the + /// getNamedAlias - Return the global alias in the module with the /// specified name, of arbitrary type. This method returns null if a global /// with the specified name is not found. GlobalAlias *getNamedAlias(StringRef Name) const; @@ -325,12 +340,12 @@ public: /// @name Named Metadata Accessors /// @{ - /// getNamedMetadata - Return the first NamedMDNode in the module with the + /// getNamedMetadata - Return the NamedMDNode in the module with the /// specified name. This method returns null if a NamedMDNode with the /// specified name is not found. NamedMDNode *getNamedMetadata(const Twine &Name) const; - /// getOrInsertNamedMetadata - Return the first named MDNode in the module + /// getOrInsertNamedMetadata - Return the named MDNode in the module /// with the specified name. This method returns a new NamedMDNode if a /// NamedMDNode with the specified name is not found. NamedMDNode *getOrInsertNamedMetadata(StringRef Name); @@ -340,23 +355,6 @@ public: void eraseNamedMetadata(NamedMDNode *NMD); /// @} -/// @name Type Accessors -/// @{ - - /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If - /// there is already an entry for this name, true is returned and the symbol - /// table is not modified. - bool addTypeName(StringRef Name, const Type *Ty); - - /// getTypeName - If there is at least one entry in the symbol table for the - /// specified type, return it. - std::string getTypeName(const Type *Ty) const; - - /// getTypeByName - Return the type with the specified name in this module, or - /// null if there is none by that name. - const Type *getTypeByName(StringRef Name) const; - -/// @} /// @name Materialization /// @{ @@ -429,41 +427,26 @@ public: const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; } /// Get the Module's symbol table of global variable and function identifiers. ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; } - /// Get the symbol table of types - const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; } - /// Get the Module's symbol table of types - TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; } /// @} /// @name Global Variable Iteration /// @{ - /// Get an iterator to the first global variable global_iterator global_begin() { return GlobalList.begin(); } - /// Get a constant iterator to the first global variable const_global_iterator global_begin() const { return GlobalList.begin(); } - /// Get an iterator to the last global variable global_iterator global_end () { return GlobalList.end(); } - /// Get a constant iterator to the last global variable const_global_iterator global_end () const { return GlobalList.end(); } - /// Determine if the list of globals is empty. bool global_empty() const { return GlobalList.empty(); } /// @} /// @name Function Iteration /// @{ - /// Get an iterator to the first function. iterator begin() { return FunctionList.begin(); } - /// Get a constant iterator to the first function. const_iterator begin() const { return FunctionList.begin(); } - /// Get an iterator to the last function. iterator end () { return FunctionList.end(); } - /// Get a constant iterator to the last function. const_iterator end () const { return FunctionList.end(); } - /// Determine how many functions are in the Module's list of functions. size_t size() const { return FunctionList.size(); } - /// Determine if the list of functions is empty. bool empty() const { return FunctionList.empty(); } /// @} @@ -487,17 +470,11 @@ public: /// @name Alias Iteration /// @{ - /// Get an iterator to the first alias. alias_iterator alias_begin() { return AliasList.begin(); } - /// Get a constant iterator to the first alias. const_alias_iterator alias_begin() const { return AliasList.begin(); } - /// Get an iterator to the last alias. alias_iterator alias_end () { return AliasList.end(); } - /// Get a constant iterator to the last alias. const_alias_iterator alias_end () const { return AliasList.end(); } - /// Determine how many aliases are in the Module's list of aliases. size_t alias_size () const { return AliasList.size(); } - /// Determine if the list of aliases is empty. bool alias_empty() const { return AliasList.empty(); } @@ -505,24 +482,17 @@ public: /// @name Named Metadata Iteration /// @{ - /// Get an iterator to the first named metadata. named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); } - /// Get a constant iterator to the first named metadata. const_named_metadata_iterator named_metadata_begin() const { return NamedMDList.begin(); } - /// Get an iterator to the last named metadata. named_metadata_iterator named_metadata_end() { return NamedMDList.end(); } - /// Get a constant iterator to the last named metadata. const_named_metadata_iterator named_metadata_end() const { return NamedMDList.end(); } - /// Determine how many NamedMDNodes are in the Module's list of named - /// metadata. size_t named_metadata_size() const { return NamedMDList.size(); } - /// Determine if the list of named metadata is empty. bool named_metadata_empty() const { return NamedMDList.empty(); } @@ -530,11 +500,13 @@ public: /// @name Utility functions for printing and dumping Module objects /// @{ - /// Print the module to an output stream with AssemblyAnnotationWriter. + /// Print the module to an output stream with an optional + /// AssemblyAnnotationWriter. void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const; /// Dump the module to stderr (for debugging). void dump() const; + /// This function causes all the subinstructions to "let go" of all references /// that they are maintaining. This allows one to 'delete' a whole class at /// a time, even though there may be circular references... first all diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h new file mode 100644 index 0000000..cd092fd --- /dev/null +++ b/include/llvm/Object/Binary.h @@ -0,0 +1,67 @@ +//===- Binary.h - A generic binary file -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the Binary class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_BINARY_H +#define LLVM_OBJECT_BINARY_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Object/Error.h" + +namespace llvm { + +class MemoryBuffer; +class StringRef; + +namespace object { + +class Binary { +private: + Binary(); // = delete + Binary(const Binary &other); // = delete + + unsigned int TypeID; + +protected: + MemoryBuffer *Data; + + Binary(unsigned int Type, MemoryBuffer *Source); + + enum { + isArchive, + + // Object and children. + isObject, + isCOFF, + isELF, + isMachO, + lastObject + }; + +public: + virtual ~Binary(); + + StringRef getData() const; + StringRef getFileName() const; + + // Cast methods. + unsigned int getType() const { return TypeID; } + static inline bool classof(const Binary *v) { return true; } +}; + +error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); +error_code createBinary(StringRef Path, OwningPtr<Binary> &Result); + +} +} + +#endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h new file mode 100644 index 0000000..121f9e8 --- /dev/null +++ b/include/llvm/Object/COFF.h @@ -0,0 +1,117 @@ +//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the COFFObjectFile class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_COFF_H +#define LLVM_OBJECT_COFF_H + +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/COFF.h" +#include "llvm/Support/Endian.h" + +namespace llvm { +namespace object { + +struct coff_file_header { + support::ulittle16_t Machine; + support::ulittle16_t NumberOfSections; + support::ulittle32_t TimeDateStamp; + support::ulittle32_t PointerToSymbolTable; + support::ulittle32_t NumberOfSymbols; + support::ulittle16_t SizeOfOptionalHeader; + support::ulittle16_t Characteristics; +}; + +struct coff_symbol { + struct StringTableOffset { + support::ulittle32_t Zeroes; + support::ulittle32_t Offset; + }; + + union { + char ShortName[8]; + StringTableOffset Offset; + } Name; + + support::ulittle32_t Value; + support::little16_t SectionNumber; + + struct { + support::ulittle8_t BaseType; + support::ulittle8_t ComplexType; + } Type; + + support::ulittle8_t StorageClass; + support::ulittle8_t NumberOfAuxSymbols; +}; + +struct coff_section { + char Name[8]; + support::ulittle32_t VirtualSize; + support::ulittle32_t VirtualAddress; + support::ulittle32_t SizeOfRawData; + support::ulittle32_t PointerToRawData; + support::ulittle32_t PointerToRelocations; + support::ulittle32_t PointerToLinenumbers; + support::ulittle16_t NumberOfRelocations; + support::ulittle16_t NumberOfLinenumbers; + support::ulittle32_t Characteristics; +}; + +class COFFObjectFile : public ObjectFile { +private: + const coff_file_header *Header; + const coff_section *SectionTable; + const coff_symbol *SymbolTable; + const char *StringTable; + uint32_t StringTableSize; + + error_code getSection(int32_t index, + const coff_section *&Res) const; + error_code getString(uint32_t offset, StringRef &Res) const; + + const coff_symbol *toSymb(DataRefImpl Symb) const; + const coff_section *toSec(DataRefImpl Sec) const; + +protected: + virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; + virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; + virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; + + virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; + virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; + virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; + virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; + virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; + virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const; + +public: + COFFObjectFile(MemoryBuffer *Object, error_code &ec); + virtual symbol_iterator begin_symbols() const; + virtual symbol_iterator end_symbols() const; + virtual section_iterator begin_sections() const; + virtual section_iterator end_sections() const; + + virtual uint8_t getBytesInAddress() const; + virtual StringRef getFileFormatName() const; + virtual unsigned getArch() const; +}; + +} +} + +#endif diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h new file mode 100644 index 0000000..fbaf71c --- /dev/null +++ b/include/llvm/Object/Error.h @@ -0,0 +1,50 @@ +//===- Error.h - system_error extensions for Object -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This declares a new error_category for the Object library. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ERROR_H +#define LLVM_OBJECT_ERROR_H + +#include "llvm/Support/system_error.h" + +namespace llvm { +namespace object { + +const error_category &object_category(); + +struct object_error { +enum _ { + success = 0, + invalid_file_type, + parse_failed, + unexpected_eof +}; + _ v_; + + object_error(_ v) : v_(v) {} + explicit object_error(int v) : v_(_(v)) {} + operator int() const {return v_;} +}; + +inline error_code make_error_code(object_error e) { + return error_code(static_cast<int>(e), object_category()); +} + +} // end namespace object. + +template <> struct is_error_code_enum<object::object_error> : true_type { }; + +template <> struct is_error_code_enum<object::object_error::_> : true_type { }; + +} // end namespace llvm. + +#endif diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index eee9d44..98ac067 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -14,15 +14,14 @@ #ifndef LLVM_OBJECT_OBJECT_FILE_H #define LLVM_OBJECT_OBJECT_FILE_H +#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" #include <cstring> namespace llvm { - -class MemoryBuffer; -class StringRef; - namespace object { class ObjectFile; @@ -31,7 +30,7 @@ union DataRefImpl { struct { uint32_t a, b; } d; - intptr_t p; + uintptr_t p; }; static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { @@ -40,52 +39,80 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } +class RelocationRef { + DataRefImpl RelocationPimpl; + const ObjectFile *OwningObject; + +public: + RelocationRef() : OwningObject(NULL) { + std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); + } + + RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); + + bool operator==(const RelocationRef &Other) const; + + error_code getNext(RelocationRef &Result); +}; + /// SymbolRef - This is a value type class that represents a single symbol in /// the list of symbols in the object file. class SymbolRef { + friend class SectionRef; DataRefImpl SymbolPimpl; const ObjectFile *OwningObject; public: + SymbolRef() : OwningObject(NULL) { + std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); + } + SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); bool operator==(const SymbolRef &Other) const; - SymbolRef getNext() const; + error_code getNext(SymbolRef &Result) const; - StringRef getName() const; - uint64_t getAddress() const; - uint64_t getSize() const; + error_code getName(StringRef &Result) const; + error_code getAddress(uint64_t &Result) const; + error_code getSize(uint64_t &Result) const; /// Returns the ascii char that should be displayed in a symbol table dump via /// nm for this symbol. - char getNMTypeChar() const; + error_code getNMTypeChar(char &Result) const; /// Returns true for symbols that are internal to the object file format such /// as section symbols. - bool isInternal() const; + error_code isInternal(bool &Result) const; }; /// SectionRef - This is a value type class that represents a single section in /// the list of sections in the object file. class SectionRef { + friend class SymbolRef; DataRefImpl SectionPimpl; const ObjectFile *OwningObject; public: + SectionRef() : OwningObject(NULL) { + std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); + } + SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; - SectionRef getNext() const; + error_code getNext(SectionRef &Result) const; - StringRef getName() const; - uint64_t getAddress() const; - uint64_t getSize() const; - StringRef getContents() const; + error_code getName(StringRef &Result) const; + error_code getAddress(uint64_t &Result) const; + error_code getSize(uint64_t &Result) const; + error_code getContents(StringRef &Result) const; // FIXME: Move to the normalization layer when it's created. - bool isText() const; + error_code isText(bool &Result) const; + + error_code containsSymbol(SymbolRef S, bool &Result) const; }; const uint64_t UnknownAddressOrSize = ~0ULL; @@ -93,38 +120,44 @@ const uint64_t UnknownAddressOrSize = ~0ULL; /// ObjectFile - This class is the base class for all object file types. /// Concrete instances of this object are created by createObjectFile, which /// figure out which type to create. -class ObjectFile { +class ObjectFile : public Binary { private: ObjectFile(); // = delete ObjectFile(const ObjectFile &other); // = delete protected: - MemoryBuffer *MapFile; - const uint8_t *base; + ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec); - ObjectFile(MemoryBuffer *Object); + const uint8_t *base() const { + return reinterpret_cast<const uint8_t *>(Data->getBufferStart()); + } // These functions are for SymbolRef to call internally. The main goal of // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol // entry in the memory mapped object file. SymbolPimpl cannot contain any // virtual functions because then it could not point into the memory mapped // file. + // + // Implementations assume that the DataRefImpl is valid and has not been + // modified externally. It's UB otherwise. friend class SymbolRef; - virtual SymbolRef getSymbolNext(DataRefImpl Symb) const = 0; - virtual StringRef getSymbolName(DataRefImpl Symb) const = 0; - virtual uint64_t getSymbolAddress(DataRefImpl Symb) const = 0; - virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; - virtual char getSymbolNMTypeChar(DataRefImpl Symb) const = 0; - virtual bool isSymbolInternal(DataRefImpl Symb) const = 0; + virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; + virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0; + virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; + virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0; // Same as above for SectionRef. friend class SectionRef; - virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0; - virtual StringRef getSectionName(DataRefImpl Sec) const = 0; - virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0; - virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0; - virtual StringRef getSectionContents(DataRefImpl Sec) const = 0; - virtual bool isSectionText(DataRefImpl Sec) const = 0; + virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0; + virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0; + virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0; + virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0; + virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0; + virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const = 0; public: @@ -139,6 +172,10 @@ public: return &Current; } + const content_type &operator*() const { + return Current; + } + bool operator==(const content_iterator &other) const { return Current == other.Current; } @@ -147,8 +184,12 @@ public: return !(*this == other); } - content_iterator& operator++() { // Preincrement - Current = Current.getNext(); + content_iterator& increment(error_code &err) { + content_type next; + if (error_code ec = Current.getNext(next)) + err = ec; + else + Current = next; return *this; } }; @@ -156,8 +197,6 @@ public: typedef content_iterator<SymbolRef> symbol_iterator; typedef content_iterator<SectionRef> section_iterator; - virtual ~ObjectFile(); - virtual symbol_iterator begin_symbols() const = 0; virtual symbol_iterator end_symbols() const = 0; @@ -171,8 +210,6 @@ public: virtual StringRef getFileFormatName() const = 0; virtual /* Triple::ArchType */ unsigned getArch() const = 0; - StringRef getFilename() const; - /// @returns Pointer to ObjectFile subclass to handle this type of object. /// @param ObjectPath The path to the object file. ObjectPath.isObject must /// return true. @@ -180,12 +217,16 @@ public: static ObjectFile *createObjectFile(StringRef ObjectPath); static ObjectFile *createObjectFile(MemoryBuffer *Object); -private: + static inline bool classof(const Binary *v) { + return v->getType() >= isObject && + v->getType() < lastObject; + } + static inline bool classof(const ObjectFile *v) { return true; } + +public: static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); static ObjectFile *createELFObjectFile(MemoryBuffer *Object); static ObjectFile *createMachOObjectFile(MemoryBuffer *Object); - static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object); - static ObjectFile *createLibObjectFile(MemoryBuffer *Object); }; // Inline function definitions. @@ -197,28 +238,28 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const { return SymbolPimpl == Other.SymbolPimpl; } -inline SymbolRef SymbolRef::getNext() const { - return OwningObject->getSymbolNext(SymbolPimpl); +inline error_code SymbolRef::getNext(SymbolRef &Result) const { + return OwningObject->getSymbolNext(SymbolPimpl, Result); } -inline StringRef SymbolRef::getName() const { - return OwningObject->getSymbolName(SymbolPimpl); +inline error_code SymbolRef::getName(StringRef &Result) const { + return OwningObject->getSymbolName(SymbolPimpl, Result); } -inline uint64_t SymbolRef::getAddress() const { - return OwningObject->getSymbolAddress(SymbolPimpl); +inline error_code SymbolRef::getAddress(uint64_t &Result) const { + return OwningObject->getSymbolAddress(SymbolPimpl, Result); } -inline uint64_t SymbolRef::getSize() const { - return OwningObject->getSymbolSize(SymbolPimpl); +inline error_code SymbolRef::getSize(uint64_t &Result) const { + return OwningObject->getSymbolSize(SymbolPimpl, Result); } -inline char SymbolRef::getNMTypeChar() const { - return OwningObject->getSymbolNMTypeChar(SymbolPimpl); +inline error_code SymbolRef::getNMTypeChar(char &Result) const { + return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); } -inline bool SymbolRef::isInternal() const { - return OwningObject->isSymbolInternal(SymbolPimpl); +inline error_code SymbolRef::isInternal(bool &Result) const { + return OwningObject->isSymbolInternal(SymbolPimpl, Result); } @@ -232,28 +273,33 @@ inline bool SectionRef::operator==(const SectionRef &Other) const { return SectionPimpl == Other.SectionPimpl; } -inline SectionRef SectionRef::getNext() const { - return OwningObject->getSectionNext(SectionPimpl); +inline error_code SectionRef::getNext(SectionRef &Result) const { + return OwningObject->getSectionNext(SectionPimpl, Result); +} + +inline error_code SectionRef::getName(StringRef &Result) const { + return OwningObject->getSectionName(SectionPimpl, Result); } -inline StringRef SectionRef::getName() const { - return OwningObject->getSectionName(SectionPimpl); +inline error_code SectionRef::getAddress(uint64_t &Result) const { + return OwningObject->getSectionAddress(SectionPimpl, Result); } -inline uint64_t SectionRef::getAddress() const { - return OwningObject->getSectionAddress(SectionPimpl); +inline error_code SectionRef::getSize(uint64_t &Result) const { + return OwningObject->getSectionSize(SectionPimpl, Result); } -inline uint64_t SectionRef::getSize() const { - return OwningObject->getSectionSize(SectionPimpl); +inline error_code SectionRef::getContents(StringRef &Result) const { + return OwningObject->getSectionContents(SectionPimpl, Result); } -inline StringRef SectionRef::getContents() const { - return OwningObject->getSectionContents(SectionPimpl); +inline error_code SectionRef::isText(bool &Result) const { + return OwningObject->isSectionText(SectionPimpl, Result); } -inline bool SectionRef::isText() const { - return OwningObject->isSectionText(SectionPimpl); +inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { + return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, + Result); } } // end namespace object diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index 7ba6491..2e81490 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -19,15 +19,9 @@ namespace llvm { class raw_ostream; -class BranchProbabilityInfo; -class MachineBranchProbabilityInfo; -class MachineBasicBlock; // This class represents Branch Probability as a non-negative fraction. class BranchProbability { - friend class BranchProbabilityInfo; - friend class MachineBranchProbabilityInfo; - friend class MachineBasicBlock; // Numerator uint32_t N; @@ -35,9 +29,17 @@ class BranchProbability { // Denominator uint32_t D; +public: BranchProbability(uint32_t n, uint32_t d); -public: + uint32_t getNumerator() const { return N; } + uint32_t getDenominator() const { return D; } + + // Return (1 - Probability). + BranchProbability getCompl() { + return BranchProbability(D - N, D); + } + raw_ostream &print(raw_ostream &OS) const; void dump() const; diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index d2ea123..29313ef 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -33,7 +33,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag, USE_iterator It; inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example PHI nodes). + // Loop to ignore non terminator uses (for example BlockAddresses). while (!It.atEnd() && !isa<TerminatorInst>(*It)) ++It; } @@ -109,11 +109,18 @@ public: // TODO: This can be random access iterator, only operator[] missing. explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator - assert(T && "getTerminator returned null!"); } inline SuccIterator(Term_ T, bool) // end iterator - : Term(T), idx(Term->getNumSuccessors()) { - assert(T && "getTerminator returned null!"); + : Term(T) { + if (Term) + idx = Term->getNumSuccessors(); + else + // Term == NULL happens, if a basic block is not fully constructed and + // consequently getTerminator() returns NULL. In this case we construct a + // SuccIterator which describes a basic block that has zero successors. + // Defining SuccIterator for incomplete and malformed CFGs is especially + // useful for debugging. + idx = 0; } inline const Self &operator=(const Self &I) { @@ -201,6 +208,7 @@ public: /// Get the source BB of this iterator. inline BB_ *getSource() { + assert(Term && "Source not available, if basic block was malformed"); return Term->getParent(); } }; diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index d0eaa3e..7330235 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -210,14 +210,14 @@ public: return ConstantExpr::getShuffleVector(V1, V2, Mask); } - Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx); + Constant *CreateExtractValue(Constant *Agg, + ArrayRef<unsigned> IdxList) const { + return ConstantExpr::getExtractValue(Agg, IdxList); } Constant *CreateInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx) const { - return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx); + ArrayRef<unsigned> IdxList) const { + return ConstantExpr::getInsertValue(Agg, Val, IdxList); } }; diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index 98a05a4..2ee9f87 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -61,7 +61,10 @@ namespace llvm { /// getFromDILocation - Translate the DILocation quad into a DebugLoc. static DebugLoc getFromDILocation(MDNode *N); - + + /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc. + static DebugLoc getFromDILexicalBlock(MDNode *N); + /// isUnknown - Return true if this is an unknown location. bool isUnknown() const { return ScopeIdx == 0; } @@ -94,6 +97,8 @@ namespace llvm { return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx; } bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } + + void dump(const LLVMContext &Ctx) const; }; template <> diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index cc72bd5..be48112 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -487,11 +487,11 @@ enum { SHT_REL = 9, // Relocation entries; no explicit addends. SHT_SHLIB = 10, // Reserved. SHT_DYNSYM = 11, // Symbol table. - SHT_INIT_ARRAY = 14, // Pointers to initialisation functions. + SHT_INIT_ARRAY = 14, // Pointers to initialization functions. SHT_FINI_ARRAY = 15, // Pointers to termination functions. SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. SHT_GROUP = 17, // Section group. - SHT_SYMTAB_SHNDX = 18, // Indicies for SHN_XINDEX entries. + SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. SHT_LOOS = 0x60000000, // Lowest operating system-specific type. SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type. @@ -630,7 +630,7 @@ enum { STT_FUNC = 2, // Symbol is executable code (function, etc.) STT_SECTION = 3, // Symbol refers to a section STT_FILE = 4, // Local, absolute symbol that refers to a file - STT_COMMON = 5, // An uninitialised common block + STT_COMMON = 5, // An uninitialized common block STT_TLS = 6, // Thread local data object STT_LOPROC = 13, // Lowest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type @@ -804,7 +804,7 @@ enum { DT_RELENT = 19, // Size of a Rel relocation entry. DT_PLTREL = 20, // Type of relocation entry used for linking. DT_DEBUG = 21, // Reserved for debugger. - DT_TEXTREL = 22, // Relocations exist for non-writable segements. + DT_TEXTREL = 22, // Relocations exist for non-writable segments. DT_JMPREL = 23, // Address of relocations associated with PLT. DT_BIND_NOW = 24, // Process all relocations before execution. DT_INIT_ARRAY = 25, // Pointer to array of initialization functions. diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index f62eab0..af1b506 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -14,7 +14,6 @@ #ifndef LLVM_SUPPORT_ENDIAN_H #define LLVM_SUPPORT_ENDIAN_H -#include "llvm/Config/config.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 6a7c277..91cd78e 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -82,7 +82,7 @@ public: InsertPt = I; SetCurrentDebugLocation(I->getDebugLoc()); } - + /// SetInsertPoint - This specifies that created instructions should be /// inserted at the specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { @@ -90,6 +90,19 @@ public: InsertPt = IP; } + /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and + /// specify that created instructions should be inserted at this point. + void SetInsertPoint(Use &U) { + Instruction *UseInst = cast<Instruction>(U.getUser()); + if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) { + BasicBlock *PredBB = Phi->getIncomingBlock(U); + assert(U != PredBB->getTerminator() && "critical edge not split"); + SetInsertPoint(PredBB, PredBB->getTerminator()); + return; + } + SetInsertPoint(UseInst); + } + /// SetCurrentDebugLocation - Set location information used by debugging /// information. void SetCurrentDebugLocation(const DebugLoc &L) { @@ -98,7 +111,7 @@ public: /// getCurrentDebugLocation - Get location information used by debugging /// information. - const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } + DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; } /// SetInstDebugLocation - If this builder has a current debug location, set /// it on the specified instruction. @@ -109,8 +122,8 @@ public: /// getCurrentFunctionReturnType - Get the return type of the current function /// that we're emitting into. - const Type *getCurrentFunctionReturnType() const; - + Type *getCurrentFunctionReturnType() const; + /// InsertPoint - A saved insertion point. class InsertPoint { BasicBlock *Block; @@ -198,7 +211,7 @@ public: ConstantInt *getInt64(uint64_t C) { return ConstantInt::get(getInt64Ty(), C); } - + /// getInt - Get a constant integer value. ConstantInt *getInt(const APInt &AI) { return ConstantInt::get(Context, AI); @@ -209,46 +222,46 @@ public: //===--------------------------------------------------------------------===// /// getInt1Ty - Fetch the type representing a single bit - const IntegerType *getInt1Ty() { + IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); } /// getInt8Ty - Fetch the type representing an 8-bit integer. - const IntegerType *getInt8Ty() { + IntegerType *getInt8Ty() { return Type::getInt8Ty(Context); } /// getInt16Ty - Fetch the type representing a 16-bit integer. - const IntegerType *getInt16Ty() { + IntegerType *getInt16Ty() { return Type::getInt16Ty(Context); } /// getInt32Ty - Fetch the type resepresenting a 32-bit integer. - const IntegerType *getInt32Ty() { + IntegerType *getInt32Ty() { return Type::getInt32Ty(Context); } /// getInt64Ty - Fetch the type representing a 64-bit integer. - const IntegerType *getInt64Ty() { + IntegerType *getInt64Ty() { return Type::getInt64Ty(Context); } /// getFloatTy - Fetch the type representing a 32-bit floating point value. - const Type *getFloatTy() { + Type *getFloatTy() { return Type::getFloatTy(Context); } /// getDoubleTy - Fetch the type representing a 64-bit floating point value. - const Type *getDoubleTy() { + Type *getDoubleTy() { return Type::getDoubleTy(Context); } /// getVoidTy - Fetch the type representing void. - const Type *getVoidTy() { + Type *getVoidTy() { return Type::getVoidTy(Context); } - const PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { + PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { return Type::getInt8PtrTy(Context, AddrSpace); } @@ -263,7 +276,7 @@ public: bool isVolatile = false, MDNode *TBAATag = 0) { return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag); } - + CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0); @@ -274,7 +287,7 @@ public: bool isVolatile = false, MDNode *TBAATag = 0) { return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); } - + CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0); @@ -285,9 +298,9 @@ public: bool isVolatile = false, MDNode *TBAATag = 0) { return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); } - + CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, - bool isVolatile = false, MDNode *TBAATag = 0); + bool isVolatile = false, MDNode *TBAATag = 0); /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer /// isn't i8* it will be converted. @@ -341,7 +354,13 @@ public: SetInsertPoint(IP); SetCurrentDebugLocation(IP->getDebugLoc()); } - + + explicit IRBuilder(Use &U) + : IRBuilderBase(U->getContext()), Folder() { + SetInsertPoint(U); + SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); + } + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) : IRBuilderBase(TheBB->getContext()), Folder(F) { SetInsertPoint(TheBB, IP); @@ -430,34 +449,30 @@ public: InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, const Twine &Name = "") { - Value *Args[] = { 0 }; - return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, - Args), Name); + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, + ArrayRef<Value *>()), + Name); } InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, Value *Arg1, const Twine &Name = "") { - Value *Args[] = { Arg1 }; - return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, - Args+1), Name); + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1), + Name); } InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, Value *Arg1, Value *Arg2, Value *Arg3, const Twine &Name = "") { Value *Args[] = { Arg1, Arg2, Arg3 }; - return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, - Args+3), Name); + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), + Name); } /// CreateInvoke - Create an invoke instruction. - template<typename RandomAccessIterator> InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, - BasicBlock *UnwindDest, - RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, + BasicBlock *UnwindDest, ArrayRef<Value *> Args, const Twine &Name = "") { - return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, - ArgBegin, ArgEnd), Name); + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), + Name); } UnwindInst *CreateUnwind() { @@ -1107,33 +1122,27 @@ public: CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2, const Twine &Name = "") { Value *Args[] = { Arg1, Arg2 }; - return Insert(CallInst::Create(Callee, Args, Args+2), Name); + return Insert(CallInst::Create(Callee, Args), Name); } CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, const Twine &Name = "") { Value *Args[] = { Arg1, Arg2, Arg3 }; - return Insert(CallInst::Create(Callee, Args, Args+3), Name); + return Insert(CallInst::Create(Callee, Args), Name); } CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, Value *Arg4, const Twine &Name = "") { Value *Args[] = { Arg1, Arg2, Arg3, Arg4 }; - return Insert(CallInst::Create(Callee, Args, Args+4), Name); + return Insert(CallInst::Create(Callee, Args), Name); } CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, Value *Arg4, Value *Arg5, const Twine &Name = "") { Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 }; - return Insert(CallInst::Create(Callee, Args, Args+5), Name); + return Insert(CallInst::Create(Callee, Args), Name); } - CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Arg, + CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, const Twine &Name = "") { - return Insert(CallInst::Create(Callee, Arg.begin(), Arg.end(), Name)); - } - - template<typename RandomAccessIterator> - CallInst *CreateCall(Value *Callee, RandomAccessIterator ArgBegin, - RandomAccessIterator ArgEnd, const Twine &Name = "") { - return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name); + return Insert(CallInst::Create(Callee, Args, Name)); } Value *CreateSelect(Value *C, Value *True, Value *False, @@ -1175,43 +1184,21 @@ public: return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } - Value *CreateExtractValue(Value *Agg, unsigned Idx, - const Twine &Name = "") { - if (Constant *AggC = dyn_cast<Constant>(Agg)) - return Insert(Folder.CreateExtractValue(AggC, &Idx, 1), Name); - return Insert(ExtractValueInst::Create(Agg, Idx), Name); - } - - template<typename RandomAccessIterator> Value *CreateExtractValue(Value *Agg, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) - return Insert(Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd-IdxBegin), - Name); - return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name); + return Insert(Folder.CreateExtractValue(AggC, Idxs), Name); + return Insert(ExtractValueInst::Create(Agg, Idxs), Name); } - Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx, - const Twine &Name = "") { - if (Constant *AggC = dyn_cast<Constant>(Agg)) - if (Constant *ValC = dyn_cast<Constant>(Val)) - return Insert(Folder.CreateInsertValue(AggC, ValC, &Idx, 1), Name); - return Insert(InsertValueInst::Create(Agg, Val, Idx), Name); - } - - template<typename RandomAccessIterator> Value *CreateInsertValue(Value *Agg, Value *Val, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef<unsigned> Idxs, const Twine &Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) if (Constant *ValC = dyn_cast<Constant>(Val)) - return Insert(Folder.CreateInsertValue(AggC, ValC, IdxBegin, - IdxEnd - IdxBegin), - Name); - return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name); + return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name); + return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); } //===--------------------------------------------------------------------===// @@ -1238,7 +1225,7 @@ public: Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { assert(LHS->getType() == RHS->getType() && "Pointer subtraction operand types must match!"); - const PointerType *ArgType = cast<PointerType>(LHS->getType()); + PointerType *ArgType = cast<PointerType>(LHS->getType()); Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); Value *Difference = CreateSub(LHS_int, RHS_int); diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 5ead26e..94359a5 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -22,6 +22,7 @@ #ifndef LLVM_SUPPORT_NOFOLDER_H #define LLVM_SUPPORT_NOFOLDER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" @@ -269,15 +270,14 @@ public: return new ShuffleVectorInst(V1, V2, Mask); } - Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList, - unsigned NumIdx) const { - return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx); + Instruction *CreateExtractValue(Constant *Agg, + ArrayRef<unsigned> IdxList) const { + return ExtractValueInst::Create(Agg, IdxList); } Instruction *CreateInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, - unsigned NumIdx) const { - return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx); + ArrayRef<unsigned> IdxList) const { + return InsertValueInst::Create(Agg, Val, IdxList); } }; diff --git a/include/llvm/Support/PassManagerBuilder.h b/include/llvm/Support/PassManagerBuilder.h index 513bb88..b0cec6e 100644 --- a/include/llvm/Support/PassManagerBuilder.h +++ b/include/llvm/Support/PassManagerBuilder.h @@ -67,7 +67,12 @@ public: /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to /// the end of the loop optimizer. - EP_LoopOptimizerEnd + EP_LoopOptimizerEnd, + + /// EP_ScalarOptimizerLate - This extension point allows adding optimization + /// passes after most of the main optimizations, but before the last + /// cleanup-ish optimizations. + EP_ScalarOptimizerLate }; /// The Optimization Level - Specify the basic optimization level. @@ -147,6 +152,7 @@ public: FPM.add(createCFGSimplificationPass()); FPM.add(createScalarReplAggregatesPass()); FPM.add(createEarlyCSEPass()); + FPM.add(createLowerExpectIntrinsicPass()); } /// populateModulePassManager - This sets up the primary pass manager. @@ -223,13 +229,16 @@ public: MPM.add(createJumpThreadingPass()); // Thread jumps MPM.add(createCorrelatedValuePropagationPass()); MPM.add(createDeadStoreEliminationPass()); // Delete dead stores + + addExtensionsToPM(EP_ScalarOptimizerLate, MPM); + MPM.add(createAggressiveDCEPass()); // Delete dead instructions MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createInstructionCombiningPass()); // Clean up after everything. if (!DisableUnitAtATime) { + // FIXME: We shouldn't bother with this anymore. MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - MPM.add(createDeadTypeEliminationPass()); // Eliminate dead types // GlobalOpt already deletes dead functions and globals, at -O3 try a // late pass of GlobalDCE. It is capable of deleting dead cycles. diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 20ca557..3233a98 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -21,6 +21,7 @@ #include "llvm/Constants.h" #include "llvm/InstrTypes.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Analysis/ConstantFolding.h" namespace llvm { @@ -226,14 +227,14 @@ public: return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); } - Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx)); + Constant *CreateExtractValue(Constant *Agg, + ArrayRef<unsigned> IdxList) const { + return Fold(ConstantExpr::getExtractValue(Agg, IdxList)); } Constant *CreateInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx) const { - return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx)); + ArrayRef<unsigned> IdxList) const { + return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList)); } }; diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index ea63da0..1800778 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" #include <limits.h> +#include <vector> namespace llvm { @@ -50,7 +51,7 @@ namespace llvm { /// namespace llvm { /// template<bool xcompile> class TypeBuilder<MyType, xcompile> { /// public: -/// static const StructType *get(LLVMContext &Context) { +/// static StructType *get(LLVMContext &Context) { /// // If you cache this result, be sure to cache it separately /// // for each LLVMContext. /// return StructType::get( @@ -103,7 +104,7 @@ template<typename T, bool cross> class TypeBuilder<const volatile T, cross> // Pointers template<typename T, bool cross> class TypeBuilder<T*, cross> { public: - static const PointerType *get(LLVMContext &Context) { + static PointerType *get(LLVMContext &Context) { return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); } }; @@ -114,14 +115,14 @@ template<typename T, bool cross> class TypeBuilder<T&, cross> {}; // Arrays template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { public: - static const ArrayType *get(LLVMContext &Context) { + static ArrayType *get(LLVMContext &Context) { return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); } }; /// LLVM uses an array of length 0 to represent an unknown-length array. template<typename T, bool cross> class TypeBuilder<T[], cross> { public: - static const ArrayType *get(LLVMContext &Context) { + static ArrayType *get(LLVMContext &Context) { return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); } }; @@ -151,7 +152,7 @@ public: #define DEFINE_INTEGRAL_TYPEBUILDER(T) \ template<> class TypeBuilder<T, false> { \ public: \ - static const IntegerType *get(LLVMContext &Context) { \ + static IntegerType *get(LLVMContext &Context) { \ return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ } \ }; \ @@ -180,14 +181,14 @@ DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); template<uint32_t num_bits, bool cross> class TypeBuilder<types::i<num_bits>, cross> { public: - static const IntegerType *get(LLVMContext &C) { + static IntegerType *get(LLVMContext &C) { return IntegerType::get(C, num_bits); } }; template<> class TypeBuilder<float, false> { public: - static const Type *get(LLVMContext& C) { + static Type *get(LLVMContext& C) { return Type::getFloatTy(C); } }; @@ -195,7 +196,7 @@ template<> class TypeBuilder<float, true> {}; template<> class TypeBuilder<double, false> { public: - static const Type *get(LLVMContext& C) { + static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } }; @@ -203,32 +204,32 @@ template<> class TypeBuilder<double, true> {}; template<bool cross> class TypeBuilder<types::ieee_float, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getFloatTy(C); } + static Type *get(LLVMContext& C) { return Type::getFloatTy(C); } }; template<bool cross> class TypeBuilder<types::ieee_double, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } + static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } }; template<bool cross> class TypeBuilder<types::x86_fp80, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } + static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } }; template<bool cross> class TypeBuilder<types::fp128, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } + static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } }; template<bool cross> class TypeBuilder<types::ppc_fp128, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } + static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } }; template<bool cross> class TypeBuilder<types::x86_mmx, cross> { public: - static const Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); } + static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); } }; template<bool cross> class TypeBuilder<void, cross> { public: - static const Type *get(LLVMContext &C) { + static Type *get(LLVMContext &C) { return Type::getVoidTy(C); } }; @@ -246,14 +247,14 @@ template<> class TypeBuilder<const volatile void*, false> template<typename R, bool cross> class TypeBuilder<R(), cross> { public: - static const FunctionType *get(LLVMContext &Context) { + static FunctionType *get(LLVMContext &Context) { return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); } }; template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(1); params.push_back(TypeBuilder<A1, cross>::get(Context)); return FunctionType::get(TypeBuilder<R, cross>::get(Context), @@ -263,8 +264,8 @@ public: template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(2); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -275,8 +276,8 @@ public: template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(3); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -290,8 +291,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, bool cross> class TypeBuilder<R(A1, A2, A3, A4), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(4); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -306,8 +307,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, bool cross> class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(5); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -321,15 +322,15 @@ public: template<typename R, bool cross> class TypeBuilder<R(...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { + static FunctionType *get(LLVMContext &Context) { return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); } }; template<typename R, typename A1, bool cross> class TypeBuilder<R(A1, ...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(1); params.push_back(TypeBuilder<A1, cross>::get(Context)); return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); @@ -338,8 +339,8 @@ public: template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2, ...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(2); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -350,8 +351,8 @@ public: template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3, ...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(3); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -365,8 +366,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, bool cross> class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(4); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); @@ -381,8 +382,8 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, bool cross> class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { public: - static const FunctionType *get(LLVMContext &Context) { - std::vector<const Type*> params; + static FunctionType *get(LLVMContext &Context) { + std::vector<Type*> params; params.reserve(5); params.push_back(TypeBuilder<A1, cross>::get(Context)); params.push_back(TypeBuilder<A2, cross>::get(Context)); diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h index 47759b9..2c15b69 100644 --- a/include/llvm/Support/system_error.h +++ b/include/llvm/Support/system_error.h @@ -222,7 +222,7 @@ template <> struct hash<std::error_code>; */ -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/type_traits.h" #include <cerrno> #include <string> @@ -669,7 +669,7 @@ const error_category& generic_category(); const error_category& system_category(); /// Get the error_category used for errno values from POSIX functions. This is -/// the same as the system_category on POISIX systems, but is the same as the +/// the same as the system_category on POSIX systems, but is the same as the /// generic_category on Windows. const error_category& posix_category(); diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index ab6a4e2..018ccbd 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -26,11 +26,19 @@ class SubRegIndex { string Namespace = ""; } +// RegAltNameIndex - The alternate name set to use for register operands of +// this register class when printing. +class RegAltNameIndex { + string Namespace = ""; +} +def NoRegAltName : RegAltNameIndex; + // Register - You should define one instance of this class for each register // in the target machine. String n will become the "name" of the register. -class Register<string n> { +class Register<string n, list<string> altNames = []> { string Namespace = ""; string AsmName = n; + list<string> AltNames = altNames; // Aliases - A list of registers that this register overlaps with. A read or // modification of this register can potentially read or modify the aliased @@ -48,6 +56,10 @@ class Register<string n> { // SubRegs. list<SubRegIndex> SubRegIndices = []; + // RegAltNameIndices - The alternate name indices which are valid for this + // register. + list<RegAltNameIndex> RegAltNameIndices = []; + // CompositeIndices - Specify subreg indices that don't correspond directly to // a register in SubRegs and are not inherited. The following formats are // supported: @@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> { // registers by register allocators. // class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, - list<Register> regList> { + dag regList, RegAltNameIndex idx = NoRegAltName> { string Namespace = namespace; // RegType - Specify the list ValueType of the registers in this register @@ -122,7 +134,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, // allocation_order_* method are not specified, this also defines the order of // allocation used by the register allocator. // - list<Register> MemberList = regList; + dag MemberList = regList; + + // AltNameIndex - The alternate register name to use when printing operands + // of this register class. Every register in the register class must have + // a valid alternate name for the given index. + RegAltNameIndex altNameIndex = idx; // SubRegClasses - Specify the register class of subregisters as a list of // dags: (RegClass SubRegIndex, SubRegindex, ...) @@ -133,11 +150,91 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, // model instruction operand constraints, and should have isAllocatable = 0. bit isAllocatable = 1; - // MethodProtos/MethodBodies - These members can be used to insert arbitrary - // code into a generated register class. The normal usage of this is to - // overload virtual methods. - code MethodProtos = [{}]; - code MethodBodies = [{}]; + // AltOrders - List of alternative allocation orders. The default order is + // MemberList itself, and that is good enough for most targets since the + // register allocators automatically remove reserved registers and move + // callee-saved registers to the end. + list<dag> AltOrders = []; + + // AltOrderSelect - The body of a function that selects the allocation order + // to use in a given machine function. The code will be inserted in a + // function like this: + // + // static inline unsigned f(const MachineFunction &MF) { ... } + // + // The function should return 0 to select the default order defined by + // MemberList, 1 to select the first AltOrders entry and so on. + code AltOrderSelect = [{}]; +} + +// The memberList in a RegisterClass is a dag of set operations. TableGen +// evaluates these set operations and expand them into register lists. These +// are the most common operation, see test/TableGen/SetTheory.td for more +// examples of what is possible: +// +// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a +// register class, or a sub-expression. This is also the way to simply list +// registers. +// +// (sub GPR, SP) - Set difference. Subtract the last arguments from the first. +// +// (and GPR, CSR) - Set intersection. All registers from the first set that are +// also in the second set. +// +// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of +// numbered registers. +// +// (shl GPR, 4) - Remove the first N elements. +// +// (trunc GPR, 4) - Truncate after the first N elements. +// +// (rotl GPR, 1) - Rotate N places to the left. +// +// (rotr GPR, 1) - Rotate N places to the right. +// +// (decimate GPR, 2) - Pick every N'th element, starting with the first. +// +// All of these operators work on ordered sets, not lists. That means +// duplicates are removed from sub-expressions. + +// Set operators. The rest is defined in TargetSelectionDAG.td. +def sequence; +def decimate; + +// RegisterTuples - Automatically generate super-registers by forming tuples of +// sub-registers. This is useful for modeling register sequence constraints +// with pseudo-registers that are larger than the architectural registers. +// +// The sub-register lists are zipped together: +// +// def EvenOdd : RegisterTuples<[sube, subo], [(add R0, R2), (add R1, R3)]>; +// +// Generates the same registers as: +// +// let SubRegIndices = [sube, subo] in { +// def R0_R1 : RegisterWithSubRegs<"", [R0, R1]>; +// def R2_R3 : RegisterWithSubRegs<"", [R2, R3]>; +// } +// +// The generated pseudo-registers inherit super-classes and fields from their +// first sub-register. Most fields from the Register class are inferred, and +// the AsmName and Dwarf numbers are cleared. +// +// RegisterTuples instances can be used in other set operations to form +// register classes and so on. This is the only way of using the generated +// registers. +class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> { + // SubRegs - N lists of registers to be zipped up. Super-registers are + // synthesized from the first element of each SubRegs list, the second + // element and so on. + list<dag> SubRegs = Regs; + + // SubRegIndices - N SubRegIndex instances. This provides the names of the + // sub-registers in the synthesized super-registers. + list<SubRegIndex> SubRegIndices = Indices; + + // Compose sub-register indices like in a normal Register. + list<dag> CompositeIndices = []; } @@ -196,7 +293,12 @@ class Instruction { // code. list<Predicate> Predicates = []; - // Code size. + // Size - Size of encoded instruction, or zero if the size cannot be determined + // from the opcode. + int Size = 0; + + // Code size, for instruction selection. + // FIXME: What does this actually mean? int CodeSize = 0; // Added complexity passed onto matching pattern. @@ -227,6 +329,9 @@ class Instruction { bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? + bit isPseudo = 0; // Is this instruction a pseudo-instruction? + // If so, won't have encoding information for + // the [MC]CodeEmitter stuff. // Side effect flags - When set, the flags have these meanings: // @@ -241,6 +346,11 @@ class Instruction { // Is this instruction a "real" instruction (with a distinct machine // encoding), or is it a pseudo instruction used for codegen modeling // purposes. + // FIXME: For now this is distinct from isPseudo, above, as code-gen-only + // instructions can (and often do) still have encoding information + // associated with them. Once we've migrated all of them over to true + // pseudo-instructions that are lowered to real instructions prior to + // the printer/emitter, we can remove this attribute and just use isPseudo. bit isCodeGenOnly = 0; // Is this instruction a pseudo instruction for use by the assembler parser. @@ -268,6 +378,14 @@ class Instruction { ///@} } +/// PseudoInstExpansion - Expansion information for a pseudo-instruction. +/// Which instruction it expands to and how the operands map from the +/// pseudo. +class PseudoInstExpansion<dag Result> { + dag ResultInst = Result; // The instruction to generate. + bit isPseudo = 1; +} + /// Predicates - These are extra conditionals which are turned into instruction /// selector matching code. Currently each predicate is just a string. class Predicate<string cond> { @@ -277,6 +395,15 @@ class Predicate<string cond> { /// matcher, this is true. Targets should set this by inheriting their /// feature from the AssemblerPredicate class in addition to Predicate. bit AssemblerMatcherPredicate = 0; + + /// AssemblerCondString - Name of the subtarget feature being tested used + /// as alternative condition string used for assembler matcher. + /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0". + /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0". + /// It can also list multiple features separated by ",". + /// e.g. "ModeThumb,FeatureThumb2" is translated to + /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0". + string AssemblerCondString = ""; } /// NoHonorSignDependentRounding - This predicate is true if support for @@ -373,6 +500,7 @@ class Operand<ValueType ty> { string EncoderMethod = ""; string DecoderMethod = ""; string AsmOperandLowerMethod = ?; + string OperandType = "OPERAND_UNKNOWN"; dag MIOperandInfo = (ops); // ParserMatchClass - The "match class" that operands of this type fit @@ -386,6 +514,25 @@ class Operand<ValueType ty> { AsmOperandClass ParserMatchClass = ImmAsmOperand; } +class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> { + // RegClass - The register class of the operand. + RegisterClass RegClass = regclass; + // PrintMethod - The target method to call to print register operands of + // this type. The method normally will just use an alt-name index to look + // up the name to print. Default to the generic printOperand(). + string PrintMethod = pm; + // ParserMatchClass - The "match class" that operands of this type fit + // in. Match classes are used to define the order in which instructions are + // match, to ensure that which instructions gets matched is deterministic. + // + // The target specific parser must be able to classify an parsed operand into + // a unique class, which does not partially overlap with any other classes. It + // can match a subset of some other class, in which case the AsmOperandClass + // should declare the other operand as one of its super classes. + AsmOperandClass ParserMatchClass; +} + +let OperandType = "OPERAND_IMMEDIATE" in { def i1imm : Operand<i1>; def i8imm : Operand<i8>; def i16imm : Operand<i16>; @@ -394,6 +541,7 @@ def i64imm : Operand<i64>; def f32imm : Operand<f32>; def f64imm : Operand<f64>; +} /// zero_reg definition - Special node to stand for the zero register. /// @@ -566,8 +714,9 @@ def DefaultAsmParser : AsmParser; /// AssemblerPredicate - This is a Predicate that can be used when the assembler /// matches instructions and aliases. -class AssemblerPredicate { +class AssemblerPredicate<string cond> { bit AssemblerMatcherPredicate = 1; + string AssemblerCondString = cond; } diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 743a2d4..5a526dc 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -20,6 +20,7 @@ #include "llvm/Target/TargetRegisterInfo.h" namespace llvm { + template <typename T> class ArrayRef; class MCSection; class MCContext; class MachineFunction; @@ -27,30 +28,14 @@ namespace llvm { class TargetLoweringObjectFile; class TargetAsmInfo { - unsigned PointerSize; - bool IsLittleEndian; - TargetFrameLowering::StackDirection StackDir; - const TargetRegisterInfo *TRI; std::vector<MachineMove> InitialFrameState; + const TargetRegisterInfo *TRI; + const TargetFrameLowering *TFI; const TargetLoweringObjectFile *TLOF; public: explicit TargetAsmInfo(const TargetMachine &TM); - /// getPointerSize - Get the pointer size in bytes. - unsigned getPointerSize() const { - return PointerSize; - } - - /// islittleendian - True if the target is little endian. - bool isLittleEndian() const { - return IsLittleEndian; - } - - TargetFrameLowering::StackDirection getStackGrowthDirection() const { - return StackDir; - } - const MCSection *getDwarfLineSection() const { return TLOF->getDwarfLineSection(); } @@ -59,6 +44,10 @@ public: return TLOF->getEHFrameSection(); } + const MCSection *getCompactUnwindSection() const { + return TLOF->getCompactUnwindSection(); + } + const MCSection *getDwarfFrameSection() const { return TLOF->getDwarfFrameSection(); } @@ -79,6 +68,12 @@ public: return TLOF->isFunctionEHFrameSymbolPrivate(); } + int getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs, + int DataAlignmentFactor, + bool IsEH) const { + return TFI->getCompactUnwindEncoding(Instrs, DataAlignmentFactor, IsEH); + } + const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { return TRI->getCalleeSavedRegs(MF); } diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 9ff50cb..df84231 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -15,7 +15,6 @@ namespace llvm { class MCStreamer; class StringRef; -class Target; class SMLoc; class AsmToken; class MCParsedAsmOperand; @@ -26,23 +25,19 @@ class TargetAsmParser : public MCAsmParserExtension { TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetAsmParser(const Target &); + TargetAsmParser(); - /// The Target that this machine was created for. - const Target &TheTarget; - - /// The current set of available features. + /// AvailableFeatures - The current set of available features. unsigned AvailableFeatures; public: virtual ~TargetAsmParser(); - const Target &getTarget() const { return TheTarget; } - unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } - virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) = 0; /// ParseInstruction - Parse one assembly instruction. /// diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 32e3e2b..c280810 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -259,7 +259,7 @@ public: /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. /// - const IntegerType *getIntPtrType(LLVMContext &C) const; + IntegerType *getIntPtrType(LLVMContext &C) const; /// getIndexedOffset - return the offset from the beginning of the type for /// the specified indices. This is used to implement getelementptr. @@ -272,12 +272,6 @@ public: /// information is lazily cached. const StructLayout *getStructLayout(const StructType *Ty) const; - /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout - /// objects. If a TargetData object is alive when types are being refined and - /// removed, this method must be called whenever a StructType is removed to - /// avoid a dangling pointer in this cache. - void InvalidateStructLayoutInfo(const StructType *Ty) const; - /// getPreferredAlignment - Return the preferred alignment of the specified /// global. This includes an explicitly requested alignment (if the global /// has one). diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index e104b16..e3d77cf 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -15,6 +15,8 @@ #define LLVM_TARGET_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/ADT/ArrayRef.h" #include <utility> #include <vector> @@ -189,6 +191,14 @@ public: /// virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const { } + + /// getCompactUnwindEncoding - Get the compact unwind encoding for the + /// function. Return 0 if the compact unwind isn't available. + virtual uint32_t getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs, + int DataAlignmentFactor, + bool IsEH) const { + return 0; + } }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 418f3fe..f663566 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -14,7 +14,7 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H -#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/CodeGen/MachineFunction.h" namespace llvm { @@ -32,6 +32,7 @@ class SelectionDAG; class ScheduleDAG; class TargetRegisterClass; class TargetRegisterInfo; +class BranchProbability; template<class T> class SmallVectorImpl; @@ -40,25 +41,22 @@ template<class T> class SmallVectorImpl; /// /// TargetInstrInfo - Interface to description of machine instruction set /// -class TargetInstrInfo { - const TargetInstrDesc *Descriptors; // Raw array to allow static init'n - unsigned NumOpcodes; // Number of entries in the desc array - +class TargetInstrInfo : public MCInstrInfo { TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT public: - TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes); + TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1) + : CallFrameSetupOpcode(CFSetupOpcode), + CallFrameDestroyOpcode(CFDestroyOpcode) { + } + virtual ~TargetInstrInfo(); - unsigned getNumOpcodes() const { return NumOpcodes; } - - /// get - Return the machine instruction descriptor that corresponds to the - /// specified instruction opcode. - /// - const TargetInstrDesc &get(unsigned Opcode) const { - assert(Opcode < NumOpcodes && "Invalid opcode!"); - return Descriptors[Opcode]; - } + /// getRegClass - Givem a machine instruction descriptor, returns the register + /// class constraint for OpNum, or NULL. + const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, + unsigned OpNum, + const TargetRegisterInfo *TRI) const; /// isTriviallyReMaterializable - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands @@ -93,6 +91,15 @@ private: AliasAnalysis *AA) const; public: + /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the + /// frame setup/destroy instructions if they exist (-1 otherwise). Some + /// targets use pseudo instructions in order to abstract away the difference + /// between operating with a frame pointer and operating without, through the + /// use of these two instructions. + /// + int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; } + int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } + /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" /// extension instruction. That is, it's like a copy where it's legal for the /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns @@ -315,7 +322,7 @@ public: virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, unsigned ExtraPredCycles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -330,7 +337,7 @@ public: unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -342,7 +349,7 @@ public: /// will be properly predicted. virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -663,6 +670,9 @@ public: virtual bool hasLowDefLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx) const; + +private: + int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; /// TargetInstrInfoImpl - This is the default implementation of @@ -671,8 +681,9 @@ public: /// libcodegen, not in libtarget. class TargetInstrInfoImpl : public TargetInstrInfo { protected: - TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) - : TargetInstrInfo(desc, NumOpcodes) {} + TargetInstrInfoImpl(int CallFrameSetupOpcode = -1, + int CallFrameDestroyOpcode = -1) + : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {} public: virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest) const; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3e36fb7..533c3ac 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1421,13 +1421,6 @@ public: /// is for this target. virtual ConstraintType getConstraintType(const std::string &Constraint) const; - /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"), - /// return a list of registers that can be used to satisfy the constraint. - /// This should only be used for C_RegisterClass constraints. - virtual std::vector<unsigned> - getRegClassForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; - /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. /// {edx}), return the register number and the register class for the /// register. @@ -1547,6 +1540,8 @@ public: //===--------------------------------------------------------------------===// // Div utility functions // + SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, + SelectionDAG &DAG) const; SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, std::vector<SDNode*>* Created) const; SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, @@ -1836,9 +1831,8 @@ private: // Build a new vector type and check if it is legal. MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); - // Found a legal promoted vector type. - if (ValueTypeActions.getTypeAction(NVT) == TypeLegal) + if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal) return LegalizeKind(TypePromoteInteger, EVT::getVectorVT(Context, EltVT, NumElts)); } @@ -1853,6 +1847,7 @@ private: // If there is no simple vector type with this many elements then there // cannot be a larger legal vector type. Note that this assumes that // there are no skipped intermediate vector types in the simple types. + if (!EltVT.isSimple()) break; MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); if (LargerVector == MVT()) break; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 3991035..2e1d6b9 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -68,6 +68,11 @@ protected: /// LSDASection - If exception handling is supported by the target, this is /// the section the Language Specific Data Area information is emitted to. const MCSection *LSDASection; + + /// CompactUnwindSection - If exception handling is supported by the target + /// and the target can support a compact representation of the CIE and FDE, + /// this is the section to emit them into. + const MCSection *CompactUnwindSection; // Dwarf sections for debug info. If a target supports debug info, these must // be set. @@ -102,8 +107,8 @@ protected: /// private linkage, aka an L or .L label) or false if it should be a normal /// non-.globl label. This defaults to true. bool IsFunctionEHFrameSymbolPrivate; + public: - MCContext &getContext() const { return *Ctx; } virtual ~TargetLoweringObjectFile(); @@ -121,7 +126,6 @@ public: bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; } - bool getCommDirectiveSupportsAlignment() const { return CommDirectiveSupportsAlignment; } @@ -132,6 +136,7 @@ public: const MCSection *getStaticCtorSection() const { return StaticCtorSection; } const MCSection *getStaticDtorSection() const { return StaticDtorSection; } const MCSection *getLSDASection() const { return LSDASection; } + const MCSection *getCompactUnwindSection() const{return CompactUnwindSection;} virtual const MCSection *getEHFrameSection() const = 0; virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 78f770c..ac41a58 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,29 +14,30 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H -#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> namespace llvm { -class Target; +class InstrItineraryData; +class JITCodeEmitter; class MCAsmInfo; +class MCContext; +class Pass; +class PassManager; +class PassManagerBase; +class Target; class TargetData; -class TargetSubtarget; +class TargetELFWriterInfo; +class TargetFrameLowering; class TargetInstrInfo; class TargetIntrinsicInfo; class TargetJITInfo; class TargetLowering; -class TargetSelectionDAGInfo; -class TargetFrameLowering; -class JITCodeEmitter; -class MCContext; class TargetRegisterInfo; -class PassManagerBase; -class PassManager; -class Pass; -class TargetELFWriterInfo; +class TargetSelectionDAGInfo; +class TargetSubtargetInfo; class formatted_raw_ostream; class raw_ostream; @@ -91,15 +92,22 @@ class TargetMachine { TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT void operator=(const TargetMachine &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetMachine(const Target &); + TargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); /// getSubtargetImpl - virtual method implemented by subclasses that returns - /// a reference to that target's TargetSubtarget-derived member variable. - virtual const TargetSubtarget *getSubtargetImpl() const { return 0; } + /// a reference to that target's TargetSubtargetInfo-derived member variable. + virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; } /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target + /// feature strings the TargetMachine instance is created with. + std::string TargetTriple; + std::string TargetCPU; + std::string TargetFS; + /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; @@ -115,6 +123,10 @@ public: const Target &getTarget() const { return TheTarget; } + const StringRef getTargetTriple() const { return TargetTriple; } + const StringRef getTargetCPU() const { return TargetCPU; } + const StringRef getTargetFeatureString() const { return TargetFS; } + // Interfaces to the major aspects of target machine information: // -- Instruction opcode and operand information // -- Pipelines and scheduling information @@ -132,7 +144,7 @@ public: const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; } /// getSubtarget - This method returns a pointer to the specified type of - /// TargetSubtarget. In debug builds, it verifies that the object being + /// TargetSubtargetInfo. In debug builds, it verifies that the object being /// returned is of the correct type. template<typename STC> const STC &getSubtarget() const { return *static_cast<const STC*>(getSubtargetImpl()); @@ -295,10 +307,9 @@ public: /// implemented with the LLVM target-independent code generator. /// class LLVMTargetMachine : public TargetMachine { - std::string TargetTriple; - protected: // Can only create subclasses. - LLVMTargetMachine(const Target &T, const std::string &TargetTriple); + LLVMTargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); private: /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for @@ -311,9 +322,6 @@ private: virtual void setCodeModelForStatic(); public: - - const std::string &getTargetTriple() const { return TargetTriple; } - /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. If OptLevel is None, the code generator should emit code as diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 01fba66..37f7b2f 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -71,6 +71,10 @@ namespace TargetOpcode { /// REG_SEQUENCE - This variadic instruction is used to form a register that /// represent a consecutive sequence of sub-registers. It's used as register /// coalescing / allocation aid and must be eliminated before code emission. + // In SDNode form, the first operand encodes the register class created by + // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index + // pair. Once it has been lowered to a MachineInstr, the regclass operand + // is no longer present. /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 /// After register coalescing references of v1024 should be replace with /// v1027:3, v1025 with v1027:4, etc. diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index beed039..55d50d9 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -133,8 +133,8 @@ namespace llvm { /// as their parent function, etc.), using an alternate ABI if necessary. extern bool GuaranteedTailCallOpt; - /// StackAlignment - Override default stack alignment for target. - extern unsigned StackAlignment; + /// StackAlignmentOverride - Override default stack alignment for target. + extern unsigned StackAlignmentOverride; /// RealignStack - This flag indicates whether the stack should be /// automatically realigned, if needed. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index f6a8414..8d827f1 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -16,8 +16,10 @@ #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/ADT/DenseSet.h" #include <cassert> #include <functional> @@ -26,30 +28,10 @@ namespace llvm { class BitVector; class MachineFunction; -class MachineMove; class RegScavenger; template<class T> class SmallVectorImpl; class raw_ostream; -/// TargetRegisterDesc - This record contains all of the information known about -/// a particular register. The Overlaps field contains a pointer to a zero -/// terminated array of registers that this register aliases, starting with -/// itself. This is needed for architectures like X86 which have AL alias AX -/// alias EAX. The SubRegs field is a zero terminated array of registers that -/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of -/// AX. The SuperRegs field is a zero terminated array of registers that are -/// super-registers of the specific register, e.g. RAX, EAX, are super-registers -/// of AX. -/// -struct TargetRegisterDesc { - const char *Name; // Printable name for the reg (for debugging) - const unsigned *Overlaps; // Overlapping registers, described above - const unsigned *SubRegs; // Sub-register set, described above - const unsigned *SuperRegs; // Super-register set, described above - unsigned CostPerUse; // Extra cost of instructions using register. - bool inAllocatableClass; // Register belongs to an allocatable regclass. -}; - class TargetRegisterClass { public: typedef const unsigned* iterator; @@ -236,27 +218,23 @@ public: return SuperClasses[0] != 0; } - /// allocation_order_begin/end - These methods define a range of registers - /// which specify the registers in this class that are valid to register - /// allocate, and the preferred order to allocate them in. For example, - /// callee saved registers should be at the end of the list, because it is - /// cheaper to allocate caller saved registers. - /// - /// These methods take a MachineFunction argument, which can be used to tune - /// the allocatable registers based on the characteristics of the function, - /// subtarget, or other criteria. + /// getRawAllocationOrder - Returns the preferred order for allocating + /// registers from this register class in MF. The raw order comes directly + /// from the .td file and may include reserved registers that are not + /// allocatable. Register allocators should also make sure to allocate + /// callee-saved registers only after all the volatiles are used. The + /// RegisterClassInfo class provides filtered allocation orders with + /// callee-saved registers moved to the end. /// - /// Register allocators should account for the fact that an allocation - /// order iterator may return a reserved register and always check - /// if the register is allocatable (getAllocatableSet()) before using it. + /// The MachineFunction argument can be used to tune the allocatable + /// registers based on the characteristics of the function, subtarget, or + /// other criteria. /// - /// By default, these methods return all registers in the class. + /// By default, this method returns all registers in the class. /// - virtual iterator allocation_order_begin(const MachineFunction &MF) const { - return begin(); - } - virtual iterator allocation_order_end(const MachineFunction &MF) const { - return end(); + virtual + ArrayRef<unsigned> getRawAllocationOrder(const MachineFunction &MF) const { + return ArrayRef<unsigned>(begin(), getNumRegs()); } /// getSize - Return the size of the register in bytes, which is also the size @@ -277,6 +255,12 @@ public: bool isAllocatable() const { return Allocatable; } }; +/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about +/// registers. These are used by codegen, not by MC. +struct TargetRegisterInfoDesc { + unsigned CostPerUse; // Extra cost of instructions using register. + bool inAllocatableClass; // Register belongs to an allocatable regclass. +}; /// TargetRegisterInfo base class - We assume that the target defines a static /// array of TargetRegisterDesc objects that represent all of the machine @@ -284,34 +268,19 @@ public: /// to this array so that we can turn register number into a register /// descriptor. /// -class TargetRegisterInfo { -protected: - const unsigned* SubregHash; - const unsigned SubregHashSize; - const unsigned* AliasesHash; - const unsigned AliasesHashSize; +class TargetRegisterInfo : public MCRegisterInfo { public: typedef const TargetRegisterClass * const * regclass_iterator; private: - const TargetRegisterDesc *Desc; // Pointer to the descriptor array + const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. - unsigned NumRegs; // Number of entries in the array - regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses - int CallFrameSetupOpcode, CallFrameDestroyOpcode; - protected: - TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR, + TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, - const char *const *subregindexnames, - int CallFrameSetupOpcode = -1, - int CallFrameDestroyOpcode = -1, - const unsigned* subregs = 0, - const unsigned subregsize = 0, - const unsigned* aliases = 0, - const unsigned aliasessize = 0); + const char *const *subregindexnames); virtual ~TargetRegisterInfo(); public: @@ -391,71 +360,16 @@ public: BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC = NULL) const; - const TargetRegisterDesc &operator[](unsigned RegNo) const { - assert(RegNo < NumRegs && - "Attempting to access record for invalid register number!"); - return Desc[RegNo]; - } - - /// Provide a get method, equivalent to [], but more useful if we have a - /// pointer to this object. - /// - const TargetRegisterDesc &get(unsigned RegNo) const { - return operator[](RegNo); - } - - /// getAliasSet - Return the set of registers aliased by the specified - /// register, or a null list of there are none. The list returned is zero - /// terminated. - /// - const unsigned *getAliasSet(unsigned RegNo) const { - // The Overlaps set always begins with Reg itself. - return get(RegNo).Overlaps + 1; - } - - /// getOverlaps - Return a list of registers that overlap Reg, including - /// itself. This is the same as the alias set except Reg is included in the - /// list. - /// These are exactly the registers in { x | regsOverlap(x, Reg) }. - /// - const unsigned *getOverlaps(unsigned RegNo) const { - return get(RegNo).Overlaps; - } - - /// getSubRegisters - Return the list of registers that are sub-registers of - /// the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. - /// - const unsigned *getSubRegisters(unsigned RegNo) const { - return get(RegNo).SubRegs; - } - - /// getSuperRegisters - Return the list of registers that are super-registers - /// of the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::AL's super-register list is RAX, EAX, AX. - /// - const unsigned *getSuperRegisters(unsigned RegNo) const { - return get(RegNo).SuperRegs; - } - - /// getName - Return the human-readable symbolic target-specific name for the - /// specified physical register. - const char *getName(unsigned RegNo) const { - return get(RegNo).Name; - } - /// getCostPerUse - Return the additional cost of using this register instead /// of other registers in its class. unsigned getCostPerUse(unsigned RegNo) const { - return get(RegNo).CostPerUse; + return InfoDesc[RegNo].CostPerUse; } - /// getNumRegs - Return the number of registers this target has (useful for - /// sizing arrays holding per register information) - unsigned getNumRegs() const { - return NumRegs; + /// isInAllocatableClass - Return true if the register is in the allocation + /// of any register class. + bool isInAllocatableClass(unsigned RegNo) const { + return InfoDesc[RegNo].inAllocatableClass; } /// getSubRegIndexName - Return the human-readable symbolic target-specific @@ -468,49 +382,28 @@ public: /// regsOverlap - Returns true if the two registers are equal or alias each /// other. The registers may be virtual register. bool regsOverlap(unsigned regA, unsigned regB) const { - if (regA == regB) - return true; - + if (regA == regB) return true; if (isVirtualRegister(regA) || isVirtualRegister(regB)) return false; - - // regA and regB are distinct physical registers. Do they alias? - size_t index = (regA + regB * 37) & (AliasesHashSize-1); - unsigned ProbeAmt = 0; - while (AliasesHash[index*2] != 0 && - AliasesHash[index*2+1] != 0) { - if (AliasesHash[index*2] == regA && AliasesHash[index*2+1] == regB) - return true; - - index = (index + ProbeAmt) & (AliasesHashSize-1); - ProbeAmt += 2; + for (const unsigned *regList = getOverlaps(regA)+1; *regList; ++regList) { + if (*regList == regB) return true; } - return false; } /// isSubRegister - Returns true if regB is a sub-register of regA. /// bool isSubRegister(unsigned regA, unsigned regB) const { - // SubregHash is a simple quadratically probed hash table. - size_t index = (regA + regB * 37) & (SubregHashSize-1); - unsigned ProbeAmt = 2; - while (SubregHash[index*2] != 0 && - SubregHash[index*2+1] != 0) { - if (SubregHash[index*2] == regA && SubregHash[index*2+1] == regB) - return true; - - index = (index + ProbeAmt) & (SubregHashSize-1); - ProbeAmt += 2; - } - - return false; + return isSuperRegister(regB, regA); } /// isSuperRegister - Returns true if regB is a super-register of regA. /// bool isSuperRegister(unsigned regA, unsigned regB) const { - return isSubRegister(regB, regA); + for (const unsigned *regList = getSuperRegisters(regA); *regList;++regList){ + if (*regList == regB) return true; + } + return false; } /// getCalleeSavedRegs - Return a null-terminated list of all of the @@ -599,7 +492,7 @@ public: } /// getRegClass - Returns the register class associated with the enumeration - /// value. See class TargetOperandInfo. + /// value. See class MCOperandInfo. const TargetRegisterClass *getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); return RegClassBegin[i]; @@ -642,14 +535,17 @@ public: return 0; } - /// getAllocationOrder - Returns the register allocation order for a specified - /// register class in the form of a pair of TargetRegisterClass iterators. - virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> - getAllocationOrder(const TargetRegisterClass *RC, - unsigned HintType, unsigned HintReg, - const MachineFunction &MF) const { - return std::make_pair(RC->allocation_order_begin(MF), - RC->allocation_order_end(MF)); + /// 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<unsigned> + getRawAllocationOrder(const TargetRegisterClass *RC, + unsigned HintType, unsigned HintReg, + const MachineFunction &MF) const { + return RC->getRawAllocationOrder(MF); } /// ResolveRegAllocHint - Resolves the specified register allocation hint @@ -762,15 +658,6 @@ public: return false; // Must return a value in order to compile with VS 2005 } - /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the - /// frame setup/destroy instructions if they exist (-1 otherwise). Some - /// targets use pseudo instructions in order to abstract away the difference - /// between operating with a frame pointer and operating without, through the - /// use of these two instructions. - /// - int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; } - int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } - /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog /// code insertion to eliminate call frame setup and destroy pseudo /// instructions (but only if the Target is using them). It is responsible @@ -782,9 +669,6 @@ public: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { - assert(getCallFrameSetupOpcode()== -1 && getCallFrameDestroyOpcode()== -1 && - "eliminateCallFramePseudoInstr must be implemented if using" - " call frame setup/destroy pseudo instructions!"); assert(0 && "Call Frame Pseudo Instructions do not exist on this target!"); } @@ -836,6 +720,12 @@ public: virtual int getSEHRegNum(unsigned i) const { return i; } + + /// getCompactUnwindRegNum - This function maps the register to the number for + /// compact unwind encoding. Return -1 if the register isn't valid. + virtual int getCompactUnwindRegNum(unsigned, bool) const { + return -1; + } }; diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index a464822..7e0ce19 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -33,7 +33,10 @@ namespace llvm { class MCContext; class MCDisassembler; class MCInstPrinter; + class MCInstrInfo; + class MCRegisterInfo; class MCStreamer; + class MCSubtargetInfo; class TargetAsmBackend; class TargetAsmLexer; class TargetAsmParser; @@ -63,10 +66,16 @@ namespace llvm { typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); - typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T, - StringRef TT); + typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, + StringRef TT); + typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); + typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void); + typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, + StringRef CPU, + StringRef Features); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, const std::string &TT, + const std::string &CPU, const std::string &Features); typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, MCStreamer &Streamer); @@ -74,15 +83,14 @@ namespace llvm { const std::string &TT); typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); - typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P, - TargetMachine &TM); + typedef TargetAsmParser *(*AsmParserCtorTy)(MCSubtargetInfo &STI, + MCAsmParser &P); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, - TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI); - typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, - TargetMachine &TM, + typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const MCInstrInfo &II, + const MCSubtargetInfo &STI, MCContext &Ctx); typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T, const std::string &TT, @@ -120,7 +128,21 @@ namespace llvm { /// HasJIT - Whether this target supports the JIT. bool HasJIT; - AsmInfoCtorFnTy AsmInfoCtorFn; + /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if + /// registered. + MCAsmInfoCtorFnTy MCAsmInfoCtorFn; + + /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, + /// if registered. + MCInstrInfoCtorFnTy MCInstrInfoCtorFn; + + /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, + /// if registered. + MCRegInfoCtorFnTy MCRegInfoCtorFn; + + /// MCSubtargetInfoCtorFn - Constructor function for this target's + /// MCSubtargetInfo, if registered. + MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; /// TargetMachineCtorFn - Construction function for this target's /// TargetMachine, if registered. @@ -218,17 +240,49 @@ namespace llvm { /// @name Feature Constructors /// @{ - /// createAsmInfo - Create a MCAsmInfo implementation for the specified + /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified /// target triple. /// /// \arg Triple - This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. - MCAsmInfo *createAsmInfo(StringRef Triple) const { - if (!AsmInfoCtorFn) + MCAsmInfo *createMCAsmInfo(StringRef Triple) const { + if (!MCAsmInfoCtorFn) + return 0; + return MCAsmInfoCtorFn(*this, Triple); + } + + /// createMCInstrInfo - Create a MCInstrInfo implementation. + /// + MCInstrInfo *createMCInstrInfo() const { + if (!MCInstrInfoCtorFn) + return 0; + return MCInstrInfoCtorFn(); + } + + /// createMCRegInfo - Create a MCRegisterInfo implementation. + /// + MCRegisterInfo *createMCRegInfo() const { + if (!MCRegInfoCtorFn) + return 0; + return MCRegInfoCtorFn(); + } + + /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. + /// + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. + /// \arg CPU - This specifies the name of the target CPU. + /// \arg Features - This specifies the string representation of the + /// additional target features. + MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU, + StringRef Features) const { + if (!MCSubtargetInfoCtorFn) return 0; - return AsmInfoCtorFn(*this, Triple); + return MCSubtargetInfoCtorFn(Triple, CPU, Features); } /// createTargetMachine - Create a target specific machine implementation @@ -239,10 +293,11 @@ namespace llvm { /// either the target triple from the module, or the target triple of the /// host if that does not exist. TargetMachine *createTargetMachine(const std::string &Triple, + const std::string &CPU, const std::string &Features) const { if (!TargetMachineCtorFn) return 0; - return TargetMachineCtorFn(*this, Triple, Features); + return TargetMachineCtorFn(*this, Triple, CPU, Features); } /// createAsmBackend - Create a target specific assembly parser. @@ -267,11 +322,11 @@ namespace llvm { /// /// \arg Parser - The target independent parser implementation to use for /// parsing and lexing. - TargetAsmParser *createAsmParser(MCAsmParser &Parser, - TargetMachine &TM) const { + TargetAsmParser *createAsmParser(MCSubtargetInfo &STI, + MCAsmParser &Parser) const { if (!AsmParserCtorFn) return 0; - return AsmParserCtorFn(*this, Parser, TM); + return AsmParserCtorFn(STI, Parser); } /// createAsmPrinter - Create a target specific assembly printer pass. This @@ -288,20 +343,21 @@ namespace llvm { return MCDisassemblerCtorFn(*this); } - MCInstPrinter *createMCInstPrinter(TargetMachine &TM, - unsigned SyntaxVariant, + MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, const MCAsmInfo &MAI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, TM, SyntaxVariant, MAI); + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); } /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const { + MCCodeEmitter *createCodeEmitter(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx) const { if (!CodeEmitterCtorFn) return 0; - return CodeEmitterCtorFn(*this, TM, Ctx); + return CodeEmitterCtorFn(II, STI, Ctx); } /// createObjectStreamer - Create a target specific MCStreamer. @@ -429,7 +485,7 @@ namespace llvm { Target::TripleMatchQualityFnTy TQualityFn, bool HasJIT = false); - /// RegisterAsmInfo - Register a MCAsmInfo implementation for the + /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the /// given target. /// /// Clients are responsible for ensuring that registration doesn't occur @@ -438,10 +494,56 @@ namespace llvm { /// /// @param T - The target being registered. /// @param Fn - A function to construct a MCAsmInfo for the target. - static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) { + static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCAsmInfoCtorFn) + T.MCAsmInfoCtorFn = Fn; + } + + /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCInstrInfo for the target. + static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCInstrInfoCtorFn) + T.MCInstrInfoCtorFn = Fn; + } + + /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCRegisterInfo for the target. + static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCRegInfoCtorFn) + T.MCRegInfoCtorFn = Fn; + } + + /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for + /// the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCSubtargetInfo for the target. + static void RegisterMCSubtargetInfo(Target &T, + Target::MCSubtargetInfoCtorFnTy Fn) { // Ignore duplicate registration. - if (!T.AsmInfoCtorFn) - T.AsmInfoCtorFn = Fn; + if (!T.MCSubtargetInfoCtorFn) + T.MCSubtargetInfoCtorFn = Fn; } /// RegisterTargetMachine - Register a TargetMachine implementation for the @@ -620,18 +722,18 @@ namespace llvm { } }; - /// RegisterAsmInfo - Helper template for registering a target assembly info + /// RegisterMCAsmInfo - Helper template for registering a target assembly info /// implementation. This invokes the static "Create" method on the class to /// actually do the construction. Usage: /// /// extern "C" void LLVMInitializeFooTarget() { /// extern Target TheFooTarget; - /// RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget); + /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); /// } template<class MCAsmInfoImpl> - struct RegisterAsmInfo { - RegisterAsmInfo(Target &T) { - TargetRegistry::RegisterAsmInfo(T, &Allocator); + struct RegisterMCAsmInfo { + RegisterMCAsmInfo(Target &T) { + TargetRegistry::RegisterMCAsmInfo(T, &Allocator); } private: static MCAsmInfo *Allocator(const Target &T, StringRef TT) { @@ -640,20 +742,119 @@ namespace llvm { }; - /// RegisterAsmInfoFn - Helper template for registering a target assembly info + /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info /// implementation. This invokes the specified function to do the /// construction. Usage: /// /// extern "C" void LLVMInitializeFooTarget() { /// extern Target TheFooTarget; - /// RegisterAsmInfoFn X(TheFooTarget, TheFunction); + /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); /// } - struct RegisterAsmInfoFn { - RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) { - TargetRegistry::RegisterAsmInfo(T, Fn); + struct RegisterMCAsmInfoFn { + RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCAsmInfo(T, Fn); } }; + /// RegisterMCInstrInfo - Helper template for registering a target instruction + /// info implementation. This invokes the static "Create" method on the class + /// to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); + /// } + template<class MCInstrInfoImpl> + struct RegisterMCInstrInfo { + RegisterMCInstrInfo(Target &T) { + TargetRegistry::RegisterMCInstrInfo(T, &Allocator); + } + private: + static MCInstrInfo *Allocator() { + return new MCInstrInfoImpl(); + } + }; + + /// RegisterMCInstrInfoFn - Helper template for registering a target + /// instruction info implementation. This invokes the specified function to + /// do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCInstrInfoFn { + RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCInstrInfo(T, Fn); + } + }; + + /// RegisterMCRegInfo - Helper template for registering a target register info + /// implementation. This invokes the static "Create" method on the class to + /// actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); + /// } + template<class MCRegisterInfoImpl> + struct RegisterMCRegInfo { + RegisterMCRegInfo(Target &T) { + TargetRegistry::RegisterMCRegInfo(T, &Allocator); + } + private: + static MCRegisterInfo *Allocator() { + return new MCRegisterInfoImpl(); + } + }; + + /// RegisterMCRegInfoFn - Helper template for registering a target register + /// info implementation. This invokes the specified function to do the + /// construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCRegInfoFn { + RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCRegInfo(T, Fn); + } + }; + + /// RegisterMCSubtargetInfo - Helper template for registering a target + /// subtarget info implementation. This invokes the static "Create" method + /// on the class to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); + /// } + template<class MCSubtargetInfoImpl> + struct RegisterMCSubtargetInfo { + RegisterMCSubtargetInfo(Target &T) { + TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); + } + private: + static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU, + StringRef FS) { + return new MCSubtargetInfoImpl(); + } + }; + + /// RegisterMCSubtargetInfoFn - Helper template for registering a target + /// subtarget info implementation. This invokes the specified function to + /// do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCSubtargetInfoFn { + RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCSubtargetInfo(T, Fn); + } + }; /// RegisterTargetMachine - Helper template for registering a target machine /// implementation, for use in the target machine initialization @@ -671,8 +872,9 @@ namespace llvm { private: static TargetMachine *Allocator(const Target &T, const std::string &TT, + const std::string &CPU, const std::string &FS) { - return new TargetMachineImpl(T, TT, FS); + return new TargetMachineImpl(T, TT, CPU, FS); } }; @@ -731,9 +933,8 @@ namespace llvm { } private: - static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P, - TargetMachine &TM) { - return new AsmParserImpl(T, P, TM); + static TargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { + return new AsmParserImpl(STI, P); } }; @@ -772,9 +973,10 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM, + static MCCodeEmitter *Allocator(const MCInstrInfo &II, + const MCSubtargetInfo &STI, MCContext &Ctx) { - return new CodeEmitterImpl(T, TM, Ctx); + return new CodeEmitterImpl(); } }; diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h index c5ab90b..272ee09 100644 --- a/include/llvm/Target/TargetSelect.h +++ b/include/llvm/Target/TargetSelect.h @@ -26,6 +26,18 @@ extern "C" { #define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" +#define LLVM_TARGET(TargetName) \ + void LLVMInitialize##TargetName##MCAsmInfo(); +#include "llvm/Config/Targets.def" + +#define LLVM_TARGET(TargetName) \ + void LLVMInitialize##TargetName##MCInstrInfo(); +#include "llvm/Config/Targets.def" + +#define LLVM_TARGET(TargetName) \ + void LLVMInitialize##TargetName##MCSubtargetInfo(); +#include "llvm/Config/Targets.def" + // Declare all of the available assembly printer initialization functions. #define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" @@ -35,7 +47,8 @@ extern "C" { #include "llvm/Config/AsmParsers.def" // Declare all of the available disassembler initialization functions. -#define LLVM_DISASSEMBLER(TargetName) void LLVMInitialize##TargetName##Disassembler(); +#define LLVM_DISASSEMBLER(TargetName) \ + void LLVMInitialize##TargetName##Disassembler(); #include "llvm/Config/Disassemblers.def" } @@ -63,6 +76,38 @@ namespace llvm { #include "llvm/Config/Targets.def" } + /// InitializeAllMCAsmInfos - The main program should call this function + /// if it wants access to all available assembly infos for targets that + /// LLVM is configured to support, to make them available via the + /// TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllMCAsmInfos() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCAsmInfo(); +#include "llvm/Config/Targets.def" + } + + /// InitializeAllMCInstrInfos - The main program should call this function + /// if it wants access to all available instruction infos for targets that + /// LLVM is configured to support, to make them available via the + /// TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllMCInstrInfos() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCInstrInfo(); +#include "llvm/Config/Targets.def" + } + + /// InitializeAllMCSubtargetInfos - The main program should call this function + /// if it wants access to all available subtarget infos for targets that LLVM + /// is configured to support, to make them available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllMCSubtargetInfos() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCSubtargetInfo(); +#include "llvm/Config/Targets.def" + } + /// InitializeAllAsmPrinters - The main program should call this function if /// it wants all asm printers that LLVM is configured to support, to make them /// available via the TargetRegistry. @@ -103,6 +148,7 @@ namespace llvm { #ifdef LLVM_NATIVE_TARGET LLVM_NATIVE_TARGETINFO(); LLVM_NATIVE_TARGET(); + LLVM_NATIVE_MCASMINFO(); return false; #else return true; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 672117f..9d1ef2c 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -197,8 +197,8 @@ def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> ]>; -def SDTPrefetch : SDTypeProfile<0, 3, [ // prefetch - SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1> +def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch + SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> ]>; def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barier @@ -353,6 +353,7 @@ def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; +def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; diff --git a/include/llvm/Target/TargetSubtarget.h b/include/llvm/Target/TargetSubtargetInfo.h index 22b09ba..9556c7a 100644 --- a/include/llvm/Target/TargetSubtarget.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -1,4 +1,4 @@ -//==-- llvm/Target/TargetSubtarget.h - Target Information --------*- C++ -*-==// +//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETSUBTARGET_H -#define LLVM_TARGET_TARGETSUBTARGET_H +#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H +#define LLVM_TARGET_TARGETSUBTARGETINFO_H +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Target/TargetMachine.h" namespace llvm { @@ -25,22 +26,22 @@ template <typename T> class SmallVectorImpl; //===----------------------------------------------------------------------===// /// -/// TargetSubtarget - Generic base class for all target subtargets. All +/// TargetSubtargetInfo - Generic base class for all target subtargets. All /// Target-specific options that control code generation and printing should -/// be exposed through a TargetSubtarget-derived class. +/// be exposed through a TargetSubtargetInfo-derived class. /// -class TargetSubtarget { - TargetSubtarget(const TargetSubtarget&); // DO NOT IMPLEMENT - void operator=(const TargetSubtarget&); // DO NOT IMPLEMENT +class TargetSubtargetInfo : public MCSubtargetInfo { + TargetSubtargetInfo(const TargetSubtargetInfo&); // DO NOT IMPLEMENT + void operator=(const TargetSubtargetInfo&); // DO NOT IMPLEMENT protected: // Can only create subclasses... - TargetSubtarget(); + TargetSubtargetInfo(); public: // AntiDepBreakMode - Type of anti-dependence breaking that should // be performed before post-RA scheduling. typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode; typedef SmallVectorImpl<TargetRegisterClass*> RegClassVector; - virtual ~TargetSubtarget(); + virtual ~TargetSubtargetInfo(); /// getSpecialAddressLatency - For targets where it is beneficial to /// backschedule instructions that compute addresses, return a value diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index d12fd1d..f025e180 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -74,13 +74,6 @@ ModulePass *createGlobalOptimizerPass(); //===----------------------------------------------------------------------===// -/// createDeadTypeEliminationPass - Return a new pass that eliminates symbol -/// table entries for types that are never used. -/// -ModulePass *createDeadTypeEliminationPass(); - - -//===----------------------------------------------------------------------===// /// createGlobalDCEPass - This transform is designed to eliminate unreachable /// internal globals (functions or global variables) /// diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index de46a8d..2187d4e 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -338,11 +338,37 @@ Pass *createCorrelatedValuePropagationPass(); //===----------------------------------------------------------------------===// // +// ObjCARCExpand - ObjC ARC preliminary simplifications. +// +Pass *createObjCARCExpandPass(); + +//===----------------------------------------------------------------------===// +// +// ObjCARCContract - Late ObjC ARC cleanups. +// +Pass *createObjCARCContractPass(); + +//===----------------------------------------------------------------------===// +// +// ObjCARCOpt - ObjC ARC optimization. +// +Pass *createObjCARCOptPass(); + +//===----------------------------------------------------------------------===// +// // InstructionSimplifier - Remove redundant instructions. // FunctionPass *createInstructionSimplifierPass(); extern char &InstructionSimplifierID; + +//===----------------------------------------------------------------------===// +// +// LowerExpectIntriniscs - Removes llvm.expect intrinsics and creates +// "block_weights" metadata. +FunctionPass *createLowerExpectIntrinsicPass(); + + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 853de2d..674c2d0 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -107,12 +107,6 @@ BasicBlock *CloneBasicBlock(const BasicBlock *BB, const Twine &NameSuffix = "", Function *F = 0, ClonedCodeInfo *CodeInfo = 0); - -/// CloneLoop - Clone Loop. Clone dominator info for loop insiders. Populate -/// VMap using old blocks to new blocks mapping. -Loop *CloneLoop(Loop *L, LPPassManager *LPM, LoopInfo *LI, - ValueToValueMapTy &VMap, Pass *P); - /// CloneFunction - Return a copy of the specified function, but without /// embedding the function into another module. Also, any references specified /// in the VMap are changed to refer to their mapped value instead of the diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 51c8467..063d413 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -122,12 +122,9 @@ private: class LoadAndStorePromoter { protected: SSAUpdater &SSA; - DbgDeclareInst *DDI; - DIBuilder *DIB; public: LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts, - SSAUpdater &S, DbgDeclareInst *DDI, DIBuilder *DIB, - StringRef Name = StringRef()); + SSAUpdater &S, StringRef Name = StringRef()); virtual ~LoadAndStorePromoter() {} /// run - This does the promotion. Insts is a list of loads and stores to @@ -161,6 +158,10 @@ public: virtual void instructionDeleted(Instruction *I) const { } + /// updateDebugInfo - This is called to update debug info associated with the + /// instruction. + virtual void updateDebugInfo(Instruction *I) const { + } }; } // End llvm namespace diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index d612213..2194373 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -22,6 +22,18 @@ namespace llvm { class Instruction; typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy; + /// ValueMapTypeRemapper - This is a class that can be implemented by clients + /// to remap types when cloning constants and instructions. + class ValueMapTypeRemapper { + virtual void Anchor(); // Out of line method. + public: + virtual ~ValueMapTypeRemapper() {} + + /// remapType - The client should implement this method if they want to + /// remap types while mapping values. + virtual Type *remapType(Type *SrcTy) = 0; + }; + /// RemapFlags - These are flags that the value mapping APIs allow. enum RemapFlags { RF_None = 0, @@ -42,9 +54,27 @@ namespace llvm { } Value *MapValue(const Value *V, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None); + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0); + void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None); + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0); + + /// MapValue - provide versions that preserve type safety for MDNode and + /// Constants. + inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0) { + return (MDNode*)MapValue((const Value*)V, VM, Flags, TypeMapper); + } + inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0) { + return (Constant*)MapValue((const Value*)V, VM, Flags, TypeMapper); + } + + } // End llvm namespace #endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 3bda91d..e4ff3e1 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -6,86 +6,64 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// This file contains the declaration of the Type class. For more "Type" +// stuff, look in DerivedTypes.h. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_TYPE_H #define LLVM_TYPE_H -#include "llvm/AbstractTypeUser.h" #include "llvm/Support/Casting.h" -#include "llvm/ADT/GraphTraits.h" -#include <string> -#include <vector> namespace llvm { -class DerivedType; class PointerType; class IntegerType; -class TypeMapBase; class raw_ostream; class Module; class LLVMContext; +class LLVMContextImpl; +template<class GraphType> struct GraphTraits; -/// This file contains the declaration of the Type class. For more "Type" type -/// stuff, look in DerivedTypes.h. -/// /// The instances of the Type class are immutable: once they are created, /// they are never changed. Also note that only one instance of a particular /// type is ever created. Thus seeing if two types are equal is a matter of /// doing a trivial pointer comparison. To enforce that no two equal instances /// are created, Type instances can only be created via static factory methods -/// in class Type and in derived classes. +/// in class Type and in derived classes. Once allocated, Types are never +/// free'd. /// -/// Once allocated, Types are never free'd, unless they are an abstract type -/// that is resolved to a more concrete type. -/// -/// Types themself don't have a name, and can be named either by: -/// - using SymbolTable instance, typically from some Module, -/// - using convenience methods in the Module class (which uses module's -/// SymbolTable too). -/// -/// Opaque types are simple derived types with no state. There may be many -/// different Opaque type objects floating around, but two are only considered -/// identical if they are pointer equals of each other. This allows us to have -/// two opaque types that end up resolving to different concrete types later. -/// -/// Opaque types are also kinda weird and scary and different because they have -/// to keep a list of uses of the type. When, through linking, parsing, or -/// bitcode reading, they become resolved, they need to find and update all -/// users of the unknown type, causing them to reference a new, more concrete -/// type. Opaque types are deleted when their use list dwindles to zero users. -/// -/// @brief Root of type hierarchy -class Type : public AbstractTypeUser { +class Type { public: - //===-------------------------------------------------------------------===// + //===--------------------------------------------------------------------===// /// Definitions of all of the base types for the Type system. Based on this - /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h) + /// value, you can cast to a class defined in DerivedTypes.h. /// Note: If you add an element to this, you need to add an element to the /// Type::getPrimitiveType function, or else things will break! /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding. /// enum TypeID { - // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date + // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date. VoidTyID = 0, ///< 0: type with no size - FloatTyID, ///< 1: 32 bit floating point type - DoubleTyID, ///< 2: 64 bit floating point type - X86_FP80TyID, ///< 3: 80 bit floating point type (X87) - FP128TyID, ///< 4: 128 bit floating point type (112-bit mantissa) - PPC_FP128TyID, ///< 5: 128 bit floating point type (two 64-bits) + FloatTyID, ///< 1: 32-bit floating point type + DoubleTyID, ///< 2: 64-bit floating point type + X86_FP80TyID, ///< 3: 80-bit floating point type (X87) + FP128TyID, ///< 4: 128-bit floating point type (112-bit mantissa) + PPC_FP128TyID, ///< 5: 128-bit floating point type (two 64-bits, PowerPC) LabelTyID, ///< 6: Labels MetadataTyID, ///< 7: Metadata - X86_MMXTyID, ///< 8: MMX vectors (64 bits) + X86_MMXTyID, ///< 8: MMX vectors (64 bits, X86 specific) - // Derived types... see DerivedTypes.h file... - // Make sure FirstDerivedTyID stays up to date!!! + // Derived types... see DerivedTypes.h file. + // Make sure FirstDerivedTyID stays up to date! IntegerTyID, ///< 9: Arbitrary bit width integers FunctionTyID, ///< 10: Functions StructTyID, ///< 11: Structures ArrayTyID, ///< 12: Arrays PointerTyID, ///< 13: Pointers - OpaqueTyID, ///< 14: Opaque: type with unknown structure - VectorTyID, ///< 15: SIMD 'packed' format, or other vector type + VectorTyID, ///< 14: SIMD 'packed' format, or other vector type NumTypeIDs, // Must remain as last defined ID LastPrimitiveTyID = X86_MMXTyID, @@ -93,101 +71,52 @@ public: }; private: - TypeID ID : 8; // The current base type of this type. - bool Abstract : 1; // True if type contains an OpaqueType - unsigned SubclassData : 23; //Space for subclasses to store data - - /// RefCount - This counts the number of PATypeHolders that are pointing to - /// this type. When this number falls to zero, if the type is abstract and - /// has no AbstractTypeUsers, the type is deleted. This is only sensical for - /// derived types. - /// - mutable unsigned RefCount; - /// Context - This refers to the LLVMContext in which this type was uniqued. LLVMContext &Context; - friend class LLVMContextImpl; - - const Type *getForwardedTypeInternal() const; - // Some Type instances are allocated as arrays, some aren't. So we provide - // this method to get the right kind of destruction for the type of Type. - void destroy() const; // const is a lie, this does "delete this"! + TypeID ID : 8; // The current base type of this type. + unsigned SubclassData : 24; // Space for subclasses to store data protected: - explicit Type(LLVMContext &C, TypeID id) : - ID(id), Abstract(false), SubclassData(0), - RefCount(0), Context(C), - ForwardType(0), NumContainedTys(0), - ContainedTys(0) {} - virtual ~Type() { - assert(AbstractTypeUsers.empty() && "Abstract types remain"); - } - - /// Types can become nonabstract later, if they are refined. - /// - inline void setAbstract(bool Val) { Abstract = Val; } - - unsigned getRefCount() const { return RefCount; } + friend class LLVMContextImpl; + explicit Type(LLVMContext &C, TypeID tid) + : Context(C), ID(tid), SubclassData(0), + NumContainedTys(0), ContainedTys(0) {} + ~Type() {} unsigned getSubclassData() const { return SubclassData; } - void setSubclassData(unsigned val) { SubclassData = val; } - - /// ForwardType - This field is used to implement the union find scheme for - /// abstract types. When types are refined to other types, this field is set - /// to the more refined type. Only abstract types can be forwarded. - mutable const Type *ForwardType; - - - /// AbstractTypeUsers - Implement a list of the users that need to be notified - /// if I am a type, and I get resolved into a more concrete type. - /// - mutable std::vector<AbstractTypeUser *> AbstractTypeUsers; + void setSubclassData(unsigned val) { + SubclassData = val; + // Ensure we don't have any accidental truncation. + assert(SubclassData == val && "Subclass data too large for field"); + } - /// NumContainedTys - Keeps track of how many PATypeHandle instances there - /// are at the end of this type instance for the list of contained types. It - /// is the subclasses responsibility to set this up. Set to 0 if there are no - /// contained types in this type. + /// NumContainedTys - Keeps track of how many Type*'s there are in the + /// ContainedTys list. unsigned NumContainedTys; - /// ContainedTys - A pointer to the array of Types (PATypeHandle) contained - /// by this Type. For example, this includes the arguments of a function - /// type, the elements of a structure, the pointee of a pointer, the element - /// type of an array, etc. This pointer may be 0 for types that don't - /// contain other types (Integer, Double, Float). In general, the subclass - /// should arrange for space for the PATypeHandles to be included in the - /// allocation of the type object and set this pointer to the address of the - /// first element. This allows the Type class to manipulate the ContainedTys - /// without understanding the subclass's placement for this array. keeping - /// it here also allows the subtype_* members to be implemented MUCH more - /// efficiently, and dynamically very few types do not contain any elements. - PATypeHandle *ContainedTys; + /// ContainedTys - A pointer to the array of Types contained by this Type. + /// For example, this includes the arguments of a function type, the elements + /// of a structure, the pointee of a pointer, the element type of an array, + /// etc. This pointer may be 0 for types that don't contain other types + /// (Integer, Double, Float). + Type * const *ContainedTys; public: void print(raw_ostream &O) const; - - /// @brief Debugging support: print to stderr void dump() const; - /// @brief Debugging support: print to stderr (use type names from context - /// module). - void dump(const Module *Context) const; - - /// getContext - Fetch the LLVMContext in which this type was uniqued. + /// getContext - Return the LLVMContext in which this type was uniqued. LLVMContext &getContext() const { return Context; } //===--------------------------------------------------------------------===// - // Property accessors for dealing with types... Some of these virtual methods - // are defined in private classes defined in Type.cpp for primitive types. + // Accessors for working with types. // - /// getDescription - Return the string representation of the type. - std::string getDescription() const; - /// getTypeID - Return the type id for the type. This will return one /// of the TypeID enum elements defined above. /// - inline TypeID getTypeID() const { return ID; } + TypeID getTypeID() const { return ID; } /// isVoidTy - Return true if this is 'void'. bool isVoidTy() const { return ID == VoidTyID; } @@ -209,8 +138,10 @@ public: /// isFloatingPointTy - Return true if this is one of the five floating point /// types - bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID || - ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; } + bool isFloatingPointTy() const { + return ID == FloatTyID || ID == DoubleTyID || + ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; + } /// isX86_MMXTy - Return true if this is X86 MMX. bool isX86_MMXTy() const { return ID == X86_MMXTyID; } @@ -253,19 +184,10 @@ public: /// bool isPointerTy() const { return ID == PointerTyID; } - /// isOpaqueTy - True if this is an instance of OpaqueType. - /// - bool isOpaqueTy() const { return ID == OpaqueTyID; } - /// isVectorTy - True if this is an instance of VectorType. /// bool isVectorTy() const { return ID == VectorTyID; } - /// isAbstract - True if the type is either an Opaque type, or is a derived - /// type that includes an opaque type somewhere in it. - /// - inline bool isAbstract() const { return Abstract; } - /// canLosslesslyBitCastTo - Return true if this type could be converted /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts /// are valid for types of the same size only where no re-interpretation of @@ -280,24 +202,22 @@ public: /// Here are some useful little methods to query what type derived types are /// Note that all other types can just compare to see if this == Type::xxxTy; /// - inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; } - inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } + bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; } + bool isDerivedType() const { return ID >= FirstDerivedTyID; } /// isFirstClassType - Return true if the type is "first class", meaning it /// is a valid type for a Value. /// - inline bool isFirstClassType() const { - // There are more first-class kinds than non-first-class kinds, so a - // negative test is simpler than a positive one. - return ID != FunctionTyID && ID != VoidTyID && ID != OpaqueTyID; + bool isFirstClassType() const { + return ID != FunctionTyID && ID != VoidTyID; } /// isSingleValueType - Return true if the type is a valid type for a - /// virtual register in codegen. This includes all first-class types - /// except struct and array types. + /// register in codegen. This includes all first-class types except struct + /// and array types. /// - inline bool isSingleValueType() const { - return (ID != VoidTyID && ID <= LastPrimitiveTyID) || + bool isSingleValueType() const { + return (ID != VoidTyID && isPrimitiveType()) || ID == IntegerTyID || ID == PointerTyID || ID == VectorTyID; } @@ -306,7 +226,7 @@ public: /// extractvalue instruction. This includes struct and array types, but /// does not include vector types. /// - inline bool isAggregateType() const { + bool isAggregateType() const { return ID == StructTyID || ID == ArrayTyID; } @@ -323,9 +243,8 @@ public: // it doesn't have a size. if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID) return false; - // If it is something that can have a size and it's concrete, it definitely - // has a size, otherwise we have to try harder to decide. - return !isAbstract() || isSizedDerivedType(); + // Otherwise we have to try harder to decide. + return isSizedDerivedType(); } /// getPrimitiveSizeInBits - Return the basic size of this type if it is a @@ -350,28 +269,14 @@ public: /// have a stable mantissa (e.g. ppc long double), this method returns -1. int getFPMantissaWidth() const; - /// getForwardedType - Return the type that this type has been resolved to if - /// it has been resolved to anything. This is used to implement the - /// union-find algorithm for type resolution, and shouldn't be used by general - /// purpose clients. - const Type *getForwardedType() const { - if (!ForwardType) return 0; - return getForwardedTypeInternal(); - } - - /// getVAArgsPromotedType - Return the type an argument of this type - /// will be promoted to if passed through a variable argument - /// function. - const Type *getVAArgsPromotedType(LLVMContext &C) const; - /// getScalarType - If this is a vector type, return the element type, - /// otherwise return this. + /// otherwise return 'this'. const Type *getScalarType() const; //===--------------------------------------------------------------------===// - // Type Iteration support + // Type Iteration support. // - typedef PATypeHandle *subtype_iterator; + typedef Type * const *subtype_iterator; subtype_iterator subtype_begin() const { return ContainedTys; } subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];} @@ -379,9 +284,9 @@ public: /// (defined a the end of the file). For derived types, this returns the /// types 'contained' in the derived type. /// - const Type *getContainedType(unsigned i) const { + Type *getContainedType(unsigned i) const { assert(i < NumContainedTys && "Index out of range!"); - return ContainedTys[i].get(); + return ContainedTys[i]; } /// getNumContainedTypes - Return the number of types in the derived type. @@ -394,139 +299,76 @@ public: // /// getPrimitiveType - Return a type based on an identifier. - static const Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber); + static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber); //===--------------------------------------------------------------------===// - // These are the builtin types that are always available... + // These are the builtin types that are always available. // - static const Type *getVoidTy(LLVMContext &C); - static const Type *getLabelTy(LLVMContext &C); - static const Type *getFloatTy(LLVMContext &C); - static const Type *getDoubleTy(LLVMContext &C); - static const Type *getMetadataTy(LLVMContext &C); - static const Type *getX86_FP80Ty(LLVMContext &C); - static const Type *getFP128Ty(LLVMContext &C); - static const Type *getPPC_FP128Ty(LLVMContext &C); - static const Type *getX86_MMXTy(LLVMContext &C); - static const IntegerType *getIntNTy(LLVMContext &C, unsigned N); - static const IntegerType *getInt1Ty(LLVMContext &C); - static const IntegerType *getInt8Ty(LLVMContext &C); - static const IntegerType *getInt16Ty(LLVMContext &C); - static const IntegerType *getInt32Ty(LLVMContext &C); - static const IntegerType *getInt64Ty(LLVMContext &C); + static Type *getVoidTy(LLVMContext &C); + static Type *getLabelTy(LLVMContext &C); + static Type *getFloatTy(LLVMContext &C); + static Type *getDoubleTy(LLVMContext &C); + static Type *getMetadataTy(LLVMContext &C); + static Type *getX86_FP80Ty(LLVMContext &C); + static Type *getFP128Ty(LLVMContext &C); + static Type *getPPC_FP128Ty(LLVMContext &C); + static Type *getX86_MMXTy(LLVMContext &C); + static IntegerType *getIntNTy(LLVMContext &C, unsigned N); + static IntegerType *getInt1Ty(LLVMContext &C); + static IntegerType *getInt8Ty(LLVMContext &C); + static IntegerType *getInt16Ty(LLVMContext &C); + static IntegerType *getInt32Ty(LLVMContext &C); + static IntegerType *getInt64Ty(LLVMContext &C); //===--------------------------------------------------------------------===// // Convenience methods for getting pointer types with one of the above builtin // types as pointee. // - static const PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, - unsigned AS = 0); - static const PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0); + static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Type *) { return true; } - void addRef() const { - assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); - ++RefCount; - } - - void dropRef() const { - assert(isAbstract() && "Cannot drop a reference to a non-abstract type!"); - assert(RefCount && "No objects are currently referencing this object!"); - - // If this is the last PATypeHolder using this object, and there are no - // PATypeHandles using it, the type is dead, delete it now. - if (--RefCount == 0 && AbstractTypeUsers.empty()) - this->destroy(); - } - - /// addAbstractTypeUser - Notify an abstract type that there is a new user of - /// it. This function is called primarily by the PATypeHandle class. - /// - void addAbstractTypeUser(AbstractTypeUser *U) const; - - /// removeAbstractTypeUser - Notify an abstract type that a user of the class - /// no longer has a handle to the type. This function is called primarily by - /// the PATypeHandle class. When there are no users of the abstract type, it - /// is annihilated, because there is no way to get a reference to it ever - /// again. - /// - void removeAbstractTypeUser(AbstractTypeUser *U) const; - /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). - const PointerType *getPointerTo(unsigned AddrSpace = 0) const; + PointerType *getPointerTo(unsigned AddrSpace = 0) const; private: /// isSizedDerivedType - Derived types like structures and arrays are sized /// iff all of the members of the type are sized as well. Since asking for /// their size is relatively uncommon, move this operation out of line. bool isSizedDerivedType() const; - - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - -protected: - // PromoteAbstractToConcrete - This is an internal method used to calculate - // change "Abstract" from true to false when types are refined. - void PromoteAbstractToConcrete(); - friend class TypeMapBase; }; -//===----------------------------------------------------------------------===// -// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class. -// These are defined here because they MUST be inlined, yet are dependent on -// the definition of the Type class. -// -inline void PATypeHandle::addUser() { - assert(Ty && "Type Handle has a null type!"); - if (Ty->isAbstract()) - Ty->addAbstractTypeUser(User); -} -inline void PATypeHandle::removeUser() { - if (Ty->isAbstract()) - Ty->removeAbstractTypeUser(User); -} - -// Define inline methods for PATypeHolder. - -/// get - This implements the forwarding part of the union-find algorithm for -/// abstract types. Before every access to the Type*, we check to see if the -/// type we are pointing to is forwarding to a new type. If so, we drop our -/// reference to the type. -/// -inline Type* PATypeHolder::get() const { - if (Ty == 0) return 0; - const Type *NewTy = Ty->getForwardedType(); - if (!NewTy) return const_cast<Type*>(Ty); - return *const_cast<PATypeHolder*>(this) = NewTy; -} - -inline void PATypeHolder::addRef() { - if (Ty && Ty->isAbstract()) - Ty->addRef(); -} - -inline void PATypeHolder::dropRef() { - if (Ty && Ty->isAbstract()) - Ty->dropRef(); +// Printing of types. +static inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) { + T.print(OS); + return OS; } +// allow isa<PointerType>(x) to work without DerivedTypes.h included. +template <> struct isa_impl<PointerType, Type> { + static inline bool doit(const Type &Ty) { + return Ty.getTypeID() == Type::PointerTyID; + } +}; + //===----------------------------------------------------------------------===// // Provide specializations of GraphTraits to be able to treat a type as a -// graph of sub types... +// graph of sub types. + template <> struct GraphTraits<Type*> { typedef Type NodeType; @@ -554,14 +396,6 @@ template <> struct GraphTraits<const Type*> { } }; -template <> struct isa_impl<PointerType, Type> { - static inline bool doit(const Type &Ty) { - return Ty.getTypeID() == Type::PointerTyID; - } -}; - -raw_ostream &operator<<(raw_ostream &OS, const Type &T); - } // End llvm namespace #endif diff --git a/include/llvm/TypeSymbolTable.h b/include/llvm/TypeSymbolTable.h deleted file mode 100644 index 89ad534..0000000 --- a/include/llvm/TypeSymbolTable.h +++ /dev/null @@ -1,152 +0,0 @@ -//===-- llvm/TypeSymbolTable.h - Implement a Type Symtab --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the name/type symbol table for LLVM. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TYPE_SYMBOL_TABLE_H -#define LLVM_TYPE_SYMBOL_TABLE_H - -#include "llvm/Type.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataTypes.h" -#include <map> - -namespace llvm { - -/// This class provides a symbol table of name/type pairs with operations to -/// support constructing, searching and iterating over the symbol table. The -/// class derives from AbstractTypeUser so that the contents of the symbol -/// table can be updated when abstract types become concrete. -class TypeSymbolTable : public AbstractTypeUser { - -/// @name Types -/// @{ -public: - - /// @brief A mapping of names to types. - typedef std::map<const std::string, const Type*> TypeMap; - - /// @brief An iterator over the TypeMap. - typedef TypeMap::iterator iterator; - - /// @brief A const_iterator over the TypeMap. - typedef TypeMap::const_iterator const_iterator; - -/// @} -/// @name Constructors -/// @{ -public: - - TypeSymbolTable():LastUnique(0) {} - ~TypeSymbolTable(); - -/// @} -/// @name Accessors -/// @{ -public: - - /// Generates a unique name for a type based on the \p BaseName by - /// incrementing an integer and appending it to the name, if necessary - /// @returns the unique name - /// @brief Get a unique name for a type - std::string getUniqueName(StringRef BaseName) const; - - /// This method finds the type with the given \p name in the type map - /// and returns it. - /// @returns null if the name is not found, otherwise the Type - /// associated with the \p name. - /// @brief Lookup a type by name. - Type *lookup(StringRef name) const; - - /// Lookup the type associated with name. - /// @returns end() if the name is not found, or an iterator at the entry for - /// Type. - iterator find(StringRef Name) { - return tmap.find(Name); - } - - /// Lookup the type associated with name. - /// @returns end() if the name is not found, or an iterator at the entry for - /// Type. - const_iterator find(StringRef Name) const { - return tmap.find(Name); - } - - /// @returns true iff the symbol table is empty. - /// @brief Determine if the symbol table is empty - inline bool empty() const { return tmap.empty(); } - - /// @returns the size of the symbol table - /// @brief The number of name/type pairs is returned. - inline unsigned size() const { return unsigned(tmap.size()); } - - /// This function can be used from the debugger to display the - /// content of the symbol table while debugging. - /// @brief Print out symbol table on stderr - void dump() const; - -/// @} -/// @name Iteration -/// @{ -public: - /// Get an iterator to the start of the symbol table - inline iterator begin() { return tmap.begin(); } - - /// @brief Get a const_iterator to the start of the symbol table - inline const_iterator begin() const { return tmap.begin(); } - - /// Get an iterator to the end of the symbol table. - inline iterator end() { return tmap.end(); } - - /// Get a const_iterator to the end of the symbol table. - inline const_iterator end() const { return tmap.end(); } - -/// @} -/// @name Mutators -/// @{ -public: - - /// Inserts a type into the symbol table with the specified name. There can be - /// a many-to-one mapping between names and types. This method allows a type - /// with an existing entry in the symbol table to get a new name. - /// @brief Insert a type under a new name. - void insert(StringRef Name, const Type *Typ); - - /// Remove a type at the specified position in the symbol table. - /// @returns the removed Type. - /// @returns the Type that was erased from the symbol table. - Type* remove(iterator TI); - -/// @} -/// @name AbstractTypeUser Methods -/// @{ -private: - /// This function is called when one of the types in the type plane - /// is refined. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - - /// This function marks a type as being concrete (defined). - virtual void typeBecameConcrete(const DerivedType *AbsTy); - -/// @} -/// @name Internal Data -/// @{ -private: - TypeMap tmap; ///< This is the mapping of names to types. - mutable uint32_t LastUnique; ///< Counter for tracking unique names - -/// @} - -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Use.h b/include/llvm/Use.h index ccbdd7f..a496325 100644 --- a/include/llvm/Use.h +++ b/include/llvm/Use.h @@ -60,6 +60,10 @@ public: /// that also works with less standard-compliant compilers void swap(Use &RHS); + // A type for the word following an array of hung-off Uses in memory, which is + // a pointer back to their User with the bottom bit set. + typedef PointerIntPair<User*, 1, unsigned> UserRef; + private: /// Copy ctor - do not implement Use(const Use &U); @@ -108,13 +112,16 @@ public: Use *getNext() const { return Next; } + /// initTags - initialize the waymarking tags on an array of Uses, so that + /// getUser() can find the User from any of those Uses. + static Use *initTags(Use *Start, Use *Stop); + /// zap - This is used to destroy Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); private: const Use* getImpliedUser() const; - static Use *initTags(Use *Start, Use *Stop); Value *Val; Use *Next; @@ -136,7 +143,6 @@ private: } friend class Value; - friend class User; }; // simplify_type - Allow clients to treat uses just like values when using @@ -208,15 +214,6 @@ public: unsigned getOperandNo() const; }; -//===----------------------------------------------------------------------===// -// AugmentedUse layout struct -//===----------------------------------------------------------------------===// - -struct AugmentedUse : public Use { - PointerIntPair<User*, 1, unsigned> ref; - AugmentedUse(); // not implemented -}; - } // End llvm namespace #endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 3a1c3ca..08fa1c9 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -14,7 +14,6 @@ #ifndef LLVM_VALUE_H #define LLVM_VALUE_H -#include "llvm/AbstractTypeUser.h" #include "llvm/Use.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -32,7 +31,6 @@ class GlobalVariable; class GlobalAlias; class InlineAsm; class ValueSymbolTable; -class TypeSymbolTable; template<typename ValueTy> class StringMapEntry; template <typename ValueTy = Value> class AssertingVH; @@ -43,6 +41,7 @@ class ValueHandleBase; class LLVMContext; class Twine; class MDNode; +class Type; //===----------------------------------------------------------------------===// // Value Class @@ -77,12 +76,11 @@ private: /// This field is initialized to zero by the ctor. unsigned short SubclassData; - PATypeHolder VTy; + Type *VTy; Use *UseList; friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. friend class ValueHandleBase; - friend class AbstractTypeUser; ValueName *Name; void operator=(const Value &); // Do not implement @@ -107,13 +105,13 @@ public: /// All values are typed, get the type of this value. /// - inline const Type *getType() const { return VTy; } + Type *getType() const { return VTy; } /// All values hold a context through their type. LLVMContext &getContext() const; // All values can potentially be named... - inline bool hasName() const { return Name != 0; } + bool hasName() const { return Name != 0; } ValueName *getValueName() const { return Name; } /// getName() - Return a constant reference to the value's name. This is cheap @@ -149,10 +147,6 @@ public: /// void replaceAllUsesWith(Value *V); - // uncheckedReplaceAllUsesWith - Just like replaceAllUsesWith but dangerous. - // Only use when in type resolution situations! - void uncheckedReplaceAllUsesWith(Value *V); - //---------------------------------------------------------------------- // Methods for handling the chain of uses of this Value. // @@ -279,10 +273,6 @@ public: return true; // Values are always values. } - /// getRawType - This should only be used to implement the vmcore library. - /// - const Type *getRawType() const { return VTy.getRawType(); } - /// stripPointerCasts - This method strips off any unneeded pointer /// casts from the specified value, returning the original uncasted value. /// Note that the returned value has pointer type if the specified value does. @@ -310,6 +300,15 @@ public: /// load, store, and alloca instructions, and global values. static const unsigned MaximumAlignment = 1u << 29; + /// mutateType - Mutate the type of this Value to be of the specified type. + /// Note that this is an extremely dangerous operation which can create + /// completely invalid IR very easily. It is strongly recommended that you + /// recreate IR objects with the right types instead of mutating them in + /// place. + void mutateType(Type *Ty) { + VTy = Ty; + } + protected: unsigned short getSubclassDataFromValue() const { return SubclassData; } void setValueSubclassData(unsigned short D) { SubclassData = D; } |