diff options
Diffstat (limited to 'include')
65 files changed, 1317 insertions, 607 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 6879205..d57c250 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -117,8 +117,7 @@ typedef enum { LLVMNoCaptureAttribute = 1<<21, LLVMNoRedZoneAttribute = 1<<22, LLVMNoImplicitFloatAttribute = 1<<23, - LLVMNakedAttribute = 1<<24, - LLVMInlineHintAttribute = 1<<25 + LLVMNakedAttribute = 1<<24 } LLVMAttribute; typedef enum { @@ -1008,7 +1007,7 @@ namespace llvm { \ template<typename T> \ inline T *unwrap(ref P) { \ - T *Q = dynamic_cast<T*>(unwrap(P)); \ + T *Q = (T*)unwrap(P); \ assert(Q && "Invalid cast!"); \ return Q; \ } diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 6b494ef..41197a1 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -92,6 +92,19 @@ template<> struct DenseMapInfo<unsigned long long> { } }; +// Provide DenseMapInfo for long longs. +template<> struct DenseMapInfo<long long> { + static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } + static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } + static unsigned getHashValue(const long long& Val) { + return (unsigned)(Val * 37LL); + } + static bool isEqual(const long long& LHS, + const long long& RHS) { + return LHS == RHS; + } +}; + // Provide DenseMapInfo for all pairs whose members have info. template<typename T, typename U> struct DenseMapInfo<std::pair<T, U> > { diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index fc9fe8b..1b3f1a9 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -217,7 +217,7 @@ public: // Utility methods. //===--------------------------------------------------===// - inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; } + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) { ID.AddPointer(M.Root); diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 676a198..ac06a40 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -51,13 +51,11 @@ public: /// getLeft - Returns a pointer to the left subtree. This value /// is NULL if there is no left subtree. - ImutAVLTree *getLeft() const { - return reinterpret_cast<ImutAVLTree*>(Left & ~LeftFlags); - } + ImutAVLTree *getLeft() const { return Left; } /// getRight - Returns a pointer to the right subtree. This value is /// NULL if there is no right subtree. - ImutAVLTree* getRight() const { return Right; } + ImutAVLTree *getRight() const { return Right; } /// getHeight - Returns the height of the tree. A tree with no subtrees /// has a height of 1. @@ -190,23 +188,22 @@ public: unsigned HL = getLeft() ? getLeft()->verify() : 0; unsigned HR = getRight() ? getRight()->verify() : 0; - assert (getHeight() == ( HL > HR ? HL : HR ) + 1 - && "Height calculation wrong."); - - assert ((HL > HR ? HL-HR : HR-HL) <= 2 - && "Balancing invariant violated."); + assert(getHeight() == ( HL > HR ? HL : HR ) + 1 + && "Height calculation wrong"); + assert((HL > HR ? HL-HR : HR-HL) <= 2 + && "Balancing invariant violated"); - assert (!getLeft() - || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()), - ImutInfo::KeyOfValue(getValue())) - && "Value in left child is not less that current value."); + assert(!getLeft() + || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()), + ImutInfo::KeyOfValue(getValue())) + && "Value in left child is not less that current value"); - assert (!getRight() - || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()), - ImutInfo::KeyOfValue(getRight()->getValue())) - && "Current value is not less that value of right child."); + assert(!getRight() + || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()), + ImutInfo::KeyOfValue(getRight()->getValue())) + && "Current value is not less that value of right child"); return getHeight(); } @@ -221,9 +218,11 @@ public: //===----------------------------------------------------===// private: - uintptr_t Left; + ImutAVLTree* Left; ImutAVLTree* Right; - unsigned Height; + unsigned Height : 28; + unsigned Mutable : 1; + unsigned CachedDigest : 1; value_type Value; uint32_t Digest; @@ -232,15 +231,12 @@ private: //===----------------------------------------------------===// private: - - enum { Mutable = 0x1, NoCachedDigest = 0x2, LeftFlags = 0x3 }; - /// ImutAVLTree - Internal constructor that is only called by /// ImutAVLFactory. - ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height) - : Left(reinterpret_cast<uintptr_t>(l) | (Mutable | NoCachedDigest)), - Right(r), Height(height), Value(v), Digest(0) {} - + ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, + unsigned height) + : Left(l), Right(r), Height(height), Mutable(true), CachedDigest(false), + Value(v), Digest(0) {} /// isMutable - Returns true if the left and right subtree references /// (as well as height) can be changed. If this method returns false, @@ -248,11 +244,11 @@ private: /// object should always have this method return true. Further, if this /// method returns false for an instance of ImutAVLTree, all subtrees /// will also have this method return false. The converse is not true. - bool isMutable() const { return Left & Mutable; } + bool isMutable() const { return Mutable; } /// hasCachedDigest - Returns true if the digest for this tree is cached. /// This can only be true if the tree is immutable. - bool hasCachedDigest() const { return !(Left & NoCachedDigest); } + bool hasCachedDigest() const { return CachedDigest; } //===----------------------------------------------------===// // Mutating operations. A tree root can be manipulated as @@ -269,13 +265,13 @@ private: /// it is an error to call setLeft(), setRight(), and setHeight(). void MarkImmutable() { assert(isMutable() && "Mutable flag already removed."); - Left &= ~Mutable; + Mutable = false; } /// MarkedCachedDigest - Clears the NoCachedDigest flag for a tree. void MarkedCachedDigest() { assert(!hasCachedDigest() && "NoCachedDigest flag already removed."); - Left &= ~NoCachedDigest; + CachedDigest = true; } /// setLeft - Changes the reference of the left subtree. Used internally @@ -283,7 +279,8 @@ private: void setLeft(ImutAVLTree* NewLeft) { assert(isMutable() && "Only a mutable tree can have its left subtree changed."); - Left = reinterpret_cast<uintptr_t>(NewLeft) | LeftFlags; + Left = NewLeft; + CachedDigest = false; } /// setRight - Changes the reference of the right subtree. Used internally @@ -293,9 +290,7 @@ private: "Only a mutable tree can have its right subtree changed."); Right = NewRight; - // Set the NoCachedDigest flag. - Left = Left | NoCachedDigest; - + CachedDigest = false; } /// setHeight - Changes the height of the tree. Used internally by @@ -397,7 +392,7 @@ public: private: bool isEmpty(TreeTy* T) const { return !T; } - unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; } + unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; } TreeTy* Left(TreeTy* T) const { return T->getLeft(); } TreeTy* Right(TreeTy* T) const { return T->getRight(); } value_type_ref Value(TreeTy* T) const { return T->Value; } @@ -405,7 +400,7 @@ private: unsigned IncrementHeight(TreeTy* L, TreeTy* R) const { unsigned hl = Height(L); unsigned hr = Height(R); - return ( hl > hr ? hl : hr ) + 1; + return (hl > hr ? hl : hr) + 1; } static bool CompareTreeWithSection(TreeTy* T, @@ -434,17 +429,17 @@ private: TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) { BumpPtrAllocator& A = getAllocator(); TreeTy* T = (TreeTy*) A.Allocate<TreeTy>(); - new (T) TreeTy(L,R,V,IncrementHeight(L,R)); + new (T) TreeTy(L, R, V, IncrementHeight(L,R)); return T; } TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) { - assert (!isEmpty(OldTree)); + assert(!isEmpty(OldTree)); if (OldTree->isMutable()) { OldTree->setLeft(L); OldTree->setRight(R); - OldTree->setHeight(IncrementHeight(L,R)); + OldTree->setHeight(IncrementHeight(L, R)); return OldTree; } else @@ -459,8 +454,7 @@ private: unsigned hr = Height(R); if (hl > hr + 2) { - assert (!isEmpty(L) && - "Left tree cannot be empty to have a height >= 2."); + assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2"); TreeTy* LL = Left(L); TreeTy* LR = Right(L); @@ -468,8 +462,7 @@ private: if (Height(LL) >= Height(LR)) return CreateNode(LL, L, CreateNode(LR,V,R)); - assert (!isEmpty(LR) && - "LR cannot be empty because it has a height >= 1."); + assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1"); TreeTy* LRL = Left(LR); TreeTy* LRR = Right(LR); @@ -477,8 +470,7 @@ private: return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R)); } else if (hr > hl + 2) { - assert (!isEmpty(R) && - "Right tree cannot be empty to have a height >= 2."); + assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2"); TreeTy* RL = Left(R); TreeTy* RR = Right(R); @@ -486,8 +478,7 @@ private: if (Height(RR) >= Height(RL)) return CreateNode(CreateNode(L,V,RL), R, RR); - assert (!isEmpty(RL) && - "RL cannot be empty because it has a height >= 1."); + assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1"); TreeTy* RLL = Left(RL); TreeTy* RLR = Right(RL); @@ -505,7 +496,7 @@ private: if (isEmpty(T)) return CreateNode(T, V, T); - assert (!T->isMutable()); + assert(!T->isMutable()); key_type_ref K = ImutInfo::KeyOfValue(V); key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); @@ -526,7 +517,7 @@ private: if (isEmpty(T)) return T; - assert (!T->isMutable()); + assert(!T->isMutable()); key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T)); @@ -548,7 +539,7 @@ private: } TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) { - assert (!isEmpty(T)); + assert(!isEmpty(T)); if (isEmpty(Left(T))) { NodeRemoved = T; @@ -641,12 +632,12 @@ public: } TreeTy* operator*() const { - assert (!stack.empty()); + assert(!stack.empty()); return reinterpret_cast<TreeTy*>(stack.back() & ~Flags); } uintptr_t getVisitState() { - assert (!stack.empty()); + assert(!stack.empty()); return stack.back() & Flags; } @@ -658,7 +649,7 @@ public: } void SkipToParent() { - assert (!stack.empty()); + assert(!stack.empty()); stack.pop_back(); if (stack.empty()) @@ -672,7 +663,7 @@ public: stack.back() |= VisitedRight; break; default: - assert (false && "Unreachable."); + assert(false && "Unreachable."); } } @@ -690,10 +681,10 @@ public: inline bool operator!=(const _Self& x) const { return !operator==(x); } _Self& operator++() { - assert (!stack.empty()); + assert(!stack.empty()); TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); - assert (Current); + assert(Current); switch (getVisitState()) { case VisitedNone: @@ -717,17 +708,17 @@ public: break; default: - assert (false && "Unreachable."); + assert(false && "Unreachable."); } return *this; } _Self& operator--() { - assert (!stack.empty()); + assert(!stack.empty()); TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); - assert (Current); + assert(Current); switch (getVisitState()) { case VisitedNone: @@ -752,7 +743,7 @@ public: break; default: - assert (false && "Unreachable."); + assert(false && "Unreachable."); } return *this; @@ -1051,7 +1042,7 @@ public: // Utility methods. //===--------------------------------------------------===// - inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; } + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) { ID.AddPointer(S.Root); diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h new file mode 100644 index 0000000..4828eba --- /dev/null +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -0,0 +1,83 @@ +//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Templates to create dotty viewer and printer passes for GraphTraits graphs. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H +#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H + +#include "llvm/Pass.h" +#include "llvm/Analysis/CFGPrinter.h" + +namespace llvm { +template <class Analysis, bool Simple> +struct DOTGraphTraitsViewer : public FunctionPass { + std::string Name; + + DOTGraphTraitsViewer(std::string GraphName, const void *ID) : FunctionPass(ID) { + Name = GraphName; + } + + virtual bool runOnFunction(Function &F) { + Analysis *Graph; + std::string Title, GraphName; + Graph = &getAnalysis<Analysis>(); + GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); + Title = GraphName + " for '" + F.getNameStr() + "' function"; + ViewGraph(Graph, Name, Simple, Title); + + return false; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<Analysis>(); + } +}; + +template <class Analysis, bool Simple> +struct DOTGraphTraitsPrinter : public FunctionPass { + + std::string Name; + + DOTGraphTraitsPrinter(std::string GraphName, const void *ID) + : FunctionPass(ID) { + Name = GraphName; + } + + virtual bool runOnFunction(Function &F) { + Analysis *Graph; + std::string Filename = Name + "." + F.getNameStr() + ".dot"; + errs() << "Writing '" << Filename << "'..."; + + std::string ErrorInfo; + raw_fd_ostream File(Filename.c_str(), ErrorInfo); + Graph = &getAnalysis<Analysis>(); + + std::string Title, GraphName; + GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); + Title = GraphName + " for '" + F.getNameStr() + "' function"; + + if (ErrorInfo.empty()) + WriteGraph(File, Graph, Simple, Name, Title); + else + errs() << " error opening file for writing!"; + errs() << "\n"; + return false; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<Analysis>(); + } +}; +} +#endif diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index cc9514c..150d3ee 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -475,7 +475,7 @@ namespace llvm { /// is not associated with any DWARF tag. class DILocation : public DIDescriptor { public: - explicit DILocation(MDNode *N) : DIDescriptor(N) { ; } + explicit DILocation(MDNode *N) : DIDescriptor(N) { } unsigned getLineNumber() const { return getUnsignedField(0); } unsigned getColumnNumber() const { return getUnsignedField(1); } @@ -587,7 +587,7 @@ namespace llvm { StringRef DisplayName, StringRef LinkageName, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type, bool isLocalToUnit, + DIType Ty, bool isLocalToUnit, bool isDefinition, unsigned VK = 0, unsigned VIndex = 0, @@ -603,21 +603,21 @@ namespace llvm { StringRef DisplayName, StringRef LinkageName, DICompileUnit CompileUnit, - unsigned LineNo, DIType Type, bool isLocalToUnit, + unsigned LineNo, DIType Ty, bool isLocalToUnit, bool isDefinition, llvm::GlobalVariable *GV); /// CreateVariable - Create a new descriptor for the specified variable. DIVariable CreateVariable(unsigned Tag, DIDescriptor Context, StringRef Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type); + DIType Ty); /// CreateComplexVariable - Create a new descriptor for the specified /// variable which has a complex address expression for its address. DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type, + DIType Ty, SmallVector<Value *, 9> &addr); /// CreateLexicalBlock - This creates a descriptor for a lexical block @@ -656,13 +656,6 @@ namespace llvm { Constant *GetTagConstant(unsigned TAG); }; - /// Finds the dbg.declare intrinsic corresponding to this value if any. - /// It looks through pointer casts too. - const DbgDeclareInst *findDbgDeclare(const Value *V); - - /// Find the debug info descriptor corresponding to this global variable. - Value *findDbgGlobalDeclare(GlobalVariable *V); - bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type, unsigned &LineNo, std::string &File, std::string &Dir); diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h index 5ecb348..8cea96d 100644 --- a/include/llvm/Analysis/DominatorInternals.h +++ b/include/llvm/Analysis/DominatorInternals.h @@ -262,29 +262,17 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, DT.Info[W]; // Step #2: Calculate the semidominators of all vertices - bool HasChildOutsideDFS = false; // initialize the semi dominator to point to the parent node WInfo.Semi = WInfo.Parent; for (typename GraphTraits<Inverse<NodeT> >::ChildIteratorType CI = GraphTraits<Inverse<NodeT> >::child_begin(W), - E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI) { + E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI) if (DT.Info.count(*CI)) { // Only if this predecessor is reachable! unsigned SemiU = DT.Info[Eval<GraphT>(DT, *CI)].Semi; if (SemiU < WInfo.Semi) WInfo.Semi = SemiU; } - else { - // if the child has no DFS number it is not post-dominated by any exit, - // and so is the current block. - HasChildOutsideDFS = true; - } - } - - // if some child has no DFS number it is not post-dominated by any exit, - // and so is the current block. - if (DT.isPostDominator() && HasChildOutsideDFS) - WInfo.Semi = 0; DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W); diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index fcd9caa..50f7d45 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -212,6 +212,11 @@ public: /// value of the OperandValToReplace of the given IVStrideUse. const SCEV *getReplacementExpr(const IVStrideUse &U) const; + /// getCanonicalExpr - Return a SCEV expression which computes the + /// value of the SCEV of the given IVStrideUse, ignoring the + /// isUseOfPostIncrementedValue flag. + const SCEV *getCanonicalExpr(const IVStrideUse &U) const; + void print(raw_ostream &OS, const Module* = 0) const; /// dump - This method is used for debugging. diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 2dceccb..10ff103 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -28,8 +28,8 @@ class PMStack; class LoopPass : public Pass { public: - explicit LoopPass(intptr_t pid) : Pass(pid) {} - explicit LoopPass(void *pid) : Pass(pid) {} + explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {} + explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {} // runOnLoop - This method should be implemented by the subclass to perform // whatever action is necessary for the specified Loop. @@ -94,6 +94,9 @@ public: return "Loop Pass Manager"; } + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + /// Print passes managed by this manager void dumpPassStructure(unsigned Offset); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 6f57c74..e281971 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -167,7 +167,7 @@ namespace llvm { }; friend class SCEVCallbackVH; - friend struct SCEVExpander; + friend class SCEVExpander; /// F - The function we are analyzing. /// @@ -181,6 +181,10 @@ namespace llvm { /// TargetData *TD; + /// DT - The dominator tree. + /// + DominatorTree *DT; + /// CouldNotCompute - This SCEV is used to represent unknown trip /// counts and things. SCEVCouldNotCompute CouldNotCompute; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index bbdd043..01df503 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -26,19 +26,47 @@ namespace llvm { /// Clients should create an instance of this class when rewriting is needed, /// and destroy it when finished to allow the release of the associated /// memory. - struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { + class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { + public: ScalarEvolution &SE; + + private: std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > InsertedExpressions; std::set<Value*> InsertedValues; + /// PostIncLoop - When non-null, expanded addrecs referring to the given + /// loop expanded in post-inc mode. For example, expanding {1,+,1}<L> in + /// post-inc mode returns the add instruction that adds one to the phi + /// for {0,+,1}<L>, as opposed to a new phi starting at 1. This is only + /// supported in non-canonical mode. + const Loop *PostIncLoop; + + /// IVIncInsertPos - When this is non-null, addrecs expanded in the + /// loop it indicates should be inserted with increments at + /// IVIncInsertPos. + const Loop *IVIncInsertLoop; + + /// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop, + /// insert the IV increment at this position. + Instruction *IVIncInsertPos; + + /// CanonicalMode - When true, expressions are expanded in "canonical" + /// form. In particular, addrecs are expanded as arithmetic based on + /// a canonical induction variable. When false, expression are expanded + /// in a more literal form. + bool CanonicalMode; + + protected: typedef IRBuilder<true, TargetFolder> BuilderType; BuilderType Builder; friend struct SCEVVisitor<SCEVExpander, Value*>; public: + /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. explicit SCEVExpander(ScalarEvolution &se) - : SE(se), Builder(se.getContext(), TargetFolder(se.TD)) {} + : SE(se), PostIncLoop(0), IVIncInsertLoop(0), CanonicalMode(true), + Builder(se.getContext(), TargetFolder(se.TD)) {} /// clear - Erase the contents of the InsertedExpressions map so that users /// trying to expand the same expression into multiple BasicBlocks or @@ -54,11 +82,36 @@ namespace llvm { /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *IP) { + Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I) { + BasicBlock::iterator IP = I; + while (isInsertedInstruction(IP)) ++IP; Builder.SetInsertPoint(IP->getParent(), IP); return expandCodeFor(SH, Ty); } + /// setIVIncInsertPos - Set the current IV increment loop and position. + void setIVIncInsertPos(const Loop *L, Instruction *Pos) { + assert(!CanonicalMode && + "IV increment positions are not supported in CanonicalMode"); + IVIncInsertLoop = L; + IVIncInsertPos = Pos; + } + + /// setPostInc - If L is non-null, enable post-inc expansion for addrecs + /// referring to the given loop. If L is null, disable post-inc expansion + /// completely. Post-inc expansion is only supported in non-canonical + /// mode. + void setPostInc(const Loop *L) { + assert(!CanonicalMode && + "Post-inc expansion is not supported in CanonicalMode"); + PostIncLoop = L; + } + + /// disableCanonicalMode - Disable the behavior of expanding expressions in + /// canonical form rather than in a more literal form. Non-canonical mode + /// is useful for late optimization passes. + void disableCanonicalMode() { CanonicalMode = false; } + private: LLVMContext &getContext() const { return SE.getContext(); } @@ -121,6 +174,16 @@ namespace llvm { Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); } + + void rememberInstruction(Value *I) { + if (!PostIncLoop) InsertedValues.insert(I); + } + + Value *expandAddRecExprLiterally(const SCEVAddRecExpr *); + PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, + const Loop *L, + const Type *ExpandTy, + const Type *IntTy); }; } diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 2c50350..64b8b0b 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -295,6 +295,13 @@ namespace llvm { public: virtual const char *getOperationStr() const { return " + "; } + virtual const Type *getType() const { + // Use the type of the last operand, which is likely to be a pointer + // type, if there is one. This doesn't usually matter, but it can help + // reduce casts when the expressions are expanded. + return getOperand(getNumOperands() - 1)->getType(); + } + /// 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) { diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 068f81f..7fa5d4a 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -58,8 +58,6 @@ const Attributes NoRedZone = 1<<22; /// disable redzone const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point /// instructions. const Attributes Naked = 1<<24; ///< Naked function -const Attributes InlineHint = 1<<25; ///< source said inlining was - ///desirable /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -68,7 +66,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// be used on return values or function parameters. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone | NoImplicitFloat | Naked | InlineHint; + NoRedZone | NoImplicitFloat | Naked; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/CallGraphSCCPass.h index fc9feda..feab763 100644 --- a/include/llvm/CallGraphSCCPass.h +++ b/include/llvm/CallGraphSCCPass.h @@ -32,8 +32,8 @@ class PMStack; struct CallGraphSCCPass : public Pass { - explicit CallGraphSCCPass(intptr_t pid) : Pass(pid) {} - explicit CallGraphSCCPass(void *pid) : Pass(pid) {} + explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {} + explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {} /// doInitialization - This method is called before the SCC's of the program /// has been processed, allowing the pass to do initialization as necessary. diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 9a07e31..377096c 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -48,10 +48,12 @@ namespace llvm { class MCSection; class MCStreamer; class MCSymbol; + class MDNode; class DwarfWriter; class Mangler; class MCAsmInfo; class TargetLoweringObjectFile; + class Twine; class Type; class formatted_raw_ostream; @@ -131,10 +133,10 @@ namespace llvm { /// Mangler *Mang; - /// Cache of mangled name for current function. This is recalculated at the + /// The symbol for the current function. This is recalculated at the /// beginning of each call to runOnMachineFunction(). /// - std::string CurrentFnName; + MCSymbol *CurrentFnSym; /// getCurrentSection() - Return the current section we are emitting to. const MCSection *getCurrentSection() const; @@ -151,7 +153,7 @@ namespace llvm { mutable unsigned Counter; // Private state for processDebugLoc() - mutable DebugLocTuple PrevDLT; + mutable const MDNode *PrevDLT; protected: explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM, @@ -213,10 +215,6 @@ namespace llvm { unsigned AsmVariant, const char *ExtraCode); - /// PrintGlobalVariable - Emit the specified global variable and its - /// initializer to the output stream. - virtual void PrintGlobalVariable(const GlobalVariable *GV) = 0; - /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); @@ -238,6 +236,9 @@ namespace llvm { /// void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF); + /// EmitGlobalVariable - Emit the specified global variable to the .s file. + virtual void EmitGlobalVariable(const GlobalVariable *GV); + /// EmitSpecialLLVMGlobal - Check to see if the specified global is a /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. @@ -245,39 +246,9 @@ namespace llvm { public: //===------------------------------------------------------------------===// - /// LEB 128 number encoding. - - /// PrintULEB128 - Print a series of hexidecimal values(separated by commas) - /// representing an unsigned leb128 value. - void PrintULEB128(unsigned Value) const; - - /// PrintSLEB128 - Print a series of hexidecimal values(separated by commas) - /// representing a signed leb128 value. - void PrintSLEB128(int Value) const; - - //===------------------------------------------------------------------===// // Emission and print routines // - /// PrintHex - Print a value as a hexidecimal value. - /// - void PrintHex(int Value) const; - - /// EOL - Print a newline character to asm stream. If a comment is present - /// then it will be printed first. Comments should not contain '\n'. - void EOL() const; - void EOL(const std::string &Comment) const; - void EOL(const char* Comment) const; - void EOL(const char *Comment, unsigned Encoding) const; - - /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an - /// unsigned leb128 value. - void EmitULEB128Bytes(unsigned Value) const; - - /// EmitSLEB128Bytes - print an assembler byte data directive to compose a - /// signed leb128 value. - void EmitSLEB128Bytes(int Value) const; - /// EmitInt8 - Emit a byte directive and value. /// void EmitInt8(int Value) const; @@ -294,14 +265,8 @@ namespace llvm { /// void EmitInt64(uint64_t Value) const; - /// EmitString - Emit a string with quotes and a null terminator. - /// Special characters are emitted properly. - /// @verbatim (Eg. '\t') @endverbatim - void EmitString(const StringRef String) const; - void EmitString(const char *String, unsigned Size) const; - /// EmitFile - Emit a .file directive. - void EmitFile(unsigned Number, const std::string &Name) const; + void EmitFile(unsigned Number, StringRef Name) const; //===------------------------------------------------------------------===// @@ -336,13 +301,32 @@ namespace llvm { /// EmitComments - Pretty-print comments for instructions void EmitComments(const MachineInstr &MI) const; - /// EmitComments - Pretty-print comments for basic blocks - void EmitComments(const MachineBasicBlock &MBB) const; + /// GetGlobalValueSymbol - Return the MCSymbol for the specified global + /// value. + MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; + + /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with + /// global value name as its base, with the specified suffix, and where the + /// symbol is forced to have private linkage if ForcePrivate is true. + MCSymbol *GetSymbolWithGlobalValueBase(const GlobalValue *GV, + StringRef Suffix, + bool ForcePrivate = true) const; + + /// GetExternalSymbolSymbol - Return the MCSymbol for the specified + /// ExternalSymbol. + MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; + /// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic /// block label. MCSymbol *GetMBBSymbol(unsigned MBBID) const; + /// GetCPISymbol - Return the symbol for the specified constant pool entry. + MCSymbol *GetCPISymbol(unsigned CPID) const; + + /// GetJTISymbol - Return the symbol for the specified jump table entry. + MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; + /// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress /// uses of the specified basic block. MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA, @@ -355,22 +339,14 @@ namespace llvm { /// MachineBasicBlock, an alignment (if present) and a comment describing /// it if appropriate. void EmitBasicBlockStart(const MachineBasicBlock *MBB) const; - protected: - /// EmitZeros - Emit a block of zeros. - /// - void EmitZeros(uint64_t NumZeros, unsigned AddrSpace = 0) const; - - /// EmitString - Emit a zero-byte-terminated string constant. - /// - virtual void EmitString(const ConstantArray *CVA) const; - - /// EmitConstantValueOnly - Print out the specified constant, without a - /// storage class. Only constants of first-class type are allowed here. - void EmitConstantValueOnly(const Constant *CV); - + + + // Data emission. + /// EmitGlobalConstant - Print a general LLVM constant to the .s file. void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0); - + + protected: virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); /// processDebugLoc - Processes the debug information of each machine @@ -398,26 +374,16 @@ namespace llvm { const MachineBasicBlock *MBB, unsigned uid) const; - /// printDataDirective - This method prints the asm directive for the - /// specified type. - void printDataDirective(const Type *type, unsigned AddrSpace = 0); - /// printVisibility - This prints visibility information about symbol, if /// this is suported by the target. - void printVisibility(const std::string& Name, unsigned Visibility) const; - + void printVisibility(MCSymbol *Sym, unsigned Visibility) const; + /// printOffset - This is just convenient handler for printing offsets. void printOffset(int64_t Offset) const; private: void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); - void EmitGlobalConstantStruct(const ConstantStruct* CVS, - unsigned AddrSpace); - void EmitGlobalConstantArray(const ConstantArray* CVA, unsigned AddrSpace); - void EmitGlobalConstantVector(const ConstantVector* CP); - void EmitGlobalConstantFP(const ConstantFP* CFP, unsigned AddrSpace); - void EmitGlobalConstantLargeInt(const ConstantInt* CI, unsigned AddrSpace); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; } diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h index a913d21..9dba838 100644 --- a/include/llvm/CodeGen/FileWriters.h +++ b/include/llvm/CodeGen/FileWriters.h @@ -20,11 +20,17 @@ namespace llvm { class ObjectCodeEmitter; class TargetMachine; class raw_ostream; + class formatted_raw_ostream; + class MachineFunctionPass; + class MCAsmInfo; + class MCCodeEmitter; ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, TargetMachine &TM); - ObjectCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); + MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O, + TargetMachine &TM, + const MCAsmInfo *T, + MCCodeEmitter *MCE); } // end llvm namespace diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 5608c99..27947e8 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -44,6 +44,7 @@ namespace { (void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default); (void) llvm::createTDRRListDAGScheduler(NULL, llvm::CodeGenOpt::Default); + (void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Default); (void) llvm::createTDListDAGScheduler(NULL, llvm::CodeGenOpt::Default); (void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default); (void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default); diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 6b4c640..20644c1 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -337,6 +337,10 @@ public: MachineBasicBlock *DestB, bool isCond); + /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping + /// any DEBUG_VALUE instructions. Return UnknownLoc if there is none. + DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI); + // Debugging methods. void dump() const; void print(raw_ostream &OS) const; diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index a12a55a..6ca51bf 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -26,6 +26,7 @@ namespace llvm { +class DILocation; class Value; class Function; class MachineRegisterInfo; @@ -174,9 +175,6 @@ public: AlignOf<Ty>::Alignment)); MFInfo = new (Loc) Ty(*this); } - - assert((void*)dynamic_cast<Ty*>(MFInfo) == (void*)MFInfo && - "Invalid concrete type or multiple inheritence for getInfo"); return static_cast<Ty*>(MFInfo); } @@ -368,8 +366,8 @@ public: // Debug location. // - /// getDebugLocTuple - Get the DebugLocTuple for a given DebugLoc object. - DebugLocTuple getDebugLocTuple(DebugLoc DL) const; + /// getDILocation - Get the DILocation for a given DebugLoc object. + DILocation getDILocation(DebugLoc DL) const; /// getDefaultDebugLoc - Get the default debug location for the machine /// function. diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index e9b645b..d365029 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -172,9 +172,6 @@ public: Ty &getObjFileInfo() { if (ObjFileMMI == 0) ObjFileMMI = new Ty(*this); - - assert((void*)dynamic_cast<Ty*>(ObjFileMMI) == (void*)ObjFileMMI && - "Invalid concrete type or multiple inheritence for getInfo"); return *static_cast<Ty*>(ObjFileMMI); } diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 907c25a..07d886d 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -453,11 +453,9 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateMetadata(MDNode *Meta, - unsigned char TargetFlags = 0) { + static MachineOperand CreateMetadata(MDNode *Meta) { MachineOperand Op(MachineOperand::MO_Metadata); Op.Contents.MD = Meta; - Op.setTargetFlags(TargetFlags); return Op; } diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 2203f8c..7e0da3f 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -195,10 +195,6 @@ namespace llvm { /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. FunctionPass *createSjLjEHPass(const TargetLowering *tli); - /// createMaxStackAlignmentCalculatorPass() - Determine the maximum required - /// alignment for a function. - FunctionPass* createMaxStackAlignmentCalculatorPass(); - } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h index 1cf64a0..cf3274f 100644 --- a/include/llvm/CodeGen/SchedulerRegistry.h +++ b/include/llvm/CodeGen/SchedulerRegistry.h @@ -73,6 +73,11 @@ ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel); +/// createBURRListDAGScheduler - This creates a bottom up register usage +/// reduction list scheduler that schedules in source code order when possible. +ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level OptLevel); + /// createTDListDAGScheduler - This creates a top-down list scheduler with /// a hazard recognizer. ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS, diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index d55dd7f..33ebd00 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -63,6 +63,10 @@ enum CombineLevel { NoIllegalOperations // Combine may only create legal operations and types. }; +class SelectionDAG; +void checkForCycles(const SDNode *N); +void checkForCycles(const SelectionDAG *DAG); + /// SelectionDAG class - This is used to represent a portion of an LLVM function /// in a low-level Data Dependence DAG representation suitable for instruction /// selection. This DAG is constructed as the first step of instruction @@ -204,7 +208,12 @@ public: const SDValue &setRoot(SDValue N) { assert((!N.getNode() || N.getValueType() == MVT::Other) && "DAG root value is not a chain!"); - return Root = N; + if (N.getNode()) + checkForCycles(N.getNode()); + Root = N; + if (N.getNode()) + checkForCycles(this); + return Root; } /// Combine - This iterates over the nodes in the SelectionDAG, folding diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 7b1931a..45a9d40 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -44,6 +44,8 @@ template <typename T> struct DenseMapInfo; template <typename T> struct simplify_type; template <typename T> struct ilist_traits; +void checkForCycles(const SDNode *N); + /// SDVTList - This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by /// SelectionDAG::getVTList(...). @@ -1285,11 +1287,56 @@ public: void print_details(raw_ostream &OS, const SelectionDAG *G) const; void print(raw_ostream &OS, const SelectionDAG *G = 0) const; void printr(raw_ostream &OS, const SelectionDAG *G = 0) const; + + /// printrFull - Print a SelectionDAG node and all children down to + /// the leaves. The given SelectionDAG allows target-specific nodes + /// to be printed in human-readable form. Unlike printr, this will + /// print the whole DAG, including children that appear multiple + /// times. + /// + void printrFull(raw_ostream &O, const SelectionDAG *G = 0) const; + + /// printrWithDepth - Print a SelectionDAG node and children up to + /// depth "depth." The given SelectionDAG allows target-specific + /// nodes to be printed in human-readable form. Unlike printr, this + /// will print children that appear multiple times wherever they are + /// used. + /// + void printrWithDepth(raw_ostream &O, const SelectionDAG *G = 0, + unsigned depth = 100) const; + + + /// dump - Dump this node, for debugging. void dump() const; + + /// dumpr - Dump (recursively) this node and its use-def subgraph. void dumpr() const; + + /// dump - Dump this node, for debugging. + /// The given SelectionDAG allows target-specific nodes to be printed + /// in human-readable form. void dump(const SelectionDAG *G) const; + + /// dumpr - Dump (recursively) this node and its use-def subgraph. + /// The given SelectionDAG allows target-specific nodes to be printed + /// in human-readable form. void dumpr(const SelectionDAG *G) const; + /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows + /// target-specific nodes to be printed in human-readable form. + /// Unlike dumpr, this will print the whole DAG, including children + /// that appear multiple times. + /// + void dumprFull(const SelectionDAG *G = 0) const; + + /// dumprWithDepth - printrWithDepth to dbgs(). The given + /// SelectionDAG allows target-specific nodes to be printed in + /// human-readable form. Unlike dumpr, this will print children + /// that appear multiple times wherever they are used. + /// + void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const; + + static bool classof(const SDNode *) { return true; } /// Profile - Gather unique data for the node. @@ -1318,6 +1365,7 @@ protected: OperandList[i].setUser(this); OperandList[i].setInitial(Ops[i]); } + checkForCycles(this); } /// This constructor adds no operands itself; operands can be @@ -1334,6 +1382,7 @@ protected: Ops[0].setInitial(Op0); NumOperands = 1; OperandList = Ops; + checkForCycles(this); } /// InitOperands - Initialize the operands list of this with 2 operands. @@ -1344,6 +1393,7 @@ protected: Ops[1].setInitial(Op1); NumOperands = 2; OperandList = Ops; + checkForCycles(this); } /// InitOperands - Initialize the operands list of this with 3 operands. @@ -1357,6 +1407,7 @@ protected: Ops[2].setInitial(Op2); NumOperands = 3; OperandList = Ops; + checkForCycles(this); } /// InitOperands - Initialize the operands list of this with 4 operands. @@ -1372,6 +1423,7 @@ protected: Ops[3].setInitial(Op3); NumOperands = 4; OperandList = Ops; + checkForCycles(this); } /// InitOperands - Initialize the operands list of this with N operands. @@ -1382,6 +1434,7 @@ protected: } NumOperands = N; OperandList = Ops; + checkForCycles(this); } /// DropOperands - Release the operands and set this node to have diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 85aaa7f..b5cc659 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -652,8 +652,7 @@ public: /// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. -// FIXME: why not derive from BinaryOperator? -class CmpInst: public Instruction { +class CmpInst : public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT CmpInst(); // do not implement protected: @@ -665,6 +664,7 @@ protected: Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd); + virtual void Anchor() const; // Out of line virtual method. public: /// This enumeration lists the possible predicates for CmpInst subclasses. /// Values in the range 0-31 are reserved for FCmpInst, while values in the diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index f40e8cc..d86b33e 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -25,7 +25,6 @@ #define LLVM_INTRINSICINST_H #include "llvm/Constants.h" -#include "llvm/Metadata.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" @@ -83,12 +82,7 @@ namespace llvm { /// class DbgDeclareInst : public DbgInfoIntrinsic { public: - Value *getAddress() const { - if (MDNode* MD = dyn_cast<MDNode>(getOperand(1))) - return MD->getOperand(0); - else - return NULL; - } + Value *getAddress() const; MDNode *getVariable() const { return cast<MDNode>(getOperand(2)); } // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h index 2145bf8..6cf2c4b 100644 --- a/include/llvm/LinkAllVMCore.h +++ b/include/llvm/LinkAllVMCore.h @@ -32,7 +32,6 @@ #include "llvm/System/Signals.h" #include "llvm/System/TimeValue.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SlowOperationInformer.h" #include <cstdlib> @@ -46,10 +45,9 @@ namespace { // to know that getenv() never returns -1, this will do the job. if (std::getenv("bar") != (char*) -1) return; - llvm::Module* M = new llvm::Module("", llvm::getGlobalContext()); + (void)new llvm::Module("", llvm::getGlobalContext()); (void)new llvm::UnreachableInst(llvm::getGlobalContext()); (void) llvm::createVerifierPass(); - (void) new llvm::Mangler(*M,""); } } ForceVMCoreLinking; } diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index fb69630..5e31dfe 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -16,9 +16,13 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H +#include "llvm/MC/MCDirectives.h" #include <cassert> namespace llvm { + class MCSection; + class MCContext; + /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; } @@ -29,15 +33,20 @@ namespace llvm { // Properties to be set by the target writer, used to configure asm printer. // - /// ZeroFillDirective - Directive for emitting a global to the ZeroFill - /// section on this target. Null if this target doesn't support zerofill. - const char *ZeroFillDirective; // Default is null. - - /// NonexecutableStackDirective - Directive for declaring to the - /// linker and beyond that the emitted code does not require stack - /// memory to be executable. - const char *NonexecutableStackDirective; // Default is null. - + /// HasSubsectionsViaSymbols - True if this target has the MachO + /// .subsections_via_symbols directive. + bool HasSubsectionsViaSymbols; // Default is false. + + /// HasMachoZeroFillDirective - True if this is a MachO target that supports + /// the macho-specific .zerofill directive for emitting BSS Symbols. + bool HasMachoZeroFillDirective; // Default is false. + + /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should + /// emit a ".reference .constructors_used" or ".reference .destructors_used" + /// directive after the a static ctor/dtor list. This directive is only + /// emitted in Static relocation model. + bool HasStaticCtorDtorReferenceInStaticMode; // Default is false. + /// NeedsSet - True if target asm treats expressions in data directives /// as linktime-relocatable. For assembly-time computation, we need to /// use a .set. Thus: @@ -107,7 +116,6 @@ namespace llvm { /// "\t.zero\t" and "\t.space\t". If this is set to null, the /// Data*bitsDirective's will be used to emit zero bytes. const char *ZeroDirective; // Defaults to "\t.zero\t" - const char *ZeroDirectiveSuffix; // Defaults to "" /// AsciiDirective - This directive allows emission of an ascii string with /// the standard C escape characters embedded into it. @@ -183,15 +191,10 @@ namespace llvm { /// the assembler to set the value of a variable to some expression. const char *SetDirective; // Defaults to null. - /// LCOMMDirective - This is the name of a directive (if supported) that can - /// be used to efficiently declare a local (internal) block of zero - /// initialized data in the .bss/.data section. The syntax expected is: - /// @verbatim <LCOMMDirective> SYMBOLNAME LENGTHINBYTES, ALIGNMENT - /// @endverbatim - const char *LCOMMDirective; // Defaults to null. + /// HasLCOMMDirective - This is true if the target supports the .lcomm + /// directive. + bool HasLCOMMDirective; // Defaults to false. - const char *COMMDirective; // Defaults to "\t.comm\t". - /// COMMDirectiveTakesAlignment - True if COMMDirective take a third /// argument that specifies the alignment of the declaration. bool COMMDirectiveTakesAlignment; // Defaults to true. @@ -204,10 +207,9 @@ namespace llvm { /// .file directive, this is true for ELF targets. bool HasSingleParameterDotFile; // Defaults to true. - /// UsedDirective - This directive, if non-null, is used to declare a global - /// as being used somehow that the assembler can't see. This prevents dead - /// code elimination on some targets. - const char *UsedDirective; // Defaults to NULL. + /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip + /// directive. + bool HasNoDeadStrip; // Defaults to false. /// WeakRefDirective - This directive, if non-null, is used to declare a /// global as being a weak undefined symbol. @@ -216,14 +218,18 @@ namespace llvm { /// WeakDefDirective - This directive, if non-null, is used to declare a /// global as being a weak defined symbol. const char *WeakDefDirective; // Defaults to NULL. + + /// LinkOnceDirective - This directive, if non-null is used to declare a + /// global as being a weak defined symbol. This is used on cygwin/mingw. + const char *LinkOnceDirective; // Defaults to NULL. - /// HiddenDirective - This directive, if non-null, is used to declare a - /// global or function as having hidden visibility. - const char *HiddenDirective; // Defaults to "\t.hidden\t". + /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to + /// declare a symbol as having hidden visibility. + MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden. - /// ProtectedDirective - This directive, if non-null, is used to declare a - /// global or function as having protected visibility. - const char *ProtectedDirective; // Defaults to "\t.protected\t". + /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used + /// to declare a symbol as having protected visibility. + MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected //===--- Dwarf Emission Directives -----------------------------------===// @@ -279,14 +285,12 @@ namespace llvm { explicit MCAsmInfo(); virtual ~MCAsmInfo(); - /// getSLEB128Size - Compute the number of bytes required for a signed - /// leb128 value. + // FIXME: move these methods to DwarfPrinter when the JIT stops using them. static unsigned getSLEB128Size(int Value); - - /// getULEB128Size - Compute the number of bytes required for an unsigned - /// leb128 value. static unsigned getULEB128Size(unsigned Value); + bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } + // Data directive accessors. // const char *getData8bitsDirective(unsigned AS = 0) const { @@ -302,6 +306,12 @@ namespace llvm { return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS); } + /// getNonexecutableStackSection - Targets can implement this method to + /// specify a section to switch to if the translation unit doesn't have any + /// trampolines that require an executable stack. + virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const { + return 0; + } bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; @@ -313,11 +323,9 @@ namespace llvm { // Accessors. // - const char *getZeroFillDirective() const { - return ZeroFillDirective; - } - const char *getNonexecutableStackDirective() const { - return NonexecutableStackDirective; + bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } + bool hasStaticCtorDtorReferenceInStaticMode() const { + return HasStaticCtorDtorReferenceInStaticMode; } bool needsSet() const { return NeedsSet; @@ -364,9 +372,6 @@ namespace llvm { const char *getZeroDirective() const { return ZeroDirective; } - const char *getZeroDirectiveSuffix() const { - return ZeroDirectiveSuffix; - } const char *getAsciiDirective() const { return AsciiDirective; } @@ -394,35 +399,20 @@ namespace llvm { const char *getSetDirective() const { return SetDirective; } - const char *getLCOMMDirective() const { - return LCOMMDirective; - } - const char *getCOMMDirective() const { - return COMMDirective; - } + bool hasLCOMMDirective() const { return HasLCOMMDirective; } bool getCOMMDirectiveTakesAlignment() const { return COMMDirectiveTakesAlignment; } - bool hasDotTypeDotSizeDirective() const { - return HasDotTypeDotSizeDirective; - } - bool hasSingleParameterDotFile() const { - return HasSingleParameterDotFile; - } - const char *getUsedDirective() const { - return UsedDirective; - } - const char *getWeakRefDirective() const { - return WeakRefDirective; - } - const char *getWeakDefDirective() const { - return WeakDefDirective; - } - const char *getHiddenDirective() const { - return HiddenDirective; - } - const char *getProtectedDirective() const { - return ProtectedDirective; + bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} + bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } + bool hasNoDeadStrip() const { return HasNoDeadStrip; } + const char *getWeakRefDirective() const { return WeakRefDirective; } + const char *getWeakDefDirective() const { return WeakDefDirective; } + const char *getLinkOnceDirective() const { return LinkOnceDirective; } + + MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} + MCSymbolAttr getProtectedVisibilityAttr() const { + return ProtectedVisibilityAttr; } bool isAbsoluteDebugSectionOffsets() const { return AbsoluteDebugSectionOffsets; diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h new file mode 100644 index 0000000..57ce75d --- /dev/null +++ b/include/llvm/MC/MCDirectives.h @@ -0,0 +1,44 @@ +//===- MCDirectives.h - Enums for directives on various targets -*- 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 enums that represent target-specific directives. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCDIRECTIVES_H +#define LLVM_MC_MCDIRECTIVES_H + +namespace llvm { + +enum MCSymbolAttr { + MCSA_Invalid = 0, /// Not a valid directive. + + // Various directives in alphabetical order. + MCSA_Global, /// .globl + MCSA_Hidden, /// .hidden (ELF) + MCSA_IndirectSymbol, /// .indirect_symbol (MachO) + MCSA_Internal, /// .internal (ELF) + MCSA_LazyReference, /// .lazy_reference (MachO) + MCSA_Local, /// .local (ELF) + MCSA_NoDeadStrip, /// .no_dead_strip (MachO) + MCSA_PrivateExtern, /// .private_extern (MachO) + MCSA_Protected, /// .protected (ELF) + MCSA_Reference, /// .reference (MachO) + MCSA_Weak, /// .weak + MCSA_WeakDefinition, /// .weak_definition (MachO) + MCSA_WeakReference /// .weak_reference (MachO) +}; + +enum MCAssemblerFlag { + MCAF_SubsectionsViaSymbols /// .subsections_via_symbols (MachO) +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 13d40ec..73d5f8e 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -51,7 +51,7 @@ public: /// @name Utility Methods /// @{ - void print(raw_ostream &OS, const MCAsmInfo *MAI) const; + void print(raw_ostream &OS) const; void dump() const; /// @} @@ -75,6 +75,11 @@ public: static bool classof(const MCExpr *) { return true; } }; + +inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { + E.print(OS); + return OS; +} //// MCConstantExpr - Represent a constant integer expression. class MCConstantExpr : public MCExpr { diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h new file mode 100644 index 0000000..92a115e --- /dev/null +++ b/include/llvm/MC/MCParser/AsmCond.h @@ -0,0 +1,40 @@ +//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef ASMCOND_H +#define ASMCOND_H + +namespace llvm { + +/// AsmCond - Class to support conditional assembly +/// +/// The conditional assembly feature (.if, .else, .elseif and .endif) is +/// implemented with AsmCond that tells us what we are in the middle of +/// processing. Ignore can be either true or false. When true we are ignoring +/// the block of code in the middle of a conditional. + +class AsmCond { +public: + enum ConditionalAssemblyType { + NoCond, // no conditional is being processed + IfCond, // inside if conditional + ElseIfCond, // inside elseif conditional + ElseCond // inside else conditional + }; + + ConditionalAssemblyType TheCond; + bool CondMet; + bool Ignore; + + AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {} +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h new file mode 100644 index 0000000..cf6eefb --- /dev/null +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -0,0 +1,72 @@ +//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class declares the lexer for assembly files. +// +//===----------------------------------------------------------------------===// + +#ifndef ASMLEXER_H +#define ASMLEXER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/System/DataTypes.h" +#include <string> +#include <cassert> + +namespace llvm { +class MemoryBuffer; +class SMLoc; +class MCAsmInfo; + +/// AsmLexer - Lexer class for assembly files. +class AsmLexer : public MCAsmLexer { + const MCAsmInfo &MAI; + + const char *CurPtr; + const MemoryBuffer *CurBuf; + + const char *TokStart; + + void operator=(const AsmLexer&); // DO NOT IMPLEMENT + AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT + +protected: + /// LexToken - Read the next token and return its code. + virtual AsmToken LexToken(); + +public: + AsmLexer(const MCAsmInfo &MAI); + ~AsmLexer(); + + void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); + + SMLoc getLoc() const; + + StringRef LexUntilEndOfStatement(); + + bool isAtStartOfComment(char Char); + + const MCAsmInfo &getMAI() const { return MAI; } + +private: + int getNextChar(); + AsmToken ReturnError(const char *Loc, const std::string &Msg); + + AsmToken LexIdentifier(); + AsmToken LexSlash(); + AsmToken LexLineComment(); + AsmToken LexDigit(); + AsmToken LexQuote(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h new file mode 100644 index 0000000..f82584c --- /dev/null +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -0,0 +1,178 @@ +//===- AsmParser.h - Parser for Assembly Files ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class declares the parser for assembly files. +// +//===----------------------------------------------------------------------===// + +#ifndef ASMPARSER_H +#define ASMPARSER_H + +#include <vector> +#include "llvm/MC/MCParser/AsmLexer.h" +#include "llvm/MC/MCParser/AsmCond.h" +#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/ADT/StringMap.h" + +namespace llvm { +class AsmCond; +class AsmToken; +class MCContext; +class MCExpr; +class MCInst; +class MCStreamer; +class MCAsmInfo; +class MCValue; +class SourceMgr; +class TargetAsmParser; +class Twine; + +class AsmParser : public MCAsmParser { +private: + AsmLexer Lexer; + MCContext &Ctx; + MCStreamer &Out; + SourceMgr &SrcMgr; + TargetAsmParser *TargetParser; + + /// This is the current buffer index we're lexing from as managed by the + /// SourceMgr object. + int CurBuffer; + + AsmCond TheCondState; + std::vector<AsmCond> TheCondStack; + + // FIXME: Figure out where this should leave, the code is a copy of that which + // is also used by TargetLoweringObjectFile. + mutable void *SectionUniquingMap; + + /// DirectiveMap - This is a table handlers for directives. Each handler is + /// invoked after the directive identifier is read and is responsible for + /// parsing and validating the rest of the directive. The handler is passed + /// in the directive name and the location of the directive keyword. + StringMap<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap; +public: + AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, + const MCAsmInfo &_MAI); + ~AsmParser(); + + bool Run(); + + + void AddDirectiveHandler(StringRef Directive, + bool (AsmParser::*Handler)(StringRef, SMLoc)) { + DirectiveMap[Directive] = Handler; + } +public: + TargetAsmParser &getTargetParser() const { return *TargetParser; } + void setTargetParser(TargetAsmParser &P) { TargetParser = &P; } + + /// @name MCAsmParser Interface + /// { + + virtual MCAsmLexer &getLexer() { return Lexer; } + virtual MCContext &getContext() { return Ctx; } + virtual MCStreamer &getStreamer() { return Out; } + + virtual void Warning(SMLoc L, const Twine &Meg); + virtual bool Error(SMLoc L, const Twine &Msg); + + const AsmToken &Lex(); + + bool ParseExpression(const MCExpr *&Res); + virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc); + virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); + virtual bool ParseAbsoluteExpression(int64_t &Res); + + /// } + +private: + MCSymbol *CreateSymbol(StringRef Name); + + // FIXME: See comment on SectionUniquingMap. + const MCSection *getMachOSection(const StringRef &Segment, + const StringRef &Section, + unsigned TypeAndAttributes, + unsigned Reserved2, + SectionKind Kind) const; + + bool ParseStatement(); + + bool TokError(const char *Msg); + + void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const; + + /// EnterIncludeFile - Enter the specified file. This returns true on failure. + bool EnterIncludeFile(const std::string &Filename); + + bool ParseConditionalAssemblyDirectives(StringRef Directive, + SMLoc DirectiveLoc); + void EatToEndOfStatement(); + + bool ParseAssignment(const StringRef &Name); + + bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); + bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); + bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); + + /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) + /// and set \arg Res to the identifier contents. + bool ParseIdentifier(StringRef &Res); + + // Directive Parsing. + bool ParseDirectiveDarwinSection(); // Darwin specific ".section". + bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section, + unsigned TAA = 0, unsigned ImplicitAlign = 0, + unsigned StubSize = 0); + bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz" + bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... + bool ParseDirectiveFill(); // ".fill" + bool ParseDirectiveSpace(); // ".space" + bool ParseDirectiveSet(); // ".set" + bool ParseDirectiveOrg(); // ".org" + // ".align{,32}", ".p2align{,w,l}" + bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize); + + /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which + /// accepts a single symbol (which should be a label or an external). + bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); + bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc" + bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym" + + bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" + bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill" + + // Darwin specific ".subsections_via_symbols" + bool ParseDirectiveDarwinSubsectionsViaSymbols(); + // Darwin specific .dump and .load + bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump); + + bool ParseDirectiveAbort(); // ".abort" + bool ParseDirectiveInclude(); // ".include" + + bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" + bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" + bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" + bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif + + bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file" + bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line" + bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc" + + /// ParseEscapedString - Parse the current token as a string which may include + /// escaped characters and return the string contents. + bool ParseEscapedString(std::string &Data); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index e9a6e3f..043c363 100644 --- a/include/llvm/MC/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -12,11 +12,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/System/DataTypes.h" +#include "llvm/Support/SMLoc.h" namespace llvm { class MCAsmLexer; class MCInst; -class SMLoc; class Target; /// AsmToken - Target independent representation for an assembler token. @@ -33,6 +33,9 @@ public: // Integer values. Integer, + // Register values (stored in IntVal). Only used by TargetAsmLexer. + Register, + // No-value. EndOfStatement, Colon, @@ -96,6 +99,13 @@ public: assert(Kind == Integer && "This token isn't an integer!"); return IntVal; } + + /// getRegVal - Get the register number for the current token, which should + /// be a register. + unsigned getRegVal() const { + assert(Kind == Register && "This token isn't a register!"); + return static_cast<unsigned>(IntVal); + } }; /// MCAsmLexer - Generic assembler lexer interface, for use by target specific @@ -103,6 +113,10 @@ public: class MCAsmLexer { /// The current token, stored in the base class for faster access. AsmToken CurTok; + + /// The location and description of the current error + SMLoc ErrLoc; + std::string Err; MCAsmLexer(const MCAsmLexer &); // DO NOT IMPLEMENT void operator=(const MCAsmLexer &); // DO NOT IMPLEMENT @@ -110,7 +124,12 @@ protected: // Can only create subclasses. MCAsmLexer(); virtual AsmToken LexToken() = 0; - + + void SetError(const SMLoc &errLoc, const std::string &err) { + ErrLoc = errLoc; + Err = err; + } + public: virtual ~MCAsmLexer(); @@ -126,6 +145,16 @@ public: const AsmToken &getTok() { return CurTok; } + + /// getErrLoc - Get the current error location + const SMLoc &getErrLoc() { + return ErrLoc; + } + + /// getErr - Get the current error string + const std::string &getErr() { + return Err; + } /// getKind - Get the kind of current token. AsmToken::TokenKind getKind() const { return CurTok.getKind(); } diff --git a/include/llvm/MC/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index d530093..843c692 100644 --- a/include/llvm/MC/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -13,6 +13,7 @@ #include "llvm/System/DataTypes.h" namespace llvm { +class AsmToken; class MCAsmLexer; class MCContext; class MCExpr; @@ -50,20 +51,28 @@ public: /// clients. virtual bool Error(SMLoc L, const Twine &Msg) = 0; + /// Lex - Get the next AsmToken in the stream, possibly handling file + /// inclusion first. + virtual const AsmToken &Lex() = 0; + + /// getTok - Get the current AsmToken from the stream. + const AsmToken &getTok(); + /// ParseExpression - Parse an arbitrary expression. /// /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseExpression(const MCExpr *&Res) = 0; - + virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; + bool ParseExpression(const MCExpr *&Res); + /// ParseParenExpression - Parse an arbitrary expression, assuming that an /// initial '(' has already been consumed. /// /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseParenExpression(const MCExpr *&Res) = 0; + virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; /// ParseAbsoluteExpression - Parse an expression which must evaluate to an /// absolute value. diff --git a/include/llvm/MC/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 7c2f5be..7c2f5be 100644 --- a/include/llvm/MC/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 4ec745f..2dccf5c 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -31,7 +31,7 @@ class MCSectionELF : public MCSection { unsigned Flags; /// IsExplicit - Indicates that this section comes from globals with an - /// explicit section specfied. + /// explicit section specified. bool IsExplicit; protected: @@ -47,8 +47,7 @@ public: /// ShouldOmitSectionDirective - Decides whether a '.section' directive /// should be printed before the section name - bool ShouldOmitSectionDirective(const char *Name, - const MCAsmInfo &MAI) const; + bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; /// ShouldPrintSectionType - Only prints the section type if supported bool ShouldPrintSectionType(unsigned Ty) const; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 5febed7..2bcb594 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSTREAMER_H #include "llvm/System/DataTypes.h" +#include "llvm/MC/MCDirectives.h" namespace llvm { class MCAsmInfo; @@ -26,7 +27,9 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; + class Twine; class raw_ostream; + class formatted_raw_ostream; /// MCStreamer - Streaming machine code generation interface. This interface /// is intended to provide a programatic interface that is very similar to the @@ -38,30 +41,6 @@ namespace llvm { /// a .s file, and implementations that write out .o files of various formats. /// class MCStreamer { - public: - enum SymbolAttr { - Global, /// .globl - Hidden, /// .hidden (ELF) - IndirectSymbol, /// .indirect_symbol (Apple) - Internal, /// .internal (ELF) - LazyReference, /// .lazy_reference (Apple) - NoDeadStrip, /// .no_dead_strip (Apple) - PrivateExtern, /// .private_extern (Apple) - Protected, /// .protected (ELF) - Reference, /// .reference (Apple) - Weak, /// .weak - WeakDefinition, /// .weak_definition (Apple) - WeakReference, /// .weak_reference (Apple) - - SymbolAttrFirst = Global, - SymbolAttrLast = WeakReference - }; - - enum AssemblerFlag { - SubsectionsViaSymbols /// .subsections_via_symbols (Apple) - }; - - private: MCContext &Context; MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT @@ -79,6 +58,28 @@ namespace llvm { MCContext &getContext() const { return Context; } + /// @name Assembly File Formatting. + /// @{ + + /// AddComment - Add a comment that can be emitted to the generated .s + /// file if applicable as a QoI issue to make the output of the compiler + /// more readable. This only affects the MCAsmStreamer, and only when + /// verbose assembly output is enabled. + /// + /// If the comment includes embedded \n's, they will each get the comment + /// prefix as appropriate. The added comment should not end with a \n. + virtual void AddComment(const Twine &T) {} + + /// GetCommentOS - Return a raw_ostream that comments can be written to. + /// Unlike AddComment, you are required to terminate comments with \n if you + /// use this method. + virtual raw_ostream &GetCommentOS(); + + /// AddBlankLine - Emit a blank line to a .s file to pretty it up. + virtual void AddBlankLine() {} + + /// @} + /// @name Symbol & Section Management /// @{ @@ -103,7 +104,7 @@ namespace llvm { virtual void EmitLabel(MCSymbol *Symbol) = 0; /// EmitAssemblerFlag - Note in the output the specified @param Flag - virtual void EmitAssemblerFlag(AssemblerFlag Flag) = 0; + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; /// EmitAssignment - Emit an assignment of @param Value to @param Symbol. /// @@ -120,7 +121,7 @@ namespace llvm { /// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol. virtual void EmitSymbolAttribute(MCSymbol *Symbol, - SymbolAttr Attribute) = 0; + MCSymbolAttr Attribute) = 0; /// EmitSymbolDesc - Set the @param DescValue for the @param Symbol. /// @@ -128,15 +129,21 @@ namespace llvm { /// @param DescValue - The value to set into the n_desc field. virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0; - /// EmitCommonSymbol - Emit a common or local common symbol. + /// EmitCommonSymbol - Emit a common symbol. /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. /// @param ByteAlignment - The alignment of the symbol if - /// non-zero. This must be a power of 2 on some targets. - virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, + /// non-zero. This must be a power of 2. + virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) = 0; + /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. + /// + /// @param Symbol - The common symbol to emit. + /// @param Size - The size of the common symbol. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; + /// EmitZerofill - Emit a the zerofill section and an option symbol. /// /// @param Section - The zerofill section to create and or to put the symbol @@ -155,7 +162,7 @@ namespace llvm { /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. - virtual void EmitBytes(StringRef Data) = 0; + virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; /// EmitValue - Emit the expression @param Value into the output as a native /// integer of the given @param Size bytes. @@ -166,8 +173,25 @@ namespace llvm { /// @param Value - The value to emit. /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. - virtual void EmitValue(const MCExpr *Value, unsigned Size) = 0; + virtual void EmitValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) = 0; + /// EmitIntValue - Special case of EmitValue that avoids the client having + /// to pass in a MCExpr for constant integers. + virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace); + + /// EmitFill - Emit NumBytes bytes worth of the value specified by + /// FillValue. This implements directives such as '.space'. + virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace); + + /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience + /// function that just wraps EmitFill. + void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) { + EmitFill(NumBytes, 0, AddrSpace); + } + + /// EmitValueToAlignment - Emit some number of copies of @param Value until /// the byte alignment @param ByteAlignment is reached. /// @@ -217,8 +241,9 @@ namespace llvm { /// createAsmStreamer - Create a machine code streamer which will print out /// assembly for the native target, suitable for compiling with a native /// assembler. - MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS, - const MCAsmInfo &MAI, + MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + const MCAsmInfo &MAI, bool isLittleEndian, + bool isVerboseAsm, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0); diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index eb59453..e770604 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -19,14 +19,14 @@ #include "llvm/System/DataTypes.h" namespace llvm { - class MCAsmInfo; class MCExpr; class MCSection; class MCContext; class raw_ostream; /// MCSymbol - Instances of this class represent a symbol name in the MC file, - /// and MCSymbols are created and unique'd by the MCContext class. + /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols + /// should only be constructed with valid names for the object file. /// /// If the symbol is defined/emitted into the current translation unit, the /// Section member is set to indicate what section it lives in. Otherwise, if @@ -53,7 +53,7 @@ namespace llvm { /// typically does not survive in the .o file's symbol table. Usually /// "Lfoo" or ".foo". unsigned IsTemporary : 1; - + private: // MCContext creates and uniques these. friend class MCContext; MCSymbol(StringRef _Name, bool _IsTemporary) @@ -132,17 +132,16 @@ namespace llvm { /// @} /// print - Print the value to the stream \arg OS. - void print(raw_ostream &OS, const MCAsmInfo *MAI) const; + void print(raw_ostream &OS) const; /// dump - Print the value to stderr. void dump() const; - - /// printMangledName - Print the specified string in mangled form if it uses - /// any unusual characters. - static void printMangledName(StringRef Str, raw_ostream &OS, - const MCAsmInfo *MAI); }; + inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { + Sym.print(OS); + return OS; + } } // end namespace llvm #endif diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 4f5ab31..8aa73f3 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -20,6 +20,7 @@ namespace llvm { class MCSymbol; +class MCAsmInfo; class raw_ostream; /// MCValue - This represents an "assembler immediate". In its most general diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h index 945cff7..c9557f2 100644 --- a/include/llvm/MC/SectionKind.h +++ b/include/llvm/MC/SectionKind.h @@ -87,6 +87,18 @@ class SectionKind { /// BSS - Zero initialized writeable data. BSS, + + /// BSSLocal - This is BSS (zero initialized and writable) data + /// which has local linkage. + BSSLocal, + + /// BSSExtern - This is BSS data with normal external linkage. + BSSExtern, + + /// Common - Data with common linkage. These represent tentative + /// definitions, which always have a zero initializer and are never + /// marked 'constant'. + Common, /// DataRel - This is the most general form of data that is written /// to by the program, it can have random relocations to arbitrary @@ -158,10 +170,14 @@ public: bool isThreadData() const { return K == ThreadData; } bool isGlobalWriteableData() const { - return isBSS() || isDataRel() || isReadOnlyWithRel(); + return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel(); } - bool isBSS() const { return K == BSS; } + bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; } + bool isBSSLocal() const { return K == BSSLocal; } + bool isBSSExtern() const { return K == BSSExtern; } + + bool isCommon() const { return K == Common; } bool isDataRel() const { return K == DataRel || K == DataRelLocal || K == DataNoRel; @@ -207,6 +223,9 @@ public: static SectionKind getThreadBSS() { return get(ThreadBSS); } static SectionKind getThreadData() { return get(ThreadData); } static SectionKind getBSS() { return get(BSS); } + static SectionKind getBSSLocal() { return get(BSSLocal); } + static SectionKind getBSSExtern() { return get(BSSExtern); } + static SectionKind getCommon() { return get(Common); } static SectionKind getDataRel() { return get(DataRel); } static SectionKind getDataRelLocal() { return get(DataRelLocal); } static SectionKind getDataNoRel() { return get(DataNoRel); } diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 179010b..f1e7a22 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -31,26 +31,10 @@ template<typename ValueSubClass, typename ItemParentClass> //===----------------------------------------------------------------------===// -// MetadataBase - A base class for MDNode and MDString. -class MetadataBase : public Value { -protected: - MetadataBase(const Type *Ty, unsigned scid) - : Value(Ty, scid) {} - -public: - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MetadataBase *) { return true; } - static bool classof(const Value *V) { - return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal; - } -}; - -//===----------------------------------------------------------------------===// /// MDString - a single uniqued string. /// These are used to efficiently contain a byte sequence for metadata. /// MDString is always unnamd. -class MDString : public MetadataBase { +class MDString : public Value { MDString(const MDString &); // DO NOT IMPLEMENT StringRef Str; @@ -87,7 +71,7 @@ class MDNodeOperand; //===----------------------------------------------------------------------===// /// MDNode - a tuple of other values. -class MDNode : public MetadataBase, public FoldingSetNode { +class MDNode : public Value, public FoldingSetNode { MDNode(const MDNode &); // DO NOT IMPLEMENT void operator=(const MDNode &); // DO NOT IMPLEMENT friend class MDNodeOperand; @@ -154,8 +138,9 @@ public: // getFunction - If this metadata is function-local and recursively has a // function-local operand, return the first such operand's parent function. - // Otherwise, return null. - Function *getFunction() const; + // Otherwise, return null. getFunction() should not be used for performance- + // critical code because it recursively visits all the MDNode's operands. + const Function *getFunction() const; // destroy - Delete this node. Only when there are no uses. void destroy(); diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index f3e4dfd..ab08afb 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -64,6 +64,16 @@ enum PassManagerType { PMT_Last }; +// Different types of passes. +enum PassKind { + PT_BasicBlock, + PT_Loop, + PT_Function, + PT_CallGraphSCC, + PT_Module, + PT_PassManager +}; + //===----------------------------------------------------------------------===// /// Pass interface - Implemented by all 'passes'. Subclass this if you are an /// interprocedural optimization or you do not fit into any of the more @@ -72,19 +82,23 @@ enum PassManagerType { class Pass { AnalysisResolver *Resolver; // Used to resolve analysis intptr_t PassID; - + PassKind Kind; void operator=(const Pass&); // DO NOT IMPLEMENT Pass(const Pass &); // DO NOT IMPLEMENT public: - explicit Pass(intptr_t pid) : Resolver(0), PassID(pid) { + explicit Pass(PassKind K, intptr_t pid) : Resolver(0), PassID(pid), Kind(K) { assert(pid && "pid cannot be 0"); } - explicit Pass(const void *pid) : Resolver(0), PassID((intptr_t)pid) { + explicit Pass(PassKind K, const void *pid) + : Resolver(0), PassID((intptr_t)pid), Kind(K) { assert(pid && "pid cannot be 0"); } virtual ~Pass(); + + PassKind getPassKind() const { return Kind; } + /// getPassName - Return a nice clean name for a pass. This usually /// implemented in terms of the name that is registered by one of the /// Registration templates, but can be overloaded directly. @@ -118,7 +132,7 @@ public: // Access AnalysisResolver inline void setResolver(AnalysisResolver *AR) { - assert (!Resolver && "Resolver is already set"); + assert(!Resolver && "Resolver is already set"); Resolver = AR; } inline AnalysisResolver *getResolver() { @@ -145,6 +159,16 @@ public: /// virtual void releaseMemory(); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it should + /// override this to adjust the this pointer as needed for the specified pass + /// info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + return this; + } + virtual ImmutablePass *getAsImmutablePass() { return 0; } + virtual PMDataManager *getAsPMDataManager() { return 0; } + /// verifyAnalysis() - This member can be implemented by a analysis pass to /// check state of analysis information. virtual void verifyAnalysis() const; @@ -219,8 +243,8 @@ public: /// Return what kind of Pass Manager can manage this pass. virtual PassManagerType getPotentialPassManagerType() const; - explicit ModulePass(intptr_t pid) : Pass(pid) {} - explicit ModulePass(const void *pid) : Pass(pid) {} + explicit ModulePass(intptr_t pid) : Pass(PT_Module, pid) {} + explicit ModulePass(const void *pid) : Pass(PT_Module, pid) {} // Force out-of-line virtual method. virtual ~ModulePass(); }; @@ -241,6 +265,8 @@ public: /// virtual void initializePass(); + virtual ImmutablePass *getAsImmutablePass() { return this; } + /// ImmutablePasses are never run. /// bool runOnModule(Module &) { return false; } @@ -264,8 +290,8 @@ public: /// class FunctionPass : public Pass { public: - explicit FunctionPass(intptr_t pid) : Pass(pid) {} - explicit FunctionPass(const void *pid) : Pass(pid) {} + explicit FunctionPass(intptr_t pid) : Pass(PT_Function, pid) {} + explicit FunctionPass(const void *pid) : Pass(PT_Function, pid) {} /// doInitialization - Virtual method overridden by subclasses to do /// any necessary per-module initialization. @@ -314,8 +340,8 @@ public: /// class BasicBlockPass : public Pass { public: - explicit BasicBlockPass(intptr_t pid) : Pass(pid) {} - explicit BasicBlockPass(const void *pid) : Pass(pid) {} + explicit BasicBlockPass(intptr_t pid) : Pass(PT_BasicBlock, pid) {} + explicit BasicBlockPass(const void *pid) : Pass(PT_BasicBlock, pid) {} /// doInitialization - Virtual method overridden by subclasses to do /// any necessary per-module initialization. diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index 5864fad..d59be3c 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -19,15 +19,13 @@ #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H #define LLVM_PASS_ANALYSIS_SUPPORT_H -#include <vector> #include "llvm/Pass.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include <vector> namespace llvm { -class StringRef; - //===----------------------------------------------------------------------===// // AnalysisUsage - Represent the analysis usage information of a pass. This // tracks analyses that the pass REQUIRES (must be available when the pass @@ -192,8 +190,15 @@ AnalysisType *Pass::getAnalysisIfAvailable() const { const PassInfo *PI = getClassPassInfo<AnalysisType>(); if (PI == 0) return 0; - return dynamic_cast<AnalysisType*> - (Resolver->getAnalysisIfAvailable(PI, true)); + + Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true); + if (ResultPass == 0) return 0; + + // Because the AnalysisType may not be a subclass of pass (for + // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially + // adjust the return pointer (because the class may multiply inherit, once + // from pass, once from AnalysisType). + return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); } /// getAnalysis<AnalysisType>() - This function is used by subclasses to get @@ -202,8 +207,7 @@ AnalysisType *Pass::getAnalysisIfAvailable() const { /// template<typename AnalysisType> AnalysisType &Pass::getAnalysis() const { - assert(Resolver &&"Pass has not been inserted into a PassManager object!"); - + assert(Resolver && "Pass has not been inserted into a PassManager object!"); return getAnalysisID<AnalysisType>(getClassPassInfo<AnalysisType>()); } @@ -220,13 +224,10 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const { "'required' by pass!"); // Because the AnalysisType may not be a subclass of pass (for - // AnalysisGroups), we must use dynamic_cast here to potentially adjust the - // return pointer (because the class may multiply inherit, once from pass, - // once from AnalysisType). - // - AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass); - assert(Result && "Pass does not implement interface required!"); - return *Result; + // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially + // adjust the return pointer (because the class may multiply inherit, once + // from pass, once from AnalysisType). + return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); } /// getAnalysis<AnalysisType>() - This function is used by subclasses to get @@ -248,16 +249,13 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI, Function &F) { // should be a small number, we just do a linear search over a (dense) // vector. Pass *ResultPass = Resolver->findImplPass(this, PI, F); - assert (ResultPass && "Unable to find requested analysis info"); + assert(ResultPass && "Unable to find requested analysis info"); // Because the AnalysisType may not be a subclass of pass (for - // AnalysisGroups), we must use dynamic_cast here to potentially adjust the - // return pointer (because the class may multiply inherit, once from pass, - // once from AnalysisType). - // - AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass); - assert(Result && "Pass does not implement interface required!"); - return *Result; + // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially + // adjust the return pointer (because the class may multiply inherit, once + // from pass, once from AnalysisType). + return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); } } // End llvm namespace diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index dffc24a..443a9e0 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -273,6 +273,8 @@ public: } virtual ~PMDataManager(); + + virtual Pass *getAsPass() = 0; /// Augment AvailableAnalysis by adding analysis made available by pass P. void recordAvailableAnalysis(Pass *P); @@ -413,7 +415,6 @@ private: /// function. class FPPassManager : public ModulePass, public PMDataManager { - public: static char ID; explicit FPPassManager(int Depth) @@ -435,6 +436,9 @@ public: /// bool doFinalization(Module &M); + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + /// Pass Manager itself does not invalidate any analysis info. void getAnalysisUsage(AnalysisUsage &Info) const { Info.setPreservesAll(); diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index d7f3097..b229989 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -82,6 +82,11 @@ public: /// TODO : Rename intptr_t getTypeInfo() const { return PassID; } + /// Return true if this PassID implements the specified ID pointer. + bool isPassID(void *IDPtr) const { + return PassID == (intptr_t)IDPtr; + } + /// isAnalysisGroup - Return true if this is an analysis group, not a normal /// pass. /// diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index 90b95bf..3875f0b 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -149,8 +149,8 @@ public: } inline bool operator>(const _Self& x) const { - return idx > x.idx; assert(Term == x.Term && "Cannot compare iterators of different blocks!"); + return idx > x.idx; } inline _Self& operator+=(int Right) { diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index 6814f63..32631fc 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -21,29 +21,6 @@ namespace llvm { class MDNode; - /// DebugLocTuple - Debug location tuple of filename id, line and column. - /// - struct DebugLocTuple { - MDNode *Scope; - MDNode *InlinedAtLoc; - unsigned Line, Col; - - DebugLocTuple() - : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {} - - DebugLocTuple(MDNode *n, MDNode *i, unsigned l, unsigned c) - : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {} - - bool operator==(const DebugLocTuple &DLT) const { - return Scope == DLT.Scope && - InlinedAtLoc == DLT.InlinedAtLoc && - Line == DLT.Line && Col == DLT.Col; - } - bool operator!=(const DebugLocTuple &DLT) const { - return !(*this == DLT); - } - }; - /// DebugLoc - Debug location id. This is carried by SDNode and MachineInstr /// to index into a vector of unique debug location tuples. class DebugLoc { @@ -65,40 +42,16 @@ namespace llvm { bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } }; - // Specialize DenseMapInfo for DebugLocTuple. - template<> struct DenseMapInfo<DebugLocTuple> { - static inline DebugLocTuple getEmptyKey() { - return DebugLocTuple(0, 0, ~0U, ~0U); - } - static inline DebugLocTuple getTombstoneKey() { - return DebugLocTuple((MDNode*)~1U, (MDNode*)~1U, ~1U, ~1U); - } - static unsigned getHashValue(const DebugLocTuple &Val) { - return DenseMapInfo<MDNode*>::getHashValue(Val.Scope) ^ - DenseMapInfo<MDNode*>::getHashValue(Val.InlinedAtLoc) ^ - DenseMapInfo<unsigned>::getHashValue(Val.Line) ^ - DenseMapInfo<unsigned>::getHashValue(Val.Col); - } - static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) { - return LHS.Scope == RHS.Scope && - LHS.InlinedAtLoc == RHS.InlinedAtLoc && - LHS.Line == RHS.Line && - LHS.Col == RHS.Col; - } - }; - template <> struct isPodLike<DebugLocTuple> {static const bool value = true;}; - - - /// DebugLocTracker - This class tracks debug location information. + /// DebugLocTracker - This class tracks debug location information. /// struct DebugLocTracker { /// DebugLocations - A vector of unique DebugLocTuple's. /// - std::vector<DebugLocTuple> DebugLocations; + std::vector<MDNode *> DebugLocations; /// DebugIdMap - This maps DebugLocTuple's to indices into the /// DebugLocations vector. - DenseMap<DebugLocTuple, unsigned> DebugIdMap; + DenseMap<MDNode *, unsigned> DebugIdMap; DebugLocTracker() {} }; diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h deleted file mode 100644 index aa230d4..0000000 --- a/include/llvm/Support/Mangler.h +++ /dev/null @@ -1,142 +0,0 @@ -//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Unified name mangler for various backends. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_MANGLER_H -#define LLVM_SUPPORT_MANGLER_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include <string> - -namespace llvm { -class Twine; -class Type; -class Module; -class Value; -class GlobalValue; -template <typename T> class SmallVectorImpl; - -class Mangler { -public: - enum ManglerPrefixTy { - Default, ///< Emit default string before each symbol. - Private, ///< Emit "private" prefix before each symbol. - LinkerPrivate ///< Emit "linker private" prefix before each symbol. - }; - -private: - /// Prefix - This string is added to each symbol that is emitted, unless the - /// symbol is marked as not needing this prefix. - const char *Prefix; - - /// PrivatePrefix - This string is emitted before each symbol with private - /// linkage. - const char *PrivatePrefix; - - /// LinkerPrivatePrefix - This string is emitted before each symbol with - /// "linker_private" linkage. - const char *LinkerPrivatePrefix; - - /// UseQuotes - If this is set, the target accepts global names in quotes, - /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping - /// the space character. By default, this is false. - bool UseQuotes; - - /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to - /// start with digits (e.g., "0x0021"). By default, this is false. - bool SymbolsCanStartWithDigit; - - /// AnonGlobalIDs - We need to give global values the same name every time - /// they are mangled. This keeps track of the number we give to anonymous - /// ones. - /// - DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs; - - /// NextAnonGlobalID - This simple counter is used to unique value names. - /// - unsigned NextAnonGlobalID; - - /// AcceptableChars - This bitfield contains a one for each character that is - /// allowed to be part of an unmangled name. - unsigned AcceptableChars[256 / 32]; - -public: - // Mangler ctor - if a prefix is specified, it will be prepended onto all - // symbols. - Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "", - const char *linkerPrivatePrefix = ""); - - /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted - /// strings for assembler labels. - void setUseQuotes(bool Val) { UseQuotes = Val; } - - /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true, - /// this target allows symbols to start with digits. - void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = Val; } - - /// Acceptable Characters - This allows the target to specify which characters - /// are acceptable to the assembler without being mangled. By default we - /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'. - void markCharAcceptable(unsigned char X) { - AcceptableChars[X/32] |= 1 << (X&31); - } - void markCharUnacceptable(unsigned char X) { - AcceptableChars[X/32] &= ~(1 << (X&31)); - } - bool isCharAcceptable(unsigned char X) const { - return (AcceptableChars[X/32] & (1 << (X&31))) != 0; - } - - /// getMangledName - Returns the mangled name of V, an LLVM Value, - /// in the current module. If 'Suffix' is specified, the name ends with the - /// specified suffix. If 'ForcePrivate' is specified, the label is specified - /// to have a private label prefix. - /// - /// FIXME: This is deprecated, new code should use getNameWithPrefix and use - /// MCSymbol printing to handle quotes or not etc. - /// - std::string getMangledName(const GlobalValue *V, const char *Suffix = "", - bool ForcePrivate = false); - - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix - /// and the specified global variable's name. If the global variable doesn't - /// have a name, this fills in a unique name for the global. - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, - bool isImplicitlyPrivate); - - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix - /// and the specified name as the global variable name. GVName must not be - /// empty. - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, - ManglerPrefixTy PrefixTy = Mangler::Default); - -private: - /// makeNameProper - We don't want identifier names with ., space, or - /// - in them, so we mangle these characters into the strings "d_", - /// "s_", and "D_", respectively. This is a very simple mangling that - /// doesn't guarantee unique names for values. getValueName already - /// does this for you, so there's no point calling it on the result - /// from getValueName. - /// - /// FIXME: This is deprecated, new code should use getNameWithPrefix and use - /// MCSymbol printing to handle quotes or not etc. - /// - void makeNameProper(SmallVectorImpl<char> &OutName, - const Twine &Name, - ManglerPrefixTy PrefixTy = Mangler::Default); - -}; - -} // End llvm namespace - -#endif // LLVM_SUPPORT_MANGLER_H diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h index ea4fe01..cdca978 100644 --- a/include/llvm/Support/PassNameParser.h +++ b/include/llvm/Support/PassNameParser.h @@ -41,7 +41,9 @@ class PassNameParser : public PassRegistrationListener, cl::Option *Opt; public: PassNameParser() : Opt(0) {} - + virtual ~PassNameParser(); + + void initialize(cl::Option &O) { Opt = &O; cl::parser<const PassInfo*>::initialize(O); diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h new file mode 100644 index 0000000..967bf14 --- /dev/null +++ b/include/llvm/Support/SMLoc.h @@ -0,0 +1,44 @@ +//===- SMLoc.h - Source location for use with diagnostics -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the SMLoc class. This class encapsulates a location in +// source code for use in diagnostics. +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_SMLOC_H +#define SUPPORT_SMLOC_H + +namespace llvm { + +// SMLoc - Represents a location in source code. +class SMLoc { + const char *Ptr; +public: + SMLoc() : Ptr(0) {} + SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {} + + bool isValid() const { return Ptr != 0; } + + bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } + bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } + + const char *getPointer() const { return Ptr; } + + static SMLoc getFromPointer(const char *Ptr) { + SMLoc L; + L.Ptr = Ptr; + return L; + } +}; + +} + +#endif + diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index b695ff1..5433a00 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file declares the SMLoc, SMDiagnostic and SourceMgr classes. This +// This file declares the SMDiagnostic and SourceMgr classes. This // provides a simple substrate for diagnostics, #include handling, and other low // level things for simple parsers. // @@ -16,6 +16,8 @@ #ifndef SUPPORT_SOURCEMGR_H #define SUPPORT_SOURCEMGR_H +#include "llvm/Support/SMLoc.h" + #include <string> #include <vector> #include <cassert> @@ -25,26 +27,6 @@ namespace llvm { class SourceMgr; class SMDiagnostic; class raw_ostream; - -class SMLoc { - const char *Ptr; -public: - SMLoc() : Ptr(0) {} - SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {} - - bool isValid() const { return Ptr != 0; } - - bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } - bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } - - const char *getPointer() const { return Ptr; } - - static SMLoc getFromPointer(const char *Ptr) { - SMLoc L; - L.Ptr = Ptr; - return L; - } -}; /// SourceMgr - This owns the files read by a parser, handles include stacks, /// and handles diagnostic wrangling. diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index d3c45c2..0f227cc 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -456,6 +456,11 @@ public: explicit raw_svector_ostream(SmallVectorImpl<char> &O); ~raw_svector_ostream(); + /// resync - This is called when the SmallVector we're appending to is changed + /// outside of the raw_svector_ostream's control. It is only safe to do this + /// if the raw_svector_ostream has previously been flushed. + void resync(); + /// str - Flushes the stream contents to the target vector and return a /// StringRef for the vector contents. StringRef str(); diff --git a/include/llvm/System/Host.h b/include/llvm/System/Host.h index 6de1a4a..4fbf5c1 100644 --- a/include/llvm/System/Host.h +++ b/include/llvm/System/Host.h @@ -14,6 +14,7 @@ #ifndef LLVM_SYSTEM_HOST_H #define LLVM_SYSTEM_HOST_H +#include "llvm/ADT/StringMap.h" #include <string> namespace llvm { @@ -47,6 +48,18 @@ namespace sys { /// /// \return - The host CPU name, or empty if the CPU could not be determined. std::string getHostCPUName(); + + /// getHostCPUFeatures - Get the LLVM names for the host CPU features. + /// The particular format of the names are target dependent, and suitable for + /// passing as -mattr to the target which matches the host. + /// + /// \param Features - A string mapping feature names to either + /// true (if enabled) or false (if disabled). This routine makes no guarantees + /// about exactly which features may appear in this map, except that they are + /// all valid LLVM feature names. + /// + /// \return - True on success. + bool getHostCPUFeatures(StringMap<bool> &Features); } } diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h new file mode 100644 index 0000000..04de4e9 --- /dev/null +++ b/include/llvm/Target/Mangler.h @@ -0,0 +1,75 @@ +//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Unified name mangler for various backends. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MANGLER_H +#define LLVM_SUPPORT_MANGLER_H + +#include "llvm/ADT/DenseMap.h" +#include <string> + +namespace llvm { +class StringRef; +class Twine; +class Value; +class GlobalValue; +template <typename T> class SmallVectorImpl; +class MCAsmInfo; + +class Mangler { +public: + enum ManglerPrefixTy { + Default, ///< Emit default string before each symbol. + Private, ///< Emit "private" prefix before each symbol. + LinkerPrivate ///< Emit "linker private" prefix before each symbol. + }; + +private: + const MCAsmInfo &MAI; + + /// AnonGlobalIDs - We need to give global values the same name every time + /// they are mangled. This keeps track of the number we give to anonymous + /// ones. + /// + DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs; + + /// NextAnonGlobalID - This simple counter is used to unique value names. + /// + unsigned NextAnonGlobalID; + +public: + // Mangler ctor - if a prefix is specified, it will be prepended onto all + // symbols. + Mangler(const MCAsmInfo &mai) : MAI(mai), NextAnonGlobalID(1) {} + + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix + /// and the specified global variable's name. If the global variable doesn't + /// have a name, this fills in a unique name for the global. + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + bool isImplicitlyPrivate); + + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix + /// and the specified name as the global variable name. GVName must not be + /// empty. + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, + ManglerPrefixTy PrefixTy = Mangler::Default); + + /// getNameWithPrefix - Return the name of the appropriate prefix + /// and the specified global variable's name. If the global variable doesn't + /// have a name, this fills in a unique name for the global. + std::string getNameWithPrefix(const GlobalValue *GV, + bool isImplicitlyPrivate = false); +}; + +} // End llvm namespace + +#endif // LLVM_SUPPORT_MANGLER_H diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 206e42e..354e743 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -479,7 +479,7 @@ def COPY_TO_REGCLASS : Instruction { } def DEBUG_VALUE : Instruction { let OutOperandList = (ops); - let InOperandList = (ops unknown:$value, i64imm:$offset, unknown:$meta); + let InOperandList = (ops variable_ops); let AsmString = "DEBUG_VALUE"; let Namespace = "TargetInstrInfo"; let isAsCheapAsAMove = 1; diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/Target/TargetAsmLexer.h new file mode 100644 index 0000000..daba1ba --- /dev/null +++ b/include/llvm/Target/TargetAsmLexer.h @@ -0,0 +1,79 @@ +//===-- llvm/Target/TargetAsmLexer.h - Target Assembly Lexer ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETASMLEXER_H +#define LLVM_TARGET_TARGETASMLEXER_H + +#include "llvm/MC/MCParser/MCAsmLexer.h" + +namespace llvm { +class Target; + +/// TargetAsmLexer - Generic interface to target specific assembly lexers. +class TargetAsmLexer { + /// The current token + AsmToken CurTok; + + /// The location and description of the current error + SMLoc ErrLoc; + std::string Err; + + TargetAsmLexer(const TargetAsmLexer &); // DO NOT IMPLEMENT + void operator=(const TargetAsmLexer &); // DO NOT IMPLEMENT +protected: // Can only create subclasses. + TargetAsmLexer(const Target &); + + virtual AsmToken LexToken() = 0; + + void SetError(const SMLoc &errLoc, const std::string &err) { + ErrLoc = errLoc; + Err = err; + } + + /// TheTarget - The Target that this machine was created for. + const Target &TheTarget; + +public: + virtual ~TargetAsmLexer(); + + const Target &getTarget() const { return TheTarget; } + + /// Lex - Consume the next token from the input stream and return it. + const AsmToken &Lex() { + return CurTok = LexToken(); + } + + /// getTok - Get the current (last) lexed token. + const AsmToken &getTok() { + return CurTok; + } + + /// getErrLoc - Get the current error location + const SMLoc &getErrLoc() { + return ErrLoc; + } + + /// getErr - Get the current error string + const std::string &getErr() { + return Err; + } + + /// getKind - Get the kind of current token. + AsmToken::TokenKind getKind() const { return CurTok.getKind(); } + + /// is - Check if the current token has kind \arg K. + bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } + + /// isNot - Check if the current token has kind \arg K. + bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 1d3da8b..da9ba2b 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -11,7 +11,6 @@ #define LLVM_TARGET_TARGETPARSER_H namespace llvm { -class MCAsmParser; class MCInst; class StringRef; class Target; diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 8e2157e..7144fe0 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -486,6 +486,30 @@ public: unsigned *LoadRegIndex = 0) const { return 0; } + + /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler + /// to determine if two loads are loading from the same base address. It + /// should only return true if the base pointers are the same and the + /// only differences between the two addresses are the offset. It also returns + /// the offsets by reference. + virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, + int64_t &Offset1, int64_t &Offset2) const { + return false; + } + + /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to + /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should + /// be scheduled togther. On some targets if two loads are loading from + /// addresses in the same cache line, it's better if they are scheduled + /// together. This function takes two integers that represent the load offsets + /// from the common base address. It returns true if it decides it's desirable + /// to schedule the two loads together. "NumLoads" is the number of loads that + /// have already been scheduled after Load1. + virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, + int64_t Offset1, int64_t Offset2, + unsigned NumLoads) const { + return false; + } /// ReverseBranchCondition - Reverses the branch condition of the specified /// condition list, returning false on success and true if it cannot be diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 3dd7471..d3e5cf2 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -258,6 +258,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { const MCSection *ConstDataCoalSection; const MCSection *ConstDataSection; const MCSection *DataCoalSection; + const MCSection *DataCommonSection; + const MCSection *DataBSSSection; const MCSection *FourByteConstantSection; const MCSection *EightByteConstantSection; const MCSection *SixteenByteConstantSection; diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 84cd5b4..4db3d3e 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -81,6 +81,14 @@ namespace CodeGenOpt { }; } +// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes. +namespace DwarfLSDAEncoding { + enum Encoding { + Default, + FourByte, + EightByte + }; +} //===----------------------------------------------------------------------===// /// @@ -129,10 +137,7 @@ public: /// TargetSubtarget. In debug builds, it verifies that the object being /// returned is of the correct type. template<typename STC> const STC &getSubtarget() const { - const TargetSubtarget *TST = getSubtargetImpl(); - assert(TST && dynamic_cast<const STC*>(TST) && - "Not the right kind of subtarget!"); - return *static_cast<const STC*>(TST); + return *static_cast<const STC*>(getSubtargetImpl()); } /// getRegisterInfo - If register information is available, return it. If @@ -192,6 +197,20 @@ public: /// is false. static void setAsmVerbosityDefault(bool); + /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are + /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that + /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded + /// as a 4-byte pointer by default. However, some systems may require a + /// different size due to bugs or other conditions. We will default to a + /// 4-byte encoding unless the system tells us otherwise. + /// + /// FIXME: This call-back isn't good! We should be using the correct encoding + /// regardless of the system. However, there are some systems which have bugs + /// that prevent this from occuring. + virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const { + return DwarfLSDAEncoding::Default; + } + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit. enum CodeGenFileType { @@ -452,6 +471,14 @@ public: bool addAssemblyEmitter(PassManagerBase &, CodeGenOpt::Level, bool /* VerboseAsmDefault */, formatted_raw_ostream &); + + /// addObjectFileEmitter - Helper function which creates a target specific + /// object files emitter, if available. This interface is temporary, for + /// bringing up MCAssembler-based object file emitters. + /// + /// \return Returns 'false' on success. + bool addObjectFileEmitter(PassManagerBase &, CodeGenOpt::Level, + formatted_raw_ostream &); }; } // End llvm namespace diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index 167e1d1..d3aa867 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -31,6 +31,7 @@ namespace llvm { class MCAsmInfo; class MCDisassembler; class MCInstPrinter; + class TargetAsmLexer; class TargetAsmParser; class TargetMachine; class formatted_raw_ostream; @@ -59,8 +60,9 @@ namespace llvm { TargetMachine &TM, const MCAsmInfo *MAI, bool VerboseAsm); - typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T, - MCAsmParser &P); + typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, + const MCAsmInfo &MAI); + typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P); typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, @@ -97,8 +99,12 @@ namespace llvm { /// if registered. AsmPrinterCtorTy AsmPrinterCtorFn; - /// AsmParserCtorFn - Construction function for this target's AsmParser, + /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer, /// if registered. + AsmLexerCtorTy AsmLexerCtorFn; + + /// AsmParserCtorFn - Construction function for this target's + /// TargetAsmParser, if registered. AsmParserCtorTy AsmParserCtorFn; /// MCDisassemblerCtorFn - Construction function for this target's @@ -191,6 +197,14 @@ namespace llvm { return AsmPrinterCtorFn(OS, TM, MAI, Verbose); } + /// createAsmLexer - Create a target specific assembly lexer. + /// + TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const { + if (!AsmLexerCtorFn) + return 0; + return AsmLexerCtorFn(*this, MAI); + } + /// createAsmParser - Create a target specific assembly parser. /// /// \arg Parser - The target independent parser implementation to use for @@ -358,6 +372,20 @@ namespace llvm { T.AsmPrinterCtorFn = Fn; } + /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an AsmPrinter for the target. + static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) { + if (!T.AsmLexerCtorFn) + T.AsmLexerCtorFn = Fn; + } + /// RegisterAsmParser - Register a TargetAsmParser implementation for the /// given target. /// @@ -524,6 +552,26 @@ namespace llvm { } }; + /// RegisterAsmLexer - Helper template for registering a target specific + /// assembly lexer, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooAsmLexer() { + /// extern Target TheFooTarget; + /// RegisterAsmLexer<FooAsmLexer> X(TheFooTarget); + /// } + template<class AsmLexerImpl> + struct RegisterAsmLexer { + RegisterAsmLexer(Target &T) { + TargetRegistry::RegisterAsmLexer(T, &Allocator); + } + + private: + static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) { + return new AsmLexerImpl(T, MAI); + } + }; + /// RegisterAsmParser - Helper template for registering a target specific /// assembly parser, for use in the target machine initialization /// function. Usage: diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index 5d00f42..dc5e644 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -51,6 +51,12 @@ struct Inliner : public CallGraphSCCPass { /// unsigned getInlineThreshold() const { return InlineThreshold; } + /// Calculate the inline threshold for given Caller. This threshold is lower + /// if Caller is marked with OptimizeForSize and -inline-threshold is not + /// given on the comand line. + /// + unsigned getInlineThreshold(Function* Caller) const; + /// getInlineCost - This method must be implemented by the subclass to /// determine the cost of inlining the specified call site. If the cost /// returned is greater than the current inline threshold, the call site is diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 0b8147e..f6d9f82 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -27,7 +27,6 @@ class PHINode; class AllocaInst; class ConstantExpr; class TargetData; -class DbgInfoIntrinsic; template<typename T> class SmallVectorImpl; @@ -154,12 +153,6 @@ AllocaInst *DemoteRegToStack(Instruction &X, /// The phi node is deleted and it returns the pointer to the alloca inserted. AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0); -/// OnlyUsedByDbgIntrinsics - Return true if the instruction I is only used -/// by DbgIntrinsics. If DbgInUses is specified then the vector is filled -/// with DbgInfoIntrinsic that use the instruction I. -bool OnlyUsedByDbgInfoIntrinsics(Instruction *I, - SmallVectorImpl<DbgInfoIntrinsic *> *DbgInUses = 0); - } // End llvm namespace #endif |