diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
| commit | 1e7804dbd25b8dbf534c850355d70ad215206f4b (patch) | |
| tree | dba00119388b84f9f44e6ec5e9129f807fd79ca3 /lib/VMCore | |
| parent | 571945e6affd20b19264ec22495da418d0fbdbb4 (diff) | |
Notes
Diffstat (limited to 'lib/VMCore')
| -rw-r--r-- | lib/VMCore/AsmWriter.cpp | 532 | ||||
| -rw-r--r-- | lib/VMCore/BasicBlock.cpp | 2 | ||||
| -rw-r--r-- | lib/VMCore/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/VMCore/ConstantFold.cpp | 8 | ||||
| -rw-r--r-- | lib/VMCore/Constants.cpp | 64 | ||||
| -rw-r--r-- | lib/VMCore/Dominators.cpp | 4 | ||||
| -rw-r--r-- | lib/VMCore/Function.cpp | 9 | ||||
| -rw-r--r-- | lib/VMCore/IRBuilder.cpp | 51 | ||||
| -rw-r--r-- | lib/VMCore/Instruction.cpp | 21 | ||||
| -rw-r--r-- | lib/VMCore/Instructions.cpp | 30 | ||||
| -rw-r--r-- | lib/VMCore/IntrinsicInst.cpp | 12 | ||||
| -rw-r--r-- | lib/VMCore/LLVMContext.cpp | 6 | ||||
| -rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 27 | ||||
| -rw-r--r-- | lib/VMCore/LeaksContext.h | 3 | ||||
| -rw-r--r-- | lib/VMCore/Metadata.cpp | 585 | ||||
| -rw-r--r-- | lib/VMCore/Module.cpp | 20 | ||||
| -rw-r--r-- | lib/VMCore/PassManager.cpp | 4 | ||||
| -rw-r--r-- | lib/VMCore/Type.cpp | 28 | ||||
| -rw-r--r-- | lib/VMCore/Value.cpp | 12 | ||||
| -rw-r--r-- | lib/VMCore/Verifier.cpp | 43 |
20 files changed, 720 insertions, 742 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index c765d968fcde7..d3c9d7794f1e3 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -21,11 +21,8 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" -#include "llvm/Instruction.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Operator.h" -#include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" @@ -60,9 +57,11 @@ static const Module *getModuleFromVal(const Value *V) { const Function *M = I->getParent() ? I->getParent()->getParent() : 0; return M ? M->getParent() : 0; } - + if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV->getParent(); + if (const NamedMDNode *NMD = dyn_cast<NamedMDNode>(V)) + return NMD->getParent(); return 0; } @@ -475,12 +474,6 @@ private: const Function* TheFunction; bool FunctionProcessed; - /// TheMDNode - The MDNode for which we are holding slot numbers. - const MDNode *TheMDNode; - - /// TheNamedMDNode - The MDNode for which we are holding slot numbers. - const NamedMDNode *TheNamedMDNode; - /// mMap - The TypePlanes map for the module level data. ValueMap mMap; unsigned mNext; @@ -490,17 +483,13 @@ private: unsigned fNext; /// mdnMap - Map for MDNodes. - ValueMap mdnMap; + DenseMap<const MDNode*, unsigned> mdnMap; unsigned mdnNext; public: /// Construct from a module explicit SlotTracker(const Module *M); /// Construct from a function, starting out in incorp state. explicit SlotTracker(const Function *F); - /// Construct from a mdnode. - explicit SlotTracker(const MDNode *N); - /// Construct from a named mdnode. - explicit SlotTracker(const NamedMDNode *N); /// Return the slot number of the specified value in it's type /// plane. If something is not in the SlotTracker, return -1. @@ -521,10 +510,11 @@ public: void purgeFunction(); /// MDNode map iterators. - ValueMap::iterator mdnBegin() { return mdnMap.begin(); } - ValueMap::iterator mdnEnd() { return mdnMap.end(); } - unsigned mdnSize() const { return mdnMap.size(); } - bool mdnEmpty() const { return mdnMap.empty(); } + typedef DenseMap<const MDNode*, unsigned>::iterator mdn_iterator; + mdn_iterator mdn_begin() { return mdnMap.begin(); } + mdn_iterator mdn_end() { return mdnMap.end(); } + unsigned mdn_size() const { return mdnMap.size(); } + bool mdn_empty() const { return mdnMap.empty(); } /// This function does the actual initialization. inline void initialize(); @@ -547,12 +537,6 @@ private: /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); - /// Add all MDNode operands. - void processMDNode(); - - /// Add all MDNode operands. - void processNamedMDNode(); - SlotTracker(const SlotTracker &); // DO NOT IMPLEMENT void operator=(const SlotTracker &); // DO NOT IMPLEMENT }; @@ -591,27 +575,15 @@ static SlotTracker *createSlotTracker(const Value *V) { // Module level constructor. Causes the contents of the Module (sans functions) // to be added to the slot table. SlotTracker::SlotTracker(const Module *M) - : TheModule(M), TheFunction(0), FunctionProcessed(false), TheMDNode(0), - TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { + : TheModule(M), TheFunction(0), FunctionProcessed(false), + mNext(0), fNext(0), mdnNext(0) { } // Function level constructor. Causes the contents of the Module and the one // function provided to be added to the slot table. SlotTracker::SlotTracker(const Function *F) : TheModule(F ? F->getParent() : 0), TheFunction(F), FunctionProcessed(false), - TheMDNode(0), TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { -} - -// Constructor to handle single MDNode. -SlotTracker::SlotTracker(const MDNode *C) - : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(C), - TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { -} - -// Constructor to handle single NamedMDNode. -SlotTracker::SlotTracker(const NamedMDNode *N) - : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(0), - TheNamedMDNode(N), mNext(0), fNext(0), mdnNext(0) { + mNext(0), fNext(0), mdnNext(0) { } inline void SlotTracker::initialize() { @@ -622,12 +594,6 @@ inline void SlotTracker::initialize() { if (TheFunction && !FunctionProcessed) processFunction(); - - if (TheMDNode) - processMDNode(); - - if (TheNamedMDNode) - processNamedMDNode(); } // Iterate through all the global variables, functions, and global @@ -640,10 +606,6 @@ void SlotTracker::processModule() { E = TheModule->global_end(); I != E; ++I) { if (!I->hasName()) CreateModuleSlot(I); - if (I->hasInitializer()) { - if (MDNode *N = dyn_cast<MDNode>(I->getInitializer())) - CreateMetadataSlot(N); - } } // Add metadata used by named metadata. @@ -651,9 +613,9 @@ void SlotTracker::processModule() { I = TheModule->named_metadata_begin(), E = TheModule->named_metadata_end(); I != E; ++I) { const NamedMDNode *NMD = I; - for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { - MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i)); - if (MD) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + // FIXME: Change accessor to be type safe. + if (MDNode *MD = cast_or_null<MDNode>(NMD->getOperand(i))) CreateMetadataSlot(MD); } } @@ -680,30 +642,30 @@ void SlotTracker::processFunction() { ST_DEBUG("Inserting Instructions:\n"); - MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); - typedef SmallVector<std::pair<unsigned, TrackingVH<MDNode> >, 2> MDMapTy; - MDMapTy MDs; + SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst; // Add all of the basic blocks and instructions with no names. for (Function::const_iterator BB = TheFunction->begin(), E = TheFunction->end(); BB != E; ++BB) { if (!BB->hasName()) CreateFunctionSlot(BB); + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - if (I->getType() != Type::getVoidTy(TheFunction->getContext()) && - !I->hasName()) + if (!I->getType()->isVoidTy() && !I->hasName()) CreateFunctionSlot(I); - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) - CreateMetadataSlot(N); + + // Intrinsics can directly use metadata. + if (isa<IntrinsicInst>(I)) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) + CreateMetadataSlot(N); // Process metadata attached with this instruction. - MDs.clear(); - TheMetadata.getMDs(I, MDs); - for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; - ++MI) - CreateMetadataSlot(MI->second); + I->getAllMetadata(MDForInst); + for (unsigned i = 0, e = MDForInst.size(); i != e; ++i) + CreateMetadataSlot(MDForInst[i].second); + MDForInst.clear(); } } @@ -712,28 +674,6 @@ void SlotTracker::processFunction() { ST_DEBUG("end processFunction!\n"); } -/// processMDNode - Process TheMDNode. -void SlotTracker::processMDNode() { - ST_DEBUG("begin processMDNode!\n"); - mdnNext = 0; - CreateMetadataSlot(TheMDNode); - TheMDNode = 0; - ST_DEBUG("end processMDNode!\n"); -} - -/// processNamedMDNode - Process TheNamedMDNode. -void SlotTracker::processNamedMDNode() { - ST_DEBUG("begin processNamedMDNode!\n"); - mdnNext = 0; - for (unsigned i = 0, e = TheNamedMDNode->getNumElements(); i != e; ++i) { - MDNode *MD = dyn_cast_or_null<MDNode>(TheNamedMDNode->getElement(i)); - if (MD) - CreateMetadataSlot(MD); - } - TheNamedMDNode = 0; - ST_DEBUG("end processNamedMDNode!\n"); -} - /// Clean up after incorporating a function. This is the only way to get out of /// the function incorporation state that affects get*Slot/Create*Slot. Function /// incorporation state is indicated by TheFunction != 0. @@ -755,13 +695,13 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) { return MI == mMap.end() ? -1 : (int)MI->second; } -/// getGlobalSlot - Get the slot number of a MDNode. +/// getMetadataSlot - Get the slot number of a MDNode. int SlotTracker::getMetadataSlot(const MDNode *N) { // Check for uninitialized state and do lazy initialization. initialize(); // Find the type plane in the module map - ValueMap::iterator MI = mdnMap.find(N); + mdn_iterator MI = mdnMap.find(N); return MI == mdnMap.end() ? -1 : (int)MI->second; } @@ -781,8 +721,7 @@ int SlotTracker::getLocalSlot(const Value *V) { /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void SlotTracker::CreateModuleSlot(const GlobalValue *V) { assert(V && "Can't insert a null Value into SlotTracker!"); - assert(V->getType() != Type::getVoidTy(V->getContext()) && - "Doesn't need a slot!"); + assert(!V->getType()->isVoidTy() && "Doesn't need a slot!"); assert(!V->hasName() && "Doesn't need a slot!"); unsigned DestSlot = mNext++; @@ -798,8 +737,7 @@ void SlotTracker::CreateModuleSlot(const GlobalValue *V) { /// CreateSlot - Create a new slot for the specified value if it has no name. void SlotTracker::CreateFunctionSlot(const Value *V) { - assert(V->getType() != Type::getVoidTy(TheFunction->getContext()) && - !V->hasName() && "Doesn't need a slot!"); + assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!"); unsigned DestSlot = fNext++; fMap[V] = DestSlot; @@ -813,24 +751,22 @@ void SlotTracker::CreateFunctionSlot(const Value *V) { void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); - // Don't insert if N contains an instruction. - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) - if (N->getElement(i) && isa<Instruction>(N->getElement(i))) - return; + // Don't insert if N is a function-local metadata, these are always printed + // inline. + if (N->isFunctionLocal()) + return; - ValueMap::iterator I = mdnMap.find(N); + mdn_iterator I = mdnMap.find(N); if (I != mdnMap.end()) return; unsigned DestSlot = mdnNext++; mdnMap[N] = DestSlot; - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { - const Value *TV = N->getElement(i); - if (TV) - if (const MDNode *N2 = dyn_cast<MDNode>(TV)) - CreateMetadataSlot(N2); - } + // Recursively add any MDNodes referenced by operands. + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + if (const MDNode *Op = dyn_cast_or_null<MDNode>(N->getOperand(i))) + CreateMetadataSlot(Op); } //===----------------------------------------------------------------------===// @@ -846,95 +782,36 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, static const char *getPredicateText(unsigned predicate) { const char * pred = "unknown"; switch (predicate) { - case FCmpInst::FCMP_FALSE: pred = "false"; break; - case FCmpInst::FCMP_OEQ: pred = "oeq"; break; - case FCmpInst::FCMP_OGT: pred = "ogt"; break; - case FCmpInst::FCMP_OGE: pred = "oge"; break; - case FCmpInst::FCMP_OLT: pred = "olt"; break; - case FCmpInst::FCMP_OLE: pred = "ole"; break; - case FCmpInst::FCMP_ONE: pred = "one"; break; - case FCmpInst::FCMP_ORD: pred = "ord"; break; - case FCmpInst::FCMP_UNO: pred = "uno"; break; - case FCmpInst::FCMP_UEQ: pred = "ueq"; break; - case FCmpInst::FCMP_UGT: pred = "ugt"; break; - case FCmpInst::FCMP_UGE: pred = "uge"; break; - case FCmpInst::FCMP_ULT: pred = "ult"; break; - case FCmpInst::FCMP_ULE: pred = "ule"; break; - case FCmpInst::FCMP_UNE: pred = "une"; break; - case FCmpInst::FCMP_TRUE: pred = "true"; break; - case ICmpInst::ICMP_EQ: pred = "eq"; break; - case ICmpInst::ICMP_NE: pred = "ne"; break; - case ICmpInst::ICMP_SGT: pred = "sgt"; break; - case ICmpInst::ICMP_SGE: pred = "sge"; break; - case ICmpInst::ICMP_SLT: pred = "slt"; break; - case ICmpInst::ICMP_SLE: pred = "sle"; break; - case ICmpInst::ICMP_UGT: pred = "ugt"; break; - case ICmpInst::ICMP_UGE: pred = "uge"; break; - case ICmpInst::ICMP_ULT: pred = "ult"; break; - case ICmpInst::ICMP_ULE: pred = "ule"; break; + case FCmpInst::FCMP_FALSE: pred = "false"; break; + case FCmpInst::FCMP_OEQ: pred = "oeq"; break; + case FCmpInst::FCMP_OGT: pred = "ogt"; break; + case FCmpInst::FCMP_OGE: pred = "oge"; break; + case FCmpInst::FCMP_OLT: pred = "olt"; break; + case FCmpInst::FCMP_OLE: pred = "ole"; break; + case FCmpInst::FCMP_ONE: pred = "one"; break; + case FCmpInst::FCMP_ORD: pred = "ord"; break; + case FCmpInst::FCMP_UNO: pred = "uno"; break; + case FCmpInst::FCMP_UEQ: pred = "ueq"; break; + case FCmpInst::FCMP_UGT: pred = "ugt"; break; + case FCmpInst::FCMP_UGE: pred = "uge"; break; + case FCmpInst::FCMP_ULT: pred = "ult"; break; + case FCmpInst::FCMP_ULE: pred = "ule"; break; + case FCmpInst::FCMP_UNE: pred = "une"; break; + case FCmpInst::FCMP_TRUE: pred = "true"; break; + case ICmpInst::ICMP_EQ: pred = "eq"; break; + case ICmpInst::ICMP_NE: pred = "ne"; break; + case ICmpInst::ICMP_SGT: pred = "sgt"; break; + case ICmpInst::ICMP_SGE: pred = "sge"; break; + case ICmpInst::ICMP_SLT: pred = "slt"; break; + case ICmpInst::ICMP_SLE: pred = "sle"; break; + case ICmpInst::ICMP_UGT: pred = "ugt"; break; + case ICmpInst::ICMP_UGE: pred = "uge"; break; + case ICmpInst::ICMP_ULT: pred = "ult"; break; + case ICmpInst::ICMP_ULE: pred = "ule"; break; } return pred; } -static void WriteMDNodeComment(const MDNode *Node, - formatted_raw_ostream &Out) { - if (Node->getNumElements() < 1) - return; - ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getElement(0)); - if (!CI) return; - unsigned Val = CI->getZExtValue(); - unsigned Tag = Val & ~LLVMDebugVersionMask; - if (Val >= LLVMDebugVersion) { - if (Tag == dwarf::DW_TAG_auto_variable) - Out << "; [ DW_TAG_auto_variable ]"; - else if (Tag == dwarf::DW_TAG_arg_variable) - Out << "; [ DW_TAG_arg_variable ]"; - else if (Tag == dwarf::DW_TAG_return_variable) - Out << "; [ DW_TAG_return_variable ]"; - else if (Tag == dwarf::DW_TAG_vector_type) - Out << "; [ DW_TAG_vector_type ]"; - else if (Tag == dwarf::DW_TAG_user_base) - Out << "; [ DW_TAG_user_base ]"; - else - Out << "; [" << dwarf::TagString(Tag) << " ]"; - } -} - -static void WriteMDNodes(formatted_raw_ostream &Out, TypePrinting &TypePrinter, - SlotTracker &Machine) { - SmallVector<const MDNode *, 16> Nodes; - Nodes.resize(Machine.mdnSize()); - for (SlotTracker::ValueMap::iterator I = - Machine.mdnBegin(), E = Machine.mdnEnd(); I != E; ++I) - Nodes[I->second] = cast<MDNode>(I->first); - - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { - Out << '!' << i << " = metadata "; - const MDNode *Node = Nodes[i]; - Out << "!{"; - for (unsigned mi = 0, me = Node->getNumElements(); mi != me; ++mi) { - const Value *V = Node->getElement(mi); - if (!V) - Out << "null"; - else if (const MDNode *N = dyn_cast<MDNode>(V)) { - Out << "metadata "; - Out << '!' << Machine.getMetadataSlot(N); - } - else { - TypePrinter.print(V->getType(), Out); - Out << ' '; - WriteAsOperandInternal(Out, Node->getElement(mi), - &TypePrinter, &Machine); - } - if (mi + 1 != me) - Out << ", "; - } - - Out << "}"; - WriteMDNodeComment(Node, Out); - Out << "\n"; - } -} static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { if (const OverflowingBinaryOperator *OBO = @@ -1197,6 +1074,27 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << "<placeholder or erroneous Constant>"; } +static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, + TypePrinting *TypePrinter, + SlotTracker *Machine) { + Out << "!{"; + for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) { + const Value *V = Node->getOperand(mi); + if (V == 0) + Out << "null"; + else { + TypePrinter->print(V->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, Node->getOperand(mi), + TypePrinter, Machine); + } + if (mi + 1 != me) + Out << ", "; + } + + Out << "}"; +} + /// WriteAsOperand - Write the name of the specified value out to the specified /// ostream. This can be useful when you just want to print int %reg126, not @@ -1232,22 +1130,9 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, } if (const MDNode *N = dyn_cast<MDNode>(V)) { - if (Machine->getMetadataSlot(N) == -1) { + if (N->isFunctionLocal()) { // Print metadata inline, not via slot reference number. - Out << "!{"; - for (unsigned mi = 0, me = N->getNumElements(); mi != me; ++mi) { - const Value *Val = N->getElement(mi); - if (!Val) - Out << "null"; - else { - TypePrinter->print(N->getElement(0)->getType(), Out); - Out << ' '; - WriteAsOperandInternal(Out, N->getElement(0), TypePrinter, Machine); - } - if (mi + 1 != me) - Out << ", "; - } - Out << '}'; + WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine); return; } @@ -1331,48 +1216,28 @@ class AssemblyWriter { TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; std::vector<const Type*> NumberedTypes; - DenseMap<unsigned, StringRef> MDNames; - + SmallVector<StringRef, 8> MDNames; + public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW) : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); - // FIXME: Provide MDPrinter - if (M) { - MetadataContext &TheMetadata = M->getContext().getMetadata(); - SmallVector<std::pair<unsigned, StringRef>, 4> Names; - TheMetadata.getHandlerNames(Names); - for (SmallVector<std::pair<unsigned, StringRef>, 4>::iterator - I = Names.begin(), - E = Names.end(); I != E; ++I) { - MDNames[I->first] = I->second; - } - } - } - - void write(const Module *M) { printModule(M); } - - void write(const GlobalValue *G) { - if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) - printGlobal(GV); - else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) - printAlias(GA); - else if (const Function *F = dyn_cast<Function>(G)) - printFunction(F); - else - llvm_unreachable("Unknown global"); + if (M) + M->getMDKindNames(MDNames); } - void write(const BasicBlock *BB) { printBasicBlock(BB); } - void write(const Instruction *I) { printInstruction(*I); } + 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, Attributes Attrs); -private: - void printModule(const Module *M); + void writeAllMDNodes(); + void printTypeSymbolTable(const TypeSymbolTable &ST); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); @@ -1380,6 +1245,7 @@ private: void printArgument(const Argument *FA, Attributes Attrs); void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); +private: // printInfoComment - Print a little comment after the instruction indicating // which slot it occupies. @@ -1391,29 +1257,30 @@ private: void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { if (Operand == 0) { Out << "<null operand!>"; - } else { - if (PrintType) { - TypePrinter.print(Operand->getType(), Out); - Out << ' '; - } - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + return; + } + if (PrintType) { + TypePrinter.print(Operand->getType(), Out); + Out << ' '; } + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } void AssemblyWriter::writeParamOperand(const Value *Operand, Attributes Attrs) { if (Operand == 0) { Out << "<null operand!>"; - } else { - // Print the type - TypePrinter.print(Operand->getType(), Out); - // Print parameter attributes list - if (Attrs != Attribute::None) - Out << ' ' << Attribute::getAsString(Attrs); - Out << ' '; - // Print the operand - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + return; } + + // Print the type + TypePrinter.print(Operand->getType(), Out); + // Print parameter attributes list + if (Attrs != Attribute::None) + Out << ' ' << Attribute::getAsString(Attrs); + Out << ' '; + // Print the operand + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } void AssemblyWriter::printModule(const Module *M) { @@ -1486,23 +1353,31 @@ void AssemblyWriter::printModule(const Module *M) { // Output named metadata. if (!M->named_metadata_empty()) Out << '\n'; + for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), - E = M->named_metadata_end(); I != E; ++I) { - const NamedMDNode *NMD = I; - Out << "!" << NMD->getName() << " = !{"; - for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { - if (i) Out << ", "; - MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i)); - Out << '!' << Machine.getMetadataSlot(MD); - } - Out << "}\n"; - } + E = M->named_metadata_end(); I != E; ++I) + printNamedMDNode(I); // Output metadata. - if (!Machine.mdnEmpty()) Out << '\n'; - WriteMDNodes(Out, TypePrinter, Machine); + if (!Machine.mdn_empty()) { + Out << '\n'; + writeAllMDNodes(); + } +} + +void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { + Out << "!" << NMD->getName() << " = !{"; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + if (i) Out << ", "; + // FIXME: Change accessor to be typesafe. + // FIXME: This doesn't handle null?? + MDNode *MD = cast_or_null<MDNode>(NMD->getOperand(i)); + Out << '!' << Machine.getMetadataSlot(MD); + } + Out << "}\n"; } + static void PrintLinkage(GlobalValue::LinkageTypes LT, formatted_raw_ostream &Out) { switch (LT) { @@ -1531,7 +1406,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, static void PrintVisibility(GlobalValue::VisibilityTypes Vis, formatted_raw_ostream &Out) { switch (Vis) { - default: llvm_unreachable("Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; case GlobalValue::ProtectedVisibility: Out << "protected "; break; @@ -1806,12 +1680,12 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { /// which slot it occupies. /// void AssemblyWriter::printInfoComment(const Value &V) { - if (V.getType() != Type::getVoidTy(V.getContext())) { - Out.PadToColumn(50); - Out << "; <"; - TypePrinter.print(V.getType(), Out); - Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses - } + if (V.getType()->isVoidTy()) return; + + Out.PadToColumn(50); + Out << "; <"; + TypePrinter.print(V.getType(), Out); + Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses } // This member is called for each Instruction in a function.. @@ -1825,7 +1699,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (I.hasName()) { PrintLLVMName(Out, &I); Out << " = "; - } else if (I.getType() != Type::getVoidTy(I.getContext())) { + } else if (!I.getType()->isVoidTy()) { // Print out the def slot taken. int SlotNum = Machine.getLocalSlot(&I); if (SlotNum == -1) @@ -2076,27 +1950,68 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } } - // Print post operand alignment for load/store + // Print post operand alignment for load/store. if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) { Out << ", align " << cast<LoadInst>(I).getAlignment(); } else if (isa<StoreInst>(I) && cast<StoreInst>(I).getAlignment()) { Out << ", align " << cast<StoreInst>(I).getAlignment(); } - // Print Metadata info + // Print Metadata info. if (!MDNames.empty()) { - MetadataContext &TheMetadata = I.getContext().getMetadata(); - typedef SmallVector<std::pair<unsigned, TrackingVH<MDNode> >, 2> MDMapTy; - MDMapTy MDs; - TheMetadata.getMDs(&I, MDs); - for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; - ++MI) - Out << ", !" << MDNames[MI->first] - << " !" << Machine.getMetadataSlot(MI->second); + SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD; + I.getAllMetadata(InstMD); + for (unsigned i = 0, e = InstMD.size(); i != e; ++i) + Out << ", !" << MDNames[InstMD[i].first] + << " !" << Machine.getMetadataSlot(InstMD[i].second); } printInfoComment(I); } +static void WriteMDNodeComment(const MDNode *Node, + formatted_raw_ostream &Out) { + if (Node->getNumOperands() < 1) + return; + ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getOperand(0)); + if (!CI) return; + unsigned Val = CI->getZExtValue(); + unsigned Tag = Val & ~LLVMDebugVersionMask; + if (Val < LLVMDebugVersion) + return; + + Out.PadToColumn(50); + if (Tag == dwarf::DW_TAG_auto_variable) + Out << "; [ DW_TAG_auto_variable ]"; + else if (Tag == dwarf::DW_TAG_arg_variable) + Out << "; [ DW_TAG_arg_variable ]"; + else if (Tag == dwarf::DW_TAG_return_variable) + Out << "; [ DW_TAG_return_variable ]"; + else if (Tag == dwarf::DW_TAG_vector_type) + Out << "; [ DW_TAG_vector_type ]"; + else if (Tag == dwarf::DW_TAG_user_base) + Out << "; [ DW_TAG_user_base ]"; + else if (const char *TagName = dwarf::TagString(Tag)) + Out << "; [ " << TagName << " ]"; +} + +void AssemblyWriter::writeAllMDNodes() { + SmallVector<const MDNode *, 16> Nodes; + Nodes.resize(Machine.mdn_size()); + for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end(); + I != E; ++I) + Nodes[I->second] = cast<MDNode>(I->first); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Out << '!' << i << " = metadata "; + printMDNodeBody(Nodes[i]); + } +} + +void AssemblyWriter::printMDNodeBody(const MDNode *Node) { + WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine); + WriteMDNodeComment(Node, Out); + Out << "\n"; +} //===----------------------------------------------------------------------===// // External Interface declarations @@ -2106,7 +2021,7 @@ void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(this); formatted_raw_ostream OS(ROS); AssemblyWriter W(OS, SlotTable, this, AAW); - W.write(this); + W.printModule(this); } void Type::print(raw_ostream &OS) const { @@ -2126,53 +2041,36 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { if (const Instruction *I = dyn_cast<Instruction>(this)) { const Function *F = I->getParent() ? I->getParent()->getParent() : 0; SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW); - W.write(I); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), AAW); + W.printInstruction(*I); } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) { SlotTracker SlotTable(BB->getParent()); - AssemblyWriter W(OS, SlotTable, - BB->getParent() ? BB->getParent()->getParent() : 0, AAW); - W.write(BB); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), AAW); + W.printBasicBlock(BB); } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) { SlotTracker SlotTable(GV->getParent()); AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW); - W.write(GV); - } else if (const MDString *MDS = dyn_cast<MDString>(this)) { - TypePrinting TypePrinter; - TypePrinter.print(MDS->getType(), OS); - OS << ' '; - OS << "!\""; - PrintEscapedString(MDS->getString(), OS); - OS << '"'; + if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV)) + W.printGlobal(V); + else if (const Function *F = dyn_cast<Function>(GV)) + W.printFunction(F); + else + W.printAlias(cast<GlobalAlias>(GV)); } else if (const MDNode *N = dyn_cast<MDNode>(this)) { - SlotTracker SlotTable(N); - TypePrinting TypePrinter; - SlotTable.initialize(); - WriteMDNodes(OS, TypePrinter, SlotTable); + SlotTracker SlotTable((Function*)0); + AssemblyWriter W(OS, SlotTable, 0, AAW); + W.printMDNodeBody(N); } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) { - SlotTracker SlotTable(N); - TypePrinting TypePrinter; - SlotTable.initialize(); - OS << "!" << N->getName() << " = !{"; - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { - if (i) OS << ", "; - MDNode *MD = dyn_cast_or_null<MDNode>(N->getElement(i)); - if (MD) - OS << '!' << SlotTable.getMetadataSlot(MD); - else - OS << "null"; - } - OS << "}\n"; - WriteMDNodes(OS, TypePrinter, SlotTable); + SlotTracker SlotTable(N->getParent()); + AssemblyWriter W(OS, SlotTable, N->getParent(), AAW); + W.printNamedMDNode(N); } else if (const Constant *C = dyn_cast<Constant>(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); OS << ' '; WriteConstantInt(OS, C, TypePrinter, 0); - } else if (const Argument *A = dyn_cast<Argument>(this)) { - WriteAsOperand(OS, this, true, - A->getParent() ? A->getParent()->getParent() : 0); - } else if (isa<InlineAsm>(this)) { + } else if (isa<InlineAsm>(this) || isa<MDString>(this) || + isa<Argument>(this)) { WriteAsOperand(OS, this, true, 0); } else { // Otherwise we don't know what it is. Call the virtual function to diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index c7f7f53e2305d..16437bc130454 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -35,7 +35,7 @@ LLVMContext &BasicBlock::getContext() const { // Explicit instantiation of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits<Instruction, BasicBlock>; +template class llvm::SymbolTableListTraits<Instruction, BasicBlock>; BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt index 9b17d4bcd2106..61d01ee9d37e9 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -13,6 +13,7 @@ add_llvm_library(LLVMCore Instruction.cpp Instructions.cpp IntrinsicInst.cpp + IRBuilder.cpp LLVMContext.cpp LeakDetector.cpp Mangler.cpp diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 7f713d15c67a4..2449739aaf502 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -1839,14 +1839,16 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context, } } - if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) { + if ((!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) || + (C1->isNullValue() && !C2->isNullValue())) { // If C2 is a constant expr and C1 isn't, flip them around and fold the // other way if possible. + // Also, if C1 is null and C2 isn't, flip them around. switch (pred) { case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_NE: // No change of predicate required. - return ConstantFoldCompareInstruction(Context, pred, C2, C1); + return ConstantExpr::getICmp(pred, C2, C1); case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: @@ -1858,7 +1860,7 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context, case ICmpInst::ICMP_SGE: // Change the predicate as necessary to swap the operands. pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred); - return ConstantFoldCompareInstruction(Context, pred, C2, C1); + return ConstantExpr::getICmp(pred, C2, C1); default: // These predicates cannot be flopped around. break; diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index a62f75b1c8062..e3c6144c76aab 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -481,15 +481,12 @@ Constant *ConstantArray::get(const ArrayType *Ty, // If this is an all-zero array, return a ConstantAggregateZero object if (!V.empty()) { Constant *C = V[0]; - if (!C->isNullValue()) { - // Implicitly locked. + if (!C->isNullValue()) return pImpl->ArrayConstants.getOrCreate(Ty, V); - } + for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - // Implicitly locked. + if (V[i] != C) return pImpl->ArrayConstants.getOrCreate(Ty, V); - } } return ConstantAggregateZero::get(Ty); @@ -550,7 +547,6 @@ Constant* ConstantStruct::get(const StructType* T, // Create a ConstantAggregateZero value if all elements are zeros... for (unsigned i = 0, e = V.size(); i != e; ++i) if (!V[i]->isNullValue()) - // Implicitly locked. return pImpl->StructConstants.getOrCreate(T, V); return ConstantAggregateZero::get(T); @@ -613,7 +609,6 @@ Constant* ConstantVector::get(const VectorType* T, if (isUndef) return UndefValue::get(T); - // Implicitly locked. return pImpl->VectorConstants.getOrCreate(T, V); } @@ -627,6 +622,12 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) { return get(std::vector<Constant*>(Vals, Vals+NumVals)); } +Constant* ConstantExpr::getNSWNeg(Constant* C) { + assert(C->getType()->isIntOrIntVector() && + "Cannot NEG a nonintegral value!"); + return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); +} + Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { return getTy(C1->getType(), Instruction::Add, C1, C2, OverflowingBinaryOperator::NoSignedWrap); @@ -637,6 +638,11 @@ Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) { OverflowingBinaryOperator::NoSignedWrap); } +Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::Mul, C1, C2, + OverflowingBinaryOperator::NoSignedWrap); +} + Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { return getTy(C1->getType(), Instruction::SDiv, C1, C2, SDivOperator::IsExact); @@ -752,14 +758,14 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); Ops[OpNo-1] = Op; return cast<GEPOperator>(this)->isInBounds() ? - ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) : + ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0],Ops.size()): ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); } default: assert(getNumOperands() == 2 && "Must be binary operator?"); Op0 = (OpNo == 0) ? Op : getOperand(0); Op1 = (OpNo == 1) ? Op : getOperand(1); - return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData); + return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassOptionalData); } } @@ -809,7 +815,7 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); default: assert(getNumOperands() == 2 && "Must be binary operator?"); - return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData); + return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData); } } @@ -883,14 +889,12 @@ ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { "Cannot create an aggregate zero of non-aggregate type!"); LLVMContextImpl *pImpl = Ty->getContext().pImpl; - // Implicitly locked. return pImpl->AggZeroConstants.getOrCreate(Ty, 0); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantAggregateZero::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->AggZeroConstants.remove(this); destroyConstantImpl(); } @@ -898,7 +902,6 @@ void ConstantAggregateZero::destroyConstant() { /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } @@ -963,7 +966,6 @@ namespace llvm { // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } @@ -971,7 +973,6 @@ void ConstantStruct::destroyConstant() { // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->VectorConstants.remove(this); destroyConstantImpl(); } @@ -1007,14 +1008,12 @@ Constant *ConstantVector::getSplatValue() { // ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { - // Implicitly locked. return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0); } // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->NullPtrConstants.remove(this); destroyConstantImpl(); } @@ -1126,7 +1125,6 @@ static inline Constant *getFoldedCast( std::vector<Constant*> argVec(1, C); ExprMapKeyType Key(opc, argVec); - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(Ty, Key); } @@ -1372,8 +1370,6 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, ExprMapKeyType Key(Opcode, argVec, 0, Flags); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1524,8 +1520,6 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, ExprMapKeyType Key(Instruction::Select, argVec); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1553,8 +1547,6 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1584,8 +1576,6 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, GEPOperator::IsInBounds); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1639,8 +1629,6 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) { const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); } @@ -1662,8 +1650,6 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); } @@ -1672,15 +1658,13 @@ Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, Constant *Idx) { if (Constant *FC = ConstantFoldExtractElementInstruction( ReqTy->getContext(), Val, Idx)) - return FC; // Fold a few common cases... + return FC; // Fold a few common cases. // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec(1, Val); ArgVec.push_back(Idx); const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1697,7 +1681,7 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, Constant *Elt, Constant *Idx) { if (Constant *FC = ConstantFoldInsertElementInstruction( ReqTy->getContext(), Val, Elt, Idx)) - return FC; // Fold a few common cases... + return FC; // Fold a few common cases. // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec(1, Val); ArgVec.push_back(Elt); @@ -1705,8 +1689,6 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1733,8 +1715,6 @@ Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1903,9 +1883,7 @@ Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) { // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { - // Implicitly locked. - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - pImpl->ExprConstants.remove(this); + getType()->getContext().pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -2185,7 +2163,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Constant *C2 = getOperand(1); if (C1 == From) C1 = To; if (C2 == From) C2 = To; - Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData); + Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassOptionalData); } else { llvm_unreachable("Unknown ConstantExpr type!"); return; diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index 26c02e0f50439..34417505814f7 100644 --- a/lib/VMCore/Dominators.cpp +++ b/lib/VMCore/Dominators.cpp @@ -47,8 +47,8 @@ VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), // //===----------------------------------------------------------------------===// -TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>); -TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>); +TEMPLATE_INSTANTIATION(class llvm::DomTreeNodeBase<BasicBlock>); +TEMPLATE_INSTANTIATION(class llvm::DominatorTreeBase<BasicBlock>); char DominatorTree::ID = 0; static RegisterPass<DominatorTree> diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 88e1fe8ae4f70..e04b6d6a14bd3 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -29,8 +29,8 @@ using namespace llvm; // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file... -template class SymbolTableListTraits<Argument, Function>; -template class SymbolTableListTraits<BasicBlock, Function>; +template class llvm::SymbolTableListTraits<Argument, Function>; +template class llvm::SymbolTableListTraits<BasicBlock, Function>; //===----------------------------------------------------------------------===// // Argument Implementation @@ -160,7 +160,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, // If the function has arguments, mark them as lazily built. if (Ty->getNumParams()) - SubclassData = 1; // Set the "has lazy arguments" bit. + setValueSubclassData(1); // Set the "has lazy arguments" bit. // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -195,7 +195,8 @@ void Function::BuildLazyArguments() const { } // Clear the lazy arguments bit. - const_cast<Function*>(this)->SubclassData &= ~1; + unsigned SDC = getSubclassDataFromValue(); + const_cast<Function*>(this)->setValueSubclassData(SDC &= ~1); } size_t Function::arg_size() const { diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp new file mode 100644 index 0000000000000..699bf0f6535e3 --- /dev/null +++ b/lib/VMCore/IRBuilder.cpp @@ -0,0 +1,51 @@ +//===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===// +// +// 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 IRBuilder class, which is used as a convenient way +// to create LLVM instructions with a consistent and simplified interface. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/IRBuilder.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Function.h" +#include "llvm/LLVMContext.h" +using namespace llvm; + +/// CreateGlobalString - Make a new global variable with an initializer that +/// has array of i8 type filled in the the nul terminated string value +/// specified. If Name is specified, it is the name of the global variable +/// created. +Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) { + Constant *StrConstant = ConstantArray::get(Context, Str, true); + Module &M = *BB->getParent()->getParent(); + GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), + true, GlobalValue::InternalLinkage, + StrConstant, "", 0, false); + GV->setName(Name); + return GV; +} + +/// SetCurrentDebugLocation - Set location information used by debugging +/// information. +void IRBuilderBase::SetCurrentDebugLocation(MDNode *L) { + if (DbgMDKind == 0) + DbgMDKind = Context.getMDKindID("dbg"); + CurDbgLocation = L; +} + +void IRBuilderBase::SetInstDebugLocation(Instruction *I) const { + if (CurDbgLocation) + I->setMetadata(DbgMDKind, CurDbgLocation); +} + +const Type *IRBuilderBase::getCurrentFunctionReturnType() const { + assert(BB && BB->getParent() && "No current function!"); + return BB->getParent()->getReturnType(); +} diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index ce253d64cedf9..a5500e6de4854 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -11,12 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "LLVMContextImpl.h" +#include "llvm/Instruction.h" #include "llvm/Type.h" #include "llvm/Instructions.h" -#include "llvm/Function.h" #include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" #include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" @@ -51,10 +49,8 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, // Out of line virtual method, so the vtable, etc has a home. Instruction::~Instruction() { assert(Parent == 0 && "Instruction still linked in the program!"); - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsDeleted(this); - } + if (hasMetadata()) + removeAllMetadata(); } @@ -464,7 +460,14 @@ bool Instruction::isSafeToSpeculativelyExecute() const { Instruction *Instruction::clone() const { Instruction *New = clone_impl(); New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - getContext().pImpl->TheMetadata.ValueIsCloned(this, New); + if (!hasMetadata()) + return New; + + // Otherwise, enumerate and copy over metadata from the old instruction to the + // new one. + SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs; + getAllMetadata(TheMDs); + for (unsigned i = 0, e = TheMDs.size(); i != e; ++i) + New->setMetadata(TheMDs[i].first, TheMDs[i].second); return New; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index b03ee93dbe751..3e9950e2aade4 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -413,7 +413,9 @@ CallInst::CallInst(const CallInst &CI) OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(), CI.getNumOperands()) { setAttributes(CI.getAttributes()); - SubclassData = CI.SubclassData; + setTailCall(CI.isTailCall()); + setCallingConv(CI.getCallingConv()); + Use *OL = OperandList; Use *InOL = CI.OperandList; for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) @@ -637,7 +639,7 @@ InvokeInst::InvokeInst(const InvokeInst &II) - II.getNumOperands(), II.getNumOperands()) { setAttributes(II.getAttributes()); - SubclassData = II.SubclassData; + setCallingConv(II.getCallingConv()); Use *OL = OperandList, *InOL = II.OperandList; for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i) OL[i] = InOL[i]; @@ -957,7 +959,7 @@ AllocaInst::~AllocaInst() { void AllocaInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); - SubclassData = Log2_32(Align) + 1; + setInstructionSubclassData(Log2_32(Align) + 1); assert(getAlignment() == Align && "Alignment representation error!"); } @@ -1092,7 +1094,8 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile, void LoadInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); - SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1); + setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + ((Log2_32(Align)+1)<<1)); } //===----------------------------------------------------------------------===// @@ -1187,7 +1190,8 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, void StoreInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); - SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1); + setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + ((Log2_32(Align)+1) << 1)); } //===----------------------------------------------------------------------===// @@ -1772,6 +1776,18 @@ BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, Op->getType(), Name, InsertAtEnd); } +BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, + Instruction *InsertBefore) { + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); + return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertBefore); +} + +BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd) { + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); + return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertAtEnd); +} + BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); @@ -2708,7 +2724,7 @@ CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, InsertBefore) { Op<0>() = LHS; Op<1>() = RHS; - SubclassData = predicate; + setPredicate((Predicate)predicate); setName(Name); } @@ -2721,7 +2737,7 @@ CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, InsertAtEnd) { Op<0>() = LHS; Op<1>() = RHS; - SubclassData = predicate; + setPredicate((Predicate)predicate); setName(Name); } diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp index 5f33d0eebb942..5e0f42e063bf8 100644 --- a/lib/VMCore/IntrinsicInst.cpp +++ b/lib/VMCore/IntrinsicInst.cpp @@ -61,11 +61,19 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) { Value *DbgStopPointInst::getFileName() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (7 << 16) && "Verify operand indices"); - return getContext()->getElement(3); + return getContext()->getOperand(3); } Value *DbgStopPointInst::getDirectory() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (7 << 16) && "Verify operand indices"); - return getContext()->getElement(4); + return getContext()->getOperand(4); +} + +//===----------------------------------------------------------------------===// +/// DbgValueInst - This represents the llvm.dbg.value instruction. +/// + +Value *DbgValueInst::getValue() const { + return cast<MDNode>(getOperand(1))->getOperand(0); } diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 3b4a1a3a15540..5a8ea5cf6d34d 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -17,10 +17,7 @@ #include "llvm/Constants.h" #include "llvm/Instruction.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/ValueHandle.h" #include "LLVMContextImpl.h" -#include <set> - using namespace llvm; static ManagedStatic<LLVMContext> GlobalContext; @@ -45,6 +42,3 @@ GetElementPtrConstantExpr::GetElementPtrConstantExpr OperandList[i+1] = IdxList[i]; } -MetadataContext &LLVMContext::getMetadata() { - return pImpl->TheMetadata; -} diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 8a2378ec7c9eb..ccca789209574 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -23,10 +23,12 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include <vector> @@ -159,13 +161,28 @@ public: TypeMap<StructValType, StructType> StructTypes; TypeMap<IntegerValType, IntegerType> IntegerTypes; + // Opaque types are not structurally uniqued, so don't use TypeMap. + typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy; + OpaqueTypesTy OpaqueTypes; + + /// ValueHandles - This map keeps track of all of the value handles that are /// watching a Value*. The Value::HasValueHandle bit is used to know // whether or not a value has an entry in this map. typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy; ValueHandlesTy ValueHandles; - MetadataContext TheMetadata; + /// CustomMDKindNames - Map to hold the metadata string to ID mapping. + StringMap<unsigned> CustomMDKindNames; + + typedef std::pair<unsigned, TrackingVH<MDNode> > MDPairTy; + typedef SmallVector<MDPairTy, 2> MDMapTy; + + /// MetadataStore - Collection of per-instruction metadata used in this + /// context. + DenseMap<const Instruction *, MDMapTy> MetadataStore; + + LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0), VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), @@ -181,8 +198,7 @@ public: Int32Ty(C, 32), Int64Ty(C, 64) { } - ~LLVMContextImpl() - { + ~LLVMContextImpl() { ExprConstants.freeConstants(); ArrayConstants.freeConstants(); StructConstants.freeConstants(); @@ -201,6 +217,11 @@ public: delete I->second; } MDNodeSet.clear(); + for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end(); + I != E; ++I) { + (*I)->AbstractTypeUsers.clear(); + delete *I; + } } }; diff --git a/lib/VMCore/LeaksContext.h b/lib/VMCore/LeaksContext.h index bd10a479ae2a0..abff090b87963 100644 --- a/lib/VMCore/LeaksContext.h +++ b/lib/VMCore/LeaksContext.h @@ -46,8 +46,9 @@ struct LeakDetectorImpl { // immediately, it is added to the CachedValue Value. If it is // immediately removed, no set search need be performed. void addGarbage(const T* o) { + assert(Ts.count(o) == 0 && "Object already in set!"); if (Cache) { - assert(Ts.count(Cache) == 0 && "Object already in set!"); + assert(Cache != o && "Object already in set!"); Ts.insert(Cache); } Cache = o; diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index b80b6bfebc436..8e9aab93a14ae 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -11,23 +11,24 @@ // //===----------------------------------------------------------------------===// -#include "LLVMContextImpl.h" #include "llvm/Metadata.h" +#include "LLVMContextImpl.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Instruction.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "SymbolTableListTraitsImpl.h" +#include "llvm/Support/ValueHandle.h" using namespace llvm; //===----------------------------------------------------------------------===// -// MetadataBase implementation. -// - -//===----------------------------------------------------------------------===// // MDString implementation. // + +MDString::MDString(LLVMContext &C, StringRef S) + : MetadataBase(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {} + MDString *MDString::get(LLVMContext &Context, StringRef Str) { LLVMContextImpl *pImpl = Context.pImpl; StringMapEntry<MDString *> &Entry = @@ -47,23 +48,89 @@ MDString *MDString::get(LLVMContext &Context, const char *Str) { } //===----------------------------------------------------------------------===// +// MDNodeOperand implementation. +// + +// Use CallbackVH to hold MDNode operands. +namespace llvm { +class MDNodeOperand : public CallbackVH { + MDNode *Parent; +public: + MDNodeOperand(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {} + ~MDNodeOperand() {} + + void set(Value *V) { + setValPtr(V); + } + + virtual void deleted(); + virtual void allUsesReplacedWith(Value *NV); +}; +} // end namespace llvm. + + +void MDNodeOperand::deleted() { + Parent->replaceOperand(this, 0); +} + +void MDNodeOperand::allUsesReplacedWith(Value *NV) { + Parent->replaceOperand(this, NV); +} + + + +//===----------------------------------------------------------------------===// // MDNode implementation. // -MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals) - : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) { - NodeSize = NumVals; - Node = new ElementVH[NodeSize]; - ElementVH *Ptr = Node; - for (unsigned i = 0; i != NumVals; ++i) - *Ptr++ = ElementVH(Vals[i], this); + +/// getOperandPtr - Helper function to get the MDNodeOperand's coallocated on +/// the end of the MDNode. +static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) { + assert(Op < N->getNumOperands() && "Invalid operand number"); + return reinterpret_cast<MDNodeOperand*>(N+1)+Op; } -void MDNode::Profile(FoldingSetNodeID &ID) const { - for (unsigned i = 0, e = getNumElements(); i != e; ++i) - ID.AddPointer(getElement(i)); +MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, + bool isFunctionLocal) +: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) { + NumOperands = NumVals; + + if (isFunctionLocal) + setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit); + + // Initialize the operand list, which is co-allocated on the end of the node. + for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands; + Op != E; ++Op, ++Vals) + new (Op) MDNodeOperand(*Vals, this); } -MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { + +/// ~MDNode - Destroy MDNode. +MDNode::~MDNode() { + assert((getSubclassDataFromValue() & DestroyFlag) != 0 && + "Not being destroyed through destroy()?"); + if (!isNotUniqued()) { + LLVMContextImpl *pImpl = getType()->getContext().pImpl; + pImpl->MDNodeSet.RemoveNode(this); + } + + // Destroy the operands. + for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands; + Op != E; ++Op) + Op->~MDNodeOperand(); +} + +// destroy - Delete this node. Only when there are no uses. +void MDNode::destroy() { + setValueSubclassData(getSubclassDataFromValue() | DestroyFlag); + // Placement delete, the free the memory. + this->~MDNode(); + free(this); +} + + +MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, + bool isFunctionLocal) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; for (unsigned i = 0; i != NumVals; ++i) @@ -72,56 +139,58 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); if (!N) { + // Coallocate space for the node and Operands together, then placement new. + void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand)); + N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal); + // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = new MDNode(Context, Vals, NumVals); pImpl->MDNodeSet.InsertNode(N, InsertPoint); } return N; } -/// ~MDNode - Destroy MDNode. -MDNode::~MDNode() { - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - pImpl->MDNodeSet.RemoveNode(this); - delete [] Node; - Node = NULL; +/// getOperand - Return specified operand. +Value *MDNode::getOperand(unsigned i) const { + return *getOperandPtr(const_cast<MDNode*>(this), i); } -// Replace value from this node's element list. -void MDNode::replaceElement(Value *From, Value *To) { - if (From == To || !getType()) - return; - LLVMContext &Context = getType()->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; +void MDNode::Profile(FoldingSetNodeID &ID) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + ID.AddPointer(getOperand(i)); +} - // Find value. This is a linear search, do something if it consumes - // lot of time. It is possible that to have multiple instances of - // From in this MDNode's element list. - SmallVector<unsigned, 4> Indexes; - unsigned Index = 0; - for (unsigned i = 0, e = getNumElements(); i != e; ++i, ++Index) { - Value *V = getElement(i); - if (V && V == From) - Indexes.push_back(Index); - } - if (Indexes.empty()) +// Replace value from this node's operand list. +void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { + Value *From = *Op; + + if (From == To) return; - // Remove "this" from the context map. + // Update the operand. + Op->set(To); + + // If this node is already not being uniqued (because one of the operands + // already went to null), then there is nothing else to do here. + if (isNotUniqued()) return; + + LLVMContextImpl *pImpl = getType()->getContext().pImpl; + + // Remove "this" from the context map. FoldingSet doesn't have to reprofile + // this node to remove it, so we don't care what state the operands are in. pImpl->MDNodeSet.RemoveNode(this); - // Replace From element(s) in place. - for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end(); - I != E; ++I) { - unsigned Index = *I; - Node[Index] = ElementVH(To, this); + // If we are dropping an argument to null, we choose to not unique the MDNode + // anymore. This commonly occurs during destruction, and uniquing these + // brings little reuse. + if (To == 0) { + setIsNotUniqued(); + return; } - - // Insert updated "this" into the context's folding node set. - // If a node with same element list already exist then before inserting - // updated "this" into the folding node set, replace all uses of existing - // node with updated "this" node. + + // Now that the node is out of the folding set, get ready to reinsert it. + // First, check to see if another node with the same operands already exists + // in the set. If it doesn't exist, this returns the position to insert it. FoldingSetNodeID ID; Profile(ID); void *InsertPoint; @@ -129,27 +198,31 @@ void MDNode::replaceElement(Value *From, Value *To) { if (N) { N->replaceAllUsesWith(this); - delete N; - N = 0; + N->destroy(); + N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + assert(N == 0 && "shouldn't be in the map now!"); (void)N; } - N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - if (!N) { - // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = this; - pImpl->MDNodeSet.InsertNode(N, InsertPoint); - } + // InsertPoint will have been set by the FindNodeOrInsertPos call. + pImpl->MDNodeSet.InsertNode(this, InsertPoint); } //===----------------------------------------------------------------------===// // NamedMDNode implementation. // +static SmallVector<TrackingVH<MetadataBase>, 4> &getNMDOps(void *Operands) { + return *(SmallVector<TrackingVH<MetadataBase>, 4>*)Operands; +} + NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N, MetadataBase *const *MDs, unsigned NumMDs, Module *ParentModule) : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) { setName(N); - + + Operands = new SmallVector<TrackingVH<MetadataBase>, 4>(); + + SmallVector<TrackingVH<MetadataBase>, 4> &Node = getNMDOps(Operands); for (unsigned i = 0; i != NumMDs; ++i) Node.push_back(TrackingVH<MetadataBase>(MDs[i])); @@ -160,243 +233,54 @@ NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N, NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) { assert(NMD && "Invalid source NamedMDNode!"); SmallVector<MetadataBase *, 4> Elems; - for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) - Elems.push_back(NMD->getElement(i)); + Elems.reserve(NMD->getNumOperands()); + + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + Elems.push_back(NMD->getOperand(i)); return new NamedMDNode(NMD->getContext(), NMD->getName().data(), Elems.data(), Elems.size(), M); } -/// eraseFromParent - Drop all references and remove the node from parent -/// module. -void NamedMDNode::eraseFromParent() { - getParent()->getNamedMDList().erase(this); -} - -/// dropAllReferences - Remove all uses and clear node vector. -void NamedMDNode::dropAllReferences() { - Node.clear(); -} - NamedMDNode::~NamedMDNode() { dropAllReferences(); + delete &getNMDOps(Operands); } -//===----------------------------------------------------------------------===// -// MetadataContextImpl implementation. -// -namespace llvm { -class MetadataContextImpl { -public: - typedef std::pair<unsigned, TrackingVH<MDNode> > MDPairTy; - typedef SmallVector<MDPairTy, 2> MDMapTy; - typedef DenseMap<const Instruction *, MDMapTy> MDStoreTy; - friend class BitcodeReader; -private: - - /// MetadataStore - Collection of metadata used in this context. - MDStoreTy MetadataStore; - - /// MDHandlerNames - Map to hold metadata handler names. - StringMap<unsigned> MDHandlerNames; - -public: - /// registerMDKind - Register a new metadata kind and return its ID. - /// A metadata kind can be registered only once. - unsigned registerMDKind(StringRef Name); - - /// getMDKind - Return metadata kind. If the requested metadata kind - /// is not registered then return 0. - unsigned getMDKind(StringRef Name) const; - - /// getMD - Get the metadata of given kind attached to an Instruction. - /// If the metadata is not found then return 0. - MDNode *getMD(unsigned Kind, const Instruction *Inst); - - /// getMDs - Get the metadata attached to an Instruction. - void getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const; - - /// addMD - Attach the metadata of given kind to an Instruction. - void addMD(unsigned Kind, MDNode *Node, Instruction *Inst); - - /// removeMD - Remove metadata of given kind attached with an instruction. - void removeMD(unsigned Kind, Instruction *Inst); - - /// removeAllMetadata - Remove all metadata attached with an instruction. - void removeAllMetadata(Instruction *Inst); - - /// copyMD - If metadata is attached with Instruction In1 then attach - /// the same metadata to In2. - void copyMD(Instruction *In1, Instruction *In2); - - /// getHandlerNames - Populate client-supplied smallvector using custom - /// metadata name and ID. - void getHandlerNames(SmallVectorImpl<std::pair<unsigned, StringRef> >&) const; - - /// ValueIsDeleted - This handler is used to update metadata store - /// when a value is deleted. - void ValueIsDeleted(const Value *) {} - void ValueIsDeleted(Instruction *Inst) { - removeAllMetadata(Inst); - } - void ValueIsRAUWd(Value *V1, Value *V2); - - /// ValueIsCloned - This handler is used to update metadata store - /// when In1 is cloned to create In2. - void ValueIsCloned(const Instruction *In1, Instruction *In2); -}; +/// getNumOperands - Return number of NamedMDNode operands. +unsigned NamedMDNode::getNumOperands() const { + return (unsigned)getNMDOps(Operands).size(); } -/// registerMDKind - Register a new metadata kind and return its ID. -/// A metadata kind can be registered only once. -unsigned MetadataContextImpl::registerMDKind(StringRef Name) { - unsigned Count = MDHandlerNames.size(); - assert(MDHandlerNames.count(Name) == 0 && "Already registered MDKind!"); - return MDHandlerNames[Name] = Count + 1; +/// getOperand - Return specified operand. +MetadataBase *NamedMDNode::getOperand(unsigned i) const { + assert(i < getNumOperands() && "Invalid Operand number!"); + return getNMDOps(Operands)[i]; } -/// getMDKind - Return metadata kind. If the requested metadata kind -/// is not registered then return 0. -unsigned MetadataContextImpl::getMDKind(StringRef Name) const { - StringMap<unsigned>::const_iterator I = MDHandlerNames.find(Name); - if (I == MDHandlerNames.end()) - return 0; - - return I->getValue(); +/// addOperand - Add metadata Operand. +void NamedMDNode::addOperand(MetadataBase *M) { + getNMDOps(Operands).push_back(TrackingVH<MetadataBase>(M)); } -/// addMD - Attach the metadata of given kind to an Instruction. -void MetadataContextImpl::addMD(unsigned MDKind, MDNode *Node, - Instruction *Inst) { - assert(Node && "Invalid null MDNode"); - Inst->HasMetadata = true; - MDMapTy &Info = MetadataStore[Inst]; - if (Info.empty()) { - Info.push_back(std::make_pair(MDKind, Node)); - MetadataStore.insert(std::make_pair(Inst, Info)); - return; - } - - // If there is an entry for this MDKind then replace it. - for (unsigned i = 0, e = Info.size(); i != e; ++i) { - MDPairTy &P = Info[i]; - if (P.first == MDKind) { - Info[i] = std::make_pair(MDKind, Node); - return; - } - } - - // Otherwise add a new entry. - Info.push_back(std::make_pair(MDKind, Node)); -} - -/// removeMD - Remove metadata of given kind attached with an instruction. -void MetadataContextImpl::removeMD(unsigned Kind, Instruction *Inst) { - MDStoreTy::iterator I = MetadataStore.find(Inst); - if (I == MetadataStore.end()) - return; - - MDMapTy &Info = I->second; - for (MDMapTy::iterator MI = Info.begin(), ME = Info.end(); MI != ME; ++MI) { - MDPairTy &P = *MI; - if (P.first == Kind) { - Info.erase(MI); - return; - } - } -} - -/// removeAllMetadata - Remove all metadata attached with an instruction. -void MetadataContextImpl::removeAllMetadata(Instruction *Inst) { - MetadataStore.erase(Inst); - Inst->HasMetadata = false; -} - -/// copyMD - If metadata is attached with Instruction In1 then attach -/// the same metadata to In2. -void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) { - assert(In1 && In2 && "Invalid instruction!"); - MDMapTy &In1Info = MetadataStore[In1]; - if (In1Info.empty()) - return; - - for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) - addMD(I->first, I->second, In2); -} - -/// getMD - Get the metadata of given kind attached to an Instruction. -/// If the metadata is not found then return 0. -MDNode *MetadataContextImpl::getMD(unsigned MDKind, const Instruction *Inst) { - MDMapTy &Info = MetadataStore[Inst]; - if (Info.empty()) - return NULL; - - for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; ++I) - if (I->first == MDKind) - return I->second; - return NULL; -} - -/// getMDs - Get the metadata attached to an Instruction. -void MetadataContextImpl:: -getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const { - MDStoreTy::const_iterator I = MetadataStore.find(Inst); - if (I == MetadataStore.end()) - return; - MDs.resize(I->second.size()); - for (MDMapTy::const_iterator MI = I->second.begin(), ME = I->second.end(); - MI != ME; ++MI) - // MD kinds are numbered from 1. - MDs[MI->first - 1] = std::make_pair(MI->first, MI->second); -} - -/// getHandlerNames - Populate client supplied smallvector using custome -/// metadata name and ID. -void MetadataContextImpl:: -getHandlerNames(SmallVectorImpl<std::pair<unsigned, StringRef> >&Names) const { - Names.resize(MDHandlerNames.size()); - for (StringMap<unsigned>::const_iterator I = MDHandlerNames.begin(), - E = MDHandlerNames.end(); I != E; ++I) - // MD Handlers are numbered from 1. - Names[I->second - 1] = std::make_pair(I->second, I->first()); +/// eraseFromParent - Drop all references and remove the node from parent +/// module. +void NamedMDNode::eraseFromParent() { + getParent()->getNamedMDList().erase(this); } -/// ValueIsCloned - This handler is used to update metadata store -/// when In1 is cloned to create In2. -void MetadataContextImpl::ValueIsCloned(const Instruction *In1, - Instruction *In2) { - // Find Metadata handles for In1. - MDStoreTy::iterator I = MetadataStore.find(In1); - assert(I != MetadataStore.end() && "Invalid custom metadata info!"); - - // FIXME : Give all metadata handlers a chance to adjust. - - MDMapTy &In1Info = I->second; - MDMapTy In2Info; - for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) - addMD(I->first, I->second, In2); +/// dropAllReferences - Remove all uses and clear node vector. +void NamedMDNode::dropAllReferences() { + getNMDOps(Operands).clear(); } -/// ValueIsRAUWd - This handler is used when V1's all uses are replaced by -/// V2. -void MetadataContextImpl::ValueIsRAUWd(Value *V1, Value *V2) { - Instruction *I1 = dyn_cast<Instruction>(V1); - Instruction *I2 = dyn_cast<Instruction>(V2); - if (!I1 || !I2) - return; - - // FIXME : Give custom handlers a chance to override this. - ValueIsCloned(I1, I2); -} //===----------------------------------------------------------------------===// -// MetadataContext implementation. +// LLVMContext MDKind naming implementation. // -MetadataContext::MetadataContext() - : pImpl(new MetadataContextImpl()) { } -MetadataContext::~MetadataContext() { delete pImpl; } +#ifndef NDEBUG /// isValidName - Return true if Name is a valid custom metadata handler name. -bool MetadataContext::isValidName(StringRef MDName) { +static bool isValidName(StringRef MDName) { if (MDName.empty()) return false; @@ -410,72 +294,123 @@ bool MetadataContext::isValidName(StringRef MDName) { } return true; } +#endif -/// registerMDKind - Register a new metadata kind and return its ID. -/// A metadata kind can be registered only once. -unsigned MetadataContext::registerMDKind(StringRef Name) { - assert(isValidName(Name) && "Invalid custome metadata name!"); - return pImpl->registerMDKind(Name); -} - -/// getMDKind - Return metadata kind. If the requested metadata kind -/// is not registered then return 0. -unsigned MetadataContext::getMDKind(StringRef Name) const { - return pImpl->getMDKind(Name); +/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. +unsigned LLVMContext::getMDKindID(StringRef Name) const { + assert(isValidName(Name) && "Invalid MDNode name"); + + unsigned &Entry = pImpl->CustomMDKindNames[Name]; + + // If this is new, assign it its ID. + if (Entry == 0) Entry = pImpl->CustomMDKindNames.size(); + return Entry; } -/// getMD - Get the metadata of given kind attached to an Instruction. -/// If the metadata is not found then return 0. -MDNode *MetadataContext::getMD(unsigned Kind, const Instruction *Inst) { - return pImpl->getMD(Kind, Inst); +/// getHandlerNames - Populate client supplied smallvector using custome +/// metadata name and ID. +void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { + Names.resize(pImpl->CustomMDKindNames.size()+1); + Names[0] = ""; + for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), + E = pImpl->CustomMDKindNames.end(); I != E; ++I) + // MD Handlers are numbered from 1. + Names[I->second] = I->first(); } -/// getMDs - Get the metadata attached to an Instruction. -void MetadataContext:: -getMDs(const Instruction *Inst, - SmallVectorImpl<std::pair<unsigned, TrackingVH<MDNode> > > &MDs) const { - return pImpl->getMDs(Inst, MDs); -} +//===----------------------------------------------------------------------===// +// Instruction Metadata method implementations. +// -/// addMD - Attach the metadata of given kind to an Instruction. -void MetadataContext::addMD(unsigned Kind, MDNode *Node, Instruction *Inst) { - pImpl->addMD(Kind, Node, Inst); +void Instruction::setMetadata(const char *Kind, MDNode *Node) { + if (Node == 0 && !hasMetadata()) return; + setMetadata(getContext().getMDKindID(Kind), Node); } -/// removeMD - Remove metadata of given kind attached with an instruction. -void MetadataContext::removeMD(unsigned Kind, Instruction *Inst) { - pImpl->removeMD(Kind, Inst); +MDNode *Instruction::getMetadataImpl(const char *Kind) const { + return getMetadataImpl(getContext().getMDKindID(Kind)); } -/// removeAllMetadata - Remove all metadata attached with an instruction. -void MetadataContext::removeAllMetadata(Instruction *Inst) { - pImpl->removeAllMetadata(Inst); +/// setMetadata - Set the metadata of of the specified kind to the specified +/// node. This updates/replaces metadata if already present, or removes it if +/// Node is null. +void Instruction::setMetadata(unsigned KindID, MDNode *Node) { + if (Node == 0 && !hasMetadata()) return; + + // Handle the case when we're adding/updating metadata on an instruction. + if (Node) { + LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; + assert(!Info.empty() == hasMetadata() && "HasMetadata bit is wonked"); + if (Info.empty()) { + setHasMetadata(true); + } else { + // Handle replacement of an existing value. + for (unsigned i = 0, e = Info.size(); i != e; ++i) + if (Info[i].first == KindID) { + Info[i].second = Node; + return; + } + } + + // No replacement, just add it to the list. + Info.push_back(std::make_pair(KindID, Node)); + return; + } + + // Otherwise, we're removing metadata from an instruction. + assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) && + "HasMetadata bit out of date!"); + LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; + + // Common case is removing the only entry. + if (Info.size() == 1 && Info[0].first == KindID) { + getContext().pImpl->MetadataStore.erase(this); + setHasMetadata(false); + return; + } + + // Handle replacement of an existing value. + for (unsigned i = 0, e = Info.size(); i != e; ++i) + if (Info[i].first == KindID) { + Info[i] = Info.back(); + Info.pop_back(); + assert(!Info.empty() && "Removing last entry should be handled above"); + return; + } + // Otherwise, removing an entry that doesn't exist on the instruction. } -/// copyMD - If metadata is attached with Instruction In1 then attach -/// the same metadata to In2. -void MetadataContext::copyMD(Instruction *In1, Instruction *In2) { - pImpl->copyMD(In1, In2); +MDNode *Instruction::getMetadataImpl(unsigned KindID) const { + LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; + assert(hasMetadata() && !Info.empty() && "Shouldn't have called this"); + + for (LLVMContextImpl::MDMapTy::iterator I = Info.begin(), E = Info.end(); + I != E; ++I) + if (I->first == KindID) + return I->second; + return 0; } -/// getHandlerNames - Populate client supplied smallvector using custome -/// metadata name and ID. -void MetadataContext:: -getHandlerNames(SmallVectorImpl<std::pair<unsigned, StringRef> >&N) const { - pImpl->getHandlerNames(N); +void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, + MDNode*> > &Result)const { + assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) && + "Shouldn't have called this"); + const LLVMContextImpl::MDMapTy &Info = + getContext().pImpl->MetadataStore.find(this)->second; + assert(!Info.empty() && "Shouldn't have called this"); + + Result.clear(); + Result.append(Info.begin(), Info.end()); + + // Sort the resulting array so it is stable. + if (Result.size() > 1) + array_pod_sort(Result.begin(), Result.end()); } -/// ValueIsDeleted - This handler is used to update metadata store -/// when a value is deleted. -void MetadataContext::ValueIsDeleted(Instruction *Inst) { - pImpl->ValueIsDeleted(Inst); -} -void MetadataContext::ValueIsRAUWd(Value *V1, Value *V2) { - pImpl->ValueIsRAUWd(V1, V2); +/// removeAllMetadata - Remove all metadata from this instruction. +void Instruction::removeAllMetadata() { + assert(hasMetadata() && "Caller should check"); + getContext().pImpl->MetadataStore.erase(this); + setHasMetadata(false); } -/// ValueIsCloned - This handler is used to update metadata store -/// when In1 is cloned to create In2. -void MetadataContext::ValueIsCloned(const Instruction *In1, Instruction *In2) { - pImpl->ValueIsCloned(In1, In2); -} diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 3efd3e348823e..a7f503bacb99b 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -47,9 +47,9 @@ GlobalAlias *ilist_traits<GlobalAlias>::createSentinel() { // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file. -template class SymbolTableListTraits<GlobalVariable, Module>; -template class SymbolTableListTraits<Function, Module>; -template class SymbolTableListTraits<GlobalAlias, Module>; +template class llvm::SymbolTableListTraits<GlobalVariable, Module>; +template class llvm::SymbolTableListTraits<Function, Module>; +template class llvm::SymbolTableListTraits<GlobalAlias, Module>; //===----------------------------------------------------------------------===// // Primitive Module methods. @@ -118,6 +118,20 @@ GlobalValue *Module::getNamedValue(StringRef Name) const { return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name)); } +/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. +/// This ID is uniqued across modules in the current LLVMContext. +unsigned Module::getMDKindID(StringRef Name) const { + return Context.getMDKindID(Name); +} + +/// getMDKindNames - Populate client supplied SmallVector with the name for +/// custom metadata IDs registered in this LLVMContext. ID #0 is not used, +/// so it is filled in as an empty string. +void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const { + return Context.getMDKindNames(Result); +} + + //===----------------------------------------------------------------------===// // Methods for easy access to the functions in the module. // diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 52e8a8269a023..d68838584029e 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -1133,7 +1133,7 @@ bool BBPassManager::runOnFunction(Function &F) { removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); } - return Changed |= doFinalization(F); + return doFinalization(F) || Changed; } // Implement doInitialization and doFinalization @@ -1355,7 +1355,7 @@ bool FPPassManager::runOnModule(Module &M) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) runOnFunction(*I); - return Changed |= doFinalization(M); + return doFinalization(M) || Changed; } bool FPPassManager::doInitialization(Module &M) { diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 739c463d91b4f..fd46aa1f41d1f 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -79,6 +79,9 @@ void Type::destroy() const { operator delete(const_cast<Type *>(this)); return; + } else if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) { + LLVMContextImpl *pImpl = this->getContext().pImpl; + pImpl->OpaqueTypes.erase(opaque_this); } // For all the other type subclasses, there is either no contained types or @@ -684,9 +687,11 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2, } } +namespace llvm { // in namespace llvm so findable by ADL static bool TypesEqual(const Type *Ty, const Type *Ty2) { std::map<const Type *, const Type *> EqTypes; - return TypesEqual(Ty, Ty2, EqTypes); + return ::TypesEqual(Ty, Ty2, EqTypes); +} } // AbstractTypeHasCycleThrough - Return true there is a path from CurTy to @@ -722,8 +727,10 @@ static bool ConcreteTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy, return false; } -/// TypeHasCycleThroughItself - Return true if the specified type has a cycle -/// back to itself. +/// TypeHasCycleThroughItself - Return true if the specified type has +/// a cycle back to itself. + +namespace llvm { // in namespace llvm so it's findable by ADL static bool TypeHasCycleThroughItself(const Type *Ty) { SmallPtrSet<const Type*, 128> VisitedTypes; @@ -740,6 +747,7 @@ static bool TypeHasCycleThroughItself(const Type *Ty) { } return false; } +} //===----------------------------------------------------------------------===// // Function Type Factory and Value Class... @@ -955,6 +963,20 @@ bool PointerType::isValidElementType(const Type *ElemTy) { //===----------------------------------------------------------------------===// +// Opaque Type Factory... +// + +OpaqueType *OpaqueType::get(LLVMContext &C) { + OpaqueType *OT = new OpaqueType(C); // All opaque types are distinct + + LLVMContextImpl *pImpl = C.pImpl; + pImpl->OpaqueTypes.insert(OT); + return OT; +} + + + +//===----------------------------------------------------------------------===// // Derived Type Refinement Functions //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 826e8a10b5e46..fe1219f9a88fb 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -19,7 +19,6 @@ #include "llvm/Instructions.h" #include "llvm/Operator.h" #include "llvm/Module.h" -#include "llvm/Metadata.h" #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" @@ -41,7 +40,7 @@ static inline const Type *checkType(const Type *Ty) { } Value::Value(const Type *ty, unsigned scid) - : SubclassID(scid), HasValueHandle(0), HasMetadata(0), + : SubclassID(scid), HasValueHandle(0), SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)), UseList(0), Name(0) { if (isa<CallInst>(this) || isa<InvokeInst>(this)) @@ -57,11 +56,6 @@ Value::Value(const Type *ty, unsigned scid) } Value::~Value() { - if (HasMetadata) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsDeleted(this); - } - // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsDeleted(this); @@ -306,10 +300,6 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); - if (HasMetadata) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsRAUWd(this, New); - } while (!use_empty()) { Use &U = *UseList; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 7aa86b776c761..30528bfebde7b 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -329,6 +329,8 @@ namespace { int VT, unsigned ArgNo, std::string &Suffix); void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, unsigned RetNum, unsigned ParamNum, ...); + void VerifyFunctionLocalMetadata(MDNode *N, Function *F, + SmallPtrSet<MDNode *, 32> &Visited); void VerifyParameterAttrs(Attributes Attrs, const Type *Ty, bool isReturnValue, const Value *V); void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs, @@ -1526,6 +1528,38 @@ void Verifier::VerifyType(const Type *Ty) { } } +/// VerifyFunctionLocalMetadata - Verify that the specified MDNode is local to +/// specified Function. +void Verifier::VerifyFunctionLocalMetadata(MDNode *N, Function *F, + SmallPtrSet<MDNode *, 32> &Visited) { + assert(N->isFunctionLocal() && "Should only be called on function-local MD"); + + // Only visit each node once. + if (!Visited.insert(N)) + return; + + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + Value *V = N->getOperand(i); + if (!V) continue; + + Function *ActualF = 0; + if (Instruction *I = dyn_cast<Instruction>(V)) + ActualF = I->getParent()->getParent(); + else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) + ActualF = BB->getParent(); + else if (Argument *A = dyn_cast<Argument>(V)) + ActualF = A->getParent(); + else if (MDNode *MD = dyn_cast<MDNode>(V)) + if (MD->isFunctionLocal()) + VerifyFunctionLocalMetadata(MD, F, Visited); + + // If this was an instruction, bb, or argument, verify that it is in the + // function that we expect. + Assert1(ActualF == 0 || ActualF == F, + "function-local metadata used in wrong function", N); + } +} + // Flags used by TableGen to mark intrinsic parameters with the // LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes. static const unsigned ExtendedElementVectorType = 0x40000000; @@ -1542,6 +1576,15 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_VERIFIER + // If the intrinsic takes MDNode arguments, verify that they are either global + // or are local to *this* function. + for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) + if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(i))) { + if (!MD->isFunctionLocal()) continue; + SmallPtrSet<MDNode *, 32> Visited; + VerifyFunctionLocalMetadata(MD, CI.getParent()->getParent(), Visited); + } + switch (ID) { default: break; |
