diff options
Diffstat (limited to 'include')
76 files changed, 2003 insertions, 582 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 8cf03c268cd..620d0887be7 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg); * Set the alignment for a function parameter. * * @see llvm::Argument::addAttr() - * @see llvm::Attributes::constructAlignmentFromInt() + * @see llvm::AttrBuilder::addAlignmentAttr() */ void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align); diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index 92228701e31..57abfa0207f 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -172,10 +172,20 @@ enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef); See the method llvm::DataLayout::getPointerSize. */ unsigned LLVMPointerSize(LLVMTargetDataRef); +/** Returns the pointer size in bytes for a target for a specified + address space. + See the method llvm::DataLayout::getPointerSize. */ +unsigned LLVMPointerSizeForAS(LLVMTargetDataRef, unsigned AS); + /** Returns the integer type that is the same size as a pointer on a target. See the method llvm::DataLayout::getIntPtrType. */ LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef); +/** Returns the integer type that is the same size as a pointer on a target. + This version allows the address space to be specified. + See the method llvm::DataLayout::getIntPtrType. */ +LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef, unsigned AS); + /** Computes the size of a type in bytes for a target. See the method llvm::DataLayout::getTypeSizeInBits. */ unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef); diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 26ec346b182..9d6388f7ee6 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -237,6 +237,34 @@ public: return *this; } + /// set - Efficiently set a range of bits in [I, E) + BitVector &set(unsigned I, unsigned E) { + assert(I <= E && "Attempted to set backwards range!"); + assert(E <= size() && "Attempted to set out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] |= Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] |= PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = ~0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + Bits[I / BITWORD_SIZE] |= PostfixMask; + + return *this; + } + BitVector &reset() { init_words(Bits, Capacity, false); return *this; @@ -247,6 +275,34 @@ public: return *this; } + /// reset - Efficiently reset a range of bits in [I, E) + BitVector &reset(unsigned I, unsigned E) { + assert(I <= E && "Attempted to reset backwards range!"); + assert(E <= size() && "Attempted to reset out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] &= ~Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] &= ~PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = 0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + Bits[I / BITWORD_SIZE] &= ~PostfixMask; + + return *this; + } + BitVector &flip() { for (unsigned i = 0; i < NumBitWords(size()); ++i) Bits[i] = ~Bits[i]; diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 261d0494e2d..3900f96be16 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -89,7 +89,7 @@ public: ImutAVLTree* getMaxElement() { ImutAVLTree *T = this; ImutAVLTree *Right = T->getRight(); - while (Right) { T = right; right = T->getRight(); } + while (Right) { T = Right; Right = T->getRight(); } return T; } diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 7a645e0c724..fba1d12542a 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -300,6 +300,21 @@ public: return *this; } + /// set - Efficiently set a range of bits in [I, E) + SmallBitVector &set(unsigned I, unsigned E) { + assert(I <= E && "Attempted to set backwards range!"); + assert(E <= size() && "Attempted to set out-of-bounds range!"); + if (I == E) return *this; + if (isSmall()) { + uintptr_t EMask = 1 << E; + uintptr_t IMask = 1 << I; + uintptr_t Mask = EMask - IMask; + setSmallBits(getSmallBits() | Mask); + } else + getPointer()->set(I, E); + return *this; + } + SmallBitVector &reset() { if (isSmall()) setSmallBits(0); @@ -316,6 +331,21 @@ public: return *this; } + /// reset - Efficiently reset a range of bits in [I, E) + SmallBitVector &reset(unsigned I, unsigned E) { + assert(I <= E && "Attempted to reset backwards range!"); + assert(E <= size() && "Attempted to reset out-of-bounds range!"); + if (I == E) return *this; + if (isSmall()) { + uintptr_t EMask = 1 << E; + uintptr_t IMask = 1 << I; + uintptr_t Mask = EMask - IMask; + setSmallBits(getSmallBits() & ~Mask); + } else + getPointer()->reset(I, E); + return *this; + } + SmallBitVector &flip() { if (isSmall()) setSmallBits(~getSmallBits()); diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index a0527683f67..15fe55fbe3b 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -76,7 +76,8 @@ public: SCEI, BGP, BGQ, - Freescale + Freescale, + IBM }; enum OSType { UnknownOS, @@ -101,7 +102,8 @@ public: RTEMS, NativeClient, CNK, // BG/P Compute-Node Kernel - Bitrig + Bitrig, + AIX }; enum EnvironmentType { UnknownEnvironment, diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h new file mode 100644 index 00000000000..9b6a6bbd3ed --- /dev/null +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -0,0 +1,891 @@ +//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// DependenceAnalysis is an LLVM pass that analyses dependences between memory +// accesses. Currently, it is an implementation of the approach described in +// +// Practical Dependence Testing +// Goff, Kennedy, Tseng +// PLDI 1991 +// +// There's a single entry point that analyzes the dependence between a pair +// of memory references in a function, returning either NULL, for no dependence, +// or a more-or-less detailed description of the dependence between them. +// +// Please note that this is work in progress and the interface is subject to +// change. +// +// Plausible changes: +// Return a set of more precise dependences instead of just one dependence +// summarizing all. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H +#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H + +#include "llvm/BasicBlock.h" +#include "llvm/Function.h" +#include "llvm/Instruction.h" +#include "llvm/Pass.h" +#include "llvm/ADT/SmallBitVector.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Support/raw_ostream.h" + + +namespace llvm { + class AliasAnalysis; + class ScalarEvolution; + class SCEV; + class Value; + class raw_ostream; + + /// Dependence - This class represents a dependence between two memory + /// memory references in a function. It contains minimal information and + /// is used in the very common situation where the compiler is unable to + /// determine anything beyond the existence of a dependence; that is, it + /// represents a confused dependence (see also FullDependence). In most + /// cases (for output, flow, and anti dependences), the dependence implies + /// an ordering, where the source must preceed the destination; in contrast, + /// input dependences are unordered. + class Dependence { + public: + Dependence(const Instruction *Source, + const Instruction *Destination) : + Src(Source), Dst(Destination) {} + virtual ~Dependence() {} + + /// Dependence::DVEntry - Each level in the distance/direction vector + /// has a direction (or perhaps a union of several directions), and + /// perhaps a distance. + struct DVEntry { + enum { NONE = 0, + LT = 1, + EQ = 2, + LE = 3, + GT = 4, + NE = 5, + GE = 6, + ALL = 7 }; + unsigned char Direction : 3; // Init to ALL, then refine. + bool Scalar : 1; // Init to true. + bool PeelFirst : 1; // Peeling the first iteration will break dependence. + bool PeelLast : 1; // Peeling the last iteration will break the dependence. + bool Splitable : 1; // Splitting the loop will break dependence. + const SCEV *Distance; // NULL implies no distance available. + DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false), + PeelLast(false), Splitable(false), Distance(NULL) { } + }; + + /// getSrc - Returns the source instruction for this dependence. + /// + const Instruction *getSrc() const { return Src; } + + /// getDst - Returns the destination instruction for this dependence. + /// + const Instruction *getDst() const { return Dst; } + + /// isInput - Returns true if this is an input dependence. + /// + bool isInput() const; + + /// isOutput - Returns true if this is an output dependence. + /// + bool isOutput() const; + + /// isFlow - Returns true if this is a flow (aka true) dependence. + /// + bool isFlow() const; + + /// isAnti - Returns true if this is an anti dependence. + /// + bool isAnti() const; + + /// isOrdered - Returns true if dependence is Output, Flow, or Anti + /// + bool isOrdered() const { return isOutput() || isFlow() || isAnti(); } + + /// isUnordered - Returns true if dependence is Input + /// + bool isUnordered() const { return isInput(); } + + /// isLoopIndependent - Returns true if this is a loop-independent + /// dependence. + virtual bool isLoopIndependent() const { return true; } + + /// isConfused - Returns true if this dependence is confused + /// (the compiler understands nothing and makes worst-case + /// assumptions). + virtual bool isConfused() const { return true; } + + /// isConsistent - Returns true if this dependence is consistent + /// (occurs every time the source and destination are executed). + virtual bool isConsistent() const { return false; } + + /// getLevels - Returns the number of common loops surrounding the + /// souce and destination of the dependence. + virtual unsigned getLevels() const { return 0; } + + /// getDirection - Returns the direction associated with a particular + /// level. + virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; } + + /// getDistance - Returns the distance (or NULL) associated with a + /// particular level. + virtual const SCEV *getDistance(unsigned Level) const { return NULL; } + + /// isPeelFirst - Returns true if peeling the first iteration from + /// this loop will break this dependence. + virtual bool isPeelFirst(unsigned Level) const { return false; } + + /// isPeelLast - Returns true if peeling the last iteration from + /// this loop will break this dependence. + virtual bool isPeelLast(unsigned Level) const { return false; } + + /// isSplitable - Returns true if splitting this loop will break + /// the dependence. + virtual bool isSplitable(unsigned Level) const { return false; } + + /// isScalar - Returns true if a particular level is scalar; that is, + /// if no subscript in the source or destination mention the induction + /// variable associated with the loop at this level. + virtual bool isScalar(unsigned Level) const; + + /// dump - For debugging purposes, dumps a dependence to OS. + /// + void dump(raw_ostream &OS) const; + private: + const Instruction *Src, *Dst; + friend class DependenceAnalysis; + }; + + + /// FullDependence - This class represents a dependence between two memory + /// references in a function. It contains detailed information about the + /// dependence (direction vectors, etc) and is used when the compiler is + /// able to accurately analyze the interaction of the references; that is, + /// it is not a confused dependence (see Dependence). In most cases + /// (for output, flow, and anti dependences), the dependence implies an + /// ordering, where the source must preceed the destination; in contrast, + /// input dependences are unordered. + class FullDependence : public Dependence { + public: + FullDependence(const Instruction *Src, + const Instruction *Dst, + bool LoopIndependent, + unsigned Levels); + ~FullDependence() { + delete DV; + } + + /// isLoopIndependent - Returns true if this is a loop-independent + /// dependence. + bool isLoopIndependent() const { return LoopIndependent; } + + /// isConfused - Returns true if this dependence is confused + /// (the compiler understands nothing and makes worst-case + /// assumptions). + bool isConfused() const { return false; } + + /// isConsistent - Returns true if this dependence is consistent + /// (occurs every time the source and destination are executed). + bool isConsistent() const { return Consistent; } + + /// getLevels - Returns the number of common loops surrounding the + /// souce and destination of the dependence. + unsigned getLevels() const { return Levels; } + + /// getDirection - Returns the direction associated with a particular + /// level. + unsigned getDirection(unsigned Level) const; + + /// getDistance - Returns the distance (or NULL) associated with a + /// particular level. + const SCEV *getDistance(unsigned Level) const; + + /// isPeelFirst - Returns true if peeling the first iteration from + /// this loop will break this dependence. + bool isPeelFirst(unsigned Level) const; + + /// isPeelLast - Returns true if peeling the last iteration from + /// this loop will break this dependence. + bool isPeelLast(unsigned Level) const; + + /// isSplitable - Returns true if splitting the loop will break + /// the dependence. + bool isSplitable(unsigned Level) const; + + /// isScalar - Returns true if a particular level is scalar; that is, + /// if no subscript in the source or destination mention the induction + /// variable associated with the loop at this level. + bool isScalar(unsigned Level) const; + private: + unsigned short Levels; + bool LoopIndependent; + bool Consistent; // Init to true, then refine. + DVEntry *DV; + friend class DependenceAnalysis; + }; + + + /// DependenceAnalysis - This class is the main dependence-analysis driver. + /// + class DependenceAnalysis : public FunctionPass { + void operator=(const DependenceAnalysis &); // do not implement + DependenceAnalysis(const DependenceAnalysis &); // do not implement + public: + /// depends - Tests for a dependence between the Src and Dst instructions. + /// Returns NULL if no dependence; otherwise, returns a Dependence (or a + /// FullDependence) with as much information as can be gleaned. + /// The flag PossiblyLoopIndependent should be set by the caller + /// if it appears that control flow can reach from Src to Dst + /// without traversing a loop back edge. + Dependence *depends(const Instruction *Src, + const Instruction *Dst, + bool PossiblyLoopIndependent); + + /// getSplitIteration - Give a dependence that's splitable at some + /// particular level, return the iteration that should be used to split + /// the loop. + /// + /// Generally, the dependence analyzer will be used to build + /// a dependence graph for a function (basically a map from instructions + /// to dependences). Looking for cycles in the graph shows us loops + /// that cannot be trivially vectorized/parallelized. + /// + /// We can try to improve the situation by examining all the dependences + /// that make up the cycle, looking for ones we can break. + /// Sometimes, peeling the first or last iteration of a loop will break + /// dependences, and there are flags for those possibilities. + /// Sometimes, splitting a loop at some other iteration will do the trick, + /// and we've got a flag for that case. Rather than waste the space to + /// record the exact iteration (since we rarely know), we provide + /// a method that calculates the iteration. It's a drag that it must work + /// from scratch, but wonderful in that it's possible. + /// + /// Here's an example: + /// + /// for (i = 0; i < 10; i++) + /// A[i] = ... + /// ... = A[11 - i] + /// + /// There's a loop-carried flow dependence from the store to the load, + /// found by the weak-crossing SIV test. The dependence will have a flag, + /// indicating that the dependence can be broken by splitting the loop. + /// Calling getSplitIteration will return 5. + /// Splitting the loop breaks the dependence, like so: + /// + /// for (i = 0; i <= 5; i++) + /// A[i] = ... + /// ... = A[11 - i] + /// for (i = 6; i < 10; i++) + /// A[i] = ... + /// ... = A[11 - i] + /// + /// breaks the dependence and allows us to vectorize/parallelize + /// both loops. + const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level); + + private: + AliasAnalysis *AA; + ScalarEvolution *SE; + LoopInfo *LI; + Function *F; + + /// Subscript - This private struct represents a pair of subscripts from + /// a pair of potentially multi-dimensional array references. We use a + /// vector of them to guide subscript partitioning. + struct Subscript { + const SCEV *Src; + const SCEV *Dst; + enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification; + SmallBitVector Loops; + SmallBitVector GroupLoops; + SmallBitVector Group; + }; + + struct CoefficientInfo { + const SCEV *Coeff; + const SCEV *PosPart; + const SCEV *NegPart; + const SCEV *Iterations; + }; + + struct BoundInfo { + const SCEV *Iterations; + const SCEV *Upper[8]; + const SCEV *Lower[8]; + unsigned char Direction; + unsigned char DirSet; + }; + + /// Constraint - This private class represents a constraint, as defined + /// in the paper + /// + /// Practical Dependence Testing + /// Goff, Kennedy, Tseng + /// PLDI 1991 + /// + /// There are 5 kinds of constraint, in a hierarchy. + /// 1) Any - indicates no constraint, any dependence is possible. + /// 2) Line - A line ax + by = c, where a, b, and c are parameters, + /// representing the dependence equation. + /// 3) Distance - The value d of the dependence distance; + /// 4) Point - A point <x, y> representing the dependence from + /// iteration x to iteration y. + /// 5) Empty - No dependence is possible. + class Constraint { + private: + enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind; + ScalarEvolution *SE; + const SCEV *A; + const SCEV *B; + const SCEV *C; + const Loop *AssociatedLoop; + public: + /// isEmpty - Return true if the constraint is of kind Empty. + bool isEmpty() const { return Kind == Empty; } + + /// isPoint - Return true if the constraint is of kind Point. + bool isPoint() const { return Kind == Point; } + + /// isDistance - Return true if the constraint is of kind Distance. + bool isDistance() const { return Kind == Distance; } + + /// isLine - Return true if the constraint is of kind Line. + /// Since Distance's can also be represented as Lines, we also return + /// true if the constraint is of kind Distance. + bool isLine() const { return Kind == Line || Kind == Distance; } + + /// isAny - Return true if the constraint is of kind Any; + bool isAny() const { return Kind == Any; } + + /// getX - If constraint is a point <X, Y>, returns X. + /// Otherwise assert. + const SCEV *getX() const; + + /// getY - If constraint is a point <X, Y>, returns Y. + /// Otherwise assert. + const SCEV *getY() const; + + /// getA - If constraint is a line AX + BY = C, returns A. + /// Otherwise assert. + const SCEV *getA() const; + + /// getB - If constraint is a line AX + BY = C, returns B. + /// Otherwise assert. + const SCEV *getB() const; + + /// getC - If constraint is a line AX + BY = C, returns C. + /// Otherwise assert. + const SCEV *getC() const; + + /// getD - If constraint is a distance, returns D. + /// Otherwise assert. + const SCEV *getD() const; + + /// getAssociatedLoop - Returns the loop associated with this constraint. + const Loop *getAssociatedLoop() const; + + /// setPoint - Change a constraint to Point. + void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop); + + /// setLine - Change a constraint to Line. + void setLine(const SCEV *A, const SCEV *B, + const SCEV *C, const Loop *CurrentLoop); + + /// setDistance - Change a constraint to Distance. + void setDistance(const SCEV *D, const Loop *CurrentLoop); + + /// setEmpty - Change a constraint to Empty. + void setEmpty(); + + /// setAny - Change a constraint to Any. + void setAny(ScalarEvolution *SE); + + /// dump - For debugging purposes. Dumps the constraint + /// out to OS. + void dump(raw_ostream &OS) const; + }; + + + /// establishNestingLevels - Examines the loop nesting of the Src and Dst + /// instructions and establishes their shared loops. Sets the variables + /// CommonLevels, SrcLevels, and MaxLevels. + /// The source and destination instructions needn't be contained in the same + /// loop. The routine establishNestingLevels finds the level of most deeply + /// nested loop that contains them both, CommonLevels. An instruction that's + /// not contained in a loop is at level = 0. MaxLevels is equal to the level + /// of the source plus the level of the destination, minus CommonLevels. + /// This lets us allocate vectors MaxLevels in length, with room for every + /// distinct loop referenced in both the source and destination subscripts. + /// The variable SrcLevels is the nesting depth of the source instruction. + /// It's used to help calculate distinct loops referenced by the destination. + /// Here's the map from loops to levels: + /// 0 - unused + /// 1 - outermost common loop + /// ... - other common loops + /// CommonLevels - innermost common loop + /// ... - loops containing Src but not Dst + /// SrcLevels - innermost loop containing Src but not Dst + /// ... - loops containing Dst but not Src + /// MaxLevels - innermost loop containing Dst but not Src + /// Consider the follow code fragment: + /// for (a = ...) { + /// for (b = ...) { + /// for (c = ...) { + /// for (d = ...) { + /// A[] = ...; + /// } + /// } + /// for (e = ...) { + /// for (f = ...) { + /// for (g = ...) { + /// ... = A[]; + /// } + /// } + /// } + /// } + /// } + /// If we're looking at the possibility of a dependence between the store + /// to A (the Src) and the load from A (the Dst), we'll note that they + /// have 2 loops in common, so CommonLevels will equal 2 and the direction + /// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7. + /// A map from loop names to level indices would look like + /// a - 1 + /// b - 2 = CommonLevels + /// c - 3 + /// d - 4 = SrcLevels + /// e - 5 + /// f - 6 + /// g - 7 = MaxLevels + void establishNestingLevels(const Instruction *Src, + const Instruction *Dst); + + unsigned CommonLevels, SrcLevels, MaxLevels; + + /// mapSrcLoop - Given one of the loops containing the source, return + /// its level index in our numbering scheme. + unsigned mapSrcLoop(const Loop *SrcLoop) const; + + /// mapDstLoop - Given one of the loops containing the destination, + /// return its level index in our numbering scheme. + unsigned mapDstLoop(const Loop *DstLoop) const; + + /// isLoopInvariant - Returns true if Expression is loop invariant + /// in LoopNest. + bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const; + + /// removeMatchingExtensions - Examines a subscript pair. + /// If the source and destination are identically sign (or zero) + /// extended, it strips off the extension in an effort to + /// simplify the actual analysis. + void removeMatchingExtensions(Subscript *Pair); + + /// collectCommonLoops - Finds the set of loops from the LoopNest that + /// have a level <= CommonLevels and are referred to by the SCEV Expression. + void collectCommonLoops(const SCEV *Expression, + const Loop *LoopNest, + SmallBitVector &Loops) const; + + /// checkSrcSubscript - Examines the SCEV Src, returning true iff it's + /// linear. Collect the set of loops mentioned by Src. + bool checkSrcSubscript(const SCEV *Src, + const Loop *LoopNest, + SmallBitVector &Loops); + + /// checkDstSubscript - Examines the SCEV Dst, returning true iff it's + /// linear. Collect the set of loops mentioned by Dst. + bool checkDstSubscript(const SCEV *Dst, + const Loop *LoopNest, + SmallBitVector &Loops); + + /// isKnownPredicate - Compare X and Y using the predicate Pred. + /// Basically a wrapper for SCEV::isKnownPredicate, + /// but tries harder, especially in the presense of sign and zero + /// extensions and symbolics. + bool isKnownPredicate(ICmpInst::Predicate Pred, + const SCEV *X, + const SCEV *Y) const; + + /// collectUpperBound - All subscripts are the same type (on my machine, + /// an i64). The loop bound may be a smaller type. collectUpperBound + /// find the bound, if available, and zero extends it to the Type T. + /// (I zero extend since the bound should always be >= 0.) + /// If no upper bound is available, return NULL. + const SCEV *collectUpperBound(const Loop *l, Type *T) const; + + /// collectConstantUpperBound - Calls collectUpperBound(), then + /// attempts to cast it to SCEVConstant. If the cast fails, + /// returns NULL. + const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const; + + /// classifyPair - Examines the subscript pair (the Src and Dst SCEVs) + /// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear. + /// Collects the associated loops in a set. + Subscript::ClassificationKind classifyPair(const SCEV *Src, + const Loop *SrcLoopNest, + const SCEV *Dst, + const Loop *DstLoopNest, + SmallBitVector &Loops); + + /// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// If the dependence isn't proven to exist, + /// marks the Result as inconsistent. + bool testZIV(const SCEV *Src, + const SCEV *Dst, + FullDependence &Result) const; + + /// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence. + /// Things of the form [c1 + a1*i] and [c2 + a2*j], where + /// i and j are induction variables, c1 and c2 are loop invariant, + /// and a1 and a2 are constant. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction vector entry and, when possible, + /// the distance vector entry. + /// If the dependence isn't proven to exist, + /// marks the Result as inconsistent. + bool testSIV(const SCEV *Src, + const SCEV *Dst, + unsigned &Level, + FullDependence &Result, + Constraint &NewConstraint, + const SCEV *&SplitIter) const; + + /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence. + /// Things of the form [c1 + a1*i] and [c2 + a2*j] + /// where i and j are induction variables, c1 and c2 are loop invariant, + /// and a1 and a2 are constant. + /// With minor algebra, this test can also be used for things like + /// [c1 + a1*i + a2*j][c2]. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Marks the Result as inconsistent. + bool testRDIV(const SCEV *Src, + const SCEV *Dst, + FullDependence &Result) const; + + /// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence. + /// Returns true if dependence disproved. + /// Can sometimes refine direction vectors. + bool testMIV(const SCEV *Src, + const SCEV *Dst, + const SmallBitVector &Loops, + FullDependence &Result) const; + + /// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst) + /// for dependence. + /// Things of the form [c1 + a*i] and [c2 + a*i], + /// where i is an induction variable, c1 and c2 are loop invariant, + /// and a is a constant + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction and distance. + bool strongSIVtest(const SCEV *Coeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *CurrentLoop, + unsigned Level, + FullDependence &Result, + Constraint &NewConstraint) const; + + /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair + /// (Src and Dst) for dependence. + /// Things of the form [c1 + a*i] and [c2 - a*i], + /// where i is an induction variable, c1 and c2 are loop invariant, + /// and a is a constant. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction entry. + /// Set consistent to false. + /// Marks the dependence as splitable. + bool weakCrossingSIVtest(const SCEV *SrcCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *CurrentLoop, + unsigned Level, + FullDependence &Result, + Constraint &NewConstraint, + const SCEV *&SplitIter) const; + + /// ExactSIVtest - Tests the SIV subscript pair + /// (Src and Dst) for dependence. + /// Things of the form [c1 + a1*i] and [c2 + a2*i], + /// where i is an induction variable, c1 and c2 are loop invariant, + /// and a1 and a2 are constant. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction entry. + /// Set consistent to false. + bool exactSIVtest(const SCEV *SrcCoeff, + const SCEV *DstCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *CurrentLoop, + unsigned Level, + FullDependence &Result, + Constraint &NewConstraint) const; + + /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair + /// (Src and Dst) for dependence. + /// Things of the form [c1] and [c2 + a*i], + /// where i is an induction variable, c1 and c2 are loop invariant, + /// and a is a constant. See also weakZeroDstSIVtest. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction entry. + /// Set consistent to false. + /// If loop peeling will break the dependence, mark appropriately. + bool weakZeroSrcSIVtest(const SCEV *DstCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *CurrentLoop, + unsigned Level, + FullDependence &Result, + Constraint &NewConstraint) const; + + /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair + /// (Src and Dst) for dependence. + /// Things of the form [c1 + a*i] and [c2], + /// where i is an induction variable, c1 and c2 are loop invariant, + /// and a is a constant. See also weakZeroSrcSIVtest. + /// Returns true if any possible dependence is disproved. + /// If there might be a dependence, returns false. + /// Sets appropriate direction entry. + /// Set consistent to false. + /// If loop peeling will break the dependence, mark appropriately. + bool weakZeroDstSIVtest(const SCEV *SrcCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *CurrentLoop, + unsigned Level, + FullDependence &Result, + Constraint &NewConstraint) const; + + /// exactRDIVtest - Tests the RDIV subscript pair for dependence. + /// Things of the form [c1 + a*i] and [c2 + b*j], + /// where i and j are induction variable, c1 and c2 are loop invariant, + /// and a and b are constants. + /// Returns true if any possible dependence is disproved. + /// Marks the result as inconsistant. + /// Works in some cases that symbolicRDIVtest doesn't, + /// and vice versa. + bool exactRDIVtest(const SCEV *SrcCoeff, + const SCEV *DstCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *SrcLoop, + const Loop *DstLoop, + FullDependence &Result) const; + + /// symbolicRDIVtest - Tests the RDIV subscript pair for dependence. + /// Things of the form [c1 + a*i] and [c2 + b*j], + /// where i and j are induction variable, c1 and c2 are loop invariant, + /// and a and b are constants. + /// Returns true if any possible dependence is disproved. + /// Marks the result as inconsistant. + /// Works in some cases that exactRDIVtest doesn't, + /// and vice versa. Can also be used as a backup for + /// ordinary SIV tests. + bool symbolicRDIVtest(const SCEV *SrcCoeff, + const SCEV *DstCoeff, + const SCEV *SrcConst, + const SCEV *DstConst, + const Loop *SrcLoop, + const Loop *DstLoop) const; + + /// gcdMIVtest - Tests an MIV subscript pair for dependence. + /// Returns true if any possible dependence is disproved. + /// Marks the result as inconsistant. + /// Can sometimes disprove the equal direction for 1 or more loops. + // Can handle some symbolics that even the SIV tests don't get, + /// so we use it as a backup for everything. + bool gcdMIVtest(const SCEV *Src, + const SCEV *Dst, + FullDependence &Result) const; + + /// banerjeeMIVtest - Tests an MIV subscript pair for dependence. + /// Returns true if any possible dependence is disproved. + /// Marks the result as inconsistant. + /// Computes directions. + bool banerjeeMIVtest(const SCEV *Src, + const SCEV *Dst, + const SmallBitVector &Loops, + FullDependence &Result) const; + + /// collectCoefficientInfo - Walks through the subscript, + /// collecting each coefficient, the associated loop bounds, + /// and recording its positive and negative parts for later use. + CoefficientInfo *collectCoeffInfo(const SCEV *Subscript, + bool SrcFlag, + const SCEV *&Constant) const; + + /// getPositivePart - X^+ = max(X, 0). + /// + const SCEV *getPositivePart(const SCEV *X) const; + + /// getNegativePart - X^- = min(X, 0). + /// + const SCEV *getNegativePart(const SCEV *X) const; + + /// getLowerBound - Looks through all the bounds info and + /// computes the lower bound given the current direction settings + /// at each level. + const SCEV *getLowerBound(BoundInfo *Bound) const; + + /// getUpperBound - Looks through all the bounds info and + /// computes the upper bound given the current direction settings + /// at each level. + const SCEV *getUpperBound(BoundInfo *Bound) const; + + /// exploreDirections - Hierarchically expands the direction vector + /// search space, combining the directions of discovered dependences + /// in the DirSet field of Bound. Returns the number of distinct + /// dependences discovered. If the dependence is disproved, + /// it will return 0. + unsigned exploreDirections(unsigned Level, + CoefficientInfo *A, + CoefficientInfo *B, + BoundInfo *Bound, + const SmallBitVector &Loops, + unsigned &DepthExpanded, + const SCEV *Delta) const; + + /// testBounds - Returns true iff the current bounds are plausible. + /// + bool testBounds(unsigned char DirKind, + unsigned Level, + BoundInfo *Bound, + const SCEV *Delta) const; + + /// findBoundsALL - Computes the upper and lower bounds for level K + /// using the * direction. Records them in Bound. + void findBoundsALL(CoefficientInfo *A, + CoefficientInfo *B, + BoundInfo *Bound, + unsigned K) const; + + /// findBoundsLT - Computes the upper and lower bounds for level K + /// using the < direction. Records them in Bound. + void findBoundsLT(CoefficientInfo *A, + CoefficientInfo *B, + BoundInfo *Bound, + unsigned K) const; + + /// findBoundsGT - Computes the upper and lower bounds for level K + /// using the > direction. Records them in Bound. + void findBoundsGT(CoefficientInfo *A, + CoefficientInfo *B, + BoundInfo *Bound, + unsigned K) const; + + /// findBoundsEQ - Computes the upper and lower bounds for level K + /// using the = direction. Records them in Bound. + void findBoundsEQ(CoefficientInfo *A, + CoefficientInfo *B, + BoundInfo *Bound, + unsigned K) const; + + /// intersectConstraints - Updates X with the intersection + /// of the Constraints X and Y. Returns true if X has changed. + bool intersectConstraints(Constraint *X, + const Constraint *Y); + + /// propagate - Review the constraints, looking for opportunities + /// to simplify a subscript pair (Src and Dst). + /// Return true if some simplification occurs. + /// If the simplification isn't exact (that is, if it is conservative + /// in terms of dependence), set consistent to false. + bool propagate(const SCEV *&Src, + const SCEV *&Dst, + SmallBitVector &Loops, + SmallVector<Constraint, 4> &Constraints, + bool &Consistent); + + /// propagateDistance - Attempt to propagate a distance + /// constraint into a subscript pair (Src and Dst). + /// Return true if some simplification occurs. + /// If the simplification isn't exact (that is, if it is conservative + /// in terms of dependence), set consistent to false. + bool propagateDistance(const SCEV *&Src, + const SCEV *&Dst, + Constraint &CurConstraint, + bool &Consistent); + + /// propagatePoint - Attempt to propagate a point + /// constraint into a subscript pair (Src and Dst). + /// Return true if some simplification occurs. + bool propagatePoint(const SCEV *&Src, + const SCEV *&Dst, + Constraint &CurConstraint); + + /// propagateLine - Attempt to propagate a line + /// constraint into a subscript pair (Src and Dst). + /// Return true if some simplification occurs. + /// If the simplification isn't exact (that is, if it is conservative + /// in terms of dependence), set consistent to false. + bool propagateLine(const SCEV *&Src, + const SCEV *&Dst, + Constraint &CurConstraint, + bool &Consistent); + + /// findCoefficient - Given a linear SCEV, + /// return the coefficient corresponding to specified loop. + /// If there isn't one, return the SCEV constant 0. + /// For example, given a*i + b*j + c*k, returning the coefficient + /// corresponding to the j loop would yield b. + const SCEV *findCoefficient(const SCEV *Expr, + const Loop *TargetLoop) const; + + /// zeroCoefficient - Given a linear SCEV, + /// return the SCEV given by zeroing out the coefficient + /// corresponding to the specified loop. + /// For example, given a*i + b*j + c*k, zeroing the coefficient + /// corresponding to the j loop would yield a*i + c*k. + const SCEV *zeroCoefficient(const SCEV *Expr, + const Loop *TargetLoop) const; + + /// addToCoefficient - Given a linear SCEV Expr, + /// return the SCEV given by adding some Value to the + /// coefficient corresponding to the specified TargetLoop. + /// For example, given a*i + b*j + c*k, adding 1 to the coefficient + /// corresponding to the j loop would yield a*i + (b+1)*j + c*k. + const SCEV *addToCoefficient(const SCEV *Expr, + const Loop *TargetLoop, + const SCEV *Value) const; + + /// updateDirection - Update direction vector entry + /// based on the current constraint. + void updateDirection(Dependence::DVEntry &Level, + const Constraint &CurConstraint) const; + public: + static char ID; // Class identification, replacement for typeinfo + DependenceAnalysis() : FunctionPass(ID) { + initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F); + void releaseMemory(); + void getAnalysisUsage(AnalysisUsage &) const; + void print(raw_ostream &, const Module * = 0) const; + }; // class DependenceAnalysis + + /// createDependenceAnalysisPass - This creates an instance of the + /// DependenceAnalysis pass. + FunctionPass *createDependenceAnalysisPass(); + +} // namespace llvm + +#endif diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index c52f846b5ca..c127830e0e5 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -180,11 +180,20 @@ namespace llvm { //===--------------------------------------------------------------------===// // + // createDependenceAnalysisPass - This creates an instance of the + // DependenceAnalysis pass. + // + FunctionPass *createDependenceAnalysisPass(); + + //===--------------------------------------------------------------------===// + // // createLoopDependenceAnalysisPass - This creates an instance of the // LoopDependenceAnalysis pass. // LoopPass *createLoopDependenceAnalysisPass(); + //===--------------------------------------------------------------------===// + // // Minor pass prototypes, allowing us to expose them through bugpoint and // analyze. FunctionPass *createInstCountPass(); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index a055195352a..67c9a4d14fe 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -162,7 +162,6 @@ namespace llvm { SCEVCouldNotCompute(); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVCouldNotCompute *S) { return true; } static bool classof(const SCEV *S); }; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 3f8f149cb42..3ab9c8256bb 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -22,7 +22,7 @@ #include <set> namespace llvm { - class TargetLowering; + class ScalarTargetTransformInfo; /// Return true if the given expression is safe to expand in the sense that /// all materialized values are safe to speculate. @@ -129,7 +129,7 @@ namespace llvm { /// representative. Return the number of phis eliminated. unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, SmallVectorImpl<WeakVH> &DeadInsts, - const TargetLowering *TLI = NULL); + const ScalarTargetTransformInfo *STTI = NULL); /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index ded12974fac..54db7d6bcf0 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -46,7 +46,6 @@ namespace llvm { Type *getType() const { return V->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVConstant *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scConstant; } @@ -68,7 +67,6 @@ namespace llvm { Type *getType() const { return Ty; } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVCastExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate || S->getSCEVType() == scZeroExtend || @@ -88,7 +86,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVTruncateExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate; } @@ -106,7 +103,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVZeroExtendExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scZeroExtend; } @@ -124,7 +120,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVSignExtendExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scSignExtend; } @@ -166,7 +161,6 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVNAryExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr || @@ -188,7 +182,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVCommutativeExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr || @@ -223,7 +216,6 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr; } @@ -242,7 +234,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVMulExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scMulExpr; } @@ -274,7 +265,6 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUDivExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scUDivExpr; } @@ -358,7 +348,6 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddRecExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddRecExpr; } @@ -380,7 +369,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVSMaxExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; } @@ -402,7 +390,6 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUMaxExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; } @@ -449,7 +436,6 @@ namespace llvm { Type *getType() const { return getValPtr()->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUnknown *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; } diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index 1155b974ecd..b1c22185191 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -81,7 +81,6 @@ public: /// classof - Methods for support type inquiry through isa, cast, and /// dyn_cast: /// - static inline bool classof(const Argument *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == ArgumentVal; } diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index d20a47a286e..a28aa183473 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -15,7 +15,6 @@ #ifndef LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H -#include "llvm/AttributesImpl.h" #include "llvm/Support/MathExtras.h" #include "llvm/ADT/ArrayRef.h" #include <cassert> @@ -23,13 +22,11 @@ namespace llvm { +class AttrBuilder; +class AttributesImpl; class LLVMContext; class Type; -/// AttributeImpl - The internal representation of the Attributes class. This is -/// uniquified. -class AttributesImpl; - /// Attributes - A bitset of attributes. class Attributes { public: @@ -37,15 +34,15 @@ public: /// should be treated by optimizations and code generation. This enumeration /// lists the attributes that can be associated with parameters, function /// results or the function itself. - /// + /// /// 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 /// function. - /// + /// /// In a theoretical system that uses tables for profiling and sjlj for /// exceptions, they would be fully independent. In a normal system that uses /// tables for both, the semantics are: - /// + /// /// nil = Needs an entry because an exception might pass by. /// nounwind = No need for an entry /// uwtable = Needs an entry because the ABI says so and because @@ -53,6 +50,7 @@ public: /// uwtable + nounwind = Needs an entry because the ABI says so. enum AttrVal { + // IR-Level Attributes None = 0, ///< No attributes have been set AddressSafety = 1, ///< Address safety checking is on. Alignment = 2, ///< Alignment of parameter (5 bits) @@ -89,74 +87,26 @@ public: ZExt = 27 ///< Zero extended before/after call }; private: - AttributesImpl Attrs; - - explicit Attributes(AttributesImpl *A); + AttributesImpl *Attrs; + Attributes(AttributesImpl *A) : Attrs(A) {} public: Attributes() : Attrs(0) {} - explicit Attributes(uint64_t Val); - Attributes(const Attributes &A); - - class Builder { - friend class Attributes; - uint64_t Bits; - public: - Builder() : Bits(0) {} - Builder(const Attributes &A) : Bits(A.Raw()) {} - - void clear() { Bits = 0; } - - bool hasAttribute(Attributes::AttrVal A) const; - bool hasAttributes() const; - bool hasAttributes(const Attributes &A) const; - bool hasAlignmentAttr() const; - - uint64_t getAlignment() const; - uint64_t getStackAlignment() const; - - Builder &addAttribute(Attributes::AttrVal Val); - Builder &removeAttribute(Attributes::AttrVal Val); - - void addAlignmentAttr(unsigned Align); - void addStackAlignmentAttr(unsigned Align); - - void removeAttributes(const Attributes &A); - - /// @brief Remove attributes that are used on functions only. - void removeFunctionOnlyAttrs() { - removeAttribute(Attributes::NoReturn) - .removeAttribute(Attributes::NoUnwind) - .removeAttribute(Attributes::ReadNone) - .removeAttribute(Attributes::ReadOnly) - .removeAttribute(Attributes::NoInline) - .removeAttribute(Attributes::AlwaysInline) - .removeAttribute(Attributes::OptimizeForSize) - .removeAttribute(Attributes::StackProtect) - .removeAttribute(Attributes::StackProtectReq) - .removeAttribute(Attributes::NoRedZone) - .removeAttribute(Attributes::NoImplicitFloat) - .removeAttribute(Attributes::Naked) - .removeAttribute(Attributes::InlineHint) - .removeAttribute(Attributes::StackAlignment) - .removeAttribute(Attributes::UWTable) - .removeAttribute(Attributes::NonLazyBind) - .removeAttribute(Attributes::ReturnsTwice) - .removeAttribute(Attributes::AddressSafety); - } - }; + Attributes(const Attributes &A) : Attrs(A.Attrs) {} + Attributes &operator=(const Attributes &A) { + Attrs = A.Attrs; + return *this; + } /// get - Return a uniquified Attributes object. This takes the uniquified /// value from the Builder and wraps it in the Attributes class. - static Attributes get(Builder &B); - static Attributes get(LLVMContext &Context, Builder &B); + static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals); + static Attributes get(LLVMContext &Context, AttrBuilder &B); /// @brief Return true if the attribute is present. bool hasAttribute(AttrVal Val) const; /// @brief Return true if attributes exist - bool hasAttributes() const { - return Attrs.hasAttributes(); - } + bool hasAttributes() const; /// @brief Return true if the attributes are a non-null intersection. bool hasAttributes(const Attributes &A) const; @@ -205,91 +155,29 @@ public: hasAttribute(Attributes::AddressSafety); } - bool isEmptyOrSingleton() const; - - // This is a "safe bool() operator". - operator const void *() const { return Attrs.Bits ? this : 0; } - bool operator == (const Attributes &A) const { - return Attrs.Bits == A.Attrs.Bits; + bool operator==(const Attributes &A) const { + return Attrs == A.Attrs; } - bool operator != (const Attributes &A) const { - return Attrs.Bits != A.Attrs.Bits; + bool operator!=(const Attributes &A) const { + return Attrs != A.Attrs; } - Attributes operator | (const Attributes &A) const; - Attributes operator & (const Attributes &A) const; - Attributes operator ^ (const Attributes &A) const; - Attributes &operator |= (const Attributes &A); - Attributes &operator &= (const Attributes &A); - Attributes operator ~ () const; - uint64_t Raw() const; - /// constructAlignmentFromInt - This turns an int alignment (a power of 2, - /// normally) into the form used internally in Attributes. - static Attributes constructAlignmentFromInt(unsigned i) { - // Default alignment, allow the target to define how to align it. - if (i == 0) - return Attributes(); - - assert(isPowerOf2_32(i) && "Alignment must be a power of two."); - assert(i <= 0x40000000 && "Alignment too large."); - return Attributes((Log2_32(i)+1) << 16); - } - - /// constructStackAlignmentFromInt - This turns an int stack alignment (which - /// must be a power of 2) into the form used internally in Attributes. - static Attributes constructStackAlignmentFromInt(unsigned i) { - // Default alignment, allow the target to define how to align it. - if (i == 0) - return Attributes(); - - assert(isPowerOf2_32(i) && "Alignment must be a power of two."); - assert(i <= 0x100 && "Alignment too large."); - return Attributes((Log2_32(i)+1) << 26); - } - /// @brief Which attributes cannot be applied to a type. static Attributes typeIncompatible(Type *Ty); /// encodeLLVMAttributesForBitcode - This returns an integer containing an /// encoding of all the LLVM attributes found in the given attribute bitset. /// Any change to this encoding is a breaking change to bitcode compatibility. - static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) { - // FIXME: It doesn't make sense to store the alignment information as an - // expanded out value, we should store it as a log2 value. However, we - // can't just change that here without breaking bitcode compatibility. If - // this ever becomes a problem in practice, we should introduce new tag - // numbers in the bitcode file and have those tags use a more efficiently - // encoded alignment field. - - // Store the alignment in the bitcode as a 16-bit raw value instead of a - // 5-bit log2 encoded value. Shift the bits above the alignment up by 11 - // bits. - uint64_t EncodedAttrs = Attrs.Raw() & 0xffff; - if (Attrs.hasAttribute(Attributes::Alignment)) - EncodedAttrs |= Attrs.getAlignment() << 16; - EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11; - return EncodedAttrs; - } + static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs); /// decodeLLVMAttributesForBitcode - This returns an attribute bitset /// containing the LLVM attributes that have been decoded from the given /// integer. This function must stay in sync with /// 'encodeLLVMAttributesForBitcode'. - static Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) { - // The alignment is stored as a 16-bit raw value from bits 31--16. We shift - // the bits above 31 down by 11 bits. - unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; - assert((!Alignment || isPowerOf2_32(Alignment)) && - "Alignment must be a power of two."); - - Attributes Attrs(EncodedAttrs & 0xffff); - if (Alignment) - Attrs |= Attributes::constructAlignmentFromInt(Alignment); - Attrs |= Attributes((EncodedAttrs & (0xfffULL << 32)) >> 11); - return Attrs; - } + static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C, + uint64_t EncodedAttrs); /// getAsString - The set of Attributes set in Attributes is converted to a /// string of equivalent mnemonics. This is, presumably, for writing out the @@ -299,6 +187,96 @@ public: }; //===----------------------------------------------------------------------===// +/// AttrBuilder - This class is used in conjunction with the Attributes::get +/// method to create an Attributes object. The object itself is uniquified. The +/// Builder's value, however, is not. So this can be used as a quick way to test +/// for equality, presence of attributes, etc. +class AttrBuilder { + uint64_t Bits; +public: + AttrBuilder() : Bits(0) {} + explicit AttrBuilder(uint64_t B) : Bits(B) {} + AttrBuilder(const Attributes &A) : Bits(A.Raw()) {} + AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {} + + void clear() { Bits = 0; } + + /// addAttribute - Add an attribute to the builder. + AttrBuilder &addAttribute(Attributes::AttrVal Val); + + /// removeAttribute - Remove an attribute from the builder. + AttrBuilder &removeAttribute(Attributes::AttrVal Val); + + /// addAttribute - Add the attributes from A to the builder. + AttrBuilder &addAttributes(const Attributes &A); + + /// removeAttribute - Remove the attributes from A from the builder. + AttrBuilder &removeAttributes(const Attributes &A); + + /// hasAttribute - Return true if the builder has the specified attribute. + bool hasAttribute(Attributes::AttrVal A) const; + + /// hasAttributes - Return true if the builder has IR-level attributes. + bool hasAttributes() const; + + /// hasAttributes - Return true if the builder has any attribute that's in the + /// specified attribute. + bool hasAttributes(const Attributes &A) const; + + /// hasAlignmentAttr - Return true if the builder has an alignment attribute. + bool hasAlignmentAttr() const; + + /// getAlignment - Retrieve the alignment attribute, if it exists. + uint64_t getAlignment() const; + + /// getStackAlignment - Retrieve the stack alignment attribute, if it exists. + uint64_t getStackAlignment() const; + + /// addAlignmentAttr - This turns an int alignment (which must be a power of + /// 2) into the form used internally in Attributes. + AttrBuilder &addAlignmentAttr(unsigned Align); + + /// addStackAlignmentAttr - This turns an int stack alignment (which must be a + /// power of 2) into the form used internally in Attributes. + AttrBuilder &addStackAlignmentAttr(unsigned Align); + + /// addRawValue - Add the raw value to the internal representation. + /// N.B. This should be used ONLY for decoding LLVM bitcode! + AttrBuilder &addRawValue(uint64_t Val); + + /// @brief Remove attributes that are used on functions only. + void removeFunctionOnlyAttrs() { + removeAttribute(Attributes::NoReturn) + .removeAttribute(Attributes::NoUnwind) + .removeAttribute(Attributes::ReadNone) + .removeAttribute(Attributes::ReadOnly) + .removeAttribute(Attributes::NoInline) + .removeAttribute(Attributes::AlwaysInline) + .removeAttribute(Attributes::OptimizeForSize) + .removeAttribute(Attributes::StackProtect) + .removeAttribute(Attributes::StackProtectReq) + .removeAttribute(Attributes::NoRedZone) + .removeAttribute(Attributes::NoImplicitFloat) + .removeAttribute(Attributes::Naked) + .removeAttribute(Attributes::InlineHint) + .removeAttribute(Attributes::StackAlignment) + .removeAttribute(Attributes::UWTable) + .removeAttribute(Attributes::NonLazyBind) + .removeAttribute(Attributes::ReturnsTwice) + .removeAttribute(Attributes::AddressSafety); + } + + uint64_t Raw() const { return Bits; } + + bool operator==(const AttrBuilder &B) { + return Bits == B.Bits; + } + bool operator!=(const AttrBuilder &B) { + return Bits != B.Bits; + } +}; + +//===----------------------------------------------------------------------===// // AttributeWithIndex //===----------------------------------------------------------------------===// @@ -310,9 +288,9 @@ struct AttributeWithIndex { ///< Index 0 is used for return value attributes. ///< Index ~0U is used for function attributes. - static AttributeWithIndex get(unsigned Idx, + static AttributeWithIndex get(LLVMContext &C, unsigned Idx, ArrayRef<Attributes::AttrVal> Attrs) { - Attributes::Builder B; + AttrBuilder B; for (ArrayRef<Attributes::AttrVal>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) @@ -320,7 +298,7 @@ struct AttributeWithIndex { AttributeWithIndex P; P.Index = Idx; - P.Attrs = Attributes::get(B); + P.Attrs = Attributes::get(C, B); return P; } static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { @@ -340,6 +318,12 @@ class AttributeListImpl; /// AttrListPtr - This class manages the ref count for the opaque /// AttributeListImpl object and provides accessors for it. class AttrListPtr { +public: + enum AttrIndex { + ReturnIndex = 0U, + FunctionIndex = ~0U + }; +private: /// AttrList - The attributes that we are managing. This can be null /// to represent the empty attributes list. AttributeListImpl *AttrList; @@ -359,12 +343,12 @@ public: /// addAttr - Add the specified attribute at the specified index to this /// attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const; + AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; /// removeAttr - Remove the specified attribute at the specified index from /// this attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const; + AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; //===--------------------------------------------------------------------===// // Attribute List Accessors @@ -378,12 +362,12 @@ public: /// getRetAttributes - The attributes for the ret value are /// returned. Attributes getRetAttributes() const { - return getAttributes(0); + return getAttributes(ReturnIndex); } /// getFnAttributes - The function attributes are returned. Attributes getFnAttributes() const { - return getAttributes(~0U); + return getAttributes(FunctionIndex); } /// paramHasAttr - Return true if the specified parameter index has the @@ -411,8 +395,6 @@ public: bool operator!=(const AttrListPtr &RHS) const { return AttrList != RHS.AttrList; } - void dump() const; - //===--------------------------------------------------------------------===// // Attribute List Introspection //===--------------------------------------------------------------------===// @@ -442,6 +424,8 @@ public: /// holds a index number plus a set of attributes. const AttributeWithIndex &getSlot(unsigned Slot) const; + void dump() const; + private: explicit AttrListPtr(AttributeListImpl *L); diff --git a/include/llvm/AttributesImpl.h b/include/llvm/AttributesImpl.h deleted file mode 100644 index eea11a7011a..00000000000 --- a/include/llvm/AttributesImpl.h +++ /dev/null @@ -1,53 +0,0 @@ -//===-- AttributesImpl.h - Attributes Internals -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines various helper methods and classes used by LLVMContextImpl -// for creating and managing attributes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ATTRIBUTESIMPL_H -#define LLVM_ATTRIBUTESIMPL_H - -#include "llvm/ADT/FoldingSet.h" - -namespace llvm { - -class Attributes; - -class AttributesImpl : public FoldingSetNode { - friend class Attributes; - uint64_t Bits; // FIXME: We will be expanding this. - -public: - AttributesImpl(uint64_t bits) : Bits(bits) {} - - bool hasAttribute(uint64_t A) const; - - bool hasAttributes() const; - bool hasAttributes(const Attributes &A) const; - - uint64_t getAlignment() const; - uint64_t getStackAlignment() const; - - bool isEmptyOrSingleton() const; - - static uint64_t getAttrMask(uint64_t Val); - - void Profile(FoldingSetNodeID &ID) const { - Profile(ID, Bits); - } - static void Profile(FoldingSetNodeID &ID, uint64_t Bits) { - ID.AddInteger(Bits); - } -}; - -} // end llvm namespace - -#endif diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 9ab4a74e5a5..02c2a96b6c6 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -213,7 +213,6 @@ public: ValueSymbolTable *getValueSymbolTable(); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BasicBlock *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::BasicBlockVal; } diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 3daef789d61..840f57e7526 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -409,7 +409,7 @@ public: } /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter - /// the block, and return true if the block is valid. + /// the block, and return true if the block has an error. bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { // Save the current block's state on BlockScope. BlockScope.push_back(Block(CurCodeSize)); diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h new file mode 100644 index 00000000000..90ee2342449 --- /dev/null +++ b/include/llvm/CodeGen/CommandFlags.h @@ -0,0 +1,228 @@ +//===-- CommandFlags.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 codegen-specific flags that are shared between different +// command line tools. The tools "llc" and "opt" both use this file to prevent +// flag duplication. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H +#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Target/TargetMachine.h" + +#include <string> +using namespace llvm; + +cl::opt<std::string> +MArch("march", cl::desc("Architecture to generate code for (see --version)")); + +cl::opt<std::string> +MCPU("mcpu", + cl::desc("Target a specific cpu type (-mcpu=help for details)"), + cl::value_desc("cpu-name"), + cl::init("")); + +cl::list<std::string> +MAttrs("mattr", + cl::CommaSeparated, + cl::desc("Target specific attributes (-mattr=help for details)"), + cl::value_desc("a1,+a2,-a3,...")); + +cl::opt<Reloc::Model> +RelocModel("relocation-model", + cl::desc("Choose relocation model"), + cl::init(Reloc::Default), + cl::values( + clEnumValN(Reloc::Default, "default", + "Target default relocation model"), + clEnumValN(Reloc::Static, "static", + "Non-relocatable code"), + clEnumValN(Reloc::PIC_, "pic", + "Fully relocatable, position independent code"), + clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", + "Relocatable external references, non-relocatable code"), + clEnumValEnd)); + +cl::opt<llvm::CodeModel::Model> +CMModel("code-model", + cl::desc("Choose code model"), + cl::init(CodeModel::Default), + cl::values(clEnumValN(CodeModel::Default, "default", + "Target default code model"), + clEnumValN(CodeModel::Small, "small", + "Small code model"), + clEnumValN(CodeModel::Kernel, "kernel", + "Kernel code model"), + clEnumValN(CodeModel::Medium, "medium", + "Medium code model"), + clEnumValN(CodeModel::Large, "large", + "Large code model"), + clEnumValEnd)); + +cl::opt<bool> +RelaxAll("mc-relax-all", + cl::desc("When used with filetype=obj, " + "relax all fixups in the emitted object file")); + +cl::opt<TargetMachine::CodeGenFileType> +FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), + cl::desc("Choose a file type (not all types are supported by all targets):"), + cl::values( + clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm", + "Emit an assembly ('.s') file"), + clEnumValN(TargetMachine::CGFT_ObjectFile, "obj", + "Emit a native object ('.o') file"), + clEnumValN(TargetMachine::CGFT_Null, "null", + "Emit nothing, for performance testing"), + clEnumValEnd)); + +cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden, + cl::desc("Do not use .loc entries")); + +cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden, + cl::desc("Do not use .cfi_* directives")); + +cl::opt<bool> EnableDwarfDirectory("enable-dwarf-directory", cl::Hidden, + cl::desc("Use .file directives with an explicit directory.")); + +cl::opt<bool> +DisableRedZone("disable-red-zone", + cl::desc("Do not emit code that uses the red zone."), + cl::init(false)); + +cl::opt<bool> +EnableFPMAD("enable-fp-mad", + cl::desc("Enable less precise MAD instructions to be generated"), + cl::init(false)); + +cl::opt<bool> +DisableFPElim("disable-fp-elim", + cl::desc("Disable frame pointer elimination optimization"), + cl::init(false)); + +cl::opt<bool> +DisableFPElimNonLeaf("disable-non-leaf-fp-elim", + cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"), + cl::init(false)); + +cl::opt<bool> +EnableUnsafeFPMath("enable-unsafe-fp-math", + cl::desc("Enable optimizations that may decrease FP precision"), + cl::init(false)); + +cl::opt<bool> +EnableNoInfsFPMath("enable-no-infs-fp-math", + cl::desc("Enable FP math optimizations that assume no +-Infs"), + cl::init(false)); + +cl::opt<bool> +EnableNoNaNsFPMath("enable-no-nans-fp-math", + cl::desc("Enable FP math optimizations that assume no NaNs"), + cl::init(false)); + +cl::opt<bool> +EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math", + cl::Hidden, + cl::desc("Force codegen to assume rounding mode can change dynamically"), + cl::init(false)); + +cl::opt<bool> +GenerateSoftFloatCalls("soft-float", + cl::desc("Generate software floating point library calls"), + cl::init(false)); + +cl::opt<llvm::FloatABI::ABIType> +FloatABIForCalls("float-abi", + cl::desc("Choose float ABI type"), + cl::init(FloatABI::Default), + cl::values( + clEnumValN(FloatABI::Default, "default", + "Target default float ABI type"), + clEnumValN(FloatABI::Soft, "soft", + "Soft float ABI (implied by -soft-float)"), + clEnumValN(FloatABI::Hard, "hard", + "Hard float ABI (uses FP registers)"), + clEnumValEnd)); + +cl::opt<llvm::FPOpFusion::FPOpFusionMode> +FuseFPOps("fp-contract", + cl::desc("Enable aggresive formation of fused FP ops"), + cl::init(FPOpFusion::Standard), + cl::values( + clEnumValN(FPOpFusion::Fast, "fast", + "Fuse FP ops whenever profitable"), + clEnumValN(FPOpFusion::Standard, "on", + "Only fuse 'blessed' FP ops."), + clEnumValN(FPOpFusion::Strict, "off", + "Only fuse FP ops when the result won't be effected."), + clEnumValEnd)); + +cl::opt<bool> +DontPlaceZerosInBSS("nozero-initialized-in-bss", + cl::desc("Don't place zero-initialized symbols into bss section"), + cl::init(false)); + +cl::opt<bool> +EnableGuaranteedTailCallOpt("tailcallopt", + cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."), + cl::init(false)); + +cl::opt<bool> +DisableTailCalls("disable-tail-calls", + cl::desc("Never emit tail calls"), + cl::init(false)); + +cl::opt<unsigned> +OverrideStackAlignment("stack-alignment", + cl::desc("Override default stack alignment"), + cl::init(0)); + +cl::opt<bool> +EnableRealignStack("realign-stack", + cl::desc("Realign stack if needed"), + cl::init(true)); + +cl::opt<std::string> +TrapFuncName("trap-func", cl::Hidden, + cl::desc("Emit a call to trap function rather than a trap instruction"), + cl::init("")); + +cl::opt<bool> +EnablePIE("enable-pie", + cl::desc("Assume the creation of a position independent executable."), + cl::init(false)); + +cl::opt<bool> +SegmentedStacks("segmented-stacks", + cl::desc("Use segmented stacks if possible."), + cl::init(false)); + +cl::opt<bool> +UseInitArray("use-init-array", + cl::desc("Use .init_array instead of .ctors."), + cl::init(false)); + +cl::opt<std::string> StopAfter("stop-after", + cl::desc("Stop compilation after a specific pass"), + cl::value_desc("pass-name"), + cl::init("")); +cl::opt<std::string> StartAfter("start-after", + cl::desc("Resume compilation after a specific pass"), + cl::value_desc("pass-name"), + cl::init("")); + +cl::opt<unsigned> +SSPBufferSize("stack-protector-buffer-size", cl::init(8), + cl::desc("Lower bound for a buffer to be considered for " + "stack protection")); +#endif diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 1e8dde12553..b421753dd53 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -65,12 +65,6 @@ namespace llvm { /// Live interval pointers for all the virtual registers. IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals; - /// AllocatableRegs - A bit vector of allocatable registers. - BitVector AllocatableRegs; - - /// ReservedRegs - A bit vector of reserved registers. - BitVector ReservedRegs; - /// RegMaskSlots - Sorted list of instructions with register mask operands. /// Always use the 'r' slot, RegMasks are normal clobbers, not early /// clobbers. @@ -123,18 +117,6 @@ namespace llvm { return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg]; } - /// isAllocatable - is the physical register reg allocatable in the current - /// function? - bool isAllocatable(unsigned reg) const { - return AllocatableRegs.test(reg); - } - - /// isReserved - is the physical register reg reserved in the current - /// function - bool isReserved(unsigned reg) const { - return ReservedRegs.test(reg); - } - // Interval creation. LiveInterval &getOrCreateInterval(unsigned Reg) { if (!hasInterval(Reg)) { @@ -278,15 +260,20 @@ namespace llvm { /// instruction 'mi' has been moved within a basic block. This will update /// the live intervals for all operands of mi. Moves between basic blocks /// are not supported. - void handleMove(MachineInstr* MI); + /// + /// \param UpdateFlags Update live intervals for nonallocatable physregs. + void handleMove(MachineInstr* MI, bool UpdateFlags = false); /// moveIntoBundle - Update intervals for operands of MI so that they /// begin/end on the SlotIndex for BundleStart. /// + /// \param UpdateFlags Update live intervals for nonallocatable physregs. + /// /// Requires MI and BundleStart to have SlotIndexes, and assumes /// existing liveness is accurate. BundleStart should be the first /// instruction in the Bundle. - void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart); + void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart, + bool UpdateFlags = false); // Register mask functions. // diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index d4bb409e060..3bb134b8fb2 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -126,12 +126,6 @@ private: /// building live intervals. SparseBitVector<> PHIJoins; - /// ReservedRegisters - This vector keeps track of which registers - /// are reserved register which are not allocatable by the target machine. - /// We can not track liveness for values that are in this set. - /// - BitVector ReservedRegisters; - private: // Intermediate data structures MachineFunction *MF; diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 654361f9d42..770685358ab 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -176,15 +176,24 @@ public: } // Add a displacement from an existing MachineOperand with an added offset. - const MachineInstrBuilder &addDisp(const MachineOperand &Disp, - int64_t off) const { + const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off, + unsigned char TargetFlags = 0) const { switch (Disp.getType()) { default: llvm_unreachable("Unhandled operand type in addDisp()"); case MachineOperand::MO_Immediate: return addImm(Disp.getImm() + off); - case MachineOperand::MO_GlobalAddress: - return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off); + case MachineOperand::MO_GlobalAddress: { + // If caller specifies new TargetFlags then use it, otherwise the + // default behavior is to copy the target flags from the existing + // MachineOperand. This means if the caller wants to clear the + // target flags it needs to do so explicitly. + if (TargetFlags) + return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, + TargetFlags); + return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, + Disp.getTargetFlags()); + } } } }; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 91d24dd0fc0..a5bc7f7d391 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -95,9 +95,6 @@ class MachineRegisterInfo { /// started. BitVector ReservedRegs; - /// AllocatableRegs - From TRI->getAllocatableSet. - mutable BitVector AllocatableRegs; - /// LiveIns/LiveOuts - Keep track of the physical registers that are /// livein/liveout of the function. Live in values are typically arguments in /// registers, live out values are typically return values in registers. @@ -427,6 +424,34 @@ public: return !reservedRegsFrozen() || ReservedRegs.test(PhysReg); } + /// getReservedRegs - Returns a reference to the frozen set of reserved + /// registers. This method should always be preferred to calling + /// TRI::getReservedRegs() when possible. + const BitVector &getReservedRegs() const { + assert(reservedRegsFrozen() && + "Reserved registers haven't been frozen yet. " + "Use TRI::getReservedRegs()."); + return ReservedRegs; + } + + /// isReserved - Returns true when PhysReg is a reserved register. + /// + /// Reserved registers may belong to an allocatable register class, but the + /// target has explicitly requested that they are not used. + /// + bool isReserved(unsigned PhysReg) const { + return getReservedRegs().test(PhysReg); + } + + /// isAllocatable - Returns true when PhysReg belongs to an allocatable + /// register class and it hasn't been reserved. + /// + /// Allocatable registers may show up in the allocation order of some virtual + /// register, so a register allocator needs to track its liveness and + /// availability. + bool isAllocatable(unsigned PhysReg) const { + return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); + } //===--------------------------------------------------------------------===// // LiveIn/LiveOut Management diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 93990e164d1..2b96c7abe42 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -110,6 +110,10 @@ public: /// Initialize the strategy after building the DAG for a new region. virtual void initialize(ScheduleDAGMI *DAG) = 0; + /// Notify this strategy that all roots have been released (including those + /// that depend on EntrySU or ExitSU). + virtual void registerRoots() {} + /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to /// schedule the node at the top of the unscheduled region. Otherwise it will /// be scheduled at the bottom. diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index 7dab4f94862..8f52d3bf47d 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -50,7 +50,6 @@ namespace llvm { /// classof - Methods for support type inquiry through isa, cast, and /// dyn_cast: /// - static inline bool classof(const PseudoSourceValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == PseudoSourceValueVal || V->getValueID() == FixedStackPseudoSourceValueVal; @@ -90,9 +89,6 @@ namespace llvm { /// classof - Methods for support type inquiry through isa, cast, and /// dyn_cast: /// - static inline bool classof(const FixedStackPseudoSourceValue *) { - return true; - } static inline bool classof(const Value *V) { return V->getValueID() == FixedStackPseudoSourceValueVal; } diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h index 400e1f48ce5..4467b62f237 100644 --- a/include/llvm/CodeGen/RegisterClassInfo.h +++ b/include/llvm/CodeGen/RegisterClassInfo.h @@ -106,25 +106,6 @@ public: return CalleeSaved[N-1]; return 0; } - - /// isReserved - Returns true when PhysReg is a reserved register. - /// - /// Reserved registers may belong to an allocatable register class, but the - /// target has explicitly requested that they are not used. - /// - bool isReserved(unsigned PhysReg) const { - return Reserved.test(PhysReg); - } - - /// isAllocatable - Returns true when PhysReg belongs to an allocatable - /// register class and it hasn't been reserved. - /// - /// Allocatable registers may show up in the allocation order of some virtual - /// register, so a register allocator needs to track its liveness and - /// availability. - bool isAllocatable(unsigned PhysReg) const { - return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); - } }; } // end namespace llvm diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 3986a8dd7da..08d316992ec 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -18,6 +18,7 @@ #define LLVM_CODEGEN_REGISTER_SCAVENGING_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/ADT/BitVector.h" namespace llvm { @@ -59,10 +60,6 @@ class RegScavenger { /// BitVector CalleeSavedRegs; - /// ReservedRegs - A bitvector of reserved registers. - /// - BitVector ReservedRegs; - /// RegsAvailable - The current state of all the physical registers immediately /// before MBBI. One bit per physical register. If bit is set that means it's /// available, unset means the register is currently being used. @@ -130,12 +127,12 @@ public: void setUsed(unsigned Reg); private: /// isReserved - Returns true if a register is reserved. It is never "unused". - bool isReserved(unsigned Reg) const { return ReservedRegs.test(Reg); } + bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } /// isUsed / isUnused - Test if a register is currently being used. /// bool isUsed(unsigned Reg) const { - return !RegsAvailable.test(Reg) || ReservedRegs.test(Reg); + return !RegsAvailable.test(Reg) || isReserved(Reg); } /// isAliasUsed - Is Reg or an alias currently in use? diff --git a/include/llvm/CodeGen/ScheduleDAGILP.h b/include/llvm/CodeGen/ScheduleDAGILP.h new file mode 100644 index 00000000000..1aa40584217 --- /dev/null +++ b/include/llvm/CodeGen/ScheduleDAGILP.h @@ -0,0 +1,86 @@ +//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of an ILP metric for machine level instruction scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H +#define LLVM_CODEGEN_SCHEDULEDAGILP_H + +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { + +class raw_ostream; +class ScheduleDAGInstrs; +class SUnit; + +/// \brief Represent the ILP of the subDAG rooted at a DAG node. +struct ILPValue { + unsigned InstrCount; + unsigned Cycles; + + ILPValue(): InstrCount(0), Cycles(0) {} + + ILPValue(unsigned count, unsigned cycles): + InstrCount(count), Cycles(cycles) {} + + bool isValid() const { return Cycles > 0; } + + // Order by the ILP metric's value. + bool operator<(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Cycles + < (uint64_t)Cycles * RHS.InstrCount; + } + bool operator>(ILPValue RHS) const { + return RHS < *this; + } + bool operator<=(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Cycles + <= (uint64_t)Cycles * RHS.InstrCount; + } + bool operator>=(ILPValue RHS) const { + return RHS <= *this; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + void print(raw_ostream &OS) const; + + void dump() const; +#endif +}; + +/// \brief Compute the values of each DAG node for an ILP metric. +/// +/// This metric assumes that the DAG is a forest of trees with roots at the +/// bottom of the schedule. +class ScheduleDAGILP { + bool IsBottomUp; + std::vector<ILPValue> ILPValues; + +public: + ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {} + + /// \brief Initialize the result data with the size of the DAG. + void resize(unsigned NumSUnits); + + /// \brief Compute the ILP metric for the subDAG at this root. + void computeILP(const SUnit *Root); + + /// \brief Get the ILP value for a DAG node. + ILPValue getILP(const SUnit *SU); +}; + +raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); + +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 63d47592650..2c828751080 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -662,9 +662,6 @@ public: /// void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const; - - static bool classof(const SDNode *) { return true; } - /// Profile - Gather unique data for the node. /// void Profile(FoldingSetNodeID &ID) const; @@ -976,7 +973,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const MemSDNode *) { return true; } static bool classof(const SDNode *N) { // For some targets, we lower some target intrinsics to a MemIntrinsicNode // with either an intrinsic or a target opcode. @@ -1061,7 +1057,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const AtomicSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ATOMIC_CMP_SWAP || N->getOpcode() == ISD::ATOMIC_SWAP || @@ -1093,7 +1088,6 @@ public: } // Methods to support isa and dyn_cast - static bool classof(const MemIntrinsicSDNode *) { return true; } static bool classof(const SDNode *N) { // We lower some target intrinsics to their target opcode // early a node with a target opcode can be of this class @@ -1148,7 +1142,6 @@ public: } static bool isSplatMask(const int *Mask, EVT VT); - static bool classof(const ShuffleVectorSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VECTOR_SHUFFLE; } @@ -1172,7 +1165,6 @@ public: bool isNullValue() const { return Value->isNullValue(); } bool isAllOnesValue() const { return Value->isAllOnesValue(); } - static bool classof(const ConstantSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::Constant || N->getOpcode() == ISD::TargetConstant; @@ -1219,7 +1211,6 @@ public: static bool isValueValidForType(EVT VT, const APFloat& Val); - static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ConstantFP || N->getOpcode() == ISD::TargetConstantFP; @@ -1241,7 +1232,6 @@ public: // Return the address space this GlobalAddress belongs to. unsigned getAddressSpace() const; - static bool classof(const GlobalAddressSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::GlobalAddress || N->getOpcode() == ISD::TargetGlobalAddress || @@ -1261,7 +1251,6 @@ public: int getIndex() const { return FI; } - static bool classof(const FrameIndexSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::FrameIndex || N->getOpcode() == ISD::TargetFrameIndex; @@ -1281,7 +1270,6 @@ public: int getIndex() const { return JTI; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const JumpTableSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::JumpTable || N->getOpcode() == ISD::TargetJumpTable; @@ -1342,7 +1330,6 @@ public: Type *getType() const; - static bool classof(const ConstantPoolSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ConstantPool || N->getOpcode() == ISD::TargetConstantPool; @@ -1366,7 +1353,6 @@ public: int getIndex() const { return Index; } int64_t getOffset() const { return Offset; } - static bool classof(const TargetIndexSDNode*) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::TargetIndex; } @@ -1385,7 +1371,6 @@ public: MachineBasicBlock *getBasicBlock() const { return MBB; } - static bool classof(const BasicBlockSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::BasicBlock; } @@ -1410,7 +1395,6 @@ public: unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits = 0, bool isBigEndian = false); - static inline bool classof(const BuildVectorSDNode *) { return true; } static inline bool classof(const SDNode *N) { return N->getOpcode() == ISD::BUILD_VECTOR; } @@ -1431,7 +1415,6 @@ public: /// getValue - return the contained Value. const Value *getValue() const { return V; } - static bool classof(const SrcValueSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::SRCVALUE; } @@ -1446,7 +1429,6 @@ public: const MDNode *getMD() const { return MD; } - static bool classof(const MDNodeSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::MDNODE_SDNODE; } @@ -1463,7 +1445,6 @@ public: unsigned getReg() const { return Reg; } - static bool classof(const RegisterSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::Register; } @@ -1480,7 +1461,6 @@ public: const uint32_t *getRegMask() const { return RegMask; } - static bool classof(const RegisterMaskSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::RegisterMask; } @@ -1501,7 +1481,6 @@ public: int64_t getOffset() const { return Offset; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const BlockAddressSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::BlockAddress || N->getOpcode() == ISD::TargetBlockAddress; @@ -1519,7 +1498,6 @@ class EHLabelSDNode : public SDNode { public: MCSymbol *getLabel() const { return Label; } - static bool classof(const EHLabelSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::EH_LABEL; } @@ -1539,7 +1517,6 @@ public: const char *getSymbol() const { return Symbol; } unsigned char getTargetFlags() const { return TargetFlags; } - static bool classof(const ExternalSymbolSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::ExternalSymbol || N->getOpcode() == ISD::TargetExternalSymbol; @@ -1557,7 +1534,6 @@ public: ISD::CondCode get() const { return Condition; } - static bool classof(const CondCodeSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::CONDCODE; } @@ -1577,7 +1553,6 @@ class CvtRndSatSDNode : public SDNode { public: ISD::CvtCode getCvtCode() const { return CvtCode; } - static bool classof(const CvtRndSatSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::CONVERT_RNDSAT; } @@ -1596,7 +1571,6 @@ public: EVT getVT() const { return ValueType; } - static bool classof(const VTSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VALUETYPE; } @@ -1640,7 +1614,6 @@ public: /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store. bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } - static bool classof(const LSBaseSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE; @@ -1672,7 +1645,6 @@ public: const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getOffset() const { return getOperand(2); } - static bool classof(const LoadSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD; } @@ -1703,7 +1675,6 @@ public: const SDValue &getBasePtr() const { return getOperand(2); } const SDValue &getOffset() const { return getOperand(3); } - static bool classof(const StoreSDNode *) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::STORE; } @@ -1744,7 +1715,6 @@ public: MemRefsEnd = NewMemRefsEnd; } - static bool classof(const MachineSDNode *) { return true; } static bool classof(const SDNode *N) { return N->isMachineOpcode(); } diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 7464dce3303..7fecf4c7b45 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -108,8 +108,6 @@ public: virtual void destroyConstant() { llvm_unreachable("Not reached!"); } //// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Constant *) { return true; } - static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() >= ConstantFirstVal && V->getValueID() <= ConstantLastVal; diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 85fed4259d3..b56b9cad117 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -221,7 +221,6 @@ public: } /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const ConstantInt *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantIntVal; } @@ -291,7 +290,6 @@ public: return isExactlyValue(FV); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantFP *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantFPVal; } @@ -334,7 +332,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantAggregateZero *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantAggregateZeroVal; } @@ -367,7 +364,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantArray *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantArrayVal; } @@ -426,7 +422,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantStruct *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantStructVal; } @@ -474,7 +469,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantVector *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantVectorVal; } @@ -517,7 +511,6 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantPointerNull *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantPointerNullVal; } @@ -639,7 +632,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataSequential *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataArrayVal || V->getValueID() == ConstantDataVectorVal; @@ -695,7 +687,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataArray *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataArrayVal; } @@ -749,7 +740,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: /// - static bool classof(const ConstantDataVector *) { return true; } static bool classof(const Value *V) { return V->getValueID() == ConstantDataVectorVal; } @@ -781,7 +771,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BlockAddress *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == BlockAddressVal; } @@ -1094,7 +1083,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ConstantExpr *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; } @@ -1159,7 +1147,6 @@ public: virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UndefValue *) { return true; } static bool classof(const Value *V) { return V->getValueID() == UndefValueVal; } diff --git a/include/llvm/DataLayout.h b/include/llvm/DataLayout.h index a24737e842b..c9ac0b7feaa 100644 --- a/include/llvm/DataLayout.h +++ b/include/llvm/DataLayout.h @@ -231,9 +231,7 @@ public: } /// Layout pointer alignment - /// FIXME: The defaults need to be removed once all of - /// the backends/clients are updated. - unsigned getPointerABIAlignment(unsigned AS = 0) const { + unsigned getPointerABIAlignment(unsigned AS) const { DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); if (val == Pointers.end()) { val = Pointers.find(0); @@ -241,9 +239,7 @@ public: return val->second.ABIAlign; } /// Return target's alignment for stack-based pointers - /// FIXME: The defaults need to be removed once all of - /// the backends/clients are updated. - unsigned getPointerPrefAlignment(unsigned AS = 0) const { + unsigned getPointerPrefAlignment(unsigned AS) const { DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); if (val == Pointers.end()) { val = Pointers.find(0); @@ -251,9 +247,7 @@ public: return val->second.PrefAlign; } /// Layout pointer size - /// FIXME: The defaults need to be removed once all of - /// the backends/clients are updated. - unsigned getPointerSize(unsigned AS = 0) const { + unsigned getPointerSize(unsigned AS) const { DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); if (val == Pointers.end()) { val = Pointers.find(0); @@ -261,9 +255,7 @@ public: return val->second.TypeBitWidth; } /// Layout pointer size, in bits - /// FIXME: The defaults need to be removed once all of - /// the backends/clients are updated. - unsigned getPointerSizeInBits(unsigned AS = 0) const { + unsigned getPointerSizeInBits(unsigned AS) const { DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS); if (val == Pointers.end()) { val = Pointers.find(0); diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index da1e62dc043..c862c2c8bb2 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -85,7 +85,6 @@ public: bool isPowerOf2ByteWidth() const; // 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; } @@ -134,7 +133,6 @@ public: unsigned getNumParams() const { return NumContainedTys - 1; } // 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; } @@ -157,7 +155,6 @@ public: bool indexValid(unsigned Idx) const; // 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 || T->getTypeID() == StructTyID || @@ -293,7 +290,6 @@ public: } // 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; } @@ -323,7 +319,6 @@ public: Type *getElementType() const { return ContainedTys[0]; } // 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 || T->getTypeID() == PointerTyID || @@ -353,7 +348,6 @@ public: uint64_t getNumElements() const { return NumElements; } // 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; } @@ -420,7 +414,6 @@ public: } // 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; } @@ -452,7 +445,6 @@ public: inline unsigned getAddressSpace() const { return getSubclassData(); } // 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; } diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 855c926bf5c..e211e9ab52a 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -178,9 +178,7 @@ public: /// void addFnAttr(Attributes::AttrVal N) { // Function Attributes are stored at ~0 index - Attributes::Builder B; - B.addAttribute(N); - addAttribute(~0U, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), N)); } /// removeFnAttr - Remove function attributes from this function. @@ -278,9 +276,7 @@ public: return getParamAttributes(n).hasAttribute(Attributes::NoAlias); } void setDoesNotAlias(unsigned n) { - Attributes::Builder B; - B.addAttribute(Attributes::NoAlias); - addAttribute(n, Attributes::get(B)); + addAttribute(n, Attributes::get(getContext(), Attributes::NoAlias)); } /// @brief Determine if the parameter can be captured. @@ -289,9 +285,7 @@ public: return getParamAttributes(n).hasAttribute(Attributes::NoCapture); } void setDoesNotCapture(unsigned n) { - Attributes::Builder B; - B.addAttribute(Attributes::NoCapture); - addAttribute(n, Attributes::get(B)); + addAttribute(n, Attributes::get(getContext(), Attributes::NoCapture)); } /// copyAttributesFrom - copy all additional attributes (those not needed to @@ -404,7 +398,6 @@ public: void viewCFGOnly() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Function *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal; } diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index a97ecd30c9d..d0f014733fc 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -76,7 +76,6 @@ public: 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; } static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalAliasVal; } diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 58d02576c17..7f7f74b1e2d 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -287,7 +287,6 @@ public: inline const Module *getParent() const { return Parent; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal || diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 27a2ea7fb9f..b9d3f68642f 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -174,7 +174,6 @@ public: virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalVariable *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; } diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 409246cf148..ee9b1c5852e 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -94,6 +94,7 @@ void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); +void initializeDependenceAnalysisPass(PassRegistry&); void initializeDomOnlyPrinterPass(PassRegistry&); void initializeDomOnlyViewerPass(PassRegistry&); void initializeDomPrinterPass(PassRegistry&); @@ -247,6 +248,7 @@ void initializeTailCallElimPass(PassRegistry&); void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); void initializeDataLayoutPass(PassRegistry&); +void initializeTargetTransformInfoPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); void initializeTypeBasedAliasAnalysisPass(PassRegistry&); diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index 58c1e84e53f..c6e0aab05e7 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -189,7 +189,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InlineAsm *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::InlineAsmVal; } diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index bda9d79da75..cfc79394b22 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -73,7 +73,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const TerminatorInst *) { return true; } static inline bool classof(const Instruction *I) { return I->isTerminator(); } @@ -113,7 +112,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UnaryInstruction *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || @@ -361,7 +359,6 @@ public: bool isExact() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->isBinaryOp(); } @@ -611,7 +608,6 @@ public: static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CastInst *) { return true; } static inline bool classof(const Instruction *I) { return I->isCast(); } @@ -816,7 +812,6 @@ public: static bool isFalseWhenEqual(unsigned short predicate); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CmpInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp || I->getOpcode() == Instruction::FCmp; diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index c85eda28f42..8aa8a56bf82 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -310,7 +310,6 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() >= Value::InstructionVal; } diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index a1a2bd53c82..40dbbaabe69 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -112,7 +112,6 @@ public: bool isStaticAlloca() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AllocaInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Alloca); } @@ -232,7 +231,6 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const LoadInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; } @@ -350,11 +348,19 @@ public: static unsigned getPointerOperandIndex() { return 1U; } unsigned getPointerAddressSpace() const { - return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace(); + if (getPointerOperand()->getType()->isPointerTy()) + return cast<PointerType>(getPointerOperand()->getType()) + ->getAddressSpace(); + if (getPointerOperand()->getType()->isVectorTy() + && cast<VectorType>(getPointerOperand()->getType())->isPointerTy()) + return cast<PointerType>(cast<VectorType>( + getPointerOperand()->getType())->getElementType()) + ->getAddressSpace(); + llvm_unreachable("Only a vector of pointers or pointers can be used!"); + return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const StoreInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; } @@ -426,7 +432,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FenceInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Fence; } @@ -526,7 +531,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AtomicCmpXchgInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; } @@ -670,7 +674,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const AtomicRMWInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; } @@ -849,7 +852,6 @@ public: bool isInBounds() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GetElementPtrInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); } @@ -1031,7 +1033,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp; } @@ -1141,7 +1142,6 @@ public: } /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FCmpInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::FCmp; } @@ -1281,9 +1281,8 @@ public: /// @brief Return true if the call should not be inlined. bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } void setIsNoInline() { - Attributes::Builder B; - B.addAttribute(Attributes::NoInline); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoInline)); } /// @brief Return true if the call can return twice @@ -1291,9 +1290,8 @@ public: return hasFnAttr(Attributes::ReturnsTwice); } void setCanReturnTwice() { - Attributes::Builder B; - B.addAttribute(Attributes::ReturnsTwice); - addAttribute(~0U, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReturnsTwice)); } /// @brief Determine if the call does not access memory. @@ -1301,9 +1299,8 @@ public: return hasFnAttr(Attributes::ReadNone); } void setDoesNotAccessMemory() { - Attributes::Builder B; - B.addAttribute(Attributes::ReadNone); - addAttribute(~0U, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadNone)); } /// @brief Determine if the call does not access or only reads memory. @@ -1311,25 +1308,22 @@ public: return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } void setOnlyReadsMemory() { - Attributes::Builder B; - B.addAttribute(Attributes::ReadOnly); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadOnly)); } /// @brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } void setDoesNotReturn() { - Attributes::Builder B; - B.addAttribute(Attributes::NoReturn); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoReturn)); } /// @brief Determine if the call cannot unwind. bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } - void setDoesNotThrow(bool DoesNotThrow = true) { - Attributes::Builder B; - B.addAttribute(Attributes::NoUnwind); - addAttribute(~0, Attributes::get(B)); + void setDoesNotThrow() { + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoUnwind)); } /// @brief Determine if the call returns a structure through first @@ -1370,7 +1364,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CallInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; } @@ -1476,7 +1469,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SelectInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Select; } @@ -1519,7 +1511,6 @@ public: static unsigned getPointerOperandIndex() { return 0U; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const VAArgInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == VAArg; } @@ -1573,7 +1564,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ExtractElementInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractElement; } @@ -1632,7 +1622,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InsertElementInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertElement; } @@ -1713,7 +1702,6 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ShuffleVectorInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; } @@ -1809,7 +1797,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ExtractValueInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractValue; } @@ -1931,7 +1918,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InsertValueInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertValue; } @@ -2148,7 +2134,6 @@ public: Value *hasConstantValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const PHINode *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::PHI; } @@ -2256,7 +2241,6 @@ public: void reserveClauses(unsigned Size) { growOperands(Size); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const LandingPadInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::LandingPad; } @@ -2325,7 +2309,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ReturnInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Ret); } @@ -2425,7 +2408,6 @@ public: void swapSuccessors(); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BranchInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); } @@ -2836,7 +2818,6 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Switch; } @@ -2935,7 +2916,6 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IndirectBrInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; } @@ -3050,9 +3030,8 @@ public: /// @brief Return true if the call should not be inlined. bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } void setIsNoInline() { - Attributes::Builder B; - B.addAttribute(Attributes::NoInline); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoInline)); } /// @brief Determine if the call does not access memory. @@ -3060,9 +3039,8 @@ public: return hasFnAttr(Attributes::ReadNone); } void setDoesNotAccessMemory() { - Attributes::Builder B; - B.addAttribute(Attributes::ReadNone); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadNone)); } /// @brief Determine if the call does not access or only reads memory. @@ -3070,25 +3048,22 @@ public: return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); } void setOnlyReadsMemory() { - Attributes::Builder B; - B.addAttribute(Attributes::ReadOnly); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::ReadOnly)); } /// @brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } void setDoesNotReturn() { - Attributes::Builder B; - B.addAttribute(Attributes::NoReturn); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoReturn)); } /// @brief Determine if the call cannot unwind. bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } void setDoesNotThrow() { - Attributes::Builder B; - B.addAttribute(Attributes::NoUnwind); - addAttribute(~0, Attributes::get(B)); + addAttribute(AttrListPtr::FunctionIndex, + Attributes::get(getContext(), Attributes::NoUnwind)); } /// @brief Determine if the call returns a structure through first @@ -3154,7 +3129,6 @@ public: unsigned getNumSuccessors() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const InvokeInst *) { return true; } static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); } @@ -3234,7 +3208,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ResumeInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Resume; } @@ -3279,7 +3252,6 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UnreachableInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Unreachable; } @@ -3320,7 +3292,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const TruncInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Trunc; } @@ -3357,7 +3328,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ZExtInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == ZExt; } @@ -3394,7 +3364,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SExtInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == SExt; } @@ -3431,7 +3400,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPTruncInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == FPTrunc; } @@ -3468,7 +3436,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPExtInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == FPExt; } @@ -3505,7 +3472,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == UIToFP; } @@ -3542,7 +3508,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == SIToFP; } @@ -3579,7 +3544,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPToUIInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == FPToUI; } @@ -3616,7 +3580,6 @@ public: ); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FPToSIInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == FPToSI; } @@ -3653,11 +3616,18 @@ public: /// @brief return the address space of the pointer. unsigned getAddressSpace() const { - return cast<PointerType>(getType())->getAddressSpace(); + if (getType()->isPointerTy()) + return cast<PointerType>(getType())->getAddressSpace(); + if (getType()->isVectorTy() && + cast<VectorType>(getType())->getElementType()->isPointerTy()) + return cast<PointerType>( + cast<VectorType>(getType())->getElementType()) + ->getAddressSpace(); + llvm_unreachable("Must be a pointer or a vector of pointers."); + return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntToPtrInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == IntToPtr; } @@ -3695,11 +3665,19 @@ public: /// @brief return the address space of the pointer. unsigned getPointerAddressSpace() const { - return cast<PointerType>(getOperand(0)->getType())->getAddressSpace(); + Type *Ty = getOperand(0)->getType(); + if (Ty->isPointerTy()) + return cast<PointerType>(Ty)->getAddressSpace(); + if (Ty->isVectorTy() + && cast<VectorType>(Ty)->getElementType()->isPointerTy()) + return cast<PointerType>( + cast<VectorType>(Ty)->getElementType()) + ->getAddressSpace(); + llvm_unreachable("Must be a pointer or a vector of pointers."); + return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const PtrToIntInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == PtrToInt; } @@ -3736,7 +3714,6 @@ public: ); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BitCastInst *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == BitCast; } diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index e9bf0f6759b..a31220355f6 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -45,7 +45,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *) { return true; } static inline bool classof(const CallInst *I) { if (const Function *CF = I->getCalledFunction()) return CF->getIntrinsicID() != 0; @@ -62,7 +61,6 @@ namespace llvm { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgInfoIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::dbg_declare: @@ -86,7 +84,6 @@ namespace llvm { MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgDeclareInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_declare; } @@ -108,7 +105,6 @@ namespace llvm { MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const DbgValueInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_value; } @@ -175,7 +171,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memcpy: @@ -205,7 +200,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemSetInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memset; } @@ -238,7 +232,6 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemTransferInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy || I->getIntrinsicID() == Intrinsic::memmove; @@ -254,7 +247,6 @@ namespace llvm { class MemCpyInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemCpyInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy; } @@ -268,7 +260,6 @@ namespace llvm { class MemMoveInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemMoveInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memmove; } diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index c3503889e70..3108a8e5251 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -50,7 +50,7 @@ namespace Intrinsic { /// Intrinsic::getType(ID) - Return the function type for an intrinsic. /// FunctionType *getType(LLVMContext &Context, ID id, - ArrayRef<Type*> Tys = ArrayRef<Type*>()); + ArrayRef<Type*> Tys = ArrayRef<Type*>()); /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be /// overloaded. @@ -58,7 +58,7 @@ namespace Intrinsic { /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic. /// - AttrListPtr getAttributes(ID id); + AttrListPtr getAttributes(LLVMContext &C, ID id); /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function /// declaration for an intrinsic, and return it. diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index c01e4710248..4b10d0e5415 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -64,6 +64,7 @@ namespace { (void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadStoreEliminationPass(); + (void) llvm::createDependenceAnalysisPass(); (void) llvm::createDomOnlyPrinterPass(); (void) llvm::createDomPrinterPass(); (void) llvm::createDomOnlyViewerPass(); diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 83c01ec5b98..5771415c81c 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -99,8 +99,6 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - static bool classof(const MCFragment *O) { return true; } - void dump(); }; @@ -151,7 +149,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } - static bool classof(const MCDataFragment *) { return true; } }; // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as @@ -213,7 +210,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Inst; } - static bool classof(const MCInstFragment *) { return true; } }; class MCAlignFragment : public MCFragment { @@ -263,7 +259,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Align; } - static bool classof(const MCAlignFragment *) { return true; } }; class MCFillFragment : public MCFragment { @@ -302,7 +297,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Fill; } - static bool classof(const MCFillFragment *) { return true; } }; class MCOrgFragment : public MCFragment { @@ -331,7 +325,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Org; } - static bool classof(const MCOrgFragment *) { return true; } }; class MCLEBFragment : public MCFragment { @@ -364,7 +357,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_LEB; } - static bool classof(const MCLEBFragment *) { return true; } }; class MCDwarfLineAddrFragment : public MCFragment { @@ -401,7 +393,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Dwarf; } - static bool classof(const MCDwarfLineAddrFragment *) { return true; } }; class MCDwarfCallFrameFragment : public MCFragment { @@ -431,7 +422,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_DwarfFrame; } - static bool classof(const MCDwarfCallFrameFragment *) { return true; } }; // FIXME: Should this be a separate class, or just merged into MCSection? Since diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 50328872485..4c10e5114a3 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -99,8 +99,6 @@ public: const MCSection *FindAssociatedSection() const; /// @} - - static bool classof(const MCExpr *) { return true; } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { @@ -132,7 +130,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Constant; } - static bool classof(const MCConstantExpr *) { return true; } }; /// MCSymbolRefExpr - Represent a reference to a symbol from inside an @@ -248,7 +245,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::SymbolRef; } - static bool classof(const MCSymbolRefExpr *) { return true; } }; /// MCUnaryExpr - Unary assembler expressions. @@ -302,7 +298,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Unary; } - static bool classof(const MCUnaryExpr *) { return true; } }; /// MCBinaryExpr - Binary assembler expressions. @@ -437,7 +432,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Binary; } - static bool classof(const MCBinaryExpr *) { return true; } }; /// MCTargetExpr - This is an extension point for target-specific MCExpr @@ -461,7 +455,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; } - static bool classof(const MCTargetExpr *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index adc960d27e0..08758cda226 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -20,6 +20,7 @@ class MCAsmLexer; class MCAsmParserExtension; class MCContext; class MCExpr; +class MCParsedAsmOperand; class MCStreamer; class MCTargetAsmParser; class SMLoc; @@ -73,6 +74,27 @@ public: /// Run - Run the parser on the input source buffer. virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; + virtual void setParsingInlineAsm(bool V) = 0; + + /// ParseStatement - Parse the next statement. + virtual bool ParseStatement() = 0; + + /// getNumParsedOperands - Returns the number of MCAsmParsedOperands from the + /// previously parsed statement. + virtual unsigned getNumParsedOperands() = 0; + + /// getParsedOperand - Get a MCAsmParsedOperand. + virtual MCParsedAsmOperand &getParsedOperand(unsigned OpNum) = 0; + + /// freeParsedOperands - Free the MCAsmParsedOperands. + virtual void freeParsedOperands() = 0; + + /// isInstruction - Was the previously parsed statement an instruction? + virtual bool isInstruction() = 0; + + /// getOpcode - Get the opcode from the previously parsed instruction. + virtual unsigned getOpcode() = 0; + /// Warning - Emit a warning at the location \p L, with the message \p Msg. /// /// \return The return value is true, if warnings are fatal. diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 0ce32d617ef..280145bfbc8 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -19,10 +19,34 @@ class raw_ostream; /// base class is used by target-independent clients and is the interface /// between parsing an asm instruction and recognizing it. class MCParsedAsmOperand { + /// MCOperandNum - The corresponding MCInst operand number. Only valid when + /// parsing MS-style inline assembly. + unsigned MCOperandNum; + + /// Constraint - The constraint on this operand. Only valid when parsing + /// MS-style inline assembly. + std::string Constraint; + public: MCParsedAsmOperand() {} virtual ~MCParsedAsmOperand() {} + void setConstraint(StringRef C) { Constraint = C.str(); } + StringRef getConstraint() { return Constraint; } + + void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; } + unsigned getMCOperandNum() { return MCOperandNum; } + + unsigned getNameLen() { + assert (getStartLoc().isValid() && "Invalid StartLoc!"); + assert (getEndLoc().isValid() && "Invalid EndLoc!"); + return getEndLoc().getPointer() - getStartLoc().getPointer(); + } + + StringRef getName() { + return StringRef(getStartLoc().getPointer(), getNameLen()); + } + /// isToken - Is this a token operand? virtual bool isToken() const = 0; /// isImm - Is this an immediate operand? diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index a92fc379e19..21fdb6bd39b 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -64,8 +64,6 @@ namespace llvm { /// isVirtualSection - Check whether this section is "virtual", that is /// has no actual object file contents. virtual bool isVirtualSection() const = 0; - - static bool classof(const MCSection *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 7eacde57f48..b050c0f442b 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -61,7 +61,6 @@ namespace llvm { static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } - static bool classof(const MCSectionCOFF *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 7321ca83e89..4d54465760d 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -76,7 +76,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } - static bool classof(const MCSectionELF *) { return true; } // Return the entry size for sections with fixed-width data. static unsigned DetermineEntrySize(SectionKind Kind); diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 15eb4f4a768..71ea8f3e901 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -174,7 +174,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; } - static bool classof(const MCSectionMachO *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 44698989c17..230d27ef2ef 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -554,6 +554,11 @@ namespace llvm { virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); + /// PPC-related methods. + /// FIXME: Eventually replace it with some "target MC streamer" and move + /// these methods there. + virtual void EmitTCEntry(const MCSymbol &S); + /// FinishImpl - Streamer specific finalization. virtual void FinishImpl() = 0; /// Finish - Finish emission of machine code. diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index a966a6b8b32..c9ea5ae4846 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -50,12 +50,6 @@ public: virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; - /// MapAndConstraints - Map inline assembly operands to MCInst operands - /// and an associated constraint. - typedef std::pair< unsigned, std::string > MapAndConstraint; - typedef SmallVector<MapAndConstraint, 4> MatchInstMapAndConstraints; - typedef SmallVectorImpl<MapAndConstraint> MatchInstMapAndConstraintsImpl; - /// ParseInstruction - Parse one assembly instruction. /// /// The parser is positioned following the instruction name. The target @@ -88,22 +82,6 @@ public: /// otherwise. virtual bool mnemonicIsValid(StringRef Mnemonic) = 0; - /// MatchInstruction - Recognize a series of operands of a parsed instruction - /// as an actual MCInst. This returns false on success and returns true on - /// failure to match. - /// - /// On failure, the target parser is responsible for emitting a diagnostic - /// explaining the match failure. - virtual bool - MatchInstruction(SMLoc IDLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out, unsigned &Kind, unsigned &Opcode, - MatchInstMapAndConstraintsImpl &MapAndConstraints, - unsigned &OrigErrorInfo, bool matchingInlineAsm = false) { - OrigErrorInfo = ~0x0; - return true; - } - /// MatchAndEmitInstruction - Recognize a series of operands of a parsed /// instruction as an actual MCInst and emit it to the specified MCStreamer. /// This returns false on success and returns true on failure to match. @@ -111,9 +89,10 @@ public: /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. virtual bool - MatchAndEmitInstruction(SMLoc IDLoc, + MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out) = 0; + MCStreamer &Out, unsigned &ErrorInfo, + bool MatchingInlineAsm) = 0; /// checkTargetMatchPredicate - Validate the instruction match against /// any complex target predicates not expressible via match classes. @@ -122,8 +101,7 @@ public: } virtual void convertToMapAndConstraints(unsigned Kind, - const SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MatchInstMapAndConstraintsImpl &MapAndConstraints) = 0; + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; }; } // End llvm namespace diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index d0e65246233..0fbbb959888 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -59,7 +59,6 @@ public: iterator end() const { return getName().end(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MDString *) { return true; } static bool classof(const Value *V) { return V->getValueID() == MDStringVal; } @@ -161,7 +160,6 @@ public: void Profile(FoldingSetNodeID &ID) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MDNode *) { return true; } static bool classof(const Value *V) { return V->getValueID() == MDNodeVal; } diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 358b27a416c..f3d824960c2 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -129,7 +129,6 @@ public: symbol_iterator end_symbols() const; // Cast methods. - static inline bool classof(Archive const *v) { return true; } static inline bool classof(Binary const *v) { return v->isArchive(); } diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index baed81827d0..d555de3accc 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -64,7 +64,6 @@ public: // Cast methods. unsigned int getType() const { return TypeID; } - static inline bool classof(const Binary *v) { return true; } // Convenience methods bool isObject() const { diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index ba81058ae40..d6b92ed0213 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -198,7 +198,6 @@ public: static inline bool classof(const Binary *v) { return v->isCOFF(); } - static inline bool classof(const COFFObjectFile *v) { return true; } }; } diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 3ca69bcb153..204348c0c50 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -723,7 +723,6 @@ public: return v->getType() == getELFType(target_endianness == support::little, is64Bits); } - static inline bool classof(const ELFObjectFile *v) { return true; } }; // Iterate through the version definitions, and place each Elf_Verdef diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index ecb9e256050..97cd4191aa6 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -49,7 +49,6 @@ public: static inline bool classof(const Binary *v) { return v->isMachO(); } - static inline bool classof(const MachOObjectFile *v) { return true; } protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 99ddb3b87b8..41959bd34e1 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -76,13 +76,13 @@ public: } }; -inline bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { +inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } -inline bool operator <(const DataRefImpl &a, const DataRefImpl &b) { +inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; @@ -144,7 +144,7 @@ public: SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; - bool operator <(const SectionRef &Other) const; + bool operator<(const SectionRef &Other) const; error_code getNext(SectionRef &Result) const; @@ -208,7 +208,7 @@ public: SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); bool operator==(const SymbolRef &Other) const; - bool operator <(const SymbolRef &Other) const; + bool operator<(const SymbolRef &Other) const; error_code getNext(SymbolRef &Result) const; @@ -251,7 +251,7 @@ public: LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner); bool operator==(const LibraryRef &Other) const; - bool operator <(const LibraryRef &Other) const; + bool operator<(const LibraryRef &Other) const; error_code getNext(LibraryRef &Result) const; @@ -290,8 +290,8 @@ protected: friend class SymbolRef; 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 getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const =0; + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; + virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; @@ -317,7 +317,7 @@ protected: // A section is 'virtual' if its contents aren't present in the object image. virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0; - virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const = 0; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; @@ -388,7 +388,6 @@ public: static inline bool classof(const Binary *v) { return v->isObject(); } - static inline bool classof(const ObjectFile *v) { return true; } public: static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); @@ -405,7 +404,7 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const { return SymbolPimpl == Other.SymbolPimpl; } -inline bool SymbolRef::operator <(const SymbolRef &Other) const { +inline bool SymbolRef::operator<(const SymbolRef &Other) const { return SymbolPimpl < Other.SymbolPimpl; } @@ -460,7 +459,7 @@ inline bool SectionRef::operator==(const SectionRef &Other) const { return SectionPimpl == Other.SectionPimpl; } -inline bool SectionRef::operator <(const SectionRef &Other) const { +inline bool SectionRef::operator<(const SectionRef &Other) const { return SectionPimpl < Other.SectionPimpl; } @@ -594,7 +593,7 @@ inline bool LibraryRef::operator==(const LibraryRef &Other) const { return LibraryPimpl == Other.LibraryPimpl; } -inline bool LibraryRef::operator <(const LibraryRef &Other) const { +inline bool LibraryRef::operator<(const LibraryRef &Other) const { return LibraryPimpl < Other.LibraryPimpl; } diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 61ac163d4a1..bc5da8e8aa3 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -60,7 +60,6 @@ public: return Instruction::UserOp1; } - static inline bool classof(const Operator *) { return true; } static inline bool classof(const Instruction *) { return true; } static inline bool classof(const ConstantExpr *) { return true; } static inline bool classof(const Value *V) { @@ -106,7 +105,6 @@ public: return (SubclassOptionalData & NoSignedWrap) != 0; } - static inline bool classof(const OverflowingBinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub || @@ -180,7 +178,6 @@ public: /// default precision. float getFPAccuracy() const; - static inline bool classof(const FPMathOperator *) { return true; } static inline bool classof(const Instruction *I) { return I->getType()->isFPOrFPVectorTy(); } @@ -196,9 +193,6 @@ template<typename SuperClass, unsigned Opc> class ConcreteOperator : public SuperClass { ~ConcreteOperator() LLVM_DELETED_FUNCTION; public: - static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) { - return true; - } static inline bool classof(const Instruction *I) { return I->getOpcode() == Opc; } diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index d35febbe6d8..0c71882a77b 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_CASTING_H #define LLVM_SUPPORT_CASTING_H +#include "llvm/Support/type_traits.h" #include <cassert> namespace llvm { @@ -44,13 +45,23 @@ template<typename From> struct simplify_type<const From> { // The core of the implementation of isa<X> is here; To and From should be // the names of classes. This template can be specialized to customize the // implementation of isa<> without rewriting it from scratch. -template <typename To, typename From> +template <typename To, typename From, typename Enabler = void> struct isa_impl { static inline bool doit(const From &Val) { return To::classof(&Val); } }; +/// \brief Always allow upcasts, and perform no dynamic check for them. +template <typename To, typename From> +struct isa_impl<To, From, + typename llvm::enable_if_c< + llvm::is_base_of<To, From>::value + >::type + > { + static inline bool doit(const From &) { return true; } +}; + template <typename To, typename From> struct isa_impl_cl { static inline bool doit(const From &Val) { return isa_impl<To, From>::doit(Val); diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h index 8227c84bffa..025eee7f9f3 100644 --- a/include/llvm/Support/Memory.h +++ b/include/llvm/Support/Memory.h @@ -98,8 +98,8 @@ namespace sys { /// \p ErrMsg [out] returns a string describing any error that occured. /// /// If \p Flags is MF_WRITE, the actual behavior varies - /// with the operating system (i.e. MF_READWRITE on Windows) and the - /// target architecture (i.e. MF_WRITE -> MF_READWRITE on i386). + /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the + /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386). /// /// \r error_success if the function was successful, or an error_code /// describing the failure if an error occurred. diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index eacd651394c..12958fa173d 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -133,7 +133,6 @@ public: virtual void skip() {} unsigned int getType() const { return TypeID; } - static inline bool classof(const Node *) { return true; } void *operator new ( size_t Size , BumpPtrAllocator &Alloc @@ -166,7 +165,6 @@ class NullNode : public Node { public: NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {} - static inline bool classof(const NullNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Null; } @@ -199,7 +197,6 @@ public: /// This happens with escaped characters and multi-line literals. StringRef getValue(SmallVectorImpl<char> &Storage) const; - static inline bool classof(const ScalarNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Scalar; } @@ -246,7 +243,6 @@ public: getValue()->skip(); } - static inline bool classof(const KeyValueNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_KeyValue; } @@ -362,7 +358,6 @@ public: yaml::skip(*this); } - static inline bool classof(const MappingNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Mapping; } @@ -425,7 +420,6 @@ public: yaml::skip(*this); } - static inline bool classof(const SequenceNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Sequence; } @@ -450,7 +444,6 @@ public: StringRef getName() const { return Name; } Node *getTarget(); - static inline bool classof(const ScalarNode *) { return true; } static inline bool classof(const Node *N) { return N->getType() == NK_Alias; } diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 079dc8ce8ed..319298c1325 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -85,7 +85,6 @@ private: virtual void anchor(); public: - static bool classof(const RecTy *) { return true; } RecTyKind getRecTyKind() const { return Kind; } RecTy(RecTyKind K) : Kind(K), ListTy(0) {} @@ -153,7 +152,6 @@ class BitRecTy : public RecTy { static BitRecTy Shared; BitRecTy() : RecTy(BitRecTyKind) {} public: - static bool classof(const BitRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == BitRecTyKind; } @@ -199,7 +197,6 @@ class BitsRecTy : public RecTy { unsigned Size; explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} public: - static bool classof(const BitsRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == BitsRecTyKind; } @@ -248,7 +245,6 @@ class IntRecTy : public RecTy { static IntRecTy Shared; IntRecTy() : RecTy(IntRecTyKind) {} public: - static bool classof(const IntRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == IntRecTyKind; } @@ -293,7 +289,6 @@ class StringRecTy : public RecTy { static StringRecTy Shared; StringRecTy() : RecTy(StringRecTyKind) {} public: - static bool classof(const StringRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == StringRecTyKind; } @@ -342,7 +337,6 @@ class ListRecTy : public RecTy { explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} friend ListRecTy *RecTy::getListTy(); public: - static bool classof(const ListRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == ListRecTyKind; } @@ -389,7 +383,6 @@ class DagRecTy : public RecTy { static DagRecTy Shared; DagRecTy() : RecTy(DagRecTyKind) {} public: - static bool classof(const DagRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == DagRecTyKind; } @@ -436,7 +429,6 @@ class RecordRecTy : public RecTy { explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {} friend class Record; public: - static bool classof(const RecordRecTy *) { return true; } static bool classof(const RecTy *RT) { return RT->getRecTyKind() == RecordRecTyKind; } @@ -485,12 +477,53 @@ RecTy *resolveTypes(RecTy *T1, RecTy *T2); //===----------------------------------------------------------------------===// class Init { +protected: + /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.) + /// + /// This enum is laid out by a preorder traversal of the inheritance + /// hierarchy, and does not contain an entry for abstract classes, as per + /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst. + /// + /// We also explicitly include "first" and "last" values for each + /// interior node of the inheritance tree, to make it easier to read the + /// corresponding classof(). + /// + /// We could pack these a bit tighter by not having the IK_FirstXXXInit + /// and IK_LastXXXInit be their own values, but that would degrade + /// readability for really no benefit. + enum InitKind { + IK_BitInit, + IK_BitsInit, + IK_FirstTypedInit, + IK_DagInit, + IK_DefInit, + IK_FieldInit, + IK_IntInit, + IK_ListInit, + IK_FirstOpInit, + IK_BinOpInit, + IK_TernOpInit, + IK_UnOpInit, + IK_LastOpInit, + IK_StringInit, + IK_VarInit, + IK_VarListElementInit, + IK_LastTypedInit, + IK_UnsetInit, + IK_VarBitInit + }; + +private: + const InitKind Kind; Init(const Init &) LLVM_DELETED_FUNCTION; Init &operator=(const Init &) LLVM_DELETED_FUNCTION; virtual void anchor(); +public: + InitKind getKind() const { return Kind; } + protected: - Init(void) {} + explicit Init(InitKind K) : Kind(K) {} public: virtual ~Init() {} @@ -591,9 +624,13 @@ class TypedInit : public Init { TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION; protected: - explicit TypedInit(RecTy *T) : Ty(T) {} + explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {} public: + static bool classof(const Init *I) { + return I->getKind() >= IK_FirstTypedInit && + I->getKind() <= IK_LastTypedInit; + } RecTy *getType() const { return Ty; } virtual Init * @@ -618,12 +655,15 @@ public: /// UnsetInit - ? - Represents an uninitialized value /// class UnsetInit : public Init { - UnsetInit() : Init() {} + UnsetInit() : Init(IK_UnsetInit) {} UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION; UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_UnsetInit; + } static UnsetInit *get(); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -644,12 +684,15 @@ public: class BitInit : public Init { bool Value; - explicit BitInit(bool V) : Value(V) {} + explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION; BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_BitInit; + } static BitInit *get(bool V); bool getValue() const { return Value; } @@ -672,12 +715,16 @@ public: class BitsInit : public Init, public FoldingSetNode { std::vector<Init*> Bits; - BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {} + BitsInit(ArrayRef<Init *> Range) + : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {} BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION; BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_BitsInit; + } static BitsInit *get(ArrayRef<Init *> Range); void Profile(FoldingSetNodeID &ID) const; @@ -716,12 +763,16 @@ public: class IntInit : public TypedInit { int64_t Value; - explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {} + explicit IntInit(int64_t V) + : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {} IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION; IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_IntInit; + } static IntInit *get(int64_t V); int64_t getValue() const { return Value; } @@ -754,13 +805,16 @@ class StringInit : public TypedInit { std::string Value; explicit StringInit(const std::string &V) - : TypedInit(StringRecTy::get()), Value(V) {} + : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION; StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION; virtual void anchor(); public: + static bool classof(const Init *I) { + return I->getKind() == IK_StringInit; + } static StringInit *get(StringRef); const std::string &getValue() const { return Value; } @@ -794,12 +848,16 @@ public: private: explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy) - : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {} + : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), + Values(Range.begin(), Range.end()) {} ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION; ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_ListInit; + } static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy); void Profile(FoldingSetNodeID &ID) const; @@ -855,9 +913,13 @@ class OpInit : public TypedInit { OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION; protected: - explicit OpInit(RecTy *Type) : TypedInit(Type) {} + explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {} public: + static bool classof(const Init *I) { + return I->getKind() >= IK_FirstOpInit && + I->getKind() <= IK_LastOpInit; + } // Clone - Clone this operator, replacing arguments with the new list virtual OpInit *clone(std::vector<Init *> &Operands) const = 0; @@ -889,12 +951,15 @@ private: Init *LHS; UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) - : OpInit(Type), Opc(opc), LHS(lhs) {} + : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {} UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION; UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_UnOpInit; + } static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); // Clone - Clone this operator, replacing arguments with the new list @@ -932,12 +997,15 @@ private: Init *LHS, *RHS; BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {} + OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {} BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION; BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_BinOpInit; + } static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type); @@ -982,12 +1050,15 @@ private: TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} + OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION; TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_TernOpInit; + } static TernOpInit *get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type); @@ -1036,14 +1107,17 @@ class VarInit : public TypedInit { Init *VarName; explicit VarInit(const std::string &VN, RecTy *T) - : TypedInit(T), VarName(StringInit::get(VN)) {} + : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {} explicit VarInit(Init *VN, RecTy *T) - : TypedInit(T), VarName(VN) {} + : TypedInit(IK_VarInit, T), VarName(VN) {} VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION; VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarInit; + } static VarInit *get(const std::string &VN, RecTy *T); static VarInit *get(Init *VN, RecTy *T); @@ -1083,7 +1157,7 @@ class VarBitInit : public Init { TypedInit *TI; unsigned Bit; - VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) { + VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) { assert(T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && @@ -1095,6 +1169,9 @@ class VarBitInit : public Init { VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarBitInit; + } static VarBitInit *get(TypedInit *T, unsigned B); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -1120,8 +1197,9 @@ class VarListElementInit : public TypedInit { unsigned Element; VarListElementInit(TypedInit *T, unsigned E) - : TypedInit(cast<ListRecTy>(T->getType())->getElementType()), - TI(T), Element(E) { + : TypedInit(IK_VarListElementInit, + cast<ListRecTy>(T->getType())->getElementType()), + TI(T), Element(E) { assert(T->getType() && isa<ListRecTy>(T->getType()) && "Illegal VarBitInit expression!"); } @@ -1130,6 +1208,9 @@ class VarListElementInit : public TypedInit { void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_VarListElementInit; + } static VarListElementInit *get(TypedInit *T, unsigned E); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -1157,13 +1238,16 @@ public: class DefInit : public TypedInit { Record *Def; - DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {} + DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {} friend class Record; DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION; DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_DefInit; + } static DefInit *get(Record*); virtual Init *convertInitializerTo(RecTy *Ty) const { @@ -1201,7 +1285,7 @@ class FieldInit : public TypedInit { std::string FieldName; // Field we are accessing FieldInit(Init *R, const std::string &FN) - : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { + : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) { assert(getType() && "FieldInit with non-record type!"); } @@ -1209,6 +1293,9 @@ class FieldInit : public TypedInit { FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_FieldInit; + } static FieldInit *get(Init *R, const std::string &FN); static FieldInit *get(Init *R, const Init *FN); @@ -1242,7 +1329,7 @@ class DagInit : public TypedInit, public FoldingSetNode { DagInit(Init *V, const std::string &VN, ArrayRef<Init *> ArgRange, ArrayRef<std::string> NameRange) - : TypedInit(DagRecTy::get()), Val(V), ValName(VN), + : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN), Args(ArgRange.begin(), ArgRange.end()), ArgNames(NameRange.begin(), NameRange.end()) {} @@ -1250,6 +1337,9 @@ class DagInit : public TypedInit, public FoldingSetNode { DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION; public: + static bool classof(const Init *I) { + return I->getKind() == IK_DagInit; + } static DagInit *get(Init *V, const std::string &VN, ArrayRef<Init *> ArgRange, ArrayRef<std::string> NameRange); diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index b3149e960a8..ad85c7e13ae 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -146,7 +146,7 @@ public: // Return the pointer type for the given address space, defaults to // the pointer type from the data layout. // FIXME: The default needs to be removed once all the code is updated. - virtual MVT getPointerTy(uint32_t addrspace = 0) const { return PointerTy; } + virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; } virtual MVT getShiftAmountTy(EVT LHSTy) const; /// isSelectExpensive - Return true if the select operation is expensive for @@ -1366,7 +1366,7 @@ public: } /// HandleByVal - Target-specific cleanup for formal ByVal parameters. - virtual void HandleByVal(CCState *, unsigned &) const {} + virtual void HandleByVal(CCState *, unsigned &, unsigned) const {} /// CanLowerReturn - This hook should be implemented to check whether the /// return values described by the Outs array can fit into the return diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 988916f9d95..18e589e2bc0 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -17,6 +17,8 @@ #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/TargetTransformInfo.h" +#include "llvm/Target/TargetTransformImpl.h" #include "llvm/ADT/StringRef.h" #include <cassert> #include <string> @@ -107,6 +109,10 @@ public: virtual const TargetLowering *getTargetLowering() const { return 0; } virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; } virtual const DataLayout *getDataLayout() const { return 0; } + virtual const ScalarTargetTransformInfo* + getScalarTargetTransformInfo() const { return 0; } + virtual const VectorTargetTransformInfo* + getVectorTargetTransformInfo() const { return 0; } /// getMCAsmInfo - Return target specific asm information. /// diff --git a/include/llvm/Target/TargetTransformImpl.h b/include/llvm/Target/TargetTransformImpl.h new file mode 100644 index 00000000000..7648f4f935c --- /dev/null +++ b/include/llvm/Target/TargetTransformImpl.h @@ -0,0 +1,54 @@ +//=- llvm/Target/TargetTransformImpl.h - Target Loop Trans 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 contains the target-specific implementations of the +// TargetTransform interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H +#define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H + +#include "llvm/TargetTransformInfo.h" + +namespace llvm { + +class TargetLowering; + +/// ScalarTargetTransformInfo - This is a default implementation for the +/// ScalarTargetTransformInfo interface. Different targets can implement +/// this interface differently. +class ScalarTargetTransformImpl : public ScalarTargetTransformInfo { +private: + const TargetLowering *TLI; + +public: + /// Ctor + explicit ScalarTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} + + virtual bool isLegalAddImmediate(int64_t imm) const; + + virtual bool isLegalICmpImmediate(int64_t imm) const; + + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; + + virtual bool isTypeLegal(Type *Ty) const; + + virtual unsigned getJumpBufAlignment() const; + + virtual unsigned getJumpBufSize() const; +}; + +class VectorTargetTransformImpl : public VectorTargetTransformInfo { }; + +} // end llvm namespace + +#endif diff --git a/include/llvm/TargetTransformInfo.h b/include/llvm/TargetTransformInfo.h new file mode 100644 index 00000000000..82fc14dbd74 --- /dev/null +++ b/include/llvm/TargetTransformInfo.h @@ -0,0 +1,128 @@ +//===- llvm/Transforms/TargetTransformInfo.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass exposes codegen information to IR-level passes. Every +// transformation that uses codegen information is broken into three parts: +// 1. The IR-level analysis pass. +// 2. The IR-level transformation interface which provides the needed +// information. +// 3. Codegen-level implementation which uses target-specific hooks. +// +// This file defines #2, which is the interface that IR-level transformations +// use for querying the codegen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE +#define LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE + +#include "llvm/Pass.h" +#include "llvm/AddressingMode.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Type.h" + +namespace llvm { + +class ScalarTargetTransformInfo; +class VectorTargetTransformInfo; + +/// TargetTransformInfo - This pass provides access to the codegen +/// interfaces that are needed for IR-level transformations. +class TargetTransformInfo : public ImmutablePass { +private: + const ScalarTargetTransformInfo *STTI; + const VectorTargetTransformInfo *VTTI; +public: + /// Default ctor. + /// + /// @note This has to exist, because this is a pass, but it should never be + /// used. + TargetTransformInfo(); + + explicit TargetTransformInfo(const ScalarTargetTransformInfo* S, + const VectorTargetTransformInfo *V) + : ImmutablePass(ID), STTI(S), VTTI(V) { + initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry()); + } + + TargetTransformInfo(const TargetTransformInfo &T) : + ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { } + + const ScalarTargetTransformInfo* getScalarTargetTransformInfo() { + return STTI; + } + const VectorTargetTransformInfo* getVectorTargetTransformInfo() { + return VTTI; + } + + /// Pass identification, replacement for typeid. + static char ID; +}; + +// ---------------------------------------------------------------------------// +// The classes below are inherited and implemented by target-specific classes +// in the codegen. +// ---------------------------------------------------------------------------// + +/// ScalarTargetTransformInfo - This interface is used by IR-level passes +/// that need target-dependent information for generic scalar transformations. +/// LSR, and LowerInvoke use this interface. +class ScalarTargetTransformInfo { +public: + virtual ~ScalarTargetTransformInfo() {} + + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t) const { + return false; + } + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(int64_t) const { + return false; + } + /// isLegalAddressingMode - Return true if the addressing mode represented by + /// AM is legal for this target, for a load/store of the specified type. + /// The type may be VoidTy, in which case only return true if the addressing + /// mode is legal for a load/store of any legal type. + /// TODO: Handle pre/postinc as well. + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const { + return false; + } + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(Type * /*Ty1*/, Type * /*Ty2*/) const { + return false; + } + /// Is this type legal. + virtual bool isTypeLegal(Type *Ty) const { + return false; + } + /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes + virtual unsigned getJumpBufAlignment() const { + return 0; + } + /// getJumpBufSize - returns the target's jmp_buf size in bytes. + virtual unsigned getJumpBufSize() const { + return 0; + } +}; + +class VectorTargetTransformInfo { + // TODO: define an interface for VectorTargetTransformInfo. +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 4b0c448acfc..8e63aaa4e87 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -34,7 +34,7 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, bool UseExtraChecksum = false); // Insert AddressSanitizer (address sanity checking) instrumentation -ModulePass *createAddressSanitizerPass(); +FunctionPass *createAddressSanitizerPass(); // Insert ThreadSanitizer (race detection) instrumentation FunctionPass *createThreadSanitizerPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index a5d8eed7462..3b665bf4b68 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -119,7 +119,7 @@ Pass *createLICMPass(); // optional parameter used to consult the target machine whether certain // transformations are profitable. // -Pass *createLoopStrengthReducePass(const TargetLowering *TLI = 0); +Pass *createLoopStrengthReducePass(); Pass *createGlobalMergePass(const TargetLowering *TLI = 0); @@ -249,9 +249,8 @@ extern char &LowerSwitchID; // purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet" // lowering pass. // -FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0); -FunctionPass *createLowerInvokePass(const TargetLowering *TLI, - bool useExpensiveEHSupport); +FunctionPass *createLowerInvokePass(); +FunctionPass *createLowerInvokePass(bool useExpensiveEHSupport); extern char &LowerInvokePassID; //===----------------------------------------------------------------------===// diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 21dd3fbe110..fd1b5556ef2 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -186,7 +186,8 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, bool isInBounds = cast<GEPOperator>(GEP)->isInBounds() && !NoAssumptions; // Build a mask for high order bits. - unsigned IntPtrWidth = TD.getPointerSizeInBits(); + unsigned AS = cast<GEPOperator>(GEP)->getPointerAddressSpace(); + unsigned IntPtrWidth = TD.getPointerSizeInBits(AS); uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth); for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h new file mode 100644 index 00000000000..5db2d001814 --- /dev/null +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -0,0 +1,43 @@ +//===- SimplifyLibCalls.h - Library call simplifier -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file exposes an interface to build some C language libcalls for +// optimization passes that need to call the various functions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H +#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H + +namespace llvm { + class Value; + class CallInst; + class DataLayout; + class TargetLibraryInfo; + class LibCallSimplifierImpl; + + /// LibCallSimplifier - This class implements a collection of optimizations + /// that replace well formed calls to library functions with a more optimal + /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'. + class LibCallSimplifier { + /// Impl - A pointer to the actual implementation of the library call + /// simplifier. + LibCallSimplifierImpl *Impl; + public: + LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); + virtual ~LibCallSimplifier(); + + /// optimizeCall - Take the given call instruction and return a more + /// optimal value to replace the instruction with or 0 if a more + /// optimal form can't be found. + Value *optimizeCall(CallInst *CI); + }; +} // End llvm namespace + +#endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 8e66ea86094..5a867045af8 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -389,9 +389,6 @@ public: 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; } - /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). PointerType *getPointerTo(unsigned AddrSpace = 0); diff --git a/include/llvm/User.h b/include/llvm/User.h index ade3676260b..df303d0dd5f 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -176,7 +176,6 @@ public: void replaceUsesOfWith(Value *From, Value *To); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const User *) { return true; } static inline bool classof(const Value *V) { return isa<Instruction>(V) || isa<Constant>(V); } diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 6560a420bf6..5b19435ebaf 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -257,11 +257,6 @@ public: /// hasValueHandle - Return true if there is a value handle associated with /// this value. bool hasValueHandle() const { return HasValueHandle; } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *) { - return true; // Values are always values. - } /// stripPointerCasts - This method strips off any unneeded pointer casts and /// all-zero GEPs from the specified value, returning the original uncasted |