diff options
Diffstat (limited to 'contrib/llvm/lib/IR')
27 files changed, 4620 insertions, 3156 deletions
diff --git a/contrib/llvm/lib/IR/AsmWriter.cpp b/contrib/llvm/lib/IR/AsmWriter.cpp index a78b19c..7decffd 100644 --- a/contrib/llvm/lib/IR/AsmWriter.cpp +++ b/contrib/llvm/lib/IR/AsmWriter.cpp @@ -14,6 +14,8 @@ // //===----------------------------------------------------------------------===// +#include "AsmWriter.h" + #include "llvm/Assembly/Writer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -38,6 +40,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MathExtras.h" + #include <algorithm> #include <cctype> using namespace llvm; @@ -71,6 +74,8 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { default: Out << "cc" << cc; break; case CallingConv::Fast: Out << "fastcc"; break; case CallingConv::Cold: Out << "coldcc"; break; + case CallingConv::WebKit_JS: Out << "webkit_jscc"; break; + case CallingConv::AnyReg: Out << "anyregcc"; break; case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break; case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break; case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break; @@ -155,35 +160,8 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix); } -//===----------------------------------------------------------------------===// -// TypePrinting Class: Type printing machinery -//===----------------------------------------------------------------------===// - -/// TypePrinting - Type printing machinery. -namespace { -class TypePrinting { - TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION; - void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION; -public: - - /// NamedTypes - The named types that are used by the current module. - TypeFinder NamedTypes; - - /// NumberedTypes - The numbered types, along with their value. - DenseMap<StructType*, unsigned> NumberedTypes; - - - TypePrinting() {} - ~TypePrinting() {} - - void incorporateTypes(const Module &M); - - void print(Type *Ty, raw_ostream &OS); - - void printStructBody(StructType *Ty, raw_ostream &OS); -}; -} // end anonymous namespace. +namespace llvm { void TypePrinting::incorporateTypes(const Module &M) { NamedTypes.run(M, false); @@ -315,14 +293,9 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { OS << '>'; } - - //===----------------------------------------------------------------------===// // SlotTracker Class: Enumerate slot numbers for unnamed values //===----------------------------------------------------------------------===// - -namespace { - /// This class provides computation of slot numbers for LLVM Assembly writing. /// class SlotTracker { @@ -420,8 +393,9 @@ private: void operator=(const SlotTracker &) LLVM_DELETED_FUNCTION; }; -} // end anonymous namespace - +SlotTracker *createSlotTracker(const Module *M) { + return new SlotTracker(M); +} static SlotTracker *createSlotTracker(const Value *V) { if (const Argument *FA = dyn_cast<Argument>(V)) @@ -1202,8 +1176,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << "<badref>"; } -void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, - bool PrintType, const Module *Context) { +void WriteAsOperand(raw_ostream &Out, const Value *V, + bool PrintType, const Module *Context) { // Fast path: Don't construct and populate a TypePrinting object if we // won't be needing any types printed. @@ -1227,50 +1201,27 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context); } -namespace { - -class AssemblyWriter { - formatted_raw_ostream &Out; - SlotTracker &Machine; - const Module *TheModule; - TypePrinting TypePrinter; - AssemblyAnnotationWriter *AnnotationWriter; - -public: - inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, - const Module *M, - AssemblyAnnotationWriter *AAW) - : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { - if (M) - TypePrinter.incorporateTypes(*M); - } - - void printMDNodeBody(const MDNode *MD); - void printNamedMDNode(const NamedMDNode *NMD); - - void printModule(const Module *M); +void AssemblyWriter::init() { + if (TheModule) + TypePrinter.incorporateTypes(*TheModule); +} - void writeOperand(const Value *Op, bool PrintType); - void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx); - void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); - void writeAllMDNodes(); - void writeAllAttributeGroups(); +AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, + AssemblyAnnotationWriter *AAW) + : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW) { + init(); +} - void printTypeIdentities(); - void printGlobal(const GlobalVariable *GV); - void printAlias(const GlobalAlias *GV); - void printFunction(const Function *F); - void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx); - void printBasicBlock(const BasicBlock *BB); - void printInstruction(const Instruction &I); +AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M, + AssemblyAnnotationWriter *AAW) + : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)), + Machine(*ModuleSlotTracker), AnnotationWriter(AAW) { + init(); +} -private: - // printInfoComment - Print a little comment after the instruction indicating - // which slot it occupies. - void printInfoComment(const Value &V); -}; -} // end of anonymous namespace +AssemblyWriter::~AssemblyWriter() { } void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { if (Operand == 0) { @@ -1445,9 +1396,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; - case GlobalValue::LinkOnceODRAutoHideLinkage: - Out << "linkonce_odr_auto_hide "; - break; case GlobalValue::WeakAnyLinkage: Out << "weak "; break; case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; case GlobalValue::CommonLinkage: Out << "common "; break; @@ -1698,6 +1646,10 @@ void AssemblyWriter::printFunction(const Function *F) { Out << " align " << F->getAlignment(); if (F->hasGC()) Out << " gc \"" << F->getGC() << '"'; + if (F->hasPrefixData()) { + Out << " prefix "; + writeOperand(F->getPrefixData(), true); + } if (F->isDeclaration()) { Out << '\n'; } else { @@ -1774,13 +1726,18 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { // Output all of the instructions in the basic block... for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - printInstruction(*I); - Out << '\n'; + printInstructionLine(*I); } if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } +/// printInstructionLine - Print an instruction and a newline character. +void AssemblyWriter::printInstructionLine(const Instruction &I) { + printInstruction(I); + Out << '\n'; +} + /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// @@ -2095,9 +2052,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { unsigned Kind = InstMD[i].first; if (Kind < MDNames.size()) { Out << ", !" << MDNames[Kind]; - } else { - Out << ", !<unknown kind #" << Kind << ">"; - } + } else { + Out << ", !<unknown kind #" << Kind << ">"; + } Out << ' '; WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine, TheModule); @@ -2129,6 +2086,11 @@ static void WriteMDNodeComment(const MDNode *Node, } } +void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) { + Out << '!' << Slot << " = metadata "; + printMDNodeBody(Node); +} + void AssemblyWriter::writeAllMDNodes() { SmallVector<const MDNode *, 16> Nodes; Nodes.resize(Machine.mdn_size()); @@ -2137,8 +2099,7 @@ void AssemblyWriter::writeAllMDNodes() { Nodes[I->second] = cast<MDNode>(I->first); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { - Out << '!' << i << " = metadata "; - printMDNodeBody(Nodes[i]); + writeMDNode(i, Nodes[i]); } } @@ -2162,6 +2123,8 @@ void AssemblyWriter::writeAllAttributeGroups() { << I->first.getAsString(AttributeSet::FunctionIndex, true) << " }\n"; } +} // namespace llvm + //===----------------------------------------------------------------------===// // External Interface declarations //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/IR/AsmWriter.h b/contrib/llvm/lib/IR/AsmWriter.h new file mode 100644 index 0000000..8f4a377 --- /dev/null +++ b/contrib/llvm/lib/IR/AsmWriter.h @@ -0,0 +1,118 @@ +//===-- llvm/IR/AsmWriter.h - Printing LLVM IR as an assembly file - C++ --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files defines the interface for the AssemblyWriter class used to print +// LLVM IR and various helper classes that are used in printing. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_ASSEMBLYWRITER_H +#define LLVM_IR_ASSEMBLYWRITER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/Support/FormattedStream.h" + +namespace llvm { + +class BasicBlock; +class Function; +class GlobalValue; +class Module; +class NamedMDNode; +class Value; +class SlotTracker; + +/// Create a new SlotTracker for a Module +SlotTracker *createSlotTracker(const Module *M); + +//===----------------------------------------------------------------------===// +// TypePrinting Class: Type printing machinery +//===----------------------------------------------------------------------===// + +class TypePrinting { + TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION; + void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION; +public: + + /// NamedTypes - The named types that are used by the current module. + TypeFinder NamedTypes; + + /// NumberedTypes - The numbered types, along with their value. + DenseMap<StructType*, unsigned> NumberedTypes; + + + TypePrinting() {} + ~TypePrinting() {} + + void incorporateTypes(const Module &M); + + void print(Type *Ty, raw_ostream &OS); + + void printStructBody(StructType *Ty, raw_ostream &OS); +}; + +class AssemblyWriter { +protected: + formatted_raw_ostream &Out; + const Module *TheModule; + +private: + OwningPtr<SlotTracker> ModuleSlotTracker; + SlotTracker &Machine; + TypePrinting TypePrinter; + AssemblyAnnotationWriter *AnnotationWriter; + +public: + /// Construct an AssemblyWriter with an external SlotTracker + AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, AssemblyAnnotationWriter *AAW); + + /// Construct an AssemblyWriter with an internally allocated SlotTracker + AssemblyWriter(formatted_raw_ostream &o, const Module *M, + AssemblyAnnotationWriter *AAW); + + virtual ~AssemblyWriter(); + + void printMDNodeBody(const MDNode *MD); + void printNamedMDNode(const NamedMDNode *NMD); + + void printModule(const Module *M); + + void writeOperand(const Value *Op, bool PrintType); + void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx); + void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); + + void writeAllMDNodes(); + void writeMDNode(unsigned Slot, const MDNode *Node); + void writeAllAttributeGroups(); + + void printTypeIdentities(); + void printGlobal(const GlobalVariable *GV); + void printAlias(const GlobalAlias *GV); + void printFunction(const Function *F); + void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx); + void printBasicBlock(const BasicBlock *BB); + void printInstructionLine(const Instruction &I); + void printInstruction(const Instruction &I); + +private: + void init(); + + // printInfoComment - Print a little comment after the instruction indicating + // which slot it occupies. + void printInfoComment(const Value &V); +}; + +} // namespace llvm + +#endif //LLVM_IR_ASMWRITER_H diff --git a/contrib/llvm/lib/IR/AttributeImpl.h b/contrib/llvm/lib/IR/AttributeImpl.h index 0b6228b..ea954ac 100644 --- a/contrib/llvm/lib/IR/AttributeImpl.h +++ b/contrib/llvm/lib/IR/AttributeImpl.h @@ -27,97 +27,30 @@ class LLVMContext; //===----------------------------------------------------------------------===// /// \class -/// \brief A set of classes that contain the kind and (optional) value of the -/// attribute object. There are three main categories: enum attribute entries, -/// represented by Attribute::AttrKind; alignment attribute entries; and string -/// attribute enties, which are for target-dependent attributes. -class AttributeEntry { - unsigned char KindID; +/// \brief This class represents a single, uniqued attribute. That attribute +/// could be a single enum, a tuple, or a string. +class AttributeImpl : public FoldingSetNode { + unsigned char KindID; ///< Holds the AttrEntryKind of the attribute + + // AttributesImpl is uniqued, these should not be publicly available. + void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; + AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; + protected: enum AttrEntryKind { EnumAttrEntry, AlignAttrEntry, StringAttrEntry }; -public: - AttributeEntry(AttrEntryKind Kind) - : KindID(Kind) {} - virtual ~AttributeEntry() {} - unsigned getKindID() const { return KindID; } + AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {} - static inline bool classof(const AttributeEntry *) { return true; } -}; - -class EnumAttributeEntry : public AttributeEntry { - Attribute::AttrKind Kind; public: - EnumAttributeEntry(Attribute::AttrKind Kind) - : AttributeEntry(EnumAttrEntry), Kind(Kind) {} - - Attribute::AttrKind getEnumKind() const { return Kind; } - - static inline bool classof(const AttributeEntry *AE) { - return AE->getKindID() == EnumAttrEntry; - } - static inline bool classof(const EnumAttributeEntry *) { return true; } -}; + virtual ~AttributeImpl(); -class AlignAttributeEntry : public AttributeEntry { - Attribute::AttrKind Kind; - unsigned Align; -public: - AlignAttributeEntry(Attribute::AttrKind Kind, unsigned Align) - : AttributeEntry(AlignAttrEntry), Kind(Kind), Align(Align) {} - - Attribute::AttrKind getEnumKind() const { return Kind; } - unsigned getAlignment() const { return Align; } - - static inline bool classof(const AttributeEntry *AE) { - return AE->getKindID() == AlignAttrEntry; - } - static inline bool classof(const AlignAttributeEntry *) { return true; } -}; - -class StringAttributeEntry : public AttributeEntry { - std::string Kind; - std::string Val; -public: - StringAttributeEntry(StringRef Kind, StringRef Val = StringRef()) - : AttributeEntry(StringAttrEntry), Kind(Kind), Val(Val) {} - - StringRef getStringKind() const { return Kind; } - StringRef getStringValue() const { return Val; } - - static inline bool classof(const AttributeEntry *AE) { - return AE->getKindID() == StringAttrEntry; - } - static inline bool classof(const StringAttributeEntry *) { return true; } -}; - -//===----------------------------------------------------------------------===// -/// \class -/// \brief This class represents a single, uniqued attribute. That attribute -/// could be a single enum, a tuple, or a string. -class AttributeImpl : public FoldingSetNode { - LLVMContext &Context; ///< Global context for uniquing objects - - AttributeEntry *Entry; ///< Holds the kind and value of the attribute - - // AttributesImpl is uniqued, these should not be publicly available. - void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; - AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; -public: - AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind); - AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind, unsigned Align); - AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val = StringRef()); - ~AttributeImpl(); - - LLVMContext &getContext() { return Context; } - - bool isEnumAttribute() const; - bool isAlignAttribute() const; - bool isStringAttribute() const; + bool isEnumAttribute() const { return KindID == EnumAttrEntry; } + bool isAlignAttribute() const { return KindID == AlignAttrEntry; } + bool isStringAttribute() const { return KindID == StringAttrEntry; } bool hasAttribute(Attribute::AttrKind A) const; bool hasAttribute(StringRef Kind) const; @@ -155,13 +88,66 @@ public: //===----------------------------------------------------------------------===// /// \class +/// \brief A set of classes that contain the value of the +/// attribute object. There are three main categories: enum attribute entries, +/// represented by Attribute::AttrKind; alignment attribute entries; and string +/// attribute enties, which are for target-dependent attributes. + +class EnumAttributeImpl : public AttributeImpl { + virtual void anchor(); + Attribute::AttrKind Kind; + +protected: + EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind) + : AttributeImpl(ID), Kind(Kind) {} + +public: + EnumAttributeImpl(Attribute::AttrKind Kind) + : AttributeImpl(EnumAttrEntry), Kind(Kind) {} + + Attribute::AttrKind getEnumKind() const { return Kind; } +}; + +class AlignAttributeImpl : public EnumAttributeImpl { + virtual void anchor(); + unsigned Align; + +public: + AlignAttributeImpl(Attribute::AttrKind Kind, unsigned Align) + : EnumAttributeImpl(AlignAttrEntry, Kind), Align(Align) { + assert( + (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) && + "Wrong kind for alignment attribute!"); + } + + unsigned getAlignment() const { return Align; } +}; + +class StringAttributeImpl : public AttributeImpl { + virtual void anchor(); + std::string Kind; + std::string Val; + +public: + StringAttributeImpl(StringRef Kind, StringRef Val = StringRef()) + : AttributeImpl(StringAttrEntry), Kind(Kind), Val(Val) {} + + StringRef getStringKind() const { return Kind; } + StringRef getStringValue() const { return Val; } +}; + +//===----------------------------------------------------------------------===// +/// \class /// \brief This class represents a group of attributes that apply to one /// element: function, return type, or parameter. class AttributeSetNode : public FoldingSetNode { - SmallVector<Attribute, 4> AttrList; + unsigned NumAttrs; ///< Number of attributes in this node. - AttributeSetNode(ArrayRef<Attribute> Attrs) - : AttrList(Attrs.begin(), Attrs.end()) {} + AttributeSetNode(ArrayRef<Attribute> Attrs) : NumAttrs(Attrs.size()) { + // There's memory after the node where we can store the entries in. + std::copy(Attrs.begin(), Attrs.end(), + reinterpret_cast<Attribute *>(this + 1)); + } // AttributesSetNode is uniqued, these should not be publicly available. void operator=(const AttributeSetNode &) LLVM_DELETED_FUNCTION; @@ -171,7 +157,7 @@ public: bool hasAttribute(Attribute::AttrKind Kind) const; bool hasAttribute(StringRef Kind) const; - bool hasAttributes() const { return !AttrList.empty(); } + bool hasAttributes() const { return NumAttrs != 0; } Attribute getAttribute(Attribute::AttrKind Kind) const; Attribute getAttribute(StringRef Kind) const; @@ -180,17 +166,12 @@ public: unsigned getStackAlignment() const; std::string getAsString(bool InAttrGrp) const; - typedef SmallVectorImpl<Attribute>::iterator iterator; - typedef SmallVectorImpl<Attribute>::const_iterator const_iterator; - - iterator begin() { return AttrList.begin(); } - iterator end() { return AttrList.end(); } - - const_iterator begin() const { return AttrList.begin(); } - const_iterator end() const { return AttrList.end(); } + typedef const Attribute *iterator; + iterator begin() const { return reinterpret_cast<iterator>(this + 1); } + iterator end() const { return begin() + NumAttrs; } void Profile(FoldingSetNodeID &ID) const { - Profile(ID, AttrList); + Profile(ID, makeArrayRef(begin(), end())); } static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { for (unsigned I = 0, E = AttrList.size(); I != E; ++I) @@ -208,58 +189,67 @@ class AttributeSetImpl : public FoldingSetNode { LLVMContext &Context; typedef std::pair<unsigned, AttributeSetNode*> IndexAttrPair; - SmallVector<IndexAttrPair, 4> AttrNodes; + unsigned NumAttrs; ///< Number of entries in this set. + + /// \brief Return a pointer to the IndexAttrPair for the specified slot. + const IndexAttrPair *getNode(unsigned Slot) const { + return reinterpret_cast<const IndexAttrPair *>(this + 1) + Slot; + } // AttributesSet is uniqued, these should not be publicly available. void operator=(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; AttributeSetImpl(const AttributeSetImpl &) LLVM_DELETED_FUNCTION; public: AttributeSetImpl(LLVMContext &C, - ArrayRef<std::pair<unsigned, AttributeSetNode*> > attrs) - : Context(C), AttrNodes(attrs.begin(), attrs.end()) {} + ArrayRef<std::pair<unsigned, AttributeSetNode *> > Attrs) + : Context(C), NumAttrs(Attrs.size()) { +#ifndef NDEBUG + if (Attrs.size() >= 2) { + for (const std::pair<unsigned, AttributeSetNode *> *i = Attrs.begin() + 1, + *e = Attrs.end(); + i != e; ++i) { + assert((i-1)->first <= i->first && "Attribute set not ordered!"); + } + } +#endif + // There's memory after the node where we can store the entries in. + std::copy(Attrs.begin(), Attrs.end(), + reinterpret_cast<IndexAttrPair *>(this + 1)); + } /// \brief Get the context that created this AttributeSetImpl. LLVMContext &getContext() { return Context; } /// \brief Return the number of attributes this AttributeSet contains. - unsigned getNumAttributes() const { return AttrNodes.size(); } + unsigned getNumAttributes() const { return NumAttrs; } /// \brief Get the index of the given "slot" in the AttrNodes list. This index /// is the index of the return, parameter, or function object that the /// attributes are applied to, not the index into the AttrNodes list where the /// attributes reside. unsigned getSlotIndex(unsigned Slot) const { - return AttrNodes[Slot].first; + return getNode(Slot)->first; } /// \brief Retrieve the attributes for the given "slot" in the AttrNode list. /// \p Slot is an index into the AttrNodes list, not the index of the return / /// parameter/ function which the attributes apply to. AttributeSet getSlotAttributes(unsigned Slot) const { - return AttributeSet::get(Context, AttrNodes[Slot]); + return AttributeSet::get(Context, *getNode(Slot)); } /// \brief Retrieve the attribute set node for the given "slot" in the /// AttrNode list. AttributeSetNode *getSlotNode(unsigned Slot) const { - return AttrNodes[Slot].second; + return getNode(Slot)->second; } - typedef AttributeSetNode::iterator iterator; - typedef AttributeSetNode::const_iterator const_iterator; - - iterator begin(unsigned Slot) - { return AttrNodes[Slot].second->begin(); } - iterator end(unsigned Slot) - { return AttrNodes[Slot].second->end(); } - - const_iterator begin(unsigned Slot) const - { return AttrNodes[Slot].second->begin(); } - const_iterator end(unsigned Slot) const - { return AttrNodes[Slot].second->end(); } + typedef AttributeSetNode::iterator iterator; + iterator begin(unsigned Slot) const { return getSlotNode(Slot)->begin(); } + iterator end(unsigned Slot) const { return getSlotNode(Slot)->end(); } void Profile(FoldingSetNodeID &ID) const { - Profile(ID, AttrNodes); + Profile(ID, makeArrayRef(getNode(0), getNumAttributes())); } static void Profile(FoldingSetNodeID &ID, ArrayRef<std::pair<unsigned, AttributeSetNode*> > Nodes) { @@ -271,6 +261,8 @@ public: // FIXME: This atrocity is temporary. uint64_t Raw(unsigned Index) const; + + void dump() const; }; } // end llvm namespace diff --git a/contrib/llvm/lib/IR/Attributes.cpp b/contrib/llvm/lib/IR/Attributes.cpp index 4fe6f9d..0f2b7a0 100644 --- a/contrib/llvm/lib/IR/Attributes.cpp +++ b/contrib/llvm/lib/IR/Attributes.cpp @@ -43,9 +43,10 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = !Val ? - new AttributeImpl(Context, Kind) : - new AttributeImpl(Context, Kind, Val); + if (!Val) + PA = new EnumAttributeImpl(Kind); + else + PA = new AlignAttributeImpl(Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -65,7 +66,7 @@ Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) { if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = new AttributeImpl(Context, Kind, Val); + PA = new StringAttributeImpl(Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -103,24 +104,28 @@ bool Attribute::isStringAttribute() const { } Attribute::AttrKind Attribute::getKindAsEnum() const { + if (!pImpl) return None; assert((isEnumAttribute() || isAlignAttribute()) && "Invalid attribute type to get the kind as an enum!"); return pImpl ? pImpl->getKindAsEnum() : None; } uint64_t Attribute::getValueAsInt() const { + if (!pImpl) return 0; assert(isAlignAttribute() && "Expected the attribute to be an alignment attribute!"); return pImpl ? pImpl->getValueAsInt() : 0; } StringRef Attribute::getKindAsString() const { + if (!pImpl) return StringRef(); assert(isStringAttribute() && "Invalid attribute type to get the kind as a string!"); return pImpl ? pImpl->getKindAsString() : StringRef(); } StringRef Attribute::getValueAsString() const { + if (!pImpl) return StringRef(); assert(isStringAttribute() && "Invalid attribute type to get the value as a string!"); return pImpl ? pImpl->getValueAsString() : StringRef(); @@ -157,6 +162,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "sanitize_address"; if (hasAttribute(Attribute::AlwaysInline)) return "alwaysinline"; + if (hasAttribute(Attribute::Builtin)) + return "builtin"; if (hasAttribute(Attribute::ByVal)) return "byval"; if (hasAttribute(Attribute::InlineHint)) @@ -189,6 +196,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "noreturn"; if (hasAttribute(Attribute::NoUnwind)) return "nounwind"; + if (hasAttribute(Attribute::OptimizeNone)) + return "optnone"; if (hasAttribute(Attribute::OptimizeForSize)) return "optsize"; if (hasAttribute(Attribute::ReadNone)) @@ -217,6 +226,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "uwtable"; if (hasAttribute(Attribute::ZExt)) return "zeroext"; + if (hasAttribute(Attribute::Cold)) + return "cold"; // FIXME: These should be output like this: // @@ -275,35 +286,11 @@ bool Attribute::operator<(Attribute A) const { // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind) - : Context(C), Entry(new EnumAttributeEntry(Kind)) {} - -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind, - unsigned Align) - : Context(C) { - assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) && - "Wrong kind for alignment attribute!"); - Entry = new AlignAttributeEntry(Kind, Align); -} - -AttributeImpl::AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val) - : Context(C), Entry(new StringAttributeEntry(Kind, Val)) {} - -AttributeImpl::~AttributeImpl() { - delete Entry; -} - -bool AttributeImpl::isEnumAttribute() const { - return isa<EnumAttributeEntry>(Entry); -} - -bool AttributeImpl::isAlignAttribute() const { - return isa<AlignAttributeEntry>(Entry); -} - -bool AttributeImpl::isStringAttribute() const { - return isa<StringAttributeEntry>(Entry); -} +// Pin the vtabels to this file. +AttributeImpl::~AttributeImpl() {} +void EnumAttributeImpl::anchor() {} +void AlignAttributeImpl::anchor() {} +void StringAttributeImpl::anchor() {} bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { if (isStringAttribute()) return false; @@ -316,21 +303,23 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { } Attribute::AttrKind AttributeImpl::getKindAsEnum() const { - if (EnumAttributeEntry *E = dyn_cast<EnumAttributeEntry>(Entry)) - return E->getEnumKind(); - return cast<AlignAttributeEntry>(Entry)->getEnumKind(); + assert(isEnumAttribute() || isAlignAttribute()); + return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); } uint64_t AttributeImpl::getValueAsInt() const { - return cast<AlignAttributeEntry>(Entry)->getAlignment(); + assert(isAlignAttribute()); + return static_cast<const AlignAttributeImpl *>(this)->getAlignment(); } StringRef AttributeImpl::getKindAsString() const { - return cast<StringAttributeEntry>(Entry)->getStringKind(); + assert(isStringAttribute()); + return static_cast<const StringAttributeImpl *>(this)->getStringKind(); } StringRef AttributeImpl::getValueAsString() const { - return cast<StringAttributeEntry>(Entry)->getStringValue(); + assert(isStringAttribute()); + return static_cast<const StringAttributeImpl *>(this)->getStringValue(); } bool AttributeImpl::operator<(const AttributeImpl &AI) const { @@ -396,6 +385,9 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { case Attribute::SanitizeMemory: return 1ULL << 37; case Attribute::NoBuiltin: return 1ULL << 38; case Attribute::Returned: return 1ULL << 39; + case Attribute::Cold: return 1ULL << 40; + case Attribute::Builtin: return 1ULL << 41; + case Attribute::OptimizeNone: return 1ULL << 42; } llvm_unreachable("Unsupported attribute type"); } @@ -427,7 +419,10 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, // If we didn't find any existing attributes of the same shape then create a // new one and insert it. if (!PA) { - PA = new AttributeSetNode(SortedAttrs); + // Coallocate entries after the AttributeSetNode itself. + void *Mem = ::operator new(sizeof(AttributeSetNode) + + sizeof(Attribute) * SortedAttrs.size()); + PA = new (Mem) AttributeSetNode(SortedAttrs); pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); } @@ -436,48 +431,42 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, } bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return true; return false; } bool AttributeSetNode::hasAttribute(StringRef Kind) const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return true; return false; } Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return *I; return Attribute(); } Attribute AttributeSetNode::getAttribute(StringRef Kind) const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return *I; return Attribute(); } unsigned AttributeSetNode::getAlignment() const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Attribute::Alignment)) return I->getAlignment(); return 0; } unsigned AttributeSetNode::getStackAlignment() const { - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Attribute::StackAlignment)) return I->getStackAlignment(); return 0; @@ -485,9 +474,8 @@ unsigned AttributeSetNode::getStackAlignment() const { std::string AttributeSetNode::getAsString(bool InAttrGrp) const { std::string Str; - for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) { - if (I != AttrList.begin()) + for (iterator I = begin(), E = end(); I != E; ++I) { + if (I != begin()) Str += ' '; Str += I->getAsString(InAttrGrp); } @@ -501,10 +489,10 @@ std::string AttributeSetNode::getAsString(bool InAttrGrp) const { uint64_t AttributeSetImpl::Raw(unsigned Index) const { for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { if (getSlotIndex(I) != Index) continue; - const AttributeSetNode *ASN = AttrNodes[I].second; + const AttributeSetNode *ASN = getSlotNode(I); uint64_t Mask = 0; - for (AttributeSetNode::const_iterator II = ASN->begin(), + for (AttributeSetNode::iterator II = ASN->begin(), IE = ASN->end(); II != IE; ++II) { Attribute Attr = *II; @@ -527,6 +515,10 @@ uint64_t AttributeSetImpl::Raw(unsigned Index) const { return 0; } +void AttributeSetImpl::dump() const { + AttributeSet(const_cast<AttributeSetImpl *>(this)).dump(); +} + //===----------------------------------------------------------------------===// // AttributeSet Construction and Mutation Methods //===----------------------------------------------------------------------===// @@ -544,7 +536,11 @@ AttributeSet::getImpl(LLVMContext &C, // If we didn't find any existing attributes of the same shape then // create a new one and insert it. if (!PA) { - PA = new AttributeSetImpl(C, Attrs); + // Coallocate entries after the AttributeSetImpl itself. + void *Mem = ::operator new(sizeof(AttributeSetImpl) + + sizeof(std::pair<unsigned, AttributeSetNode *>) * + Attrs.size()); + PA = new (Mem) AttributeSetImpl(C, Attrs); pImpl->AttrsLists.InsertNode(PA, InsertPoint); } @@ -636,12 +632,30 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) { if (Attrs.empty()) return AttributeSet(); + if (Attrs.size() == 1) return Attrs[0]; SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec; - for (unsigned I = 0, E = Attrs.size(); I != E; ++I) { - AttributeSet AS = Attrs[I]; - if (!AS.pImpl) continue; - AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end()); + AttributeSetImpl *A0 = Attrs[0].pImpl; + if (A0) + AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumAttributes())); + // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec + // ordered by index. Because we know that each list in Attrs is ordered by + // index we only need to merge each successive list in rather than doing a + // full sort. + for (unsigned I = 1, E = Attrs.size(); I != E; ++I) { + AttributeSetImpl *AS = Attrs[I].pImpl; + if (!AS) continue; + SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator + ANVI = AttrNodeVec.begin(), ANVE; + for (const AttributeSetImpl::IndexAttrPair + *AI = AS->getNode(0), + *AE = AS->getNode(AS->getNumAttributes()); + AI != AE; ++AI) { + ANVE = AttrNodeVec.end(); + while (ANVI != ANVE && ANVI->first <= AI->first) + ++ANVI; + ANVI = AttrNodeVec.insert(ANVI, *AI) + 1; + } } return getImpl(C, AttrNodeVec); @@ -660,6 +674,13 @@ AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, return addAttributes(C, Index, AttributeSet::get(C, Index, B)); } +AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, + StringRef Kind, StringRef Value) const { + llvm::AttrBuilder B; + B.addAttribute(Kind, Value); + return addAttributes(C, Index, AttributeSet::get(C, Index, B)); +} + AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const { if (!pImpl) return Attrs; @@ -694,7 +715,7 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index, for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) if (Attrs.getSlotIndex(I) == Index) { - for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), + for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I), IE = Attrs.pImpl->end(I); II != IE; ++II) B.addAttribute(*II); break; @@ -815,7 +836,7 @@ bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { if (pImpl == 0) return false; for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + for (AttributeSetImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) if (II->hasAttribute(Attr)) return true; @@ -931,7 +952,7 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index) for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { if (pImpl->getSlotIndex(I) != Index) continue; - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + for (AttributeSetImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) addAttribute(*II); @@ -1151,6 +1172,8 @@ AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { .addAttribute(Attribute::Nest) .addAttribute(Attribute::NoAlias) .addAttribute(Attribute::NoCapture) + .addAttribute(Attribute::ReadNone) + .addAttribute(Attribute::ReadOnly) .addAttribute(Attribute::StructRet); return AttributeSet::get(Ty->getContext(), Index, Incompatible); diff --git a/contrib/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm/lib/IR/AutoUpgrade.cpp index f237537..d12bf7b 100644 --- a/contrib/llvm/lib/IR/AutoUpgrade.cpp +++ b/contrib/llvm/lib/IR/AutoUpgrade.cpp @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file implements the auto-upgrade helper functions +// This file implements the auto-upgrade helper functions // //===----------------------------------------------------------------------===// #include "llvm/AutoUpgrade.h" +#include "llvm/DebugInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -55,14 +56,14 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { case 'a': { if (Name.startswith("arm.neon.vclz")) { Type* args[2] = { - F->arg_begin()->getType(), + F->arg_begin()->getType(), Type::getInt1Ty(F->getContext()) }; // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to // the end of the name. Change name from llvm.arm.neon.vclz.* to // llvm.ctlz.* FunctionType* fType = FunctionType::get(F->getReturnType(), args, false); - NewFn = Function::Create(fType, F->getLinkage(), + NewFn = Function::Create(fType, F->getLinkage(), "llvm.ctlz." + Name.substr(14), F->getParent()); return true; } @@ -88,6 +89,20 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; } + case 'o': + // We only need to change the name to match the mangling including the + // address space. + if (F->arg_size() == 2 && Name.startswith("objectsize.")) { + Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() }; + if (F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) { + F->setName(Name + ".old"); + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::objectsize, Tys); + return true; + } + } + break; + case 'x': { if (Name.startswith("x86.sse2.pcmpeq.") || Name.startswith("x86.sse2.pcmpgt.") || @@ -97,6 +112,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name == "x86.avx.movnt.dq.256" || Name == "x86.avx.movnt.pd.256" || Name == "x86.avx.movnt.ps.256" || + Name == "x86.sse42.crc32.64.8" || (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) { NewFn = 0; return true; @@ -257,6 +273,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID); Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0), CI->getArgOperand(1), Builder.getInt8(Imm)); + } else if (Name == "llvm.x86.sse42.crc32.64.8") { + Function *CRC32 = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::x86_sse42_crc32_32_8); + Value *Trunc0 = Builder.CreateTrunc(CI->getArgOperand(0), Type::getInt32Ty(C)); + Rep = Builder.CreateCall2(CRC32, Trunc0, CI->getArgOperand(1)); + Rep = Builder.CreateZExt(Rep, CI->getType(), ""); } else { bool PD128 = false, PD256 = false, PS128 = false, PS256 = false; if (Name == "llvm.x86.avx.vpermil.pd.256") @@ -317,6 +339,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); return; + case Intrinsic::objectsize: + CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, + CI->getArgOperand(0), + CI->getArgOperand(1), + Name)); + CI->eraseFromParent(); + return; + case Intrinsic::arm_neon_vclz: { // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.* CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0), @@ -369,8 +399,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { } } -// This tests each Function to determine if it needs upgrading. When we find -// one we are interested in, we then upgrade all calls to reflect the new +// This tests each Function to determine if it needs upgrading. When we find +// one we are interested in, we then upgrade all calls to reflect the new // function. void llvm::UpgradeCallsToIntrinsic(Function* F) { assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); @@ -391,3 +421,81 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { } } +void llvm::UpgradeInstWithTBAATag(Instruction *I) { + MDNode *MD = I->getMetadata(LLVMContext::MD_tbaa); + assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag"); + // Check if the tag uses struct-path aware TBAA format. + if (isa<MDNode>(MD->getOperand(0)) && MD->getNumOperands() >= 3) + return; + + if (MD->getNumOperands() == 3) { + Value *Elts[] = { + MD->getOperand(0), + MD->getOperand(1) + }; + MDNode *ScalarType = MDNode::get(I->getContext(), Elts); + // Create a MDNode <ScalarType, ScalarType, offset 0, const> + Value *Elts2[] = { + ScalarType, ScalarType, + Constant::getNullValue(Type::getInt64Ty(I->getContext())), + MD->getOperand(2) + }; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2)); + } else { + // Create a MDNode <MD, MD, offset 0> + Value *Elts[] = {MD, MD, + Constant::getNullValue(Type::getInt64Ty(I->getContext()))}; + I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts)); + } +} + +Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, + Instruction *&Temp) { + if (Opc != Instruction::BitCast) + return 0; + + Temp = 0; + Type *SrcTy = V->getType(); + if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) { + LLVMContext &Context = V->getContext(); + + // We have no information about target data layout, so we assume that + // the maximum pointer size is 64bit. + Type *MidTy = Type::getInt64Ty(Context); + Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy); + + return CastInst::Create(Instruction::IntToPtr, Temp, DestTy); + } + + return 0; +} + +Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { + if (Opc != Instruction::BitCast) + return 0; + + Type *SrcTy = C->getType(); + if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) { + LLVMContext &Context = C->getContext(); + + // We have no information about target data layout, so we assume that + // the maximum pointer size is 64bit. + Type *MidTy = Type::getInt64Ty(Context); + + return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy), + DestTy); + } + + return 0; +} + +/// Check the debug info version number, if it is out-dated, drop the debug +/// info. Return true if module is modified. +bool llvm::UpgradeDebugInfo(Module &M) { + if (getDebugMetadataVersionFromModule(M) == DEBUG_METADATA_VERSION) + return false; + + return StripDebugInfo(M); +} diff --git a/contrib/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm/lib/IR/ConstantFold.cpp index bf93d4f..f5e225c 100644 --- a/contrib/llvm/lib/IR/ConstantFold.cpp +++ b/contrib/llvm/lib/IR/ConstantFold.cpp @@ -75,7 +75,7 @@ static unsigned foldConstantCastPair( unsigned opc, ///< opcode of the second cast constant expression ConstantExpr *Op, ///< the first cast constant expression - Type *DstTy ///< desintation type of the first cast + Type *DstTy ///< destination type of the first cast ) { assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!"); assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type"); @@ -87,13 +87,14 @@ foldConstantCastPair( Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode()); Instruction::CastOps secondOp = Instruction::CastOps(opc); - // Assume that pointers are never more than 64 bits wide. + // Assume that pointers are never more than 64 bits wide, and only use this + // for the middle type. Otherwise we could end up folding away illegal + // bitcasts between address spaces with different sizes. IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext()); // Let CastInst::isEliminableCastPair do the heavy lifting. return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, - FakeIntPtrTy, FakeIntPtrTy, - FakeIntPtrTy); + 0, FakeIntPtrTy, 0); } static Constant *FoldBitCast(Constant *V, Type *DestTy) { @@ -688,6 +689,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, } case Instruction::BitCast: return FoldBitCast(V, DestTy); + case Instruction::AddrSpaceCast: + return 0; } } @@ -1857,9 +1860,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, if (CE1Inverse == CE1Op0) { // Check whether we can safely truncate the right hand side. Constant *C2Inverse = ConstantExpr::getTrunc(C2, CE1Op0->getType()); - if (ConstantExpr::getZExt(C2Inverse, C2->getType()) == C2) { + if (ConstantExpr::getCast(CE1->getOpcode(), C2Inverse, + C2->getType()) == C2) return ConstantExpr::getICmp(pred, CE1Inverse, C2Inverse); - } } } } @@ -1896,6 +1899,37 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) { return true; } +/// \brief Test whether a given ConstantInt is in-range for a SequentialType. +static bool isIndexInRangeOfSequentialType(const SequentialType *STy, + const ConstantInt *CI) { + if (const PointerType *PTy = dyn_cast<PointerType>(STy)) + // Only handle pointers to sized types, not pointers to functions. + return PTy->getElementType()->isSized(); + + uint64_t NumElements = 0; + // Determine the number of elements in our sequential type. + if (const ArrayType *ATy = dyn_cast<ArrayType>(STy)) + NumElements = ATy->getNumElements(); + else if (const VectorType *VTy = dyn_cast<VectorType>(STy)) + NumElements = VTy->getNumElements(); + + assert((isa<ArrayType>(STy) || NumElements > 0) && + "didn't expect non-array type to have zero elements!"); + + // We cannot bounds check the index if it doesn't fit in an int64_t. + if (CI->getValue().getActiveBits() > 64) + return false; + + // A negative index or an index past the end of our sequential type is + // considered out-of-range. + int64_t IndexVal = CI->getSExtValue(); + if (IndexVal < 0 || (NumElements > 0 && (uint64_t)IndexVal >= NumElements)) + return false; + + // Otherwise, it is in-range. + return true; +} + template<typename IndexTy> static Constant *ConstantFoldGetElementPtrImpl(Constant *C, bool inBounds, @@ -1939,7 +1973,32 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, I != E; ++I) LastTy = *I; - if ((LastTy && isa<SequentialType>(LastTy)) || Idx0->isNullValue()) { + // We cannot combine indices if doing so would take us outside of an + // array or vector. Doing otherwise could trick us if we evaluated such a + // GEP as part of a load. + // + // e.g. Consider if the original GEP was: + // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c, + // i32 0, i32 0, i64 0) + // + // If we then tried to offset it by '8' to get to the third element, + // an i8, we should *not* get: + // i8* getelementptr ({ [2 x i8], i32, i8, [3 x i8] }* @main.c, + // i32 0, i32 0, i64 8) + // + // This GEP tries to index array element '8 which runs out-of-bounds. + // Subsequent evaluation would get confused and produce erroneous results. + // + // The following prohibits such a GEP from being formed by checking to see + // if the index is in-range with respect to an array or vector. + bool PerformFold = false; + if (Idx0->isNullValue()) + PerformFold = true; + else if (SequentialType *STy = dyn_cast_or_null<SequentialType>(LastTy)) + if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0)) + PerformFold = isIndexInRangeOfSequentialType(STy, CI); + + if (PerformFold) { SmallVector<Value*, 16> NewIndices; NewIndices.reserve(Idxs.size() + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) @@ -1999,8 +2058,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, } // Check to see if any array indices are not within the corresponding - // notional array bounds. If so, try to determine if they can be factored - // out into preceding dimensions. + // notional array or vector bounds. If so, try to determine if they can be + // factored out into preceding dimensions. bool Unknown = false; SmallVector<Constant *, 8> NewIdxs; Type *Ty = C->getType(); @@ -2008,16 +2067,20 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, for (unsigned i = 0, e = Idxs.size(); i != e; Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) { if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) { - if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) - if (ATy->getNumElements() <= INT64_MAX && - ATy->getNumElements() != 0 && - CI->getSExtValue() >= (int64_t)ATy->getNumElements()) { + if (isa<ArrayType>(Ty) || isa<VectorType>(Ty)) + if (CI->getSExtValue() > 0 && + !isIndexInRangeOfSequentialType(cast<SequentialType>(Ty), CI)) { if (isa<SequentialType>(Prev)) { // It's out of range, but we can factor it into the prior // dimension. NewIdxs.resize(Idxs.size()); - ConstantInt *Factor = ConstantInt::get(CI->getType(), - ATy->getNumElements()); + uint64_t NumElements = 0; + if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) + NumElements = ATy->getNumElements(); + else + NumElements = cast<VectorType>(Ty)->getNumElements(); + + ConstantInt *Factor = ConstantInt::get(CI->getType(), NumElements); NewIdxs[i] = ConstantExpr::getSRem(CI, Factor); Constant *PrevIdx = cast<Constant>(Idxs[i-1]); diff --git a/contrib/llvm/lib/IR/Constants.cpp b/contrib/llvm/lib/IR/Constants.cpp index 2c6971c..690ac59 100644 --- a/contrib/llvm/lib/IR/Constants.cpp +++ b/contrib/llvm/lib/IR/Constants.cpp @@ -483,8 +483,8 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { // Get the corresponding integer type for the bit width of the value. IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); // get an existing value or the insertion position - DenseMapAPIntKeyInfo::KeyTy Key(V, ITy); - ConstantInt *&Slot = Context.pImpl->IntConstants[Key]; + LLVMContextImpl *pImpl = Context.pImpl; + ConstantInt *&Slot = pImpl->IntConstants[DenseMapAPIntKeyInfo::KeyTy(V, ITy)]; if (!Slot) Slot = new ConstantInt(ITy, V); return Slot; } @@ -608,11 +608,9 @@ Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { // ConstantFP accessors. ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { - DenseMapAPFloatKeyInfo::KeyTy Key(V); - LLVMContextImpl* pImpl = Context.pImpl; - ConstantFP *&Slot = pImpl->FPConstants[Key]; + ConstantFP *&Slot = pImpl->FPConstants[DenseMapAPFloatKeyInfo::KeyTy(V)]; if (!Slot) { Type *Ty; @@ -1128,6 +1126,7 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: + case Instruction::AddrSpaceCast: return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); @@ -1391,7 +1390,7 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { BasicBlock *NewBB = getBasicBlock(); if (U == &Op<0>()) - NewF = cast<Function>(To); + NewF = cast<Function>(To->stripPointerCasts()); else NewBB = cast<BasicBlock>(To); @@ -1463,6 +1462,7 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) { case Instruction::PtrToInt: return getPtrToInt(C, Ty); case Instruction::IntToPtr: return getIntToPtr(C, Ty); case Instruction::BitCast: return getBitCast(C, Ty); + case Instruction::AddrSpaceCast: return getAddrSpaceCast(C, Ty); } } @@ -1491,10 +1491,26 @@ Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { if (Ty->isIntOrIntVectorTy()) return getPtrToInt(S, Ty); + + unsigned SrcAS = S->getType()->getPointerAddressSpace(); + if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + + return getBitCast(S, Ty); +} + +Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S, + Type *Ty) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + return getBitCast(S, Ty); } -Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, +Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid cast"); @@ -1664,6 +1680,13 @@ Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) { return getFoldedCast(Instruction::BitCast, C, DstTy); } +Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) { + assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) && + "Invalid constantexpr addrspacecast!"); + + return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy); +} + Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags) { // Check the operands for consistency first. @@ -1956,14 +1979,22 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, ArrayRef<unsigned> Idxs) { + assert(Agg->getType()->isFirstClassType() && + "Non-first-class type for constant insertvalue expression"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == Val->getType() && "insertvalue indices invalid!"); - assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant insertvalue expression"); - Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs); - assert(FC && "insertvalue constant expr couldn't be folded!"); - return FC; + Type *ReqTy = Val->getType(); + + if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs)) + return FC; + + Constant *ArgVec[] = { Agg, Val }; + const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs); + + LLVMContextImpl *pImpl = Agg->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getExtractValue(Constant *Agg, @@ -1977,9 +2008,14 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, assert(Agg->getType()->isFirstClassType() && "Non-first-class type for constant extractvalue expression"); - Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs); - assert(FC && "ExtractValue constant expr couldn't be folded!"); - return FC; + if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs)) + return FC; + + Constant *ArgVec[] = { Agg }; + const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs); + + LLVMContextImpl *pImpl = Agg->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { diff --git a/contrib/llvm/lib/IR/Core.cpp b/contrib/llvm/lib/IR/Core.cpp index 889d574..c70f459 100644 --- a/contrib/llvm/lib/IR/Core.cpp +++ b/contrib/llvm/lib/IR/Core.cpp @@ -58,6 +58,10 @@ void LLVMShutdown() { /*===-- Error handling ----------------------------------------------------===*/ +char *LLVMCreateMessage(const char *Message) { + return strdup(Message); +} + void LLVMDisposeMessage(char *Message) { free(Message); } @@ -93,7 +97,7 @@ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { return wrap(new Module(ModuleID, getGlobalContext())); } -LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, +LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, LLVMContextRef C) { return wrap(new Module(ModuleID, *unwrap(C))); } @@ -143,6 +147,16 @@ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, return false; } +char *LLVMPrintModuleToString(LLVMModuleRef M) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(M)->print(os, NULL); + os.flush(); + + return strdup(buf.c_str()); +} + /*--.. Operations on inline assembler ......................................--*/ void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) { unwrap(M)->setModuleInlineAsm(StringRef(Asm)); @@ -206,6 +220,20 @@ LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) { return wrap(&unwrap(Ty)->getContext()); } +void LLVMDumpType(LLVMTypeRef Ty) { + return unwrap(Ty)->dump(); +} + +char *LLVMPrintTypeToString(LLVMTypeRef Ty) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(Ty)->print(os); + os.flush(); + + return strdup(buf.c_str()); +} + /*--.. Operations on integer types .........................................--*/ LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) { @@ -446,6 +474,16 @@ void LLVMDumpValue(LLVMValueRef Val) { unwrap(Val)->dump(); } +char* LLVMPrintValueToString(LLVMValueRef Val) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(Val)->print(os); + os.flush(); + + return strdup(buf.c_str()); +} + void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); } @@ -677,7 +715,7 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), DontNullTerminate == 0)); } -LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, +LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { Constant **Elements = unwrap<Constant>(ConstantVals, Count); @@ -995,6 +1033,12 @@ LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { unwrap(ToType))); } +LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getAddrSpaceCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal), @@ -1106,8 +1150,6 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { return LLVMLinkOnceAnyLinkage; case GlobalValue::LinkOnceODRLinkage: return LLVMLinkOnceODRLinkage; - case GlobalValue::LinkOnceODRAutoHideLinkage: - return LLVMLinkOnceODRAutoHideLinkage; case GlobalValue::WeakAnyLinkage: return LLVMWeakAnyLinkage; case GlobalValue::WeakODRLinkage: @@ -1152,7 +1194,8 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { GV->setLinkage(GlobalValue::LinkOnceODRLinkage); break; case LLVMLinkOnceODRAutoHideLinkage: - GV->setLinkage(GlobalValue::LinkOnceODRAutoHideLinkage); + DEBUG(errs() << "LLVMSetLinkage(): LLVMLinkOnceODRAutoHideLinkage is no " + "longer supported."); break; case LLVMWeakAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); @@ -1212,12 +1255,30 @@ void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { ->setVisibility(static_cast<GlobalValue::VisibilityTypes>(Viz)); } -unsigned LLVMGetAlignment(LLVMValueRef Global) { - return unwrap<GlobalValue>(Global)->getAlignment(); +/*--.. Operations on global variables, load and store instructions .........--*/ + +unsigned LLVMGetAlignment(LLVMValueRef V) { + Value *P = unwrap<Value>(V); + if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + return GV->getAlignment(); + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->getAlignment(); + if (StoreInst *SI = dyn_cast<StoreInst>(P)) + return SI->getAlignment(); + + llvm_unreachable("only GlobalValue, LoadInst and StoreInst have alignment"); } -void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes) { - unwrap<GlobalValue>(Global)->setAlignment(Bytes); +void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { + Value *P = unwrap<Value>(V); + if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + GV->setAlignment(Bytes); + else if (LoadInst *LI = dyn_cast<LoadInst>(P)) + LI->setAlignment(Bytes); + else if (StoreInst *SI = dyn_cast<StoreInst>(P)) + SI->setAlignment(Bytes); + else + llvm_unreachable("only GlobalValue, LoadInst and StoreInst have alignment"); } /*--.. Operations on global variables ......................................--*/ @@ -1549,7 +1610,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) { return (LLVMAttribute)A->getParent()->getAttributes(). Raw(A->getArgNo()+1); } - + void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { Argument *A = unwrap<Argument>(Arg); @@ -1741,7 +1802,7 @@ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { llvm_unreachable("LLVMSetInstructionCallConv applies only to call and invoke!"); } -void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, +void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute PA) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B(PA); @@ -1751,7 +1812,7 @@ void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, index, B))); } -void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, +void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute PA) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B(PA); @@ -1761,7 +1822,7 @@ void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, index, B))); } -void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, +void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned align) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B; @@ -2115,8 +2176,8 @@ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); - Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), - ITy, unwrap(Ty), AllocSize, + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, 0, 0, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } @@ -2126,8 +2187,8 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); - Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), - ITy, unwrap(Ty), AllocSize, + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, unwrap(Val), 0, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } @@ -2153,7 +2214,7 @@ LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); } -LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, +LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, LLVMValueRef PointerVal) { return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); } @@ -2263,6 +2324,11 @@ LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); } +LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name)); +} + LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy), @@ -2392,9 +2458,9 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name)); } -LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, - LLVMValueRef PTR, LLVMValueRef Val, - LLVMAtomicOrdering ordering, +LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, + LLVMValueRef PTR, LLVMValueRef Val, + LLVMAtomicOrdering ordering, LLVMBool singleThread) { AtomicRMWInst::BinOp intop; switch (op) { @@ -2417,14 +2483,14 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, case LLVMAtomicOrderingMonotonic: intordering = Monotonic; break; case LLVMAtomicOrderingAcquire: intordering = Acquire; break; case LLVMAtomicOrderingRelease: intordering = Release; break; - case LLVMAtomicOrderingAcquireRelease: - intordering = AcquireRelease; + case LLVMAtomicOrderingAcquireRelease: + intordering = AcquireRelease; break; - case LLVMAtomicOrderingSequentiallyConsistent: - intordering = SequentiallyConsistent; + case LLVMAtomicOrderingSequentiallyConsistent: + intordering = SequentiallyConsistent; break; } - return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), + return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), intordering, singleThread ? SingleThread : CrossThread)); } diff --git a/contrib/llvm/lib/IR/DIBuilder.cpp b/contrib/llvm/lib/IR/DIBuilder.cpp index 0980e80..c4a9f41 100644 --- a/contrib/llvm/lib/IR/DIBuilder.cpp +++ b/contrib/llvm/lib/IR/DIBuilder.cpp @@ -30,17 +30,24 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { } DIBuilder::DIBuilder(Module &m) - : M(m), VMContext(M.getContext()), TheCU(0), TempEnumTypes(0), - TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0), - ValueFn(0) -{} + : M(m), VMContext(M.getContext()), TempEnumTypes(0), TempRetainTypes(0), + TempSubprograms(0), TempGVs(0), DeclareFn(0), ValueFn(0) {} /// finalize - Construct any deferred debug info descriptors. void DIBuilder::finalize() { DIArray Enums = getOrCreateArray(AllEnumTypes); DIType(TempEnumTypes).replaceAllUsesWith(Enums); - DIArray RetainTypes = getOrCreateArray(AllRetainTypes); + SmallVector<Value *, 16> RetainValues; + // Declarations and definitions of the same type may be retained. Some + // clients RAUW these pairs, leaving duplicates in the retained types + // list. Use a set to remove the duplicates while we transform the + // TrackingVHs back into Values. + SmallPtrSet<Value *, 16> RetainSet; + for (unsigned I = 0, E = AllRetainTypes.size(); I < E; I++) + if (RetainSet.insert(AllRetainTypes[I])) + RetainValues.push_back(AllRetainTypes[I]); + DIArray RetainTypes = getOrCreateArray(RetainValues); DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes); DIArray SPs = getOrCreateArray(AllSubprograms); @@ -79,17 +86,18 @@ static MDNode *createFilePathPair(LLVMContext &VMContext, StringRef Filename, assert(!Filename.empty() && "Unable to create file without name"); Value *Pair[] = { MDString::get(VMContext, Filename), - MDString::get(VMContext, Directory), + MDString::get(VMContext, Directory) }; return MDNode::get(VMContext, Pair); } /// createCompileUnit - A CompileUnit provides an anchor for all debugging /// information generated during this instance of compilation. -void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, - StringRef Directory, StringRef Producer, - bool isOptimized, StringRef Flags, - unsigned RunTimeVer, StringRef SplitName) { +DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, + StringRef Directory, + StringRef Producer, bool isOptimized, + StringRef Flags, unsigned RunTimeVer, + StringRef SplitName) { assert(((Lang <= dwarf::DW_LANG_Python && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && "Invalid Language tag"); @@ -121,23 +129,70 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, TempImportedModules, MDString::get(VMContext, SplitName) }; - TheCU = DICompileUnit(MDNode::get(VMContext, Elts)); + + MDNode *CUNode = MDNode::get(VMContext, Elts); // Create a named metadata so that it is easier to find cu in a module. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); - NMD->addOperand(TheCU); + NMD->addOperand(CUNode); + + return DICompileUnit(CUNode); +} + +static DIImportedEntity +createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, + unsigned Line, StringRef Name, + SmallVectorImpl<Value *> &AllImportedModules) { + const MDNode *R; + if (Name.empty()) { + Value *Elts[] = { + GetTagConstant(C, dwarf::DW_TAG_imported_module), + Context, + NS, + ConstantInt::get(Type::getInt32Ty(C), Line), + }; + R = MDNode::get(C, Elts); + } else { + Value *Elts[] = { + GetTagConstant(C, dwarf::DW_TAG_imported_module), + Context, + NS, + ConstantInt::get(Type::getInt32Ty(C), Line), + MDString::get(C, Name) + }; + R = MDNode::get(C, Elts); + } + DIImportedEntity M(R); + assert(M.Verify() && "Imported module should be valid"); + AllImportedModules.push_back(M); + return M; } -DIImportedModule DIBuilder::createImportedModule(DIScope Context, - DINameSpace NS, - unsigned Line) { +DIImportedEntity DIBuilder::createImportedModule(DIScope Context, + DINameSpace NS, unsigned Line, + StringRef Name) { + return ::createImportedModule(VMContext, Context, NS, Line, Name, + AllImportedModules); +} + +DIImportedEntity DIBuilder::createImportedModule(DIScope Context, + DIImportedEntity NS, + unsigned Line, + StringRef Name) { + return ::createImportedModule(VMContext, Context, NS, Line, Name, + AllImportedModules); +} + +DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, + DIDescriptor Decl, + unsigned Line) { Value *Elts[] = { - GetTagConstant(VMContext, dwarf::DW_TAG_imported_module), + GetTagConstant(VMContext, dwarf::DW_TAG_imported_declaration), Context, - NS, + Decl, ConstantInt::get(Type::getInt32Ty(VMContext), Line), }; - DIImportedModule M(MDNode::get(VMContext, Elts)); + DIImportedEntity M(MDNode::get(VMContext, Elts)); assert(M.Verify() && "Imported module should be valid"); AllImportedModules.push_back(M); return M; @@ -154,7 +209,7 @@ DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { } /// createEnumerator - Create a single enumerator value. -DIEnumerator DIBuilder::createEnumerator(StringRef Name, uint64_t Val) { +DIEnumerator DIBuilder::createEnumerator(StringRef Name, int64_t Val) { assert(!Name.empty() && "Unable to create enumerator without name"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumerator), @@ -164,15 +219,15 @@ DIEnumerator DIBuilder::createEnumerator(StringRef Name, uint64_t Val) { return DIEnumerator(MDNode::get(VMContext, Elts)); } -/// createNullPtrType - Create C++0x nullptr type. -DIType DIBuilder::createNullPtrType(StringRef Name) { +/// \brief Create a DWARF unspecified type. +DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) { assert(!Name.empty() && "Unable to create type without name"); - // nullptr is encoded in DIBasicType format. Line number, filename, - // ,size, alignment, offset and flags are always empty here. + // Unspecified types are encoded in DIBasicType format. Line number, filename, + // size, alignment, offset and flags are always empty here. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_type), NULL, // Filename - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size @@ -181,7 +236,12 @@ DIType DIBuilder::createNullPtrType(StringRef Name) { ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags; ConstantInt::get(Type::getInt32Ty(VMContext), 0) // Encoding }; - return DIType(MDNode::get(VMContext, Elts)); + return DIBasicType(MDNode::get(VMContext, Elts)); +} + +/// \brief Create C++11 nullptr type. +DIBasicType DIBuilder::createNullPtrType() { + return createUnspecifiedType("decltype(nullptr)"); } /// createBasicType - Create debugging information entry for a basic @@ -195,7 +255,7 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_base_type), NULL, // File/directory name - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), @@ -214,14 +274,14 @@ DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { Value *Elts[] = { GetTagConstant(VMContext, Tag), NULL, // Filename - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, StringRef()), // Empty name. ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - FromTy + FromTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -234,14 +294,14 @@ DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type), NULL, // Filename - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - PointeeTy + PointeeTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -252,15 +312,15 @@ DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_ptr_to_member_type), NULL, // Filename - NULL, //TheCU, + NULL, // Unused NULL, ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - PointeeTy, - Base + PointeeTy.getRef(), + Base.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -268,7 +328,7 @@ DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, /// createReferenceType - Create debugging information entry for a reference /// type. DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { - assert(RTy.Verify() && "Unable to create reference type"); + assert(RTy.isType() && "Unable to create reference type"); // References are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, Tag), @@ -280,7 +340,7 @@ DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - RTy + RTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -289,117 +349,120 @@ DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, unsigned LineNo, DIDescriptor Context) { // typedefs are encoded in DIDerivedType format. - assert(Ty.Verify() && "Invalid typedef type!"); + assert(Ty.isType() && "Invalid typedef type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - Ty + Ty.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createFriend - Create debugging information entry for a 'friend'. -DIType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { +DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { // typedefs are encoded in DIDerivedType format. - assert(Ty.Verify() && "Invalid type!"); - assert(FriendTy.Verify() && "Invalid friend type!"); + assert(Ty.isType() && "Invalid type!"); + assert(FriendTy.isType() && "Invalid friend type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_friend), NULL, - Ty, + Ty.getRef(), NULL, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags - FriendTy + FriendTy.getRef() }; - return DIType(MDNode::get(VMContext, Elts)); + return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createInheritance - Create debugging information entry to establish /// inheritance relationship between two types. -DIDerivedType DIBuilder::createInheritance( - DIType Ty, DIType BaseTy, uint64_t BaseOffset, unsigned Flags) { - assert(Ty.Verify() && "Unable to create inheritance"); +DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, + uint64_t BaseOffset, + unsigned Flags) { + assert(Ty.isType() && "Unable to create inheritance"); // TAG_inheritance is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_inheritance), NULL, - Ty, + Ty.getRef(), NULL, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - BaseTy + BaseTy.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createMemberType - Create debugging information entry for a member. -DIDerivedType DIBuilder::createMemberType( - DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, DIType Ty) { +DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - Ty + Ty.getRef() }; return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createStaticMemberType - Create debugging information entry for a /// C++ static data member. -DIType DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, - DIFile File, unsigned LineNumber, - DIType Ty, unsigned Flags, - llvm::Value *Val) { +DIDerivedType +DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + DIType Ty, unsigned Flags, + llvm::Value *Val) { // TAG_member is encoded in DIDerivedType format. Flags |= DIDescriptor::FlagStaticMember; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*SizeInBits*/), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*AlignInBits*/), - ConstantInt::get(Type::getInt64Ty(VMContext), 0/*OffsetInBits*/), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - Ty, + Ty.getRef(), Val }; - return DIType(MDNode::get(VMContext, Elts)); + return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. -DIType DIBuilder::createObjCIVar(StringRef Name, - DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType Ty, StringRef PropertyName, - StringRef GetterName, StringRef SetterName, - unsigned PropertyAttributes) { +DIDerivedType +DIBuilder::createObjCIVar(StringRef Name, DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, DIType Ty, + StringRef PropertyName, StringRef GetterName, + StringRef SetterName, unsigned PropertyAttributes) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), @@ -417,16 +480,17 @@ DIType DIBuilder::createObjCIVar(StringRef Name, MDString::get(VMContext, SetterName), ConstantInt::get(Type::getInt32Ty(VMContext), PropertyAttributes) }; - return DIType(MDNode::get(VMContext, Elts)); + return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. -DIType DIBuilder::createObjCIVar(StringRef Name, - DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType Ty, MDNode *PropertyNode) { +DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, + unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty, MDNode *PropertyNode) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), @@ -441,17 +505,15 @@ DIType DIBuilder::createObjCIVar(StringRef Name, Ty, PropertyNode }; - return DIType(MDNode::get(VMContext, Elts)); + return DIDerivedType(MDNode::get(VMContext, Elts)); } /// createObjCProperty - Create debugging information entry for Objective-C /// property. -DIObjCProperty DIBuilder::createObjCProperty(StringRef Name, - DIFile File, unsigned LineNumber, - StringRef GetterName, - StringRef SetterName, - unsigned PropertyAttributes, - DIType Ty) { +DIObjCProperty +DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber, + StringRef GetterName, StringRef SetterName, + unsigned PropertyAttributes, DIType Ty) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_APPLE_property), MDString::get(VMContext, Name), @@ -473,9 +535,9 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), - Ty, + Ty.getRef(), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo) @@ -483,19 +545,18 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, return DITemplateTypeParameter(MDNode::get(VMContext, Elts)); } -/// createTemplateValueParameter - Create debugging information for template -/// value parameter. DITemplateValueParameter -DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, - DIType Ty, uint64_t Val, - MDNode *File, unsigned LineNo, +DIBuilder::createTemplateValueParameter(unsigned Tag, DIDescriptor Context, + StringRef Name, DIType Ty, + Value *Val, MDNode *File, + unsigned LineNo, unsigned ColumnNo) { Value *Elts[] = { - GetTagConstant(VMContext, dwarf::DW_TAG_template_value_parameter), - getNonCompileUnitScope(Context), + GetTagConstant(VMContext, Tag), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), - Ty, - ConstantInt::get(Type::getInt64Ty(VMContext), Val), + Ty.getRef(), + Val, File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo) @@ -503,6 +564,38 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, return DITemplateValueParameter(MDNode::get(VMContext, Elts)); } +/// createTemplateValueParameter - Create debugging information for template +/// value parameter. +DITemplateValueParameter +DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, + DIType Ty, Value *Val, + MDNode *File, unsigned LineNo, + unsigned ColumnNo) { + return createTemplateValueParameter(dwarf::DW_TAG_template_value_parameter, + Context, Name, Ty, Val, File, LineNo, + ColumnNo); +} + +DITemplateValueParameter +DIBuilder::createTemplateTemplateParameter(DIDescriptor Context, StringRef Name, + DIType Ty, StringRef Val, + MDNode *File, unsigned LineNo, + unsigned ColumnNo) { + return createTemplateValueParameter( + dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty, + MDString::get(VMContext, Val), File, LineNo, ColumnNo); +} + +DITemplateValueParameter +DIBuilder::createTemplateParameterPack(DIDescriptor Context, StringRef Name, + DIType Ty, DIArray Val, + MDNode *File, unsigned LineNo, + unsigned ColumnNo) { + return createTemplateValueParameter(dwarf::DW_TAG_GNU_template_parameter_pack, + Context, Name, Ty, Val, File, LineNo, + ColumnNo); +} + /// createClassType - Create debugging information entry for a class. DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, @@ -511,29 +604,34 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, - MDNode *VTableHolder, - MDNode *TemplateParams) { - assert((!Context || Context.Verify()) && + DIType VTableHolder, + MDNode *TemplateParams, + StringRef UniqueIdentifier) { + assert((!Context || Context.isScope() || Context.isType()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - DerivedFrom, + DerivedFrom.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - VTableHolder, - TemplateParams + VTableHolder.getRef(), + TemplateParams, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); - assert(R.Verify() && "createClassType should return a verifiable DIType"); + assert(R.isCompositeType() && + "createClassType should return a DICompositeType"); + if (!UniqueIdentifier.empty()) + retainType(R); return R; } @@ -546,26 +644,31 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RunTimeLang, - MDNode *VTableHolder) { + DIType VTableHolder, + StringRef UniqueIdentifier) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_structure_type), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - DerivedFrom, + DerivedFrom.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), - VTableHolder, + VTableHolder.getRef(), NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); - assert(R.Verify() && "createStructType should return a verifiable DIType"); + assert(R.isCompositeType() && + "createStructType should return a DICompositeType"); + if (!UniqueIdentifier.empty()) + retainType(R); return R; } @@ -575,45 +678,52 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIArray Elements, - unsigned RunTimeLang) { + unsigned RunTimeLang, + StringRef UniqueIdentifier) { // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_union_type), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), Flags), NULL, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), - Constant::getNullValue(Type::getInt32Ty(VMContext)), - NULL + NULL, + NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; - return DICompositeType(MDNode::get(VMContext, Elts)); + DICompositeType R(MDNode::get(VMContext, Elts)); + if (!UniqueIdentifier.empty()) + retainType(R); + return R; } /// createSubroutineType - Create subroutine type. -DICompositeType -DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { +DICompositeType DIBuilder::createSubroutineType(DIFile File, + DIArray ParameterTypes) { // TAG_subroutine_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type), Constant::getNullValue(Type::getInt32Ty(VMContext)), - Constant::getNullValue(Type::getInt32Ty(VMContext)), + NULL, MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt64Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags NULL, ParameterTypes, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -623,26 +733,30 @@ DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, - DIType UnderlyingType) { + DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), File.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - UnderlyingType, + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags + UnderlyingType.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; - MDNode *Node = MDNode::get(VMContext, Elts); - AllEnumTypes.push_back(Node); - return DICompositeType(Node); + DICompositeType CTy(MDNode::get(VMContext, Elts)); + AllEnumTypes.push_back(CTy); + if (!UniqueIdentifier.empty()) + retainType(CTy); + return CTy; } /// createArrayType - Create debugging information entry for an array. @@ -652,42 +766,45 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), NULL, // Filename/Directory, - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Ty, + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags + Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } /// createVectorType - Create debugging information entry for a vector. -DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, - DIType Ty, DIArray Subscripts) { - +DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, + DIType Ty, DIArray Subscripts) { // A vector is an array type with the FlagVector flag applied. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), NULL, // Filename/Directory, - NULL, //TheCU, + NULL, // Unused MDString::get(VMContext, ""), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), DIType::FlagVector), - Ty, + Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - Constant::getNullValue(Type::getInt32Ty(VMContext)) + NULL, + NULL, + NULL // Type Identifer }; - return DIType(MDNode::get(VMContext, Elts)); + return DICompositeType(MDNode::get(VMContext, Elts)); } /// createArtificialType - Create a new DIType with "artificial" flag set. @@ -698,17 +815,14 @@ DIType DIBuilder::createArtificialType(DIType Ty) { SmallVector<Value *, 9> Elts; MDNode *N = Ty; assert (N && "Unexpected input DIType!"); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - Elts.push_back(V); - else - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - } + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + Elts.push_back(N->getOperand(i)); unsigned CurFlags = Ty.getFlags(); CurFlags = CurFlags | DIType::FlagArtificial; // Flags are stored at this slot. + // FIXME: Add an enum for this magic value. Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); return DIType(MDNode::get(VMContext, Elts)); @@ -723,17 +837,14 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) { SmallVector<Value *, 9> Elts; MDNode *N = Ty; assert (N && "Unexpected input DIType!"); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) - Elts.push_back(V); - else - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - } + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + Elts.push_back(N->getOperand(i)); unsigned CurFlags = Ty.getFlags(); CurFlags = CurFlags | (DIType::FlagObjectPointer | DIType::FlagArtificial); // Flags are stored at this slot. + // FIXME: Add an enum for this magic value. Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); return DIType(MDNode::get(VMContext, Elts)); @@ -742,7 +853,7 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) { /// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. void DIBuilder::retainType(DIType T) { - AllRetainTypes.push_back(T); + AllRetainTypes.push_back(TrackingVH<MDNode>(T)); } /// createUnspecifiedParameter - Create unspeicified type descriptor @@ -756,31 +867,36 @@ DIDescriptor DIBuilder::createUnspecifiedParameter() { /// createForwardDecl - Create a temporary forward-declared type that /// can be RAUW'd if the full type is seen. -DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, - DIDescriptor Scope, DIFile F, - unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, - uint64_t AlignInBits) { +DICompositeType +DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, + DIFile F, unsigned Line, unsigned RuntimeLang, + uint64_t SizeInBits, uint64_t AlignInBits, + StringRef UniqueIdentifier) { // Create a temporary MDNode. Value *Elts[] = { GetTagConstant(VMContext, Tag), F.getFileNode(), - getNonCompileUnitScope(Scope), + DIScope(getNonCompileUnitScope(Scope)).getRef(), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), - ConstantInt::get(Type::getInt32Ty(VMContext), 0), - ConstantInt::get(Type::getInt32Ty(VMContext), - DIDescriptor::FlagFwdDecl), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), NULL, DIArray(), - ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) + ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang), + NULL, + NULL, //TemplateParams + UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); - assert(DIType(Node).Verify() && - "createForwardDecl result should be verifiable"); - return DIType(Node); + DICompositeType RetTy(Node); + assert(RetTy.isCompositeType() && + "createForwardDecl result should be a DIType"); + if (!UniqueIdentifier.empty()) + retainType(RetTy); + return RetTy; } /// getOrCreateArray - Get a DIArray, create one if required. @@ -805,10 +921,11 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { } /// \brief Create a new descriptor for the specified global. -DIGlobalVariable DIBuilder:: -createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile F, - unsigned LineNumber, DIType Ty, bool isLocalToUnit, - Value *Val) { +DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, + StringRef LinkageName, + DIFile F, unsigned LineNumber, + DIType Ty, bool isLocalToUnit, + Value *Val) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -830,19 +947,22 @@ createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile F, } /// \brief Create a new descriptor for the specified global. -DIGlobalVariable DIBuilder:: -createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, Value *Val) { +DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIFile F, + unsigned LineNumber, DIType Ty, + bool isLocalToUnit, + Value *Val) { return createGlobalVariable(Name, Name, F, LineNumber, Ty, isLocalToUnit, Val); } /// createStaticVariable - Create a new descriptor for the specified static /// variable. -DIGlobalVariable DIBuilder:: -createStaticVariable(DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, Value *Val, MDNode *Decl) { +DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context, + StringRef Name, + StringRef LinkageName, + DIFile F, unsigned LineNumber, + DIType Ty, bool isLocalToUnit, + Value *Val, MDNode *Decl) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -870,9 +990,9 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { DIDescriptor Context(getNonCompileUnitScope(Scope)); - assert((!Context || Context.Verify()) && + assert((!Context || Context.isScope()) && "createLocalVariable should be called with a valid Context"); - assert(Ty.Verify() && + assert(Ty.isType() && "createLocalVariable should be called with a valid type"); Value *Elts[] = { GetTagConstant(VMContext, Tag), @@ -893,9 +1013,10 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, Fn); FnLocals->addOperand(Node); } - assert(DIVariable(Node).Verify() && - "createLocalVariable should return a verifiable DIVariable"); - return DIVariable(Node); + DIVariable RetVar(Node); + assert(RetVar.isVariable() && + "createLocalVariable should return a valid DIVariable"); + return RetVar; } /// createComplexVariable - Create a new descriptor for the specified variable @@ -921,22 +1042,38 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, } /// createFunction - Create a new descriptor for the specified function. -DISubprogram DIBuilder::createFunction(DIDescriptor Context, - StringRef Name, - StringRef LinkageName, - DIFile File, unsigned LineNo, - DIType Ty, +/// FIXME: this is added for dragonegg. Once we update dragonegg +/// to call resolve function, this will be removed. +DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name, + StringRef LinkageName, DIFile File, + unsigned LineNo, DICompositeType Ty, + bool isLocalToUnit, bool isDefinition, + unsigned ScopeLine, unsigned Flags, + bool isOptimized, Function *Fn, + MDNode *TParams, MDNode *Decl) { + // dragonegg does not generate identifier for types, so using an empty map + // to resolve the context should be fine. + DITypeIdentifierMap EmptyMap; + return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File, + LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, + Flags, isOptimized, Fn, TParams, Decl); +} + +/// createFunction - Create a new descriptor for the specified function. +DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile File, + unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, - unsigned Flags, bool isOptimized, - Function *Fn, - MDNode *TParams, - MDNode *Decl) { + unsigned ScopeLine, unsigned Flags, + bool isOptimized, Function *Fn, + MDNode *TParams, MDNode *Decl) { + assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && + "function types should be subroutines"); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -961,29 +1098,29 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); - assert(S.Verify() && "createFunction should return a valid DISubprogram"); + assert(S.isSubprogram() && "createFunction should return a valid DISubprogram"); return S; } /// createMethod - Create a new descriptor for the specified C++ method. -DISubprogram DIBuilder::createMethod(DIDescriptor Context, - StringRef Name, - StringRef LinkageName, - DIFile F, - unsigned LineNo, DIType Ty, - bool isLocalToUnit, - bool isDefinition, +DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile F, + unsigned LineNo, DICompositeType Ty, + bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, - MDNode *VTableHolder, - unsigned Flags, - bool isOptimized, - Function *Fn, + DIType VTableHolder, unsigned Flags, + bool isOptimized, Function *Fn, MDNode *TParam) { + assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && + "function types should be subroutines"); + assert(getNonCompileUnitScope(Context) && + "Methods should have both a Context and a context that isn't " + "the compile unit."); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), F.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(Context).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -991,9 +1128,9 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, Ty, ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), - ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK), + ConstantInt::get(Type::getInt32Ty(VMContext), VK), ConstantInt::get(Type::getInt32Ty(VMContext), VIndex), - VTableHolder, + VTableHolder.getRef(), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, @@ -1007,7 +1144,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); - assert(S.Verify() && "createMethod should return a valid DISubprogram"); + assert(S.isSubprogram() && "createMethod should return a valid DISubprogram"); return S; } @@ -1046,7 +1183,7 @@ DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col) { - // Defeat MDNode uniqing for lexical blocks by using unique id. + // Defeat MDNode uniquing for lexical blocks by using unique id. static unsigned int unique_id = 0; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), @@ -1066,7 +1203,8 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, Instruction *InsertBefore) { assert(Storage && "no storage passed to dbg.declare"); - assert(VarInfo.Verify() && "empty DIVariable passed to dbg.declare"); + assert(VarInfo.isVariable() && + "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); @@ -1078,7 +1216,8 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, BasicBlock *InsertAtEnd) { assert(Storage && "no storage passed to dbg.declare"); - assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.declare"); + assert(VarInfo.isVariable() && + "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); @@ -1097,7 +1236,8 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable VarInfo, Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); - assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.value"); + assert(VarInfo.isVariable() && + "empty or invalid DIVariable passed to dbg.value"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); @@ -1112,7 +1252,8 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable VarInfo, BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); - assert(VarInfo.Verify() && "invalid DIVariable passed to dbg.value"); + assert(VarInfo.isVariable() && + "empty or invalid DIVariable passed to dbg.value"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); diff --git a/contrib/llvm/lib/IR/DataLayout.cpp b/contrib/llvm/lib/IR/DataLayout.cpp index 5658f56..6bdc09e 100644 --- a/contrib/llvm/lib/IR/DataLayout.cpp +++ b/contrib/llvm/lib/IR/DataLayout.cpp @@ -200,9 +200,7 @@ static unsigned inBytes(unsigned Bits) { } void DataLayout::parseSpecifier(StringRef Desc) { - while (!Desc.empty()) { - // Split at '-'. std::pair<StringRef, StringRef> Split = split(Desc, '-'); Desc = Split.second; @@ -482,7 +480,7 @@ std::string DataLayout::getStringRepresentation() const { addrSpaces.push_back(pib->first); } std::sort(addrSpaces.begin(), addrSpaces.end()); - for (SmallVector<unsigned, 8>::iterator asb = addrSpaces.begin(), + for (SmallVectorImpl<unsigned>::iterator asb = addrSpaces.begin(), ase = addrSpaces.end(); asb != ase; ++asb) { const PointerAlignElem &PI = Pointers.find(*asb)->second; OS << "-p"; @@ -509,6 +507,15 @@ std::string DataLayout::getStringRepresentation() const { return OS.str(); } +unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const { + assert(Ty->isPtrOrPtrVectorTy() && + "This should only be called with a pointer or pointer vector type"); + + if (Ty->isPointerTy()) + return getTypeSizeInBits(Ty); + + return getTypeSizeInBits(Ty->getScalarType()); +} /*! \param abi_or_pref Flag that determines which alignment is returned. true @@ -582,7 +589,6 @@ unsigned DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const { return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, 0); } - unsigned DataLayout::getCallFrameTypeAlignment(Type *Ty) const { for (unsigned i = 0, e = Alignments.size(); i != e; ++i) if (Alignments[i].AlignType == STACK_ALIGN) @@ -601,16 +607,11 @@ unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const { return Log2_32(Align); } -/// getIntPtrType - Return an integer type with size at least as big as that -/// of a pointer in the given address space. IntegerType *DataLayout::getIntPtrType(LLVMContext &C, unsigned AddressSpace) const { return IntegerType::get(C, getPointerSizeInBits(AddressSpace)); } -/// getIntPtrType - Return an integer (vector of integer) type with size at -/// least as big as that of a pointer of the given pointer (vector of pointer) -/// type. Type *DataLayout::getIntPtrType(Type *Ty) const { assert(Ty->isPtrOrPtrVectorTy() && "Expected a pointer or pointer vector type."); @@ -628,6 +629,13 @@ Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const return 0; } +unsigned DataLayout::getLargestLegalIntTypeSize() const { + unsigned MaxWidth = 0; + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) + MaxWidth = std::max<unsigned>(MaxWidth, LegalIntWidths[i]); + return MaxWidth; +} + uint64_t DataLayout::getIndexedOffset(Type *ptrTy, ArrayRef<Value *> Indices) const { Type *Ty = ptrTy; diff --git a/contrib/llvm/lib/IR/DebugInfo.cpp b/contrib/llvm/lib/IR/DebugInfo.cpp index ec83dca..70a756f 100644 --- a/contrib/llvm/lib/IR/DebugInfo.cpp +++ b/contrib/llvm/lib/IR/DebugInfo.cpp @@ -34,24 +34,6 @@ using namespace llvm::dwarf; // DIDescriptor //===----------------------------------------------------------------------===// -DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DIVariable F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DIType F) : DbgNode(F.DbgNode) { -} - bool DIDescriptor::Verify() const { return DbgNode && (DIDerivedType(DbgNode).Verify() || @@ -65,7 +47,7 @@ bool DIDescriptor::Verify() const { DIObjCProperty(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() || DITemplateValueParameter(DbgNode).Verify() || - DIImportedModule(DbgNode).Verify()); + DIImportedEntity(DbgNode).Verify()); } static Value *getField(const MDNode *DbgNode, unsigned Elt) { @@ -74,10 +56,8 @@ static Value *getField(const MDNode *DbgNode, unsigned Elt) { return DbgNode->getOperand(Elt); } -static const MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) { - if (const MDNode *R = dyn_cast_or_null<MDNode>(getField(DbgNode, Elt))) - return R; - return 0; +static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) { + return dyn_cast_or_null<MDNode>(getField(DbgNode, Elt)); } static StringRef getStringField(const MDNode *DbgNode, unsigned Elt) { @@ -95,8 +75,8 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI - = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) + if (ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) return CI->getZExtValue(); return 0; @@ -107,21 +87,16 @@ int64_t DIDescriptor::getInt64Field(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI - = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) + if (ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt))) return CI->getSExtValue(); return 0; } DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { - if (DbgNode == 0) - return DIDescriptor(); - - if (Elt < DbgNode->getNumOperands()) - return - DIDescriptor(dyn_cast_or_null<const MDNode>(DbgNode->getOperand(Elt))); - return DIDescriptor(); + MDNode *Field = getNodeField(DbgNode, Elt); + return DIDescriptor(Field); } GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { @@ -129,7 +104,7 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); return 0; } @@ -138,7 +113,7 @@ Constant *DIDescriptor::getConstantField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt)); return 0; } @@ -147,7 +122,7 @@ Function *DIDescriptor::getFunctionField(unsigned Elt) const { return 0; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt)); + return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt)); return 0; } @@ -156,19 +131,17 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { return; if (Elt < DbgNode->getNumOperands()) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); Node->replaceOperandWith(Elt, F); } } unsigned DIVariable::getNumAddrElements() const { - return DbgNode->getNumOperands()-8; + return DbgNode->getNumOperands() - 8; } /// getInlinedAt - If this variable is inlined then return inline location. -MDNode *DIVariable::getInlinedAt() const { - return dyn_cast_or_null<MDNode>(DbgNode->getOperand(7)); -} +MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } //===----------------------------------------------------------------------===// // Predicates @@ -177,7 +150,8 @@ MDNode *DIVariable::getInlinedAt() const { /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_base_type: case dwarf::DW_TAG_unspecified_type: @@ -189,7 +163,8 @@ bool DIDescriptor::isBasicType() const { /// isDerivedType - Return true if the specified tag is legal for DIDerivedType. bool DIDescriptor::isDerivedType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_pointer_type: @@ -212,7 +187,8 @@ bool DIDescriptor::isDerivedType() const { /// isCompositeType - Return true if the specified tag is legal for /// DICompositeType. bool DIDescriptor::isCompositeType() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_array_type: case dwarf::DW_TAG_structure_type: @@ -228,7 +204,8 @@ bool DIDescriptor::isCompositeType() const { /// isVariable - Return true if the specified tag is legal for DIVariable. bool DIDescriptor::isVariable() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_auto_variable: case dwarf::DW_TAG_arg_variable: @@ -256,11 +233,6 @@ bool DIDescriptor::isGlobalVariable() const { getTag() == dwarf::DW_TAG_constant); } -/// isGlobal - Return true if the specified tag is legal for DIGlobal. -bool DIDescriptor::isGlobal() const { - return isGlobalVariable(); -} - /// isUnspecifiedParmeter - Return true if the specified tag is /// DW_TAG_unspecified_parameters. bool DIDescriptor::isUnspecifiedParameter() const { @@ -270,17 +242,19 @@ bool DIDescriptor::isUnspecifiedParameter() const { /// isScope - Return true if the specified tag is one of the scope /// related tag. bool DIDescriptor::isScope() const { - if (!DbgNode) return false; + if (!DbgNode) + return false; switch (getTag()) { case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_lexical_block: case dwarf::DW_TAG_subprogram: case dwarf::DW_TAG_namespace: + case dwarf::DW_TAG_file_type: return true; default: break; } - return false; + return isType(); } /// isTemplateTypeParameter - Return true if the specified tag is @@ -292,7 +266,9 @@ bool DIDescriptor::isTemplateTypeParameter() const { /// isTemplateValueParameter - Return true if the specified tag is /// DW_TAG_template_value_parameter. bool DIDescriptor::isTemplateValueParameter() const { - return DbgNode && getTag() == dwarf::DW_TAG_template_value_parameter; + return DbgNode && (getTag() == dwarf::DW_TAG_template_value_parameter || + getTag() == dwarf::DW_TAG_GNU_template_template_param || + getTag() == dwarf::DW_TAG_GNU_template_parameter_pack); } /// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit. @@ -314,13 +290,13 @@ bool DIDescriptor::isNameSpace() const { /// lexical block with an extra file. bool DIDescriptor::isLexicalBlockFile() const { return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() == 3); + (DbgNode->getNumOperands() == 3); } /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() > 3); + (DbgNode->getNumOperands() > 3); } /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. @@ -338,33 +314,28 @@ bool DIDescriptor::isObjCProperty() const { return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property; } -/// \brief Return true if the specified tag is DW_TAG_imported_module. -bool DIDescriptor::isImportedModule() const { - return DbgNode && getTag() == dwarf::DW_TAG_imported_module; +/// \brief Return true if the specified tag is DW_TAG_imported_module or +/// DW_TAG_imported_declaration. +bool DIDescriptor::isImportedEntity() const { + return DbgNode && (getTag() == dwarf::DW_TAG_imported_module || + getTag() == dwarf::DW_TAG_imported_declaration); } //===----------------------------------------------------------------------===// // Simple Descriptor Constructors and other Methods //===----------------------------------------------------------------------===// -DIType::DIType(const MDNode *N) : DIScope(N) { - if (!N) return; - if (!isBasicType() && !isDerivedType() && !isCompositeType()) { - DbgNode = 0; - } -} - unsigned DIArray::getNumElements() const { if (!DbgNode) return 0; return DbgNode->getNumOperands(); } -/// replaceAllUsesWith - Replace all uses of debug info referenced by -/// this descriptor. +/// replaceAllUsesWith - Replace all uses of the MDNode used by this +/// type with the one in the passed descriptor. void DIType::replaceAllUsesWith(DIDescriptor &D) { - if (!DbgNode) - return; + + assert(DbgNode && "Trying to replace an unverified type!"); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something @@ -372,19 +343,19 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) { // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (DbgNode != D) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); const MDNode *DN = D; const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value*>(V)); + Node->replaceAllUsesWith(const_cast<Value *>(V)); MDNode::deleteTemporary(Node); } } -/// replaceAllUsesWith - Replace all uses of debug info referenced by -/// this descriptor. +/// replaceAllUsesWith - Replace all uses of the MDNode used by this +/// type with the one in D. void DIType::replaceAllUsesWith(MDNode *D) { - if (!DbgNode) - return; + + assert(DbgNode && "Trying to replace an unverified type!"); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something @@ -392,39 +363,24 @@ void DIType::replaceAllUsesWith(MDNode *D) { // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (DbgNode != D) { - MDNode *Node = const_cast<MDNode*>(DbgNode); + MDNode *Node = const_cast<MDNode *>(DbgNode); const MDNode *DN = D; const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value*>(V)); + Node->replaceAllUsesWith(const_cast<Value *>(V)); MDNode::deleteTemporary(Node); } } -/// isUnsignedDIType - Return true if type encoding is unsigned. -bool DIType::isUnsignedDIType() { - DIDerivedType DTy(DbgNode); - if (DTy.Verify()) - return DTy.getTypeDerivedFrom().isUnsignedDIType(); - - DIBasicType BTy(DbgNode); - if (BTy.Verify()) { - unsigned Encoding = BTy.getEncoding(); - if (Encoding == dwarf::DW_ATE_unsigned || - Encoding == dwarf::DW_ATE_unsigned_char || - Encoding == dwarf::DW_ATE_boolean) - return true; - } - return false; -} - /// Verify - Verify that a compile unit is well formed. bool DICompileUnit::Verify() const { if (!isCompileUnit()) return false; - StringRef N = getFilename(); - if (N.empty()) + + // Don't bother verifying the compilation directory or producer string + // as those could be empty. + if (getFilename().empty()) return false; - // It is possible that directory and produce string is empty. + return DbgNode->getNumOperands() == 13; } @@ -433,31 +389,85 @@ bool DIObjCProperty::Verify() const { if (!isObjCProperty()) return false; - DIType Ty = getType(); - if (!Ty.Verify()) return false; - // Don't worry about the rest of the strings for now. return DbgNode->getNumOperands() == 8; } +/// Check if a field at position Elt of a MDNode is a MDNode. +/// We currently allow an empty string and an integer. +/// But we don't allow a non-empty string in a MDNode field. +static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { + // FIXME: This function should return true, if the field is null or the field + // is indeed a MDNode: return !Fld || isa<MDNode>(Fld). + Value *Fld = getField(DbgNode, Elt); + if (Fld && isa<MDString>(Fld) && !cast<MDString>(Fld)->getString().empty()) + return false; + return true; +} + +/// Check if a field at position Elt of a MDNode is a MDString. +static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return !Fld || isa<MDString>(Fld); +} + +/// Check if a value can be a reference to a type. +static bool isTypeRef(const Value *Val) { + return !Val || + (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) || + (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType()); +} + +/// Check if a field at position Elt of a MDNode can be a reference to a type. +static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isTypeRef(Fld); +} + +/// Check if a value can be a ScopeRef. +static bool isScopeRef(const Value *Val) { + return !Val || + (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) || + (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope()); +} + +/// Check if a field at position Elt of a MDNode can be a ScopeRef. +static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isScopeRef(Fld); +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!isType()) return false; - if (getContext() && !getContext().Verify()) + // Make sure Context @ field 2 is MDNode. + if (!fieldIsScopeRef(DbgNode, 2)) return false; - unsigned Tag = getTag(); + + // FIXME: Sink this into the various subclass verifies. + uint16_t Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type && Tag != dwarf::DW_TAG_ptr_to_member_type && Tag != dwarf::DW_TAG_reference_type && Tag != dwarf::DW_TAG_rvalue_reference_type && - Tag != dwarf::DW_TAG_restrict_type && - Tag != dwarf::DW_TAG_array_type && + Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_array_type && Tag != dwarf::DW_TAG_enumeration_type && Tag != dwarf::DW_TAG_subroutine_type && + Tag != dwarf::DW_TAG_inheritance && Tag != dwarf::DW_TAG_friend && getFilename().empty()) return false; + // DIType is abstract, it should be a BasicType, a DerivedType or + // a CompositeType. + if (isBasicType()) + DIBasicType(DbgNode).Verify(); + else if (isCompositeType()) + DICompositeType(DbgNode).Verify(); + else if (isDerivedType()) + DIDerivedType(DbgNode).Verify(); + else + return false; return true; } @@ -468,6 +478,14 @@ bool DIBasicType::Verify() const { /// Verify - Verify that a derived type descriptor is well formed. bool DIDerivedType::Verify() const { + // Make sure DerivedFrom @ field 9 is TypeRef. + if (!fieldIsTypeRef(DbgNode, 9)) + return false; + if (getTag() == dwarf::DW_TAG_ptr_to_member_type) + // Make sure ClassType @ field 10 is a TypeRef. + if (!fieldIsTypeRef(DbgNode, 10)) + return false; + return isDerivedType() && DbgNode->getNumOperands() >= 10 && DbgNode->getNumOperands() <= 14; } @@ -476,10 +494,18 @@ bool DIDerivedType::Verify() const { bool DICompositeType::Verify() const { if (!isCompositeType()) return false; - if (getContext() && !getContext().Verify()) + + // Make sure DerivedFrom @ field 9 and ContainingType @ field 12 are TypeRef. + if (!fieldIsTypeRef(DbgNode, 9)) + return false; + if (!fieldIsTypeRef(DbgNode, 12)) + return false; + + // Make sure the type identifier at field 14 is MDString, it can be null. + if (!fieldIsMDString(DbgNode, 14)) return false; - return DbgNode->getNumOperands() >= 10 && DbgNode->getNumOperands() <= 14; + return DbgNode->getNumOperands() == 15; } /// Verify - Verify that a subprogram descriptor is well formed. @@ -487,11 +513,13 @@ bool DISubprogram::Verify() const { if (!isSubprogram()) return false; - if (getContext() && !getContext().Verify()) + // Make sure context @ field 2 is a ScopeRef and type @ field 7 is a MDNode. + if (!fieldIsScopeRef(DbgNode, 2)) return false; - - DICompositeType Ty = getType(); - if (!Ty.Verify()) + if (!fieldIsMDNode(DbgNode, 7)) + return false; + // Containing type @ field 12. + if (!fieldIsTypeRef(DbgNode, 12)) return false; return DbgNode->getNumOperands() == 20; } @@ -503,15 +531,13 @@ bool DIGlobalVariable::Verify() const { if (getDisplayName().empty()) return false; - - if (getContext() && !getContext().Verify()) + // Make sure context @ field 2 and type @ field 8 are MDNodes. + if (!fieldIsMDNode(DbgNode, 2)) return false; - - DIType Ty = getType(); - if (!Ty.Verify()) + if (!fieldIsMDNode(DbgNode, 8)) return false; - - if (!getGlobal() && !getConstant()) + // Make sure StaticDataMemberDeclaration @ field 12 is MDNode. + if (!fieldIsMDNode(DbgNode, 12)) return false; return DbgNode->getNumOperands() == 13; @@ -522,13 +548,11 @@ bool DIVariable::Verify() const { if (!isVariable()) return false; - if (getContext() && !getContext().Verify()) + // Make sure context @ field 1 and type @ field 5 are MDNodes. + if (!fieldIsMDNode(DbgNode, 1)) return false; - - DIType Ty = getType(); - if (!Ty.Verify()) + if (!fieldIsMDNode(DbgNode, 5)) return false; - return DbgNode->getNumOperands() >= 8; } @@ -548,9 +572,7 @@ bool DINameSpace::Verify() const { } /// \brief Retrieve the MDNode for the directory/file pair. -MDNode *DIFile::getFileNode() const { - return const_cast<MDNode*>(getNodeField(DbgNode, 1)); -} +MDNode *DIFile::getFileNode() const { return getNodeField(DbgNode, 1); } /// \brief Verify that the file descriptor is well formed. bool DIFile::Verify() const { @@ -588,62 +610,82 @@ bool DITemplateValueParameter::Verify() const { } /// \brief Verify that the imported module descriptor is well formed. -bool DIImportedModule::Verify() const { - return isImportedModule() && DbgNode->getNumOperands() == 4; +bool DIImportedEntity::Verify() const { + return isImportedEntity() && + (DbgNode->getNumOperands() == 4 || DbgNode->getNumOperands() == 5); } -/// getOriginalTypeSize - If this type is derived from a base type then -/// return base type size. -uint64_t DIDerivedType::getOriginalTypeSize() const { - unsigned Tag = getTag(); - - if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && - Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && - Tag != dwarf::DW_TAG_restrict_type) - return getSizeInBits(); - - DIType BaseType = getTypeDerivedFrom(); - - // If this type is not derived from any type then take conservative approach. - if (!BaseType.isValid()) - return getSizeInBits(); - - // If this is a derived type, go ahead and get the base type, unless it's a - // reference then it's just the size of the field. Pointer types have no need - // of this since they're a different type of qualification on the type. - if (BaseType.getTag() == dwarf::DW_TAG_reference_type || - BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) - return getSizeInBits(); - - if (BaseType.isDerivedType()) - return DIDerivedType(BaseType).getOriginalTypeSize(); +/// getObjCProperty - Return property node, if this ivar is associated with one. +MDNode *DIDerivedType::getObjCProperty() const { + return getNodeField(DbgNode, 10); +} - return BaseType.getSizeInBits(); +MDString *DICompositeType::getIdentifier() const { + return cast_or_null<MDString>(getField(DbgNode, 14)); } -/// getObjCProperty - Return property node, if this ivar is associated with one. -MDNode *DIDerivedType::getObjCProperty() const { - if (DbgNode->getNumOperands() <= 10) - return NULL; - return dyn_cast_or_null<MDNode>(DbgNode->getOperand(10)); +#ifndef NDEBUG +static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { + for (unsigned i = 0; i != LHS->getNumOperands(); ++i) { + // Skip the 'empty' list (that's a single i32 0, rather than truly empty). + if (i == 0 && isa<ConstantInt>(LHS->getOperand(i))) + continue; + const MDNode *E = cast<MDNode>(LHS->getOperand(i)); + bool found = false; + for (unsigned j = 0; !found && j != RHS->getNumOperands(); ++j) + found = E == RHS->getOperand(j); + assert(found && "Losing a member during member list replacement"); + } } +#endif /// \brief Set the array of member DITypes. void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) { - assert((!TParams || DbgNode->getNumOperands() == 14) && + assert((!TParams || DbgNode->getNumOperands() == 15) && "If you're setting the template parameters this should include a slot " "for that!"); TrackingVH<MDNode> N(*this); - N->replaceOperandWith(10, Elements); + if (Elements) { +#ifndef NDEBUG + // Check that the new list of members contains all the old members as well. + if (const MDNode *El = cast_or_null<MDNode>(N->getOperand(10))) + VerifySubsetOf(El, Elements); +#endif + N->replaceOperandWith(10, Elements); + } if (TParams) N->replaceOperandWith(13, TParams); DbgNode = N; } +void DICompositeType::addMember(DIDescriptor D) { + SmallVector<llvm::Value *, 16> M; + DIArray OrigM = getTypeArray(); + unsigned Elements = OrigM.getNumElements(); + if (Elements == 1 && !OrigM.getElement(0)) + Elements = 0; + M.reserve(Elements + 1); + for (unsigned i = 0; i != Elements; ++i) + M.push_back(OrigM.getElement(i)); + M.push_back(D); + setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M))); +} + +/// Generate a reference to this DIType. Uses the type identifier instead +/// of the actual MDNode if possible, to help type uniquing. +DIScopeRef DIScope::getRef() const { + if (!isCompositeType()) + return DIScopeRef(*this); + DICompositeType DTy(DbgNode); + if (!DTy.getIdentifier()) + return DIScopeRef(*this); + return DIScopeRef(DTy.getIdentifier()); +} + /// \brief Set the containing type. void DICompositeType::setContainingType(DICompositeType ContainingType) { TrackingVH<MDNode> N(*this); - N->replaceOperandWith(12, ContainingType); + N->replaceOperandWith(12, ContainingType.getRef()); DbgNode = N; } @@ -673,24 +715,59 @@ bool DISubprogram::describes(const Function *F) { } unsigned DISubprogram::isOptimized() const { - assert (DbgNode && "Invalid subprogram descriptor!"); + assert(DbgNode && "Invalid subprogram descriptor!"); if (DbgNode->getNumOperands() == 15) return getUnsignedField(14); return 0; } MDNode *DISubprogram::getVariablesNodes() const { - if (!DbgNode || DbgNode->getNumOperands() <= 18) - return NULL; - return dyn_cast_or_null<MDNode>(DbgNode->getOperand(18)); + return getNodeField(DbgNode, 18); } DIArray DISubprogram::getVariables() const { - if (!DbgNode || DbgNode->getNumOperands() <= 18) - return DIArray(); - if (MDNode *T = dyn_cast_or_null<MDNode>(DbgNode->getOperand(18))) - return DIArray(T); - return DIArray(); + return DIArray(getNodeField(DbgNode, 18)); +} + +Value *DITemplateValueParameter::getValue() const { + return getField(DbgNode, 4); +} + +// If the current node has a parent scope then return that, +// else return an empty scope. +DIScopeRef DIScope::getContext() const { + + if (isType()) + return DIType(DbgNode).getContext(); + + if (isSubprogram()) + return DIScopeRef(DISubprogram(DbgNode).getContext()); + + if (isLexicalBlock()) + return DIScopeRef(DILexicalBlock(DbgNode).getContext()); + + if (isLexicalBlockFile()) + return DIScopeRef(DILexicalBlockFile(DbgNode).getContext()); + + if (isNameSpace()) + return DIScopeRef(DINameSpace(DbgNode).getContext()); + + assert((isFile() || isCompileUnit()) && "Unhandled type of scope."); + return DIScopeRef(NULL); +} + +// If the scope node has a name, return that, else return an empty string. +StringRef DIScope::getName() const { + if (isType()) + return DIType(DbgNode).getName(); + if (isSubprogram()) + return DISubprogram(DbgNode).getName(); + if (isNameSpace()) + return DINameSpace(DbgNode).getName(); + assert((isLexicalBlock() || isLexicalBlockFile() || isFile() || + isCompileUnit()) && + "Unhandled type of scope."); + return StringRef(); } StringRef DIScope::getFilename() const { @@ -709,54 +786,51 @@ DIArray DICompileUnit::getEnumTypes() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); - if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(7))) - return DIArray(N); - return DIArray(); + return DIArray(getNodeField(DbgNode, 7)); } DIArray DICompileUnit::getRetainedTypes() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); - if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(8))) - return DIArray(N); - return DIArray(); + return DIArray(getNodeField(DbgNode, 8)); } DIArray DICompileUnit::getSubprograms() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); - if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(9))) - return DIArray(N); - return DIArray(); + return DIArray(getNodeField(DbgNode, 9)); } - DIArray DICompileUnit::getGlobalVariables() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); - if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(10))) - return DIArray(N); - return DIArray(); + return DIArray(getNodeField(DbgNode, 10)); } -DIArray DICompileUnit::getImportedModules() const { +DIArray DICompileUnit::getImportedEntities() const { if (!DbgNode || DbgNode->getNumOperands() < 13) return DIArray(); - if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(11))) - return DIArray(N); - return DIArray(); + return DIArray(getNodeField(DbgNode, 11)); } -/// fixupObjcLikeName - Replace contains special characters used +/// fixupSubprogramName - Replace contains special characters used /// in a typical Objective-C names with '.' in a given string. -static void fixupObjcLikeName(StringRef Str, SmallVectorImpl<char> &Out) { +static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) { + StringRef FName = + Fn.getFunction() ? Fn.getFunction()->getName() : Fn.getName(); + FName = Function::getRealLinkageName(FName); + + StringRef Prefix("llvm.dbg.lv."); + Out.reserve(FName.size() + Prefix.size()); + Out.append(Prefix.begin(), Prefix.end()); + bool isObjCLike = false; - for (size_t i = 0, e = Str.size(); i < e; ++i) { - char C = Str[i]; + for (size_t i = 0, e = FName.size(); i < e; ++i) { + char C = FName[i]; if (C == '[') isObjCLike = true; @@ -771,33 +845,16 @@ static void fixupObjcLikeName(StringRef Str, SmallVectorImpl<char> &Out) { /// getFnSpecificMDNode - Return a NameMDNode, if available, that is /// suitable to hold function specific information. NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) { - SmallString<32> Name = StringRef("llvm.dbg.lv."); - StringRef FName = "fn"; - if (Fn.getFunction()) - FName = Fn.getFunction()->getName(); - else - FName = Fn.getName(); - char One = '\1'; - if (FName.startswith(StringRef(&One, 1))) - FName = FName.substr(1); - fixupObjcLikeName(FName, Name); + SmallString<32> Name; + fixupSubprogramName(Fn, Name); return M.getNamedMetadata(Name.str()); } /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable /// to hold function specific information. NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) { - SmallString<32> Name = StringRef("llvm.dbg.lv."); - StringRef FName = "fn"; - if (Fn.getFunction()) - FName = Fn.getFunction()->getName(); - else - FName = Fn.getName(); - char One = '\1'; - if (FName.startswith(StringRef(&One, 1))) - FName = FName.substr(1); - fixupObjcLikeName(FName, Name); - + SmallString<32> Name; + fixupSubprogramName(Fn, Name); return M.getOrInsertNamedMetadata(Name.str()); } @@ -810,8 +867,7 @@ DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, SmallVector<Value *, 16> Elts; // Insert inlined scope as 7th element. for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? Elts.push_back(InlinedScope) : - Elts.push_back(DV->getOperand(i)); + i == 7 ? Elts.push_back(InlinedScope) : Elts.push_back(DV->getOperand(i)); return DIVariable(MDNode::get(VMContext, Elts)); } @@ -820,9 +876,8 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { SmallVector<Value *, 16> Elts; // Insert inlined scope as 7th element. for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))): - Elts.push_back(DV->getOperand(i)); + i == 7 ? Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))) + : Elts.push_back(DV->getOperand(i)); return DIVariable(MDNode::get(VMContext, Elts)); } @@ -846,31 +901,70 @@ DICompositeType llvm::getDICompositeType(DIType T) { if (T.isCompositeType()) return DICompositeType(T); - if (T.isDerivedType()) - return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()); + if (T.isDerivedType()) { + // This function is currently used by dragonegg and dragonegg does + // not generate identifier for types, so using an empty map to resolve + // DerivedFrom should be fine. + DITypeIdentifierMap EmptyMap; + return getDICompositeType( + DIDerivedType(T).getTypeDerivedFrom().resolve(EmptyMap)); + } return DICompositeType(); } -/// isSubprogramContext - Return true if Context is either a subprogram -/// or another context nested inside a subprogram. -bool llvm::isSubprogramContext(const MDNode *Context) { - if (!Context) - return false; - DIDescriptor D(Context); - if (D.isSubprogram()) - return true; - if (D.isType()) - return isSubprogramContext(DIType(Context).getContext()); - return false; +/// Update DITypeIdentifierMap by going through retained types of each CU. +DITypeIdentifierMap +llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) { + DITypeIdentifierMap Map; + for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) { + DICompileUnit CU(CU_Nodes->getOperand(CUi)); + DIArray Retain = CU.getRetainedTypes(); + for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) { + if (!Retain.getElement(Ti).isCompositeType()) + continue; + DICompositeType Ty(Retain.getElement(Ti)); + if (MDString *TypeId = Ty.getIdentifier()) { + // Definition has priority over declaration. + // Try to insert (TypeId, Ty) to Map. + std::pair<DITypeIdentifierMap::iterator, bool> P = + Map.insert(std::make_pair(TypeId, Ty)); + // If TypeId already exists in Map and this is a definition, replace + // whatever we had (declaration or definition) with the definition. + if (!P.second && !Ty.isForwardDecl()) + P.first->second = Ty; + } + } + } + return Map; } //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. //===----------------------------------------------------------------------===// +void DebugInfoFinder::reset() { + CUs.clear(); + SPs.clear(); + GVs.clear(); + TYs.clear(); + Scopes.clear(); + NodesSeen.clear(); + TypeIdentifierMap.clear(); + TypeMapInitialized = false; +} + +void DebugInfoFinder::InitializeTypeMap(const Module &M) { + if (!TypeMapInitialized) + if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); + TypeMapInitialized = true; + } +} + /// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(const Module &M) { + InitializeTypeMap(M); if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { DICompileUnit CU(CU_Nodes->getOperand(i)); @@ -878,8 +972,10 @@ void DebugInfoFinder::processModule(const Module &M) { DIArray GVs = CU.getGlobalVariables(); for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { DIGlobalVariable DIG(GVs.getElement(i)); - if (addGlobalVariable(DIG)) + if (addGlobalVariable(DIG)) { + processScope(DIG.getContext()); processType(DIG.getType()); + } } DIArray SPs = CU.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) @@ -890,36 +986,38 @@ void DebugInfoFinder::processModule(const Module &M) { DIArray RetainedTypes = CU.getRetainedTypes(); for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) processType(DIType(RetainedTypes.getElement(i))); - // FIXME: We really shouldn't be bailing out after visiting just one CU - return; + DIArray Imports = CU.getImportedEntities(); + for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) { + DIImportedEntity Import = DIImportedEntity(Imports.getElement(i)); + DIDescriptor Entity = Import.getEntity(); + if (Entity.isType()) + processType(DIType(Entity)); + else if (Entity.isSubprogram()) + processSubprogram(DISubprogram(Entity)); + else if (Entity.isNameSpace()) + processScope(DINameSpace(Entity).getContext()); + } } } } /// processLocation - Process DILocation. -void DebugInfoFinder::processLocation(DILocation Loc) { - if (!Loc.Verify()) return; - DIDescriptor S(Loc.getScope()); - if (S.isCompileUnit()) - addCompileUnit(DICompileUnit(S)); - else if (S.isSubprogram()) - processSubprogram(DISubprogram(S)); - else if (S.isLexicalBlock()) - processLexicalBlock(DILexicalBlock(S)); - else if (S.isLexicalBlockFile()) { - DILexicalBlockFile DBF = DILexicalBlockFile(S); - processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - processLocation(Loc.getOrigLocation()); +void DebugInfoFinder::processLocation(const Module &M, DILocation Loc) { + if (!Loc) + return; + InitializeTypeMap(M); + processScope(Loc.getScope()); + processLocation(M, Loc.getOrigLocation()); } /// processType - Process DIType. void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; + processScope(DT.getContext().resolve(TypeIdentifierMap)); if (DT.isCompositeType()) { DICompositeType DCT(DT); - processType(DCT.getTypeDerivedFrom()); + processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); DIArray DA = DCT.getTypeArray(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); @@ -930,7 +1028,35 @@ void DebugInfoFinder::processType(DIType DT) { } } else if (DT.isDerivedType()) { DIDerivedType DDT(DT); - processType(DDT.getTypeDerivedFrom()); + processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); + } +} + +void DebugInfoFinder::processScope(DIScope Scope) { + if (Scope.isType()) { + DIType Ty(Scope); + processType(Ty); + return; + } + if (Scope.isCompileUnit()) { + addCompileUnit(DICompileUnit(Scope)); + return; + } + if (Scope.isSubprogram()) { + processSubprogram(DISubprogram(Scope)); + return; + } + if (!addScope(Scope)) + return; + if (Scope.isLexicalBlock()) { + DILexicalBlock LB(Scope); + processScope(LB.getContext()); + } else if (Scope.isLexicalBlockFile()) { + DILexicalBlockFile LBF = DILexicalBlockFile(Scope); + processScope(LBF.getScope()); + } else if (Scope.isNameSpace()) { + DINameSpace NS(Scope); + processScope(NS.getContext()); } } @@ -942,8 +1068,7 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { else if (Context.isLexicalBlockFile()) { DILexicalBlockFile DBF = DILexicalBlockFile(Context); return processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - else + } else return processSubprogram(DISubprogram(Context)); } @@ -951,13 +1076,30 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; + processScope(SP.getContext().resolve(TypeIdentifierMap)); processType(SP.getType()); + DIArray TParams = SP.getTemplateParams(); + for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) { + DIDescriptor Element = TParams.getElement(I); + if (Element.isTemplateTypeParameter()) { + DITemplateTypeParameter TType(Element); + processScope(TType.getContext().resolve(TypeIdentifierMap)); + processType(TType.getType().resolve(TypeIdentifierMap)); + } else if (Element.isTemplateValueParameter()) { + DITemplateValueParameter TVal(Element); + processScope(TVal.getContext().resolve(TypeIdentifierMap)); + processType(TVal.getType().resolve(TypeIdentifierMap)); + } + } } /// processDeclare - Process DbgDeclareInst. -void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) { +void DebugInfoFinder::processDeclare(const Module &M, + const DbgDeclareInst *DDI) { MDNode *N = dyn_cast<MDNode>(DDI->getVariable()); - if (!N) return; + if (!N) + return; + InitializeTypeMap(M); DIDescriptor DV(N); if (!DV.isVariable()) @@ -965,12 +1107,29 @@ void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) { if (!NodesSeen.insert(DV)) return; + processScope(DIVariable(N).getContext()); + processType(DIVariable(N).getType()); +} + +void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { + MDNode *N = dyn_cast<MDNode>(DVI->getVariable()); + if (!N) + return; + InitializeTypeMap(M); + + DIDescriptor DV(N); + if (!DV.isVariable()) + return; + + if (!NodesSeen.insert(DV)) + return; + processScope(DIVariable(N).getContext()); processType(DIVariable(N).getType()); } /// addType - Add type into Tys. bool DebugInfoFinder::addType(DIType DT) { - if (!DT.isValid()) + if (!DT) return false; if (!NodesSeen.insert(DT)) @@ -982,9 +1141,8 @@ bool DebugInfoFinder::addType(DIType DT) { /// addCompileUnit - Add compile unit into CUs. bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { - if (!CU.Verify()) + if (!CU) return false; - if (!NodesSeen.insert(CU)) return false; @@ -994,7 +1152,7 @@ bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { /// addGlobalVariable - Add global variable into GVs. bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { - if (!DIDescriptor(DIG).isGlobalVariable()) + if (!DIG) return false; if (!NodesSeen.insert(DIG)) @@ -1006,7 +1164,7 @@ bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { // addSubprogram - Add subprgoram into SPs. bool DebugInfoFinder::addSubprogram(DISubprogram SP) { - if (!DIDescriptor(SP).isSubprogram()) + if (!SP) return false; if (!NodesSeen.insert(SP)) @@ -1016,18 +1174,33 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) { return true; } +bool DebugInfoFinder::addScope(DIScope Scope) { + if (!Scope) + return false; + // FIXME: Ocaml binding generates a scope with no content, we treat it + // as null for now. + if (Scope->getNumOperands() == 0) + return false; + if (!NodesSeen.insert(Scope)) + return false; + Scopes.push_back(Scope); + return true; +} + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// /// dump - Print descriptor to dbgs() with a newline. void DIDescriptor::dump() const { - print(dbgs()); dbgs() << '\n'; + print(dbgs()); + dbgs() << '\n'; } /// print - Print descriptor. void DIDescriptor::print(raw_ostream &OS) const { - if (!DbgNode) return; + if (!DbgNode) + return; if (const char *Tag = dwarf::TagString(getTag())) OS << "[ " << Tag << " ]"; @@ -1089,7 +1262,8 @@ void DIEnumerator::printInternal(raw_ostream &OS) const { } void DIType::printInternal(raw_ostream &OS) const { - if (!DbgNode) return; + if (!DbgNode) + return; StringRef Res = getName(); if (!Res.empty()) @@ -1097,13 +1271,11 @@ void DIType::printInternal(raw_ostream &OS) const { // TODO: Print context? - OS << " [line " << getLineNumber() - << ", size " << getSizeInBits() - << ", align " << getAlignInBits() - << ", offset " << getOffsetInBits(); + OS << " [line " << getLineNumber() << ", size " << getSizeInBits() + << ", align " << getAlignInBits() << ", offset " << getOffsetInBits(); if (isBasicType()) if (const char *Enc = - dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding())) + dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding())) OS << ", enc " << Enc; OS << "]"; @@ -1116,7 +1288,12 @@ void DIType::printInternal(raw_ostream &OS) const { OS << " [artificial]"; if (isForwardDecl()) - OS << " [fwd]"; + OS << " [decl]"; + else if (getTag() == dwarf::DW_TAG_structure_type || + getTag() == dwarf::DW_TAG_union_type || + getTag() == dwarf::DW_TAG_enumeration_type || + getTag() == dwarf::DW_TAG_class_type) + OS << " [def]"; if (isVector()) OS << " [vector]"; if (isStaticMember()) @@ -1194,19 +1371,17 @@ void DIObjCProperty::printInternal(raw_ostream &OS) const { if (!Name.empty()) OS << " [" << Name << ']'; - OS << " [line " << getLineNumber() - << ", properties " << getUnsignedField(6) << ']'; + OS << " [line " << getLineNumber() << ", properties " << getUnsignedField(6) + << ']'; } static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, const LLVMContext &Ctx) { - if (!DL.isUnknown()) { // Print source line info. + if (!DL.isUnknown()) { // Print source line info. DIScope Scope(DL.getScope(Ctx)); + assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope."); // Omit the directory, because it's likely to be long and uninteresting. - if (Scope.Verify()) - CommentOS << Scope.getFilename(); - else - CommentOS << "<unknown>"; + CommentOS << Scope.getFilename(); CommentOS << ':' << DL.getLine(); if (DL.getCol() != 0) CommentOS << ':' << DL.getCol(); @@ -1233,3 +1408,81 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } } + +/// Specialize constructor to make sure it has the correct type. +template <> DIRef<DIScope>::DIRef(const Value *V) : Val(V) { + assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); +} +template <> DIRef<DIType>::DIRef(const Value *V) : Val(V) { + assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); +} + +/// Specialize getFieldAs to handle fields that are references to DIScopes. +template <> +DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const { + return DIScopeRef(getField(DbgNode, Elt)); +} +/// Specialize getFieldAs to handle fields that are references to DITypes. +template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const { + return DITypeRef(getField(DbgNode, Elt)); +} + +/// Strip debug info in the module if it exists. +/// To do this, we remove all calls to the debugger intrinsics and any named +/// metadata for debugging. We also remove debug locations for instructions. +/// Return true if module is modified. +bool llvm::StripDebugInfo(Module &M) { + + bool Changed = false; + + // Remove all of the calls to the debugger intrinsics, and remove them from + // the module. + if (Function *Declare = M.getFunction("llvm.dbg.declare")) { + while (!Declare->use_empty()) { + CallInst *CI = cast<CallInst>(Declare->use_back()); + CI->eraseFromParent(); + } + Declare->eraseFromParent(); + Changed = true; + } + + if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { + while (!DbgVal->use_empty()) { + CallInst *CI = cast<CallInst>(DbgVal->use_back()); + CI->eraseFromParent(); + } + DbgVal->eraseFromParent(); + Changed = true; + } + + for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), + NME = M.named_metadata_end(); NMI != NME;) { + NamedMDNode *NMD = NMI; + ++NMI; + if (NMD->getName().startswith("llvm.dbg.")) { + NMD->eraseFromParent(); + Changed = true; + } + } + + for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) + for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; + ++FI) + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; + ++BI) { + if (!BI->getDebugLoc().isUnknown()) { + Changed = true; + BI->setDebugLoc(DebugLoc()); + } + } + + return Changed; +} + +/// Return Debug Info Metadata Version by checking module flags. +unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { + Value *Val = M.getModuleFlag("Debug Info Version"); + if (!Val) + return 0; + return cast<ConstantInt>(Val)->getZExtValue(); +} diff --git a/contrib/llvm/lib/IR/Function.cpp b/contrib/llvm/lib/IR/Function.cpp index 7f7efab..e8a2402 100644 --- a/contrib/llvm/lib/IR/Function.cpp +++ b/contrib/llvm/lib/IR/Function.cpp @@ -131,6 +131,15 @@ bool Argument::hasReturnedAttr() const { hasAttribute(getArgNo()+1, Attribute::Returned); } +/// Return true if this argument has the readonly or readnone attribute on it +/// in its containing function. +bool Argument::onlyReadsMemory() const { + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::ReadOnly) || + getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::ReadNone); +} + /// addAttr - Add attributes to an argument. void Argument::addAttr(AttributeSet AS) { assert(AS.getNumSlots() <= 1 && @@ -267,6 +276,9 @@ void Function::dropAllReferences() { // blockaddresses, but BasicBlock's destructor takes care of those. while (!BasicBlocks.empty()) BasicBlocks.begin()->eraseFromParent(); + + // Prefix data is stored in a side table. + setPrefixData(0); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -342,6 +354,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setGC(SrcF->getGC()); else clearGC(); + if (SrcF->hasPrefixData()) + setPrefixData(SrcF->getPrefixData()); + else + setPrefixData(0); } /// getIntrinsicID - This method returns the ID number of the specified @@ -437,7 +453,9 @@ enum IIT_Info { IIT_STRUCT5 = 22, IIT_EXTEND_VEC_ARG = 23, IIT_TRUNC_VEC_ARG = 24, - IIT_ANYPTR = 25 + IIT_ANYPTR = 25, + IIT_V1 = 26, + IIT_VARARG = 27 }; @@ -451,6 +469,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, case IIT_Done: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0)); return; + case IIT_VARARG: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0)); + return; case IIT_MMX: OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0)); return; @@ -481,6 +502,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, case IIT_I64: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64)); return; + case IIT_V1: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 1)); + DecodeIITType(NextElt, Infos, OutputTable); + return; case IIT_V2: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Vector, 2)); DecodeIITType(NextElt, Infos, OutputTable); @@ -592,6 +617,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, switch (D.Kind) { case IITDescriptor::Void: return Type::getVoidTy(Context); + case IITDescriptor::VarArg: return Type::getVoidTy(Context); case IITDescriptor::MMX: return Type::getX86_MMXTy(Context); case IITDescriptor::Metadata: return Type::getMetadataTy(Context); case IITDescriptor::Half: return Type::getHalfTy(Context); @@ -712,3 +738,31 @@ bool Function::callsFunctionThatReturnsTwice() const { return false; } +Constant *Function::getPrefixData() const { + assert(hasPrefixData()); + const LLVMContextImpl::PrefixDataMapTy &PDMap = + getContext().pImpl->PrefixDataMap; + assert(PDMap.find(this) != PDMap.end()); + return cast<Constant>(PDMap.find(this)->second->getReturnValue()); +} + +void Function::setPrefixData(Constant *PrefixData) { + if (!PrefixData && !hasPrefixData()) + return; + + unsigned SCData = getSubclassDataFromValue(); + LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap; + ReturnInst *&PDHolder = PDMap[this]; + if (PrefixData) { + if (PDHolder) + PDHolder->setOperand(0, PrefixData); + else + PDHolder = ReturnInst::Create(getContext(), PrefixData); + SCData |= 2; + } else { + delete PDHolder; + PDMap.erase(this); + SCData &= ~2; + } + setValueSubclassData(SCData); +} diff --git a/contrib/llvm/lib/IR/GCOV.cpp b/contrib/llvm/lib/IR/GCOV.cpp index ea2f0a6..f0f8c7d 100644 --- a/contrib/llvm/lib/IR/GCOV.cpp +++ b/contrib/llvm/lib/IR/GCOV.cpp @@ -7,14 +7,16 @@ // //===----------------------------------------------------------------------===// // -// GCOV implements the interface to read and write coverage files that use +// GCOV implements the interface to read and write coverage files that use // 'gcov' format. // //===----------------------------------------------------------------------===// +#include "llvm/Support/Debug.h" #include "llvm/Support/GCOV.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/system_error.h" using namespace llvm; @@ -43,27 +45,47 @@ bool GCOVFile::read(GCOVBuffer &Buffer) { if (Format == GCOV::InvalidGCOV) return false; - unsigned i = 0; - while (1) { - GCOVFunction *GFun = NULL; - if (isGCDAFile(Format)) { - // Use existing function while reading .gcda file. - assert(i < Functions.size() && ".gcda data does not match .gcno data"); - GFun = Functions[i]; - } else if (isGCNOFile(Format)){ - GFun = new GCOVFunction(); + if (isGCNOFile(Format)) { + while (true) { + if (!Buffer.readFunctionTag()) break; + GCOVFunction *GFun = new GCOVFunction(); + if (!GFun->read(Buffer, Format)) + return false; Functions.push_back(GFun); } - if (!GFun || !GFun->read(Buffer, Format)) - break; - ++i; } + else if (isGCDAFile(Format)) { + for (size_t i = 0, e = Functions.size(); i < e; ++i) { + if (!Buffer.readFunctionTag()) { + errs() << "Unexpected number of functions.\n"; + return false; + } + if (!Functions[i]->read(Buffer, Format)) + return false; + } + if (Buffer.readObjectTag()) { + uint32_t Length; + uint32_t Dummy; + if (!Buffer.readInt(Length)) return false; + if (!Buffer.readInt(Dummy)) return false; // checksum + if (!Buffer.readInt(Dummy)) return false; // num + if (!Buffer.readInt(RunCount)) return false;; + Buffer.advanceCursor(Length-3); + } + while (Buffer.readProgramTag()) { + uint32_t Length; + if (!Buffer.readInt(Length)) return false; + Buffer.advanceCursor(Length); + ++ProgramCount; + } + } + return true; } -/// dump - Dump GCOVFile content on standard out for debugging purposes. +/// dump - Dump GCOVFile content to dbgs() for debugging purposes. void GCOVFile::dump() { - for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(), + for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), E = Functions.end(); I != E; ++I) (*I)->dump(); } @@ -71,10 +93,11 @@ void GCOVFile::dump() { /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVFile::collectLineCounts(FileInfo &FI) { - for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) + for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), + E = Functions.end(); I != E; ++I) (*I)->collectLineCounts(FI); - FI.print(); + FI.setRunCount(RunCount); + FI.setProgramCount(ProgramCount); } //===----------------------------------------------------------------------===// @@ -85,77 +108,122 @@ GCOVFunction::~GCOVFunction() { DeleteContainerPointers(Blocks); } -/// read - Read a aunction from the buffer. Return false if buffer cursor +/// read - Read a function from the buffer. Return false if buffer cursor /// does not point to a function tag. bool GCOVFunction::read(GCOVBuffer &Buff, GCOV::GCOVFormat Format) { - if (!Buff.readFunctionTag()) - return false; + uint32_t Dummy; + if (!Buff.readInt(Dummy)) return false; // Function header length + if (!Buff.readInt(Ident)) return false; + if (!Buff.readInt(Dummy)) return false; // Checksum #1 + if (Format != GCOV::GCNO_402 && Format != GCOV::GCDA_402) + if (!Buff.readInt(Dummy)) return false; // Checksum #2 - Buff.readInt(); // Function header length - Ident = Buff.readInt(); - Buff.readInt(); // Checksum #1 - if (Format != GCOV::GCNO_402) - Buff.readInt(); // Checksum #2 + if (!Buff.readString(Name)) return false; - Name = Buff.readString(); if (Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404) - Filename = Buff.readString(); + if (!Buff.readString(Filename)) return false; if (Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404) { - Buff.readArcTag(); - uint32_t Count = Buff.readInt() / 2; - for (unsigned i = 0, e = Count; i != e; ++i) { - Blocks[i]->addCount(Buff.readInt64()); + if (!Buff.readArcTag()) { + errs() << "Arc tag not found.\n"; + return false; + } + uint32_t Count; + if (!Buff.readInt(Count)) return false; + Count /= 2; + + // This for loop adds the counts for each block. A second nested loop is + // required to combine the edge counts that are contained in the GCDA file. + for (uint32_t Line = 0; Count > 0; ++Line) { + if (Line >= Blocks.size()) { + errs() << "Unexpected number of edges.\n"; + return false; + } + GCOVBlock &Block = *Blocks[Line]; + for (size_t Edge = 0, End = Block.getNumEdges(); Edge < End; ++Edge) { + if (Count == 0) { + errs() << "Unexpected number of edges.\n"; + return false; + } + uint64_t ArcCount; + if (!Buff.readInt64(ArcCount)) return false; + Block.addCount(ArcCount); + --Count; + } } return true; } - LineNumber = Buff.readInt(); + if (!Buff.readInt(LineNumber)) return false; // read blocks. - bool BlockTagFound = Buff.readBlockTag(); - (void)BlockTagFound; - assert(BlockTagFound && "Block Tag not found!"); - uint32_t BlockCount = Buff.readInt(); - for (int i = 0, e = BlockCount; i != e; ++i) { - Buff.readInt(); // Block flags; - Blocks.push_back(new GCOVBlock(i)); + if (!Buff.readBlockTag()) { + errs() << "Block tag not found.\n"; + return false; + } + uint32_t BlockCount; + if (!Buff.readInt(BlockCount)) return false; + for (uint32_t i = 0, e = BlockCount; i != e; ++i) { + if (!Buff.readInt(Dummy)) return false; // Block flags; + Blocks.push_back(new GCOVBlock(*this, i)); } // read edges. while (Buff.readEdgeTag()) { - uint32_t EdgeCount = (Buff.readInt() - 1) / 2; - uint32_t BlockNo = Buff.readInt(); - assert(BlockNo < BlockCount && "Unexpected Block number!"); - for (int i = 0, e = EdgeCount; i != e; ++i) { - Blocks[BlockNo]->addEdge(Buff.readInt()); - Buff.readInt(); // Edge flag + uint32_t EdgeCount; + if (!Buff.readInt(EdgeCount)) return false; + EdgeCount = (EdgeCount - 1) / 2; + uint32_t BlockNo; + if (!Buff.readInt(BlockNo)) return false; + if (BlockNo >= BlockCount) { + errs() << "Unexpected block number.\n"; + return false; + } + for (uint32_t i = 0, e = EdgeCount; i != e; ++i) { + uint32_t Dst; + if (!Buff.readInt(Dst)) return false; + Blocks[BlockNo]->addEdge(Dst); + if (!Buff.readInt(Dummy)) return false; // Edge flag } } // read line table. while (Buff.readLineTag()) { - uint32_t LineTableLength = Buff.readInt(); - uint32_t Size = Buff.getCursor() + LineTableLength*4; - uint32_t BlockNo = Buff.readInt(); - assert(BlockNo < BlockCount && "Unexpected Block number!"); + uint32_t LineTableLength; + if (!Buff.readInt(LineTableLength)) return false; + uint32_t EndPos = Buff.getCursor() + LineTableLength*4; + uint32_t BlockNo; + if (!Buff.readInt(BlockNo)) return false; + if (BlockNo >= BlockCount) { + errs() << "Unexpected block number.\n"; + return false; + } GCOVBlock *Block = Blocks[BlockNo]; - Buff.readInt(); // flag - while (Buff.getCursor() != (Size - 4)) { - StringRef Filename = Buff.readString(); - if (Buff.getCursor() == (Size - 4)) break; - while (uint32_t L = Buff.readInt()) - Block->addLine(Filename, L); + if (!Buff.readInt(Dummy)) return false; // flag + while (Buff.getCursor() != (EndPos - 4)) { + StringRef F; + if (!Buff.readString(F)) return false; + if (F != Filename) { + errs() << "Multiple sources for a single basic block.\n"; + return false; + } + if (Buff.getCursor() == (EndPos - 4)) break; + while (true) { + uint32_t Line; + if (!Buff.readInt(Line)) return false; + if (!Line) break; + Block->addLine(Line); + } } - Buff.readInt(); // flag + if (!Buff.readInt(Dummy)) return false; // flag } return true; } -/// dump - Dump GCOVFunction content on standard out for debugging purposes. +/// dump - Dump GCOVFunction content to dbgs() for debugging purposes. void GCOVFunction::dump() { - outs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; - for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(), + dbgs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; + for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) (*I)->dump(); } @@ -163,7 +231,7 @@ void GCOVFunction::dump() { /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVFunction::collectLineCounts(FileInfo &FI) { - for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(), + for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) (*I)->collectLineCounts(FI); } @@ -174,110 +242,73 @@ void GCOVFunction::collectLineCounts(FileInfo &FI) { /// ~GCOVBlock - Delete GCOVBlock and its content. GCOVBlock::~GCOVBlock() { Edges.clear(); - DeleteContainerSeconds(Lines); -} - -void GCOVBlock::addLine(StringRef Filename, uint32_t LineNo) { - GCOVLines *&LinesForFile = Lines[Filename]; - if (!LinesForFile) - LinesForFile = new GCOVLines(); - LinesForFile->add(LineNo); + Lines.clear(); } /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVBlock::collectLineCounts(FileInfo &FI) { - for (StringMap<GCOVLines *>::iterator I = Lines.begin(), + for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), E = Lines.end(); I != E; ++I) - I->second->collectLineCounts(FI, I->first(), Counter); + FI.addLineCount(Parent.getFilename(), *I, Counter); } -/// dump - Dump GCOVBlock content on standard out for debugging purposes. +/// dump - Dump GCOVBlock content to dbgs() for debugging purposes. void GCOVBlock::dump() { - outs() << "Block : " << Number << " Counter : " << Counter << "\n"; + dbgs() << "Block : " << Number << " Counter : " << Counter << "\n"; if (!Edges.empty()) { - outs() << "\tEdges : "; - for (SmallVector<uint32_t, 16>::iterator I = Edges.begin(), E = Edges.end(); + dbgs() << "\tEdges : "; + for (SmallVectorImpl<uint32_t>::iterator I = Edges.begin(), E = Edges.end(); I != E; ++I) - outs() << (*I) << ","; - outs() << "\n"; + dbgs() << (*I) << ","; + dbgs() << "\n"; } if (!Lines.empty()) { - outs() << "\tLines : "; - for (StringMap<GCOVLines *>::iterator LI = Lines.begin(), - LE = Lines.end(); LI != LE; ++LI) { - outs() << LI->first() << " -> "; - LI->second->dump(); - outs() << "\n"; - } + dbgs() << "\tLines : "; + for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), + E = Lines.end(); I != E; ++I) + dbgs() << (*I) << ","; + dbgs() << "\n"; } } //===----------------------------------------------------------------------===// -// GCOVLines implementation. - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVLines::collectLineCounts(FileInfo &FI, StringRef Filename, - uint32_t Count) { - for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - FI.addLineCount(Filename, *I, Count); -} - -/// dump - Dump GCOVLines content on standard out for debugging purposes. -void GCOVLines::dump() { - for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - outs() << (*I) << ","; -} - -//===----------------------------------------------------------------------===// // FileInfo implementation. -/// addLineCount - Add line count for the given line number in a file. -void FileInfo::addLineCount(StringRef Filename, uint32_t Line, uint32_t Count) { - if (LineInfo.find(Filename) == LineInfo.end()) { - OwningPtr<MemoryBuffer> Buff; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; - return; - } - StringRef AllLines = Buff.take()->getBuffer(); - LineCounts L(AllLines.count('\n')+2); - L[Line-1] = Count; - LineInfo[Filename] = L; - return; - } - LineCounts &L = LineInfo[Filename]; - L[Line-1] = Count; -} - /// print - Print source files with collected line count information. -void FileInfo::print() { +void FileInfo::print(raw_fd_ostream &OS, StringRef gcnoFile, + StringRef gcdaFile) { for (StringMap<LineCounts>::iterator I = LineInfo.begin(), E = LineInfo.end(); I != E; ++I) { StringRef Filename = I->first(); - outs() << Filename << "\n"; + OS << " -: 0:Source:" << Filename << "\n"; + OS << " -: 0:Graph:" << gcnoFile << "\n"; + OS << " -: 0:Data:" << gcdaFile << "\n"; + OS << " -: 0:Runs:" << RunCount << "\n"; + OS << " -: 0:Programs:" << ProgramCount << "\n"; LineCounts &L = LineInfo[Filename]; OwningPtr<MemoryBuffer> Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { errs() << Filename << ": " << ec.message() << "\n"; return; } - StringRef AllLines = Buff.take()->getBuffer(); - for (unsigned i = 0, e = L.size(); i != e; ++i) { - if (L[i]) - outs() << L[i] << ":\t"; - else - outs() << " :\t"; + StringRef AllLines = Buff->getBuffer(); + uint32_t i = 0; + while (!AllLines.empty()) { + if (L.find(i) != L.end()) { + if (L[i] == 0) + OS << " #####:"; + else + OS << format("%9" PRIu64 ":", L[i]); + } else { + OS << " -:"; + } std::pair<StringRef, StringRef> P = AllLines.split('\n'); if (AllLines != P.first) - outs() << P.first; - outs() << "\n"; + OS << format("%5u:", i+1) << P.first; + OS << "\n"; AllLines = P.second; + ++i; } } } - - diff --git a/contrib/llvm/lib/IR/Globals.cpp b/contrib/llvm/lib/IR/Globals.cpp index 6d547f3..da3b02a 100644 --- a/contrib/llvm/lib/IR/Globals.cpp +++ b/contrib/llvm/lib/IR/Globals.cpp @@ -229,14 +229,14 @@ void GlobalAlias::setAliasee(Constant *Aliasee) { setOperand(0, Aliasee); } -const GlobalValue *GlobalAlias::getAliasedGlobal() const { - const Constant *C = getAliasee(); +GlobalValue *GlobalAlias::getAliasedGlobal() { + Constant *C = getAliasee(); if (C == 0) return 0; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) + if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) return GV; - const ConstantExpr *CE = cast<ConstantExpr>(C); + ConstantExpr *CE = cast<ConstantExpr>(C); assert((CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) && "Unsupported aliasee"); @@ -244,18 +244,18 @@ const GlobalValue *GlobalAlias::getAliasedGlobal() const { return cast<GlobalValue>(CE->getOperand(0)); } -const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const { - SmallPtrSet<const GlobalValue*, 3> Visited; +GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) { + SmallPtrSet<GlobalValue*, 3> Visited; // Check if we need to stop early. if (stopOnWeak && mayBeOverridden()) return this; - const GlobalValue *GV = getAliasedGlobal(); + GlobalValue *GV = getAliasedGlobal(); Visited.insert(GV); // Iterate over aliasing chain, stopping on weak alias if necessary. - while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { + while (GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { if (stopOnWeak && GA->mayBeOverridden()) break; diff --git a/contrib/llvm/lib/IR/Instruction.cpp b/contrib/llvm/lib/IR/Instruction.cpp index 2b5a0b3..a7773c4 100644 --- a/contrib/llvm/lib/IR/Instruction.cpp +++ b/contrib/llvm/lib/IR/Instruction.cpp @@ -223,18 +223,19 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case GetElementPtr: return "getelementptr"; // Convert instructions... - case Trunc: return "trunc"; - case ZExt: return "zext"; - case SExt: return "sext"; - case FPTrunc: return "fptrunc"; - case FPExt: return "fpext"; - case FPToUI: return "fptoui"; - case FPToSI: return "fptosi"; - case UIToFP: return "uitofp"; - case SIToFP: return "sitofp"; - case IntToPtr: return "inttoptr"; - case PtrToInt: return "ptrtoint"; - case BitCast: return "bitcast"; + case Trunc: return "trunc"; + case ZExt: return "zext"; + case SExt: return "sext"; + case FPTrunc: return "fptrunc"; + case FPExt: return "fpext"; + case FPToUI: return "fptoui"; + case FPToSI: return "fptosi"; + case UIToFP: return "uitofp"; + case SIToFP: return "sitofp"; + case IntToPtr: return "inttoptr"; + case PtrToInt: return "ptrtoint"; + case BitCast: return "bitcast"; + case AddrSpaceCast: return "addrspacecast"; // Other instructions... case ICmp: return "icmp"; diff --git a/contrib/llvm/lib/IR/Instructions.cpp b/contrib/llvm/lib/IR/Instructions.cpp index d58877e..8a6b77b 100644 --- a/contrib/llvm/lib/IR/Instructions.cpp +++ b/contrib/llvm/lib/IR/Instructions.cpp @@ -346,7 +346,7 @@ void CallInst::removeAttribute(unsigned i, Attribute attr) { setAttributes(PAL); } -bool CallInst::hasFnAttr(Attribute::AttrKind A) const { +bool CallInst::hasFnAttrImpl(Attribute::AttrKind A) const { if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) return true; if (const Function *F = getCalledFunction()) @@ -574,7 +574,7 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } -bool InvokeInst::hasFnAttr(Attribute::AttrKind A) const { +bool InvokeInst::hasFnAttrImpl(Attribute::AttrKind A) const { if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) return true; if (const Function *F = getCalledFunction()) @@ -2095,7 +2095,9 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode, case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: - return false; // These always modify bits + case Instruction::AddrSpaceCast: + // TODO: Target informations may give a more accurate answer here. + return false; case Instruction::BitCast: return true; // BitCast never modifies bits. case Instruction::PtrToInt: @@ -2137,44 +2139,46 @@ unsigned CastInst::isEliminableCastPair( // ZEXT < Integral Unsigned Integer Any // SEXT < Integral Signed Integer Any // FPTOUI n/a FloatPt n/a Integral Unsigned - // FPTOSI n/a FloatPt n/a Integral Signed - // UITOFP n/a Integral Unsigned FloatPt n/a - // SITOFP n/a Integral Signed FloatPt n/a - // FPTRUNC > FloatPt n/a FloatPt n/a - // FPEXT < FloatPt n/a FloatPt n/a + // FPTOSI n/a FloatPt n/a Integral Signed + // UITOFP n/a Integral Unsigned FloatPt n/a + // SITOFP n/a Integral Signed FloatPt n/a + // FPTRUNC > FloatPt n/a FloatPt n/a + // FPEXT < FloatPt n/a FloatPt n/a // PTRTOINT n/a Pointer n/a Integral Unsigned // INTTOPTR n/a Integral Unsigned Pointer n/a - // BITCAST = FirstClass n/a FirstClass n/a + // BITCAST = FirstClass n/a FirstClass n/a + // ADDRSPCST n/a Pointer n/a Pointer n/a // // NOTE: some transforms are safe, but we consider them to be non-profitable. // For example, we could merge "fptoui double to i32" + "zext i32 to i64", // into "fptoui double to i64", but this loses information about the range - // of the produced value (we no longer know the top-part is all zeros). + // of the produced value (we no longer know the top-part is all zeros). // Further this conversion is often much more expensive for typical hardware, - // and causes issues when building libgcc. We disallow fptosi+sext for the + // and causes issues when building libgcc. We disallow fptosi+sext for the // same reason. - const unsigned numCastOps = + const unsigned numCastOps = Instruction::CastOpsEnd - Instruction::CastOpsBegin; static const uint8_t CastResults[numCastOps][numCastOps] = { - // T F F U S F F P I B -+ - // R Z S P P I I T P 2 N T | - // U E E 2 2 2 2 R E I T C +- secondOp - // N X X U S F F N X N 2 V | - // C T T I I P P C T T P T -+ - { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // Trunc -+ - { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3 }, // ZExt | - { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3 }, // SExt | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToUI | - { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToSI | - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // UIToFP +- firstOp - { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // SIToFP | - { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4 }, // FPTrunc | - { 99,99,99, 2, 2,99,99,10, 2,99,99, 4 }, // FPExt | - { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3 }, // PtrToInt | - { 99,99,99,99,99,99,99,99,99,13,99,12 }, // IntToPtr | - { 5, 5, 5, 6, 6, 5, 5, 6, 6,11, 5, 1 }, // BitCast -+ + // T F F U S F F P I B A -+ + // R Z S P P I I T P 2 N T S | + // U E E 2 2 2 2 R E I T C C +- secondOp + // N X X U S F F N X N 2 V V | + // C T T I I P P C T T P T T -+ + { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ + { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3, 0}, // ZExt | + { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | + { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | + { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | + { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4, 0}, // FPTrunc | + { 99,99,99, 2, 2,99,99,10, 2,99,99, 4, 0}, // FPExt | + { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | + { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | + { 5, 5, 5, 6, 6, 5, 5, 6, 6,16, 5, 1,14}, // BitCast | + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ }; - + // If either of the casts are a bitcast from scalar to vector, disallow the // merging. However, bitcast of A->B->A are allowed. bool isFirstBitcast = (firstOp == Instruction::BitCast); @@ -2191,45 +2195,56 @@ unsigned CastInst::isEliminableCastPair( [secondOp-Instruction::CastOpsBegin]; switch (ElimCase) { case 0: - // categorically disallowed + // Categorically disallowed. return 0; case 1: - // allowed, use first cast's opcode + // Allowed, use first cast's opcode. return firstOp; case 2: - // allowed, use second cast's opcode + // Allowed, use second cast's opcode. return secondOp; case 3: - // no-op cast in second op implies firstOp as long as the DestTy + // No-op cast in second op implies firstOp as long as the DestTy // is integer and we are not converting between a vector and a // non vector type. if (!SrcTy->isVectorTy() && DstTy->isIntegerTy()) return firstOp; return 0; case 4: - // no-op cast in second op implies firstOp as long as the DestTy + // No-op cast in second op implies firstOp as long as the DestTy // is floating point. if (DstTy->isFloatingPointTy()) return firstOp; return 0; case 5: - // no-op cast in first op implies secondOp as long as the SrcTy + // No-op cast in first op implies secondOp as long as the SrcTy // is an integer. if (SrcTy->isIntegerTy()) return secondOp; return 0; case 6: - // no-op cast in first op implies secondOp as long as the SrcTy + // No-op cast in first op implies secondOp as long as the SrcTy // is a floating point. if (SrcTy->isFloatingPointTy()) return secondOp; return 0; - case 7: { - // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size + case 7: { + // Cannot simplify if address spaces are different! + if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) + return 0; + + unsigned MidSize = MidTy->getScalarSizeInBits(); + // We can still fold this without knowing the actual sizes as long we + // know that the intermediate pointer is the largest possible + // pointer size. + // FIXME: Is this always true? + if (MidSize == 64) + return Instruction::BitCast; + + // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size. if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy) return 0; unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits(); - unsigned MidSize = MidTy->getScalarSizeInBits(); if (MidSize >= PtrSize) return Instruction::BitCast; return 0; @@ -2246,7 +2261,8 @@ unsigned CastInst::isEliminableCastPair( return firstOp; return secondOp; } - case 9: // zext, sext -> zext, because sext can't sign extend after zext + case 9: + // zext, sext -> zext, because sext can't sign extend after zext return Instruction::ZExt; case 10: // fpext followed by ftrunc is allowed if the bit size returned to is @@ -2254,18 +2270,7 @@ unsigned CastInst::isEliminableCastPair( if (SrcTy == DstTy) return Instruction::BitCast; return 0; // If the types are not the same we can't eliminate it. - case 11: - // bitcast followed by ptrtoint is allowed as long as the bitcast - // is a pointer to pointer cast. - if (SrcTy->isPointerTy() && MidTy->isPointerTy()) - return secondOp; - return 0; - case 12: - // inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast - if (MidTy->isPointerTy() && DstTy->isPointerTy()) - return firstOp; - return 0; - case 13: { + case 11: { // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize if (!MidIntPtrTy) return 0; @@ -2276,8 +2281,65 @@ unsigned CastInst::isEliminableCastPair( return Instruction::BitCast; return 0; } + case 12: { + // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS + // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS + if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) + return Instruction::AddrSpaceCast; + return Instruction::BitCast; + } + case 13: + // FIXME: this state can be merged with (1), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() && + MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + "Illegal addrspacecast, bitcast sequence!"); + // Allowed, use first cast's opcode + return firstOp; + case 14: + // FIXME: this state can be merged with (2), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && + MidTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() && + "Illegal bitcast, addrspacecast sequence!"); + // Allowed, use second cast's opcode + return secondOp; + case 15: + // FIXME: this state can be merged with (1), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isIntOrIntVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isPtrOrPtrVectorTy() && + MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + "Illegal inttoptr, bitcast sequence!"); + // Allowed, use first cast's opcode + return firstOp; + case 16: + // FIXME: this state can be merged with (2), but the following assert + // is useful to check the correcteness of the sequence due to semantic + // change of bitcast. + assert( + SrcTy->isPtrOrPtrVectorTy() && + MidTy->isPtrOrPtrVectorTy() && + DstTy->isIntOrIntVectorTy() && + SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && + "Illegal bitcast, ptrtoint sequence!"); + // Allowed, use second cast's opcode + return secondOp; case 99: - // cast combination can't happen (error in input). This is for all cases + // Cast combination can't happen (error in input). This is for all cases // where the MidTy is not the same for the two cast instructions. llvm_unreachable("Invalid Cast Combination"); default: @@ -2290,19 +2352,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { - case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); - case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); - case SExt: return new SExtInst (S, Ty, Name, InsertBefore); - case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); - case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); - case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); - case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); - case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); - case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); - case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); - case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); - case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); - default: llvm_unreachable("Invalid opcode provided"); + case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); + case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); + case SExt: return new SExtInst (S, Ty, Name, InsertBefore); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); + case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); + case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); + case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertBefore); + default: llvm_unreachable("Invalid opcode provided"); } } @@ -2311,19 +2374,20 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { - case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); - case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); - case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); - case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); - case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); - case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); - case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); - case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); - case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); - case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); - case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); - case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); - default: llvm_unreachable("Invalid opcode provided"); + case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); + case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); + case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); + case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); + case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); + case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertAtEnd); + default: llvm_unreachable("Invalid opcode provided"); } } @@ -2378,25 +2442,43 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, Type *Ty, CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { - assert(S->getType()->isPointerTy() && "Invalid cast"); - assert((Ty->isIntegerTy() || Ty->isPointerTy()) && + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && + "Invalid cast"); + assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast"); + assert((!Ty->isVectorTy() || + Ty->getVectorNumElements() == S->getType()->getVectorNumElements()) && "Invalid cast"); - if (Ty->isIntegerTy()) + if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd); + + Type *STy = S->getType(); + if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); + return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); } /// @brief Create a BitCast or a PtrToInt cast instruction -CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, - const Twine &Name, +CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, + const Twine &Name, Instruction *InsertBefore) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && "Invalid cast"); + assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast"); + assert((!Ty->isVectorTy() || + Ty->getVectorNumElements() == S->getType()->getVectorNumElements()) && + "Invalid cast"); if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); + + Type *STy = S->getType(); + if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); + return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } @@ -2517,8 +2599,48 @@ bool CastInst::isCastable(Type *SrcTy, Type *DestTy) { } } -// Provide a way to get a "cast" where the cast opcode is inferred from the -// types and size of the operand. This, basically, is a parallel of the +bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) { + if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType()) + return false; + + if (SrcTy == DestTy) + return true; + + if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) { + if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) { + if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { + // An element by element cast. Valid if casting the elements is valid. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + } + } + + if (PointerType *DestPtrTy = dyn_cast<PointerType>(DestTy)) { + if (PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy)) { + return SrcPtrTy->getAddressSpace() == DestPtrTy->getAddressSpace(); + } + } + + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr + + // Could still have vectors of pointers if the number of elements doesn't + // match + if (SrcBits == 0 || DestBits == 0) + return false; + + if (SrcBits != DestBits) + return false; + + if (DestTy->isX86_MMXTy() || SrcTy->isX86_MMXTy()) + return false; + + return true; +} + +// Provide a way to get a "cast" where the cast opcode is inferred from the +// types and size of the operand. This, basically, is a parallel of the // logic in the castIsValid function below. This axiom should hold: // castIsValid( getCastOpcode(Val, Ty), Val, Ty) // should not assert in castIsValid. In other words, this produces a "correct" @@ -2535,6 +2657,7 @@ CastInst::getCastOpcode( if (SrcTy == DestTy) return BitCast; + // FIXME: Check address space sizes here if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { @@ -2601,6 +2724,8 @@ CastInst::getCastOpcode( return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { + if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace()) + return AddrSpaceCast; return BitCast; // ptr -> ptr } else if (SrcTy->isIntegerTy()) { return IntToPtr; // int -> ptr @@ -2695,13 +2820,27 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) { case Instruction::BitCast: // BitCast implies a no-op cast of type only. No bits change. // However, you can't cast pointers to anything but pointers. - if (SrcTy->isPointerTy() != DstTy->isPointerTy()) + if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy()) return false; - // Now we know we're not dealing with a pointer/non-pointer mismatch. In all - // these cases, the cast is okay if the source and destination bit widths - // are identical. - return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); + // For non pointer cases, the cast is okay if the source and destination bit + // widths are identical. + if (!SrcTy->isPtrOrPtrVectorTy()) + return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); + + // If both are pointers then the address spaces must match and vector of + // pointers must have the same number of elements. + return SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && + SrcTy->isVectorTy() == DstTy->isVectorTy() && + (!SrcTy->isVectorTy() || + SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements()); + + case Instruction::AddrSpaceCast: + return SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() && + SrcTy->isVectorTy() == DstTy->isVectorTy() && + (!SrcTy->isVectorTy() || + SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements()); } } @@ -2848,6 +2987,18 @@ BitCastInst::BitCastInst( assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } +AddrSpaceCastInst::AddrSpaceCastInst( + Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore +) : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); +} + +AddrSpaceCastInst::AddrSpaceCastInst( + Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, AddrSpaceCast, S, Name, InsertAtEnd) { + assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); +} + //===----------------------------------------------------------------------===// // CmpInst Classes //===----------------------------------------------------------------------===// @@ -3180,7 +3331,6 @@ SwitchInst::SwitchInst(const SwitchInst &SI) OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } - TheSubsets = SI.TheSubsets; SubclassOptionalData = SI.SubclassOptionalData; } @@ -3192,16 +3342,6 @@ SwitchInst::~SwitchInst() { /// addCase - Add an entry to the switch instruction... /// void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { - IntegersSubsetToBB Mapping; - - // FIXME: Currently we work with ConstantInt based cases. - // So inititalize IntItem container directly from ConstantInt. - Mapping.add(IntItem::fromConstantInt(OnVal)); - IntegersSubset CaseRanges = Mapping.getCase(); - addCase(CaseRanges, Dest); -} - -void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) { unsigned NewCaseIdx = getNumCases(); unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) @@ -3209,17 +3349,14 @@ void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) { // Initialize some new operands. assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+2; - - SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal); - - CaseIt Case(this, NewCaseIdx, TheSubsetsIt); - Case.updateCaseValueOperand(OnVal); + CaseIt Case(this, NewCaseIdx); + Case.setValue(OnVal); Case.setSuccessor(Dest); } /// removeCase - This method removes the specified case and its successor /// from the switch instruction. -void SwitchInst::removeCase(CaseIt& i) { +void SwitchInst::removeCase(CaseIt i) { unsigned idx = i.getCaseIndex(); assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!"); @@ -3236,16 +3373,6 @@ void SwitchInst::removeCase(CaseIt& i) { // Nuke the last value. OL[NumOps-2].set(0); OL[NumOps-2+1].set(0); - - // Do the same with TheCases collection: - if (i.SubsetIt != --TheSubsets.end()) { - *i.SubsetIt = TheSubsets.back(); - TheSubsets.pop_back(); - } else { - TheSubsets.pop_back(); - i.SubsetIt = TheSubsets.end(); - } - NumOperands = NumOps-2; } @@ -3490,6 +3617,10 @@ BitCastInst *BitCastInst::clone_impl() const { return new BitCastInst(getOperand(0), getType()); } +AddrSpaceCastInst *AddrSpaceCastInst::clone_impl() const { + return new AddrSpaceCastInst(getOperand(0), getType()); +} + CallInst *CallInst::clone_impl() const { return new(getNumOperands()) CallInst(*this); } diff --git a/contrib/llvm/lib/IR/LLVMContextImpl.h b/contrib/llvm/lib/IR/LLVMContextImpl.h index 0c659b8..407b985 100644 --- a/contrib/llvm/lib/IR/LLVMContextImpl.h +++ b/contrib/llvm/lib/IR/LLVMContextImpl.h @@ -355,6 +355,11 @@ public: typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy; IntrinsicIDCacheTy IntrinsicIDCache; + /// \brief Mapping from a function to its prefix data, which is stored as the + /// operand of an unparented ReturnInst so that the prefix data has a Use. + typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy; + PrefixDataMapTy PrefixDataMap; + int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); diff --git a/contrib/llvm/lib/IR/LegacyPassManager.cpp b/contrib/llvm/lib/IR/LegacyPassManager.cpp new file mode 100644 index 0000000..a431d82 --- /dev/null +++ b/contrib/llvm/lib/IR/LegacyPassManager.cpp @@ -0,0 +1,1920 @@ +//===- LegacyPassManager.cpp - LLVM Pass Infrastructure Implementation ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the legacy LLVM Pass Manager infrastructure. +// +//===----------------------------------------------------------------------===// + + +#include "llvm/Assembly/PrintModulePass.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/LegacyPassManagers.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <map> +using namespace llvm; +using namespace llvm::legacy; + +// See PassManagers.h for Pass Manager infrastructure overview. + +//===----------------------------------------------------------------------===// +// Pass debugging information. Often it is useful to find out what pass is +// running when a crash occurs in a utility. When this library is compiled with +// debugging on, a command line option (--debug-pass) is enabled that causes the +// pass name to be printed before it executes. +// + +namespace { +// Different debug levels that can be enabled... +enum PassDebugLevel { + Disabled, Arguments, Structure, Executions, Details +}; +} + +static cl::opt<enum PassDebugLevel> +PassDebugging("debug-pass", cl::Hidden, + cl::desc("Print PassManager debugging information"), + cl::values( + clEnumVal(Disabled , "disable debug output"), + clEnumVal(Arguments , "print pass arguments to pass to 'opt'"), + clEnumVal(Structure , "print pass structure before run()"), + clEnumVal(Executions, "print pass name before it is executed"), + clEnumVal(Details , "print pass details when it is executed"), + clEnumValEnd)); + +namespace { +typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> +PassOptionList; +} + +// Print IR out before/after specified passes. +static PassOptionList +PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes"), + cl::Hidden); + +static PassOptionList +PrintAfter("print-after", + llvm::cl::desc("Print IR after specified passes"), + cl::Hidden); + +static cl::opt<bool> +PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false)); +static cl::opt<bool> +PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false)); + +/// This is a helper to determine whether to print IR before or +/// after a pass. + +static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, + PassOptionList &PassesToPrint) { + for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { + const llvm::PassInfo *PassInf = PassesToPrint[i]; + if (PassInf) + if (PassInf->getPassArgument() == PI->getPassArgument()) { + return true; + } + } + return false; +} + +/// This is a utility to check whether a pass should have IR dumped +/// before it. +static bool ShouldPrintBeforePass(const PassInfo *PI) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); +} + +/// This is a utility to check whether a pass should have IR dumped +/// after it. +static bool ShouldPrintAfterPass(const PassInfo *PI) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); +} + +/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions +/// or higher is specified. +bool PMDataManager::isPassDebuggingExecutionsOrMore() const { + return PassDebugging >= Executions; +} + + + + +void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { + if (V == 0 && M == 0) + OS << "Releasing pass '"; + else + OS << "Running pass '"; + + OS << P->getPassName() << "'"; + + if (M) { + OS << " on module '" << M->getModuleIdentifier() << "'.\n"; + return; + } + if (V == 0) { + OS << '\n'; + return; + } + + OS << " on "; + if (isa<Function>(V)) + OS << "function"; + else if (isa<BasicBlock>(V)) + OS << "basic block"; + else + OS << "value"; + + OS << " '"; + WriteAsOperand(OS, V, /*PrintTy=*/false, M); + OS << "'\n"; +} + + +namespace { +//===----------------------------------------------------------------------===// +// BBPassManager +// +/// BBPassManager manages BasicBlockPass. It batches all the +/// pass together and sequence them to process one basic block before +/// processing next basic block. +class BBPassManager : public PMDataManager, public FunctionPass { + +public: + static char ID; + explicit BBPassManager() + : PMDataManager(), FunctionPass(ID) {} + + /// Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the function, and if so, return true. + bool runOnFunction(Function &F); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + bool doInitialization(Module &M); + bool doInitialization(Function &F); + bool doFinalization(Module &M); + bool doFinalization(Function &F); + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + + virtual const char *getPassName() const { + return "BasicBlock Pass Manager"; + } + + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + BP->dumpPassStructure(Offset + 1); + dumpLastUses(BP, Offset+1); + } + } + + BasicBlockPass *getContainedPass(unsigned N) { + assert(N < PassVector.size() && "Pass number out of range!"); + BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]); + return BP; + } + + virtual PassManagerType getPassManagerType() const { + return PMT_BasicBlockPassManager; + } +}; + +char BBPassManager::ID = 0; +} // End anonymous namespace + +namespace llvm { +namespace legacy { +//===----------------------------------------------------------------------===// +// FunctionPassManagerImpl +// +/// FunctionPassManagerImpl manages FPPassManagers +class FunctionPassManagerImpl : public Pass, + public PMDataManager, + public PMTopLevelManager { + virtual void anchor(); +private: + bool wasRun; +public: + static char ID; + explicit FunctionPassManagerImpl() : + Pass(PT_PassManager, ID), PMDataManager(), + PMTopLevelManager(new FPPassManager()), wasRun(false) {} + + /// add - Add a pass to the queue of passes to run. This passes ownership of + /// the Pass to the PassManager. When the PassManager is destroyed, the pass + /// will be destroyed as well, so there is no need to delete the pass. This + /// implies that all passes MUST be allocated with 'new'. + void add(Pass *P) { + schedulePass(P); + } + + /// createPrinterPass - Get a function printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintFunctionPass(Banner, &O); + } + + // Prepare for running an on the fly pass, freeing memory if needed + // from a previous run. + void releaseMemoryOnTheFly(); + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool run(Function &F); + + /// doInitialization - Run all of the initializers for the function passes. + /// + bool doInitialization(Module &M); + + /// doFinalization - Run all of the finalizers for the function passes. + /// + bool doFinalization(Module &M); + + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + virtual PassManagerType getTopLevelPassManagerType() { + return PMT_FunctionPassManager; + } + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + FPPassManager *getContainedManager(unsigned N) { + assert(N < PassManagers.size() && "Pass number out of range!"); + FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); + return FP; + } +}; + +void FunctionPassManagerImpl::anchor() {} + +char FunctionPassManagerImpl::ID = 0; +} // End of legacy namespace +} // End of llvm namespace + +namespace { +//===----------------------------------------------------------------------===// +// MPPassManager +// +/// MPPassManager manages ModulePasses and function pass managers. +/// It batches all Module passes and function pass managers together and +/// sequences them to process one module. +class MPPassManager : public Pass, public PMDataManager { +public: + static char ID; + explicit MPPassManager() : + Pass(PT_PassManager, ID), PMDataManager() { } + + // Delete on the fly managers. + virtual ~MPPassManager() { + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + delete FPP; + } + } + + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool runOnModule(Module &M); + + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + + /// doInitialization - Run all of the initializers for the module passes. + /// + bool doInitialization(); + + /// doFinalization - Run all of the finalizers for the module passes. + /// + bool doFinalization(); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + /// Add RequiredPass into list of lower level passes required by pass P. + /// RequiredPass is run on the fly by Pass Manager when P requests it + /// through getAnalysis interface. + virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); + + /// Return function pass corresponding to PassInfo PI, that is + /// required by module pass MP. Instantiate analysis pass, by using + /// its runOnFunction() for function F. + virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F); + + virtual const char *getPassName() const { + return "Module Pass Manager"; + } + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + ModulePass *MP = getContainedPass(Index); + MP->dumpPassStructure(Offset + 1); + std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I = + OnTheFlyManagers.find(MP); + if (I != OnTheFlyManagers.end()) + I->second->dumpPassStructure(Offset + 2); + dumpLastUses(MP, Offset+1); + } + } + + ModulePass *getContainedPass(unsigned N) { + assert(N < PassVector.size() && "Pass number out of range!"); + return static_cast<ModulePass *>(PassVector[N]); + } + + virtual PassManagerType getPassManagerType() const { + return PMT_ModulePassManager; + } + + private: + /// Collection of on the fly FPPassManagers. These managers manage + /// function passes that are required by module passes. + std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; +}; + +char MPPassManager::ID = 0; +} // End anonymous namespace + +namespace llvm { +namespace legacy { +//===----------------------------------------------------------------------===// +// PassManagerImpl +// + +/// PassManagerImpl manages MPPassManagers +class PassManagerImpl : public Pass, + public PMDataManager, + public PMTopLevelManager { + virtual void anchor(); + +public: + static char ID; + explicit PassManagerImpl() : + Pass(PT_PassManager, ID), PMDataManager(), + PMTopLevelManager(new MPPassManager()) {} + + /// add - Add a pass to the queue of passes to run. This passes ownership of + /// the Pass to the PassManager. When the PassManager is destroyed, the pass + /// will be destroyed as well, so there is no need to delete the pass. This + /// implies that all passes MUST be allocated with 'new'. + void add(Pass *P) { + schedulePass(P); + } + + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool run(Module &M); + + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + + /// doInitialization - Run all of the initializers for the module passes. + /// + bool doInitialization(); + + /// doFinalization - Run all of the finalizers for the module passes. + /// + bool doFinalization(); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + virtual PassManagerType getTopLevelPassManagerType() { + return PMT_ModulePassManager; + } + + MPPassManager *getContainedManager(unsigned N) { + assert(N < PassManagers.size() && "Pass number out of range!"); + MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]); + return MP; + } +}; + +void PassManagerImpl::anchor() {} + +char PassManagerImpl::ID = 0; +} // End of legacy namespace +} // End of llvm namespace + +namespace { + +//===----------------------------------------------------------------------===// +/// TimingInfo Class - This class is used to calculate information about the +/// amount of time each pass takes to execute. This only happens when +/// -time-passes is enabled on the command line. +/// + +static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex; + +class TimingInfo { + DenseMap<Pass*, Timer*> TimingData; + TimerGroup TG; +public: + // Use 'create' member to get this. + TimingInfo() : TG("... Pass execution timing report ...") {} + + // TimingDtor - Print out information about timing information + ~TimingInfo() { + // Delete all of the timers, which accumulate their info into the + // TimerGroup. + for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(), + E = TimingData.end(); I != E; ++I) + delete I->second; + // TimerGroup is deleted next, printing the report. + } + + // createTheTimeInfo - This method either initializes the TheTimeInfo pointer + // to a non null value (if the -time-passes option is enabled) or it leaves it + // null. It may be called multiple times. + static void createTheTimeInfo(); + + /// getPassTimer - Return the timer for the specified pass if it exists. + Timer *getPassTimer(Pass *P) { + if (P->getAsPMDataManager()) + return 0; + + sys::SmartScopedLock<true> Lock(*TimingInfoMutex); + Timer *&T = TimingData[P]; + if (T == 0) + T = new Timer(P->getPassName(), TG); + return T; + } +}; + +} // End of anon namespace + +static TimingInfo *TheTimeInfo; + +//===----------------------------------------------------------------------===// +// PMTopLevelManager implementation + +/// Initialize top level manager. Create first pass manager. +PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { + PMDM->setTopLevelManager(this); + addPassManager(PMDM); + activeStack.push(PMDM); +} + +/// Set pass P as the last user of the given analysis passes. +void +PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) { + unsigned PDepth = 0; + if (P->getResolver()) + PDepth = P->getResolver()->getPMDataManager().getDepth(); + + for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(), + E = AnalysisPasses.end(); I != E; ++I) { + Pass *AP = *I; + LastUser[AP] = P; + + if (P == AP) + continue; + + // Update the last users of passes that are required transitive by AP. + AnalysisUsage *AnUsage = findAnalysisUsage(AP); + const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); + SmallVector<Pass *, 12> LastUses; + SmallVector<Pass *, 12> LastPMUses; + for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), + E = IDs.end(); I != E; ++I) { + Pass *AnalysisPass = findAnalysisPass(*I); + assert(AnalysisPass && "Expected analysis pass to exist."); + AnalysisResolver *AR = AnalysisPass->getResolver(); + assert(AR && "Expected analysis resolver to exist."); + unsigned APDepth = AR->getPMDataManager().getDepth(); + + if (PDepth == APDepth) + LastUses.push_back(AnalysisPass); + else if (PDepth > APDepth) + LastPMUses.push_back(AnalysisPass); + } + + setLastUser(LastUses, P); + + // If this pass has a corresponding pass manager, push higher level + // analysis to this pass manager. + if (P->getResolver()) + setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass()); + + + // If AP is the last user of other passes then make P last user of + // such passes. + for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(), + LUE = LastUser.end(); LUI != LUE; ++LUI) { + if (LUI->second == AP) + // DenseMap iterator is not invalidated here because + // this is just updating existing entries. + LastUser[LUI->first] = P; + } + } +} + +/// Collect passes whose last user is P +void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, + Pass *P) { + DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI = + InversedLastUser.find(P); + if (DMI == InversedLastUser.end()) + return; + + SmallPtrSet<Pass *, 8> &LU = DMI->second; + for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(), + E = LU.end(); I != E; ++I) { + LastUses.push_back(*I); + } + +} + +AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { + AnalysisUsage *AnUsage = NULL; + DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); + if (DMI != AnUsageMap.end()) + AnUsage = DMI->second; + else { + AnUsage = new AnalysisUsage(); + P->getAnalysisUsage(*AnUsage); + AnUsageMap[P] = AnUsage; + } + return AnUsage; +} + +/// Schedule pass P for execution. Make sure that passes required by +/// P are run before P is run. Update analysis info maintained by +/// the manager. Remove dead passes. This is a recursive function. +void PMTopLevelManager::schedulePass(Pass *P) { + + // TODO : Allocate function manager for this pass, other wise required set + // may be inserted into previous function manager + + // Give pass a chance to prepare the stage. + P->preparePassManager(activeStack); + + // If P is an analysis pass and it is available then do not + // generate the analysis again. Stale analysis info should not be + // available at this point. + const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo(P->getPassID()); + if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) { + delete P; + return; + } + + AnalysisUsage *AnUsage = findAnalysisUsage(P); + + bool checkAnalysis = true; + while (checkAnalysis) { + checkAnalysis = false; + + const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); + for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(), + E = RequiredSet.end(); I != E; ++I) { + + Pass *AnalysisPass = findAnalysisPass(*I); + if (!AnalysisPass) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); + + if (PI == NULL) { + // Pass P is not in the global PassRegistry + dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n"; + dbgs() << "Verify if there is a pass dependency cycle." << "\n"; + dbgs() << "Required Passes:" << "\n"; + for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(), + E = RequiredSet.end(); I2 != E && I2 != I; ++I2) { + Pass *AnalysisPass2 = findAnalysisPass(*I2); + if (AnalysisPass2) { + dbgs() << "\t" << AnalysisPass2->getPassName() << "\n"; + } else { + dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n"; + dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n"; + dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n"; + } + } + } + + assert(PI && "Expected required passes to be initialized"); + AnalysisPass = PI->createPass(); + if (P->getPotentialPassManagerType () == + AnalysisPass->getPotentialPassManagerType()) + // Schedule analysis pass that is managed by the same pass manager. + schedulePass(AnalysisPass); + else if (P->getPotentialPassManagerType () > + AnalysisPass->getPotentialPassManagerType()) { + // Schedule analysis pass that is managed by a new manager. + schedulePass(AnalysisPass); + // Recheck analysis passes to ensure that required analyses that + // are already checked are still available. + checkAnalysis = true; + } else + // Do not schedule this analysis. Lower level analsyis + // passes are run on the fly. + delete AnalysisPass; + } + } + } + + // Now all required passes are available. + if (ImmutablePass *IP = P->getAsImmutablePass()) { + // P is a immutable pass and it will be managed by this + // top level manager. Set up analysis resolver to connect them. + PMDataManager *DM = getAsPMDataManager(); + AnalysisResolver *AR = new AnalysisResolver(*DM); + P->setResolver(AR); + DM->initializeAnalysisImpl(P); + addImmutablePass(IP); + DM->recordAvailableAnalysis(IP); + return; + } + + if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) { + Pass *PP = P->createPrinterPass( + dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***"); + PP->assignPassManager(activeStack, getTopLevelPassManagerType()); + } + + // Add the requested pass to the best available pass manager. + P->assignPassManager(activeStack, getTopLevelPassManagerType()); + + if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) { + Pass *PP = P->createPrinterPass( + dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***"); + PP->assignPassManager(activeStack, getTopLevelPassManagerType()); + } +} + +/// Find the pass that implements Analysis AID. Search immutable +/// passes and all pass managers. If desired pass is not found +/// then return NULL. +Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { + + // Check pass managers + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + if (Pass *P = (*I)->findAnalysisPass(AID, false)) + return P; + + // Check other pass managers + for (SmallVectorImpl<PMDataManager *>::iterator + I = IndirectPassManagers.begin(), + E = IndirectPassManagers.end(); I != E; ++I) + if (Pass *P = (*I)->findAnalysisPass(AID, false)) + return P; + + // Check the immutable passes. Iterate in reverse order so that we find + // the most recently registered passes first. + for (SmallVectorImpl<ImmutablePass *>::reverse_iterator I = + ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) { + AnalysisID PI = (*I)->getPassID(); + if (PI == AID) + return *I; + + // If Pass not found then check the interfaces implemented by Immutable Pass + const PassInfo *PassInf = + PassRegistry::getPassRegistry()->getPassInfo(PI); + assert(PassInf && "Expected all immutable passes to be initialized"); + const std::vector<const PassInfo*> &ImmPI = + PassInf->getInterfacesImplemented(); + for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(), + EE = ImmPI.end(); II != EE; ++II) { + if ((*II)->getTypeInfo() == AID) + return *I; + } + } + + return 0; +} + +// Print passes managed by this top level manager. +void PMTopLevelManager::dumpPasses() const { + + if (PassDebugging < Structure) + return; + + // Print out the immutable passes + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { + ImmutablePasses[i]->dumpPassStructure(0); + } + + // Every class that derives from PMDataManager also derives from Pass + // (sometimes indirectly), but there's no inheritance relationship + // between PMDataManager and Pass, so we have to getAsPass to get + // from a PMDataManager* to a Pass*. + for (SmallVectorImpl<PMDataManager *>::const_iterator I = + PassManagers.begin(), E = PassManagers.end(); I != E; ++I) + (*I)->getAsPass()->dumpPassStructure(1); +} + +void PMTopLevelManager::dumpArguments() const { + + if (PassDebugging < Arguments) + return; + + dbgs() << "Pass Arguments: "; + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = + ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + if (const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) { + assert(PI && "Expected all immutable passes to be initialized"); + if (!PI->isAnalysisGroup()) + dbgs() << " -" << PI->getPassArgument(); + } + for (SmallVectorImpl<PMDataManager *>::const_iterator I = + PassManagers.begin(), E = PassManagers.end(); I != E; ++I) + (*I)->dumpPassArguments(); + dbgs() << "\n"; +} + +void PMTopLevelManager::initializeAllAnalysisInfo() { + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + (*I)->initializeAnalysisInfo(); + + // Initailize other pass managers + for (SmallVectorImpl<PMDataManager *>::iterator + I = IndirectPassManagers.begin(), E = IndirectPassManagers.end(); + I != E; ++I) + (*I)->initializeAnalysisInfo(); + + for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(), + DME = LastUser.end(); DMI != DME; ++DMI) { + DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI = + InversedLastUser.find(DMI->second); + if (InvDMI != InversedLastUser.end()) { + SmallPtrSet<Pass *, 8> &L = InvDMI->second; + L.insert(DMI->first); + } else { + SmallPtrSet<Pass *, 8> L; L.insert(DMI->first); + InversedLastUser[DMI->second] = L; + } + } +} + +/// Destructor +PMTopLevelManager::~PMTopLevelManager() { + for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + delete *I; + + for (SmallVectorImpl<ImmutablePass *>::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; + + for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(), + DME = AnUsageMap.end(); DMI != DME; ++DMI) + delete DMI->second; +} + +//===----------------------------------------------------------------------===// +// PMDataManager implementation + +/// Augement AvailableAnalysis by adding analysis made available by pass P. +void PMDataManager::recordAvailableAnalysis(Pass *P) { + AnalysisID PI = P->getPassID(); + + AvailableAnalysis[PI] = P; + + assert(!AvailableAnalysis.empty()); + + // This pass is the current implementation of all of the interfaces it + // implements as well. + const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI); + if (PInf == 0) return; + const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + AvailableAnalysis[II[i]->getTypeInfo()] = P; +} + +// Return true if P preserves high level analysis used by other +// passes managed by this manager +bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + if (AnUsage->getPreservesAll()) + return true; + + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), + E = HigherLevelAnalysis.end(); I != E; ++I) { + Pass *P1 = *I; + if (P1->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), + P1->getPassID()) == + PreservedSet.end()) + return false; + } + + return true; +} + +/// verifyPreservedAnalysis -- Verify analysis preserved by pass P. +void PMDataManager::verifyPreservedAnalysis(Pass *P) { + // Don't do this unless assertions are enabled. +#ifdef NDEBUG + return; +#endif + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + + // Verify preserved analysis + for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), + E = PreservedSet.end(); I != E; ++I) { + AnalysisID AID = *I; + if (Pass *AP = findAnalysisPass(AID, true)) { + TimeRegion PassTimer(getPassTimer(AP)); + AP->verifyAnalysis(); + } + } +} + +/// Remove Analysis not preserved by Pass P +void PMDataManager::removeNotPreservedAnalysis(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + if (AnUsage->getPreservesAll()) + return; + + const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); + for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(), + E = AvailableAnalysis.end(); I != E; ) { + DenseMap<AnalysisID, Pass*>::iterator Info = I++; + if (Info->second->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == + PreservedSet.end()) { + // Remove this analysis + if (PassDebugging >= Details) { + Pass *S = Info->second; + dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; + dbgs() << S->getPassName() << "'\n"; + } + AvailableAnalysis.erase(Info); + } + } + + // Check inherited analysis also. If P is not preserving analysis + // provided by parent manager then remove it here. + for (unsigned Index = 0; Index < PMT_Last; ++Index) { + + if (!InheritedAnalysis[Index]) + continue; + + for (DenseMap<AnalysisID, Pass*>::iterator + I = InheritedAnalysis[Index]->begin(), + E = InheritedAnalysis[Index]->end(); I != E; ) { + DenseMap<AnalysisID, Pass *>::iterator Info = I++; + if (Info->second->getAsImmutablePass() == 0 && + std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == + PreservedSet.end()) { + // Remove this analysis + if (PassDebugging >= Details) { + Pass *S = Info->second; + dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; + dbgs() << S->getPassName() << "'\n"; + } + InheritedAnalysis[Index]->erase(Info); + } + } + } +} + +/// Remove analysis passes that are not used any longer +void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg, + enum PassDebuggingString DBG_STR) { + + SmallVector<Pass *, 12> DeadPasses; + + // If this is a on the fly manager then it does not have TPM. + if (!TPM) + return; + + TPM->collectLastUses(DeadPasses, P); + + if (PassDebugging >= Details && !DeadPasses.empty()) { + dbgs() << " -*- '" << P->getPassName(); + dbgs() << "' is the last user of following pass instances."; + dbgs() << " Free these instances\n"; + } + + for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(), + E = DeadPasses.end(); I != E; ++I) + freePass(*I, Msg, DBG_STR); +} + +void PMDataManager::freePass(Pass *P, StringRef Msg, + enum PassDebuggingString DBG_STR) { + dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg); + + { + // If the pass crashes releasing memory, remember this. + PassManagerPrettyStackEntry X(P); + TimeRegion PassTimer(getPassTimer(P)); + + P->releaseMemory(); + } + + AnalysisID PI = P->getPassID(); + if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) { + // Remove the pass itself (if it is not already removed). + AvailableAnalysis.erase(PI); + + // Remove all interfaces this pass implements, for which it is also + // listed as the available implementation. + const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) { + DenseMap<AnalysisID, Pass*>::iterator Pos = + AvailableAnalysis.find(II[i]->getTypeInfo()); + if (Pos != AvailableAnalysis.end() && Pos->second == P) + AvailableAnalysis.erase(Pos); + } + } +} + +/// Add pass P into the PassVector. Update +/// AvailableAnalysis appropriately if ProcessAnalysis is true. +void PMDataManager::add(Pass *P, bool ProcessAnalysis) { + // This manager is going to manage pass P. Set up analysis resolver + // to connect them. + AnalysisResolver *AR = new AnalysisResolver(*this); + P->setResolver(AR); + + // If a FunctionPass F is the last user of ModulePass info M + // then the F's manager, not F, records itself as a last user of M. + SmallVector<Pass *, 12> TransferLastUses; + + if (!ProcessAnalysis) { + // Add pass + PassVector.push_back(P); + return; + } + + // At the moment, this pass is the last user of all required passes. + SmallVector<Pass *, 12> LastUses; + SmallVector<Pass *, 8> RequiredPasses; + SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable; + + unsigned PDepth = this->getDepth(); + + collectRequiredAnalysis(RequiredPasses, + ReqAnalysisNotAvailable, P); + for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), + E = RequiredPasses.end(); I != E; ++I) { + Pass *PRequired = *I; + unsigned RDepth = 0; + + assert(PRequired->getResolver() && "Analysis Resolver is not set"); + PMDataManager &DM = PRequired->getResolver()->getPMDataManager(); + RDepth = DM.getDepth(); + + if (PDepth == RDepth) + LastUses.push_back(PRequired); + else if (PDepth > RDepth) { + // Let the parent claim responsibility of last use + TransferLastUses.push_back(PRequired); + // Keep track of higher level analysis used by this manager. + HigherLevelAnalysis.push_back(PRequired); + } else + llvm_unreachable("Unable to accommodate Required Pass"); + } + + // Set P as P's last user until someone starts using P. + // However, if P is a Pass Manager then it does not need + // to record its last user. + if (P->getAsPMDataManager() == 0) + LastUses.push_back(P); + TPM->setLastUser(LastUses, P); + + if (!TransferLastUses.empty()) { + Pass *My_PM = getAsPass(); + TPM->setLastUser(TransferLastUses, My_PM); + TransferLastUses.clear(); + } + + // Now, take care of required analyses that are not available. + for (SmallVectorImpl<AnalysisID>::iterator + I = ReqAnalysisNotAvailable.begin(), + E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); + Pass *AnalysisPass = PI->createPass(); + this->addLowerLevelRequiredPass(P, AnalysisPass); + } + + // Take a note of analysis required and made available by this pass. + // Remove the analysis not preserved by this pass + removeNotPreservedAnalysis(P); + recordAvailableAnalysis(P); + + // Add pass + PassVector.push_back(P); +} + + +/// Populate RP with analysis pass that are required by +/// pass P and are available. Populate RP_NotAvail with analysis +/// pass that are required by pass P but are not available. +void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP, + SmallVectorImpl<AnalysisID> &RP_NotAvail, + Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); + for (AnalysisUsage::VectorType::const_iterator + I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(*I); + } + + const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); + for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), + E = IDs.end(); I != E; ++I) { + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(*I); + } +} + +// All Required analyses should be available to the pass as it runs! Here +// we fill in the AnalysisImpls member of the pass so that it can +// successfully use the getAnalysis() method to retrieve the +// implementations it needs. +// +void PMDataManager::initializeAnalysisImpl(Pass *P) { + AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); + + for (AnalysisUsage::VectorType::const_iterator + I = AnUsage->getRequiredSet().begin(), + E = AnUsage->getRequiredSet().end(); I != E; ++I) { + Pass *Impl = findAnalysisPass(*I, true); + if (Impl == 0) + // This may be analysis pass that is initialized on the fly. + // If that is not the case then it will raise an assert when it is used. + continue; + AnalysisResolver *AR = P->getResolver(); + assert(AR && "Analysis Resolver is not set"); + AR->addAnalysisImplsPair(*I, Impl); + } +} + +/// Find the pass that implements Analysis AID. If desired pass is not found +/// then return NULL. +Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) { + + // Check if AvailableAnalysis map has one entry. + DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID); + + if (I != AvailableAnalysis.end()) + return I->second; + + // Search Parents through TopLevelManager + if (SearchParent) + return TPM->findAnalysisPass(AID); + + return NULL; +} + +// Print list of passes that are last used by P. +void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ + + SmallVector<Pass *, 12> LUses; + + // If this is a on the fly manager then it does not have TPM. + if (!TPM) + return; + + TPM->collectLastUses(LUses, P); + + for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), + E = LUses.end(); I != E; ++I) { + llvm::dbgs() << "--" << std::string(Offset*2, ' '); + (*I)->dumpPassStructure(0); + } +} + +void PMDataManager::dumpPassArguments() const { + for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) { + if (PMDataManager *PMD = (*I)->getAsPMDataManager()) + PMD->dumpPassArguments(); + else + if (const PassInfo *PI = + PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) + if (!PI->isAnalysisGroup()) + dbgs() << " -" << PI->getPassArgument(); + } +} + +void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, + enum PassDebuggingString S2, + StringRef Msg) { + if (PassDebugging < Executions) + return; + dbgs() << (void*)this << std::string(getDepth()*2+1, ' '); + switch (S1) { + case EXECUTION_MSG: + dbgs() << "Executing Pass '" << P->getPassName(); + break; + case MODIFICATION_MSG: + dbgs() << "Made Modification '" << P->getPassName(); + break; + case FREEING_MSG: + dbgs() << " Freeing Pass '" << P->getPassName(); + break; + default: + break; + } + switch (S2) { + case ON_BASICBLOCK_MSG: + dbgs() << "' on BasicBlock '" << Msg << "'...\n"; + break; + case ON_FUNCTION_MSG: + dbgs() << "' on Function '" << Msg << "'...\n"; + break; + case ON_MODULE_MSG: + dbgs() << "' on Module '" << Msg << "'...\n"; + break; + case ON_REGION_MSG: + dbgs() << "' on Region '" << Msg << "'...\n"; + break; + case ON_LOOP_MSG: + dbgs() << "' on Loop '" << Msg << "'...\n"; + break; + case ON_CG_MSG: + dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n"; + break; + default: + break; + } +} + +void PMDataManager::dumpRequiredSet(const Pass *P) const { + if (PassDebugging < Details) + return; + + AnalysisUsage analysisUsage; + P->getAnalysisUsage(analysisUsage); + dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet()); +} + +void PMDataManager::dumpPreservedSet(const Pass *P) const { + if (PassDebugging < Details) + return; + + AnalysisUsage analysisUsage; + P->getAnalysisUsage(analysisUsage); + dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); +} + +void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, + const AnalysisUsage::VectorType &Set) const { + assert(PassDebugging >= Details); + if (Set.empty()) + return; + dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; + for (unsigned i = 0; i != Set.size(); ++i) { + if (i) dbgs() << ','; + const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]); + if (!PInf) { + // Some preserved passes, such as AliasAnalysis, may not be initialized by + // all drivers. + dbgs() << " Uninitialized Pass"; + continue; + } + dbgs() << ' ' << PInf->getPassName(); + } + dbgs() << '\n'; +} + +/// Add RequiredPass into list of lower level passes required by pass P. +/// RequiredPass is run on the fly by Pass Manager when P requests it +/// through getAnalysis interface. +/// This should be handled by specific pass manager. +void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { + if (TPM) { + TPM->dumpArguments(); + TPM->dumpPasses(); + } + + // Module Level pass may required Function Level analysis info + // (e.g. dominator info). Pass manager uses on the fly function pass manager + // to provide this on demand. In that case, in Pass manager terminology, + // module level pass is requiring lower level analysis info managed by + // lower level pass manager. + + // When Pass manager is not able to order required analysis info, Pass manager + // checks whether any lower level manager will be able to provide this + // analysis info on demand or not. +#ifndef NDEBUG + dbgs() << "Unable to schedule '" << RequiredPass->getPassName(); + dbgs() << "' required by '" << P->getPassName() << "'\n"; +#endif + llvm_unreachable("Unable to schedule pass"); +} + +Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { + llvm_unreachable("Unable to find on the fly pass"); +} + +// Destructor +PMDataManager::~PMDataManager() { + for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) + delete *I; +} + +//===----------------------------------------------------------------------===// +// NOTE: Is this the right place to define this method ? +// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist. +Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const { + return PM.findAnalysisPass(ID, dir); +} + +Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, + Function &F) { + return PM.getOnTheFlyPass(P, AnalysisPI, F); +} + +//===----------------------------------------------------------------------===// +// BBPassManager implementation + +/// Execute all of the passes scheduled for execution by invoking +/// runOnBasicBlock method. Keep track of whether any of the passes modifies +/// the function, and if so, return true. +bool BBPassManager::runOnFunction(Function &F) { + if (F.isDeclaration()) + return false; + + bool Changed = doInitialization(F); + + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); + dumpRequiredSet(BP); + + initializeAnalysisImpl(BP); + + { + // If the pass crashes, remember this. + PassManagerPrettyStackEntry X(BP, *I); + TimeRegion PassTimer(getPassTimer(BP)); + + LocalChanged |= BP->runOnBasicBlock(*I); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, + I->getName()); + dumpPreservedSet(BP); + + verifyPreservedAnalysis(BP); + removeNotPreservedAnalysis(BP); + recordAvailableAnalysis(BP); + removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); + } + + return doFinalization(F) || Changed; +} + +// Implement doInitialization and doFinalization +bool BBPassManager::doInitialization(Module &M) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + return Changed; +} + +bool BBPassManager::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + return Changed; +} + +bool BBPassManager::doInitialization(Function &F) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + Changed |= BP->doInitialization(F); + } + + return Changed; +} + +bool BBPassManager::doFinalization(Function &F) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + BasicBlockPass *BP = getContainedPass(Index); + Changed |= BP->doFinalization(F); + } + + return Changed; +} + + +//===----------------------------------------------------------------------===// +// FunctionPassManager implementation + +/// Create new Function pass manager +FunctionPassManager::FunctionPassManager(Module *m) : M(m) { + FPM = new FunctionPassManagerImpl(); + // FPM is the top level manager. + FPM->setTopLevelManager(FPM); + + AnalysisResolver *AR = new AnalysisResolver(*FPM); + FPM->setResolver(AR); +} + +FunctionPassManager::~FunctionPassManager() { + delete FPM; +} + +/// add - Add a pass to the queue of passes to run. This passes +/// ownership of the Pass to the PassManager. When the +/// PassManager_X is destroyed, the pass will be destroyed as well, so +/// there is no need to delete the pass. (TODO delete passes.) +/// This implies that all passes MUST be allocated with 'new'. +void FunctionPassManager::add(Pass *P) { + FPM->add(P); +} + +/// run - Execute all of the passes scheduled for execution. Keep +/// track of whether any of the passes modifies the function, and if +/// so, return true. +/// +bool FunctionPassManager::run(Function &F) { + if (F.isMaterializable()) { + std::string errstr; + if (F.Materialize(&errstr)) + report_fatal_error("Error reading bitcode file: " + Twine(errstr)); + } + return FPM->run(F); +} + + +/// doInitialization - Run all of the initializers for the function passes. +/// +bool FunctionPassManager::doInitialization() { + return FPM->doInitialization(*M); +} + +/// doFinalization - Run all of the finalizers for the function passes. +/// +bool FunctionPassManager::doFinalization() { + return FPM->doFinalization(*M); +} + +//===----------------------------------------------------------------------===// +// FunctionPassManagerImpl implementation +// +bool FunctionPassManagerImpl::doInitialization(Module &M) { + bool Changed = false; + + dumpArguments(); + dumpPasses(); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doInitialization(M); + } + + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->doInitialization(M); + + return Changed; +} + +bool FunctionPassManagerImpl::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index) + Changed |= getContainedManager(Index)->doFinalization(M); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doFinalization(M); + } + + return Changed; +} + +/// cleanup - After running all passes, clean up pass manager cache. +void FPPassManager::cleanup() { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + AnalysisResolver *AR = FP->getResolver(); + assert(AR && "Analysis Resolver is not set"); + AR->clearAnalysisImpls(); + } +} + +void FunctionPassManagerImpl::releaseMemoryOnTheFly() { + if (!wasRun) + return; + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { + FPPassManager *FPPM = getContainedManager(Index); + for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) { + FPPM->getContainedPass(Index)->releaseMemory(); + } + } + wasRun = false; +} + +// Execute all the passes managed by this top level manager. +// Return true if any function is modified by a pass. +bool FunctionPassManagerImpl::run(Function &F) { + bool Changed = false; + TimingInfo::createTheTimeInfo(); + + initializeAllAnalysisInfo(); + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->runOnFunction(F); + + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + getContainedManager(Index)->cleanup(); + + wasRun = true; + return Changed; +} + +//===----------------------------------------------------------------------===// +// FPPassManager implementation + +char FPPassManager::ID = 0; +/// Print passes managed by this manager +void FPPassManager::dumpPassStructure(unsigned Offset) { + dbgs().indent(Offset*2) << "FunctionPass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + FP->dumpPassStructure(Offset + 1); + dumpLastUses(FP, Offset+1); + } +} + + +/// Execute all of the passes scheduled for execution by invoking +/// runOnFunction method. Keep track of whether any of the passes modifies +/// the function, and if so, return true. +bool FPPassManager::runOnFunction(Function &F) { + if (F.isDeclaration()) + return false; + + bool Changed = false; + + // Collect inherited analysis from Module level pass manager. + populateInheritedAnalysis(TPM->activeStack); + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); + dumpRequiredSet(FP); + + initializeAnalysisImpl(FP); + + { + PassManagerPrettyStackEntry X(FP, F); + TimeRegion PassTimer(getPassTimer(FP)); + + LocalChanged |= FP->runOnFunction(F); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); + dumpPreservedSet(FP); + + verifyPreservedAnalysis(FP); + removeNotPreservedAnalysis(FP); + recordAvailableAnalysis(FP); + removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); + } + return Changed; +} + +bool FPPassManager::runOnModule(Module &M) { + bool Changed = false; + + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + Changed |= runOnFunction(*I); + + return Changed; +} + +bool FPPassManager::doInitialization(Module &M) { + bool Changed = false; + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + return Changed; +} + +bool FPPassManager::doFinalization(Module &M) { + bool Changed = false; + + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + return Changed; +} + +//===----------------------------------------------------------------------===// +// MPPassManager implementation + +/// Execute all of the passes scheduled for execution by invoking +/// runOnModule method. Keep track of whether any of the passes modifies +/// the module, and if so, return true. +bool +MPPassManager::runOnModule(Module &M) { + bool Changed = false; + + // Initialize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + Changed |= FPP->doInitialization(M); + } + + // Initialize module passes + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) + Changed |= getContainedPass(Index)->doInitialization(M); + + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + ModulePass *MP = getContainedPass(Index); + bool LocalChanged = false; + + dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); + dumpRequiredSet(MP); + + initializeAnalysisImpl(MP); + + { + PassManagerPrettyStackEntry X(MP, M); + TimeRegion PassTimer(getPassTimer(MP)); + + LocalChanged |= MP->runOnModule(M); + } + + Changed |= LocalChanged; + if (LocalChanged) + dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, + M.getModuleIdentifier()); + dumpPreservedSet(MP); + + verifyPreservedAnalysis(MP); + removeNotPreservedAnalysis(MP); + recordAvailableAnalysis(MP); + removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); + } + + // Finalize module passes + for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) + Changed |= getContainedPass(Index)->doFinalization(M); + + // Finalize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + // We don't know when is the last time an on-the-fly pass is run, + // so we need to releaseMemory / finalize here + FPP->releaseMemoryOnTheFly(); + Changed |= FPP->doFinalization(M); + } + + return Changed; +} + +/// Add RequiredPass into list of lower level passes required by pass P. +/// RequiredPass is run on the fly by Pass Manager when P requests it +/// through getAnalysis interface. +void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { + assert(P->getPotentialPassManagerType() == PMT_ModulePassManager && + "Unable to handle Pass that requires lower level Analysis pass"); + assert((P->getPotentialPassManagerType() < + RequiredPass->getPotentialPassManagerType()) && + "Unable to handle Pass that requires lower level Analysis pass"); + + FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; + if (!FPP) { + FPP = new FunctionPassManagerImpl(); + // FPP is the top level manager. + FPP->setTopLevelManager(FPP); + + OnTheFlyManagers[P] = FPP; + } + FPP->add(RequiredPass); + + // Register P as the last user of RequiredPass. + if (RequiredPass) { + SmallVector<Pass *, 1> LU; + LU.push_back(RequiredPass); + FPP->setLastUser(LU, P); + } +} + +/// Return function pass corresponding to PassInfo PI, that is +/// required by module pass MP. Instantiate analysis pass, by using +/// its runOnFunction() for function F. +Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ + FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; + assert(FPP && "Unable to find on the fly pass"); + + FPP->releaseMemoryOnTheFly(); + FPP->run(F); + return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI); +} + + +//===----------------------------------------------------------------------===// +// PassManagerImpl implementation + +// +/// run - Execute all of the passes scheduled for execution. Keep track of +/// whether any of the passes modifies the module, and if so, return true. +bool PassManagerImpl::run(Module &M) { + bool Changed = false; + TimingInfo::createTheTimeInfo(); + + dumpArguments(); + dumpPasses(); + + SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doInitialization(M); + } + + initializeAllAnalysisInfo(); + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + Changed |= getContainedManager(Index)->runOnModule(M); + + for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), + E = IPV.end(); I != E; ++I) { + Changed |= (*I)->doFinalization(M); + } + + return Changed; +} + +//===----------------------------------------------------------------------===// +// PassManager implementation + +/// Create new pass manager +PassManager::PassManager() { + PM = new PassManagerImpl(); + // PM is the top level manager + PM->setTopLevelManager(PM); +} + +PassManager::~PassManager() { + delete PM; +} + +/// add - Add a pass to the queue of passes to run. This passes ownership of +/// the Pass to the PassManager. When the PassManager is destroyed, the pass +/// will be destroyed as well, so there is no need to delete the pass. This +/// implies that all passes MUST be allocated with 'new'. +void PassManager::add(Pass *P) { + PM->add(P); +} + +/// run - Execute all of the passes scheduled for execution. Keep track of +/// whether any of the passes modifies the module, and if so, return true. +bool PassManager::run(Module &M) { + return PM->run(M); +} + +//===----------------------------------------------------------------------===// +// TimingInfo implementation + +bool llvm::TimePassesIsEnabled = false; +static cl::opt<bool,true> +EnableTiming("time-passes", cl::location(TimePassesIsEnabled), + cl::desc("Time each pass, printing elapsed time for each on exit")); + +// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to +// a non null value (if the -time-passes option is enabled) or it leaves it +// null. It may be called multiple times. +void TimingInfo::createTheTimeInfo() { + if (!TimePassesIsEnabled || TheTimeInfo) return; + + // Constructed the first time this is called, iff -time-passes is enabled. + // This guarantees that the object will be constructed before static globals, + // thus it will be destroyed before them. + static ManagedStatic<TimingInfo> TTI; + TheTimeInfo = &*TTI; +} + +/// If TimingInfo is enabled then start pass timer. +Timer *llvm::getPassTimer(Pass *P) { + if (TheTimeInfo) + return TheTimeInfo->getPassTimer(P); + return 0; +} + +//===----------------------------------------------------------------------===// +// PMStack implementation +// + +// Pop Pass Manager from the stack and clear its analysis info. +void PMStack::pop() { + + PMDataManager *Top = this->top(); + Top->initializeAnalysisInfo(); + + S.pop_back(); +} + +// Push PM on the stack and set its top level manager. +void PMStack::push(PMDataManager *PM) { + assert(PM && "Unable to push. Pass Manager expected"); + assert(PM->getDepth()==0 && "Pass Manager depth set too early"); + + if (!this->empty()) { + assert(PM->getPassManagerType() > this->top()->getPassManagerType() + && "pushing bad pass manager to PMStack"); + PMTopLevelManager *TPM = this->top()->getTopLevelManager(); + + assert(TPM && "Unable to find top level manager"); + TPM->addIndirectPassManager(PM); + PM->setTopLevelManager(TPM); + PM->setDepth(this->top()->getDepth()+1); + } else { + assert((PM->getPassManagerType() == PMT_ModulePassManager + || PM->getPassManagerType() == PMT_FunctionPassManager) + && "pushing bad pass manager to PMStack"); + PM->setDepth(1); + } + + S.push_back(PM); +} + +// Dump content of the pass manager stack. +void PMStack::dump() const { + for (std::vector<PMDataManager *>::const_iterator I = S.begin(), + E = S.end(); I != E; ++I) + dbgs() << (*I)->getAsPass()->getPassName() << ' '; + + if (!S.empty()) + dbgs() << '\n'; +} + +/// Find appropriate Module Pass Manager in the PM Stack and +/// add self into that manager. +void ModulePass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + // Find Module Pass Manager + while (!PMS.empty()) { + PassManagerType TopPMType = PMS.top()->getPassManagerType(); + if (TopPMType == PreferredType) + break; // We found desired pass manager + else if (TopPMType > PMT_ModulePassManager) + PMS.pop(); // Pop children pass managers + else + break; + } + assert(!PMS.empty() && "Unable to find appropriate Pass Manager"); + PMS.top()->add(this); +} + +/// Find appropriate Function Pass Manager or Call Graph Pass Manager +/// in the PM Stack and add self into that manager. +void FunctionPass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + + // Find Function Pass Manager + while (!PMS.empty()) { + if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) + PMS.pop(); + else + break; + } + + // Create new Function Pass Manager if needed. + FPPassManager *FPP; + if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) { + FPP = (FPPassManager *)PMS.top(); + } else { + assert(!PMS.empty() && "Unable to create Function Pass Manager"); + PMDataManager *PMD = PMS.top(); + + // [1] Create new Function Pass Manager + FPP = new FPPassManager(); + FPP->populateInheritedAnalysis(PMS); + + // [2] Set up new manager's top level manager + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(FPP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + FPP->assignPassManager(PMS, PMD->getPassManagerType()); + + // [4] Push new manager into PMS + PMS.push(FPP); + } + + // Assign FPP as the manager of this pass. + FPP->add(this); +} + +/// Find appropriate Basic Pass Manager or Call Graph Pass Manager +/// in the PM Stack and add self into that manager. +void BasicBlockPass::assignPassManager(PMStack &PMS, + PassManagerType PreferredType) { + BBPassManager *BBP; + + // Basic Pass Manager is a leaf pass manager. It does not handle + // any other pass manager. + if (!PMS.empty() && + PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) { + BBP = (BBPassManager *)PMS.top(); + } else { + // If leaf manager is not Basic Block Pass manager then create new + // basic Block Pass manager. + assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager"); + PMDataManager *PMD = PMS.top(); + + // [1] Create new Basic Block Manager + BBP = new BBPassManager(); + + // [2] Set up new manager's top level manager + // Basic Block Pass Manager does not live by itself + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(BBP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + BBP->assignPassManager(PMS, PreferredType); + + // [4] Push new manager into PMS + PMS.push(BBP); + } + + // Assign BBP as the manager of this pass. + BBP->add(this); +} + +PassManagerBase::~PassManagerBase() {} diff --git a/contrib/llvm/lib/IR/Metadata.cpp b/contrib/llvm/lib/IR/Metadata.cpp index 6a6b7af..a32d25c 100644 --- a/contrib/llvm/lib/IR/Metadata.cpp +++ b/contrib/llvm/lib/IR/Metadata.cpp @@ -65,7 +65,7 @@ class MDNodeOperand : public CallbackVH { public: MDNodeOperand(Value *V) : CallbackVH(V) {} - ~MDNodeOperand() {} + virtual ~MDNodeOperand(); void set(Value *V) { unsigned IsFirst = this->getValPtrInt(); @@ -82,6 +82,8 @@ public: }; } // end namespace llvm. +// Provide out-of-line definition to prevent weak vtable. +MDNodeOperand::~MDNodeOperand() {} void MDNodeOperand::deleted() { getParent()->replaceOperand(this, 0); @@ -422,7 +424,7 @@ static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) { return !A.intersectWith(B).isEmptySet() || isContiguous(A, B); } -static bool tryMergeRange(SmallVector<Value*, 4> &EndPoints, ConstantInt *Low, +static bool tryMergeRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low, ConstantInt *High) { ConstantRange NewRange(Low->getValue(), High->getValue()); unsigned Size = EndPoints.size(); @@ -439,7 +441,7 @@ static bool tryMergeRange(SmallVector<Value*, 4> &EndPoints, ConstantInt *Low, return false; } -static void addRange(SmallVector<Value*, 4> &EndPoints, ConstantInt *Low, +static void addRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low, ConstantInt *High) { if (!EndPoints.empty()) if (tryMergeRange(EndPoints, Low, High)) diff --git a/contrib/llvm/lib/IR/Module.cpp b/contrib/llvm/lib/IR/Module.cpp index 8affcc9..4f240c7 100644 --- a/contrib/llvm/lib/IR/Module.cpp +++ b/contrib/llvm/lib/IR/Module.cpp @@ -168,23 +168,6 @@ Constant *Module::getOrInsertFunction(StringRef Name, return F; } -Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, - FunctionType *Ty, - AttributeSet AttributeList) { - // See if we have a definition for the specified function already. - GlobalValue *F = getNamedValue(Name); - if (F == 0) { - // Nope, add it - Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); - New->setAttributes(AttributeList); - FunctionList.push_back(New); - return New; // Return the new prototype. - } - - // Otherwise, we just found the existing function or a prototype. - return F; -} - Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty) { return getOrInsertFunction(Name, Ty, AttributeSet()); @@ -250,8 +233,7 @@ Function *Module::getFunction(StringRef Name) const { /// If AllowLocal is set to true, this function will return types that /// have an local. By default, these types are not returned. /// -GlobalVariable *Module::getGlobalVariable(StringRef Name, - bool AllowLocal) const { +GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { if (GlobalVariable *Result = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name))) if (AllowLocal || !Result->hasLocalLinkage()) @@ -263,7 +245,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, /// 1. If it does not exist, add a declaration of the global and return it. /// 2. Else, the global exists but has the wrong type: return the function /// with a constantexpr cast to the right type. -/// 3. Finally, if the existing global is the correct delclaration, return the +/// 3. Finally, if the existing global is the correct declaration, return the /// existing global. Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. @@ -278,8 +260,10 @@ Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // If the variable exists but has the wrong type, return a bitcast to the // right type. - if (GV->getType() != PointerType::getUnqual(Ty)) - return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty)); + Type *GVTy = GV->getType(); + PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace()); + if (GVTy != PTy) + return ConstantExpr::getBitCast(GV, PTy); // Otherwise, we just found the existing function or a prototype. return GV; @@ -334,12 +318,30 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { MDNode *Flag = ModFlags->getOperand(i); - ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); - MDString *Key = cast<MDString>(Flag->getOperand(1)); - Value *Val = Flag->getOperand(2); - Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), - Key, Val)); + if (Flag->getNumOperands() >= 3 && isa<ConstantInt>(Flag->getOperand(0)) && + isa<MDString>(Flag->getOperand(1))) { + // Check the operands of the MDNode before accessing the operands. + // The verifier will actually catch these failures. + ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); + MDString *Key = cast<MDString>(Flag->getOperand(1)); + Value *Val = Flag->getOperand(2); + Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), + Key, Val)); + } + } +} + +/// Return the corresponding value if Key appears in module flags, otherwise +/// return null. +Value *Module::getModuleFlag(StringRef Key) const { + SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; + getModuleFlagsMetadata(ModuleFlags); + for (unsigned I = 0, E = ModuleFlags.size(); I < E; ++I) { + const ModuleFlagEntry &MFE = ModuleFlags[I]; + if (Key == MFE.Key->getString()) + return MFE.Val; } + return 0; } /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that @@ -404,9 +406,15 @@ bool Module::isDematerializable(const GlobalValue *GV) const { } bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { - if (Materializer) - return Materializer->Materialize(GV, ErrInfo); - return false; + if (!Materializer) + return false; + + error_code EC = Materializer->Materialize(GV); + if (!EC) + return false; + if (ErrInfo) + *ErrInfo = EC.message(); + return true; } void Module::Dematerialize(GlobalValue *GV) { @@ -417,7 +425,12 @@ void Module::Dematerialize(GlobalValue *GV) { bool Module::MaterializeAll(std::string *ErrInfo) { if (!Materializer) return false; - return Materializer->MaterializeModule(this, ErrInfo); + error_code EC = Materializer->MaterializeModule(this); + if (!EC) + return false; + if (ErrInfo) + *ErrInfo = EC.message(); + return true; } bool Module::MaterializeAllPermanently(std::string *ErrInfo) { diff --git a/contrib/llvm/lib/IR/PassManager.cpp b/contrib/llvm/lib/IR/PassManager.cpp index 387094a..966af7d 100644 --- a/contrib/llvm/lib/IR/PassManager.cpp +++ b/contrib/llvm/lib/IR/PassManager.cpp @@ -1,4 +1,4 @@ -//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===// +//===- PassManager.h - Infrastructure for managing & running IR passes ----===// // // The LLVM Compiler Infrastructure // @@ -6,1907 +6,152 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements the LLVM Pass Manager infrastructure. -// -//===----------------------------------------------------------------------===// +#include "llvm/IR/PassManager.h" +#include "llvm/ADT/STLExtras.h" -#include "llvm/PassManagers.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/IR/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <map> using namespace llvm; -// See PassManagers.h for Pass Manager infrastructure overview. - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Pass debugging information. Often it is useful to find out what pass is -// running when a crash occurs in a utility. When this library is compiled with -// debugging on, a command line option (--debug-pass) is enabled that causes the -// pass name to be printed before it executes. -// - -// Different debug levels that can be enabled... -enum PassDebugLevel { - Disabled, Arguments, Structure, Executions, Details -}; - -static cl::opt<enum PassDebugLevel> -PassDebugging("debug-pass", cl::Hidden, - cl::desc("Print PassManager debugging information"), - cl::values( - clEnumVal(Disabled , "disable debug output"), - clEnumVal(Arguments , "print pass arguments to pass to 'opt'"), - clEnumVal(Structure , "print pass structure before run()"), - clEnumVal(Executions, "print pass name before it is executed"), - clEnumVal(Details , "print pass details when it is executed"), - clEnumValEnd)); - -typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> -PassOptionList; - -// Print IR out before/after specified passes. -static PassOptionList -PrintBefore("print-before", - llvm::cl::desc("Print IR before specified passes"), - cl::Hidden); - -static PassOptionList -PrintAfter("print-after", - llvm::cl::desc("Print IR after specified passes"), - cl::Hidden); - -static cl::opt<bool> -PrintBeforeAll("print-before-all", - llvm::cl::desc("Print IR before each pass"), - cl::init(false)); -static cl::opt<bool> -PrintAfterAll("print-after-all", - llvm::cl::desc("Print IR after each pass"), - cl::init(false)); - -/// This is a helper to determine whether to print IR before or -/// after a pass. - -static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, - PassOptionList &PassesToPrint) { - for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { - const llvm::PassInfo *PassInf = PassesToPrint[i]; - if (PassInf) - if (PassInf->getPassArgument() == PI->getPassArgument()) { - return true; - } - } - return false; -} - -/// This is a utility to check whether a pass should have IR dumped -/// before it. -static bool ShouldPrintBeforePass(const PassInfo *PI) { - return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); -} - -/// This is a utility to check whether a pass should have IR dumped -/// after it. -static bool ShouldPrintAfterPass(const PassInfo *PI) { - return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); -} - -} // End of llvm namespace - -/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions -/// or higher is specified. -bool PMDataManager::isPassDebuggingExecutionsOrMore() const { - return PassDebugging >= Executions; -} - - - - -void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { - if (V == 0 && M == 0) - OS << "Releasing pass '"; - else - OS << "Running pass '"; - - OS << P->getPassName() << "'"; - - if (M) { - OS << " on module '" << M->getModuleIdentifier() << "'.\n"; - return; - } - if (V == 0) { - OS << '\n'; - return; - } - - OS << " on "; - if (isa<Function>(V)) - OS << "function"; - else if (isa<BasicBlock>(V)) - OS << "basic block"; - else - OS << "value"; - - OS << " '"; - WriteAsOperand(OS, V, /*PrintTy=*/false, M); - OS << "'\n"; +void ModulePassManager::run() { + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(M)) + if (AM) AM->invalidateAll(M); } - -namespace { - -//===----------------------------------------------------------------------===// -// BBPassManager -// -/// BBPassManager manages BasicBlockPass. It batches all the -/// pass together and sequence them to process one basic block before -/// processing next basic block. -class BBPassManager : public PMDataManager, public FunctionPass { - -public: - static char ID; - explicit BBPassManager() - : PMDataManager(), FunctionPass(ID) {} - - /// Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the function, and if so, return true. - bool runOnFunction(Function &F); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - bool doInitialization(Module &M); - bool doInitialization(Function &F); - bool doFinalization(Module &M); - bool doFinalization(Function &F); - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - - virtual const char *getPassName() const { - return "BasicBlock Pass Manager"; - } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - BP->dumpPassStructure(Offset + 1); - dumpLastUses(BP, Offset+1); - } - } - - BasicBlockPass *getContainedPass(unsigned N) { - assert(N < PassVector.size() && "Pass number out of range!"); - BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]); - return BP; - } - - virtual PassManagerType getPassManagerType() const { - return PMT_BasicBlockPassManager; - } -}; - -char BBPassManager::ID = 0; -} - -namespace llvm { - -//===----------------------------------------------------------------------===// -// FunctionPassManagerImpl -// -/// FunctionPassManagerImpl manages FPPassManagers -class FunctionPassManagerImpl : public Pass, - public PMDataManager, - public PMTopLevelManager { - virtual void anchor(); -private: - bool wasRun; -public: - static char ID; - explicit FunctionPassManagerImpl() : - Pass(PT_PassManager, ID), PMDataManager(), - PMTopLevelManager(new FPPassManager()), wasRun(false) {} - - /// add - Add a pass to the queue of passes to run. This passes ownership of - /// the Pass to the PassManager. When the PassManager is destroyed, the pass - /// will be destroyed as well, so there is no need to delete the pass. This - /// implies that all passes MUST be allocated with 'new'. - void add(Pass *P) { - schedulePass(P); - } - - /// createPrinterPass - Get a function printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintFunctionPass(Banner, &O); - } - - // Prepare for running an on the fly pass, freeing memory if needed - // from a previous run. - void releaseMemoryOnTheFly(); - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool run(Function &F); - - /// doInitialization - Run all of the initializers for the function passes. - /// - bool doInitialization(Module &M); - - /// doFinalization - Run all of the finalizers for the function passes. - /// - bool doFinalization(Module &M); - - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { - return PMT_FunctionPassManager; - } - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - FPPassManager *getContainedManager(unsigned N) { - assert(N < PassManagers.size() && "Pass number out of range!"); - FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); - return FP; - } -}; - -void FunctionPassManagerImpl::anchor() {} - -char FunctionPassManagerImpl::ID = 0; - -//===----------------------------------------------------------------------===// -// MPPassManager -// -/// MPPassManager manages ModulePasses and function pass managers. -/// It batches all Module passes and function pass managers together and -/// sequences them to process one module. -class MPPassManager : public Pass, public PMDataManager { -public: - static char ID; - explicit MPPassManager() : - Pass(PT_PassManager, ID), PMDataManager() { } - - // Delete on the fly managers. - virtual ~MPPassManager() { - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - delete FPP; - } - } - - /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); - } - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool runOnModule(Module &M); - - using llvm::Pass::doInitialization; - using llvm::Pass::doFinalization; - - /// doInitialization - Run all of the initializers for the module passes. - /// - bool doInitialization(); - - /// doFinalization - Run all of the finalizers for the module passes. - /// - bool doFinalization(); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - /// Add RequiredPass into list of lower level passes required by pass P. - /// RequiredPass is run on the fly by Pass Manager when P requests it - /// through getAnalysis interface. - virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); - - /// Return function pass corresponding to PassInfo PI, that is - /// required by module pass MP. Instantiate analysis pass, by using - /// its runOnFunction() for function F. - virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F); - - virtual const char *getPassName() const { - return "Module Pass Manager"; - } - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - ModulePass *MP = getContainedPass(Index); - MP->dumpPassStructure(Offset + 1); - std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I = - OnTheFlyManagers.find(MP); - if (I != OnTheFlyManagers.end()) - I->second->dumpPassStructure(Offset + 2); - dumpLastUses(MP, Offset+1); - } - } - - ModulePass *getContainedPass(unsigned N) { - assert(N < PassVector.size() && "Pass number out of range!"); - return static_cast<ModulePass *>(PassVector[N]); - } - - virtual PassManagerType getPassManagerType() const { - return PMT_ModulePassManager; - } - - private: - /// Collection of on the fly FPPassManagers. These managers manage - /// function passes that are required by module passes. - std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; -}; - -char MPPassManager::ID = 0; -//===----------------------------------------------------------------------===// -// PassManagerImpl -// - -/// PassManagerImpl manages MPPassManagers -class PassManagerImpl : public Pass, - public PMDataManager, - public PMTopLevelManager { - virtual void anchor(); - -public: - static char ID; - explicit PassManagerImpl() : - Pass(PT_PassManager, ID), PMDataManager(), - PMTopLevelManager(new MPPassManager()) {} - - /// add - Add a pass to the queue of passes to run. This passes ownership of - /// the Pass to the PassManager. When the PassManager is destroyed, the pass - /// will be destroyed as well, so there is no need to delete the pass. This - /// implies that all passes MUST be allocated with 'new'. - void add(Pass *P) { - schedulePass(P); - } - - /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); - } - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool run(Module &M); - - using llvm::Pass::doInitialization; - using llvm::Pass::doFinalization; - - /// doInitialization - Run all of the initializers for the module passes. - /// - bool doInitialization(); - - /// doFinalization - Run all of the finalizers for the module passes. - /// - bool doFinalization(); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { - return PMT_ModulePassManager; - } - - MPPassManager *getContainedManager(unsigned N) { - assert(N < PassManagers.size() && "Pass number out of range!"); - MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]); - return MP; - } -}; - -void PassManagerImpl::anchor() {} - -char PassManagerImpl::ID = 0; -} // End of llvm namespace - -namespace { - -//===----------------------------------------------------------------------===// -/// TimingInfo Class - This class is used to calculate information about the -/// amount of time each pass takes to execute. This only happens when -/// -time-passes is enabled on the command line. -/// - -static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex; - -class TimingInfo { - DenseMap<Pass*, Timer*> TimingData; - TimerGroup TG; -public: - // Use 'create' member to get this. - TimingInfo() : TG("... Pass execution timing report ...") {} - - // TimingDtor - Print out information about timing information - ~TimingInfo() { - // Delete all of the timers, which accumulate their info into the - // TimerGroup. - for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(), - E = TimingData.end(); I != E; ++I) - delete I->second; - // TimerGroup is deleted next, printing the report. - } - - // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non null value (if the -time-passes option is enabled) or it leaves it - // null. It may be called multiple times. - static void createTheTimeInfo(); - - /// getPassTimer - Return the timer for the specified pass if it exists. - Timer *getPassTimer(Pass *P) { - if (P->getAsPMDataManager()) - return 0; - - sys::SmartScopedLock<true> Lock(*TimingInfoMutex); - Timer *&T = TimingData[P]; - if (T == 0) - T = new Timer(P->getPassName(), TG); - return T; - } -}; - -} // End of anon namespace - -static TimingInfo *TheTimeInfo; - -//===----------------------------------------------------------------------===// -// PMTopLevelManager implementation - -/// Initialize top level manager. Create first pass manager. -PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { - PMDM->setTopLevelManager(this); - addPassManager(PMDM); - activeStack.push(PMDM); -} - -/// Set pass P as the last user of the given analysis passes. -void -PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) { - unsigned PDepth = 0; - if (P->getResolver()) - PDepth = P->getResolver()->getPMDataManager().getDepth(); - - for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(), - E = AnalysisPasses.end(); I != E; ++I) { - Pass *AP = *I; - LastUser[AP] = P; - - if (P == AP) - continue; - - // Update the last users of passes that are required transitive by AP. - AnalysisUsage *AnUsage = findAnalysisUsage(AP); - const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); - SmallVector<Pass *, 12> LastUses; - SmallVector<Pass *, 12> LastPMUses; - for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), - E = IDs.end(); I != E; ++I) { - Pass *AnalysisPass = findAnalysisPass(*I); - assert(AnalysisPass && "Expected analysis pass to exist."); - AnalysisResolver *AR = AnalysisPass->getResolver(); - assert(AR && "Expected analysis resolver to exist."); - unsigned APDepth = AR->getPMDataManager().getDepth(); - - if (PDepth == APDepth) - LastUses.push_back(AnalysisPass); - else if (PDepth > APDepth) - LastPMUses.push_back(AnalysisPass); - } - - setLastUser(LastUses, P); - - // If this pass has a corresponding pass manager, push higher level - // analysis to this pass manager. - if (P->getResolver()) - setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass()); - - - // If AP is the last user of other passes then make P last user of - // such passes. - for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(), - LUE = LastUser.end(); LUI != LUE; ++LUI) { - if (LUI->second == AP) - // DenseMap iterator is not invalidated here because - // this is just updating existing entries. - LastUser[LUI->first] = P; - } - } -} - -/// Collect passes whose last user is P -void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, - Pass *P) { - DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI = - InversedLastUser.find(P); - if (DMI == InversedLastUser.end()) - return; - - SmallPtrSet<Pass *, 8> &LU = DMI->second; - for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(), - E = LU.end(); I != E; ++I) { - LastUses.push_back(*I); - } - -} - -AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { - AnalysisUsage *AnUsage = NULL; - DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); - if (DMI != AnUsageMap.end()) - AnUsage = DMI->second; - else { - AnUsage = new AnalysisUsage(); - P->getAnalysisUsage(*AnUsage); - AnUsageMap[P] = AnUsage; - } - return AnUsage; -} - -/// Schedule pass P for execution. Make sure that passes required by -/// P are run before P is run. Update analysis info maintained by -/// the manager. Remove dead passes. This is a recursive function. -void PMTopLevelManager::schedulePass(Pass *P) { - - // TODO : Allocate function manager for this pass, other wise required set - // may be inserted into previous function manager - - // Give pass a chance to prepare the stage. - P->preparePassManager(activeStack); - - // If P is an analysis pass and it is available then do not - // generate the analysis again. Stale analysis info should not be - // available at this point. - const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo(P->getPassID()); - if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) { - delete P; - return; - } - - AnalysisUsage *AnUsage = findAnalysisUsage(P); - - bool checkAnalysis = true; - while (checkAnalysis) { - checkAnalysis = false; - - const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); - for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(), - E = RequiredSet.end(); I != E; ++I) { - - Pass *AnalysisPass = findAnalysisPass(*I); - if (!AnalysisPass) { - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); - - if (PI == NULL) { - // Pass P is not in the global PassRegistry - dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n"; - dbgs() << "Verify if there is a pass dependency cycle." << "\n"; - dbgs() << "Required Passes:" << "\n"; - for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(), - E = RequiredSet.end(); I2 != E && I2 != I; ++I2) { - Pass *AnalysisPass2 = findAnalysisPass(*I2); - if (AnalysisPass2) { - dbgs() << "\t" << AnalysisPass2->getPassName() << "\n"; - } else { - dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n"; - dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n"; - dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n"; - } - } - } - - assert(PI && "Expected required passes to be initialized"); - AnalysisPass = PI->createPass(); - if (P->getPotentialPassManagerType () == - AnalysisPass->getPotentialPassManagerType()) - // Schedule analysis pass that is managed by the same pass manager. - schedulePass(AnalysisPass); - else if (P->getPotentialPassManagerType () > - AnalysisPass->getPotentialPassManagerType()) { - // Schedule analysis pass that is managed by a new manager. - schedulePass(AnalysisPass); - // Recheck analysis passes to ensure that required analyses that - // are already checked are still available. - checkAnalysis = true; - } else - // Do not schedule this analysis. Lower level analsyis - // passes are run on the fly. - delete AnalysisPass; +bool FunctionPassManager::run(Module *M) { + bool Changed = false; + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(I)) { + Changed = true; + if (AM) AM->invalidateAll(I); } - } - } - - // Now all required passes are available. - if (ImmutablePass *IP = P->getAsImmutablePass()) { - // P is a immutable pass and it will be managed by this - // top level manager. Set up analysis resolver to connect them. - PMDataManager *DM = getAsPMDataManager(); - AnalysisResolver *AR = new AnalysisResolver(*DM); - P->setResolver(AR); - DM->initializeAnalysisImpl(P); - addImmutablePass(IP); - DM->recordAvailableAnalysis(IP); - return; - } - - if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) { - Pass *PP = P->createPrinterPass( - dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***"); - PP->assignPassManager(activeStack, getTopLevelPassManagerType()); - } - - // Add the requested pass to the best available pass manager. - P->assignPassManager(activeStack, getTopLevelPassManagerType()); - - if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) { - Pass *PP = P->createPrinterPass( - dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***"); - PP->assignPassManager(activeStack, getTopLevelPassManagerType()); - } -} - -/// Find the pass that implements Analysis AID. Search immutable -/// passes and all pass managers. If desired pass is not found -/// then return NULL. -Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { - - // Check pass managers - for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - if (Pass *P = (*I)->findAnalysisPass(AID, false)) - return P; - - // Check other pass managers - for (SmallVectorImpl<PMDataManager *>::iterator - I = IndirectPassManagers.begin(), - E = IndirectPassManagers.end(); I != E; ++I) - if (Pass *P = (*I)->findAnalysisPass(AID, false)) - return P; - - // Check the immutable passes. Iterate in reverse order so that we find - // the most recently registered passes first. - for (SmallVector<ImmutablePass *, 8>::reverse_iterator I = - ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) { - AnalysisID PI = (*I)->getPassID(); - if (PI == AID) - return *I; - - // If Pass not found then check the interfaces implemented by Immutable Pass - const PassInfo *PassInf = - PassRegistry::getPassRegistry()->getPassInfo(PI); - assert(PassInf && "Expected all immutable passes to be initialized"); - const std::vector<const PassInfo*> &ImmPI = - PassInf->getInterfacesImplemented(); - for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(), - EE = ImmPI.end(); II != EE; ++II) { - if ((*II)->getTypeInfo() == AID) - return *I; - } - } - - return 0; -} - -// Print passes managed by this top level manager. -void PMTopLevelManager::dumpPasses() const { - - if (PassDebugging < Structure) - return; - - // Print out the immutable passes - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { - ImmutablePasses[i]->dumpPassStructure(0); - } - - // Every class that derives from PMDataManager also derives from Pass - // (sometimes indirectly), but there's no inheritance relationship - // between PMDataManager and Pass, so we have to getAsPass to get - // from a PMDataManager* to a Pass*. - for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - (*I)->getAsPass()->dumpPassStructure(1); -} - -void PMTopLevelManager::dumpArguments() const { - - if (PassDebugging < Arguments) - return; - - dbgs() << "Pass Arguments: "; - for (SmallVector<ImmutablePass *, 8>::const_iterator I = - ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - if (const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) { - assert(PI && "Expected all immutable passes to be initialized"); - if (!PI->isAnalysisGroup()) - dbgs() << " -" << PI->getPassArgument(); - } - for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - (*I)->dumpPassArguments(); - dbgs() << "\n"; + return Changed; } -void PMTopLevelManager::initializeAllAnalysisInfo() { - for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - (*I)->initializeAnalysisInfo(); +void AnalysisManager::invalidateAll(Function *F) { + assert(F->getParent() == M && "Invalidating a function from another module!"); - // Initailize other pass managers - for (SmallVectorImpl<PMDataManager *>::iterator - I = IndirectPassManagers.begin(), E = IndirectPassManagers.end(); + // First invalidate any module results we still have laying about. + // FIXME: This is a total hack based on the fact that erasure doesn't + // invalidate iteration for DenseMap. + for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), + E = ModuleAnalysisResults.end(); I != E; ++I) - (*I)->initializeAnalysisInfo(); - - for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(), - DME = LastUser.end(); DMI != DME; ++DMI) { - DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI = - InversedLastUser.find(DMI->second); - if (InvDMI != InversedLastUser.end()) { - SmallPtrSet<Pass *, 8> &L = InvDMI->second; - L.insert(DMI->first); + if (I->second->invalidate(M)) + ModuleAnalysisResults.erase(I); + + // Now clear all the invalidated results associated specifically with this + // function. + SmallVector<void *, 8> InvalidatedPassIDs; + FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; + for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), + E = ResultsList.end(); + I != E;) + if (I->second->invalidate(F)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); } else { - SmallPtrSet<Pass *, 8> L; L.insert(DMI->first); - InversedLastUser[DMI->second] = L; + ++I; } - } -} - -/// Destructor -PMTopLevelManager::~PMTopLevelManager() { - for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - delete *I; - - for (SmallVectorImpl<ImmutablePass *>::iterator - I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - delete *I; - - for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(), - DME = AnUsageMap.end(); DMI != DME; ++DMI) - delete DMI->second; -} - -//===----------------------------------------------------------------------===// -// PMDataManager implementation - -/// Augement AvailableAnalysis by adding analysis made available by pass P. -void PMDataManager::recordAvailableAnalysis(Pass *P) { - AnalysisID PI = P->getPassID(); - - AvailableAnalysis[PI] = P; - - assert(!AvailableAnalysis.empty()); - - // This pass is the current implementation of all of the interfaces it - // implements as well. - const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI); - if (PInf == 0) return; - const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) - AvailableAnalysis[II[i]->getTypeInfo()] = P; + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } -// Return true if P preserves high level analysis used by other -// passes managed by this manager -bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - if (AnUsage->getPreservesAll()) - return true; - - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), - E = HigherLevelAnalysis.end(); I != E; ++I) { - Pass *P1 = *I; - if (P1->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), - P1->getPassID()) == - PreservedSet.end()) - return false; - } - - return true; -} - -/// verifyPreservedAnalysis -- Verify analysis preserved by pass P. -void PMDataManager::verifyPreservedAnalysis(Pass *P) { - // Don't do this unless assertions are enabled. -#ifdef NDEBUG - return; -#endif - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - - // Verify preserved analysis - for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), - E = PreservedSet.end(); I != E; ++I) { - AnalysisID AID = *I; - if (Pass *AP = findAnalysisPass(AID, true)) { - TimeRegion PassTimer(getPassTimer(AP)); - AP->verifyAnalysis(); - } - } -} - -/// Remove Analysis not preserved by Pass P -void PMDataManager::removeNotPreservedAnalysis(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - if (AnUsage->getPreservesAll()) - return; - - const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet(); - for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(), - E = AvailableAnalysis.end(); I != E; ) { - DenseMap<AnalysisID, Pass*>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == - PreservedSet.end()) { - // Remove this analysis - if (PassDebugging >= Details) { - Pass *S = Info->second; - dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; - dbgs() << S->getPassName() << "'\n"; - } - AvailableAnalysis.erase(Info); - } - } - - // Check inherited analysis also. If P is not preserving analysis - // provided by parent manager then remove it here. - for (unsigned Index = 0; Index < PMT_Last; ++Index) { - - if (!InheritedAnalysis[Index]) - continue; - - for (DenseMap<AnalysisID, Pass*>::iterator - I = InheritedAnalysis[Index]->begin(), - E = InheritedAnalysis[Index]->end(); I != E; ) { - DenseMap<AnalysisID, Pass *>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && - std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == - PreservedSet.end()) { - // Remove this analysis - if (PassDebugging >= Details) { - Pass *S = Info->second; - dbgs() << " -- '" << P->getPassName() << "' is not preserving '"; - dbgs() << S->getPassName() << "'\n"; - } - InheritedAnalysis[Index]->erase(Info); - } - } - } -} - -/// Remove analysis passes that are not used any longer -void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg, - enum PassDebuggingString DBG_STR) { - - SmallVector<Pass *, 12> DeadPasses; - - // If this is a on the fly manager then it does not have TPM. - if (!TPM) - return; - - TPM->collectLastUses(DeadPasses, P); - - if (PassDebugging >= Details && !DeadPasses.empty()) { - dbgs() << " -*- '" << P->getPassName(); - dbgs() << "' is the last user of following pass instances."; - dbgs() << " Free these instances\n"; - } - - for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(), - E = DeadPasses.end(); I != E; ++I) - freePass(*I, Msg, DBG_STR); -} - -void PMDataManager::freePass(Pass *P, StringRef Msg, - enum PassDebuggingString DBG_STR) { - dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg); - - { - // If the pass crashes releasing memory, remember this. - PassManagerPrettyStackEntry X(P); - TimeRegion PassTimer(getPassTimer(P)); - - P->releaseMemory(); - } - - AnalysisID PI = P->getPassID(); - if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) { - // Remove the pass itself (if it is not already removed). - AvailableAnalysis.erase(PI); - - // Remove all interfaces this pass implements, for which it is also - // listed as the available implementation. - const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) { - DenseMap<AnalysisID, Pass*>::iterator Pos = - AvailableAnalysis.find(II[i]->getTypeInfo()); - if (Pos != AvailableAnalysis.end() && Pos->second == P) - AvailableAnalysis.erase(Pos); - } - } -} - -/// Add pass P into the PassVector. Update -/// AvailableAnalysis appropriately if ProcessAnalysis is true. -void PMDataManager::add(Pass *P, bool ProcessAnalysis) { - // This manager is going to manage pass P. Set up analysis resolver - // to connect them. - AnalysisResolver *AR = new AnalysisResolver(*this); - P->setResolver(AR); - - // If a FunctionPass F is the last user of ModulePass info M - // then the F's manager, not F, records itself as a last user of M. - SmallVector<Pass *, 12> TransferLastUses; - - if (!ProcessAnalysis) { - // Add pass - PassVector.push_back(P); - return; - } - - // At the moment, this pass is the last user of all required passes. - SmallVector<Pass *, 12> LastUses; - SmallVector<Pass *, 8> RequiredPasses; - SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable; - - unsigned PDepth = this->getDepth(); - - collectRequiredAnalysis(RequiredPasses, - ReqAnalysisNotAvailable, P); - for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), - E = RequiredPasses.end(); I != E; ++I) { - Pass *PRequired = *I; - unsigned RDepth = 0; - - assert(PRequired->getResolver() && "Analysis Resolver is not set"); - PMDataManager &DM = PRequired->getResolver()->getPMDataManager(); - RDepth = DM.getDepth(); - - if (PDepth == RDepth) - LastUses.push_back(PRequired); - else if (PDepth > RDepth) { - // Let the parent claim responsibility of last use - TransferLastUses.push_back(PRequired); - // Keep track of higher level analysis used by this manager. - HigherLevelAnalysis.push_back(PRequired); - } else - llvm_unreachable("Unable to accommodate Required Pass"); - } - - // Set P as P's last user until someone starts using P. - // However, if P is a Pass Manager then it does not need - // to record its last user. - if (P->getAsPMDataManager() == 0) - LastUses.push_back(P); - TPM->setLastUser(LastUses, P); - - if (!TransferLastUses.empty()) { - Pass *My_PM = getAsPass(); - TPM->setLastUser(TransferLastUses, My_PM); - TransferLastUses.clear(); - } - - // Now, take care of required analyses that are not available. - for (SmallVectorImpl<AnalysisID>::iterator - I = ReqAnalysisNotAvailable.begin(), - E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); - Pass *AnalysisPass = PI->createPass(); - this->addLowerLevelRequiredPass(P, AnalysisPass); - } - - // Take a note of analysis required and made available by this pass. - // Remove the analysis not preserved by this pass - removeNotPreservedAnalysis(P); - recordAvailableAnalysis(P); - - // Add pass - PassVector.push_back(P); -} - - -/// Populate RP with analysis pass that are required by -/// pass P and are available. Populate RP_NotAvail with analysis -/// pass that are required by pass P but are not available. -void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP, - SmallVectorImpl<AnalysisID> &RP_NotAvail, - Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); - for (AnalysisUsage::VectorType::const_iterator - I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); - else - RP_NotAvail.push_back(*I); - } - - const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); - for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), - E = IDs.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); - else - RP_NotAvail.push_back(*I); - } -} - -// All Required analyses should be available to the pass as it runs! Here -// we fill in the AnalysisImpls member of the pass so that it can -// successfully use the getAnalysis() method to retrieve the -// implementations it needs. -// -void PMDataManager::initializeAnalysisImpl(Pass *P) { - AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - - for (AnalysisUsage::VectorType::const_iterator - I = AnUsage->getRequiredSet().begin(), - E = AnUsage->getRequiredSet().end(); I != E; ++I) { - Pass *Impl = findAnalysisPass(*I, true); - if (Impl == 0) - // This may be analysis pass that is initialized on the fly. - // If that is not the case then it will raise an assert when it is used. - continue; - AnalysisResolver *AR = P->getResolver(); - assert(AR && "Analysis Resolver is not set"); - AR->addAnalysisImplsPair(*I, Impl); - } -} - -/// Find the pass that implements Analysis AID. If desired pass is not found -/// then return NULL. -Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) { - - // Check if AvailableAnalysis map has one entry. - DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID); - - if (I != AvailableAnalysis.end()) - return I->second; - - // Search Parents through TopLevelManager - if (SearchParent) - return TPM->findAnalysisPass(AID); - - return NULL; -} - -// Print list of passes that are last used by P. -void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ - - SmallVector<Pass *, 12> LUses; - - // If this is a on the fly manager then it does not have TPM. - if (!TPM) - return; - - TPM->collectLastUses(LUses, P); - - for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), - E = LUses.end(); I != E; ++I) { - llvm::dbgs() << "--" << std::string(Offset*2, ' '); - (*I)->dumpPassStructure(0); - } -} - -void PMDataManager::dumpPassArguments() const { - for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(), - E = PassVector.end(); I != E; ++I) { - if (PMDataManager *PMD = (*I)->getAsPMDataManager()) - PMD->dumpPassArguments(); - else - if (const PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) - if (!PI->isAnalysisGroup()) - dbgs() << " -" << PI->getPassArgument(); - } -} - -void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, - enum PassDebuggingString S2, - StringRef Msg) { - if (PassDebugging < Executions) - return; - dbgs() << (void*)this << std::string(getDepth()*2+1, ' '); - switch (S1) { - case EXECUTION_MSG: - dbgs() << "Executing Pass '" << P->getPassName(); - break; - case MODIFICATION_MSG: - dbgs() << "Made Modification '" << P->getPassName(); - break; - case FREEING_MSG: - dbgs() << " Freeing Pass '" << P->getPassName(); - break; - default: - break; - } - switch (S2) { - case ON_BASICBLOCK_MSG: - dbgs() << "' on BasicBlock '" << Msg << "'...\n"; - break; - case ON_FUNCTION_MSG: - dbgs() << "' on Function '" << Msg << "'...\n"; - break; - case ON_MODULE_MSG: - dbgs() << "' on Module '" << Msg << "'...\n"; - break; - case ON_REGION_MSG: - dbgs() << "' on Region '" << Msg << "'...\n"; - break; - case ON_LOOP_MSG: - dbgs() << "' on Loop '" << Msg << "'...\n"; - break; - case ON_CG_MSG: - dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n"; - break; - default: - break; - } -} - -void PMDataManager::dumpRequiredSet(const Pass *P) const { - if (PassDebugging < Details) - return; - - AnalysisUsage analysisUsage; - P->getAnalysisUsage(analysisUsage); - dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet()); -} - -void PMDataManager::dumpPreservedSet(const Pass *P) const { - if (PassDebugging < Details) - return; - - AnalysisUsage analysisUsage; - P->getAnalysisUsage(analysisUsage); - dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); -} - -void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, - const AnalysisUsage::VectorType &Set) const { - assert(PassDebugging >= Details); - if (Set.empty()) - return; - dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; - for (unsigned i = 0; i != Set.size(); ++i) { - if (i) dbgs() << ','; - const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]); - if (!PInf) { - // Some preserved passes, such as AliasAnalysis, may not be initialized by - // all drivers. - dbgs() << " Uninitialized Pass"; - continue; - } - dbgs() << ' ' << PInf->getPassName(); - } - dbgs() << '\n'; -} - -/// Add RequiredPass into list of lower level passes required by pass P. -/// RequiredPass is run on the fly by Pass Manager when P requests it -/// through getAnalysis interface. -/// This should be handled by specific pass manager. -void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { - if (TPM) { - TPM->dumpArguments(); - TPM->dumpPasses(); - } - - // Module Level pass may required Function Level analysis info - // (e.g. dominator info). Pass manager uses on the fly function pass manager - // to provide this on demand. In that case, in Pass manager terminology, - // module level pass is requiring lower level analysis info managed by - // lower level pass manager. - - // When Pass manager is not able to order required analysis info, Pass manager - // checks whether any lower level manager will be able to provide this - // analysis info on demand or not. -#ifndef NDEBUG - dbgs() << "Unable to schedule '" << RequiredPass->getPassName(); - dbgs() << "' required by '" << P->getPassName() << "'\n"; -#endif - llvm_unreachable("Unable to schedule pass"); -} - -Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { - llvm_unreachable("Unable to find on the fly pass"); -} - -// Destructor -PMDataManager::~PMDataManager() { - for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(), - E = PassVector.end(); I != E; ++I) - delete *I; -} - -//===----------------------------------------------------------------------===// -// NOTE: Is this the right place to define this method ? -// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist. -Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const { - return PM.findAnalysisPass(ID, dir); -} - -Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, - Function &F) { - return PM.getOnTheFlyPass(P, AnalysisPI, F); -} - -//===----------------------------------------------------------------------===// -// BBPassManager implementation - -/// Execute all of the passes scheduled for execution by invoking -/// runOnBasicBlock method. Keep track of whether any of the passes modifies -/// the function, and if so, return true. -bool BBPassManager::runOnFunction(Function &F) { - if (F.isDeclaration()) - return false; - - bool Changed = doInitialization(F); - - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); - dumpRequiredSet(BP); - - initializeAnalysisImpl(BP); - - { - // If the pass crashes, remember this. - PassManagerPrettyStackEntry X(BP, *I); - TimeRegion PassTimer(getPassTimer(BP)); - - LocalChanged |= BP->runOnBasicBlock(*I); +void AnalysisManager::invalidateAll(Module *M) { + // First invalidate any module results we still have laying about. + // FIXME: This is a total hack based on the fact that erasure doesn't + // invalidate iteration for DenseMap. + for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), + E = ModuleAnalysisResults.end(); + I != E; ++I) + if (I->second->invalidate(M)) + ModuleAnalysisResults.erase(I); + + // Now walk all of the functions for which there are cached results, and + // attempt to invalidate each of those as the entire module may have changed. + // FIXME: How do we handle functions which have been deleted or RAUWed? + SmallVector<void *, 8> InvalidatedPassIDs; + for (FunctionAnalysisResultListMapT::iterator + FI = FunctionAnalysisResultLists.begin(), + FE = FunctionAnalysisResultLists.end(); + FI != FE; ++FI) { + Function *F = FI->first; + FunctionAnalysisResultListT &ResultsList = FI->second; + for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), + E = ResultsList.end(); + I != E;) + if (I->second->invalidate(F)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); + } else { + ++I; } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, - I->getName()); - dumpPreservedSet(BP); - - verifyPreservedAnalysis(BP); - removeNotPreservedAnalysis(BP); - recordAvailableAnalysis(BP); - removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); - } - - return doFinalization(F) || Changed; -} - -// Implement doInitialization and doFinalization -bool BBPassManager::doInitialization(Module &M) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - return Changed; -} - -bool BBPassManager::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - return Changed; -} - -bool BBPassManager::doInitialization(Function &F) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doInitialization(F); + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } - - return Changed; } -bool BBPassManager::doFinalization(Function &F) { - bool Changed = false; +const AnalysisManager::AnalysisResultConcept<Module> & +AnalysisManager::getResultImpl(void *PassID, Module *M) { + assert(M == this->M && "Wrong module used when querying the AnalysisManager"); + ModuleAnalysisResultMapT::iterator RI; + bool Inserted; + llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( + PassID, polymorphic_ptr<AnalysisResultConcept<Module> >())); - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - BasicBlockPass *BP = getContainedPass(Index); - Changed |= BP->doFinalization(F); + if (Inserted) { + // We don't have a cached result for this result. Look up the pass and run + // it to produce a result, which we then add to the cache. + ModuleAnalysisPassMapT::const_iterator PI = + ModuleAnalysisPasses.find(PassID); + assert(PI != ModuleAnalysisPasses.end() && + "Analysis passes must be registered prior to being queried!"); + RI->second = PI->second->run(M); } - return Changed; + return *RI->second; } +const AnalysisManager::AnalysisResultConcept<Function> & +AnalysisManager::getResultImpl(void *PassID, Function *F) { + assert(F->getParent() == M && "Analyzing a function from another module!"); -//===----------------------------------------------------------------------===// -// FunctionPassManager implementation - -/// Create new Function pass manager -FunctionPassManager::FunctionPassManager(Module *m) : M(m) { - FPM = new FunctionPassManagerImpl(); - // FPM is the top level manager. - FPM->setTopLevelManager(FPM); - - AnalysisResolver *AR = new AnalysisResolver(*FPM); - FPM->setResolver(AR); -} - -FunctionPassManager::~FunctionPassManager() { - delete FPM; -} + FunctionAnalysisResultMapT::iterator RI; + bool Inserted; + llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( + std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); -/// add - Add a pass to the queue of passes to run. This passes -/// ownership of the Pass to the PassManager. When the -/// PassManager_X is destroyed, the pass will be destroyed as well, so -/// there is no need to delete the pass. (TODO delete passes.) -/// This implies that all passes MUST be allocated with 'new'. -void FunctionPassManager::add(Pass *P) { - FPM->add(P); -} - -/// run - Execute all of the passes scheduled for execution. Keep -/// track of whether any of the passes modifies the function, and if -/// so, return true. -/// -bool FunctionPassManager::run(Function &F) { - if (F.isMaterializable()) { - std::string errstr; - if (F.Materialize(&errstr)) - report_fatal_error("Error reading bitcode file: " + Twine(errstr)); + if (Inserted) { + // We don't have a cached result for this result. Look up the pass and run + // it to produce a result, which we then add to the cache. + FunctionAnalysisPassMapT::const_iterator PI = + FunctionAnalysisPasses.find(PassID); + assert(PI != FunctionAnalysisPasses.end() && + "Analysis passes must be registered prior to being queried!"); + FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; + ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); + RI->second = llvm::prior(ResultList.end()); } - return FPM->run(F); -} - -/// doInitialization - Run all of the initializers for the function passes. -/// -bool FunctionPassManager::doInitialization() { - return FPM->doInitialization(*M); -} - -/// doFinalization - Run all of the finalizers for the function passes. -/// -bool FunctionPassManager::doFinalization() { - return FPM->doFinalization(*M); -} - -//===----------------------------------------------------------------------===// -// FunctionPassManagerImpl implementation -// -bool FunctionPassManagerImpl::doInitialization(Module &M) { - bool Changed = false; - - dumpArguments(); - dumpPasses(); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doInitialization(M); - } - - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->doInitialization(M); - - return Changed; + return *RI->second->second; } -bool FunctionPassManagerImpl::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index) - Changed |= getContainedManager(Index)->doFinalization(M); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doFinalization(M); - } - - return Changed; +void AnalysisManager::invalidateImpl(void *PassID, Module *M) { + assert(M == this->M && "Invalidating a pass over a different module!"); + ModuleAnalysisResults.erase(PassID); } -/// cleanup - After running all passes, clean up pass manager cache. -void FPPassManager::cleanup() { - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - AnalysisResolver *AR = FP->getResolver(); - assert(AR && "Analysis Resolver is not set"); - AR->clearAnalysisImpls(); - } -} +void AnalysisManager::invalidateImpl(void *PassID, Function *F) { + assert(F->getParent() == M && + "Invalidating a pass over a function from another module!"); -void FunctionPassManagerImpl::releaseMemoryOnTheFly() { - if (!wasRun) + FunctionAnalysisResultMapT::iterator RI = + FunctionAnalysisResults.find(std::make_pair(PassID, F)); + if (RI == FunctionAnalysisResults.end()) return; - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { - FPPassManager *FPPM = getContainedManager(Index); - for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) { - FPPM->getContainedPass(Index)->releaseMemory(); - } - } - wasRun = false; -} - -// Execute all the passes managed by this top level manager. -// Return true if any function is modified by a pass. -bool FunctionPassManagerImpl::run(Function &F) { - bool Changed = false; - TimingInfo::createTheTimeInfo(); - - initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->runOnFunction(F); - - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - getContainedManager(Index)->cleanup(); - - wasRun = true; - return Changed; -} -//===----------------------------------------------------------------------===// -// FPPassManager implementation - -char FPPassManager::ID = 0; -/// Print passes managed by this manager -void FPPassManager::dumpPassStructure(unsigned Offset) { - dbgs().indent(Offset*2) << "FunctionPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - FP->dumpPassStructure(Offset + 1); - dumpLastUses(FP, Offset+1); - } -} - - -/// Execute all of the passes scheduled for execution by invoking -/// runOnFunction method. Keep track of whether any of the passes modifies -/// the function, and if so, return true. -bool FPPassManager::runOnFunction(Function &F) { - if (F.isDeclaration()) - return false; - - bool Changed = false; - - // Collect inherited analysis from Module level pass manager. - populateInheritedAnalysis(TPM->activeStack); - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); - dumpRequiredSet(FP); - - initializeAnalysisImpl(FP); - - { - PassManagerPrettyStackEntry X(FP, F); - TimeRegion PassTimer(getPassTimer(FP)); - - LocalChanged |= FP->runOnFunction(F); - } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); - dumpPreservedSet(FP); - - verifyPreservedAnalysis(FP); - removeNotPreservedAnalysis(FP); - recordAvailableAnalysis(FP); - removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); - } - return Changed; -} - -bool FPPassManager::runOnModule(Module &M) { - bool Changed = false; - - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - Changed |= runOnFunction(*I); - - return Changed; -} - -bool FPPassManager::doInitialization(Module &M) { - bool Changed = false; - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - return Changed; -} - -bool FPPassManager::doFinalization(Module &M) { - bool Changed = false; - - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - return Changed; + FunctionAnalysisResultLists[F].erase(RI->second); } - -//===----------------------------------------------------------------------===// -// MPPassManager implementation - -/// Execute all of the passes scheduled for execution by invoking -/// runOnModule method. Keep track of whether any of the passes modifies -/// the module, and if so, return true. -bool -MPPassManager::runOnModule(Module &M) { - bool Changed = false; - - // Initialize on-the-fly passes - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - Changed |= FPP->doInitialization(M); - } - - // Initialize module passes - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) - Changed |= getContainedPass(Index)->doInitialization(M); - - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - ModulePass *MP = getContainedPass(Index); - bool LocalChanged = false; - - dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); - dumpRequiredSet(MP); - - initializeAnalysisImpl(MP); - - { - PassManagerPrettyStackEntry X(MP, M); - TimeRegion PassTimer(getPassTimer(MP)); - - LocalChanged |= MP->runOnModule(M); - } - - Changed |= LocalChanged; - if (LocalChanged) - dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, - M.getModuleIdentifier()); - dumpPreservedSet(MP); - - verifyPreservedAnalysis(MP); - removeNotPreservedAnalysis(MP); - recordAvailableAnalysis(MP); - removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); - } - - // Finalize module passes - for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index) - Changed |= getContainedPass(Index)->doFinalization(M); - - // Finalize on-the-fly passes - for (std::map<Pass *, FunctionPassManagerImpl *>::iterator - I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); - I != E; ++I) { - FunctionPassManagerImpl *FPP = I->second; - // We don't know when is the last time an on-the-fly pass is run, - // so we need to releaseMemory / finalize here - FPP->releaseMemoryOnTheFly(); - Changed |= FPP->doFinalization(M); - } - - return Changed; -} - -/// Add RequiredPass into list of lower level passes required by pass P. -/// RequiredPass is run on the fly by Pass Manager when P requests it -/// through getAnalysis interface. -void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { - assert(P->getPotentialPassManagerType() == PMT_ModulePassManager && - "Unable to handle Pass that requires lower level Analysis pass"); - assert((P->getPotentialPassManagerType() < - RequiredPass->getPotentialPassManagerType()) && - "Unable to handle Pass that requires lower level Analysis pass"); - - FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; - if (!FPP) { - FPP = new FunctionPassManagerImpl(); - // FPP is the top level manager. - FPP->setTopLevelManager(FPP); - - OnTheFlyManagers[P] = FPP; - } - FPP->add(RequiredPass); - - // Register P as the last user of RequiredPass. - if (RequiredPass) { - SmallVector<Pass *, 1> LU; - LU.push_back(RequiredPass); - FPP->setLastUser(LU, P); - } -} - -/// Return function pass corresponding to PassInfo PI, that is -/// required by module pass MP. Instantiate analysis pass, by using -/// its runOnFunction() for function F. -Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ - FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; - assert(FPP && "Unable to find on the fly pass"); - - FPP->releaseMemoryOnTheFly(); - FPP->run(F); - return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI); -} - - -//===----------------------------------------------------------------------===// -// PassManagerImpl implementation - -// -/// run - Execute all of the passes scheduled for execution. Keep track of -/// whether any of the passes modifies the module, and if so, return true. -bool PassManagerImpl::run(Module &M) { - bool Changed = false; - TimingInfo::createTheTimeInfo(); - - dumpArguments(); - dumpPasses(); - - SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses(); - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doInitialization(M); - } - - initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) - Changed |= getContainedManager(Index)->runOnModule(M); - - for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), - E = IPV.end(); I != E; ++I) { - Changed |= (*I)->doFinalization(M); - } - - return Changed; -} - -//===----------------------------------------------------------------------===// -// PassManager implementation - -/// Create new pass manager -PassManager::PassManager() { - PM = new PassManagerImpl(); - // PM is the top level manager - PM->setTopLevelManager(PM); -} - -PassManager::~PassManager() { - delete PM; -} - -/// add - Add a pass to the queue of passes to run. This passes ownership of -/// the Pass to the PassManager. When the PassManager is destroyed, the pass -/// will be destroyed as well, so there is no need to delete the pass. This -/// implies that all passes MUST be allocated with 'new'. -void PassManager::add(Pass *P) { - PM->add(P); -} - -/// run - Execute all of the passes scheduled for execution. Keep track of -/// whether any of the passes modifies the module, and if so, return true. -bool PassManager::run(Module &M) { - return PM->run(M); -} - -//===----------------------------------------------------------------------===// -// TimingInfo implementation - -bool llvm::TimePassesIsEnabled = false; -static cl::opt<bool,true> -EnableTiming("time-passes", cl::location(TimePassesIsEnabled), - cl::desc("Time each pass, printing elapsed time for each on exit")); - -// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to -// a non null value (if the -time-passes option is enabled) or it leaves it -// null. It may be called multiple times. -void TimingInfo::createTheTimeInfo() { - if (!TimePassesIsEnabled || TheTimeInfo) return; - - // Constructed the first time this is called, iff -time-passes is enabled. - // This guarantees that the object will be constructed before static globals, - // thus it will be destroyed before them. - static ManagedStatic<TimingInfo> TTI; - TheTimeInfo = &*TTI; -} - -/// If TimingInfo is enabled then start pass timer. -Timer *llvm::getPassTimer(Pass *P) { - if (TheTimeInfo) - return TheTimeInfo->getPassTimer(P); - return 0; -} - -//===----------------------------------------------------------------------===// -// PMStack implementation -// - -// Pop Pass Manager from the stack and clear its analysis info. -void PMStack::pop() { - - PMDataManager *Top = this->top(); - Top->initializeAnalysisInfo(); - - S.pop_back(); -} - -// Push PM on the stack and set its top level manager. -void PMStack::push(PMDataManager *PM) { - assert(PM && "Unable to push. Pass Manager expected"); - assert(PM->getDepth()==0 && "Pass Manager depth set too early"); - - if (!this->empty()) { - assert(PM->getPassManagerType() > this->top()->getPassManagerType() - && "pushing bad pass manager to PMStack"); - PMTopLevelManager *TPM = this->top()->getTopLevelManager(); - - assert(TPM && "Unable to find top level manager"); - TPM->addIndirectPassManager(PM); - PM->setTopLevelManager(TPM); - PM->setDepth(this->top()->getDepth()+1); - } else { - assert((PM->getPassManagerType() == PMT_ModulePassManager - || PM->getPassManagerType() == PMT_FunctionPassManager) - && "pushing bad pass manager to PMStack"); - PM->setDepth(1); - } - - S.push_back(PM); -} - -// Dump content of the pass manager stack. -void PMStack::dump() const { - for (std::vector<PMDataManager *>::const_iterator I = S.begin(), - E = S.end(); I != E; ++I) - dbgs() << (*I)->getAsPass()->getPassName() << ' '; - - if (!S.empty()) - dbgs() << '\n'; -} - -/// Find appropriate Module Pass Manager in the PM Stack and -/// add self into that manager. -void ModulePass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - // Find Module Pass Manager - while (!PMS.empty()) { - PassManagerType TopPMType = PMS.top()->getPassManagerType(); - if (TopPMType == PreferredType) - break; // We found desired pass manager - else if (TopPMType > PMT_ModulePassManager) - PMS.pop(); // Pop children pass managers - else - break; - } - assert(!PMS.empty() && "Unable to find appropriate Pass Manager"); - PMS.top()->add(this); -} - -/// Find appropriate Function Pass Manager or Call Graph Pass Manager -/// in the PM Stack and add self into that manager. -void FunctionPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - - // Find Function Pass Manager - while (!PMS.empty()) { - if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) - PMS.pop(); - else - break; - } - - // Create new Function Pass Manager if needed. - FPPassManager *FPP; - if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) { - FPP = (FPPassManager *)PMS.top(); - } else { - assert(!PMS.empty() && "Unable to create Function Pass Manager"); - PMDataManager *PMD = PMS.top(); - - // [1] Create new Function Pass Manager - FPP = new FPPassManager(); - FPP->populateInheritedAnalysis(PMS); - - // [2] Set up new manager's top level manager - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(FPP); - - // [3] Assign manager to manage this new manager. This may create - // and push new managers into PMS - FPP->assignPassManager(PMS, PMD->getPassManagerType()); - - // [4] Push new manager into PMS - PMS.push(FPP); - } - - // Assign FPP as the manager of this pass. - FPP->add(this); -} - -/// Find appropriate Basic Pass Manager or Call Graph Pass Manager -/// in the PM Stack and add self into that manager. -void BasicBlockPass::assignPassManager(PMStack &PMS, - PassManagerType PreferredType) { - BBPassManager *BBP; - - // Basic Pass Manager is a leaf pass manager. It does not handle - // any other pass manager. - if (!PMS.empty() && - PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) { - BBP = (BBPassManager *)PMS.top(); - } else { - // If leaf manager is not Basic Block Pass manager then create new - // basic Block Pass manager. - assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager"); - PMDataManager *PMD = PMS.top(); - - // [1] Create new Basic Block Manager - BBP = new BBPassManager(); - - // [2] Set up new manager's top level manager - // Basic Block Pass Manager does not live by itself - PMTopLevelManager *TPM = PMD->getTopLevelManager(); - TPM->addIndirectPassManager(BBP); - - // [3] Assign manager to manage this new manager. This may create - // and push new managers into PMS - BBP->assignPassManager(PMS, PreferredType); - - // [4] Push new manager into PMS - PMS.push(BBP); - } - - // Assign BBP as the manager of this pass. - BBP->add(this); -} - -PassManagerBase::~PassManagerBase() {} diff --git a/contrib/llvm/lib/IR/PassRegistry.cpp b/contrib/llvm/lib/IR/PassRegistry.cpp index a0b64ed..d3b2f1f 100644 --- a/contrib/llvm/lib/IR/PassRegistry.cpp +++ b/contrib/llvm/lib/IR/PassRegistry.cpp @@ -21,6 +21,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/RWMutex.h" #include <vector> using namespace llvm; @@ -35,7 +36,7 @@ PassRegistry *PassRegistry::getPassRegistry() { return &*PassRegistryObj; } -static ManagedStatic<sys::SmartMutex<true> > Lock; +static ManagedStatic<sys::SmartRWMutex<true> > Lock; //===----------------------------------------------------------------------===// // PassRegistryImpl @@ -72,7 +73,7 @@ void *PassRegistry::getImpl() const { // PassRegistry::~PassRegistry() { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(), @@ -84,14 +85,14 @@ PassRegistry::~PassRegistry() { } const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedReader<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); return I != Impl->PassInfoMap.end() ? I->second : 0; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedReader<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl::StringMapType::const_iterator I = Impl->PassInfoStringMap.find(Arg); @@ -103,7 +104,7 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { // void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); bool Inserted = Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; @@ -120,7 +121,7 @@ void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { } void PassRegistry::unregisterPass(const PassInfo &PI) { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl::MapType::iterator I = Impl->PassInfoMap.find(PI.getTypeInfo()); @@ -132,7 +133,7 @@ void PassRegistry::unregisterPass(const PassInfo &PI) { } void PassRegistry::enumerateWith(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedReader<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), E = Impl->PassInfoMap.end(); I != E; ++I) @@ -160,7 +161,7 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); // Make sure we keep track of the fact that the implementation implements // the interface. @@ -186,13 +187,13 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); Impl->Listeners.push_back(L); } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedLock<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(*Lock); // NOTE: This is necessary, because removeRegistrationListener() can be called // as part of the llvm_shutdown sequence. Since we have no control over the diff --git a/contrib/llvm/lib/IR/Type.cpp b/contrib/llvm/lib/IR/Type.cpp index 46c61fc..432cbc9 100644 --- a/contrib/llvm/lib/IR/Type.cpp +++ b/contrib/llvm/lib/IR/Type.cpp @@ -616,11 +616,7 @@ bool StructType::isLayoutIdentical(StructType *Other) const { /// getTypeByName - Return the type with the specified name, or null if there /// is none by that name. StructType *Module::getTypeByName(StringRef Name) const { - StringMap<StructType*>::iterator I = - getContext().pImpl->NamedStructTypes.find(Name); - if (I != getContext().pImpl->NamedStructTypes.end()) - return I->second; - return 0; + return getContext().pImpl->NamedStructTypes.lookup(Name); } diff --git a/contrib/llvm/lib/IR/TypeFinder.cpp b/contrib/llvm/lib/IR/TypeFinder.cpp index d5e6203..689b903 100644 --- a/contrib/llvm/lib/IR/TypeFinder.cpp +++ b/contrib/llvm/lib/IR/TypeFinder.cpp @@ -44,6 +44,9 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { incorporateType(FI->getType()); + if (FI->hasPrefixData()) + incorporateValue(FI->getPrefixData()); + // First incorporate the arguments. for (Function::const_arg_iterator AI = FI->arg_begin(), AE = FI->arg_end(); AI != AE; ++AI) @@ -91,19 +94,27 @@ void TypeFinder::clear() { /// incorporateType - This method adds the type to the list of used structures /// if it's not in there already. void TypeFinder::incorporateType(Type *Ty) { - // Check to see if we're already visited this type. + // Check to see if we've already visited this type. if (!VisitedTypes.insert(Ty).second) return; - // If this is a structure or opaque type, add a name for the type. - if (StructType *STy = dyn_cast<StructType>(Ty)) - if (!OnlyNamed || STy->hasName()) - StructTypes.push_back(STy); - - // Recursively walk all contained types. - for (Type::subtype_iterator I = Ty->subtype_begin(), - E = Ty->subtype_end(); I != E; ++I) - incorporateType(*I); + SmallVector<Type *, 4> TypeWorklist; + TypeWorklist.push_back(Ty); + do { + Ty = TypeWorklist.pop_back_val(); + + // If this is a structure or opaque type, add a name for the type. + if (StructType *STy = dyn_cast<StructType>(Ty)) + if (!OnlyNamed || STy->hasName()) + StructTypes.push_back(STy); + + // Add all unvisited subtypes to worklist for processing + for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(), + E = Ty->subtype_rend(); + I != E; ++I) + if (VisitedTypes.insert(*I).second) + TypeWorklist.push_back(*I); + } while (!TypeWorklist.empty()); } /// incorporateValue - This method is used to walk operand lists finding types diff --git a/contrib/llvm/lib/IR/Value.cpp b/contrib/llvm/lib/IR/Value.cpp index 89a3c05..62a3b31 100644 --- a/contrib/llvm/lib/IR/Value.cpp +++ b/contrib/llvm/lib/IR/Value.cpp @@ -112,21 +112,20 @@ bool Value::hasNUsesOrMore(unsigned N) const { /// isUsedInBasicBlock - Return true if this value is used in the specified /// basic block. bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { - // Start by scanning over the instructions looking for a use before we start - // the expensive use iteration. - unsigned MaxBlockSize = 3; - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - if (std::find(I->op_begin(), I->op_end(), this) != I->op_end()) + // This can be computed either by scanning the instructions in BB, or by + // scanning the use list of this Value. Both lists can be very long, but + // usually one is quite short. + // + // Scan both lists simultaneously until one is exhausted. This limits the + // search to the shorter list. + BasicBlock::const_iterator BI = BB->begin(), BE = BB->end(); + const_use_iterator UI = use_begin(), UE = use_end(); + for (; BI != BE && UI != UE; ++BI, ++UI) { + // Scan basic block: Check if this Value is used by the instruction at BI. + if (std::find(BI->op_begin(), BI->op_end(), this) != BI->op_end()) return true; - if (--MaxBlockSize == 0) // If the block is larger fall back to use_iterator - break; - } - - if (MaxBlockSize != 0) // We scanned the entire block and found no use. - return false; - - for (const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) { - const Instruction *User = dyn_cast<Instruction>(*I); + // Scan use list: Check if the use at UI is in BB. + const Instruction *User = dyn_cast<Instruction>(*UI); if (User && User->getParent() == BB) return true; } @@ -366,7 +365,8 @@ static Value *stripPointerCastsAndOffsets(Value *V) { break; } V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast) { + } else if (Operator::getOpcode(V) == Instruction::BitCast || + Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast<Operator>(V)->getOperand(0); } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden()) @@ -394,6 +394,42 @@ Value *Value::stripInBoundsConstantOffsets() { return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this); } +Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, + APInt &Offset) { + if (!getType()->isPointerTy()) + return this; + + assert(Offset.getBitWidth() == DL.getPointerSizeInBits(cast<PointerType>( + getType())->getAddressSpace()) && + "The offset must have exactly as many bits as our pointer."); + + // Even though we don't look through PHI nodes, we could be called on an + // instruction in an unreachable block, which may be on a cycle. + SmallPtrSet<Value *, 4> Visited; + Visited.insert(this); + Value *V = this; + do { + if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { + if (!GEP->isInBounds()) + return V; + APInt GEPOffset(Offset); + if (!GEP->accumulateConstantOffset(DL, GEPOffset)) + return V; + Offset = GEPOffset; + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast<Operator>(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + V = GA->getAliasee(); + } else { + return V; + } + assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + } while (Visited.insert(V)); + + return V; +} + Value *Value::stripInBoundsOffsets() { return stripPointerCastsAndOffsets<PSK_InBounds>(this); } @@ -699,9 +735,5 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { #endif } -// Default implementation for CallbackVH. -void CallbackVH::allUsesReplacedWith(Value *) {} - -void CallbackVH::deleted() { - setValPtr(NULL); -} +// Pin the vtable to this file. +void CallbackVH::anchor() {} diff --git a/contrib/llvm/lib/IR/ValueTypes.cpp b/contrib/llvm/lib/IR/ValueTypes.cpp index ba04d60..2d4da95 100644 --- a/contrib/llvm/lib/IR/ValueTypes.cpp +++ b/contrib/llvm/lib/IR/ValueTypes.cpp @@ -134,6 +134,7 @@ std::string EVT::getEVTString() const { case MVT::v16i1: return "v16i1"; case MVT::v32i1: return "v32i1"; case MVT::v64i1: return "v64i1"; + case MVT::v1i8: return "v1i8"; case MVT::v2i8: return "v2i8"; case MVT::v4i8: return "v4i8"; case MVT::v8i8: return "v8i8"; @@ -156,11 +157,15 @@ std::string EVT::getEVTString() const { case MVT::v4i64: return "v4i64"; case MVT::v8i64: return "v8i64"; case MVT::v16i64: return "v16i64"; + case MVT::v1f32: return "v1f32"; case MVT::v2f32: return "v2f32"; case MVT::v2f16: return "v2f16"; + case MVT::v4f16: return "v4f16"; + case MVT::v8f16: return "v8f16"; case MVT::v4f32: return "v4f32"; case MVT::v8f32: return "v8f32"; case MVT::v16f32: return "v16f32"; + case MVT::v1f64: return "v1f64"; case MVT::v2f64: return "v2f64"; case MVT::v4f64: return "v4f64"; case MVT::v8f64: return "v8f64"; @@ -197,6 +202,7 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const { case MVT::v16i1: return VectorType::get(Type::getInt1Ty(Context), 16); case MVT::v32i1: return VectorType::get(Type::getInt1Ty(Context), 32); case MVT::v64i1: return VectorType::get(Type::getInt1Ty(Context), 64); + case MVT::v1i8: return VectorType::get(Type::getInt8Ty(Context), 1); case MVT::v2i8: return VectorType::get(Type::getInt8Ty(Context), 2); case MVT::v4i8: return VectorType::get(Type::getInt8Ty(Context), 4); case MVT::v8i8: return VectorType::get(Type::getInt8Ty(Context), 8); @@ -220,10 +226,14 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const { case MVT::v8i64: return VectorType::get(Type::getInt64Ty(Context), 8); case MVT::v16i64: return VectorType::get(Type::getInt64Ty(Context), 16); case MVT::v2f16: return VectorType::get(Type::getHalfTy(Context), 2); + case MVT::v4f16: return VectorType::get(Type::getHalfTy(Context), 4); + case MVT::v8f16: return VectorType::get(Type::getHalfTy(Context), 8); + case MVT::v1f32: return VectorType::get(Type::getFloatTy(Context), 1); case MVT::v2f32: return VectorType::get(Type::getFloatTy(Context), 2); case MVT::v4f32: return VectorType::get(Type::getFloatTy(Context), 4); case MVT::v8f32: return VectorType::get(Type::getFloatTy(Context), 8); case MVT::v16f32: return VectorType::get(Type::getFloatTy(Context), 16); + case MVT::v1f64: return VectorType::get(Type::getDoubleTy(Context), 1); case MVT::v2f64: return VectorType::get(Type::getDoubleTy(Context), 2); case MVT::v4f64: return VectorType::get(Type::getDoubleTy(Context), 4); case MVT::v8f64: return VectorType::get(Type::getDoubleTy(Context), 8); diff --git a/contrib/llvm/lib/IR/Verifier.cpp b/contrib/llvm/lib/IR/Verifier.cpp index d106173..da6b573 100644 --- a/contrib/llvm/lib/IR/Verifier.cpp +++ b/contrib/llvm/lib/IR/Verifier.cpp @@ -53,8 +53,10 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Assembly/Writer.h" +#include "llvm/DebugInfo.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" @@ -66,6 +68,7 @@ #include "llvm/PassManager.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CallSite.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -74,6 +77,9 @@ #include <cstdarg> using namespace llvm; +static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier", + cl::init(true)); + namespace { // Anonymous namespace for class struct PreVerifier : public FunctionPass { static char ID; // Pass ID, replacement for typeid @@ -93,7 +99,7 @@ namespace { // Anonymous namespace for class for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { if (I->empty() || !I->back().isTerminator()) { - dbgs() << "Basic Block in function '" << F.getName() + dbgs() << "Basic Block in function '" << F.getName() << "' does not have terminator!\n"; WriteAsOperand(dbgs(), I, true); dbgs() << "\n"; @@ -110,7 +116,7 @@ namespace { // Anonymous namespace for class } char PreVerifier::ID = 0; -INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", +INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", false, false) static char &PreVerifyID = PreVerifier::ID; @@ -123,6 +129,7 @@ namespace { Module *Mod; // Module we are verifying right now LLVMContext *Context; // Context within which we are verifying DominatorTree *DT; // Dominator Tree, caution can be null! + const DataLayout *DL; std::string Messages; raw_string_ostream MessagesStr; @@ -142,15 +149,18 @@ namespace { /// the same personality function. const Value *PersonalityFn; + /// Finder keeps track of all debug info MDNodes in a Module. + DebugInfoFinder Finder; + Verifier() : FunctionPass(ID), Broken(false), - action(AbortProcessAction), Mod(0), Context(0), DT(0), + action(AbortProcessAction), Mod(0), Context(0), DT(0), DL(0), MessagesStr(Messages), PersonalityFn(0) { initializeVerifierPass(*PassRegistry::getPassRegistry()); } explicit Verifier(VerifierFailureAction ctn) : FunctionPass(ID), Broken(false), action(ctn), Mod(0), - Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) { + Context(0), DT(0), DL(0), MessagesStr(Messages), PersonalityFn(0) { initializeVerifierPass(*PassRegistry::getPassRegistry()); } @@ -158,6 +168,8 @@ namespace { Mod = &M; Context = &M.getContext(); + DL = getAnalysisIfAvailable<DataLayout>(); + // We must abort before returning back to the pass manager, or else the // pass manager may try to run other passes on the broken module. return abortIfBroken(); @@ -170,10 +182,15 @@ namespace { Mod = F.getParent(); if (!Context) Context = &F.getContext(); + Finder.reset(); visit(F); InstsInThisBlock.clear(); PersonalityFn = 0; + if (!DisableDebugInfoVerifier) + // Verify Debug Info. + verifyDebugInfo(); + // We must abort before returning back to the pass manager, or else the // pass manager may try to run other passes on the broken module. return abortIfBroken(); @@ -188,11 +205,11 @@ namespace { if (I->isDeclaration()) visitFunction(*I); } - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) visitGlobalVariable(*I); - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) visitGlobalAlias(*I); @@ -201,6 +218,14 @@ namespace { visitNamedMDNode(*I); visitModuleFlags(M); + visitModuleIdents(M); + + if (!DisableDebugInfoVerifier) { + Finder.reset(); + Finder.processModule(M); + // Verify Debug Info. + verifyDebugInfo(); + } // If the module is broken, abort at this time. return abortIfBroken(); @@ -242,6 +267,7 @@ namespace { void visitGlobalAlias(GlobalAlias &GA); void visitNamedMDNode(NamedMDNode &NMD); void visitMDNode(MDNode &MD, Function *F); + void visitModuleIdents(Module &M); void visitModuleFlags(Module &M); void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs, SmallVectorImpl<MDNode*> &Requirements); @@ -263,6 +289,7 @@ namespace { void visitIntToPtrInst(IntToPtrInst &I); void visitPtrToIntInst(PtrToIntInst &I); void visitBitCastInst(BitCastInst &I); + void visitAddrSpaceCastInst(AddrSpaceCastInst &I); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitICmpInst(ICmpInst &IC); @@ -301,6 +328,8 @@ namespace { bool VerifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos, SmallVectorImpl<Type*> &ArgTys); + bool VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef<Intrinsic::IITDescriptor> &Infos); bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params); void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction, const Value *V); @@ -309,6 +338,11 @@ namespace { void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, const Value *V); + void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy); + void VerifyConstantExprBitcastType(const ConstantExpr *CE); + + void verifyDebugInfo(); + void WriteValue(const Value *V) { if (!V) return; if (isa<Instruction>(V)) { @@ -406,10 +440,6 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } - - Assert1(!GV.hasLinkOnceODRAutoHideLinkage() || GV.hasDefaultVisibility(), - "linkonce_odr_auto_hide can only have default visibility!", - &GV); } void Verifier::visitGlobalVariable(GlobalVariable &GV) { @@ -450,7 +480,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { } if (GV.hasName() && (GV.getName() == "llvm.used" || - GV.getName() == "llvm.compiler_used")) { + GV.getName() == "llvm.compiler.used")) { Assert1(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); Type *GVType = GV.getType()->getElementType(); @@ -463,24 +493,50 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { Assert1(InitArray, "wrong initalizer for intrinsic global variable", Init); for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) { - Value *V = Init->getOperand(i)->stripPointerCasts(); - // stripPointerCasts strips aliases, so we only need to check for - // variables and functions. - Assert1(isa<GlobalVariable>(V) || isa<Function>(V), - "invalid llvm.used member", V); + Value *V = Init->getOperand(i)->stripPointerCastsNoFollowAliases(); + Assert1( + isa<GlobalVariable>(V) || isa<Function>(V) || isa<GlobalAlias>(V), + "invalid llvm.used member", V); + Assert1(V->hasName(), "members of llvm.used must be named", V); } } } } + if (!GV.hasInitializer()) { + visitGlobalValue(GV); + return; + } + + // Walk any aggregate initializers looking for bitcasts between address spaces + SmallPtrSet<const Value *, 4> Visited; + SmallVector<const Value *, 4> WorkStack; + WorkStack.push_back(cast<Value>(GV.getInitializer())); + + while (!WorkStack.empty()) { + const Value *V = WorkStack.pop_back_val(); + if (!Visited.insert(V)) + continue; + + if (const User *U = dyn_cast<User>(V)) { + for (unsigned I = 0, N = U->getNumOperands(); I != N; ++I) + WorkStack.push_back(U->getOperand(I)); + } + + if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + VerifyConstantExprBitcastType(CE); + if (Broken) + return; + } + } + visitGlobalValue(GV); } void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(!GA.getName().empty(), "Alias name cannot be empty!", &GA); - Assert1(GA.hasExternalLinkage() || GA.hasLocalLinkage() || - GA.hasWeakLinkage(), + Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()), "Alias should have external or external weak linkage!", &GA); Assert1(GA.getAliasee(), "Aliasee cannot be NULL!", &GA); @@ -488,18 +544,29 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { "Alias and aliasee types should match!", &GA); Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); - if (!isa<GlobalValue>(GA.getAliasee())) { - const ConstantExpr *CE = dyn_cast<ConstantExpr>(GA.getAliasee()); - Assert1(CE && + Constant *Aliasee = GA.getAliasee(); + + if (!isa<GlobalValue>(Aliasee)) { + ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee); + Assert1(CE && (CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) && isa<GlobalValue>(CE->getOperand(0)), "Aliasee should be either GlobalValue or bitcast of GlobalValue", &GA); + + if (CE->getOpcode() == Instruction::BitCast) { + unsigned SrcAS = CE->getOperand(0)->getType()->getPointerAddressSpace(); + unsigned DstAS = CE->getType()->getPointerAddressSpace(); + + Assert1(SrcAS == DstAS, + "Alias bitcasts cannot be between different address spaces", + &GA); + } } - const GlobalValue* Aliasee = GA.resolveAliasedGlobal(/*stopOnWeak*/ false); - Assert1(Aliasee, + const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false); + Assert1(Resolved, "Aliasing chain should end with function or global variable", &GA); visitGlobalValue(GA); @@ -553,6 +620,24 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } +void Verifier::visitModuleIdents(Module &M) { + const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); + if (!Idents) + return; + + // llvm.ident takes a list of metadata entry. Each entry has only one string. + // Scan each llvm.ident entry and make sure that this requirement is met. + for (unsigned i = 0, e = Idents->getNumOperands(); i != e; ++i) { + const MDNode *N = Idents->getOperand(i); + Assert1(N->getNumOperands() == 1, + "incorrect number of operands in llvm.ident metadata", N); + Assert1(isa<MDString>(N->getOperand(0)), + ("invalid value for llvm.ident metadata entry operand" + "(the operand should be a string)"), + N->getOperand(0)); + } +} + void Verifier::visitModuleFlags(Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; @@ -654,7 +739,7 @@ void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs, } void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, - bool isFunction, const Value* V) { + bool isFunction, const Value *V) { unsigned Slot = ~0U; for (unsigned I = 0, E = Attrs.getNumSlots(); I != E; ++I) if (Attrs.getSlotIndex(I) == Idx) { @@ -671,8 +756,6 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, if (I->getKindAsEnum() == Attribute::NoReturn || I->getKindAsEnum() == Attribute::NoUnwind || - I->getKindAsEnum() == Attribute::ReadNone || - I->getKindAsEnum() == Attribute::ReadOnly || I->getKindAsEnum() == Attribute::NoInline || I->getKindAsEnum() == Attribute::AlwaysInline || I->getKindAsEnum() == Attribute::OptimizeForSize || @@ -692,15 +775,26 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::SanitizeMemory || I->getKindAsEnum() == Attribute::MinSize || I->getKindAsEnum() == Attribute::NoDuplicate || - I->getKindAsEnum() == Attribute::NoBuiltin) { - if (!isFunction) - CheckFailed("Attribute '" + I->getKindAsString() + - "' only applies to functions!", V); - return; - } else if (isFunction) { - CheckFailed("Attribute '" + I->getKindAsString() + - "' does not apply to functions!", V); + I->getKindAsEnum() == Attribute::Builtin || + I->getKindAsEnum() == Attribute::NoBuiltin || + I->getKindAsEnum() == Attribute::Cold || + I->getKindAsEnum() == Attribute::OptimizeNone) { + if (!isFunction) { + CheckFailed("Attribute '" + I->getAsString() + + "' only applies to functions!", V); return; + } + } else if (I->getKindAsEnum() == Attribute::ReadOnly || + I->getKindAsEnum() == Attribute::ReadNone) { + if (Idx == 0) { + CheckFailed("Attribute '" + I->getAsString() + + "' does not apply to function returns"); + return; + } + } else if (isFunction) { + CheckFailed("Attribute '" + I->getAsString() + + "' does not apply to functions!", V); + return; } } } @@ -830,6 +924,65 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::AlwaysInline)), "Attributes 'noinline and alwaysinline' are incompatible!", V); + + if (Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::OptimizeNone)) { + Assert1(Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoInline), + "Attribute 'optnone' requires 'noinline'!", V); + + Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::OptimizeForSize), + "Attributes 'optsize and optnone' are incompatible!", V); + + Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::MinSize), + "Attributes 'minsize and optnone' are incompatible!", V); + } +} + +void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) { + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + // BitCast implies a no-op cast of type only. No bits change. + // However, you can't cast pointers to anything but pointers. + Assert1(SrcTy->isPointerTy() == DestTy->isPointerTy(), + "Bitcast requires both operands to be pointer or neither", V); + Assert1(SrcBitSize == DestBitSize, + "Bitcast requires types of same width", V); + + // Disallow aggregates. + Assert1(!SrcTy->isAggregateType(), + "Bitcast operand must not be aggregate", V); + Assert1(!DestTy->isAggregateType(), + "Bitcast type must not be aggregate", V); + + // Without datalayout, assume all address spaces are the same size. + // Don't check if both types are not pointers. + // Skip casts between scalars and vectors. + if (!DL || + !SrcTy->isPtrOrPtrVectorTy() || + !DestTy->isPtrOrPtrVectorTy() || + SrcTy->isVectorTy() != DestTy->isVectorTy()) { + return; + } + + unsigned SrcAS = SrcTy->getPointerAddressSpace(); + unsigned DstAS = DestTy->getPointerAddressSpace(); + + Assert1(SrcAS == DstAS, + "Bitcasts between pointers of different address spaces is not legal." + "Use AddrSpaceCast instead.", V); +} + +void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) { + if (CE->getOpcode() == Instruction::BitCast) { + Type *SrcTy = CE->getOperand(0)->getType(); + Type *DstTy = CE->getType(); + VerifyBitcastType(CE, DstTy, SrcTy); + } } bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) { @@ -842,7 +995,7 @@ bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) { || (LastIndex == AttributeSet::FunctionIndex && (LastSlot == 0 || Attrs.getSlotIndex(LastSlot - 1) <= Params))) return true; - + return false; } @@ -861,7 +1014,7 @@ void Verifier::visitFunction(Function &F) { "# formal arguments must match # of arguments for function type!", &F, FT); Assert1(F.getReturnType()->isFirstClassType() || - F.getReturnType()->isVoidTy() || + F.getReturnType()->isVoidTy() || F.getReturnType()->isStructTy(), "Functions cannot return aggregate values!", &F); @@ -876,6 +1029,13 @@ void Verifier::visitFunction(Function &F) { // Check function attributes. VerifyFunctionAttrs(FT, Attrs, &F); + // On function declarations/definitions, we do not support the builtin + // attribute. We do not check this in VerifyFunctionAttrs since that is + // checking for Attributes that can/can not ever be on functions. + Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::Builtin), + "Attribute 'builtin' can only be applied to a callsite.", &F); + // Check that this function meets the restrictions on this calling convention. switch (F.getCallingConv()) { default: @@ -921,25 +1081,25 @@ void Verifier::visitFunction(Function &F) { // Verify that this function (which has a body) is not named "llvm.*". It // is not legal to define intrinsics. Assert1(!isLLVMdotName, "llvm intrinsics cannot be defined!", &F); - + // Check the entry node BasicBlock *Entry = &F.getEntryBlock(); Assert1(pred_begin(Entry) == pred_end(Entry), "Entry block to function must not have predecessors!", Entry); - + // The address of the entry block cannot be taken, unless it is dead. if (Entry->hasAddressTaken()) { Assert1(!BlockAddress::get(Entry)->isConstantUsed(), "blockaddress may not be used with the entry block!", Entry); } } - + // If this function is actually an intrinsic, verify that it is only used in // direct call/invokes, never having its "address taken". if (F.getIntrinsicID()) { const User *U; if (F.hasAddressTaken(&U)) - Assert1(0, "Invalid user of intrinsic instruction!", U); + Assert1(0, "Invalid user of intrinsic instruction!", U); } } @@ -1014,7 +1174,7 @@ void Verifier::visitBranchInst(BranchInst &BI) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); unsigned N = RI.getNumOperands(); - if (F->getReturnType()->isVoidTy()) + if (F->getReturnType()->isVoidTy()) Assert2(N == 0, "Found return instr that returns non-void in Function of void " "return type!", &RI, F->getReturnType()); @@ -1032,29 +1192,14 @@ void Verifier::visitSwitchInst(SwitchInst &SI) { // Check to make sure that all of the constants in the switch instruction // have the same type as the switched-on value. Type *SwitchTy = SI.getCondition()->getType(); - IntegerType *IntTy = cast<IntegerType>(SwitchTy); - IntegersSubsetToBB Mapping; - std::map<IntegersSubset::Range, unsigned> RangeSetMap; + SmallPtrSet<ConstantInt*, 32> Constants; for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { - IntegersSubset CaseRanges = i.getCaseValueEx(); - for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) { - IntegersSubset::Range r = CaseRanges.getItem(ri); - Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(), - "Switch constants must all be same type as switch value!", &SI); - Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(), - "Switch constants must all be same type as switch value!", &SI); - Mapping.add(r); - RangeSetMap[r] = i.getCaseIndex(); - } - } - - IntegersSubsetToBB::RangeIterator errItem; - if (!Mapping.verify(errItem)) { - unsigned CaseIndex = RangeSetMap[errItem->first]; - SwitchInst::CaseIt i(&SI, CaseIndex); - Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx()); + Assert1(i.getCaseValue()->getType() == SwitchTy, + "Switch constants must all be same type as switch value!", &SI); + Assert2(Constants.insert(i.getCaseValue()), + "Duplicate integer as switch case", &SI, i.getCaseValue()); } - + visitTerminatorInst(SI); } @@ -1309,26 +1454,25 @@ void Verifier::visitIntToPtrInst(IntToPtrInst &I) { } void Verifier::visitBitCastInst(BitCastInst &I) { - // Get the source and destination types Type *SrcTy = I.getOperand(0)->getType(); Type *DestTy = I.getType(); + VerifyBitcastType(&I, DestTy, SrcTy); + visitInstruction(I); +} - // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); - - // BitCast implies a no-op cast of type only. No bits change. - // However, you can't cast pointers to anything but pointers. - Assert1(SrcTy->isPointerTy() == DestTy->isPointerTy(), - "Bitcast requires both operands to be pointer or neither", &I); - Assert1(SrcBitSize == DestBitSize, "Bitcast requires types of same width",&I); - - // Disallow aggregates. - Assert1(!SrcTy->isAggregateType(), - "Bitcast operand must not be aggregate", &I); - Assert1(!DestTy->isAggregateType(), - "Bitcast type must not be aggregate", &I); +void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) { + Type *SrcTy = I.getOperand(0)->getType(); + Type *DestTy = I.getType(); + Assert1(SrcTy->isPtrOrPtrVectorTy(), + "AddrSpaceCast source must be a pointer", &I); + Assert1(DestTy->isPtrOrPtrVectorTy(), + "AddrSpaceCast result must be a pointer", &I); + Assert1(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(), + "AddrSpaceCast must be between different address spaces", &I); + if (SrcTy->isVectorTy()) + Assert1(SrcTy->getVectorNumElements() == DestTy->getVectorNumElements(), + "AddrSpaceCast vector pointer number of elements mismatch", &I); visitInstruction(I); } @@ -1339,7 +1483,7 @@ void Verifier::visitPHINode(PHINode &PN) { // This can be tested by checking whether the instruction before this is // either nonexistent (because this is begin()) or is a PHI node. If not, // then there is some other instruction before a PHI. - Assert2(&PN == &PN.getParent()->front() || + Assert2(&PN == &PN.getParent()->front() || isa<PHINode>(--BasicBlock::iterator(&PN)), "PHI nodes not grouped at top of basic block!", &PN, PN.getParent()); @@ -1403,9 +1547,9 @@ void Verifier::VerifyCallSite(CallSite CS) { // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { - Type *Ty = CS.getArgument(Idx-1)->getType(); + Type *Ty = CS.getArgument(Idx-1)->getType(); VerifyParameterAttrs(Attrs, Idx, Ty, false, I); - + if (Attrs.hasAttribute(Idx, Attribute::Nest)) { Assert1(!SawNest, "More than one parameter has attribute nest!", I); SawNest = true; @@ -1718,7 +1862,7 @@ void Verifier::visitStoreInst(StoreInst &SI) { void Verifier::visitAllocaInst(AllocaInst &AI) { PointerType *PTy = AI.getType(); - Assert1(PTy->getAddressSpace() == 0, + Assert1(PTy->getAddressSpace() == 0, "Allocation instruction pointer not in the generic address space!", &AI); Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type", @@ -1790,7 +1934,7 @@ void Verifier::visitExtractValueInst(ExtractValueInst &EVI) { EVI.getIndices()) == EVI.getType(), "Invalid ExtractValueInst operands!", &EVI); - + visitInstruction(EVI); } @@ -1799,7 +1943,7 @@ void Verifier::visitInsertValueInst(InsertValueInst &IVI) { IVI.getIndices()) == IVI.getOperand(1)->getType(), "Invalid InsertValueInst operands!", &IVI); - + visitInstruction(IVI); } @@ -1886,7 +2030,7 @@ void Verifier::visitInstruction(Instruction &I) { // Check that the return value of the instruction is either void or a legal // value type. - Assert1(I.getType()->isVoidTy() || + Assert1(I.getType()->isVoidTy() || I.getType()->isFirstClassType(), "Instruction returns a non-scalar type!", &I); @@ -1944,6 +2088,27 @@ void Verifier::visitInstruction(Instruction &I) { Assert1((i + 1 == e && isa<CallInst>(I)) || (i + 3 == e && isa<InvokeInst>(I)), "Cannot take the address of an inline asm!", &I); + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) { + if (CE->getType()->isPtrOrPtrVectorTy()) { + // If we have a ConstantExpr pointer, we need to see if it came from an + // illegal bitcast (inttoptr <constant int> ) + SmallVector<const ConstantExpr *, 4> Stack; + SmallPtrSet<const ConstantExpr *, 4> Visited; + Stack.push_back(CE); + + while (!Stack.empty()) { + const ConstantExpr *V = Stack.pop_back_val(); + if (!Visited.insert(V)) + continue; + + VerifyConstantExprBitcastType(V); + + for (unsigned I = 0, N = V->getNumOperands(); I != N; ++I) { + if (ConstantExpr *Op = dyn_cast<ConstantExpr>(V->getOperand(I))) + Stack.push_back(Op); + } + } + } } } @@ -1954,7 +2119,7 @@ void Verifier::visitInstruction(Instruction &I) { Value *Op0 = MD->getOperand(0); if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) { APFloat Accuracy = CFP0->getValueAPF(); - Assert1(Accuracy.isNormal() && !Accuracy.isNegative(), + Assert1(Accuracy.isFiniteNonZero() && !Accuracy.isNegative(), "fpmath accuracy not a positive number!", &I); } else { Assert1(false, "invalid fpmath accuracy!", &I); @@ -1964,6 +2129,11 @@ void Verifier::visitInstruction(Instruction &I) { MDNode *MD = I.getMetadata(LLVMContext::MD_range); Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I); + if (!DisableDebugInfoVerifier) { + MD = I.getMetadata(LLVMContext::MD_dbg); + Finder.processLocation(*Mod, DILocation(MD)); + } + InstsInThisBlock.insert(&I); } @@ -1978,12 +2148,13 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, using namespace Intrinsic; // If we ran out of descriptors, there are too many arguments. - if (Infos.empty()) return true; + if (Infos.empty()) return true; IITDescriptor D = Infos.front(); Infos = Infos.slice(1); - + switch (D.Kind) { case IITDescriptor::Void: return !Ty->isVoidTy(); + case IITDescriptor::VarArg: return true; case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); case IITDescriptor::Metadata: return !Ty->isMetadataTy(); case IITDescriptor::Half: return !Ty->isHalfTy(); @@ -2000,29 +2171,29 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, return PT == 0 || PT->getAddressSpace() != D.Pointer_AddressSpace || VerifyIntrinsicType(PT->getElementType(), Infos, ArgTys); } - + case IITDescriptor::Struct: { StructType *ST = dyn_cast<StructType>(Ty); if (ST == 0 || ST->getNumElements() != D.Struct_NumElements) return true; - + for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) if (VerifyIntrinsicType(ST->getElementType(i), Infos, ArgTys)) return true; return false; } - + case IITDescriptor::Argument: // Two cases here - If this is the second occurrence of an argument, verify - // that the later instance matches the previous instance. + // that the later instance matches the previous instance. if (D.getArgumentNumber() < ArgTys.size()) - return Ty != ArgTys[D.getArgumentNumber()]; - + return Ty != ArgTys[D.getArgumentNumber()]; + // Otherwise, if this is the first instance of an argument, record it and // verify the "Any" kind. assert(D.getArgumentNumber() == ArgTys.size() && "Table consistency error"); ArgTys.push_back(Ty); - + switch (D.getArgumentKind()) { case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy(); case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy(); @@ -2030,7 +2201,7 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, case IITDescriptor::AK_AnyPointer: return !isa<PointerType>(Ty); } llvm_unreachable("all argument kinds not covered"); - + case IITDescriptor::ExtendVecArgument: // This may only be used when referring to a previous vector argument. return D.getArgumentNumber() >= ArgTys.size() || @@ -2048,6 +2219,33 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, llvm_unreachable("unhandled"); } +/// \brief Verify if the intrinsic has variable arguments. +/// This method is intended to be called after all the fixed arguments have been +/// verified first. +/// +/// This method returns true on error and does not print an error message. +bool +Verifier::VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef<Intrinsic::IITDescriptor> &Infos) { + using namespace Intrinsic; + + // If there are no descriptors left, then it can't be a vararg. + if (Infos.empty()) + return isVarArg ? true : false; + + // There should be only one descriptor remaining at this point. + if (Infos.size() != 1) + return true; + + // Check and verify the descriptor. + IITDescriptor D = Infos.front(); + Infos = Infos.slice(1); + if (D.Kind == IITDescriptor::VarArg) + return isVarArg ? false : true; + + return true; +} + /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. /// void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { @@ -2058,8 +2256,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // Verify that the intrinsic prototype lines up with what the .td files // describe. FunctionType *IFTy = IF->getFunctionType(); - Assert1(!IFTy->isVarArg(), "Intrinsic prototypes are not varargs", IF); - + bool IsVarArg = IFTy->isVarArg(); + SmallVector<Intrinsic::IITDescriptor, 8> Table; getIntrinsicInfoTableEntries(ID, Table); ArrayRef<Intrinsic::IITDescriptor> TableRef = Table; @@ -2070,6 +2268,16 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i) Assert1(!VerifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys), "Intrinsic has incorrect argument type!", IF); + + // Verify if the intrinsic call matches the vararg property. + if (IsVarArg) + Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef), + "Intrinsic was not defined with variable arguments!", IF); + else + Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef), + "Callsite was not defined with variable arguments!", IF); + + // All descriptors should be absorbed by now. Assert1(TableRef.empty(), "Intrinsic has too few arguments!", IF); // Now that we have the intrinsic ID and the actual argument types (and we @@ -2078,7 +2286,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // the name. Assert1(Intrinsic::getName(ID, ArgTys) == IF->getName(), "Intrinsic name not mangled correctly for type arguments!", IF); - + // If the intrinsic takes MDNode arguments, verify that they are either global // or are local to *this* function. for (unsigned i = 0, e = CI.getNumArgOperands(); i != e; ++i) @@ -2100,7 +2308,17 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { MDNode *MD = cast<MDNode>(CI.getArgOperand(0)); Assert1(MD->getNumOperands() == 1, "invalid llvm.dbg.declare intrinsic call 2", &CI); + if (!DisableDebugInfoVerifier) + Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI)); } break; + case Intrinsic::dbg_value: { //llvm.dbg.value + if (!DisableDebugInfoVerifier) { + Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)), + "invalid llvm.dbg.value intrinsic call 1", &CI); + Finder.processValue(*Mod, cast<DbgValueInst>(&CI)); + } + break; + } case Intrinsic::memcpy: case Intrinsic::memmove: case Intrinsic::memset: @@ -2162,6 +2380,28 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { } } +void Verifier::verifyDebugInfo() { + // Verify Debug Info. + if (!DisableDebugInfoVerifier) { + for (DebugInfoFinder::iterator I = Finder.compile_unit_begin(), + E = Finder.compile_unit_end(); I != E; ++I) + Assert1(DICompileUnit(*I).Verify(), "DICompileUnit does not Verify!", *I); + for (DebugInfoFinder::iterator I = Finder.subprogram_begin(), + E = Finder.subprogram_end(); I != E; ++I) + Assert1(DISubprogram(*I).Verify(), "DISubprogram does not Verify!", *I); + for (DebugInfoFinder::iterator I = Finder.global_variable_begin(), + E = Finder.global_variable_end(); I != E; ++I) + Assert1(DIGlobalVariable(*I).Verify(), + "DIGlobalVariable does not Verify!", *I); + for (DebugInfoFinder::iterator I = Finder.type_begin(), + E = Finder.type_end(); I != E; ++I) + Assert1(DIType(*I).Verify(), "DIType does not Verify!", *I); + for (DebugInfoFinder::iterator I = Finder.scope_begin(), + E = Finder.scope_end(); I != E; ++I) + Assert1(DIScope(*I).Verify(), "DIScope does not Verify!", *I); + } +} + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// @@ -2181,6 +2421,7 @@ bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) { FunctionPassManager FPM(F.getParent()); Verifier *V = new Verifier(action); FPM.add(V); + FPM.doInitialization(); FPM.run(F); return V->Broken; } |