diff options
Diffstat (limited to 'contrib/llvm/lib/IR')
49 files changed, 5753 insertions, 2596 deletions
diff --git a/contrib/llvm/lib/IR/AsmWriter.cpp b/contrib/llvm/lib/IR/AsmWriter.cpp index 7decffd..a7499bc 100644 --- a/contrib/llvm/lib/IR/AsmWriter.cpp +++ b/contrib/llvm/lib/IR/AsmWriter.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This library implements the functionality defined in llvm/Assembly/Writer.h +// This library implements the functionality defined in llvm/IR/Writer.h // // Note that these routines must be extremely tolerant of various errors in the // LLVM code, because it can be used for debugging transformations. @@ -15,18 +15,17 @@ //===----------------------------------------------------------------------===// #include "AsmWriter.h" - -#include "llvm/Assembly/Writer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Assembly/AssemblyAnnotationWriter.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/DebugInfo.h" +#include "llvm/IR/AssemblyAnnotationWriter.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" @@ -34,13 +33,11 @@ #include "llvm/IR/Operator.h" #include "llvm/IR/TypeFinder.h" #include "llvm/IR/ValueSymbolTable.h" -#include "llvm/Support/CFG.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MathExtras.h" - #include <algorithm> #include <cctype> using namespace llvm; @@ -54,19 +51,19 @@ AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} static const Module *getModuleFromVal(const Value *V) { if (const Argument *MA = dyn_cast<Argument>(V)) - return MA->getParent() ? MA->getParent()->getParent() : 0; + return MA->getParent() ? MA->getParent()->getParent() : nullptr; if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) - return BB->getParent() ? BB->getParent()->getParent() : 0; + return BB->getParent() ? BB->getParent()->getParent() : nullptr; if (const Instruction *I = dyn_cast<Instruction>(V)) { - const Function *M = I->getParent() ? I->getParent()->getParent() : 0; - return M ? M->getParent() : 0; + const Function *M = I->getParent() ? I->getParent()->getParent() : nullptr; + return M ? M->getParent() : nullptr; } if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV->getParent(); - return 0; + return nullptr; } static void PrintCallingConv(unsigned cc, raw_ostream &Out) { @@ -76,6 +73,8 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::Cold: Out << "coldcc"; break; case CallingConv::WebKit_JS: Out << "webkit_jscc"; break; case CallingConv::AnyReg: Out << "anyregcc"; break; + case CallingConv::PreserveMost: Out << "preserve_mostcc"; break; + case CallingConv::PreserveAll: Out << "preserve_allcc"; 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; @@ -88,6 +87,8 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::PTX_Device: Out << "ptx_device"; break; case CallingConv::X86_64_SysV: Out << "x86_64_sysvcc"; break; case CallingConv::X86_64_Win64: Out << "x86_64_win64cc"; break; + case CallingConv::SPIR_FUNC: Out << "spir_func"; break; + case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break; } } @@ -105,6 +106,7 @@ static void PrintEscapedString(StringRef Name, raw_ostream &Out) { enum PrefixType { GlobalPrefix, + ComdatPrefix, LabelPrefix, LocalPrefix, NoPrefix @@ -118,6 +120,7 @@ static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) { switch (Prefix) { case NoPrefix: break; case GlobalPrefix: OS << '@'; break; + case ComdatPrefix: OS << '$'; break; case LabelPrefix: break; case LocalPrefix: OS << '%'; break; } @@ -192,16 +195,16 @@ void TypePrinting::incorporateTypes(const Module &M) { /// use of type names or up references to shorten the type name where possible. void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { - case Type::VoidTyID: OS << "void"; break; - case Type::HalfTyID: OS << "half"; break; - case Type::FloatTyID: OS << "float"; break; - case Type::DoubleTyID: OS << "double"; break; - case Type::X86_FP80TyID: OS << "x86_fp80"; break; - case Type::FP128TyID: OS << "fp128"; break; - case Type::PPC_FP128TyID: OS << "ppc_fp128"; break; - case Type::LabelTyID: OS << "label"; break; - case Type::MetadataTyID: OS << "metadata"; break; - case Type::X86_MMXTyID: OS << "x86_mmx"; break; + case Type::VoidTyID: OS << "void"; return; + case Type::HalfTyID: OS << "half"; return; + case Type::FloatTyID: OS << "float"; return; + case Type::DoubleTyID: OS << "double"; return; + case Type::X86_FP80TyID: OS << "x86_fp80"; return; + case Type::FP128TyID: OS << "fp128"; return; + case Type::PPC_FP128TyID: OS << "ppc_fp128"; return; + case Type::LabelTyID: OS << "label"; return; + case Type::MetadataTyID: OS << "metadata"; return; + case Type::X86_MMXTyID: OS << "x86_mmx"; return; case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); return; @@ -261,10 +264,8 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { OS << '>'; return; } - default: - OS << "<unrecognized-type>"; - return; } + llvm_unreachable("Invalid TypeID"); } void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { @@ -421,10 +422,10 @@ static SlotTracker *createSlotTracker(const Value *V) { if (!MD->isFunctionLocal()) return new SlotTracker(MD->getFunction()); - return new SlotTracker((Function *)0); + return new SlotTracker((Function *)nullptr); } - return 0; + return nullptr; } #if 0 @@ -436,21 +437,21 @@ 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), + : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), mNext(0), fNext(0), mdnNext(0), asNext(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), - mNext(0), fNext(0), mdnNext(0), asNext(0) { + : TheModule(F ? F->getParent() : nullptr), TheFunction(F), + FunctionProcessed(false), mNext(0), fNext(0), mdnNext(0), asNext(0) { } inline void SlotTracker::initialize() { if (TheModule) { processModule(); - TheModule = 0; ///< Prevent re-processing next time we're called. + TheModule = nullptr; ///< Prevent re-processing next time we're called. } if (TheFunction && !FunctionProcessed) @@ -525,7 +526,7 @@ void SlotTracker::processFunction() { // optimizer. if (const CallInst *CI = dyn_cast<CallInst>(I)) { if (Function *F = CI->getCalledFunction()) - if (F->getName().startswith("llvm.")) + if (F->isIntrinsic()) for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) CreateMetadataSlot(N); @@ -560,7 +561,7 @@ void SlotTracker::processFunction() { void SlotTracker::purgeFunction() { ST_DEBUG("begin purgeFunction!\n"); fMap.clear(); // Simply discard the function level map - TheFunction = 0; + TheFunction = nullptr; FunctionProcessed = false; ST_DEBUG("end purgeFunction!\n"); } @@ -677,8 +678,6 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, SlotTracker *Machine, const Module *Context); - - static const char *getPredicateText(unsigned predicate) { const char * pred = "unknown"; switch (predicate) { @@ -813,8 +812,8 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, // output the string in hexadecimal format! Note that loading and storing // floating point types changes the bits of NaNs on some hosts, notably // x86, so we must not use these types. - assert(sizeof(double) == sizeof(uint64_t) && - "assuming that double is 64 bits!"); + static_assert(sizeof(double) == sizeof(uint64_t), + "assuming that double is 64 bits!"); char Buffer[40]; APFloat apf = CFP->getValueAPF(); // Halves and floats are represented in ASCII IR as double, convert. @@ -1050,7 +1049,7 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, Out << "!{"; for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) { const Value *V = Node->getOperand(mi); - if (V == 0) + if (!V) Out << "null"; else { TypePrinter->print(V->getType(), Out); @@ -1065,11 +1064,8 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, 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 -/// the whole instruction that generated it. -/// +// Full implementation of printing a Value as an operand with support for +// TypePrinting, etc. static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, TypePrinting *TypePrinter, SlotTracker *Machine, @@ -1131,12 +1127,6 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, return; } - if (V->getValueID() == Value::PseudoSourceValueVal || - V->getValueID() == Value::FixedStackPseudoSourceValueVal) { - V->print(Out); - return; - } - char Prefix = '%'; int Slot; // If we have a SlotTracker, use it. @@ -1165,7 +1155,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Slot = Machine->getLocalSlot(V); } delete Machine; - Machine = 0; + Machine = nullptr; } else { Slot = -1; } @@ -1176,34 +1166,16 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << "<badref>"; } -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. - if (!PrintType && - ((!isa<Constant>(V) && !isa<MDNode>(V)) || - V->hasName() || isa<GlobalValue>(V))) { - WriteAsOperandInternal(Out, V, 0, 0, Context); - return; - } - - if (Context == 0) Context = getModuleFromVal(V); - - TypePrinting TypePrinter; - if (Context) - TypePrinter.incorporateTypes(*Context); - if (PrintType) { - TypePrinter.print(V->getType(), Out); - Out << ' '; - } - - WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context); -} - void AssemblyWriter::init() { - if (TheModule) - TypePrinter.incorporateTypes(*TheModule); + if (!TheModule) + return; + TypePrinter.incorporateTypes(*TheModule); + for (const Function &F : *TheModule) + if (const Comdat *C = F.getComdat()) + Comdats.insert(C); + for (const GlobalVariable &GV : TheModule->globals()) + if (const Comdat *C = GV.getComdat()) + Comdats.insert(C); } @@ -1224,7 +1196,7 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M, AssemblyWriter::~AssemblyWriter() { } void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { - if (Operand == 0) { + if (!Operand) { Out << "<null operand!>"; return; } @@ -1256,9 +1228,40 @@ void AssemblyWriter::writeAtomic(AtomicOrdering Ordering, } } +void AssemblyWriter::writeAtomicCmpXchg(AtomicOrdering SuccessOrdering, + AtomicOrdering FailureOrdering, + SynchronizationScope SynchScope) { + assert(SuccessOrdering != NotAtomic && FailureOrdering != NotAtomic); + + switch (SynchScope) { + case SingleThread: Out << " singlethread"; break; + case CrossThread: break; + } + + switch (SuccessOrdering) { + default: Out << " <bad ordering " << int(SuccessOrdering) << ">"; break; + case Unordered: Out << " unordered"; break; + case Monotonic: Out << " monotonic"; break; + case Acquire: Out << " acquire"; break; + case Release: Out << " release"; break; + case AcquireRelease: Out << " acq_rel"; break; + case SequentiallyConsistent: Out << " seq_cst"; break; + } + + switch (FailureOrdering) { + default: Out << " <bad ordering " << int(FailureOrdering) << ">"; break; + case Unordered: Out << " unordered"; break; + case Monotonic: Out << " monotonic"; break; + case Acquire: Out << " acquire"; break; + case Release: Out << " release"; break; + case AcquireRelease: Out << " acq_rel"; break; + case SequentiallyConsistent: Out << " seq_cst"; break; + } +} + void AssemblyWriter::writeParamOperand(const Value *Operand, AttributeSet Attrs, unsigned Idx) { - if (Operand == 0) { + if (!Operand) { Out << "<null operand!>"; return; } @@ -1282,8 +1285,9 @@ void AssemblyWriter::printModule(const Module *M) { M->getModuleIdentifier().find('\n') == std::string::npos) Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n"; - if (!M->getDataLayout().empty()) - Out << "target datalayout = \"" << M->getDataLayout() << "\"\n"; + const std::string &DL = M->getDataLayoutStr(); + if (!DL.empty()) + Out << "target datalayout = \"" << DL << "\"\n"; if (!M->getTargetTriple().empty()) Out << "target triple = \"" << M->getTargetTriple() << "\"\n"; @@ -1313,6 +1317,15 @@ void AssemblyWriter::printModule(const Module *M) { printTypeIdentities(); + // Output all comdats. + if (!Comdats.empty()) + Out << '\n'; + for (const Comdat *C : Comdats) { + printComdat(C); + if (C != Comdats.back()) + Out << '\n'; + } + // Output all globals. if (!M->global_empty()) Out << '\n'; for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); @@ -1389,10 +1402,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, switch (LT) { case GlobalValue::ExternalLinkage: break; case GlobalValue::PrivateLinkage: Out << "private "; break; - case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break; - case GlobalValue::LinkerPrivateWeakLinkage: - Out << "linker_private_weak "; - break; case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; @@ -1400,8 +1409,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; case GlobalValue::CommonLinkage: Out << "common "; break; case GlobalValue::AppendingLinkage: Out << "appending "; break; - case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; - case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; case GlobalValue::AvailableExternallyLinkage: Out << "available_externally "; @@ -1419,6 +1426,15 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } } +static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT, + formatted_raw_ostream &Out) { + switch (SCT) { + case GlobalValue::DefaultStorageClass: break; + case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break; + case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break; + } +} + static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM, formatted_raw_ostream &Out) { switch (TLM) { @@ -1451,11 +1467,13 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintLinkage(GV->getLinkage(), Out); PrintVisibility(GV->getVisibility(), Out); + PrintDLLStorageClass(GV->getDLLStorageClass(), Out); PrintThreadLocalModel(GV->getThreadLocalMode(), Out); + if (GV->hasUnnamedAddr()) + Out << "unnamed_addr "; if (unsigned AddressSpace = GV->getType()->getAddressSpace()) Out << "addrspace(" << AddressSpace << ") "; - if (GV->hasUnnamedAddr()) Out << "unnamed_addr "; if (GV->isExternallyInitialized()) Out << "externally_initialized "; Out << (GV->isConstant() ? "constant " : "global "); TypePrinter.print(GV->getType()->getElementType(), Out); @@ -1470,6 +1488,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintEscapedString(GV->getSection(), Out); Out << '"'; } + if (GV->hasComdat()) { + Out << ", comdat "; + PrintLLVMName(Out, GV->getComdat()->getName(), ComdatPrefix); + } if (GV->getAlignment()) Out << ", align " << GV->getAlignment(); @@ -1488,6 +1510,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << " = "; } PrintVisibility(GA->getVisibility(), Out); + PrintDLLStorageClass(GA->getDLLStorageClass(), Out); + PrintThreadLocalModel(GA->getThreadLocalMode(), Out); + if (GA->hasUnnamedAddr()) + Out << "unnamed_addr "; Out << "alias "; @@ -1495,7 +1521,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { const Constant *Aliasee = GA->getAliasee(); - if (Aliasee == 0) { + if (!Aliasee) { TypePrinter.print(GA->getType(), Out); Out << " <<NULL ALIASEE>>"; } else { @@ -1506,6 +1532,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << '\n'; } +void AssemblyWriter::printComdat(const Comdat *C) { + C->print(Out); +} + void AssemblyWriter::printTypeIdentities() { if (TypePrinter.NumberedTypes.empty() && TypePrinter.NamedTypes.empty()) @@ -1585,6 +1615,7 @@ void AssemblyWriter::printFunction(const Function *F) { PrintLinkage(F->getLinkage(), Out); PrintVisibility(F->getVisibility(), Out); + PrintDLLStorageClass(F->getDLLStorageClass(), Out); // Print the calling convention. if (F->getCallingConv() != CallingConv::C) { @@ -1642,6 +1673,10 @@ void AssemblyWriter::printFunction(const Function *F) { PrintEscapedString(F->getSection(), Out); Out << '"'; } + if (F->hasComdat()) { + Out << " comdat "; + PrintLLVMName(Out, F->getComdat()->getName(), ComdatPrefix); + } if (F->getAlignment()) Out << " align " << F->getAlignment(); if (F->hasGC()) @@ -1699,7 +1734,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { Out << "<badref>"; } - if (BB->getParent() == 0) { + if (!BB->getParent()) { Out.PadToColumn(50); Out << "; Error: Block without parent!"; } else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block? @@ -1766,8 +1801,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << '%' << SlotNum << " = "; } - if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) - Out << "tail "; + if (const CallInst *CI = dyn_cast<CallInst>(&I)) { + if (CI->isMustTailCall()) + Out << "musttail "; + else if (CI->isTailCall()) + Out << "tail "; + } // Print out the opcode... Out << I.getOpcodeName(); @@ -1777,6 +1816,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { (isa<StoreInst>(I) && cast<StoreInst>(I).isAtomic())) Out << " atomic"; + if (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isWeak()) + Out << " weak"; + // If this is a volatile operation, print out the volatile marker. if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) || (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) || @@ -1796,7 +1838,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeAtomicRMWOperation(Out, RMWI->getOperation()); // Print out the type of the operands... - const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; + const Value *Operand = I.getNumOperands() ? I.getOperand(0) : nullptr; // Special case conditional branches to swizzle the condition out to the front if (isa<BranchInst>(I) && cast<BranchInst>(I).isConditional()) { @@ -1965,6 +2007,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { Out << ' '; + if (AI->isUsedWithInAlloca()) + Out << "inalloca "; TypePrinter.print(AI->getAllocatedType(), Out); if (!AI->getArraySize() || AI->isArrayAllocation()) { Out << ", "; @@ -2035,7 +2079,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (SI->getAlignment()) Out << ", align " << SI->getAlignment(); } else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) { - writeAtomic(CXI->getOrdering(), CXI->getSynchScope()); + writeAtomicCmpXchg(CXI->getSuccessOrdering(), CXI->getFailureOrdering(), + CXI->getSynchScope()); } else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) { writeAtomic(RMWI->getOrdering(), RMWI->getSynchScope()); } else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) { @@ -2136,18 +2181,39 @@ void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { W.printModule(this); } -void NamedMDNode::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { +void NamedMDNode::print(raw_ostream &ROS) const { SlotTracker SlotTable(getParent()); formatted_raw_ostream OS(ROS); - AssemblyWriter W(OS, SlotTable, getParent(), AAW); + AssemblyWriter W(OS, SlotTable, getParent(), nullptr); W.printNamedMDNode(this); } -void Type::print(raw_ostream &OS) const { - if (this == 0) { - OS << "<null Type>"; - return; +void Comdat::print(raw_ostream &ROS) const { + PrintLLVMName(ROS, getName(), ComdatPrefix); + ROS << " = comdat "; + + switch (getSelectionKind()) { + case Comdat::Any: + ROS << "any"; + break; + case Comdat::ExactMatch: + ROS << "exactmatch"; + break; + case Comdat::Largest: + ROS << "largest"; + break; + case Comdat::NoDuplicates: + ROS << "noduplicates"; + break; + case Comdat::SameSize: + ROS << "samesize"; + break; } + + ROS << '\n'; +} + +void Type::print(raw_ostream &OS) const { TypePrinting TP; TP.print(const_cast<Type*>(this), OS); @@ -2159,24 +2225,20 @@ void Type::print(raw_ostream &OS) const { } } -void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { - if (this == 0) { - ROS << "printing a <null> value\n"; - return; - } +void Value::print(raw_ostream &ROS) const { formatted_raw_ostream OS(ROS); if (const Instruction *I = dyn_cast<Instruction>(this)) { - const Function *F = I->getParent() ? I->getParent()->getParent() : 0; + const Function *F = I->getParent() ? I->getParent()->getParent() : nullptr; SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), AAW); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr); W.printInstruction(*I); } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) { SlotTracker SlotTable(BB->getParent()); - AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), AAW); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr); W.printBasicBlock(BB); } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) { SlotTracker SlotTable(GV->getParent()); - AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW); + AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr); if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV)) W.printGlobal(V); else if (const Function *F = dyn_cast<Function>(GV)) @@ -2186,26 +2248,43 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { } else if (const MDNode *N = dyn_cast<MDNode>(this)) { const Function *F = N->getFunction(); SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW); + AssemblyWriter W(OS, SlotTable, F ? F->getParent() : nullptr, nullptr); W.printMDNodeBody(N); } else if (const Constant *C = dyn_cast<Constant>(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); OS << ' '; - WriteConstantInternal(OS, C, TypePrinter, 0, 0); + WriteConstantInternal(OS, C, TypePrinter, nullptr, nullptr); } else if (isa<InlineAsm>(this) || isa<MDString>(this) || isa<Argument>(this)) { - WriteAsOperand(OS, this, true, 0); + this->printAsOperand(OS); } else { - // Otherwise we don't know what it is. Call the virtual function to - // allow a subclass to print itself. - printCustom(OS); + llvm_unreachable("Unknown value to print out!"); } } -// Value::printCustom - subclasses should override this to implement printing. -void Value::printCustom(raw_ostream &OS) const { - llvm_unreachable("Unknown value to print out!"); +void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) const { + // Fast path: Don't construct and populate a TypePrinting object if we + // won't be needing any types printed. + if (!PrintType && + ((!isa<Constant>(this) && !isa<MDNode>(this)) || + hasName() || isa<GlobalValue>(this))) { + WriteAsOperandInternal(O, this, nullptr, nullptr, M); + return; + } + + if (!M) + M = getModuleFromVal(this); + + TypePrinting TypePrinter; + if (M) + TypePrinter.incorporateTypes(*M); + if (PrintType) { + TypePrinter.print(getType(), O); + O << ' '; + } + + WriteAsOperandInternal(O, this, &TypePrinter, nullptr, M); } // Value::dump - allow easy printing of Values from the debugger. @@ -2215,7 +2294,10 @@ void Value::dump() const { print(dbgs()); dbgs() << '\n'; } void Type::dump() const { print(dbgs()); } // Module::dump() - Allow printing of Modules from the debugger. -void Module::dump() const { print(dbgs(), 0); } +void Module::dump() const { print(dbgs(), nullptr); } + +// \brief Allow printing of Comdats from the debugger. +void Comdat::dump() const { print(dbgs()); } // NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger. -void NamedMDNode::dump() const { print(dbgs(), 0); } +void NamedMDNode::dump() const { print(dbgs()); } diff --git a/contrib/llvm/lib/IR/AsmWriter.h b/contrib/llvm/lib/IR/AsmWriter.h index 8f4a377..aef9c8a 100644 --- a/contrib/llvm/lib/IR/AsmWriter.h +++ b/contrib/llvm/lib/IR/AsmWriter.h @@ -16,7 +16,7 @@ #define LLVM_IR_ASSEMBLYWRITER_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SetVector.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/TypeFinder.h" @@ -27,6 +27,7 @@ namespace llvm { class BasicBlock; class Function; class GlobalValue; +class Comdat; class Module; class NamedMDNode; class Value; @@ -67,10 +68,11 @@ protected: const Module *TheModule; private: - OwningPtr<SlotTracker> ModuleSlotTracker; + std::unique_ptr<SlotTracker> ModuleSlotTracker; SlotTracker &Machine; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; + SetVector<const Comdat *> Comdats; public: /// Construct an AssemblyWriter with an external SlotTracker @@ -91,6 +93,9 @@ public: void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx); void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); + void writeAtomicCmpXchg(AtomicOrdering SuccessOrdering, + AtomicOrdering FailureOrdering, + SynchronizationScope SynchScope); void writeAllMDNodes(); void writeMDNode(unsigned Slot, const MDNode *Node); @@ -99,6 +104,7 @@ public: void printTypeIdentities(); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); + void printComdat(const Comdat *C); void printFunction(const Function *F); void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx); void printBasicBlock(const BasicBlock *BB); diff --git a/contrib/llvm/lib/IR/AttributeImpl.h b/contrib/llvm/lib/IR/AttributeImpl.h index ea954ac..cc6d557 100644 --- a/contrib/llvm/lib/IR/AttributeImpl.h +++ b/contrib/llvm/lib/IR/AttributeImpl.h @@ -39,7 +39,7 @@ class AttributeImpl : public FoldingSetNode { protected: enum AttrEntryKind { EnumAttrEntry, - AlignAttrEntry, + IntAttrEntry, StringAttrEntry }; @@ -49,7 +49,7 @@ public: virtual ~AttributeImpl(); bool isEnumAttribute() const { return KindID == EnumAttrEntry; } - bool isAlignAttribute() const { return KindID == AlignAttrEntry; } + bool isIntAttribute() const { return KindID == IntAttrEntry; } bool isStringAttribute() const { return KindID == StringAttrEntry; } bool hasAttribute(Attribute::AttrKind A) const; @@ -67,7 +67,7 @@ public: void Profile(FoldingSetNodeID &ID) const { if (isEnumAttribute()) Profile(ID, getKindAsEnum(), 0); - else if (isAlignAttribute()) + else if (isIntAttribute()) Profile(ID, getKindAsEnum(), getValueAsInt()); else Profile(ID, getKindAsString(), getValueAsString()); @@ -108,19 +108,20 @@ public: Attribute::AttrKind getEnumKind() const { return Kind; } }; -class AlignAttributeImpl : public EnumAttributeImpl { - virtual void anchor(); - unsigned Align; +class IntAttributeImpl : public EnumAttributeImpl { + void anchor() override; + uint64_t Val; public: - AlignAttributeImpl(Attribute::AttrKind Kind, unsigned Align) - : EnumAttributeImpl(AlignAttrEntry, Kind), Align(Align) { + IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val) + : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) { assert( - (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) && - "Wrong kind for alignment attribute!"); + (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment || + Kind == Attribute::Dereferenceable) && + "Wrong kind for int attribute!"); } - unsigned getAlignment() const { return Align; } + uint64_t getValue() const { return Val; } }; class StringAttributeImpl : public AttributeImpl { @@ -164,6 +165,7 @@ public: unsigned getAlignment() const; unsigned getStackAlignment() const; + uint64_t getDereferenceableBytes() const; std::string getAsString(bool InAttrGrp) const; typedef const Attribute *iterator; diff --git a/contrib/llvm/lib/IR/Attributes.cpp b/contrib/llvm/lib/IR/Attributes.cpp index 0f2b7a0..04545ea 100644 --- a/contrib/llvm/lib/IR/Attributes.cpp +++ b/contrib/llvm/lib/IR/Attributes.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/Attributes.h" #include "AttributeImpl.h" #include "LLVMContextImpl.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Type.h" #include "llvm/Support/Atomic.h" @@ -46,7 +47,7 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, if (!Val) PA = new EnumAttributeImpl(Kind); else - PA = new AlignAttributeImpl(Kind, Val); + PA = new IntAttributeImpl(Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -87,6 +88,12 @@ Attribute Attribute::getWithStackAlignment(LLVMContext &Context, return get(Context, StackAlignment, Align); } +Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context, + uint64_t Bytes) { + assert(Bytes && "Bytes must be non-zero."); + return get(Context, Dereferenceable, Bytes); +} + //===----------------------------------------------------------------------===// // Attribute Accessor Methods //===----------------------------------------------------------------------===// @@ -95,8 +102,8 @@ bool Attribute::isEnumAttribute() const { return pImpl && pImpl->isEnumAttribute(); } -bool Attribute::isAlignAttribute() const { - return pImpl && pImpl->isAlignAttribute(); +bool Attribute::isIntAttribute() const { + return pImpl && pImpl->isIntAttribute(); } bool Attribute::isStringAttribute() const { @@ -105,15 +112,15 @@ bool Attribute::isStringAttribute() const { Attribute::AttrKind Attribute::getKindAsEnum() const { if (!pImpl) return None; - assert((isEnumAttribute() || isAlignAttribute()) && + assert((isEnumAttribute() || isIntAttribute()) && "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!"); + assert(isIntAttribute() && + "Expected the attribute to be an integer attribute!"); return pImpl ? pImpl->getValueAsInt() : 0; } @@ -155,6 +162,14 @@ unsigned Attribute::getStackAlignment() const { return pImpl->getValueAsInt(); } +/// This returns the number of dereferenceable bytes. +uint64_t Attribute::getDereferenceableBytes() const { + assert(hasAttribute(Attribute::Dereferenceable) && + "Trying to get dereferenceable bytes from " + "non-dereferenceable attribute!"); + return pImpl->getValueAsInt(); +} + std::string Attribute::getAsString(bool InAttrGrp) const { if (!pImpl) return ""; @@ -166,10 +181,14 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "builtin"; if (hasAttribute(Attribute::ByVal)) return "byval"; + if (hasAttribute(Attribute::InAlloca)) + return "inalloca"; if (hasAttribute(Attribute::InlineHint)) return "inlinehint"; if (hasAttribute(Attribute::InReg)) return "inreg"; + if (hasAttribute(Attribute::JumpTable)) + return "jumptable"; if (hasAttribute(Attribute::MinSize)) return "minsize"; if (hasAttribute(Attribute::Naked)) @@ -190,6 +209,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "noinline"; if (hasAttribute(Attribute::NonLazyBind)) return "nonlazybind"; + if (hasAttribute(Attribute::NonNull)) + return "nonnull"; if (hasAttribute(Attribute::NoRedZone)) return "noredzone"; if (hasAttribute(Attribute::NoReturn)) @@ -256,6 +277,20 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return Result; } + if (hasAttribute(Attribute::Dereferenceable)) { + std::string Result; + Result += "dereferenceable"; + if (InAttrGrp) { + Result += "="; + Result += utostr(getValueAsInt()); + } else { + Result += "("; + Result += utostr(getValueAsInt()); + Result += ")"; + } + return Result; + } + // Convert target-dependent attributes to strings of the form: // // "kind" @@ -286,10 +321,10 @@ bool Attribute::operator<(Attribute A) const { // AttributeImpl Definition //===----------------------------------------------------------------------===// -// Pin the vtabels to this file. +// Pin the vtables to this file. AttributeImpl::~AttributeImpl() {} void EnumAttributeImpl::anchor() {} -void AlignAttributeImpl::anchor() {} +void IntAttributeImpl::anchor() {} void StringAttributeImpl::anchor() {} bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { @@ -303,13 +338,13 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { } Attribute::AttrKind AttributeImpl::getKindAsEnum() const { - assert(isEnumAttribute() || isAlignAttribute()); + assert(isEnumAttribute() || isIntAttribute()); return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); } uint64_t AttributeImpl::getValueAsInt() const { - assert(isAlignAttribute()); - return static_cast<const AlignAttributeImpl *>(this)->getAlignment(); + assert(isIntAttribute()); + return static_cast<const IntAttributeImpl *>(this)->getValue(); } StringRef AttributeImpl::getKindAsString() const { @@ -327,18 +362,18 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { // relative to their enum value) and then strings. if (isEnumAttribute()) { if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum(); - if (AI.isAlignAttribute()) return true; + if (AI.isIntAttribute()) return true; if (AI.isStringAttribute()) return true; } - if (isAlignAttribute()) { + if (isIntAttribute()) { if (AI.isEnumAttribute()) return false; - if (AI.isAlignAttribute()) return getValueAsInt() < AI.getValueAsInt(); + if (AI.isIntAttribute()) return getValueAsInt() < AI.getValueAsInt(); if (AI.isStringAttribute()) return true; } if (AI.isEnumAttribute()) return false; - if (AI.isAlignAttribute()) return false; + if (AI.isIntAttribute()) return false; if (getKindAsString() == AI.getKindAsString()) return getValueAsString() < AI.getValueAsString(); return getKindAsString() < AI.getKindAsString(); @@ -388,6 +423,11 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { case Attribute::Cold: return 1ULL << 40; case Attribute::Builtin: return 1ULL << 41; case Attribute::OptimizeNone: return 1ULL << 42; + case Attribute::InAlloca: return 1ULL << 43; + case Attribute::NonNull: return 1ULL << 44; + case Attribute::JumpTable: return 1ULL << 45; + case Attribute::Dereferenceable: + llvm_unreachable("dereferenceable attribute not supported in raw format"); } llvm_unreachable("Unsupported attribute type"); } @@ -399,7 +439,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { AttributeSetNode *AttributeSetNode::get(LLVMContext &C, ArrayRef<Attribute> Attrs) { if (Attrs.empty()) - return 0; + return nullptr; // Otherwise, build a key to look up the existing attributes. LLVMContextImpl *pImpl = C.pImpl; @@ -472,6 +512,13 @@ unsigned AttributeSetNode::getStackAlignment() const { return 0; } +uint64_t AttributeSetNode::getDereferenceableBytes() const { + for (iterator I = begin(), E = end(); I != E; ++I) + if (I->hasAttribute(Attribute::Dereferenceable)) + return I->getDereferenceableBytes(); + return 0; +} + std::string AttributeSetNode::getAsString(bool InAttrGrp) const { std::string Str; for (iterator I = begin(), E = end(); I != E; ++I) { @@ -505,6 +552,8 @@ uint64_t AttributeSetImpl::Raw(unsigned Index) const { Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16; else if (Kind == Attribute::StackAlignment) Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26; + else if (Kind == Attribute::Dereferenceable) + llvm_unreachable("dereferenceable not supported in bit mask"); else Mask |= AttributeImpl::getAttrMask(Kind); } @@ -592,7 +641,8 @@ AttributeSet AttributeSet::get(LLVMContext &C, return getImpl(C, Attrs); } -AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, AttrBuilder &B) { +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, + const AttrBuilder &B) { if (!B.hasAttributes()) return AttributeSet(); @@ -609,14 +659,18 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, AttrBuilder &B) { else if (Kind == Attribute::StackAlignment) Attrs.push_back(std::make_pair(Index, Attribute:: getWithStackAlignment(C, B.getStackAlignment()))); + else if (Kind == Attribute::Dereferenceable) + Attrs.push_back(std::make_pair(Index, + Attribute::getWithDereferenceableBytes(C, + B.getDereferenceableBytes()))); else Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind))); } // Add target-dependent (string) attributes. - for (AttrBuilder::td_iterator I = B.td_begin(), E = B.td_end(); - I != E; ++I) - Attrs.push_back(std::make_pair(Index, Attribute::get(C, I->first,I->second))); + for (const AttrBuilder::td_type &TDA : B.td_attrs()) + Attrs.push_back( + std::make_pair(Index, Attribute::get(C, TDA.first, TDA.second))); return get(C, Attrs); } @@ -833,7 +887,7 @@ bool AttributeSet::hasAttributes(unsigned Index) const { /// \brief Return true if the specified attribute is set for at least one /// parameter or for the return value. bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { - if (pImpl == 0) return false; + if (!pImpl) return false; for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) for (AttributeSetImpl::iterator II = pImpl->begin(I), @@ -866,6 +920,11 @@ unsigned AttributeSet::getStackAlignment(unsigned Index) const { return ASN ? ASN->getStackAlignment() : 0; } +uint64_t AttributeSet::getDereferenceableBytes(unsigned Index) const { + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->getDereferenceableBytes() : 0; +} + std::string AttributeSet::getAsString(unsigned Index, bool InAttrGrp) const { AttributeSetNode *ASN = getAttributes(Index); @@ -874,14 +933,14 @@ std::string AttributeSet::getAsString(unsigned Index, /// \brief The attributes for the specified index are returned. AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const { - if (!pImpl) return 0; + if (!pImpl) return nullptr; // Loop through to find the attribute node we want. for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) if (pImpl->getSlotIndex(I) == Index) return pImpl->getSlotNode(I); - return 0; + return nullptr; } AttributeSet::iterator AttributeSet::begin(unsigned Slot) const { @@ -945,7 +1004,7 @@ void AttributeSet::dump() const { //===----------------------------------------------------------------------===// AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index) - : Attrs(0), Alignment(0), StackAlignment(0) { + : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) { AttributeSetImpl *pImpl = AS.pImpl; if (!pImpl) return; @@ -962,13 +1021,14 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index) void AttrBuilder::clear() { Attrs.reset(); - Alignment = StackAlignment = 0; + Alignment = StackAlignment = DerefBytes = 0; } AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && - "Adding alignment attribute without adding alignment value!"); + Val != Attribute::Dereferenceable && + "Adding integer attribute without adding a value!"); Attrs[Val] = true; return *this; } @@ -986,6 +1046,8 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { Alignment = Attr.getAlignment(); else if (Kind == Attribute::StackAlignment) StackAlignment = Attr.getStackAlignment(); + else if (Kind == Attribute::Dereferenceable) + DerefBytes = Attr.getDereferenceableBytes(); return *this; } @@ -1002,6 +1064,8 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { Alignment = 0; else if (Val == Attribute::StackAlignment) StackAlignment = 0; + else if (Val == Attribute::Dereferenceable) + DerefBytes = 0; return *this; } @@ -1018,7 +1082,7 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) { Attribute Attr = *I; - if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { + if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { Attribute::AttrKind Kind = I->getKindAsEnum(); Attrs[Kind] = false; @@ -1026,6 +1090,8 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { Alignment = 0; else if (Kind == Attribute::StackAlignment) StackAlignment = 0; + else if (Kind == Attribute::Dereferenceable) + DerefBytes = 0; } else { assert(Attr.isStringAttribute() && "Invalid attribute type!"); std::map<std::string, std::string>::iterator @@ -1068,6 +1134,14 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { return *this; } +AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { + if (Bytes == 0) return *this; + + Attrs[Attribute::Dereferenceable] = true; + DerefBytes = Bytes; + return *this; +} + AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { // FIXME: What if both have alignments, but they don't match?! if (!Alignment) @@ -1076,6 +1150,9 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { if (!StackAlignment) StackAlignment = B.StackAlignment; + if (!DerefBytes) + DerefBytes = B.DerefBytes; + Attrs |= B.Attrs; for (td_const_iterator I = B.TargetDepAttrs.begin(), @@ -1106,7 +1183,7 @@ bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) { Attribute Attr = *I; - if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { + if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { if (Attrs[I->getKindAsEnum()]) return true; } else { @@ -1131,7 +1208,8 @@ bool AttrBuilder::operator==(const AttrBuilder &B) { if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end()) return false; - return Alignment == B.Alignment && StackAlignment == B.StackAlignment; + return Alignment == B.Alignment && StackAlignment == B.StackAlignment && + DerefBytes == B.DerefBytes; } AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { @@ -1140,6 +1218,8 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; I = Attribute::AttrKind(I + 1)) { + if (I == Attribute::Dereferenceable) + continue; if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { Attrs[I] = true; @@ -1172,9 +1252,12 @@ AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { .addAttribute(Attribute::Nest) .addAttribute(Attribute::NoAlias) .addAttribute(Attribute::NoCapture) + .addAttribute(Attribute::NonNull) + .addDereferenceableAttr(1) // the int here is ignored .addAttribute(Attribute::ReadNone) .addAttribute(Attribute::ReadOnly) - .addAttribute(Attribute::StructRet); + .addAttribute(Attribute::StructRet) + .addAttribute(Attribute::InAlloca); return AttributeSet::get(Ty->getContext(), Index, Incompatible); } diff --git a/contrib/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm/lib/IR/AutoUpgrade.cpp index d12bf7b..459bd88 100644 --- a/contrib/llvm/lib/IR/AutoUpgrade.cpp +++ b/contrib/llvm/lib/IR/AutoUpgrade.cpp @@ -11,17 +11,18 @@ // //===----------------------------------------------------------------------===// -#include "llvm/AutoUpgrade.h" -#include "llvm/DebugInfo.h" +#include "llvm/IR/AutoUpgrade.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" #include <cstring> using namespace llvm; @@ -113,8 +114,11 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name == "x86.avx.movnt.pd.256" || Name == "x86.avx.movnt.ps.256" || Name == "x86.sse42.crc32.64.8" || + Name == "x86.avx.vbroadcast.ss" || + Name == "x86.avx.vbroadcast.ss.256" || + Name == "x86.avx.vbroadcast.sd.256" || (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) { - NewFn = 0; + NewFn = nullptr; return true; } // SSE4.1 ptest functions may have an old signature. @@ -157,7 +161,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { - NewFn = 0; + NewFn = nullptr; bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); // Upgrade intrinsic attributes. This does not change the function. @@ -169,7 +173,62 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { return Upgraded; } +static bool UpgradeGlobalStructors(GlobalVariable *GV) { + ArrayType *ATy = dyn_cast<ArrayType>(GV->getType()->getElementType()); + StructType *OldTy = + ATy ? dyn_cast<StructType>(ATy->getElementType()) : nullptr; + + // Only upgrade an array of a two field struct with the appropriate field + // types. + if (!OldTy || OldTy->getNumElements() != 2) + return false; + + // Get the upgraded 3 element type. + PointerType *VoidPtrTy = Type::getInt8Ty(GV->getContext())->getPointerTo(); + Type *Tys[3] = { + OldTy->getElementType(0), + OldTy->getElementType(1), + VoidPtrTy + }; + StructType *NewTy = + StructType::get(GV->getContext(), Tys, /*isPacked=*/false); + + // Build new constants with a null third field filled in. + Constant *OldInitC = GV->getInitializer(); + ConstantArray *OldInit = dyn_cast<ConstantArray>(OldInitC); + if (!OldInit && !isa<ConstantAggregateZero>(OldInitC)) + return false; + std::vector<Constant *> Initializers; + if (OldInit) { + for (Use &U : OldInit->operands()) { + ConstantStruct *Init = cast<ConstantStruct>(&U); + Constant *NewInit = + ConstantStruct::get(NewTy, Init->getOperand(0), Init->getOperand(1), + Constant::getNullValue(VoidPtrTy), nullptr); + Initializers.push_back(NewInit); + } + } + assert(Initializers.size() == ATy->getNumElements()); + + // Replace the old GV with a new one. + ATy = ArrayType::get(NewTy, Initializers.size()); + Constant *NewInit = ConstantArray::get(ATy, Initializers); + GlobalVariable *NewGV = new GlobalVariable( + *GV->getParent(), ATy, GV->isConstant(), GV->getLinkage(), NewInit, "", + GV, GV->getThreadLocalMode(), GV->getType()->getAddressSpace(), + GV->isExternallyInitialized()); + NewGV->copyAttributesFrom(GV); + NewGV->takeName(GV); + assert(GV->use_empty() && "program cannot use initializer list"); + GV->eraseFromParent(); + return true; +} + bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { + if (GV->getName() == "llvm.global_ctors" || + GV->getName() == "llvm.global_dtors") + return UpgradeGlobalStructors(GV); + // Nothing to do yet. return false; } @@ -279,6 +338,19 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 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 if (Name.startswith("llvm.x86.avx.vbroadcast")) { + // Replace broadcasts with a series of insertelements. + Type *VecTy = CI->getType(); + Type *EltTy = VecTy->getVectorElementType(); + unsigned EltNum = VecTy->getVectorNumElements(); + Value *Cast = Builder.CreateBitCast(CI->getArgOperand(0), + EltTy->getPointerTo()); + Value *Load = Builder.CreateLoad(Cast); + Type *I32Ty = Type::getInt32Ty(C); + Rep = UndefValue::get(VecTy); + for (unsigned I = 0; I < EltNum; ++I) + Rep = Builder.CreateInsertElement(Rep, Load, + ConstantInt::get(I32Ty, I)); } else { bool PD128 = false, PD256 = false, PS128 = false, PS256 = false; if (Name == "llvm.x86.avx.vpermil.pd.256") @@ -410,7 +482,7 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { if (UpgradeIntrinsicFunction(F, NewFn)) { if (NewFn != F) { // Replace all uses to the old function with the new one if necessary. - for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); + for (Value::user_iterator UI = F->user_begin(), UE = F->user_end(); UI != UE; ) { if (CallInst *CI = dyn_cast<CallInst>(*UI++)) UpgradeIntrinsicCall(CI, NewFn); @@ -452,9 +524,9 @@ void llvm::UpgradeInstWithTBAATag(Instruction *I) { Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, Instruction *&Temp) { if (Opc != Instruction::BitCast) - return 0; + return nullptr; - Temp = 0; + Temp = nullptr; Type *SrcTy = V->getType(); if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) { @@ -468,12 +540,12 @@ Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, return CastInst::Create(Instruction::IntToPtr, Temp, DestTy); } - return 0; + return nullptr; } Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { if (Opc != Instruction::BitCast) - return 0; + return nullptr; Type *SrcTy = C->getType(); if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() && @@ -488,14 +560,29 @@ Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { DestTy); } - return 0; + return nullptr; } /// 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) + unsigned Version = getDebugMetadataVersionFromModule(M); + if (Version == DEBUG_METADATA_VERSION) return false; - return StripDebugInfo(M); + bool RetCode = StripDebugInfo(M); + if (RetCode) { + DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version); + M.getContext().diagnose(DiagVersion); + } + return RetCode; +} + +void llvm::UpgradeMDStringConstant(std::string &String) { + const std::string OldPrefix = "llvm.vectorizer."; + if (String == "llvm.vectorizer.unroll") { + String = "llvm.loop.interleave.count"; + } else if (String.find(OldPrefix) == 0) { + String.replace(0, OldPrefix.size(), "llvm.loop.vectorize."); + } } diff --git a/contrib/llvm/lib/IR/BasicBlock.cpp b/contrib/llvm/lib/IR/BasicBlock.cpp index 41e58ec..ba07433 100644 --- a/contrib/llvm/lib/IR/BasicBlock.cpp +++ b/contrib/llvm/lib/IR/BasicBlock.cpp @@ -14,20 +14,24 @@ #include "llvm/IR/BasicBlock.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Type.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/LeakDetector.h" #include <algorithm> using namespace llvm; ValueSymbolTable *BasicBlock::getValueSymbolTable() { if (Function *F = getParent()) return &F->getValueSymbolTable(); - return 0; + return nullptr; +} + +const DataLayout *BasicBlock::getDataLayout() const { + return getParent()->getDataLayout(); } LLVMContext &BasicBlock::getContext() const { @@ -41,7 +45,7 @@ template class llvm::SymbolTableListTraits<Instruction, BasicBlock>; BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0) { + : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) { // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -70,14 +74,14 @@ BasicBlock::~BasicBlock() { Constant *Replacement = ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1); while (!use_empty()) { - BlockAddress *BA = cast<BlockAddress>(use_back()); + BlockAddress *BA = cast<BlockAddress>(user_back()); BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement, BA->getType())); BA->destroyConstant(); } } - assert(getParent() == 0 && "BasicBlock still linked into the program!"); + assert(getParent() == nullptr && "BasicBlock still linked into the program!"); dropAllReferences(); InstList.clear(); } @@ -118,12 +122,12 @@ void BasicBlock::moveAfter(BasicBlock *MovePos) { TerminatorInst *BasicBlock::getTerminator() { - if (InstList.empty()) return 0; + if (InstList.empty()) return nullptr; return dyn_cast<TerminatorInst>(&InstList.back()); } const TerminatorInst *BasicBlock::getTerminator() const { - if (InstList.empty()) return 0; + if (InstList.empty()) return nullptr; return dyn_cast<TerminatorInst>(&InstList.back()); } @@ -182,10 +186,10 @@ void BasicBlock::dropAllReferences() { /// return the block, otherwise return a null pointer. BasicBlock *BasicBlock::getSinglePredecessor() { pred_iterator PI = pred_begin(this), E = pred_end(this); - if (PI == E) return 0; // No preds. + if (PI == E) return nullptr; // No preds. BasicBlock *ThePred = *PI; ++PI; - return (PI == E) ? ThePred : 0 /*multiple preds*/; + return (PI == E) ? ThePred : nullptr /*multiple preds*/; } /// getUniquePredecessor - If this basic block has a unique predecessor block, @@ -195,12 +199,12 @@ BasicBlock *BasicBlock::getSinglePredecessor() { /// a switch statement with multiple cases having the same destination). BasicBlock *BasicBlock::getUniquePredecessor() { pred_iterator PI = pred_begin(this), E = pred_end(this); - if (PI == E) return 0; // No preds. + if (PI == E) return nullptr; // No preds. BasicBlock *PredBB = *PI; ++PI; for (;PI != E; ++PI) { if (*PI != PredBB) - return 0; + return nullptr; // The same predecessor appears multiple times in the predecessor list. // This is OK. } @@ -273,7 +277,7 @@ void BasicBlock::removePredecessor(BasicBlock *Pred, PN->removeIncomingValue(Pred, false); // If all incoming values to the Phi are the same, we can replace the Phi // with that value. - Value* PNV = 0; + Value* PNV = nullptr; if (!DontDeleteUselessPHIs && (PNV = PN->hasConstantValue())) if (PNV != PN) { PN->replaceAllUsesWith(PNV); @@ -300,7 +304,7 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) { assert(I != InstList.end() && "Trying to get me to create degenerate basic block!"); - BasicBlock *InsertBefore = llvm::next(Function::iterator(this)) + BasicBlock *InsertBefore = std::next(Function::iterator(this)) .getNodePtrUnchecked(); BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(), InsertBefore); diff --git a/contrib/llvm/lib/IR/Comdat.cpp b/contrib/llvm/lib/IR/Comdat.cpp new file mode 100644 index 0000000..80715ff --- /dev/null +++ b/contrib/llvm/lib/IR/Comdat.cpp @@ -0,0 +1,25 @@ +//===-- Comdat.cpp - Implement Metadata classes --------------------------===// +// +// 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 Comdat class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Comdat.h" +#include "llvm/ADT/StringMap.h" +using namespace llvm; + +Comdat::Comdat(SelectionKind SK, StringMapEntry<Comdat> *Name) + : Name(Name), SK(SK) {} + +Comdat::Comdat(Comdat &&C) : Name(C.Name), SK(C.SK) {} + +Comdat::Comdat() : Name(nullptr), SK(Comdat::Any) {} + +StringRef Comdat::getName() const { return Name->first(); } diff --git a/contrib/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm/lib/IR/ConstantFold.cpp index f5e225c..395ac39 100644 --- a/contrib/llvm/lib/IR/ConstantFold.cpp +++ b/contrib/llvm/lib/IR/ConstantFold.cpp @@ -22,13 +22,13 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include <limits> @@ -51,7 +51,7 @@ static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) { // Analysis/ConstantFolding.cpp unsigned NumElts = DstTy->getNumElements(); if (NumElts != CV->getType()->getVectorNumElements()) - return 0; + return nullptr; Type *DstEltTy = DstTy->getElementType(); @@ -94,7 +94,7 @@ foldConstantCastPair( // Let CastInst::isEliminableCastPair do the heavy lifting. return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, - 0, FakeIntPtrTy, 0); + nullptr, FakeIntPtrTy, nullptr); } static Constant *FoldBitCast(Constant *V, Type *DestTy) { @@ -139,7 +139,7 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { if (VectorType *SrcTy = dyn_cast<VectorType>(V->getType())) { assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && "Not cast between same sized vectors!"); - SrcTy = NULL; + SrcTy = nullptr; // First, check for null. Undef is already handled. if (isa<ConstantAggregateZero>(V)) return Constant::getNullValue(DestTy); @@ -173,7 +173,7 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { CI->getValue())); // Otherwise, can't fold this (vector?) - return 0; + return nullptr; } // Handle ConstantFP input: FP -> Integral. @@ -181,7 +181,7 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { return ConstantInt::get(FP->getContext(), FP->getValueAPF().bitcastToAPInt()); - return 0; + return nullptr; } @@ -216,14 +216,14 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, // In the input is a constant expr, we might be able to recursively simplify. // If not, we definitely can't do anything. ConstantExpr *CE = dyn_cast<ConstantExpr>(C); - if (CE == 0) return 0; - + if (!CE) return nullptr; + switch (CE->getOpcode()) { - default: return 0; + default: return nullptr; case Instruction::Or: { Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize); - if (RHS == 0) - return 0; + if (!RHS) + return nullptr; // X | -1 -> -1. if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) @@ -231,32 +231,32 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, return RHSC; Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize); - if (LHS == 0) - return 0; + if (!LHS) + return nullptr; return ConstantExpr::getOr(LHS, RHS); } case Instruction::And: { Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize); - if (RHS == 0) - return 0; + if (!RHS) + return nullptr; // X & 0 -> 0. if (RHS->isNullValue()) return RHS; Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize); - if (LHS == 0) - return 0; + if (!LHS) + return nullptr; return ConstantExpr::getAnd(LHS, RHS); } case Instruction::LShr: { ConstantInt *Amt = dyn_cast<ConstantInt>(CE->getOperand(1)); - if (Amt == 0) - return 0; + if (!Amt) + return nullptr; unsigned ShAmt = Amt->getZExtValue(); // Cannot analyze non-byte shifts. if ((ShAmt & 7) != 0) - return 0; + return nullptr; ShAmt >>= 3; // If the extract is known to be all zeros, return zero. @@ -268,17 +268,17 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, return ExtractConstantBytes(CE->getOperand(0), ByteStart+ShAmt, ByteSize); // TODO: Handle the 'partially zero' case. - return 0; + return nullptr; } case Instruction::Shl: { ConstantInt *Amt = dyn_cast<ConstantInt>(CE->getOperand(1)); - if (Amt == 0) - return 0; + if (!Amt) + return nullptr; unsigned ShAmt = Amt->getZExtValue(); // Cannot analyze non-byte shifts. if ((ShAmt & 7) != 0) - return 0; + return nullptr; ShAmt >>= 3; // If the extract is known to be all zeros, return zero. @@ -290,7 +290,7 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, return ExtractConstantBytes(CE->getOperand(0), ByteStart-ShAmt, ByteSize); // TODO: Handle the 'partially zero' case. - return 0; + return nullptr; } case Instruction::ZExt: { @@ -324,7 +324,7 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart, } // TODO: Handle the 'partially zero' case. - return 0; + return nullptr; } } } @@ -376,7 +376,7 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, // If there's no interesting folding happening, bail so that we don't create // a constant that looks like it needs folding but really doesn't. if (!Folded) - return 0; + return nullptr; // Base case: Get a regular sizeof expression. Constant *C = ConstantExpr::getSizeOf(Ty); @@ -442,7 +442,7 @@ static Constant *getFoldedAlignOf(Type *Ty, Type *DestTy, // If there's no interesting folding happening, bail so that we don't create // a constant that looks like it needs folding but really doesn't. if (!Folded) - return 0; + return nullptr; // Base case: Get a regular alignof expression. Constant *C = ConstantExpr::getAlignOf(Ty); @@ -473,7 +473,7 @@ static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo, unsigned NumElems = STy->getNumElements(); // An empty struct has no members. if (NumElems == 0) - return 0; + return nullptr; // Check for a struct with all members having the same size. Constant *MemberSize = getFoldedSizeOf(STy->getElementType(0), DestTy, true); @@ -497,7 +497,7 @@ static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo, // If there's no interesting folding happening, bail so that we don't create // a constant that looks like it needs folding but really doesn't. if (!Folded) - return 0; + return nullptr; // Base case: Get a regular offsetof expression. Constant *C = ConstantExpr::getOffsetOf(Ty, FieldNo); @@ -529,7 +529,10 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, // Try hard to fold cast of cast because they are often eliminable. if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy)) return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy); - } else if (CE->getOpcode() == Instruction::GetElementPtr) { + } else if (CE->getOpcode() == Instruction::GetElementPtr && + // Do not fold addrspacecast (gep 0, .., 0). It might make the + // addrspacecast uncanonicalized. + opc != Instruction::AddrSpaceCast) { // If all of the indexes in the GEP are null values, there is no pointer // adjustment going on. We might as well cast the source pointer. bool isAllNull = true; @@ -582,7 +585,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, APFloat::rmNearestTiesToEven, &ignored); return ConstantFP::get(V->getContext(), Val); } - return 0; // Can't fold. + return nullptr; // Can't fold. case Instruction::FPToUI: case Instruction::FPToSI: if (ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { @@ -595,11 +598,11 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, APInt Val(DestBitWidth, x); return ConstantInt::get(FPC->getContext(), Val); } - return 0; // Can't fold. + return nullptr; // Can't fold. case Instruction::IntToPtr: //always treated as unsigned if (V->isNullValue()) // Is it an integral null value? return ConstantPointerNull::get(cast<PointerType>(DestTy)); - return 0; // Other pointer types cannot be casted + return nullptr; // Other pointer types cannot be casted case Instruction::PtrToInt: // always treated as unsigned // Is it a null pointer value? if (V->isNullValue()) @@ -643,7 +646,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, } } // Other pointer types cannot be casted - return 0; + return nullptr; case Instruction::UIToFP: case Instruction::SIToFP: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { @@ -655,21 +658,21 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, APFloat::rmNearestTiesToEven); return ConstantFP::get(V->getContext(), apf); } - return 0; + return nullptr; case Instruction::ZExt: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); return ConstantInt::get(V->getContext(), CI->getValue().zext(BitWidth)); } - return 0; + return nullptr; case Instruction::SExt: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); return ConstantInt::get(V->getContext(), CI->getValue().sext(BitWidth)); } - return 0; + return nullptr; case Instruction::Trunc: { uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { @@ -685,12 +688,12 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, if (Constant *Res = ExtractConstantBytes(V, 0, DestBitWidth / 8)) return Res; - return 0; + return nullptr; } case Instruction::BitCast: return FoldBitCast(V, DestTy); case Instruction::AddrSpaceCast: - return 0; + return nullptr; } } @@ -705,12 +708,21 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, SmallVector<Constant*, 16> Result; Type *Ty = IntegerType::get(CondV->getContext(), 32); for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){ - ConstantInt *Cond = dyn_cast<ConstantInt>(CondV->getOperand(i)); - if (Cond == 0) break; - - Constant *V = Cond->isNullValue() ? V2 : V1; - Constant *Res = ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i)); - Result.push_back(Res); + Constant *V; + Constant *V1Element = ConstantExpr::getExtractElement(V1, + ConstantInt::get(Ty, i)); + Constant *V2Element = ConstantExpr::getExtractElement(V2, + ConstantInt::get(Ty, i)); + Constant *Cond = dyn_cast<Constant>(CondV->getOperand(i)); + if (V1Element == V2Element) { + V = V1Element; + } else if (isa<UndefValue>(Cond)) { + V = isa<UndefValue>(V1Element) ? V1Element : V2Element; + } else { + if (!isa<ConstantInt>(Cond)) break; + V = Cond->isNullValue() ? V2Element : V1Element; + } + Result.push_back(V); } // If we were able to build the vector, return it. @@ -737,7 +749,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2)); } - return 0; + return nullptr; } Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, @@ -757,14 +769,14 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, return UndefValue::get(Val->getType()->getVectorElementType()); return Val->getAggregateElement(Index); } - return 0; + return nullptr; } Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt, Constant *Idx) { ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); - if (!CIdx) return 0; + if (!CIdx) return nullptr; const APInt &IdxVal = CIdx->getValue(); SmallVector<Constant*, 16> Result; @@ -794,7 +806,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, return UndefValue::get(VectorType::get(EltTy, MaskNumElts)); // Don't break the bitcode reader hack. - if (isa<ConstantExpr>(Mask)) return 0; + if (isa<ConstantExpr>(Mask)) return nullptr; unsigned SrcNumElts = V1->getType()->getVectorNumElements(); @@ -833,7 +845,7 @@ Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg, if (Constant *C = Agg->getAggregateElement(Idxs[0])) return ConstantFoldExtractValueInstruction(C, Idxs.slice(1)); - return 0; + return nullptr; } Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, @@ -854,8 +866,8 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, SmallVector<Constant*, 32> Result; for (unsigned i = 0; i != NumElts; ++i) { Constant *C = Agg->getAggregateElement(i); - if (C == 0) return 0; - + if (!C) return nullptr; + if (Idxs[0] == i) C = ConstantFoldInsertValueInstruction(C, Val, Idxs.slice(1)); @@ -1200,7 +1212,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } // We don't know how to fold this. - return 0; + return nullptr; } /// isZeroSizedType - This type is zero sized if its an array or structure of @@ -1280,7 +1292,7 @@ static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) { if (!isa<ConstantExpr>(V1)) { if (!isa<ConstantExpr>(V2)) { // We distilled thisUse the standard constant folder for a few cases - ConstantInt *R = 0; + ConstantInt *R = nullptr; R = dyn_cast<ConstantInt>( ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, V1, V2)); if (R && !R->isZero()) @@ -1322,6 +1334,15 @@ static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) { return FCmpInst::BAD_FCMP_PREDICATE; } +static ICmpInst::Predicate areGlobalsPotentiallyEqual(const GlobalValue *GV1, + const GlobalValue *GV2) { + // Don't try to decide equality of aliases. + if (!isa<GlobalAlias>(GV1) && !isa<GlobalAlias>(GV2)) + if (!GV1->hasExternalWeakLinkage() || !GV2->hasExternalWeakLinkage()) + return ICmpInst::ICMP_NE; + return ICmpInst::BAD_ICMP_PREDICATE; +} + /// evaluateICmpRelation - This function determines if there is anything we can /// decide about the two constants provided. This doesn't need to handle simple /// things like integer comparisons, but should instead handle ConstantExprs @@ -1346,7 +1367,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, !isa<BlockAddress>(V2)) { // We distilled this down to a simple case, use the standard constant // folder. - ConstantInt *R = 0; + ConstantInt *R = nullptr; ICmpInst::Predicate pred = ICmpInst::ICMP_EQ; R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); if (R && !R->isZero()) @@ -1383,10 +1404,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, // constant (which, since the types must match, means that it's a // ConstantPointerNull). if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(V2)) { - // Don't try to decide equality of aliases. - if (!isa<GlobalAlias>(GV) && !isa<GlobalAlias>(GV2)) - if (!GV->hasExternalWeakLinkage() || !GV2->hasExternalWeakLinkage()) - return ICmpInst::ICMP_NE; + return areGlobalsPotentiallyEqual(GV, GV2); } else if (isa<BlockAddress>(V2)) { return ICmpInst::ICMP_NE; // Globals never equal labels. } else { @@ -1451,7 +1469,8 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, } break; - case Instruction::GetElementPtr: + case Instruction::GetElementPtr: { + GEPOperator *CE1GEP = cast<GEPOperator>(CE1); // Ok, since this is a getelementptr, we know that the constant has a // pointer type. Check the various cases. if (isa<ConstantPointerNull>(V2)) { @@ -1498,7 +1517,8 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, "Surprising getelementptr!"); return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; } else { - // If they are different globals, we don't know what the value is. + if (CE1GEP->hasAllZeroIndices()) + return areGlobalsPotentiallyEqual(GV, GV2); return ICmpInst::BAD_ICMP_PREDICATE; } } @@ -1514,8 +1534,14 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, // By far the most common case to handle is when the base pointers are // obviously to the same global. if (isa<GlobalValue>(CE1Op0) && isa<GlobalValue>(CE2Op0)) { - if (CE1Op0 != CE2Op0) // Don't know relative ordering. + // Don't know relative ordering, but check for inequality. + if (CE1Op0 != CE2Op0) { + GEPOperator *CE2GEP = cast<GEPOperator>(CE2); + if (CE1GEP->hasAllZeroIndices() && CE2GEP->hasAllZeroIndices()) + return areGlobalsPotentiallyEqual(cast<GlobalValue>(CE1Op0), + cast<GlobalValue>(CE2Op0)); return ICmpInst::BAD_ICMP_PREDICATE; + } // Ok, we know that both getelementptr instructions are based on the // same global. From this, we can precisely determine the relative // ordering of the resultant pointers. @@ -1561,6 +1587,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2, } } } + } default: break; } @@ -1876,7 +1903,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, return ConstantExpr::getICmp(pred, C2, C1); } } - return 0; + return nullptr; } /// isInBoundsIndices - Test whether the given sequence of *normalized* indices @@ -1942,7 +1969,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, if (isa<UndefValue>(C)) { PointerType *Ptr = cast<PointerType>(C->getType()); Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs); - assert(Ty != 0 && "Invalid indices for GEP!"); + assert(Ty && "Invalid indices for GEP!"); return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace())); } @@ -1956,7 +1983,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, if (isNull) { PointerType *Ptr = cast<PointerType>(C->getType()); Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs); - assert(Ty != 0 && "Invalid indices for GEP!"); + assert(Ty && "Invalid indices for GEP!"); return ConstantPointerNull::get(PointerType::get(Ty, Ptr->getAddressSpace())); } @@ -1968,7 +1995,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, // getelementptr instructions into a single instruction. // if (CE->getOpcode() == Instruction::GetElementPtr) { - Type *LastTy = 0; + Type *LastTy = nullptr; for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); I != E; ++I) LastTy = *I; @@ -2063,7 +2090,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, bool Unknown = false; SmallVector<Constant *, 8> NewIdxs; Type *Ty = C->getType(); - Type *Prev = 0; + Type *Prev = nullptr; 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])) { @@ -2121,7 +2148,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, isa<GlobalVariable>(C) && isInBoundsIndices(Idxs)) return ConstantExpr::getInBoundsGetElementPtr(C, Idxs); - return 0; + return nullptr; } Constant *llvm::ConstantFoldGetElementPtr(Constant *C, diff --git a/contrib/llvm/lib/IR/ConstantRange.cpp b/contrib/llvm/lib/IR/ConstantRange.cpp new file mode 100644 index 0000000..f8e9ba4 --- /dev/null +++ b/contrib/llvm/lib/IR/ConstantRange.cpp @@ -0,0 +1,734 @@ +//===-- ConstantRange.cpp - ConstantRange implementation ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Represent a range of possible values that may occur when the program is run +// for an integral value. This keeps track of a lower and upper bound for the +// constant, which MAY wrap around the end of the numeric range. To do this, it +// keeps track of a [lower, upper) bound, which specifies an interval just like +// STL iterators. When used with boolean values, the following are important +// ranges (other integral ranges use min/max values for special range values): +// +// [F, F) = {} = Empty set +// [T, F) = {T} +// [F, T) = {F} +// [T, T) = {F, T} = Full set +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/ConstantRange.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +/// Initialize a full (the default) or empty set for the specified type. +/// +ConstantRange::ConstantRange(uint32_t BitWidth, bool Full) { + if (Full) + Lower = Upper = APInt::getMaxValue(BitWidth); + else + Lower = Upper = APInt::getMinValue(BitWidth); +} + +/// Initialize a range to hold the single specified value. +/// +ConstantRange::ConstantRange(APIntMoveTy V) + : Lower(std::move(V)), Upper(Lower + 1) {} + +ConstantRange::ConstantRange(APIntMoveTy L, APIntMoveTy U) + : Lower(std::move(L)), Upper(std::move(U)) { + assert(Lower.getBitWidth() == Upper.getBitWidth() && + "ConstantRange with unequal bit widths"); + assert((Lower != Upper || (Lower.isMaxValue() || Lower.isMinValue())) && + "Lower == Upper, but they aren't min or max value!"); +} + +ConstantRange ConstantRange::makeICmpRegion(unsigned Pred, + const ConstantRange &CR) { + if (CR.isEmptySet()) + return CR; + + uint32_t W = CR.getBitWidth(); + switch (Pred) { + default: llvm_unreachable("Invalid ICmp predicate to makeICmpRegion()"); + case CmpInst::ICMP_EQ: + return CR; + case CmpInst::ICMP_NE: + if (CR.isSingleElement()) + return ConstantRange(CR.getUpper(), CR.getLower()); + return ConstantRange(W); + case CmpInst::ICMP_ULT: { + APInt UMax(CR.getUnsignedMax()); + if (UMax.isMinValue()) + return ConstantRange(W, /* empty */ false); + return ConstantRange(APInt::getMinValue(W), UMax); + } + case CmpInst::ICMP_SLT: { + APInt SMax(CR.getSignedMax()); + if (SMax.isMinSignedValue()) + return ConstantRange(W, /* empty */ false); + return ConstantRange(APInt::getSignedMinValue(W), SMax); + } + case CmpInst::ICMP_ULE: { + APInt UMax(CR.getUnsignedMax()); + if (UMax.isMaxValue()) + return ConstantRange(W); + return ConstantRange(APInt::getMinValue(W), UMax + 1); + } + case CmpInst::ICMP_SLE: { + APInt SMax(CR.getSignedMax()); + if (SMax.isMaxSignedValue()) + return ConstantRange(W); + return ConstantRange(APInt::getSignedMinValue(W), SMax + 1); + } + case CmpInst::ICMP_UGT: { + APInt UMin(CR.getUnsignedMin()); + if (UMin.isMaxValue()) + return ConstantRange(W, /* empty */ false); + return ConstantRange(UMin + 1, APInt::getNullValue(W)); + } + case CmpInst::ICMP_SGT: { + APInt SMin(CR.getSignedMin()); + if (SMin.isMaxSignedValue()) + return ConstantRange(W, /* empty */ false); + return ConstantRange(SMin + 1, APInt::getSignedMinValue(W)); + } + case CmpInst::ICMP_UGE: { + APInt UMin(CR.getUnsignedMin()); + if (UMin.isMinValue()) + return ConstantRange(W); + return ConstantRange(UMin, APInt::getNullValue(W)); + } + case CmpInst::ICMP_SGE: { + APInt SMin(CR.getSignedMin()); + if (SMin.isMinSignedValue()) + return ConstantRange(W); + return ConstantRange(SMin, APInt::getSignedMinValue(W)); + } + } +} + +/// isFullSet - Return true if this set contains all of the elements possible +/// for this data-type +bool ConstantRange::isFullSet() const { + return Lower == Upper && Lower.isMaxValue(); +} + +/// isEmptySet - Return true if this set contains no members. +/// +bool ConstantRange::isEmptySet() const { + return Lower == Upper && Lower.isMinValue(); +} + +/// isWrappedSet - Return true if this set wraps around the top of the range, +/// for example: [100, 8) +/// +bool ConstantRange::isWrappedSet() const { + return Lower.ugt(Upper); +} + +/// isSignWrappedSet - Return true if this set wraps around the INT_MIN of +/// its bitwidth, for example: i8 [120, 140). +/// +bool ConstantRange::isSignWrappedSet() const { + return contains(APInt::getSignedMaxValue(getBitWidth())) && + contains(APInt::getSignedMinValue(getBitWidth())); +} + +/// getSetSize - Return the number of elements in this set. +/// +APInt ConstantRange::getSetSize() const { + if (isFullSet()) { + APInt Size(getBitWidth()+1, 0); + Size.setBit(getBitWidth()); + return Size; + } + + // This is also correct for wrapped sets. + return (Upper - Lower).zext(getBitWidth()+1); +} + +/// getUnsignedMax - Return the largest unsigned value contained in the +/// ConstantRange. +/// +APInt ConstantRange::getUnsignedMax() const { + if (isFullSet() || isWrappedSet()) + return APInt::getMaxValue(getBitWidth()); + return getUpper() - 1; +} + +/// getUnsignedMin - Return the smallest unsigned value contained in the +/// ConstantRange. +/// +APInt ConstantRange::getUnsignedMin() const { + if (isFullSet() || (isWrappedSet() && getUpper() != 0)) + return APInt::getMinValue(getBitWidth()); + return getLower(); +} + +/// getSignedMax - Return the largest signed value contained in the +/// ConstantRange. +/// +APInt ConstantRange::getSignedMax() const { + APInt SignedMax(APInt::getSignedMaxValue(getBitWidth())); + if (!isWrappedSet()) { + if (getLower().sle(getUpper() - 1)) + return getUpper() - 1; + return SignedMax; + } + if (getLower().isNegative() == getUpper().isNegative()) + return SignedMax; + return getUpper() - 1; +} + +/// getSignedMin - Return the smallest signed value contained in the +/// ConstantRange. +/// +APInt ConstantRange::getSignedMin() const { + APInt SignedMin(APInt::getSignedMinValue(getBitWidth())); + if (!isWrappedSet()) { + if (getLower().sle(getUpper() - 1)) + return getLower(); + return SignedMin; + } + if ((getUpper() - 1).slt(getLower())) { + if (getUpper() != SignedMin) + return SignedMin; + } + return getLower(); +} + +/// contains - Return true if the specified value is in the set. +/// +bool ConstantRange::contains(const APInt &V) const { + if (Lower == Upper) + return isFullSet(); + + if (!isWrappedSet()) + return Lower.ule(V) && V.ult(Upper); + return Lower.ule(V) || V.ult(Upper); +} + +/// contains - Return true if the argument is a subset of this range. +/// Two equal sets contain each other. The empty set contained by all other +/// sets. +/// +bool ConstantRange::contains(const ConstantRange &Other) const { + if (isFullSet() || Other.isEmptySet()) return true; + if (isEmptySet() || Other.isFullSet()) return false; + + if (!isWrappedSet()) { + if (Other.isWrappedSet()) + return false; + + return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper); + } + + if (!Other.isWrappedSet()) + return Other.getUpper().ule(Upper) || + Lower.ule(Other.getLower()); + + return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower()); +} + +/// subtract - Subtract the specified constant from the endpoints of this +/// constant range. +ConstantRange ConstantRange::subtract(const APInt &Val) const { + assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width"); + // If the set is empty or full, don't modify the endpoints. + if (Lower == Upper) + return *this; + return ConstantRange(Lower - Val, Upper - Val); +} + +/// \brief Subtract the specified range from this range (aka relative complement +/// of the sets). +ConstantRange ConstantRange::difference(const ConstantRange &CR) const { + return intersectWith(CR.inverse()); +} + +/// intersectWith - Return the range that results from the intersection of this +/// range with another range. The resultant range is guaranteed to include all +/// elements contained in both input ranges, and to have the smallest possible +/// set size that does so. Because there may be two intersections with the +/// same set size, A.intersectWith(B) might not be equal to B.intersectWith(A). +ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { + assert(getBitWidth() == CR.getBitWidth() && + "ConstantRange types don't agree!"); + + // Handle common cases. + if ( isEmptySet() || CR.isFullSet()) return *this; + if (CR.isEmptySet() || isFullSet()) return CR; + + if (!isWrappedSet() && CR.isWrappedSet()) + return CR.intersectWith(*this); + + if (!isWrappedSet() && !CR.isWrappedSet()) { + if (Lower.ult(CR.Lower)) { + if (Upper.ule(CR.Lower)) + return ConstantRange(getBitWidth(), false); + + if (Upper.ult(CR.Upper)) + return ConstantRange(CR.Lower, Upper); + + return CR; + } + if (Upper.ult(CR.Upper)) + return *this; + + if (Lower.ult(CR.Upper)) + return ConstantRange(Lower, CR.Upper); + + return ConstantRange(getBitWidth(), false); + } + + if (isWrappedSet() && !CR.isWrappedSet()) { + if (CR.Lower.ult(Upper)) { + if (CR.Upper.ult(Upper)) + return CR; + + if (CR.Upper.ule(Lower)) + return ConstantRange(CR.Lower, Upper); + + if (getSetSize().ult(CR.getSetSize())) + return *this; + return CR; + } + if (CR.Lower.ult(Lower)) { + if (CR.Upper.ule(Lower)) + return ConstantRange(getBitWidth(), false); + + return ConstantRange(Lower, CR.Upper); + } + return CR; + } + + if (CR.Upper.ult(Upper)) { + if (CR.Lower.ult(Upper)) { + if (getSetSize().ult(CR.getSetSize())) + return *this; + return CR; + } + + if (CR.Lower.ult(Lower)) + return ConstantRange(Lower, CR.Upper); + + return CR; + } + if (CR.Upper.ule(Lower)) { + if (CR.Lower.ult(Lower)) + return *this; + + return ConstantRange(CR.Lower, Upper); + } + if (getSetSize().ult(CR.getSetSize())) + return *this; + return CR; +} + + +/// unionWith - Return the range that results from the union of this range with +/// another range. The resultant range is guaranteed to include the elements of +/// both sets, but may contain more. For example, [3, 9) union [12,15) is +/// [3, 15), which includes 9, 10, and 11, which were not included in either +/// set before. +/// +ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { + assert(getBitWidth() == CR.getBitWidth() && + "ConstantRange types don't agree!"); + + if ( isFullSet() || CR.isEmptySet()) return *this; + if (CR.isFullSet() || isEmptySet()) return CR; + + if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this); + + if (!isWrappedSet() && !CR.isWrappedSet()) { + if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) { + // If the two ranges are disjoint, find the smaller gap and bridge it. + APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; + if (d1.ult(d2)) + return ConstantRange(Lower, CR.Upper); + return ConstantRange(CR.Lower, Upper); + } + + APInt L = Lower, U = Upper; + if (CR.Lower.ult(L)) + L = CR.Lower; + if ((CR.Upper - 1).ugt(U - 1)) + U = CR.Upper; + + if (L == 0 && U == 0) + return ConstantRange(getBitWidth()); + + return ConstantRange(L, U); + } + + if (!CR.isWrappedSet()) { + // ------U L----- and ------U L----- : this + // L--U L--U : CR + if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower)) + return *this; + + // ------U L----- : this + // L---------U : CR + if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) + return ConstantRange(getBitWidth()); + + // ----U L---- : this + // L---U : CR + // <d1> <d2> + if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) { + APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; + if (d1.ult(d2)) + return ConstantRange(Lower, CR.Upper); + return ConstantRange(CR.Lower, Upper); + } + + // ----U L----- : this + // L----U : CR + if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) + return ConstantRange(CR.Lower, Upper); + + // ------U L---- : this + // L-----U : CR + assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) && + "ConstantRange::unionWith missed a case with one range wrapped"); + return ConstantRange(Lower, CR.Upper); + } + + // ------U L---- and ------U L---- : this + // -U L----------- and ------------U L : CR + if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper)) + return ConstantRange(getBitWidth()); + + APInt L = Lower, U = Upper; + if (CR.Upper.ugt(U)) + U = CR.Upper; + if (CR.Lower.ult(L)) + L = CR.Lower; + + return ConstantRange(L, U); +} + +/// zeroExtend - Return a new range in the specified integer type, which must +/// be strictly larger than the current type. The returned range will +/// correspond to the possible range of values as if the source range had been +/// zero extended. +ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const { + if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false); + + unsigned SrcTySize = getBitWidth(); + assert(SrcTySize < DstTySize && "Not a value extension"); + if (isFullSet() || isWrappedSet()) { + // Change into [0, 1 << src bit width) + APInt LowerExt(DstTySize, 0); + if (!Upper) // special case: [X, 0) -- not really wrapping around + LowerExt = Lower.zext(DstTySize); + return ConstantRange(LowerExt, APInt::getOneBitSet(DstTySize, SrcTySize)); + } + + return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize)); +} + +/// signExtend - Return a new range in the specified integer type, which must +/// be strictly larger than the current type. The returned range will +/// correspond to the possible range of values as if the source range had been +/// sign extended. +ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const { + if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false); + + unsigned SrcTySize = getBitWidth(); + assert(SrcTySize < DstTySize && "Not a value extension"); + + // special case: [X, INT_MIN) -- not really wrapping around + if (Upper.isMinSignedValue()) + return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize)); + + if (isFullSet() || isSignWrappedSet()) { + return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1), + APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1); + } + + return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize)); +} + +/// truncate - Return a new range in the specified integer type, which must be +/// strictly smaller than the current type. The returned range will +/// correspond to the possible range of values as if the source range had been +/// truncated to the specified type. +ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { + assert(getBitWidth() > DstTySize && "Not a value truncation"); + if (isEmptySet()) + return ConstantRange(DstTySize, /*isFullSet=*/false); + if (isFullSet()) + return ConstantRange(DstTySize, /*isFullSet=*/true); + + APInt MaxValue = APInt::getMaxValue(DstTySize).zext(getBitWidth()); + APInt MaxBitValue(getBitWidth(), 0); + MaxBitValue.setBit(DstTySize); + + APInt LowerDiv(Lower), UpperDiv(Upper); + ConstantRange Union(DstTySize, /*isFullSet=*/false); + + // Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue] + // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and + // then we do the union with [MaxValue, Upper) + if (isWrappedSet()) { + // if Upper is greater than Max Value, it covers the whole truncated range. + if (Upper.uge(MaxValue)) + return ConstantRange(DstTySize, /*isFullSet=*/true); + + Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize)); + UpperDiv = APInt::getMaxValue(getBitWidth()); + + // Union covers the MaxValue case, so return if the remaining range is just + // MaxValue. + if (LowerDiv == UpperDiv) + return Union; + } + + // Chop off the most significant bits that are past the destination bitwidth. + if (LowerDiv.uge(MaxValue)) { + APInt Div(getBitWidth(), 0); + APInt::udivrem(LowerDiv, MaxBitValue, Div, LowerDiv); + UpperDiv = UpperDiv - MaxBitValue * Div; + } + + if (UpperDiv.ule(MaxValue)) + return ConstantRange(LowerDiv.trunc(DstTySize), + UpperDiv.trunc(DstTySize)).unionWith(Union); + + // The truncated value wrapps around. Check if we can do better than fullset. + APInt UpperModulo = UpperDiv - MaxBitValue; + if (UpperModulo.ult(LowerDiv)) + return ConstantRange(LowerDiv.trunc(DstTySize), + UpperModulo.trunc(DstTySize)).unionWith(Union); + + return ConstantRange(DstTySize, /*isFullSet=*/true); +} + +/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The +/// value is zero extended, truncated, or left alone to make it that width. +ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const { + unsigned SrcTySize = getBitWidth(); + if (SrcTySize > DstTySize) + return truncate(DstTySize); + if (SrcTySize < DstTySize) + return zeroExtend(DstTySize); + return *this; +} + +/// sextOrTrunc - make this range have the bit width given by \p DstTySize. The +/// value is sign extended, truncated, or left alone to make it that width. +ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const { + unsigned SrcTySize = getBitWidth(); + if (SrcTySize > DstTySize) + return truncate(DstTySize); + if (SrcTySize < DstTySize) + return signExtend(DstTySize); + return *this; +} + +ConstantRange +ConstantRange::add(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + if (isFullSet() || Other.isFullSet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); + APInt NewLower = getLower() + Other.getLower(); + APInt NewUpper = getUpper() + Other.getUpper() - 1; + if (NewLower == NewUpper) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + ConstantRange X = ConstantRange(NewLower, NewUpper); + if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) + // We've wrapped, therefore, full set. + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + return X; +} + +ConstantRange +ConstantRange::sub(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + if (isFullSet() || Other.isFullSet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); + APInt NewLower = getLower() - Other.getUpper() + 1; + APInt NewUpper = getUpper() - Other.getLower(); + if (NewLower == NewUpper) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + ConstantRange X = ConstantRange(NewLower, NewUpper); + if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) + // We've wrapped, therefore, full set. + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + return X; +} + +ConstantRange +ConstantRange::multiply(const ConstantRange &Other) const { + // TODO: If either operand is a single element and the multiply is known to + // be non-wrapping, round the result min and max value to the appropriate + // multiple of that element. If wrapping is possible, at least adjust the + // range according to the greatest power-of-two factor of the single element. + + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + APInt this_min = getUnsignedMin().zext(getBitWidth() * 2); + APInt this_max = getUnsignedMax().zext(getBitWidth() * 2); + APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2); + APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2); + + ConstantRange Result_zext = ConstantRange(this_min * Other_min, + this_max * Other_max + 1); + return Result_zext.truncate(getBitWidth()); +} + +ConstantRange +ConstantRange::smax(const ConstantRange &Other) const { + // X smax Y is: range(smax(X_smin, Y_smin), + // smax(X_smax, Y_smax)) + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin()); + APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1; + if (NewU == NewL) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(NewL, NewU); +} + +ConstantRange +ConstantRange::umax(const ConstantRange &Other) const { + // X umax Y is: range(umax(X_umin, Y_umin), + // umax(X_umax, Y_umax)) + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); + APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1; + if (NewU == NewL) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(NewL, NewU); +} + +ConstantRange +ConstantRange::udiv(const ConstantRange &RHS) const { + if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + if (RHS.isFullSet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax()); + + APInt RHS_umin = RHS.getUnsignedMin(); + if (RHS_umin == 0) { + // We want the lowest value in RHS excluding zero. Usually that would be 1 + // except for a range in the form of [X, 1) in which case it would be X. + if (RHS.getUpper() == 1) + RHS_umin = RHS.getLower(); + else + RHS_umin = APInt(getBitWidth(), 1); + } + + APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1; + + // If the LHS is Full and the RHS is a wrapped interval containing 1 then + // this could occur. + if (Lower == Upper) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + return ConstantRange(Lower, Upper); +} + +ConstantRange +ConstantRange::binaryAnd(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + // TODO: replace this with something less conservative + + APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax()); + if (umin.isAllOnesValue()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1); +} + +ConstantRange +ConstantRange::binaryOr(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + // TODO: replace this with something less conservative + + APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); + if (umax.isMinValue()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(umax, APInt::getNullValue(getBitWidth())); +} + +ConstantRange +ConstantRange::shl(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + APInt min = getUnsignedMin().shl(Other.getUnsignedMin()); + APInt max = getUnsignedMax().shl(Other.getUnsignedMax()); + + // there's no overflow! + APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros()); + if (Zeros.ugt(Other.getUnsignedMax())) + return ConstantRange(min, max + 1); + + // FIXME: implement the other tricky cases + return ConstantRange(getBitWidth(), /*isFullSet=*/true); +} + +ConstantRange +ConstantRange::lshr(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + APInt max = getUnsignedMax().lshr(Other.getUnsignedMin()); + APInt min = getUnsignedMin().lshr(Other.getUnsignedMax()); + if (min == max + 1) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + + return ConstantRange(min, max + 1); +} + +ConstantRange ConstantRange::inverse() const { + if (isFullSet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + if (isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(Upper, Lower); +} + +/// print - Print out the bounds to a stream... +/// +void ConstantRange::print(raw_ostream &OS) const { + if (isFullSet()) + OS << "full-set"; + else if (isEmptySet()) + OS << "empty-set"; + else + OS << "[" << Lower << "," << Upper << ")"; +} + +/// dump - Allow printing from a debugger easily... +/// +void ConstantRange::dump() const { + print(dbgs()); +} diff --git a/contrib/llvm/lib/IR/Constants.cpp b/contrib/llvm/lib/IR/Constants.cpp index 690ac59..b815936a 100644 --- a/contrib/llvm/lib/IR/Constants.cpp +++ b/contrib/llvm/lib/IR/Constants.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" @@ -28,7 +29,6 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -107,6 +107,28 @@ bool Constant::isAllOnesValue() const { return false; } +bool Constant::isMinSignedValue() const { + // Check for INT_MIN integers + if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) + return CI->isMinValue(/*isSigned=*/true); + + // Check for FP which are bitcasted from INT_MIN integers + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) + return CFP->getValueAPF().bitcastToAPInt().isMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isMinSignedValue(); + + return false; +} + // Constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { @@ -182,13 +204,13 @@ Constant *Constant::getAllOnesValue(Type *Ty) { /// 'this' is a constant expr. Constant *Constant::getAggregateElement(unsigned Elt) const { if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(this)) - return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : 0; + return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : nullptr; if (const ConstantArray *CA = dyn_cast<ConstantArray>(this)) - return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : 0; + return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : nullptr; if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) - return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : 0; + return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr; if (const ConstantAggregateZero *CAZ =dyn_cast<ConstantAggregateZero>(this)) return CAZ->getElementValue(Elt); @@ -197,15 +219,16 @@ Constant *Constant::getAggregateElement(unsigned Elt) const { return UV->getElementValue(Elt); if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this)) - return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0; - return 0; + return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) + : nullptr; + return nullptr; } Constant *Constant::getAggregateElement(Constant *Elt) const { assert(isa<IntegerType>(Elt->getType()) && "Index must be an integer"); if (ConstantInt *CI = dyn_cast<ConstantInt>(Elt)) return getAggregateElement(CI->getZExtValue()); - return 0; + return nullptr; } @@ -218,7 +241,7 @@ void Constant::destroyConstantImpl() { // Constants) that they are, in fact, invalid now and should be deleted. // while (!use_empty()) { - Value *V = use_back(); + Value *V = user_back(); #ifndef NDEBUG // Only in -g mode... if (!isa<Constant>(V)) { dbgs() << "While deleting: " << *this @@ -230,7 +253,7 @@ void Constant::destroyConstantImpl() { cast<Constant>(V)->destroyConstant(); // The constant should remove itself from our use list... - assert((use_empty() || use_back() != V) && "Constant not removed!"); + assert((use_empty() || user_back() != V) && "Constant not removed!"); } // Value has no outstanding references it is safe to delete it now... @@ -277,39 +300,52 @@ bool Constant::canTrap() const { return canTrapImpl(this, NonTrappingOps); } -/// isThreadDependent - Return true if the value can vary between threads. -bool Constant::isThreadDependent() const { - SmallPtrSet<const Constant*, 64> Visited; - SmallVector<const Constant*, 64> WorkList; - WorkList.push_back(this); - Visited.insert(this); +/// Check if C contains a GlobalValue for which Predicate is true. +static bool +ConstHasGlobalValuePredicate(const Constant *C, + bool (*Predicate)(const GlobalValue *)) { + SmallPtrSet<const Constant *, 8> Visited; + SmallVector<const Constant *, 8> WorkList; + WorkList.push_back(C); + Visited.insert(C); while (!WorkList.empty()) { - const Constant *C = WorkList.pop_back_val(); - - if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { - if (GV->isThreadLocal()) + const Constant *WorkItem = WorkList.pop_back_val(); + if (const auto *GV = dyn_cast<GlobalValue>(WorkItem)) + if (Predicate(GV)) return true; - } - - for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) { - const Constant *D = dyn_cast<Constant>(C->getOperand(I)); - if (!D) + for (const Value *Op : WorkItem->operands()) { + const Constant *ConstOp = dyn_cast<Constant>(Op); + if (!ConstOp) continue; - if (Visited.insert(D)) - WorkList.push_back(D); + if (Visited.insert(ConstOp)) + WorkList.push_back(ConstOp); } } - return false; } -/// isConstantUsed - Return true if the constant has users other than constant -/// exprs and other dangling things. +/// Return true if the value can vary between threads. +bool Constant::isThreadDependent() const { + auto DLLImportPredicate = [](const GlobalValue *GV) { + return GV->isThreadLocal(); + }; + return ConstHasGlobalValuePredicate(this, DLLImportPredicate); +} + +bool Constant::isDLLImportDependent() const { + auto DLLImportPredicate = [](const GlobalValue *GV) { + return GV->hasDLLImportStorageClass(); + }; + return ConstHasGlobalValuePredicate(this, DLLImportPredicate); +} + +/// Return true if the constant has users other than constant exprs and other +/// dangling things. bool Constant::isConstantUsed() const { - for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { - const Constant *UC = dyn_cast<Constant>(*UI); - if (UC == 0 || isa<GlobalValue>(UC)) + for (const User *U : users()) { + const Constant *UC = dyn_cast<Constant>(U); + if (!UC || isa<GlobalValue>(UC)) return true; if (UC->isConstantUsed()) @@ -377,7 +413,7 @@ static bool removeDeadUsersOfConstant(const Constant *C) { if (isa<GlobalValue>(C)) return false; // Cannot remove this while (!C->use_empty()) { - const Constant *User = dyn_cast<Constant>(C->use_back()); + const Constant *User = dyn_cast<Constant>(C->user_back()); if (!User) return false; // Non-constant usage; if (!removeDeadUsersOfConstant(User)) return false; // Constant wasn't dead @@ -393,11 +429,11 @@ static bool removeDeadUsersOfConstant(const Constant *C) { /// that want to check to see if a global is unused, but don't want to deal /// with potentially dead constants hanging off of the globals. void Constant::removeDeadConstantUsers() const { - Value::const_use_iterator I = use_begin(), E = use_end(); - Value::const_use_iterator LastNonDeadUser = E; + Value::const_user_iterator I = user_begin(), E = user_end(); + Value::const_user_iterator LastNonDeadUser = E; while (I != E) { const Constant *User = dyn_cast<Constant>(*I); - if (User == 0) { + if (!User) { LastNonDeadUser = I; ++I; continue; @@ -413,7 +449,7 @@ void Constant::removeDeadConstantUsers() const { // If the constant was dead, then the iterator is invalidated. if (LastNonDeadUser == E) { - I = use_begin(); + I = user_begin(); if (I == E) break; } else { I = LastNonDeadUser; @@ -431,7 +467,7 @@ void Constant::removeDeadConstantUsers() const { void ConstantInt::anchor() { } ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V) - : Constant(Ty, ConstantIntVal, 0, 0), Val(V) { + : Constant(Ty, ConstantIntVal, nullptr, 0), Val(V) { assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } @@ -584,23 +620,21 @@ Constant *ConstantFP::get(Type *Ty, StringRef Str) { return C; } +Constant *ConstantFP::getNegativeZero(Type *Ty) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType()); + APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true); + Constant *C = get(Ty->getContext(), NegZero); -ConstantFP *ConstantFP::getNegativeZero(Type *Ty) { - LLVMContext &Context = Ty->getContext(); - APFloat apf = cast<ConstantFP>(Constant::getNullValue(Ty))->getValueAPF(); - apf.changeSign(); - return get(Context, apf); + if (VectorType *VTy = dyn_cast<VectorType>(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + + return C; } Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { - Type *ScalarTy = Ty->getScalarType(); - if (ScalarTy->isFloatingPointTy()) { - Constant *C = getNegativeZero(ScalarTy); - if (VectorType *VTy = dyn_cast<VectorType>(Ty)) - return ConstantVector::getSplat(VTy->getNumElements(), C); - return C; - } + if (Ty->isFPOrFPVectorTy()) + return getNegativeZero(Ty); return Constant::getNullValue(Ty); } @@ -635,14 +669,18 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { return Slot; } -ConstantFP *ConstantFP::getInfinity(Type *Ty, bool Negative) { - const fltSemantics &Semantics = *TypeToFloatSemantics(Ty); - return ConstantFP::get(Ty->getContext(), - APFloat::getInf(Semantics, Negative)); +Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType()); + Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative)); + + if (VectorType *VTy = dyn_cast<VectorType>(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + + return C; } ConstantFP::ConstantFP(Type *Ty, const APFloat& V) - : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { + : Constant(Ty, ConstantFPVal, nullptr, 0), Val(V) { assert(&V.getSemantics() == TypeToFloatSemantics(Ty) && "FP type Mismatch"); } @@ -1045,7 +1083,7 @@ bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const { if (getOpcode() != Instruction::GetElementPtr) return false; gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this); - User::const_op_iterator OI = llvm::next(this->op_begin()); + User::const_op_iterator OI = std::next(this->op_begin()); // Skip the first index, as it has no static limit. ++GEPI; @@ -1233,7 +1271,7 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { "Cannot create an aggregate zero of non-aggregate type!"); ConstantAggregateZero *&Entry = Ty->getContext().pImpl->CAZConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new ConstantAggregateZero(Ty); return Entry; @@ -1281,7 +1319,7 @@ Constant *Constant::getSplatValue() const { return CV->getSplatValue(); if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) return CV->getSplatValue(); - return 0; + return nullptr; } /// getSplatValue - If this is a splat constant, where all of the @@ -1292,7 +1330,7 @@ Constant *ConstantVector::getSplatValue() const { // Then make sure all remaining elements point to the same value. for (unsigned I = 1, E = getNumOperands(); I < E; ++I) if (getOperand(I) != Elt) - return 0; + return nullptr; return Elt; } @@ -1313,7 +1351,7 @@ const APInt &Constant::getUniqueInteger() const { ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { ConstantPointerNull *&Entry = Ty->getContext().pImpl->CPNConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new ConstantPointerNull(Ty); return Entry; @@ -1333,7 +1371,7 @@ void ConstantPointerNull::destroyConstant() { UndefValue *UndefValue::get(Type *Ty) { UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new UndefValue(Ty); return Entry; @@ -1351,14 +1389,14 @@ void UndefValue::destroyConstant() { // BlockAddress *BlockAddress::get(BasicBlock *BB) { - assert(BB->getParent() != 0 && "Block must have a parent"); + assert(BB->getParent() && "Block must have a parent"); return get(BB->getParent(), BB); } BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { BlockAddress *&BA = F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)]; - if (BA == 0) + if (!BA) BA = new BlockAddress(F, BB); assert(BA->getFunction() == F && "Basic block moved between functions"); @@ -1373,6 +1411,17 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) BB->AdjustBlockAddressRefCount(1); } +BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { + if (!BB->hasAddressTaken()) + return nullptr; + + const Function *F = BB->getParent(); + assert(F && "Block must have a parent"); + BlockAddress *BA = + F->getContext().pImpl->BlockAddresses.lookup(std::make_pair(F, BB)); + assert(BA && "Refcount and block address map disagree!"); + return BA; +} // destroyConstant - Remove the constant from the constant table. // @@ -1398,7 +1447,7 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { // and return early. BlockAddress *&NewBA = getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)]; - if (NewBA == 0) { + if (!NewBA) { getBasicBlock()->AdjustBlockAddressRefCount(-1); // Remove the old entry, this can't cause the map to rehash (just a @@ -1684,6 +1733,19 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) { assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) && "Invalid constantexpr addrspacecast!"); + // Canonicalize addrspacecasts between different pointer types by first + // bitcasting the pointer type and then converting the address space. + PointerType *SrcScalarTy = cast<PointerType>(C->getType()->getScalarType()); + PointerType *DstScalarTy = cast<PointerType>(DstTy->getScalarType()); + Type *DstElemTy = DstScalarTy->getElementType(); + if (SrcScalarTy->getElementType() != DstElemTy) { + Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace()); + if (VectorType *VT = dyn_cast<VectorType>(DstTy)) { + // Handle vectors of pointers. + MidTy = VectorType::get(MidTy, VT->getNumElements()); + } + C = getBitCast(C, MidTy); + } return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy); } @@ -1779,7 +1841,7 @@ Constant *ConstantExpr::getAlignOf(Type* Ty) { // Note that a non-inbounds gep is used, as null isn't within any object. Type *AligningTy = StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); - Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); + Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo(0)); Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0); Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *Indices[2] = { Zero, One }; @@ -1923,8 +1985,8 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { assert(Val->getType()->isVectorTy() && "Tried to create extractelement operation on non-vector type!"); - assert(Idx->getType()->isIntegerTy(32) && - "Extractelement index must be i32 type!"); + assert(Idx->getType()->isIntegerTy() && + "Extractelement index must be an integer type!"); if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) return FC; // Fold a few common cases. @@ -1944,7 +2006,7 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, "Tried to create insertelement operation on non-vector type!"); assert(Elt->getType() == Val->getType()->getVectorElementType() && "Insertelement types must match!"); - assert(Idx->getType()->isIntegerTy(32) && + assert(Idx->getType()->isIntegerTy() && "Insertelement index must be i32 type!"); if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) @@ -2132,7 +2194,7 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) { switch (Opcode) { default: // Doesn't have an identity. - return 0; + return nullptr; case Instruction::Add: case Instruction::Or: @@ -2155,7 +2217,7 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { switch (Opcode) { default: // Doesn't have an absorber. - return 0; + return nullptr; case Instruction::Or: return Constant::getAllOnesValue(Ty); @@ -2272,7 +2334,7 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { // of i8, or a 1-element array of i32. They'll both end up in the same /// StringMap bucket, linked up by their Next pointers. Walk the list. ConstantDataSequential **Entry = &Slot.getValue(); - for (ConstantDataSequential *Node = *Entry; Node != 0; + for (ConstantDataSequential *Node = *Entry; Node; Entry = &Node->Next, Node = *Entry) if (Node->getType() == Ty) return Node; @@ -2299,7 +2361,7 @@ void ConstantDataSequential::destroyConstant() { ConstantDataSequential **Entry = &Slot->getValue(); // Remove the entry from the hash table. - if ((*Entry)->Next == 0) { + if (!(*Entry)->Next) { // If there is only one value in the bucket (common case) it must be this // entry, and removing the entry should remove the bucket completely. assert((*Entry) == this && "Hash mismatch in ConstantDataSequential"); @@ -2320,7 +2382,7 @@ void ConstantDataSequential::destroyConstant() { // If we were part of a list, make sure that we don't delete the list that is // still owned by the uniquing map. - Next = 0; + Next = nullptr; // Finally, actually delete it. destroyConstantImpl(); @@ -2548,7 +2610,7 @@ Constant *ConstantDataVector::getSplatValue() const { unsigned EltSize = getElementByteSize(); for (unsigned i = 1, e = getNumElements(); i != e; ++i) if (memcmp(Base, Base+i*EltSize, EltSize)) - return 0; + return nullptr; // If they're all the same, return the 0th one as a representative. return getElementAsConstant(0); @@ -2596,7 +2658,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, AllSame &= Val == ToC; } - Constant *Replacement = 0; + Constant *Replacement = nullptr; if (AllSame && ToC->isNullValue()) { Replacement = ConstantAggregateZero::get(getType()); } else if (AllSame && isa<UndefValue>(ToC)) { @@ -2682,7 +2744,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, LLVMContextImpl *pImpl = getContext().pImpl; - Constant *Replacement = 0; + Constant *Replacement = nullptr; if (isAllZeros) { Replacement = ConstantAggregateZero::get(getType()); } else if (isAllUndef) { @@ -2781,6 +2843,7 @@ Instruction *ConstantExpr::getAsInstruction() { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: + case Instruction::AddrSpaceCast: return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0], getType()); case Instruction::Select: diff --git a/contrib/llvm/lib/IR/ConstantsContext.h b/contrib/llvm/lib/IR/ConstantsContext.h index 32bed95..f06509f 100644 --- a/contrib/llvm/lib/IR/ConstantsContext.h +++ b/contrib/llvm/lib/IR/ConstantsContext.h @@ -24,6 +24,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include <map> +#include <tuple> + +#define DEBUG_TYPE "ir" namespace llvm { template<class ValType> @@ -32,7 +35,7 @@ struct ConstantTraits; /// UnaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement unary constant exprs. class UnaryConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand @@ -49,7 +52,7 @@ public: /// BinaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement binary constant exprs. class BinaryConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly two operands @@ -70,7 +73,7 @@ public: /// SelectConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement select constant exprs. class SelectConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands @@ -91,7 +94,7 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// extractelement constant exprs. class ExtractElementConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly two operands @@ -112,7 +115,7 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// insertelement constant exprs. class InsertElementConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands @@ -134,7 +137,7 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// shufflevector constant exprs. class ShuffleVectorConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands @@ -159,7 +162,7 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// extractvalue constant exprs. class ExtractValueConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand @@ -185,7 +188,7 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// insertvalue constant exprs. class InsertValueConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand @@ -212,7 +215,7 @@ public: /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. class GetElementPtrConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList, Type *DestTy); public: @@ -233,7 +236,7 @@ public: // behind the scenes to implement ICmp and FCmp constant expressions. This is // needed in order to store the predicate value for these instructions. class CompareConstantExpr : public ConstantExpr { - virtual void anchor(); + void anchor() override; void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly two operands @@ -334,14 +337,10 @@ struct ExprMapKeyType { this->indices == that.indices; } bool operator<(const ExprMapKeyType & that) const { - if (this->opcode != that.opcode) return this->opcode < that.opcode; - if (this->operands != that.operands) return this->operands < that.operands; - if (this->subclassdata != that.subclassdata) - return this->subclassdata < that.subclassdata; - if (this->subclassoptionaldata != that.subclassoptionaldata) - return this->subclassoptionaldata < that.subclassoptionaldata; - if (this->indices != that.indices) return this->indices < that.indices; - return false; + return std::tie(opcode, operands, subclassdata, subclassoptionaldata, + indices) < + std::tie(that.opcode, that.operands, that.subclassdata, + that.subclassoptionaldata, that.indices); } bool operator!=(const ExprMapKeyType& that) const { @@ -369,17 +368,10 @@ struct InlineAsmKeyType { this->asm_dialect == that.asm_dialect; } bool operator<(const InlineAsmKeyType& that) const { - if (this->asm_string != that.asm_string) - return this->asm_string < that.asm_string; - if (this->constraints != that.constraints) - return this->constraints < that.constraints; - if (this->has_side_effects != that.has_side_effects) - return this->has_side_effects < that.has_side_effects; - if (this->is_align_stack != that.is_align_stack) - return this->is_align_stack < that.is_align_stack; - if (this->asm_dialect != that.asm_dialect) - return this->asm_dialect < that.asm_dialect; - return false; + return std::tie(asm_string, constraints, has_side_effects, is_align_stack, + asm_dialect) < + std::tie(that.asm_string, that.constraints, that.has_side_effects, + that.is_align_stack, that.asm_dialect); } bool operator!=(const InlineAsmKeyType& that) const { @@ -595,7 +587,7 @@ public: /// necessary. ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { MapKey Lookup(Ty, V); - ConstantClass* Result = 0; + ConstantClass* Result = nullptr; typename MapTy::iterator I = Map.find(Lookup); // Is it in the map? @@ -731,7 +723,7 @@ public: /// necessary. ConstantClass *getOrCreate(TypeClass *Ty, Operands V) { LookupKey Lookup(Ty, V); - ConstantClass* Result = 0; + ConstantClass* Result = nullptr; typename MapTy::iterator I = Map.find_as(Lookup); // Is it in the map? diff --git a/contrib/llvm/lib/IR/Core.cpp b/contrib/llvm/lib/IR/Core.cpp index c70f459..87099a6 100644 --- a/contrib/llvm/lib/IR/Core.cpp +++ b/contrib/llvm/lib/IR/Core.cpp @@ -15,37 +15,41 @@ #include "llvm-c/Core.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/PassManager.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" #include "llvm/Support/Threading.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdlib> #include <cstring> +#include <system_error> using namespace llvm; +#define DEBUG_TYPE "ir" + void llvm::initializeCore(PassRegistry &Registry) { - initializeDominatorTreePass(Registry); - initializePrintModulePassPass(Registry); - initializePrintFunctionPassPass(Registry); + initializeDominatorTreeWrapperPassPass(Registry); + initializePrintModulePassWrapperPass(Registry); + initializePrintFunctionPassWrapperPass(Registry); initializePrintBasicBlockPassPass(Registry); - initializeVerifierPass(Registry); - initializePreVerifierPass(Registry); + initializeVerifierLegacyPassPass(Registry); } void LLVMInitializeCore(LLVMPassRegistryRef R) { @@ -77,6 +81,21 @@ LLVMContextRef LLVMGetGlobalContext() { return wrap(&getGlobalContext()); } +void LLVMContextSetDiagnosticHandler(LLVMContextRef C, + LLVMDiagnosticHandler Handler, + void *DiagnosticContext) { + unwrap(C)->setDiagnosticHandler( + LLVM_EXTENSION reinterpret_cast<LLVMContext::DiagnosticHandlerTy>(Handler), + DiagnosticContext); +} + +void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback, + void *OpaqueHandle) { + auto YieldCallback = + LLVM_EXTENSION reinterpret_cast<LLVMContext::YieldCallbackTy>(Callback); + unwrap(C)->setYieldCallback(YieldCallback, OpaqueHandle); +} + void LLVMContextDispose(LLVMContextRef C) { delete unwrap(C); } @@ -90,6 +109,40 @@ unsigned LLVMGetMDKindID(const char* Name, unsigned SLen) { return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen); } +char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { + std::string MsgStorage; + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + + unwrap(DI)->print(DP); + Stream.flush(); + + return LLVMCreateMessage(MsgStorage.c_str()); +} + +LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI){ + LLVMDiagnosticSeverity severity; + + switch(unwrap(DI)->getSeverity()) { + default: + severity = LLVMDSError; + break; + case DS_Warning: + severity = LLVMDSWarning; + break; + case DS_Remark: + severity = LLVMDSRemark; + break; + case DS_Note: + severity = LLVMDSNote; + break; + } + + return severity; +} + + + /*===-- Operations on modules ---------------------------------------------===*/ @@ -108,7 +161,7 @@ void LLVMDisposeModule(LLVMModuleRef M) { /*--.. Data layout .........................................................--*/ const char * LLVMGetDataLayout(LLVMModuleRef M) { - return unwrap(M)->getDataLayout().c_str(); + return unwrap(M)->getDataLayoutStr().c_str(); } void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple) { @@ -131,13 +184,13 @@ void LLVMDumpModule(LLVMModuleRef M) { LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, char **ErrorMessage) { std::string error; - raw_fd_ostream dest(Filename, error); + raw_fd_ostream dest(Filename, error, sys::fs::F_Text); if (!error.empty()) { *ErrorMessage = strdup(error.c_str()); return true; } - unwrap(M)->print(dest, NULL); + unwrap(M)->print(dest, nullptr); if (!error.empty()) { *ErrorMessage = strdup(error.c_str()); @@ -151,7 +204,7 @@ char *LLVMPrintModuleToString(LLVMModuleRef M) { std::string buf; raw_string_ostream os(buf); - unwrap(M)->print(os, NULL); + unwrap(M)->print(os, nullptr); os.flush(); return strdup(buf.c_str()); @@ -175,7 +228,6 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M) { LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { switch (unwrap(Ty)->getTypeID()) { - default: llvm_unreachable("Unhandled TypeID."); case Type::VoidTyID: return LLVMVoidTypeKind; case Type::HalfTyID: @@ -209,6 +261,7 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { case Type::X86_MMXTyID: return LLVMX86_MMXTypeKind; } + llvm_unreachable("Unhandled TypeID."); } LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty) @@ -228,7 +281,11 @@ char *LLVMPrintTypeToString(LLVMTypeRef Ty) { std::string buf; raw_string_ostream os(buf); - unwrap(Ty)->print(os); + if (unwrap(Ty)) + unwrap(Ty)->print(os); + else + os << "Printing <null> Type"; + os.flush(); return strdup(buf.c_str()); @@ -375,7 +432,7 @@ const char *LLVMGetStructName(LLVMTypeRef Ty) { StructType *Type = unwrap<StructType>(Ty); if (!Type->hasName()) - return 0; + return nullptr; return Type->getName().data(); } @@ -478,7 +535,11 @@ char* LLVMPrintValueToString(LLVMValueRef Val) { std::string buf; raw_string_ostream os(buf); - unwrap(Val)->print(os); + if (unwrap(Val)) + unwrap(Val)->print(os); + else + os << "Printing <null> Value"; + os.flush(); return strdup(buf.c_str()); @@ -497,7 +558,8 @@ LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { } void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { - unwrap<Instruction>(Inst)->setMetadata(KindID, MD? unwrap<MDNode>(MD) : NULL); + unwrap<Instruction>(Inst)->setMetadata(KindID, + MD ? unwrap<MDNode>(MD) : nullptr); } /*--.. Conversion functions ................................................--*/ @@ -514,15 +576,15 @@ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value *V = unwrap(Val); Value::use_iterator I = V->use_begin(); if (I == V->use_end()) - return 0; - return wrap(&(I.getUse())); + return nullptr; + return wrap(&*I); } LLVMUseRef LLVMGetNextUse(LLVMUseRef U) { Use *Next = unwrap(U)->getNext(); if (Next) return wrap(Next); - return 0; + return nullptr; } LLVMValueRef LLVMGetUser(LLVMUseRef U) { @@ -612,7 +674,7 @@ const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) { return S->getString().data(); } *Len = 0; - return 0; + return nullptr; } unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) @@ -651,7 +713,7 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); if (!N) return; - MDNode *Op = Val ? unwrap<MDNode>(Val) : NULL; + MDNode *Op = Val ? unwrap<MDNode>(Val) : nullptr; if (Op) N->addOperand(Op); } @@ -1160,14 +1222,6 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { return LLVMInternalLinkage; case GlobalValue::PrivateLinkage: return LLVMPrivateLinkage; - case GlobalValue::LinkerPrivateLinkage: - return LLVMLinkerPrivateLinkage; - case GlobalValue::LinkerPrivateWeakLinkage: - return LLVMLinkerPrivateWeakLinkage; - case GlobalValue::DLLImportLinkage: - return LLVMDLLImportLinkage; - case GlobalValue::DLLExportLinkage: - return LLVMDLLExportLinkage; case GlobalValue::ExternalWeakLinkage: return LLVMExternalWeakLinkage; case GlobalValue::CommonLinkage: @@ -1213,16 +1267,18 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMLinkerPrivateLinkage: - GV->setLinkage(GlobalValue::LinkerPrivateLinkage); + GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMLinkerPrivateWeakLinkage: - GV->setLinkage(GlobalValue::LinkerPrivateWeakLinkage); + GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMDLLImportLinkage: - GV->setLinkage(GlobalValue::DLLImportLinkage); + DEBUG(errs() + << "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported."); break; case LLVMDLLExportLinkage: - GV->setLinkage(GlobalValue::DLLExportLinkage); + DEBUG(errs() + << "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported."); break; case LLVMExternalWeakLinkage: GV->setLinkage(GlobalValue::ExternalWeakLinkage); @@ -1238,11 +1294,11 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { } const char *LLVMGetSection(LLVMValueRef Global) { - return unwrap<GlobalValue>(Global)->getSection().c_str(); + return unwrap<GlobalValue>(Global)->getSection(); } void LLVMSetSection(LLVMValueRef Global, const char *Section) { - unwrap<GlobalValue>(Global)->setSection(Section); + unwrap<GlobalObject>(Global)->setSection(Section); } LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { @@ -1255,45 +1311,70 @@ void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { ->setVisibility(static_cast<GlobalValue::VisibilityTypes>(Viz)); } +LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global) { + return static_cast<LLVMDLLStorageClass>( + unwrap<GlobalValue>(Global)->getDLLStorageClass()); +} + +void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) { + unwrap<GlobalValue>(Global)->setDLLStorageClass( + static_cast<GlobalValue::DLLStorageClassTypes>(Class)); +} + +LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) { + return unwrap<GlobalValue>(Global)->hasUnnamedAddr(); +} + +void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) { + unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr); +} + /*--.. 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 (AllocaInst *AI = dyn_cast<AllocaInst>(P)) + return AI->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"); + llvm_unreachable( + "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); } void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { Value *P = unwrap<Value>(V); - if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + if (GlobalObject *GV = dyn_cast<GlobalObject>(P)) GV->setAlignment(Bytes); + else if (AllocaInst *AI = dyn_cast<AllocaInst>(P)) + AI->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"); + llvm_unreachable( + "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); } /*--.. Operations on global variables ......................................--*/ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, - GlobalValue::ExternalLinkage, 0, Name)); + GlobalValue::ExternalLinkage, nullptr, Name)); } LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name, unsigned AddressSpace) { return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, - GlobalValue::ExternalLinkage, 0, Name, 0, - GlobalVariable::NotThreadLocal, AddressSpace)); + GlobalValue::ExternalLinkage, nullptr, Name, + nullptr, GlobalVariable::NotThreadLocal, + AddressSpace)); } LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) { @@ -1304,7 +1385,7 @@ LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::global_iterator I = Mod->global_begin(); if (I == Mod->global_end()) - return 0; + return nullptr; return wrap(I); } @@ -1312,7 +1393,7 @@ LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::global_iterator I = Mod->global_end(); if (I == Mod->global_begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1320,7 +1401,7 @@ LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar) { GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar); Module::global_iterator I = GV; if (++I == GV->getParent()->global_end()) - return 0; + return nullptr; return wrap(I); } @@ -1328,7 +1409,7 @@ LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar) { GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar); Module::global_iterator I = GV; if (I == GV->getParent()->global_begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1339,7 +1420,7 @@ void LLVMDeleteGlobal(LLVMValueRef GlobalVar) { LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) { GlobalVariable* GV = unwrap<GlobalVariable>(GlobalVar); if ( !GV->hasInitializer() ) - return 0; + return nullptr; return wrap(GV->getInitializer()); } @@ -1415,8 +1496,10 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit) { LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name) { - return wrap(new GlobalAlias(unwrap(Ty), GlobalValue::ExternalLinkage, Name, - unwrap<Constant>(Aliasee), unwrap (M))); + auto *PTy = cast<PointerType>(unwrap(Ty)); + return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), + GlobalValue::ExternalLinkage, Name, + unwrap<GlobalObject>(Aliasee), unwrap(M))); } /*--.. Operations on functions .............................................--*/ @@ -1435,7 +1518,7 @@ LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::iterator I = Mod->begin(); if (I == Mod->end()) - return 0; + return nullptr; return wrap(I); } @@ -1443,7 +1526,7 @@ LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::iterator I = Mod->end(); if (I == Mod->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1451,7 +1534,7 @@ LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Module::iterator I = Func; if (++I == Func->getParent()->end()) - return 0; + return nullptr; return wrap(I); } @@ -1459,7 +1542,7 @@ LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Module::iterator I = Func; if (I == Func->getParent()->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1484,7 +1567,7 @@ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { const char *LLVMGetGC(LLVMValueRef Fn) { Function *F = unwrap<Function>(Fn); - return F->hasGC()? F->getGC() : 0; + return F->hasGC()? F->getGC() : nullptr; } void LLVMSetGC(LLVMValueRef Fn, const char *GC) { @@ -1565,7 +1648,7 @@ LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Function::arg_iterator I = Func->arg_begin(); if (I == Func->arg_end()) - return 0; + return nullptr; return wrap(I); } @@ -1573,7 +1656,7 @@ LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Function::arg_iterator I = Func->arg_end(); if (I == Func->arg_begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1581,7 +1664,7 @@ LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg) { Argument *A = unwrap<Argument>(Arg); Function::arg_iterator I = A; if (++I == A->getParent()->arg_end()) - return 0; + return nullptr; return wrap(I); } @@ -1589,7 +1672,7 @@ LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) { Argument *A = unwrap<Argument>(Arg); Function::arg_iterator I = A; if (I == A->getParent()->arg_begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1659,7 +1742,7 @@ LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Function::iterator I = Func->begin(); if (I == Func->end()) - return 0; + return nullptr; return wrap(I); } @@ -1667,7 +1750,7 @@ LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) { Function *Func = unwrap<Function>(Fn); Function::iterator I = Func->end(); if (I == Func->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1675,7 +1758,7 @@ LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); Function::iterator I = Block; if (++I == Block->getParent()->end()) - return 0; + return nullptr; return wrap(I); } @@ -1683,7 +1766,7 @@ LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); Function::iterator I = Block; if (I == Block->getParent()->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1735,7 +1818,7 @@ LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); BasicBlock::iterator I = Block->begin(); if (I == Block->end()) - return 0; + return nullptr; return wrap(I); } @@ -1743,7 +1826,7 @@ LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); BasicBlock::iterator I = Block->end(); if (I == Block->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1751,7 +1834,7 @@ LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst) { Instruction *Instr = unwrap<Instruction>(Inst); BasicBlock::iterator I = Instr; if (++I == Instr->getParent()->end()) - return 0; + return nullptr; return wrap(I); } @@ -1759,7 +1842,7 @@ LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) { Instruction *Instr = unwrap<Instruction>(Inst); BasicBlock::iterator I = Instr; if (I == Instr->getParent()->begin()) - return 0; + return nullptr; return wrap(--I); } @@ -1922,7 +2005,7 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) { /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { - MDNode *Loc = L ? unwrap<MDNode>(L) : NULL; + MDNode *Loc = L ? unwrap<MDNode>(L) : nullptr; unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc)); } @@ -2178,7 +2261,7 @@ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), ITy, unwrap(Ty), AllocSize, - 0, 0, ""); + nullptr, nullptr, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } @@ -2189,13 +2272,13 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), ITy, unwrap(Ty), AllocSize, - unwrap(Val), 0, ""); + unwrap(Val), nullptr, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { - return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), 0, Name)); + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), nullptr, Name)); } LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, @@ -2219,6 +2302,29 @@ LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); } +static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) { + switch (Ordering) { + case LLVMAtomicOrderingNotAtomic: return NotAtomic; + case LLVMAtomicOrderingUnordered: return Unordered; + case LLVMAtomicOrderingMonotonic: return Monotonic; + case LLVMAtomicOrderingAcquire: return Acquire; + case LLVMAtomicOrderingRelease: return Release; + case LLVMAtomicOrderingAcquireRelease: return AcquireRelease; + case LLVMAtomicOrderingSequentiallyConsistent: + return SequentiallyConsistent; + } + + llvm_unreachable("Invalid LLVMAtomicOrdering value!"); +} + +LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering, + LLVMBool isSingleThread, const char *Name) { + return wrap( + unwrap(B)->CreateFence(mapFromLLVMOrdering(Ordering), + isSingleThread ? SingleThread : CrossThread, + Name)); +} + LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef *Indices, unsigned NumIndices, const char *Name) { @@ -2476,22 +2582,8 @@ LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, case LLVMAtomicRMWBinOpUMax: intop = AtomicRMWInst::UMax; break; case LLVMAtomicRMWBinOpUMin: intop = AtomicRMWInst::UMin; break; } - AtomicOrdering intordering; - switch (ordering) { - case LLVMAtomicOrderingNotAtomic: intordering = NotAtomic; break; - case LLVMAtomicOrderingUnordered: intordering = Unordered; break; - case LLVMAtomicOrderingMonotonic: intordering = Monotonic; break; - case LLVMAtomicOrderingAcquire: intordering = Acquire; break; - case LLVMAtomicOrderingRelease: intordering = Release; break; - case LLVMAtomicOrderingAcquireRelease: - intordering = AcquireRelease; - break; - case LLVMAtomicOrderingSequentiallyConsistent: - intordering = SequentiallyConsistent; - break; - } return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), - intordering, singleThread ? SingleThread : CrossThread)); + mapFromLLVMOrdering(ordering), singleThread ? SingleThread : CrossThread)); } @@ -2514,28 +2606,24 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile( LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - OwningPtr<MemoryBuffer> MB; - error_code ec; - if (!(ec = MemoryBuffer::getFile(Path, MB))) { - *OutMemBuf = wrap(MB.take()); - return 0; + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path); + if (std::error_code EC = MBOrErr.getError()) { + *OutMessage = strdup(EC.message().c_str()); + return 1; } - - *OutMessage = strdup(ec.message().c_str()); - return 1; + *OutMemBuf = wrap(MBOrErr.get().release()); + return 0; } LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - OwningPtr<MemoryBuffer> MB; - error_code ec; - if (!(ec = MemoryBuffer::getSTDIN(MB))) { - *OutMemBuf = wrap(MB.take()); - return 0; + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getSTDIN(); + if (std::error_code EC = MBOrErr.getError()) { + *OutMessage = strdup(EC.message().c_str()); + return 1; } - - *OutMessage = strdup(ec.message().c_str()); - return 1; + *OutMemBuf = wrap(MBOrErr.get().release()); + return 0; } LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange( @@ -2616,11 +2704,10 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM) { /*===-- Threading ------------------------------------------------------===*/ LLVMBool LLVMStartMultithreaded() { - return llvm_start_multithreaded(); + return LLVMIsMultithreaded(); } void LLVMStopMultithreaded() { - llvm_stop_multithreaded(); } LLVMBool LLVMIsMultithreaded() { diff --git a/contrib/llvm/lib/IR/DIBuilder.cpp b/contrib/llvm/lib/IR/DIBuilder.cpp index c4a9f41..218787c 100644 --- a/contrib/llvm/lib/IR/DIBuilder.cpp +++ b/contrib/llvm/lib/IR/DIBuilder.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DIBuilder.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" @@ -30,8 +30,9 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { } DIBuilder::DIBuilder(Module &m) - : M(m), VMContext(M.getContext()), TempEnumTypes(0), TempRetainTypes(0), - TempSubprograms(0), TempGVs(0), DeclareFn(0), ValueFn(0) {} + : M(m), VMContext(M.getContext()), TempEnumTypes(nullptr), + TempRetainTypes(nullptr), TempSubprograms(nullptr), TempGVs(nullptr), + DeclareFn(nullptr), ValueFn(nullptr) {} /// finalize - Construct any deferred debug info descriptors. void DIBuilder::finalize() { @@ -69,7 +70,10 @@ void DIBuilder::finalize() { DIArray GVs = getOrCreateArray(AllGVs); DIType(TempGVs).replaceAllUsesWith(GVs); - DIArray IMs = getOrCreateArray(AllImportedModules); + SmallVector<Value *, 16> RetainValuesI; + for (unsigned I = 0, E = AllImportedModules.size(); I < E; I++) + RetainValuesI.push_back(AllImportedModules[I]); + DIArray IMs = getOrCreateArray(RetainValuesI); DIType(TempImportedModules).replaceAllUsesWith(IMs); } @@ -77,7 +81,7 @@ void DIBuilder::finalize() { /// N. static MDNode *getNonCompileUnitScope(MDNode *N) { if (DIDescriptor(N).isCompileUnit()) - return NULL; + return nullptr; return N; } @@ -97,8 +101,11 @@ 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) || + StringRef SplitName, + DebugEmissionKind Kind, + bool EmitDebugInfo) { + + assert(((Lang <= dwarf::DW_LANG_OCaml && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && "Invalid Language tag"); assert(!Filename.empty() && @@ -127,26 +134,33 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, TempSubprograms, TempGVs, TempImportedModules, - MDString::get(VMContext, SplitName) + MDString::get(VMContext, SplitName), + ConstantInt::get(Type::getInt32Ty(VMContext), Kind) }; 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(CUNode); + // Note that we only generate this when the caller wants to actually + // emit debug information. When we are only interested in tracking + // source line locations throughout the backend, we prevent codegen from + // emitting debug info in the final output by not generating llvm.dbg.cu. + if (EmitDebugInfo) { + NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); + NMD->addOperand(CUNode); + } return DICompileUnit(CUNode); } static DIImportedEntity -createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, - unsigned Line, StringRef Name, - SmallVectorImpl<Value *> &AllImportedModules) { +createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope Context, + Value *NS, unsigned Line, StringRef Name, + SmallVectorImpl<TrackingVH<MDNode>> &AllImportedModules) { const MDNode *R; if (Name.empty()) { Value *Elts[] = { - GetTagConstant(C, dwarf::DW_TAG_imported_module), + GetTagConstant(C, Tag), Context, NS, ConstantInt::get(Type::getInt32Ty(C), Line), @@ -154,7 +168,7 @@ createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, R = MDNode::get(C, Elts); } else { Value *Elts[] = { - GetTagConstant(C, dwarf::DW_TAG_imported_module), + GetTagConstant(C, Tag), Context, NS, ConstantInt::get(Type::getInt32Ty(C), Line), @@ -164,38 +178,37 @@ createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, } DIImportedEntity M(R); assert(M.Verify() && "Imported module should be valid"); - AllImportedModules.push_back(M); + AllImportedModules.push_back(TrackingVH<MDNode>(M)); return M; } DIImportedEntity DIBuilder::createImportedModule(DIScope Context, - DINameSpace NS, unsigned Line, - StringRef Name) { - return ::createImportedModule(VMContext, Context, NS, Line, Name, - AllImportedModules); + DINameSpace NS, + unsigned Line) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, + Context, NS, Line, StringRef(), AllImportedModules); } DIImportedEntity DIBuilder::createImportedModule(DIScope Context, DIImportedEntity NS, - unsigned Line, - StringRef Name) { - return ::createImportedModule(VMContext, Context, NS, Line, Name, + unsigned Line) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, + Context, NS, Line, StringRef(), AllImportedModules); +} + +DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, + DIScope Decl, + unsigned Line, StringRef Name) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, + Context, Decl.getRef(), Line, Name, AllImportedModules); } DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, - DIDescriptor Decl, - unsigned Line) { - Value *Elts[] = { - GetTagConstant(VMContext, dwarf::DW_TAG_imported_declaration), - Context, - Decl, - ConstantInt::get(Type::getInt32Ty(VMContext), Line), - }; - DIImportedEntity M(MDNode::get(VMContext, Elts)); - assert(M.Verify() && "Imported module should be valid"); - AllImportedModules.push_back(M); - return M; + DIImportedEntity Imp, + unsigned Line, StringRef Name) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, + Context, Imp, Line, Name, AllImportedModules); } /// createFile - Create a file descriptor to hold debugging information @@ -226,8 +239,8 @@ DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) { // size, alignment, offset and flags are always empty here. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_type), - NULL, // Filename - NULL, // Unused + nullptr, // Filename + nullptr, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size @@ -254,8 +267,8 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, // offset and flags are always empty here. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_base_type), - NULL, // File/directory name - NULL, // Unused + nullptr, // File/directory name + nullptr, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), @@ -273,8 +286,8 @@ DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { // Qualified types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, Tag), - NULL, // Filename - NULL, // Unused + nullptr, // Filename + nullptr, // Unused MDString::get(VMContext, StringRef()), // Empty name. ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size @@ -293,8 +306,8 @@ DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, // Pointer types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type), - NULL, // Filename - NULL, // Unused + nullptr, // Filename + nullptr, // Unused MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), @@ -311,9 +324,9 @@ DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, // Pointer types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_ptr_to_member_type), - NULL, // Filename - NULL, // Unused - NULL, + nullptr, // Filename + nullptr, // Unused + nullptr, ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align @@ -332,9 +345,9 @@ DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { // References are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, Tag), - NULL, // Filename - NULL, // TheCU, - NULL, // Name + nullptr, // Filename + nullptr, // TheCU, + nullptr, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align @@ -349,7 +362,6 @@ 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.isType() && "Invalid typedef type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), File.getFileNode(), @@ -372,9 +384,9 @@ DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { assert(FriendTy.isType() && "Invalid friend type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_friend), - NULL, + nullptr, Ty.getRef(), - NULL, // Name + nullptr, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align @@ -394,9 +406,9 @@ DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, // TAG_inheritance is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_inheritance), - NULL, + nullptr, Ty.getRef(), - NULL, // Name + nullptr, // Name ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align @@ -625,7 +637,8 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, ConstantInt::get(Type::getInt32Ty(VMContext), 0), VTableHolder.getRef(), TemplateParams, - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && @@ -661,8 +674,9 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), VTableHolder.getRef(), - NULL, - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + nullptr, + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && @@ -691,12 +705,13 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), Flags), - NULL, + nullptr, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), - NULL, - NULL, - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + nullptr, + nullptr, + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType R(MDNode::get(VMContext, Elts)); if (!UniqueIdentifier.empty()) @@ -706,24 +721,25 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, /// createSubroutineType - Create subroutine type. DICompositeType DIBuilder::createSubroutineType(DIFile File, - DIArray ParameterTypes) { + DIArray ParameterTypes, + unsigned Flags) { // TAG_subroutine_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type), Constant::getNullValue(Type::getInt32Ty(VMContext)), - NULL, + nullptr, MDString::get(VMContext, ""), 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, + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), // Flags + nullptr, ParameterTypes, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, - NULL, - NULL // Type Identifer + nullptr, + nullptr, + nullptr // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -748,9 +764,10 @@ DICompositeType DIBuilder::createEnumerationType( UnderlyingType.getRef(), Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, - NULL, - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + nullptr, + nullptr, + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; DICompositeType CTy(MDNode::get(VMContext, Elts)); AllEnumTypes.push_back(CTy); @@ -765,8 +782,8 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, // TAG_array_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), - NULL, // Filename/Directory, - NULL, // Unused + nullptr, // Filename/Directory, + nullptr, // Unused MDString::get(VMContext, ""), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), @@ -776,9 +793,9 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, - NULL, - NULL // Type Identifer + nullptr, + nullptr, + nullptr // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -789,8 +806,8 @@ DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, // A vector is an array type with the FlagVector flag applied. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), - NULL, // Filename/Directory, - NULL, // Unused + nullptr, // Filename/Directory, + nullptr, // Unused MDString::get(VMContext, ""), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line ConstantInt::get(Type::getInt64Ty(VMContext), Size), @@ -800,9 +817,9 @@ DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, Ty.getRef(), Subscripts, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, - NULL, - NULL // Type Identifer + nullptr, + nullptr, + nullptr // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -883,12 +900,47 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), - NULL, + nullptr, DIArray(), ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang), - NULL, - NULL, //TemplateParams - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + nullptr, + nullptr, //TemplateParams + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) + }; + MDNode *Node = MDNode::get(VMContext, Elts); + DICompositeType RetTy(Node); + assert(RetTy.isCompositeType() && + "createForwardDecl result should be a DIType"); + if (!UniqueIdentifier.empty()) + retainType(RetTy); + return RetTy; +} + +/// createForwardDecl - Create a temporary forward-declared type that +/// can be RAUW'd if the full type is seen. +DICompositeType DIBuilder::createReplaceableForwardDecl( + 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(), + 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), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), + nullptr, + DIArray(), + ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang), + nullptr, + nullptr, //TemplateParams + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); DICompositeType RetTy(Node); @@ -901,10 +953,6 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, /// getOrCreateArray - Get a DIArray, create one if required. DIArray DIBuilder::getOrCreateArray(ArrayRef<Value *> Elements) { - if (Elements.empty()) { - Value *Null = Constant::getNullValue(Type::getInt32Ty(VMContext)); - return DIArray(MDNode::get(VMContext, Null)); - } return DIArray(MDNode::get(VMContext, Elements)); } @@ -924,12 +972,12 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, + DITypeRef Ty, bool isLocalToUnit, Value *Val) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), Constant::getNullValue(Type::getInt32Ty(VMContext)), - NULL, // TheCU, + nullptr, // TheCU, MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -948,7 +996,8 @@ DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, /// \brief Create a new descriptor for the specified global. DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIFile F, - unsigned LineNumber, DIType Ty, + unsigned LineNumber, + DITypeRef Ty, bool isLocalToUnit, Value *Val) { return createGlobalVariable(Name, Name, F, LineNumber, Ty, isLocalToUnit, @@ -961,7 +1010,8 @@ DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNumber, - DIType Ty, bool isLocalToUnit, + DITypeRef Ty, + bool isLocalToUnit, Value *Val, MDNode *Decl) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), @@ -986,14 +1036,12 @@ DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context, /// createVariable - Create a new descriptor for the specified variable. DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNo, DIType Ty, + unsigned LineNo, DITypeRef Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { DIDescriptor Context(getNonCompileUnitScope(Scope)); assert((!Context || Context.isScope()) && "createLocalVariable should be called with a valid Context"); - assert(Ty.isType() && - "createLocalVariable should be called with a valid type"); Value *Elts[] = { GetTagConstant(VMContext, Tag), getNonCompileUnitScope(Scope), @@ -1024,20 +1072,22 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile F, unsigned LineNo, - DIType Ty, ArrayRef<Value *> Addr, + DITypeRef Ty, + ArrayRef<Value *> Addr, unsigned ArgNo) { - SmallVector<Value *, 15> Elts; - Elts.push_back(GetTagConstant(VMContext, Tag)); - Elts.push_back(getNonCompileUnitScope(Scope)), - Elts.push_back(MDString::get(VMContext, Name)); - Elts.push_back(F); - Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), - (LineNo | (ArgNo << 24)))); - Elts.push_back(Ty); - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); - Elts.append(Addr.begin(), Addr.end()); - + assert(Addr.size() > 0 && "complex address is empty"); + Value *Elts[] = { + GetTagConstant(VMContext, Tag), + getNonCompileUnitScope(Scope), + MDString::get(VMContext, Name), + F, + ConstantInt::get(Type::getInt32Ty(VMContext), + (LineNo | (ArgNo << 24))), + Ty, + Constant::getNullValue(Type::getInt32Ty(VMContext)), + Constant::getNullValue(Type::getInt32Ty(VMContext)), + MDNode::get(VMContext, Addr) + }; return DIVariable(MDNode::get(VMContext, Elts)); } @@ -1083,7 +1133,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, + nullptr, ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, @@ -1098,7 +1148,8 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); - assert(S.isSubprogram() && "createFunction should return a valid DISubprogram"); + assert(S.isSubprogram() && + "createFunction should return a valid DISubprogram"); return S; } @@ -1116,7 +1167,6 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, 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(), @@ -1136,7 +1186,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, Fn, TParam, Constant::getNullValue(Type::getInt32Ty(VMContext)), - MDNode::getTemporary(VMContext, TElts), + nullptr, // FIXME: Do we want to use different scope/lines? ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) }; @@ -1182,7 +1232,15 @@ DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, } DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, - unsigned Line, unsigned Col) { + unsigned Line, unsigned Col, + unsigned Discriminator) { + // FIXME: This isn't thread safe nor the right way to defeat MDNode uniquing. + // I believe the right way is to have a self-referential element in the node. + // Also: why do we bother with line/column - they're not used and the + // documentation (SourceLevelDebugging.rst) claims the line/col are necessary + // for uniquing, yet then we have this other solution (because line/col were + // inadequate) anyway. Remove all 3 and replace them with a self-reference. + // Defeat MDNode uniquing for lexical blocks by using unique id. static unsigned int unique_id = 0; Value *Elts[] = { @@ -1191,6 +1249,7 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, getNonCompileUnitScope(Scope), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt32Ty(VMContext), Col), + ConstantInt::get(Type::getInt32Ty(VMContext), Discriminator), ConstantInt::get(Type::getInt32Ty(VMContext), unique_id++) }; DILexicalBlock R(MDNode::get(VMContext, Elts)); diff --git a/contrib/llvm/lib/IR/DataLayout.cpp b/contrib/llvm/lib/IR/DataLayout.cpp index 6bdc09e..dea05fb 100644 --- a/contrib/llvm/lib/IR/DataLayout.cpp +++ b/contrib/llvm/lib/IR/DataLayout.cpp @@ -18,11 +18,13 @@ #include "llvm/IR/DataLayout.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Mutex.h" @@ -33,9 +35,8 @@ using namespace llvm; // Handle the Pass registration stuff necessary to use DataLayout's. -// Register the default SparcV9 implementation... -INITIALIZE_PASS(DataLayout, "datalayout", "Data Layout", false, true) -char DataLayout::ID = 0; +INITIALIZE_PASS(DataLayoutPass, "datalayout", "Data Layout", false, true) +char DataLayoutPass::ID = 0; //===----------------------------------------------------------------------===// // Support for StructLayout @@ -118,21 +119,21 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const { } const LayoutAlignElem -DataLayout::InvalidAlignmentElem = LayoutAlignElem::get(INVALID_ALIGN, 0, 0, 0); +DataLayout::InvalidAlignmentElem = { INVALID_ALIGN, 0, 0, 0 }; //===----------------------------------------------------------------------===// // PointerAlignElem, PointerAlign support //===----------------------------------------------------------------------===// PointerAlignElem -PointerAlignElem::get(uint32_t addr_space, unsigned abi_align, - unsigned pref_align, uint32_t bit_width) { - assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); +PointerAlignElem::get(uint32_t AddressSpace, unsigned ABIAlign, + unsigned PrefAlign, uint32_t TypeByteWidth) { + assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); PointerAlignElem retval; - retval.AddressSpace = addr_space; - retval.ABIAlign = abi_align; - retval.PrefAlign = pref_align; - retval.TypeBitWidth = bit_width; + retval.AddressSpace = AddressSpace; + retval.ABIAlign = ABIAlign; + retval.PrefAlign = PrefAlign; + retval.TypeByteWidth = TypeByteWidth; return retval; } @@ -141,36 +142,52 @@ PointerAlignElem::operator==(const PointerAlignElem &rhs) const { return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace && PrefAlign == rhs.PrefAlign - && TypeBitWidth == rhs.TypeBitWidth); + && TypeByteWidth == rhs.TypeByteWidth); } const PointerAlignElem -DataLayout::InvalidPointerElem = PointerAlignElem::get(~0U, 0U, 0U, 0U); +DataLayout::InvalidPointerElem = { 0U, 0U, 0U, ~0U }; //===----------------------------------------------------------------------===// // DataLayout Class Implementation //===----------------------------------------------------------------------===// -void DataLayout::init(StringRef Desc) { - initializeDataLayoutPass(*PassRegistry::getPassRegistry()); +const char *DataLayout::getManglingComponent(const Triple &T) { + if (T.isOSBinFormatMachO()) + return "-m:o"; + if (T.isOSWindows() && T.getArch() == Triple::x86 && T.isOSBinFormatCOFF()) + return "-m:w"; + return "-m:e"; +} + +static const LayoutAlignElem DefaultAlignments[] = { + { INTEGER_ALIGN, 1, 1, 1 }, // i1 + { INTEGER_ALIGN, 8, 1, 1 }, // i8 + { INTEGER_ALIGN, 16, 2, 2 }, // i16 + { INTEGER_ALIGN, 32, 4, 4 }, // i32 + { INTEGER_ALIGN, 64, 4, 8 }, // i64 + { FLOAT_ALIGN, 16, 2, 2 }, // half + { FLOAT_ALIGN, 32, 4, 4 }, // float + { FLOAT_ALIGN, 64, 8, 8 }, // double + { FLOAT_ALIGN, 128, 16, 16 }, // ppcf128, quad, ... + { VECTOR_ALIGN, 64, 8, 8 }, // v2i32, v1i64, ... + { VECTOR_ALIGN, 128, 16, 16 }, // v16i8, v8i16, v4i32, ... + { AGGREGATE_ALIGN, 0, 0, 8 } // struct +}; + +void DataLayout::reset(StringRef Desc) { + clear(); - LayoutMap = 0; + LayoutMap = nullptr; LittleEndian = false; StackNaturalAlign = 0; + ManglingMode = MM_None; // Default alignments - setAlignment(INTEGER_ALIGN, 1, 1, 1); // i1 - setAlignment(INTEGER_ALIGN, 1, 1, 8); // i8 - setAlignment(INTEGER_ALIGN, 2, 2, 16); // i16 - setAlignment(INTEGER_ALIGN, 4, 4, 32); // i32 - setAlignment(INTEGER_ALIGN, 4, 8, 64); // i64 - setAlignment(FLOAT_ALIGN, 2, 2, 16); // half - setAlignment(FLOAT_ALIGN, 4, 4, 32); // float - setAlignment(FLOAT_ALIGN, 8, 8, 64); // double - setAlignment(FLOAT_ALIGN, 16, 16, 128); // ppcf128, quad, ... - setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ... - setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ... - setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct + for (const LayoutAlignElem &E : DefaultAlignments) { + setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign, + E.TypeBitWidth); + } setPointerAlignment(0, 8, 8, 8); parseSpecifier(Desc); @@ -185,11 +202,12 @@ static std::pair<StringRef, StringRef> split(StringRef Str, char Separator) { return Split; } -/// Get an unsinged integer, including error checks. +/// Get an unsigned integer, including error checks. static unsigned getInt(StringRef R) { unsigned Result; bool error = R.getAsInteger(10, Result); (void)error; - assert(!error && "not a number, or does not fit in an unsigned int"); + if (error) + report_fatal_error("not a number, or does not fit in an unsigned int"); return Result; } @@ -216,6 +234,10 @@ void DataLayout::parseSpecifier(StringRef Desc) { Tok = Tok.substr(1); switch (Specifier) { + case 's': + // Ignored for backward compatibility. + // FIXME: remove this on LLVM 4.0. + break; case 'E': LittleEndian = false; break; @@ -250,8 +272,7 @@ void DataLayout::parseSpecifier(StringRef Desc) { case 'i': case 'v': case 'f': - case 'a': - case 's': { + case 'a': { AlignTypeEnum AlignType; switch (Specifier) { default: @@ -259,12 +280,14 @@ void DataLayout::parseSpecifier(StringRef Desc) { case 'v': AlignType = VECTOR_ALIGN; break; case 'f': AlignType = FLOAT_ALIGN; break; case 'a': AlignType = AGGREGATE_ALIGN; break; - case 's': AlignType = STACK_ALIGN; break; } // Bit size. unsigned Size = Tok.empty() ? 0 : getInt(Tok); + assert((AlignType != AGGREGATE_ALIGN || Size == 0) && + "These specifications don't have a size"); + // ABI alignment. Split = split(Rest, ':'); unsigned ABIAlign = inBytes(getInt(Tok)); @@ -294,6 +317,26 @@ void DataLayout::parseSpecifier(StringRef Desc) { StackNaturalAlign = inBytes(getInt(Tok)); break; } + case 'm': + assert(Tok.empty()); + assert(Rest.size() == 1); + switch(Rest[0]) { + default: + llvm_unreachable("Unknown mangling in datalayout string"); + case 'e': + ManglingMode = MM_ELF; + break; + case 'o': + ManglingMode = MM_MachO; + break; + case 'm': + ManglingMode = MM_Mips; + break; + case 'w': + ManglingMode = MM_WINCOFF; + break; + } + break; default: llvm_unreachable("Unknown specifier in datalayout string"); break; @@ -301,18 +344,22 @@ void DataLayout::parseSpecifier(StringRef Desc) { } } -/// Default ctor. -/// -/// @note This has to exist, because this is a pass, but it should never be -/// used. -DataLayout::DataLayout() : ImmutablePass(ID) { - report_fatal_error("Bad DataLayout ctor used. " - "Tool did not specify a DataLayout to use?"); +DataLayout::DataLayout(const Module *M) : LayoutMap(nullptr) { + const DataLayout *Other = M->getDataLayout(); + if (Other) + *this = *Other; + else + reset(""); } -DataLayout::DataLayout(const Module *M) - : ImmutablePass(ID) { - init(M->getDataLayout()); +bool DataLayout::operator==(const DataLayout &Other) const { + bool Ret = LittleEndian == Other.LittleEndian && + StackNaturalAlign == Other.StackNaturalAlign && + ManglingMode == Other.ManglingMode && + LegalIntWidths == Other.LegalIntWidths && + Alignments == Other.Alignments && Pointers == Other.Pointers; + assert(Ret == (getStringRepresentation() == Other.getStringRepresentation())); + return Ret; } void @@ -321,12 +368,12 @@ DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align, assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); assert(pref_align < (1 << 16) && "Alignment doesn't fit in bitfield"); assert(bit_width < (1 << 24) && "Bit width doesn't fit in bitfield"); - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { - if (Alignments[i].AlignType == (unsigned)align_type && - Alignments[i].TypeBitWidth == bit_width) { + for (LayoutAlignElem &Elem : Alignments) { + if (Elem.AlignType == (unsigned)align_type && + Elem.TypeBitWidth == bit_width) { // Update the abi, preferred alignments. - Alignments[i].ABIAlign = abi_align; - Alignments[i].PrefAlign = pref_align; + Elem.ABIAlign = abi_align; + Elem.PrefAlign = pref_align; return; } } @@ -335,18 +382,26 @@ DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align, pref_align, bit_width)); } -void -DataLayout::setPointerAlignment(uint32_t addr_space, unsigned abi_align, - unsigned pref_align, uint32_t bit_width) { - assert(abi_align <= pref_align && "Preferred alignment worse than ABI!"); - DenseMap<unsigned,PointerAlignElem>::iterator val = Pointers.find(addr_space); - if (val == Pointers.end()) { - Pointers[addr_space] = PointerAlignElem::get(addr_space, - abi_align, pref_align, bit_width); +DataLayout::PointersTy::iterator +DataLayout::findPointerLowerBound(uint32_t AddressSpace) { + return std::lower_bound(Pointers.begin(), Pointers.end(), AddressSpace, + [](const PointerAlignElem &A, uint32_t AddressSpace) { + return A.AddressSpace < AddressSpace; + }); +} + +void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign, + unsigned PrefAlign, + uint32_t TypeByteWidth) { + assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); + PointersTy::iterator I = findPointerLowerBound(AddrSpace); + if (I == Pointers.end() || I->AddressSpace != AddrSpace) { + Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign, + TypeByteWidth)); } else { - val->second.ABIAlign = abi_align; - val->second.PrefAlign = pref_align; - val->second.TypeBitWidth = bit_width; + I->ABIAlign = ABIAlign; + I->PrefAlign = PrefAlign; + I->TypeByteWidth = TypeByteWidth; } } @@ -412,11 +467,10 @@ class StructLayoutMap { LayoutInfoTy LayoutInfo; public: - virtual ~StructLayoutMap() { + ~StructLayoutMap() { // Remove any layouts. - for (LayoutInfoTy::iterator I = LayoutInfo.begin(), E = LayoutInfo.end(); - I != E; ++I) { - StructLayout *Value = I->second; + for (const auto &I : LayoutInfo) { + StructLayout *Value = I.second; Value->~StructLayout(); free(Value); } @@ -425,21 +479,20 @@ public: StructLayout *&operator[](StructType *STy) { return LayoutInfo[STy]; } - - // for debugging... - virtual void dump() const {} }; } // end anonymous namespace -DataLayout::~DataLayout() { - delete static_cast<StructLayoutMap*>(LayoutMap); +void DataLayout::clear() { + LegalIntWidths.clear(); + Alignments.clear(); + Pointers.clear(); + delete static_cast<StructLayoutMap *>(LayoutMap); + LayoutMap = nullptr; } -bool DataLayout::doFinalization(Module &M) { - delete static_cast<StructLayoutMap*>(LayoutMap); - LayoutMap = 0; - return false; +DataLayout::~DataLayout() { + clear(); } const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { @@ -470,32 +523,49 @@ std::string DataLayout::getStringRepresentation() const { raw_string_ostream OS(Result); OS << (LittleEndian ? "e" : "E"); - SmallVector<unsigned, 8> addrSpaces; - // Lets get all of the known address spaces and sort them - // into increasing order so that we can emit the string - // in a cleaner format. - for (DenseMap<unsigned, PointerAlignElem>::const_iterator - pib = Pointers.begin(), pie = Pointers.end(); - pib != pie; ++pib) { - addrSpaces.push_back(pib->first); + + switch (ManglingMode) { + case MM_None: + break; + case MM_ELF: + OS << "-m:e"; + break; + case MM_MachO: + OS << "-m:o"; + break; + case MM_WINCOFF: + OS << "-m:w"; + break; + case MM_Mips: + OS << "-m:m"; + break; } - std::sort(addrSpaces.begin(), addrSpaces.end()); - for (SmallVectorImpl<unsigned>::iterator asb = addrSpaces.begin(), - ase = addrSpaces.end(); asb != ase; ++asb) { - const PointerAlignElem &PI = Pointers.find(*asb)->second; + + for (const PointerAlignElem &PI : Pointers) { + // Skip default. + if (PI.AddressSpace == 0 && PI.ABIAlign == 8 && PI.PrefAlign == 8 && + PI.TypeByteWidth == 8) + continue; + OS << "-p"; if (PI.AddressSpace) { OS << PI.AddressSpace; } - OS << ":" << PI.TypeBitWidth*8 << ':' << PI.ABIAlign*8 - << ':' << PI.PrefAlign*8; + OS << ":" << PI.TypeByteWidth*8 << ':' << PI.ABIAlign*8; + if (PI.PrefAlign != PI.ABIAlign) + OS << ':' << PI.PrefAlign*8; } - OS << "-S" << StackNaturalAlign*8; - for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { - const LayoutAlignElem &AI = Alignments[i]; - OS << '-' << (char)AI.AlignType << AI.TypeBitWidth << ':' - << AI.ABIAlign*8 << ':' << AI.PrefAlign*8; + for (const LayoutAlignElem &AI : Alignments) { + if (std::find(std::begin(DefaultAlignments), std::end(DefaultAlignments), + AI) != std::end(DefaultAlignments)) + continue; + OS << '-' << (char)AI.AlignType; + if (AI.TypeBitWidth) + OS << AI.TypeBitWidth; + OS << ':' << AI.ABIAlign*8; + if (AI.ABIAlign != AI.PrefAlign) + OS << ':' << AI.PrefAlign*8; } if (!LegalIntWidths.empty()) { @@ -504,9 +574,40 @@ std::string DataLayout::getStringRepresentation() const { for (unsigned i = 1, e = LegalIntWidths.size(); i != e; ++i) OS << ':' << (unsigned)LegalIntWidths[i]; } + + if (StackNaturalAlign) + OS << "-S" << StackNaturalAlign*8; + return OS.str(); } +unsigned DataLayout::getPointerABIAlignment(unsigned AS) const { + PointersTy::const_iterator I = findPointerLowerBound(AS); + if (I == Pointers.end() || I->AddressSpace != AS) { + I = findPointerLowerBound(0); + assert(I->AddressSpace == 0); + } + return I->ABIAlign; +} + +unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const { + PointersTy::const_iterator I = findPointerLowerBound(AS); + if (I == Pointers.end() || I->AddressSpace != AS) { + I = findPointerLowerBound(0); + assert(I->AddressSpace == 0); + } + return I->PrefAlign; +} + +unsigned DataLayout::getPointerSize(unsigned AS) const { + PointersTy::const_iterator I = findPointerLowerBound(AS); + if (I == Pointers.end() || I->AddressSpace != AS) { + I = findPointerLowerBound(0); + assert(I->AddressSpace == 0); + } + return I->TypeByteWidth; +} + unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const { assert(Ty->isPtrOrPtrVectorTy() && "This should only be called with a pointer or pointer vector type"); @@ -586,15 +687,7 @@ unsigned DataLayout::getABITypeAlignment(Type *Ty) const { /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for /// an integer type of the specified bitwidth. 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) - return Alignments[i].ABIAlign; - - return getABITypeAlignment(Ty); + return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr); } unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const { @@ -615,7 +708,7 @@ IntegerType *DataLayout::getIntPtrType(LLVMContext &C, Type *DataLayout::getIntPtrType(Type *Ty) const { assert(Ty->isPtrOrPtrVectorTy() && "Expected a pointer or pointer vector type."); - unsigned NumBits = getTypeSizeInBits(Ty->getScalarType()); + unsigned NumBits = getPointerTypeSizeInBits(Ty); IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) return VectorType::get(IntTy, VecTy->getNumElements()); @@ -623,17 +716,15 @@ Type *DataLayout::getIntPtrType(Type *Ty) const { } Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const { - for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) - if (Width <= LegalIntWidths[i]) - return Type::getIntNTy(C, LegalIntWidths[i]); - return 0; + for (unsigned LegalIntWidth : LegalIntWidths) + if (Width <= LegalIntWidth) + return Type::getIntNTy(C, LegalIntWidth); + return nullptr; } 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; + auto Max = std::max_element(LegalIntWidths.begin(), LegalIntWidths.end()); + return Max != LegalIntWidths.end() ? *Max : 0; } uint64_t DataLayout::getIndexedOffset(Type *ptrTy, @@ -703,3 +794,19 @@ unsigned DataLayout::getPreferredAlignment(const GlobalVariable *GV) const { unsigned DataLayout::getPreferredAlignmentLog(const GlobalVariable *GV) const { return Log2_32(getPreferredAlignment(GV)); } + +DataLayoutPass::DataLayoutPass() : ImmutablePass(ID), DL("") { + report_fatal_error("Bad DataLayoutPass ctor used. Tool did not specify a " + "DataLayout to use?"); +} + +DataLayoutPass::~DataLayoutPass() {} + +DataLayoutPass::DataLayoutPass(const DataLayout &DL) + : ImmutablePass(ID), DL(DL) { + initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); +} + +DataLayoutPass::DataLayoutPass(const Module *M) : ImmutablePass(ID), DL(M) { + initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); +} diff --git a/contrib/llvm/lib/IR/DebugInfo.cpp b/contrib/llvm/lib/IR/DebugInfo.cpp index 70a756f..5e39b24 100644 --- a/contrib/llvm/lib/IR/DebugInfo.cpp +++ b/contrib/llvm/lib/IR/DebugInfo.cpp @@ -12,7 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DebugInfo.h" +#include "llvm/IR/DebugInfo.h" +#include "LLVMContextImpl.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" @@ -23,9 +24,9 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace llvm::dwarf; @@ -45,14 +46,15 @@ bool DIDescriptor::Verify() const { DILexicalBlockFile(DbgNode).Verify() || DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() || DIObjCProperty(DbgNode).Verify() || + DIUnspecifiedParameter(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() || DITemplateValueParameter(DbgNode).Verify() || DIImportedEntity(DbgNode).Verify()); } static Value *getField(const MDNode *DbgNode, unsigned Elt) { - if (DbgNode == 0 || Elt >= DbgNode->getNumOperands()) - return 0; + if (!DbgNode || Elt >= DbgNode->getNumOperands()) + return nullptr; return DbgNode->getOperand(Elt); } @@ -71,7 +73,7 @@ StringRef DIDescriptor::getStringField(unsigned Elt) const { } uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { - if (DbgNode == 0) + if (!DbgNode) return 0; if (Elt < DbgNode->getNumOperands()) @@ -83,7 +85,7 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { } int64_t DIDescriptor::getInt64Field(unsigned Elt) const { - if (DbgNode == 0) + if (!DbgNode) return 0; if (Elt < DbgNode->getNumOperands()) @@ -100,34 +102,34 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { } GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { - if (DbgNode == 0) - return 0; + if (!DbgNode) + return nullptr; if (Elt < DbgNode->getNumOperands()) return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt)); - return 0; + return nullptr; } Constant *DIDescriptor::getConstantField(unsigned Elt) const { - if (DbgNode == 0) - return 0; + if (!DbgNode) + return nullptr; if (Elt < DbgNode->getNumOperands()) return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt)); - return 0; + return nullptr; } Function *DIDescriptor::getFunctionField(unsigned Elt) const { - if (DbgNode == 0) - return 0; + if (!DbgNode) + return nullptr; if (Elt < DbgNode->getNumOperands()) return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt)); - return 0; + return nullptr; } void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { - if (DbgNode == 0) + if (!DbgNode) return; if (Elt < DbgNode->getNumOperands()) { @@ -136,8 +138,14 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { } } -unsigned DIVariable::getNumAddrElements() const { - return DbgNode->getNumOperands() - 8; +uint64_t DIVariable::getAddrElement(unsigned Idx) const { + DIDescriptor ComplexExpr = getDescriptorField(8); + if (Idx < ComplexExpr->getNumOperands()) + if (auto *CI = dyn_cast_or_null<ConstantInt>(ComplexExpr->getOperand(Idx))) + return CI->getZExtValue(); + + assert(false && "non-existing complex address element requested"); + return 0; } /// getInlinedAt - If this variable is inlined then return inline location. @@ -333,7 +341,7 @@ unsigned DIArray::getNumElements() const { /// replaceAllUsesWith - Replace all uses of the MDNode used by this /// type with the one in the passed descriptor. -void DIType::replaceAllUsesWith(DIDescriptor &D) { +void DIType::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { assert(DbgNode && "Trying to replace an unverified type!"); @@ -342,13 +350,19 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) { // which, due to uniquing, has merged with the source. We shield clients from // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. - if (DbgNode != D) { - MDNode *Node = const_cast<MDNode *>(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value *>(V)); - MDNode::deleteTemporary(Node); + const MDNode *DN = D; + if (DbgNode == DN) { + SmallVector<Value*, 10> Ops(DbgNode->getNumOperands()); + for (size_t i = 0; i != Ops.size(); ++i) + Ops[i] = DbgNode->getOperand(i); + DN = MDNode::get(VMContext, Ops); } + + MDNode *Node = const_cast<MDNode *>(DbgNode); + const Value *V = cast_or_null<Value>(DN); + Node->replaceAllUsesWith(const_cast<Value *>(V)); + MDNode::deleteTemporary(Node); + DbgNode = D; } /// replaceAllUsesWith - Replace all uses of the MDNode used by this @@ -356,19 +370,12 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) { void DIType::replaceAllUsesWith(MDNode *D) { 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 - // which, due to uniquing, has merged with the source. We shield clients from - // this detail by allowing a value to be replaced with replaceAllUsesWith() - // itself. - if (DbgNode != D) { - MDNode *Node = const_cast<MDNode *>(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null<Value>(DN); - Node->replaceAllUsesWith(const_cast<Value *>(V)); - MDNode::deleteTemporary(Node); - } + assert(DbgNode != D && "This replacement should always happen"); + MDNode *Node = const_cast<MDNode *>(DbgNode); + const MDNode *DN = D; + const Value *V = cast_or_null<Value>(DN); + Node->replaceAllUsesWith(const_cast<Value *>(V)); + MDNode::deleteTemporary(Node); } /// Verify - Verify that a compile unit is well formed. @@ -381,7 +388,7 @@ bool DICompileUnit::Verify() const { if (getFilename().empty()) return false; - return DbgNode->getNumOperands() == 13; + return DbgNode->getNumOperands() == 14; } /// Verify - Verify that an ObjC property is well formed. @@ -427,8 +434,10 @@ static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { /// 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()); + (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) || + // Not checking for Val->isScope() here, because it would work + // only for lexical scopes and not all subclasses of DIScope. + isa<MDNode>(Val); } /// Check if a field at position Elt of a MDNode can be a ScopeRef. @@ -461,14 +470,13 @@ bool DIType::Verify() const { // DIType is abstract, it should be a BasicType, a DerivedType or // a CompositeType. if (isBasicType()) - DIBasicType(DbgNode).Verify(); + return DIBasicType(DbgNode).Verify(); else if (isCompositeType()) - DICompositeType(DbgNode).Verify(); + return DICompositeType(DbgNode).Verify(); else if (isDerivedType()) - DIDerivedType(DbgNode).Verify(); + return DIDerivedType(DbgNode).Verify(); else return false; - return true; } /// Verify - Verify that a basic type descriptor is well formed. @@ -505,6 +513,10 @@ bool DICompositeType::Verify() const { if (!fieldIsMDString(DbgNode, 14)) return false; + // A subroutine type can't be both & and &&. + if (isLValueReference() && isRValueReference()) + return false; + return DbgNode->getNumOperands() == 15; } @@ -521,6 +533,11 @@ bool DISubprogram::Verify() const { // Containing type @ field 12. if (!fieldIsTypeRef(DbgNode, 12)) return false; + + // A subprogram can't be both & and &&. + if (isLValueReference() && isRValueReference()) + return false; + return DbgNode->getNumOperands() == 20; } @@ -531,10 +548,11 @@ bool DIGlobalVariable::Verify() const { if (getDisplayName().empty()) return false; - // Make sure context @ field 2 and type @ field 8 are MDNodes. + // Make sure context @ field 2 is an MDNode. if (!fieldIsMDNode(DbgNode, 2)) return false; - if (!fieldIsMDNode(DbgNode, 8)) + // Make sure that type @ field 8 is a DITypeRef. + if (!fieldIsTypeRef(DbgNode, 8)) return false; // Make sure StaticDataMemberDeclaration @ field 12 is MDNode. if (!fieldIsMDNode(DbgNode, 12)) @@ -548,12 +566,19 @@ bool DIVariable::Verify() const { if (!isVariable()) return false; - // Make sure context @ field 1 and type @ field 5 are MDNodes. + // Make sure context @ field 1 is an MDNode. if (!fieldIsMDNode(DbgNode, 1)) return false; - if (!fieldIsMDNode(DbgNode, 5)) + // Make sure that type @ field 5 is a DITypeRef. + if (!fieldIsTypeRef(DbgNode, 5)) return false; - return DbgNode->getNumOperands() >= 8; + + // Variable without a complex expression. + if (DbgNode->getNumOperands() == 8) + return true; + + // Make sure the complex expression is an MDNode. + return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8)); } /// Verify - Verify that a location descriptor is well formed. @@ -591,7 +616,7 @@ bool DISubrange::Verify() const { /// \brief Verify that the lexical block descriptor is well formed. bool DILexicalBlock::Verify() const { - return isLexicalBlock() && DbgNode->getNumOperands() == 6; + return isLexicalBlock() && DbgNode->getNumOperands() == 7; } /// \brief Verify that the file-scoped lexical block descriptor is well formed. @@ -599,6 +624,11 @@ bool DILexicalBlockFile::Verify() const { return isLexicalBlockFile() && DbgNode->getNumOperands() == 3; } +/// \brief Verify that an unspecified parameter descriptor is well formed. +bool DIUnspecifiedParameter::Verify() const { + return isUnspecifiedParameter() && DbgNode->getNumOperands() == 1; +} + /// \brief Verify that the template type parameter descriptor is well formed. bool DITemplateTypeParameter::Verify() const { return isTemplateTypeParameter() && DbgNode->getNumOperands() == 7; @@ -658,19 +688,6 @@ void DICompositeType::setTypeArray(DIArray Elements, DIArray 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 { @@ -753,7 +770,7 @@ DIScopeRef DIScope::getContext() const { return DIScopeRef(DINameSpace(DbgNode).getContext()); assert((isFile() || isCompileUnit()) && "Unhandled type of scope."); - return DIScopeRef(NULL); + return DIScopeRef(nullptr); } // If the scope node has a name, return that, else return an empty string. @@ -817,6 +834,29 @@ DIArray DICompileUnit::getImportedEntities() const { return DIArray(getNodeField(DbgNode, 11)); } +/// copyWithNewScope - Return a copy of this location, replacing the +/// current scope with the given one. +DILocation DILocation::copyWithNewScope(LLVMContext &Ctx, + DILexicalBlock NewScope) { + SmallVector<Value *, 10> Elts; + assert(Verify()); + for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) { + if (I != 2) + Elts.push_back(DbgNode->getOperand(I)); + else + Elts.push_back(NewScope); + } + MDNode *NewDIL = MDNode::get(Ctx, Elts); + return DILocation(NewDIL); +} + +/// computeNewDiscriminator - Generate a new discriminator value for this +/// file and line location. +unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) { + std::pair<const char *, unsigned> Key(getFilename().data(), getLineNumber()); + return ++Ctx.pImpl->DiscriminatorTable[Key]; +} + /// fixupSubprogramName - Replace contains special characters used /// in a typical Objective-C names with '.' in a given string. static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) { @@ -974,7 +1014,7 @@ void DebugInfoFinder::processModule(const Module &M) { DIGlobalVariable DIG(GVs.getElement(i)); if (addGlobalVariable(DIG)) { processScope(DIG.getContext()); - processType(DIG.getType()); + processType(DIG.getType().resolve(TypeIdentifierMap)); } } DIArray SPs = CU.getSubprograms(); @@ -989,7 +1029,7 @@ void DebugInfoFinder::processModule(const Module &M) { DIArray Imports = CU.getImportedEntities(); for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) { DIImportedEntity Import = DIImportedEntity(Imports.getElement(i)); - DIDescriptor Entity = Import.getEntity(); + DIDescriptor Entity = Import.getEntity().resolve(TypeIdentifierMap); if (Entity.isType()) processType(DIType(Entity)); else if (Entity.isSubprogram()) @@ -1060,18 +1100,6 @@ void DebugInfoFinder::processScope(DIScope Scope) { } } -/// processLexicalBlock -void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { - DIScope Context = LB.getContext(); - if (Context.isLexicalBlock()) - return processLexicalBlock(DILexicalBlock(Context)); - else if (Context.isLexicalBlockFile()) { - DILexicalBlockFile DBF = DILexicalBlockFile(Context); - return processLexicalBlock(DILexicalBlock(DBF.getScope())); - } else - return processSubprogram(DISubprogram(Context)); -} - /// processSubprogram - Process DISubprogram. void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) @@ -1108,7 +1136,7 @@ void DebugInfoFinder::processDeclare(const Module &M, if (!NodesSeen.insert(DV)) return; processScope(DIVariable(N).getContext()); - processType(DIVariable(N).getType()); + processType(DIVariable(N).getType().resolve(TypeIdentifierMap)); } void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { @@ -1124,7 +1152,7 @@ void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { if (!NodesSeen.insert(DV)) return; processScope(DIVariable(N).getContext()); - processType(DIVariable(N).getType()); + processType(DIVariable(N).getType().resolve(TypeIdentifierMap)); } /// addType - Add type into Tys. @@ -1298,6 +1326,12 @@ void DIType::printInternal(raw_ostream &OS) const { OS << " [vector]"; if (isStaticMember()) OS << " [static]"; + + if (isLValueReference()) + OS << " [reference]"; + + if (isRValueReference()) + OS << " [rvalue reference]"; } void DIDerivedType::printInternal(raw_ostream &OS) const { @@ -1337,6 +1371,12 @@ void DISubprogram::printInternal(raw_ostream &OS) const { else if (isProtected()) OS << " [protected]"; + if (isLValueReference()) + OS << " [reference]"; + + if (isRValueReference()) + OS << " [rvalue reference]"; + StringRef Res = getName(); if (!Res.empty()) OS << " [" << Res << ']'; @@ -1439,7 +1479,7 @@ bool llvm::StripDebugInfo(Module &M) { // the module. if (Function *Declare = M.getFunction("llvm.dbg.declare")) { while (!Declare->use_empty()) { - CallInst *CI = cast<CallInst>(Declare->use_back()); + CallInst *CI = cast<CallInst>(Declare->user_back()); CI->eraseFromParent(); } Declare->eraseFromParent(); @@ -1448,7 +1488,7 @@ bool llvm::StripDebugInfo(Module &M) { if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { while (!DbgVal->use_empty()) { - CallInst *CI = cast<CallInst>(DbgVal->use_back()); + CallInst *CI = cast<CallInst>(DbgVal->user_back()); CI->eraseFromParent(); } DbgVal->eraseFromParent(); @@ -1486,3 +1526,23 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { return 0; return cast<ConstantInt>(Val)->getZExtValue(); } + +llvm::DenseMap<const llvm::Function *, llvm::DISubprogram> +llvm::makeSubprogramMap(const Module &M) { + DenseMap<const Function *, DISubprogram> R; + + NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); + if (!CU_Nodes) + return R; + + for (MDNode *N : CU_Nodes->operands()) { + DICompileUnit CUNode(N); + DIArray SPs = CUNode.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { + DISubprogram SP(SPs.getElement(i)); + if (Function *F = SP.getFunction()) + R.insert(std::make_pair(F, SP)); + } + } + return R; +} diff --git a/contrib/llvm/lib/IR/DebugLoc.cpp b/contrib/llvm/lib/IR/DebugLoc.cpp index c57b5a3..e8bdcce 100644 --- a/contrib/llvm/lib/IR/DebugLoc.cpp +++ b/contrib/llvm/lib/IR/DebugLoc.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/DebugLoc.h" +#include "llvm/IR/DebugLoc.h" #include "LLVMContextImpl.h" #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/DebugInfo.h" +#include "llvm/IR/DebugInfo.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -18,7 +18,7 @@ using namespace llvm; //===----------------------------------------------------------------------===// MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const { - if (ScopeIdx == 0) return 0; + if (ScopeIdx == 0) return nullptr; if (ScopeIdx > 0) { // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at @@ -37,7 +37,7 @@ MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const { MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const { // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at // position specified. Zero is invalid. - if (ScopeIdx >= 0) return 0; + if (ScopeIdx >= 0) return nullptr; // Otherwise, the index is in the ScopeInlinedAtRecords array. assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() && @@ -49,7 +49,7 @@ MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const { void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, const LLVMContext &Ctx) const { if (ScopeIdx == 0) { - Scope = IA = 0; + Scope = IA = nullptr; return; } @@ -59,7 +59,7 @@ void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() && "Invalid ScopeIdx!"); Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get(); - IA = 0; + IA = nullptr; return; } @@ -70,14 +70,34 @@ void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, IA = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get(); } +MDNode *DebugLoc::getScopeNode(const LLVMContext &Ctx) const { + if (MDNode *InlinedAt = getInlinedAt(Ctx)) + return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(Ctx); + return getScope(Ctx); +} + +DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const { + const MDNode *Scope = getScopeNode(Ctx); + DISubprogram SP = getDISubprogram(Scope); + if (SP.isSubprogram()) { + // Check for number of operands since the compatibility is + // cheap here. FIXME: Name the magic constant. + if (SP->getNumOperands() > 19) + return DebugLoc::get(SP.getScopeLineNumber(), 0, SP); + else + return DebugLoc::get(SP.getLineNumber(), 0, SP); + } + + return DebugLoc(); +} DebugLoc DebugLoc::get(unsigned Line, unsigned Col, MDNode *Scope, MDNode *InlinedAt) { DebugLoc Result; // If no scope is available, this is an unknown location. - if (Scope == 0) return Result; - + if (!Scope) return Result; + // Saturate line and col to "unknown". if (Col > 255) Col = 0; if (Line >= (1 << 24)) Line = 0; @@ -86,7 +106,7 @@ DebugLoc DebugLoc::get(unsigned Line, unsigned Col, LLVMContext &Ctx = Scope->getContext(); // If there is no inlined-at location, use the ScopeRecords array. - if (InlinedAt == 0) + if (!InlinedAt) Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0); else Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope, @@ -96,9 +116,9 @@ DebugLoc DebugLoc::get(unsigned Line, unsigned Col, } /// getAsMDNode - This method converts the compressed DebugLoc node into a -/// DILocation compatible MDNode. +/// DILocation-compatible MDNode. MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const { - if (isUnknown()) return 0; + if (isUnknown()) return nullptr; MDNode *Scope, *IA; getScopeAndInlinedAt(Scope, IA, Ctx); @@ -117,7 +137,7 @@ MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const { DebugLoc DebugLoc::getFromDILocation(MDNode *N) { DILocation Loc(N); MDNode *Scope = Loc.getScope(); - if (Scope == 0) return DebugLoc(); + if (!Scope) return DebugLoc(); return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope, Loc.getOrigLocation()); } @@ -126,8 +146,9 @@ DebugLoc DebugLoc::getFromDILocation(MDNode *N) { DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) { DILexicalBlock LexBlock(N); MDNode *Scope = LexBlock.getContext(); - if (Scope == 0) return DebugLoc(); - return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope, NULL); + if (!Scope) return DebugLoc(); + return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope, + nullptr); } void DebugLoc::dump(const LLVMContext &Ctx) const { @@ -146,6 +167,28 @@ void DebugLoc::dump(const LLVMContext &Ctx) const { #endif } +void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const { + if (!isUnknown()) { + // Print source line info. + DIScope Scope(getScope(Ctx)); + assert((!Scope || Scope.isScope()) && + "Scope of a DebugLoc should be null or a DIScope."); + if (Scope) + OS << Scope.getFilename(); + else + OS << "<unknown>"; + OS << ':' << getLine(); + if (getCol() != 0) + OS << ':' << getCol(); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); + if (!InlinedAtDL.isUnknown()) { + OS << " @[ "; + InlinedAtDL.print(Ctx, OS); + OS << " ]"; + } + } +} + //===----------------------------------------------------------------------===// // DenseMap specialization //===----------------------------------------------------------------------===// @@ -214,7 +257,7 @@ void DebugRecVH::deleted() { // If this is a non-canonical reference, just drop the value to null, we know // it doesn't have a map entry. if (Idx == 0) { - setValPtr(0); + setValPtr(nullptr); return; } @@ -225,7 +268,7 @@ void DebugRecVH::deleted() { assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!"); Ctx->ScopeRecordIdx.erase(Cur); // Reset this VH to null and we're done. - setValPtr(0); + setValPtr(nullptr); Idx = 0; return; } @@ -239,7 +282,7 @@ void DebugRecVH::deleted() { MDNode *OldScope = Entry.first.get(); MDNode *OldInlinedAt = Entry.second.get(); - assert(OldScope != 0 && OldInlinedAt != 0 && + assert(OldScope && OldInlinedAt && "Entry should be non-canonical if either val dropped to null"); // Otherwise, we do have an entry in it, nuke it and we're done. @@ -249,7 +292,7 @@ void DebugRecVH::deleted() { // Reset this VH to null. Drop both 'Idx' values to null to indicate that // we're in non-canonical form now. - setValPtr(0); + setValPtr(nullptr); Entry.first.Idx = Entry.second.Idx = 0; } @@ -257,8 +300,8 @@ void DebugRecVH::allUsesReplacedWith(Value *NewVa) { // If being replaced with a non-mdnode value (e.g. undef) handle this as if // the mdnode got deleted. MDNode *NewVal = dyn_cast<MDNode>(NewVa); - if (NewVal == 0) return deleted(); - + if (!NewVal) return deleted(); + // If this is a non-canonical reference, just change it, we know it already // doesn't have a map entry. if (Idx == 0) { @@ -293,7 +336,7 @@ void DebugRecVH::allUsesReplacedWith(Value *NewVa) { MDNode *OldScope = Entry.first.get(); MDNode *OldInlinedAt = Entry.second.get(); - assert(OldScope != 0 && OldInlinedAt != 0 && + assert(OldScope && OldInlinedAt && "Entry should be non-canonical if either val dropped to null"); // Otherwise, we do have an entry in it, nuke it and we're done. diff --git a/contrib/llvm/lib/IR/DiagnosticInfo.cpp b/contrib/llvm/lib/IR/DiagnosticInfo.cpp new file mode 100644 index 0000000..37cce2b --- /dev/null +++ b/contrib/llvm/lib/IR/DiagnosticInfo.cpp @@ -0,0 +1,208 @@ +//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the different classes involved in low level diagnostics. +// +// Diagnostics reporting is still done as part of the LLVMContext. +//===----------------------------------------------------------------------===// + +#include "LLVMContextImpl.h" +#include "llvm/ADT/Twine.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Regex.h" +#include <string> + +using namespace llvm; + +namespace { + +/// \brief Regular expression corresponding to the value given in one of the +/// -pass-remarks* command line flags. Passes whose name matches this regexp +/// will emit a diagnostic when calling the associated diagnostic function +/// (emitOptimizationRemark, emitOptimizationRemarkMissed or +/// emitOptimizationRemarkAnalysis). +struct PassRemarksOpt { + std::shared_ptr<Regex> Pattern; + + void operator=(const std::string &Val) { + // Create a regexp object to match pass names for emitOptimizationRemark. + if (!Val.empty()) { + Pattern = std::make_shared<Regex>(Val); + std::string RegexError; + if (!Pattern->isValid(RegexError)) + report_fatal_error("Invalid regular expression '" + Val + + "' in -pass-remarks: " + RegexError, + false); + } + }; +}; + +static PassRemarksOpt PassRemarksOptLoc; +static PassRemarksOpt PassRemarksMissedOptLoc; +static PassRemarksOpt PassRemarksAnalysisOptLoc; + +// -pass-remarks +// Command line flag to enable emitOptimizationRemark() +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> +PassRemarks("pass-remarks", cl::value_desc("pattern"), + cl::desc("Enable optimization remarks from passes whose name match " + "the given regular expression"), + cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired, + cl::ZeroOrMore); + +// -pass-remarks-missed +// Command line flag to enable emitOptimizationRemarkMissed() +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed( + "pass-remarks-missed", cl::value_desc("pattern"), + cl::desc("Enable missed optimization remarks from passes whose name match " + "the given regular expression"), + cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired, + cl::ZeroOrMore); + +// -pass-remarks-analysis +// Command line flag to enable emitOptimizationRemarkAnalysis() +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> +PassRemarksAnalysis( + "pass-remarks-analysis", cl::value_desc("pattern"), + cl::desc( + "Enable optimization analysis remarks from passes whose name match " + "the given regular expression"), + cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired, + cl::ZeroOrMore); +} + +int llvm::getNextAvailablePluginDiagnosticKind() { + static sys::cas_flag PluginKindID = DK_FirstPluginKind; + return (int)sys::AtomicIncrement(&PluginKindID); +} + +DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I, + const Twine &MsgStr, + DiagnosticSeverity Severity) + : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), + Instr(&I) { + if (const MDNode *SrcLoc = I.getMetadata("srcloc")) { + if (SrcLoc->getNumOperands() != 0) + if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0))) + LocCookie = CI->getZExtValue(); + } +} + +void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const { + DP << getMsgStr(); + if (getLocCookie()) + DP << " at line " << getLocCookie(); +} + +void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const { + DP << "stack size limit exceeded (" << getStackSize() << ") in " + << getFunction(); +} + +void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const { + DP << "ignoring debug info with an invalid version (" << getMetadataVersion() + << ") in " << getModule(); +} + +void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const { + if (getFileName() && getLineNum() > 0) + DP << getFileName() << ":" << getLineNum() << ": "; + else if (getFileName()) + DP << getFileName() << ": "; + DP << getMsg(); +} + +bool DiagnosticInfoOptimizationBase::isLocationAvailable() const { + return getDebugLoc().isUnknown() == false; +} + +void DiagnosticInfoOptimizationBase::getLocation(StringRef *Filename, + unsigned *Line, + unsigned *Column) const { + DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext())); + *Filename = DIL.getFilename(); + *Line = DIL.getLineNumber(); + *Column = DIL.getColumnNumber(); +} + +const std::string DiagnosticInfoOptimizationBase::getLocationStr() const { + StringRef Filename("<unknown>"); + unsigned Line = 0; + unsigned Column = 0; + if (isLocationAvailable()) + getLocation(&Filename, &Line, &Column); + return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str(); +} + +void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const { + DP << getLocationStr() << ": " << getMsg(); +} + +bool DiagnosticInfoOptimizationRemark::isEnabled() const { + return PassRemarksOptLoc.Pattern && + PassRemarksOptLoc.Pattern->match(getPassName()); +} + +bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const { + return PassRemarksMissedOptLoc.Pattern && + PassRemarksMissedOptLoc.Pattern->match(getPassName()); +} + +bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const { + return PassRemarksAnalysisOptLoc.Pattern && + PassRemarksAnalysisOptLoc.Pattern->match(getPassName()); +} + +void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, + const Function &Fn, const DebugLoc &DLoc, + const Twine &Msg) { + Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg)); +} + +void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg) { + Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg)); +} + +void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx, + const char *PassName, + const Function &Fn, + const DebugLoc &DLoc, + const Twine &Msg) { + Ctx.diagnose( + DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg)); +} + +bool DiagnosticInfoOptimizationFailure::isEnabled() const { + // Only print warnings. + return getSeverity() == DS_Warning; +} + +void llvm::emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, + const DebugLoc &DLoc, const Twine &Msg) { + Ctx.diagnose(DiagnosticInfoOptimizationFailure( + Fn, DLoc, Twine("loop not vectorized: " + Msg))); +} + +void llvm::emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, + const DebugLoc &DLoc, const Twine &Msg) { + Ctx.diagnose(DiagnosticInfoOptimizationFailure( + Fn, DLoc, Twine("loop not interleaved: " + Msg))); +} diff --git a/contrib/llvm/lib/IR/DiagnosticPrinter.cpp b/contrib/llvm/lib/IR/DiagnosticPrinter.cpp new file mode 100644 index 0000000..5e16026 --- /dev/null +++ b/contrib/llvm/lib/IR/DiagnosticPrinter.cpp @@ -0,0 +1,107 @@ +//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the a diagnostic printer relying on raw_ostream. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/Twine.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(char C) { + Stream << C; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned char C) { + Stream << C; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(signed char C) { + Stream << C; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(StringRef Str) { + Stream << Str; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const char *Str) { + Stream << Str; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<( + const std::string &Str) { + Stream << Str; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned long N) { + Stream << N; + return *this; +} +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<( + unsigned long long N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long long N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const void *P) { + Stream << P; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned int N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(int N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(double N) { + Stream << N; + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Twine &Str) { + Str.print(Stream); + return *this; +} + +// IR related types. +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Value &V) { + Stream << V.getName(); + return *this; +} + +DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Module &M) { + Stream << M.getModuleIdentifier(); + return *this; +} diff --git a/contrib/llvm/lib/IR/Dominators.cpp b/contrib/llvm/lib/IR/Dominators.cpp index a1160cd..d6649d6 100644 --- a/contrib/llvm/lib/IR/Dominators.cpp +++ b/contrib/llvm/lib/IR/Dominators.cpp @@ -14,17 +14,16 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/Dominators.h" +#include "llvm/IR/Dominators.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/DominatorInternals.h" -#include "llvm/Assembly/Writer.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/Instructions.h" -#include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GenericDomTreeConstruction.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> using namespace llvm; @@ -57,41 +56,23 @@ bool BasicBlockEdge::isSingleEdge() const { //===----------------------------------------------------------------------===// // // Provide public access to DominatorTree information. Implementation details -// can be found in DominatorInternals.h. +// can be found in Dominators.h, GenericDomTree.h, and +// GenericDomTreeConstruction.h. // //===----------------------------------------------------------------------===// TEMPLATE_INSTANTIATION(class llvm::DomTreeNodeBase<BasicBlock>); TEMPLATE_INSTANTIATION(class llvm::DominatorTreeBase<BasicBlock>); -char DominatorTree::ID = 0; -INITIALIZE_PASS(DominatorTree, "domtree", - "Dominator Tree Construction", true, true) - -bool DominatorTree::runOnFunction(Function &F) { - DT->recalculate(F); - return false; -} - -void DominatorTree::verifyAnalysis() const { - if (!VerifyDomInfo) return; - - Function &F = *getRoot()->getParent(); - - DominatorTree OtherDT; - OtherDT.getBase().recalculate(F); - if (compare(OtherDT)) { - errs() << "DominatorTree is not up to date!\nComputed:\n"; - print(errs()); - errs() << "\nActual:\n"; - OtherDT.print(errs()); - abort(); - } -} - -void DominatorTree::print(raw_ostream &OS, const Module *) const { - DT->print(OS); -} +#define LLVM_COMMA , +TEMPLATE_INSTANTIATION(void llvm::Calculate<Function LLVM_COMMA BasicBlock *>( + DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA + Function &F)); +TEMPLATE_INSTANTIATION( + void llvm::Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >( + DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT + LLVM_COMMA Function &F)); +#undef LLVM_COMMA // dominates - Return true if Def dominates a use in User. This performs // the special checks necessary if Def and User are in the same basic block. @@ -210,8 +191,7 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE, return true; } -bool DominatorTree::dominates(const BasicBlockEdge &BBE, - const Use &U) const { +bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const { // Assert that we have a single edge. We could handle them by simply // returning false, but since isSingleEdge is linear on the number of // edges, the callers can normally handle them more efficiently. @@ -234,8 +214,7 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE, return dominates(BBE, UseBB); } -bool DominatorTree::dominates(const Instruction *Def, - const Use &U) const { +bool DominatorTree::dominates(const Instruction *Def, const Use &U) const { Instruction *UserInst = cast<Instruction>(U.getUser()); const BasicBlock *DefBB = Def->getParent(); @@ -300,3 +279,44 @@ bool DominatorTree::isReachableFromEntry(const Use &U) const { // Everything else uses their operands in their own block. return isReachableFromEntry(I->getParent()); } + +void DominatorTree::verifyDomTree() const { + if (!VerifyDomInfo) + return; + + Function &F = *getRoot()->getParent(); + + DominatorTree OtherDT; + OtherDT.recalculate(F); + if (compare(OtherDT)) { + errs() << "DominatorTree is not up to date!\nComputed:\n"; + print(errs()); + errs() << "\nActual:\n"; + OtherDT.print(errs()); + abort(); + } +} + +//===----------------------------------------------------------------------===// +// DominatorTreeWrapperPass Implementation +//===----------------------------------------------------------------------===// +// +// The implementation details of the wrapper pass that holds a DominatorTree. +// +//===----------------------------------------------------------------------===// + +char DominatorTreeWrapperPass::ID = 0; +INITIALIZE_PASS(DominatorTreeWrapperPass, "domtree", + "Dominator Tree Construction", true, true) + +bool DominatorTreeWrapperPass::runOnFunction(Function &F) { + DT.recalculate(F); + return false; +} + +void DominatorTreeWrapperPass::verifyAnalysis() const { DT.verifyDomTree(); } + +void DominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const { + DT.print(OS); +} + diff --git a/contrib/llvm/lib/IR/Function.cpp b/contrib/llvm/lib/IR/Function.cpp index e8a2402..de59b26 100644 --- a/contrib/llvm/lib/IR/Function.cpp +++ b/contrib/llvm/lib/IR/Function.cpp @@ -18,13 +18,13 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/InstIterator.h" -#include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/RWMutex.h" #include "llvm/Support/StringPool.h" @@ -44,7 +44,7 @@ void Argument::anchor() { } Argument::Argument(Type *Ty, const Twine &Name, Function *Par) : Value(Ty, Value::ArgumentVal) { - Parent = 0; + Parent = nullptr; // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -76,6 +76,20 @@ unsigned Argument::getArgNo() const { return ArgIdx; } +/// hasNonNullAttr - Return true if this argument has the nonnull attribute on +/// it in its containing function. Also returns true if at least one byte is +/// known to be dereferenceable and the pointer is in addrspace(0). +bool Argument::hasNonNullAttr() const { + if (!getType()->isPointerTy()) return false; + if (getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::NonNull)) + return true; + else if (getDereferenceableBytes() > 0 && + getType()->getPointerAddressSpace() == 0) + return true; + return false; +} + /// hasByValAttr - Return true if this argument has the byval attribute on it /// in its containing function. bool Argument::hasByValAttr() const { @@ -84,12 +98,33 @@ bool Argument::hasByValAttr() const { hasAttribute(getArgNo()+1, Attribute::ByVal); } +/// \brief Return true if this argument has the inalloca attribute on it in +/// its containing function. +bool Argument::hasInAllocaAttr() const { + if (!getType()->isPointerTy()) return false; + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::InAlloca); +} + +bool Argument::hasByValOrInAllocaAttr() const { + if (!getType()->isPointerTy()) return false; + AttributeSet Attrs = getParent()->getAttributes(); + return Attrs.hasAttribute(getArgNo() + 1, Attribute::ByVal) || + Attrs.hasAttribute(getArgNo() + 1, Attribute::InAlloca); +} + unsigned Argument::getParamAlignment() const { assert(getType()->isPointerTy() && "Only pointers have alignments"); return getParent()->getParamAlignment(getArgNo()+1); } +uint64_t Argument::getDereferenceableBytes() const { + assert(getType()->isPointerTy() && + "Only pointers have dereferenceable bytes"); + return getParent()->getDereferenceableBytes(getArgNo()+1); +} + /// hasNestAttr - Return true if this argument has the nest attribute on /// it in its containing function. bool Argument::hasNestAttr() const { @@ -194,8 +229,8 @@ void Function::eraseFromParent() { Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name, Module *ParentModule) - : GlobalValue(PointerType::getUnqual(Ty), - Value::FunctionVal, 0, 0, Linkage, name) { + : GlobalObject(PointerType::getUnqual(Ty), + Value::FunctionVal, nullptr, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && "invalid return type"); SymTab = new ValueSymbolTable(); @@ -278,7 +313,7 @@ void Function::dropAllReferences() { BasicBlocks.begin()->eraseFromParent(); // Prefix data is stored in a side table. - setPrefixData(0); + setPrefixData(nullptr); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -333,10 +368,10 @@ void Function::clearGC() { GCNames->erase(this); if (GCNames->empty()) { delete GCNames; - GCNames = 0; + GCNames = nullptr; if (GCNamePool->empty()) { delete GCNamePool; - GCNamePool = 0; + GCNamePool = nullptr; } } } @@ -346,7 +381,7 @@ void Function::clearGC() { /// create a Function) from the Function Src to this one. void Function::copyAttributesFrom(const GlobalValue *Src) { assert(isa<Function>(Src) && "Expected a Function!"); - GlobalValue::copyAttributesFrom(Src); + GlobalObject::copyAttributesFrom(Src); const Function *SrcF = cast<Function>(Src); setCallingConv(SrcF->getCallingConv()); setAttributes(SrcF->getAttributes()); @@ -357,7 +392,7 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { if (SrcF->hasPrefixData()) setPrefixData(SrcF->getPrefixData()); else - setPrefixData(0); + setPrefixData(nullptr); } /// getIntrinsicID - This method returns the ID number of the specified @@ -451,11 +486,12 @@ enum IIT_Info { IIT_STRUCT3 = 20, IIT_STRUCT4 = 21, IIT_STRUCT5 = 22, - IIT_EXTEND_VEC_ARG = 23, - IIT_TRUNC_VEC_ARG = 24, + IIT_EXTEND_ARG = 23, + IIT_TRUNC_ARG = 24, IIT_ANYPTR = 25, IIT_V1 = 26, - IIT_VARARG = 27 + IIT_VARARG = 27, + IIT_HALF_VEC_ARG = 28 }; @@ -541,15 +577,21 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo)); return; } - case IIT_EXTEND_VEC_ARG: { + case IIT_EXTEND_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument, + ArgInfo)); + return; + } + case IIT_TRUNC_ARG: { unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); - OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendVecArgument, + OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo)); return; } - case IIT_TRUNC_VEC_ARG: { + case IIT_HALF_VEC_ARG: { unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); - OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncVecArgument, + OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument, ArgInfo)); return; } @@ -641,12 +683,24 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos, case IITDescriptor::Argument: return Tys[D.getArgumentNumber()]; - case IITDescriptor::ExtendVecArgument: - return VectorType::getExtendedElementVectorType(cast<VectorType>( - Tys[D.getArgumentNumber()])); + case IITDescriptor::ExtendArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast<VectorType>(Ty)) + return VectorType::getExtendedElementVectorType(VTy); - case IITDescriptor::TruncVecArgument: - return VectorType::getTruncatedElementVectorType(cast<VectorType>( + return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth()); + } + case IITDescriptor::TruncArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast<VectorType>(Ty)) + return VectorType::getTruncatedElementVectorType(VTy); + + IntegerType *ITy = cast<IntegerType>(Ty); + assert(ITy->getBitWidth() % 2 == 0); + return IntegerType::get(Context, ITy->getBitWidth() / 2); + } + case IITDescriptor::HalfVecArgument: + return VectorType::getHalfElementsVectorType(cast<VectorType>( Tys[D.getArgumentNumber()])); } llvm_unreachable("unhandled"); @@ -693,18 +747,23 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { #include "llvm/IR/Intrinsics.gen" #undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN +// This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method. +#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN +#include "llvm/IR/Intrinsics.gen" +#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN + /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) { - const User *U = *I; - if (isa<BlockAddress>(U)) + for (const Use &U : uses()) { + const User *FU = U.getUser(); + if (isa<BlockAddress>(FU)) continue; - if (!isa<CallInst>(U) && !isa<InvokeInst>(U)) - return PutOffender ? (*PutOffender = U, true) : true; - ImmutableCallSite CS(cast<Instruction>(U)); - if (!CS.isCallee(I)) - return PutOffender ? (*PutOffender = U, true) : true; + if (!isa<CallInst>(FU) && !isa<InvokeInst>(FU)) + return PutOffender ? (*PutOffender = FU, true) : true; + ImmutableCallSite CS(cast<Instruction>(FU)); + if (!CS.isCallee(&U)) + return PutOffender ? (*PutOffender = FU, true) : true; } return false; } @@ -716,8 +775,8 @@ bool Function::isDefTriviallyDead() const { return false; // Check if the function is used by anything other than a blockaddress. - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) - if (!isa<BlockAddress>(*I)) + for (const User *U : users()) + if (!isa<BlockAddress>(U)) return false; return true; @@ -728,10 +787,8 @@ bool Function::isDefTriviallyDead() const { bool Function::callsFunctionThatReturnsTwice() const { for (const_inst_iterator I = inst_begin(this), E = inst_end(this); I != E; ++I) { - const CallInst* callInst = dyn_cast<CallInst>(&*I); - if (!callInst) - continue; - if (callInst->canReturnTwice()) + ImmutableCallSite CS(&*I); + if (CS && CS.hasFnAttr(Attribute::ReturnsTwice)) return true; } diff --git a/contrib/llvm/lib/IR/GCOV.cpp b/contrib/llvm/lib/IR/GCOV.cpp index f0f8c7d..1667401 100644 --- a/contrib/llvm/lib/IR/GCOV.cpp +++ b/contrib/llvm/lib/IR/GCOV.cpp @@ -1,4 +1,4 @@ -//===- GCOVr.cpp - LLVM coverage tool -------------------------------------===// +//===- GCOV.cpp - LLVM coverage tool --------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -12,90 +12,95 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Debug.h" #include "llvm/Support/GCOV.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/MemoryObject.h" -#include "llvm/Support/system_error.h" +#include "llvm/Support/Path.h" +#include <algorithm> +#include <system_error> using namespace llvm; //===----------------------------------------------------------------------===// // GCOVFile implementation. -/// ~GCOVFile - Delete GCOVFile and its content. -GCOVFile::~GCOVFile() { - DeleteContainerPointers(Functions); -} +/// readGCNO - Read GCNO buffer. +bool GCOVFile::readGCNO(GCOVBuffer &Buffer) { + if (!Buffer.readGCNOFormat()) return false; + if (!Buffer.readGCOVVersion(Version)) return false; -/// isGCDAFile - Return true if Format identifies a .gcda file. -static bool isGCDAFile(GCOV::GCOVFormat Format) { - return Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404; -} + if (!Buffer.readInt(Checksum)) return false; + while (true) { + if (!Buffer.readFunctionTag()) break; + auto GFun = make_unique<GCOVFunction>(*this); + if (!GFun->readGCNO(Buffer, Version)) + return false; + Functions.push_back(std::move(GFun)); + } -/// isGCNOFile - Return true if Format identifies a .gcno file. -static bool isGCNOFile(GCOV::GCOVFormat Format) { - return Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404; + GCNOInitialized = true; + return true; } -/// read - Read GCOV buffer. -bool GCOVFile::read(GCOVBuffer &Buffer) { - GCOV::GCOVFormat Format = Buffer.readGCOVFormat(); - if (Format == GCOV::InvalidGCOV) +/// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be +/// called after readGCNO(). +bool GCOVFile::readGCDA(GCOVBuffer &Buffer) { + assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()"); + if (!Buffer.readGCDAFormat()) return false; + GCOV::GCOVVersion GCDAVersion; + if (!Buffer.readGCOVVersion(GCDAVersion)) return false; + if (Version != GCDAVersion) { + errs() << "GCOV versions do not match.\n"; return false; + } - if (isGCNOFile(Format)) { - while (true) { - if (!Buffer.readFunctionTag()) break; - GCOVFunction *GFun = new GCOVFunction(); - if (!GFun->read(Buffer, Format)) - return false; - Functions.push_back(GFun); - } + uint32_t GCDAChecksum; + if (!Buffer.readInt(GCDAChecksum)) return false; + if (Checksum != GCDAChecksum) { + errs() << "File checksums do not match: " << Checksum << " != " + << GCDAChecksum << ".\n"; + return false; } - 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; + 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]->readGCDA(Buffer, Version)) + 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 to dbgs() for debugging purposes. -void GCOVFile::dump() { - for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) - (*I)->dump(); +void GCOVFile::dump() const { + for (const auto &FPtr : Functions) + FPtr->dump(); } /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVFile::collectLineCounts(FileInfo &FI) { - for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) - (*I)->collectLineCounts(FI); + for (const auto &FPtr : Functions) + FPtr->collectLineCounts(FI); FI.setRunCount(RunCount); FI.setProgramCount(ProgramCount); } @@ -103,57 +108,24 @@ void GCOVFile::collectLineCounts(FileInfo &FI) { //===----------------------------------------------------------------------===// // GCOVFunction implementation. -/// ~GCOVFunction - Delete GCOVFunction and its content. -GCOVFunction::~GCOVFunction() { - DeleteContainerPointers(Blocks); -} - -/// 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) { +/// readGCNO - Read a function from the GCNO buffer. Return false if an error +/// occurs. +bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { 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 - - if (!Buff.readString(Name)) return false; - - if (Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404) - if (!Buff.readString(Filename)) return false; - - if (Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404) { - if (!Buff.readArcTag()) { - errs() << "Arc tag not found.\n"; + if (!Buff.readInt(Checksum)) return false; + if (Version != GCOV::V402) { + uint32_t CfgChecksum; + if (!Buff.readInt(CfgChecksum)) return false; + if (Parent.getChecksum() != CfgChecksum) { + errs() << "File checksums do not match: " << Parent.getChecksum() + << " != " << CfgChecksum << " in (" << Name << ").\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; } - + if (!Buff.readString(Name)) return false; + if (!Buff.readString(Filename)) return false; if (!Buff.readInt(LineNumber)) return false; // read blocks. @@ -165,7 +137,7 @@ bool GCOVFunction::read(GCOVBuffer &Buff, GCOV::GCOVFormat Format) { 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)); + Blocks.push_back(make_unique<GCOVBlock>(*this, i)); } // read edges. @@ -176,13 +148,17 @@ bool GCOVFunction::read(GCOVBuffer &Buff, GCOV::GCOVFormat Format) { uint32_t BlockNo; if (!Buff.readInt(BlockNo)) return false; if (BlockNo >= BlockCount) { - errs() << "Unexpected block number.\n"; + errs() << "Unexpected block number: " << BlockNo << " (in " << Name + << ").\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); + Edges.push_back(make_unique<GCOVEdge>(*Blocks[BlockNo], *Blocks[Dst])); + GCOVEdge *Edge = Edges.back().get(); + Blocks[BlockNo]->addDstEdge(Edge); + Blocks[Dst]->addSrcEdge(Edge); if (!Buff.readInt(Dummy)) return false; // Edge flag } } @@ -190,50 +166,154 @@ bool GCOVFunction::read(GCOVBuffer &Buff, GCOV::GCOVFormat Format) { // read line table. while (Buff.readLineTag()) { uint32_t LineTableLength; + // Read the length of this line table. if (!Buff.readInt(LineTableLength)) return false; uint32_t EndPos = Buff.getCursor() + LineTableLength*4; uint32_t BlockNo; + // Read the block number this table is associated with. if (!Buff.readInt(BlockNo)) return false; if (BlockNo >= BlockCount) { - errs() << "Unexpected block number.\n"; + errs() << "Unexpected block number: " << BlockNo << " (in " << Name + << ").\n"; return false; } - GCOVBlock *Block = Blocks[BlockNo]; - if (!Buff.readInt(Dummy)) return false; // flag - while (Buff.getCursor() != (EndPos - 4)) { + GCOVBlock &Block = *Blocks[BlockNo]; + // Read the word that pads the beginning of the line table. This may be a + // flag of some sort, but seems to always be zero. + if (!Buff.readInt(Dummy)) return false; + + // Line information starts here and continues up until the last word. + if (Buff.getCursor() != (EndPos - sizeof(uint32_t))) { StringRef F; + // Read the source file name. if (!Buff.readString(F)) return false; - if (F != Filename) { - errs() << "Multiple sources for a single basic block.\n"; + if (Filename != F) { + errs() << "Multiple sources for a single basic block: " << Filename + << " != " << F << " (in " << Name << ").\n"; return false; } - if (Buff.getCursor() == (EndPos - 4)) break; - while (true) { + // Read lines up to, but not including, the null terminator. + while (Buff.getCursor() < (EndPos - 2 * sizeof(uint32_t))) { uint32_t Line; if (!Buff.readInt(Line)) return false; - if (!Line) break; - Block->addLine(Line); + // Line 0 means this instruction was injected by the compiler. Skip it. + if (!Line) continue; + Block.addLine(Line); + } + // Read the null terminator. + if (!Buff.readInt(Dummy)) return false; + } + // The last word is either a flag or padding, it isn't clear which. Skip + // over it. + if (!Buff.readInt(Dummy)) return false; + } + return true; +} + +/// readGCDA - Read a function from the GCDA buffer. Return false if an error +/// occurs. +bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { + uint32_t Dummy; + if (!Buff.readInt(Dummy)) return false; // Function header length + + uint32_t GCDAIdent; + if (!Buff.readInt(GCDAIdent)) return false; + if (Ident != GCDAIdent) { + errs() << "Function identifiers do not match: " << Ident << " != " + << GCDAIdent << " (in " << Name << ").\n"; + return false; + } + + uint32_t GCDAChecksum; + if (!Buff.readInt(GCDAChecksum)) return false; + if (Checksum != GCDAChecksum) { + errs() << "Function checksums do not match: " << Checksum << " != " + << GCDAChecksum << " (in " << Name << ").\n"; + return false; + } + + uint32_t CfgChecksum; + if (Version != GCOV::V402) { + if (!Buff.readInt(CfgChecksum)) return false; + if (Parent.getChecksum() != CfgChecksum) { + errs() << "File checksums do not match: " << Parent.getChecksum() + << " != " << CfgChecksum << " (in " << Name << ").\n"; + return false; + } + } + + StringRef GCDAName; + if (!Buff.readString(GCDAName)) return false; + if (Name != GCDAName) { + errs() << "Function names do not match: " << Name << " != " << GCDAName + << ".\n"; + return false; + } + + if (!Buff.readArcTag()) { + errs() << "Arc tag not found (in " << Name << ").\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 BlockNo = 0; Count > 0; ++BlockNo) { + // The last block is always reserved for exit block + if (BlockNo >= Blocks.size()-1) { + errs() << "Unexpected number of edges (in " << Name << ").\n"; + return false; + } + GCOVBlock &Block = *Blocks[BlockNo]; + for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End; + ++EdgeNo) { + if (Count == 0) { + errs() << "Unexpected number of edges (in " << Name << ").\n"; + return false; } + uint64_t ArcCount; + if (!Buff.readInt64(ArcCount)) return false; + Block.addCount(EdgeNo, ArcCount); + --Count; } - if (!Buff.readInt(Dummy)) return false; // flag + Block.sortDstEdges(); } return true; } +/// getEntryCount - Get the number of times the function was called by +/// retrieving the entry block's count. +uint64_t GCOVFunction::getEntryCount() const { + return Blocks.front()->getCount(); +} + +/// getExitCount - Get the number of times the function returned by retrieving +/// the exit block's count. +uint64_t GCOVFunction::getExitCount() const { + return Blocks.back()->getCount(); +} + /// dump - Dump GCOVFunction content to dbgs() for debugging purposes. -void GCOVFunction::dump() { +void GCOVFunction::dump() const { dbgs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; - for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - (*I)->dump(); + for (const auto &Block : Blocks) + Block->dump(); } /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVFunction::collectLineCounts(FileInfo &FI) { - for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - (*I)->collectLineCounts(FI); + // If the line number is zero, this is a function that doesn't actually appear + // in the source file, so there isn't anything we can do with it. + if (LineNumber == 0) + return; + + for (const auto &Block : Blocks) + Block->collectLineCounts(FI); + FI.addFunctionLine(Filename, LineNumber, this); } //===----------------------------------------------------------------------===// @@ -241,31 +321,60 @@ void GCOVFunction::collectLineCounts(FileInfo &FI) { /// ~GCOVBlock - Delete GCOVBlock and its content. GCOVBlock::~GCOVBlock() { - Edges.clear(); + SrcEdges.clear(); + DstEdges.clear(); Lines.clear(); } +/// addCount - Add to block counter while storing the edge count. If the +/// destination has no outgoing edges, also update that block's count too. +void GCOVBlock::addCount(size_t DstEdgeNo, uint64_t N) { + assert(DstEdgeNo < DstEdges.size()); // up to caller to ensure EdgeNo is valid + DstEdges[DstEdgeNo]->Count = N; + Counter += N; + if (!DstEdges[DstEdgeNo]->Dst.getNumDstEdges()) + DstEdges[DstEdgeNo]->Dst.Counter += N; +} + +/// sortDstEdges - Sort destination edges by block number, nop if already +/// sorted. This is required for printing branch info in the correct order. +void GCOVBlock::sortDstEdges() { + if (!DstEdgesAreSorted) { + SortDstEdgesFunctor SortEdges; + std::stable_sort(DstEdges.begin(), DstEdges.end(), SortEdges); + } +} + /// collectLineCounts - Collect line counts. This must be used after /// reading .gcno and .gcda files. void GCOVBlock::collectLineCounts(FileInfo &FI) { for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), E = Lines.end(); I != E; ++I) - FI.addLineCount(Parent.getFilename(), *I, Counter); + FI.addBlockLine(Parent.getFilename(), *I, this); } /// dump - Dump GCOVBlock content to dbgs() for debugging purposes. -void GCOVBlock::dump() { +void GCOVBlock::dump() const { dbgs() << "Block : " << Number << " Counter : " << Counter << "\n"; - if (!Edges.empty()) { - dbgs() << "\tEdges : "; - for (SmallVectorImpl<uint32_t>::iterator I = Edges.begin(), E = Edges.end(); - I != E; ++I) - dbgs() << (*I) << ","; + if (!SrcEdges.empty()) { + dbgs() << "\tSource Edges : "; + for (EdgeIterator I = SrcEdges.begin(), E = SrcEdges.end(); I != E; ++I) { + const GCOVEdge *Edge = *I; + dbgs() << Edge->Src.Number << " (" << Edge->Count << "), "; + } + dbgs() << "\n"; + } + if (!DstEdges.empty()) { + dbgs() << "\tDestination Edges : "; + for (EdgeIterator I = DstEdges.begin(), E = DstEdges.end(); I != E; ++I) { + const GCOVEdge *Edge = *I; + dbgs() << Edge->Dst.Number << " (" << Edge->Count << "), "; + } dbgs() << "\n"; } if (!Lines.empty()) { dbgs() << "\tLines : "; - for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(), + for (SmallVectorImpl<uint32_t>::const_iterator I = Lines.begin(), E = Lines.end(); I != E; ++I) dbgs() << (*I) << ","; dbgs() << "\n"; @@ -275,40 +384,387 @@ void GCOVBlock::dump() { //===----------------------------------------------------------------------===// // FileInfo implementation. +// Safe integer division, returns 0 if numerator is 0. +static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) { + if (!Numerator) + return 0; + return Numerator/Divisor; +} + +// This custom division function mimics gcov's branch ouputs: +// - Round to closest whole number +// - Only output 0% or 100% if it's exactly that value +static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) { + if (!Numerator) + return 0; + if (Numerator == Divisor) + return 100; + + uint8_t Res = (Numerator*100+Divisor/2) / Divisor; + if (Res == 0) + return 1; + if (Res == 100) + return 99; + return Res; +} + +struct formatBranchInfo { + formatBranchInfo(const GCOVOptions &Options, uint64_t Count, + uint64_t Total) : + Options(Options), Count(Count), Total(Total) {} + + void print(raw_ostream &OS) const { + if (!Total) + OS << "never executed"; + else if (Options.BranchCount) + OS << "taken " << Count; + else + OS << "taken " << branchDiv(Count, Total) << "%"; + } + + const GCOVOptions &Options; + uint64_t Count; + uint64_t Total; +}; + +static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) { + FBI.print(OS); + return OS; +} + +namespace { +class LineConsumer { + std::unique_ptr<MemoryBuffer> Buffer; + StringRef Remaining; +public: + LineConsumer(StringRef Filename) { + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = + MemoryBuffer::getFileOrSTDIN(Filename); + if (std::error_code EC = BufferOrErr.getError()) { + errs() << Filename << ": " << EC.message() << "\n"; + Remaining = ""; + } else { + Buffer = std::move(BufferOrErr.get()); + Remaining = Buffer->getBuffer(); + } + } + bool empty() { return Remaining.empty(); } + void printNext(raw_ostream &OS, uint32_t LineNum) { + StringRef Line; + if (empty()) + Line = "/*EOF*/"; + else + std::tie(Line, Remaining) = Remaining.split("\n"); + OS << format("%5u:", LineNum) << Line << "\n"; + } +}; +} + +/// Convert a path to a gcov filename. If PreservePaths is true, this +/// translates "/" to "#", ".." to "^", and drops ".", to match gcov. +static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) { + if (!PreservePaths) + return sys::path::filename(Filename).str(); + + // This behaviour is defined by gcov in terms of text replacements, so it's + // not likely to do anything useful on filesystems with different textual + // conventions. + llvm::SmallString<256> Result(""); + StringRef::iterator I, S, E; + for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) { + if (*I != '/') + continue; + + if (I - S == 1 && *S == '.') { + // ".", the current directory, is skipped. + } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') { + // "..", the parent directory, is replaced with "^". + Result.append("^#"); + } else { + if (S < I) + // Leave other components intact, + Result.append(S, I); + // And separate with "#". + Result.push_back('#'); + } + S = I + 1; + } + + if (S < I) + Result.append(S, I); + return Result.str(); +} + +std::string FileInfo::getCoveragePath(StringRef Filename, + StringRef MainFilename) { + if (Options.NoOutput) + // This is probably a bug in gcov, but when -n is specified, paths aren't + // mangled at all, and the -l and -p options are ignored. Here, we do the + // same. + return Filename; + + std::string CoveragePath; + if (Options.LongFileNames && !Filename.equals(MainFilename)) + CoveragePath = + mangleCoveragePath(MainFilename, Options.PreservePaths) + "##"; + CoveragePath += + mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov"; + return CoveragePath; +} + +std::unique_ptr<raw_ostream> +FileInfo::openCoveragePath(StringRef CoveragePath) { + if (Options.NoOutput) + return llvm::make_unique<raw_null_ostream>(); + + std::string ErrorInfo; + auto OS = llvm::make_unique<raw_fd_ostream>(CoveragePath.str().c_str(), + ErrorInfo, sys::fs::F_Text); + if (!ErrorInfo.empty()) { + errs() << ErrorInfo << "\n"; + return llvm::make_unique<raw_null_ostream>(); + } + return std::move(OS); +} + /// print - Print source files with collected line count information. -void FileInfo::print(raw_fd_ostream &OS, StringRef gcnoFile, - StringRef gcdaFile) { - for (StringMap<LineCounts>::iterator I = LineInfo.begin(), E = LineInfo.end(); - I != E; ++I) { +void FileInfo::print(StringRef MainFilename, StringRef GCNOFile, + StringRef GCDAFile) { + for (StringMap<LineData>::const_iterator I = LineInfo.begin(), + E = LineInfo.end(); I != E; ++I) { StringRef Filename = I->first(); + auto AllLines = LineConsumer(Filename); + + std::string CoveragePath = getCoveragePath(Filename, MainFilename); + std::unique_ptr<raw_ostream> S = openCoveragePath(CoveragePath); + raw_ostream &OS = *S; + OS << " -: 0:Source:" << Filename << "\n"; - OS << " -: 0:Graph:" << gcnoFile << "\n"; - OS << " -: 0:Data:" << gcdaFile << "\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->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 { + + const LineData &Line = I->second; + GCOVCoverage FileCoverage(Filename); + for (uint32_t LineIndex = 0; + LineIndex < Line.LastLine || !AllLines.empty(); ++LineIndex) { + if (Options.BranchInfo) { + FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex); + if (FuncsIt != Line.Functions.end()) + printFunctionSummary(OS, FuncsIt->second); + } + + BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex); + if (BlocksIt == Line.Blocks.end()) { + // No basic blocks are on this line. Not an executable line of code. OS << " -:"; + AllLines.printNext(OS, LineIndex + 1); + } else { + const BlockVector &Blocks = BlocksIt->second; + + // Add up the block counts to form line counts. + DenseMap<const GCOVFunction *, bool> LineExecs; + uint64_t LineCount = 0; + for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end(); + I != E; ++I) { + const GCOVBlock *Block = *I; + if (Options.AllBlocks) { + // Only take the highest block count for that line. + uint64_t BlockCount = Block->getCount(); + LineCount = LineCount > BlockCount ? LineCount : BlockCount; + } else { + // Sum up all of the block counts. + LineCount += Block->getCount(); + } + + if (Options.FuncCoverage) { + // This is a slightly convoluted way to most accurately gather line + // statistics for functions. Basically what is happening is that we + // don't want to count a single line with multiple blocks more than + // once. However, we also don't simply want to give the total line + // count to every function that starts on the line. Thus, what is + // happening here are two things: + // 1) Ensure that the number of logical lines is only incremented + // once per function. + // 2) If there are multiple blocks on the same line, ensure that the + // number of lines executed is incremented as long as at least + // one of the blocks are executed. + const GCOVFunction *Function = &Block->getParent(); + if (FuncCoverages.find(Function) == FuncCoverages.end()) { + std::pair<const GCOVFunction *, GCOVCoverage> + KeyValue(Function, GCOVCoverage(Function->getName())); + FuncCoverages.insert(KeyValue); + } + GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second; + + if (LineExecs.find(Function) == LineExecs.end()) { + if (Block->getCount()) { + ++FuncCoverage.LinesExec; + LineExecs[Function] = true; + } else { + LineExecs[Function] = false; + } + ++FuncCoverage.LogicalLines; + } else if (!LineExecs[Function] && Block->getCount()) { + ++FuncCoverage.LinesExec; + LineExecs[Function] = true; + } + } + } + + if (LineCount == 0) + OS << " #####:"; + else { + OS << format("%9" PRIu64 ":", LineCount); + ++FileCoverage.LinesExec; + } + ++FileCoverage.LogicalLines; + + AllLines.printNext(OS, LineIndex + 1); + + uint32_t BlockNo = 0; + uint32_t EdgeNo = 0; + for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end(); + I != E; ++I) { + const GCOVBlock *Block = *I; + + // Only print block and branch information at the end of the block. + if (Block->getLastLine() != LineIndex+1) + continue; + if (Options.AllBlocks) + printBlockInfo(OS, *Block, LineIndex, BlockNo); + if (Options.BranchInfo) { + size_t NumEdges = Block->getNumDstEdges(); + if (NumEdges > 1) + printBranchInfo(OS, *Block, FileCoverage, EdgeNo); + else if (Options.UncondBranch && NumEdges == 1) + printUncondBranchInfo(OS, EdgeNo, (*Block->dst_begin())->Count); + } + } } - std::pair<StringRef, StringRef> P = AllLines.split('\n'); - if (AllLines != P.first) - OS << format("%5u:", i+1) << P.first; - OS << "\n"; - AllLines = P.second; - ++i; } + FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage)); + } + + // FIXME: There is no way to detect calls given current instrumentation. + if (Options.FuncCoverage) + printFuncCoverage(); + printFileCoverage(); + return; +} + +/// printFunctionSummary - Print function and block summary. +void FileInfo::printFunctionSummary(raw_ostream &OS, + const FunctionVector &Funcs) const { + for (FunctionVector::const_iterator I = Funcs.begin(), E = Funcs.end(); + I != E; ++I) { + const GCOVFunction *Func = *I; + uint64_t EntryCount = Func->getEntryCount(); + uint32_t BlocksExec = 0; + for (GCOVFunction::BlockIterator I = Func->block_begin(), + E = Func->block_end(); I != E; ++I) { + const GCOVBlock &Block = **I; + if (Block.getNumDstEdges() && Block.getCount()) + ++BlocksExec; + } + + OS << "function " << Func->getName() << " called " << EntryCount + << " returned " << safeDiv(Func->getExitCount()*100, EntryCount) + << "% blocks executed " + << safeDiv(BlocksExec*100, Func->getNumBlocks()-1) << "%\n"; + } +} + +/// printBlockInfo - Output counts for each block. +void FileInfo::printBlockInfo(raw_ostream &OS, const GCOVBlock &Block, + uint32_t LineIndex, uint32_t &BlockNo) const { + if (Block.getCount() == 0) + OS << " $$$$$:"; + else + OS << format("%9" PRIu64 ":", Block.getCount()); + OS << format("%5u-block %2u\n", LineIndex+1, BlockNo++); +} + +/// printBranchInfo - Print conditional branch probabilities. +void FileInfo::printBranchInfo(raw_ostream &OS, const GCOVBlock &Block, + GCOVCoverage &Coverage, uint32_t &EdgeNo) { + SmallVector<uint64_t, 16> BranchCounts; + uint64_t TotalCounts = 0; + for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end(); + I != E; ++I) { + const GCOVEdge *Edge = *I; + BranchCounts.push_back(Edge->Count); + TotalCounts += Edge->Count; + if (Block.getCount()) ++Coverage.BranchesExec; + if (Edge->Count) ++Coverage.BranchesTaken; + ++Coverage.Branches; + + if (Options.FuncCoverage) { + const GCOVFunction *Function = &Block.getParent(); + GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second; + if (Block.getCount()) ++FuncCoverage.BranchesExec; + if (Edge->Count) ++FuncCoverage.BranchesTaken; + ++FuncCoverage.Branches; + } + } + + for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(), + E = BranchCounts.end(); I != E; ++I) { + OS << format("branch %2u ", EdgeNo++) + << formatBranchInfo(Options, *I, TotalCounts) << "\n"; + } +} + +/// printUncondBranchInfo - Print unconditional branch probabilities. +void FileInfo::printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo, + uint64_t Count) const { + OS << format("unconditional %2u ", EdgeNo++) + << formatBranchInfo(Options, Count, Count) << "\n"; +} + +// printCoverage - Print generic coverage info used by both printFuncCoverage +// and printFileCoverage. +void FileInfo::printCoverage(const GCOVCoverage &Coverage) const { + outs() << format("Lines executed:%.2f%% of %u\n", + double(Coverage.LinesExec)*100/Coverage.LogicalLines, + Coverage.LogicalLines); + if (Options.BranchInfo) { + if (Coverage.Branches) { + outs() << format("Branches executed:%.2f%% of %u\n", + double(Coverage.BranchesExec)*100/Coverage.Branches, + Coverage.Branches); + outs() << format("Taken at least once:%.2f%% of %u\n", + double(Coverage.BranchesTaken)*100/Coverage.Branches, + Coverage.Branches); + } else { + outs() << "No branches\n"; + } + outs() << "No calls\n"; // to be consistent with gcov + } +} + +// printFuncCoverage - Print per-function coverage info. +void FileInfo::printFuncCoverage() const { + for (FuncCoverageMap::const_iterator I = FuncCoverages.begin(), + E = FuncCoverages.end(); I != E; ++I) { + const GCOVCoverage &Coverage = I->second; + outs() << "Function '" << Coverage.Name << "'\n"; + printCoverage(Coverage); + outs() << "\n"; + } +} + +// printFileCoverage - Print per-file coverage info. +void FileInfo::printFileCoverage() const { + for (FileCoverageList::const_iterator I = FileCoverages.begin(), + E = FileCoverages.end(); I != E; ++I) { + const std::string &Filename = I->first; + const GCOVCoverage &Coverage = I->second; + outs() << "File '" << Coverage.Name << "'\n"; + printCoverage(Coverage); + if (!Options.NoOutput) + outs() << Coverage.Name << ":creating '" << Filename << "'\n"; + outs() << "\n"; } } diff --git a/contrib/llvm/lib/IR/GVMaterializer.cpp b/contrib/llvm/lib/IR/GVMaterializer.cpp index f77a9c9..706926d 100644 --- a/contrib/llvm/lib/IR/GVMaterializer.cpp +++ b/contrib/llvm/lib/IR/GVMaterializer.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/GVMaterializer.h" +#include "llvm/IR/GVMaterializer.h" using namespace llvm; GVMaterializer::~GVMaterializer() {} diff --git a/contrib/llvm/lib/IR/Globals.cpp b/contrib/llvm/lib/IR/Globals.cpp index da3b02a..244e3e4 100644 --- a/contrib/llvm/lib/IR/Globals.cpp +++ b/contrib/llvm/lib/IR/Globals.cpp @@ -18,9 +18,10 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/LeakDetector.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -40,6 +41,10 @@ void GlobalValue::Dematerialize() { getParent()->Dematerialize(this); } +const DataLayout *GlobalValue::getDataLayout() const { + return getParent()->getDataLayout(); +} + /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { @@ -49,20 +54,62 @@ void GlobalValue::destroyConstant() { /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalValue) from the GlobalValue Src to this one. void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { - setAlignment(Src->getAlignment()); - setSection(Src->getSection()); setVisibility(Src->getVisibility()); setUnnamedAddr(Src->hasUnnamedAddr()); + setDLLStorageClass(Src->getDLLStorageClass()); +} + +unsigned GlobalValue::getAlignment() const { + if (auto *GA = dyn_cast<GlobalAlias>(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return GO->getAlignment(); + + // FIXME: we should also be able to handle: + // Alias = Global + Offset + // Alias = Absolute + return 0; + } + return cast<GlobalObject>(this)->getAlignment(); } -void GlobalValue::setAlignment(unsigned Align) { +void GlobalObject::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); - Alignment = Log2_32(Align) + 1; + setGlobalValueSubClassData(Log2_32(Align) + 1); assert(getAlignment() == Align && "Alignment representation error!"); } +void GlobalObject::copyAttributesFrom(const GlobalValue *Src) { + const auto *GV = cast<GlobalObject>(Src); + GlobalValue::copyAttributesFrom(GV); + setAlignment(GV->getAlignment()); + setSection(GV->getSection()); +} + +const char *GlobalValue::getSection() const { + if (auto *GA = dyn_cast<GlobalAlias>(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return GO->getSection(); + return ""; + } + return cast<GlobalObject>(this)->getSection(); +} + +Comdat *GlobalValue::getComdat() { + if (auto *GA = dyn_cast<GlobalAlias>(this)) { + // In general we cannot compute this at the IR level, but we try. + if (const GlobalObject *GO = GA->getBaseObject()) + return const_cast<GlobalObject *>(GO)->getComdat(); + return nullptr; + } + return cast<GlobalObject>(this)->getComdat(); +} + +void GlobalObject::setSection(StringRef S) { Section = S; } + bool GlobalValue::isDeclaration() const { // Globals are definitions if they have an initializer. if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) @@ -76,22 +123,21 @@ bool GlobalValue::isDeclaration() const { assert(isa<GlobalAlias>(this)); return false; } - + //===----------------------------------------------------------------------===// // GlobalVariable Implementation //===----------------------------------------------------------------------===// GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, - const Twine &Name, ThreadLocalMode TLMode, - unsigned AddressSpace, + Constant *InitVal, const Twine &Name, + ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), - Value::GlobalVariableVal, - OperandTraits<GlobalVariable>::op_begin(this), - InitVal != 0, Link, Name), - isConstantGlobal(constant), threadLocalMode(TLMode), - isExternallyInitializedConstant(isExternallyInitialized) { + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits<GlobalVariable>::op_begin(this), + InitVal != nullptr, Link, Name), + isConstantGlobal(constant), + isExternallyInitializedConstant(isExternallyInitialized) { + setThreadLocalMode(TLMode); if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); @@ -103,24 +149,23 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, LinkageTypes Link, Constant *InitVal, - const Twine &Name, - GlobalVariable *Before, ThreadLocalMode TLMode, - unsigned AddressSpace, + const Twine &Name, GlobalVariable *Before, + ThreadLocalMode TLMode, unsigned AddressSpace, bool isExternallyInitialized) - : GlobalValue(PointerType::get(Ty, AddressSpace), - Value::GlobalVariableVal, - OperandTraits<GlobalVariable>::op_begin(this), - InitVal != 0, Link, Name), - isConstantGlobal(constant), threadLocalMode(TLMode), - isExternallyInitializedConstant(isExternallyInitialized) { + : GlobalObject(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + OperandTraits<GlobalVariable>::op_begin(this), + InitVal != nullptr, Link, Name), + isConstantGlobal(constant), + isExternallyInitializedConstant(isExternallyInitialized) { + setThreadLocalMode(TLMode); if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); Op<0>() = InitVal; } - + LeakDetector::addGarbageObject(this); - + if (Before) Before->getParent()->getGlobalList().insert(Before, this); else @@ -164,9 +209,9 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, } void GlobalVariable::setInitializer(Constant *InitVal) { - if (InitVal == 0) { + if (!InitVal) { if (hasInitializer()) { - Op<0>().set(0); + Op<0>().set(nullptr); NumOperands = 0; } } else { @@ -182,9 +227,9 @@ void GlobalVariable::setInitializer(Constant *InitVal) { /// create a GlobalVariable) from the GlobalVariable Src to this one. void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!"); - GlobalValue::copyAttributesFrom(Src); + GlobalObject::copyAttributesFrom(Src); const GlobalVariable *SrcVar = cast<GlobalVariable>(Src); - setThreadLocal(SrcVar->isThreadLocal()); + setThreadLocalMode(SrcVar->getThreadLocalMode()); } @@ -192,20 +237,47 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { // GlobalAlias Implementation //===----------------------------------------------------------------------===// -GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, - const Twine &Name, Constant* aliasee, +GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link, + const Twine &Name, Constant *Aliasee, Module *ParentModule) - : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { + : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal, + &Op<0>(), 1, Link, Name) { LeakDetector::addGarbageObject(this); - - if (aliasee) - assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); - Op<0>() = aliasee; + Op<0>() = Aliasee; if (ParentModule) ParentModule->getAliasList().push_back(this); } +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Link, const Twine &Name, + Constant *Aliasee, Module *ParentModule) { + return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule); +} + +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + Module *Parent) { + return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent); +} + +GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + GlobalValue *Aliasee) { + return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent()); +} + +GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, + GlobalValue *Aliasee) { + PointerType *PTy = Aliasee->getType(); + return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name, + Aliasee); +} + +GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) { + return create(Aliasee->getLinkage(), Name, Aliasee); +} + void GlobalAlias::setParent(Module *parent) { if (getParent()) LeakDetector::addGarbageObject(this); @@ -225,45 +297,5 @@ void GlobalAlias::eraseFromParent() { void GlobalAlias::setAliasee(Constant *Aliasee) { assert((!Aliasee || Aliasee->getType() == getType()) && "Alias and aliasee types should match!"); - setOperand(0, Aliasee); } - -GlobalValue *GlobalAlias::getAliasedGlobal() { - Constant *C = getAliasee(); - if (C == 0) return 0; - - if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) - return GV; - - ConstantExpr *CE = cast<ConstantExpr>(C); - assert((CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::GetElementPtr) && - "Unsupported aliasee"); - - return cast<GlobalValue>(CE->getOperand(0)); -} - -GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) { - SmallPtrSet<GlobalValue*, 3> Visited; - - // Check if we need to stop early. - if (stopOnWeak && mayBeOverridden()) - return this; - - GlobalValue *GV = getAliasedGlobal(); - Visited.insert(GV); - - // Iterate over aliasing chain, stopping on weak alias if necessary. - while (GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) { - if (stopOnWeak && GA->mayBeOverridden()) - break; - - GV = GA->getAliasedGlobal(); - - if (!Visited.insert(GV)) - return 0; - } - - return GV; -} diff --git a/contrib/llvm/lib/IR/IRPrintingPasses.cpp b/contrib/llvm/lib/IR/IRPrintingPasses.cpp new file mode 100644 index 0000000..c8a1747 --- /dev/null +++ b/contrib/llvm/lib/IR/IRPrintingPasses.cpp @@ -0,0 +1,127 @@ +//===--- IRPrintingPasses.cpp - Module and Function printing passes -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// PrintModulePass and PrintFunctionPass implementations. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +PrintModulePass::PrintModulePass() : OS(dbgs()) {} +PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner) + : OS(OS), Banner(Banner) {} + +PreservedAnalyses PrintModulePass::run(Module *M) { + OS << Banner << *M; + return PreservedAnalyses::all(); +} + +PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {} +PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner) + : OS(OS), Banner(Banner) {} + +PreservedAnalyses PrintFunctionPass::run(Function *F) { + OS << Banner << static_cast<Value &>(*F); + return PreservedAnalyses::all(); +} + +namespace { + +class PrintModulePassWrapper : public ModulePass { + PrintModulePass P; + +public: + static char ID; + PrintModulePassWrapper() : ModulePass(ID) {} + PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner) + : ModulePass(ID), P(OS, Banner) {} + + bool runOnModule(Module &M) override { + P.run(&M); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +class PrintFunctionPassWrapper : public FunctionPass { + PrintFunctionPass P; + +public: + static char ID; + PrintFunctionPassWrapper() : FunctionPass(ID) {} + PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) + : FunctionPass(ID), P(OS, Banner) {} + + // This pass just prints a banner followed by the function as it's processed. + bool runOnFunction(Function &F) override { + P.run(&F); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +class PrintBasicBlockPass : public BasicBlockPass { + raw_ostream &Out; + std::string Banner; + +public: + static char ID; + PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {} + PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner) + : BasicBlockPass(ID), Out(Out), Banner(Banner) {} + + bool runOnBasicBlock(BasicBlock &BB) override { + Out << Banner << BB; + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} + +char PrintModulePassWrapper::ID = 0; +INITIALIZE_PASS(PrintModulePassWrapper, "print-module", + "Print module to stderr", false, false) +char PrintFunctionPassWrapper::ID = 0; +INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", + "Print function to stderr", false, false) +char PrintBasicBlockPass::ID = 0; +INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false, + false) + +ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, + const std::string &Banner) { + return new PrintModulePassWrapper(OS, Banner); +} + +FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, + const std::string &Banner) { + return new PrintFunctionPassWrapper(OS, Banner); +} + +BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS, + const std::string &Banner) { + return new PrintBasicBlockPass(OS, Banner); +} diff --git a/contrib/llvm/lib/IR/InlineAsm.cpp b/contrib/llvm/lib/IR/InlineAsm.cpp index 9f2a9fe..a3e1da3 100644 --- a/contrib/llvm/lib/IR/InlineAsm.cpp +++ b/contrib/llvm/lib/IR/InlineAsm.cpp @@ -64,16 +64,6 @@ InlineAsm::ConstraintInfo::ConstraintInfo() : currentAlternativeIndex(0) { } -/// Copy constructor. -InlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) : - Type(other.Type), isEarlyClobber(other.isEarlyClobber), - MatchingInput(other.MatchingInput), isCommutative(other.isCommutative), - isIndirect(other.isIndirect), Codes(other.Codes), - isMultipleAlternative(other.isMultipleAlternative), - multipleAlternatives(other.multipleAlternatives), - currentAlternativeIndex(other.currentAlternativeIndex) { -} - /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. @@ -284,7 +274,7 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { break; default: StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); - if (STy == 0 || STy->getNumElements() != NumOutputs) + if (!STy || STy->getNumElements() != NumOutputs) return false; break; } diff --git a/contrib/llvm/lib/IR/Instruction.cpp b/contrib/llvm/lib/IR/Instruction.cpp index a7773c4..86421c4 100644 --- a/contrib/llvm/lib/IR/Instruction.cpp +++ b/contrib/llvm/lib/IR/Instruction.cpp @@ -12,18 +12,18 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Instruction.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/LeakDetector.h" using namespace llvm; Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction *InsertBefore) - : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { + : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) { // Make sure that we get added to a basicblock LeakDetector::addGarbageObject(this); @@ -35,9 +35,13 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, } } +const DataLayout *Instruction::getDataLayout() const { + return getParent()->getDataLayout(); +} + Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) - : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { + : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) { // Make sure that we get added to a basicblock LeakDetector::addGarbageObject(this); @@ -49,7 +53,7 @@ Instruction::Instruction(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!"); + assert(!Parent && "Instruction still linked in the program!"); if (hasMetadataHashEntry()) clearMetadataHashEntries(); } @@ -141,31 +145,31 @@ void Instruction::setFastMathFlags(FastMathFlags FMF) { /// Determine whether the unsafe-algebra flag is set. bool Instruction::hasUnsafeAlgebra() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->hasUnsafeAlgebra(); } /// Determine whether the no-NaNs flag is set. bool Instruction::hasNoNaNs() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->hasNoNaNs(); } /// Determine whether the no-infs flag is set. bool Instruction::hasNoInfs() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->hasNoInfs(); } /// Determine whether the no-signed-zeros flag is set. bool Instruction::hasNoSignedZeros() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->hasNoSignedZeros(); } /// Determine whether the allow-reciprocal flag is set. bool Instruction::hasAllowReciprocal() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->hasAllowReciprocal(); } @@ -173,7 +177,7 @@ bool Instruction::hasAllowReciprocal() const { /// operator which supports these flags. See LangRef.html for the meaning of /// these flats. FastMathFlags Instruction::getFastMathFlags() const { - assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); + assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op"); return cast<FPMathOperator>(this)->getFastMathFlags(); } @@ -258,6 +262,59 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { } } +/// Return true if both instructions have the same special state +/// This must be kept in sync with lib/Transforms/IPO/MergeFunctions.cpp. +static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2, + bool IgnoreAlignment = false) { + assert(I1->getOpcode() == I2->getOpcode() && + "Can not compare special state of different instructions"); + + if (const LoadInst *LI = dyn_cast<LoadInst>(I1)) + return LI->isVolatile() == cast<LoadInst>(I2)->isVolatile() && + (LI->getAlignment() == cast<LoadInst>(I2)->getAlignment() || + IgnoreAlignment) && + LI->getOrdering() == cast<LoadInst>(I2)->getOrdering() && + LI->getSynchScope() == cast<LoadInst>(I2)->getSynchScope(); + if (const StoreInst *SI = dyn_cast<StoreInst>(I1)) + return SI->isVolatile() == cast<StoreInst>(I2)->isVolatile() && + (SI->getAlignment() == cast<StoreInst>(I2)->getAlignment() || + IgnoreAlignment) && + SI->getOrdering() == cast<StoreInst>(I2)->getOrdering() && + SI->getSynchScope() == cast<StoreInst>(I2)->getSynchScope(); + if (const CmpInst *CI = dyn_cast<CmpInst>(I1)) + return CI->getPredicate() == cast<CmpInst>(I2)->getPredicate(); + if (const CallInst *CI = dyn_cast<CallInst>(I1)) + return CI->isTailCall() == cast<CallInst>(I2)->isTailCall() && + CI->getCallingConv() == cast<CallInst>(I2)->getCallingConv() && + CI->getAttributes() == cast<CallInst>(I2)->getAttributes(); + if (const InvokeInst *CI = dyn_cast<InvokeInst>(I1)) + return CI->getCallingConv() == cast<InvokeInst>(I2)->getCallingConv() && + CI->getAttributes() == + cast<InvokeInst>(I2)->getAttributes(); + if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(I1)) + return IVI->getIndices() == cast<InsertValueInst>(I2)->getIndices(); + if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I1)) + return EVI->getIndices() == cast<ExtractValueInst>(I2)->getIndices(); + if (const FenceInst *FI = dyn_cast<FenceInst>(I1)) + return FI->getOrdering() == cast<FenceInst>(I2)->getOrdering() && + FI->getSynchScope() == cast<FenceInst>(I2)->getSynchScope(); + if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(I1)) + return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I2)->isVolatile() && + CXI->isWeak() == cast<AtomicCmpXchgInst>(I2)->isWeak() && + CXI->getSuccessOrdering() == + cast<AtomicCmpXchgInst>(I2)->getSuccessOrdering() && + CXI->getFailureOrdering() == + cast<AtomicCmpXchgInst>(I2)->getFailureOrdering() && + CXI->getSynchScope() == cast<AtomicCmpXchgInst>(I2)->getSynchScope(); + if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I1)) + return RMWI->getOperation() == cast<AtomicRMWInst>(I2)->getOperation() && + RMWI->isVolatile() == cast<AtomicRMWInst>(I2)->isVolatile() && + RMWI->getOrdering() == cast<AtomicRMWInst>(I2)->getOrdering() && + RMWI->getSynchScope() == cast<AtomicRMWInst>(I2)->getSynchScope(); + + return true; +} + /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any /// extra information (e.g. load is volatile) agree. @@ -275,57 +332,22 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { getType() != I->getType()) return false; + // If both instructions have no operands, they are identical. + if (getNumOperands() == 0 && I->getNumOperands() == 0) + return haveSameSpecialState(this, I); + // We have two instructions of identical opcode and #operands. Check to see // if all operands are the same. - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i) != I->getOperand(i)) - return false; + if (!std::equal(op_begin(), op_end(), I->op_begin())) + return false; - // Check special state that is a part of some instructions. - if (const LoadInst *LI = dyn_cast<LoadInst>(this)) - return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() && - LI->getAlignment() == cast<LoadInst>(I)->getAlignment() && - LI->getOrdering() == cast<LoadInst>(I)->getOrdering() && - LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope(); - if (const StoreInst *SI = dyn_cast<StoreInst>(this)) - return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() && - SI->getAlignment() == cast<StoreInst>(I)->getAlignment() && - SI->getOrdering() == cast<StoreInst>(I)->getOrdering() && - SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope(); - if (const CmpInst *CI = dyn_cast<CmpInst>(this)) - return CI->getPredicate() == cast<CmpInst>(I)->getPredicate(); - if (const CallInst *CI = dyn_cast<CallInst>(this)) - return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && - CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && - CI->getAttributes() == cast<CallInst>(I)->getAttributes(); - if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) - return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && - CI->getAttributes() == cast<InvokeInst>(I)->getAttributes(); - if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) - return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); - if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) - return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); - if (const FenceInst *FI = dyn_cast<FenceInst>(this)) - return FI->getOrdering() == cast<FenceInst>(FI)->getOrdering() && - FI->getSynchScope() == cast<FenceInst>(FI)->getSynchScope(); - if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(this)) - return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I)->isVolatile() && - CXI->getOrdering() == cast<AtomicCmpXchgInst>(I)->getOrdering() && - CXI->getSynchScope() == cast<AtomicCmpXchgInst>(I)->getSynchScope(); - if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(this)) - return RMWI->getOperation() == cast<AtomicRMWInst>(I)->getOperation() && - RMWI->isVolatile() == cast<AtomicRMWInst>(I)->isVolatile() && - RMWI->getOrdering() == cast<AtomicRMWInst>(I)->getOrdering() && - RMWI->getSynchScope() == cast<AtomicRMWInst>(I)->getSynchScope(); if (const PHINode *thisPHI = dyn_cast<PHINode>(this)) { const PHINode *otherPHI = cast<PHINode>(I); - for (unsigned i = 0, e = thisPHI->getNumOperands(); i != e; ++i) { - if (thisPHI->getIncomingBlock(i) != otherPHI->getIncomingBlock(i)) - return false; - } - return true; + return std::equal(thisPHI->block_begin(), thisPHI->block_end(), + otherPHI->block_begin()); } - return true; + + return haveSameSpecialState(this, I); } // isSameOperationAs @@ -352,65 +374,25 @@ bool Instruction::isSameOperationAs(const Instruction *I, getOperand(i)->getType() != I->getOperand(i)->getType()) return false; - // Check special state that is a part of some instructions. - if (const LoadInst *LI = dyn_cast<LoadInst>(this)) - return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() && - (LI->getAlignment() == cast<LoadInst>(I)->getAlignment() || - IgnoreAlignment) && - LI->getOrdering() == cast<LoadInst>(I)->getOrdering() && - LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope(); - if (const StoreInst *SI = dyn_cast<StoreInst>(this)) - return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() && - (SI->getAlignment() == cast<StoreInst>(I)->getAlignment() || - IgnoreAlignment) && - SI->getOrdering() == cast<StoreInst>(I)->getOrdering() && - SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope(); - if (const CmpInst *CI = dyn_cast<CmpInst>(this)) - return CI->getPredicate() == cast<CmpInst>(I)->getPredicate(); - if (const CallInst *CI = dyn_cast<CallInst>(this)) - return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && - CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && - CI->getAttributes() == cast<CallInst>(I)->getAttributes(); - if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) - return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && - CI->getAttributes() == - cast<InvokeInst>(I)->getAttributes(); - if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) - return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); - if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) - return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); - if (const FenceInst *FI = dyn_cast<FenceInst>(this)) - return FI->getOrdering() == cast<FenceInst>(I)->getOrdering() && - FI->getSynchScope() == cast<FenceInst>(I)->getSynchScope(); - if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(this)) - return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I)->isVolatile() && - CXI->getOrdering() == cast<AtomicCmpXchgInst>(I)->getOrdering() && - CXI->getSynchScope() == cast<AtomicCmpXchgInst>(I)->getSynchScope(); - if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(this)) - return RMWI->getOperation() == cast<AtomicRMWInst>(I)->getOperation() && - RMWI->isVolatile() == cast<AtomicRMWInst>(I)->isVolatile() && - RMWI->getOrdering() == cast<AtomicRMWInst>(I)->getOrdering() && - RMWI->getSynchScope() == cast<AtomicRMWInst>(I)->getSynchScope(); - - return true; + return haveSameSpecialState(this, I, IgnoreAlignment); } /// isUsedOutsideOfBlock - Return true if there are any uses of I outside of the /// specified block. Note that PHI nodes are considered to evaluate their /// operands in the corresponding predecessor block. bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { - for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { + for (const Use &U : uses()) { // PHI nodes uses values in the corresponding predecessor block. For other // instructions, just check to see whether the parent of the use matches up. - const User *U = *UI; - const PHINode *PN = dyn_cast<PHINode>(U); - if (PN == 0) { - if (cast<Instruction>(U)->getParent() != BB) + const Instruction *I = cast<Instruction>(U.getUser()); + const PHINode *PN = dyn_cast<PHINode>(I); + if (!PN) { + if (I->getParent() != BB) return true; continue; } - if (PN->getIncomingBlock(UI) != BB) + if (PN->getIncomingBlock(U) != BB) return true; } return false; @@ -548,8 +530,8 @@ Instruction *Instruction::clone() const { // new one. SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs; getAllMetadataOtherThanDebugLoc(TheMDs); - for (unsigned i = 0, e = TheMDs.size(); i != e; ++i) - New->setMetadata(TheMDs[i].first, TheMDs[i].second); + for (const auto &MD : TheMDs) + New->setMetadata(MD.first, MD.second); New->setDebugLoc(getDebugLoc()); return New; diff --git a/contrib/llvm/lib/IR/Instructions.cpp b/contrib/llvm/lib/IR/Instructions.cpp index 8a6b77b..9553252 100644 --- a/contrib/llvm/lib/IR/Instructions.cpp +++ b/contrib/llvm/lib/IR/Instructions.cpp @@ -14,14 +14,14 @@ #include "llvm/IR/Instructions.h" #include "LLVMContextImpl.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/ConstantRange.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" using namespace llvm; @@ -68,7 +68,7 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { if (VT->getElementType() != Type::getInt1Ty(Op0->getContext())) return "vector select condition element type must be i1"; VectorType *ET = dyn_cast<VectorType>(Op1->getType()); - if (ET == 0) + if (!ET) return "selected values for vector select must be vectors"; if (ET->getNumElements() != VT->getNumElements()) return "vector select requires selected vectors to have " @@ -76,7 +76,7 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { } else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) { return "select condition must be i1 or <n x i1>"; } - return 0; + return nullptr; } @@ -123,7 +123,7 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. - Op<-1>().set(0); + Op<-1>().set(nullptr); --NumOperands; // If the PHI node is dead, because it has zero entries, nuke it now. @@ -164,7 +164,7 @@ Value *PHINode::hasConstantValue() const { for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i) if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) { if (ConstantValue != this) - return 0; // Incoming values not all the same. + return nullptr; // Incoming values not all the same. // The case where the first value is this PHI. ConstantValue = getIncomingValue(i); } @@ -180,14 +180,14 @@ Value *PHINode::hasConstantValue() const { LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, unsigned NumReservedValues, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore) { + : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) { init(PersonalityFn, 1 + NumReservedValues, NameStr); } LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd) { + : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertAtEnd) { init(PersonalityFn, 1 + NumReservedValues, NameStr); } @@ -248,7 +248,7 @@ void LandingPadInst::growOperands(unsigned Size) { Use::zap(OldOps, OldOps + e, true); } -void LandingPadInst::addClause(Value *Val) { +void LandingPadInst::addClause(Constant *Val) { unsigned OpNo = getNumOperands(); growOperands(1); assert(OpNo < ReservedSpace && "Growing didn't work!"); @@ -324,7 +324,7 @@ CallInst::CallInst(const CallInst &CI) OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(), CI.getNumOperands()) { setAttributes(CI.getAttributes()); - setTailCall(CI.isTailCall()); + setTailCallKind(CI.getTailCallKind()); setCallingConv(CI.getCallingConv()); std::copy(CI.op_begin(), CI.op_end(), op_begin()); @@ -420,8 +420,8 @@ static Instruction *createMalloc(Instruction *InsertBefore, // prototype malloc as "void *malloc(size_t)" MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL); PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); - CallInst *MCall = NULL; - Instruction *Result = NULL; + CallInst *MCall = nullptr; + Instruction *Result = nullptr; if (InsertBefore) { MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall", InsertBefore); Result = MCall; @@ -458,7 +458,7 @@ Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, Value *AllocSize, Value *ArraySize, Function * MallocF, const Twine &Name) { - return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, AllocSize, + return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize, ArraySize, MallocF, Name); } @@ -474,7 +474,7 @@ Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, Function *MallocF, const Twine &Name) { - return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, + return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, ArraySize, MallocF, Name); } @@ -492,7 +492,7 @@ static Instruction* createFree(Value* Source, Instruction *InsertBefore, Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); // prototype free as "void free(void*)" Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL); - CallInst* Result = NULL; + CallInst* Result = nullptr; Value *PtrCast = Source; if (InsertBefore) { if (Source->getType() != IntPtrTy) @@ -512,14 +512,14 @@ static Instruction* createFree(Value* Source, Instruction *InsertBefore, /// CreateFree - Generate the IR for a call to the builtin free function. Instruction * CallInst::CreateFree(Value* Source, Instruction *InsertBefore) { - return createFree(Source, InsertBefore, NULL); + return createFree(Source, InsertBefore, nullptr); } /// CreateFree - Generate the IR for a call to the builtin free function. /// Note: This function does not add the call to the basic block, that is the /// responsibility of the caller. Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) { - Instruction* FreeCall = createFree(Source, NULL, InsertAtEnd); + Instruction* FreeCall = createFree(Source, nullptr, InsertAtEnd); assert(FreeCall && "CreateFree did not create a CallInst"); return FreeCall; } @@ -699,11 +699,11 @@ BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const { UnreachableInst::UnreachableInst(LLVMContext &Context, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable, - 0, 0, InsertBefore) { + nullptr, 0, InsertBefore) { } UnreachableInst::UnreachableInst(LLVMContext &Context, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable, - 0, 0, InsertAtEnd) { + nullptr, 0, InsertAtEnd) { } unsigned UnreachableInst::getNumSuccessorsV() const { @@ -732,7 +732,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 1, 1, InsertBefore) { - assert(IfTrue != 0 && "Branch destination may not be null!"); + assert(IfTrue && "Branch destination may not be null!"); Op<-1>() = IfTrue; } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, @@ -752,7 +752,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 1, 1, InsertAtEnd) { - assert(IfTrue != 0 && "Branch destination may not be null!"); + assert(IfTrue && "Branch destination may not be null!"); Op<-1>() = IfTrue; } @@ -852,7 +852,7 @@ AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, AllocaInst::AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore) : UnaryInstruction(PointerType::getUnqual(Ty), Alloca, - getAISize(Ty->getContext(), 0), InsertBefore) { + getAISize(Ty->getContext(), nullptr), InsertBefore) { setAlignment(0); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); @@ -861,7 +861,7 @@ AllocaInst::AllocaInst(Type *Ty, const Twine &Name, AllocaInst::AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) : UnaryInstruction(PointerType::getUnqual(Ty), Alloca, - getAISize(Ty->getContext(), 0), InsertAtEnd) { + getAISize(Ty->getContext(), nullptr), InsertAtEnd) { setAlignment(0); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); @@ -893,7 +893,8 @@ void AllocaInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); - setInstructionSubclassData(Log2_32(Align) + 1); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~31) | + (Log2_32(Align) + 1)); assert(getAlignment() == Align && "Alignment representation error!"); } @@ -916,7 +917,7 @@ bool AllocaInst::isStaticAlloca() const { // Must be in the entry block. const BasicBlock *Parent = getParent(); - return Parent == &Parent->getParent()->front(); + return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca(); } //===----------------------------------------------------------------------===// @@ -1083,7 +1084,7 @@ void StoreInst::AssertOK() { cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"); assert(!(isAtomic() && getAlignment() == 0) && - "Alignment required for atomic load"); + "Alignment required for atomic store"); } @@ -1215,12 +1216,14 @@ void StoreInst::setAlignment(unsigned Align) { //===----------------------------------------------------------------------===// void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal, - AtomicOrdering Ordering, + AtomicOrdering SuccessOrdering, + AtomicOrdering FailureOrdering, SynchronizationScope SynchScope) { Op<0>() = Ptr; Op<1>() = Cmp; Op<2>() = NewVal; - setOrdering(Ordering); + setSuccessOrdering(SuccessOrdering); + setFailureOrdering(FailureOrdering); setSynchScope(SynchScope); assert(getOperand(0) && getOperand(1) && getOperand(2) && @@ -1233,32 +1236,42 @@ void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal, assert(getOperand(2)->getType() == cast<PointerType>(getOperand(0)->getType())->getElementType() && "Ptr must be a pointer to NewVal type!"); - assert(Ordering != NotAtomic && + assert(SuccessOrdering != NotAtomic && + "AtomicCmpXchg instructions must be atomic!"); + assert(FailureOrdering != NotAtomic && "AtomicCmpXchg instructions must be atomic!"); + assert(SuccessOrdering >= FailureOrdering && + "AtomicCmpXchg success ordering must be at least as strong as fail"); + assert(FailureOrdering != Release && FailureOrdering != AcquireRelease && + "AtomicCmpXchg failure ordering cannot include release semantics"); } AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, - AtomicOrdering Ordering, + AtomicOrdering SuccessOrdering, + AtomicOrdering FailureOrdering, SynchronizationScope SynchScope, Instruction *InsertBefore) - : Instruction(Cmp->getType(), AtomicCmpXchg, - OperandTraits<AtomicCmpXchgInst>::op_begin(this), - OperandTraits<AtomicCmpXchgInst>::operands(this), - InsertBefore) { - Init(Ptr, Cmp, NewVal, Ordering, SynchScope); + : Instruction( + StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext()), + nullptr), + AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this), + OperandTraits<AtomicCmpXchgInst>::operands(this), InsertBefore) { + Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SynchScope); } AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, - AtomicOrdering Ordering, + AtomicOrdering SuccessOrdering, + AtomicOrdering FailureOrdering, SynchronizationScope SynchScope, BasicBlock *InsertAtEnd) - : Instruction(Cmp->getType(), AtomicCmpXchg, - OperandTraits<AtomicCmpXchgInst>::op_begin(this), - OperandTraits<AtomicCmpXchgInst>::operands(this), - InsertAtEnd) { - Init(Ptr, Cmp, NewVal, Ordering, SynchScope); + : Instruction( + StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext()), + nullptr), + AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this), + OperandTraits<AtomicCmpXchgInst>::operands(this), InsertAtEnd) { + Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SynchScope); } - + //===----------------------------------------------------------------------===// // AtomicRMWInst Implementation //===----------------------------------------------------------------------===// @@ -1312,7 +1325,7 @@ AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, SynchronizationScope SynchScope, Instruction *InsertBefore) - : Instruction(Type::getVoidTy(C), Fence, 0, 0, InsertBefore) { + : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) { setOrdering(Ordering); setSynchScope(SynchScope); } @@ -1320,7 +1333,7 @@ FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, SynchronizationScope SynchScope, BasicBlock *InsertAtEnd) - : Instruction(Type::getVoidTy(C), Fence, 0, 0, InsertAtEnd) { + : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertAtEnd) { setOrdering(Ordering); setSynchScope(SynchScope); } @@ -1358,7 +1371,7 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) template <typename IndexTy> static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) { PointerType *PTy = dyn_cast<PointerType>(Ptr->getScalarType()); - if (!PTy) return 0; // Type isn't a pointer type! + if (!PTy) return nullptr; // Type isn't a pointer type! Type *Agg = PTy->getElementType(); // Handle the special case of the empty set index set, which is always valid. @@ -1368,17 +1381,17 @@ static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) { // If there is at least one index, the top level type must be sized, otherwise // it cannot be 'stepped over'. if (!Agg->isSized()) - return 0; + return nullptr; unsigned CurIdx = 1; for (; CurIdx != IdxList.size(); ++CurIdx) { CompositeType *CT = dyn_cast<CompositeType>(Agg); - if (!CT || CT->isPointerTy()) return 0; + if (!CT || CT->isPointerTy()) return nullptr; IndexTy Index = IdxList[CurIdx]; - if (!CT->indexValid(Index)) return 0; + if (!CT->indexValid(Index)) return nullptr; Agg = CT->getTypeAtIndex(Index); } - return CurIdx == IdxList.size() ? Agg : 0; + return CurIdx == IdxList.size() ? Agg : nullptr; } Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList) { @@ -1468,7 +1481,7 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) { - if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy(32)) + if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy()) return false; return true; } @@ -1515,7 +1528,7 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType()) return false;// Second operand of insertelement must be vector element type. - if (!Index->getType()->isIntegerTy(32)) + if (!Index->getType()->isIntegerTy()) return false; // Third operand of insertelement must be i32. return true; } @@ -1568,7 +1581,7 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, // Mask must be vector of i32. VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType()); - if (MaskTy == 0 || !MaskTy->getElementType()->isIntegerTy(32)) + if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32)) return false; // Check to see if Mask is valid. @@ -1577,11 +1590,11 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, if (const ConstantVector *MV = dyn_cast<ConstantVector>(Mask)) { unsigned V1Size = cast<VectorType>(V1->getType())->getNumElements(); - for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) { - if (ConstantInt *CI = dyn_cast<ConstantInt>(MV->getOperand(i))) { + for (Value *Op : MV->operands()) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { if (CI->uge(V1Size*2)) return false; - } else if (!isa<UndefValue>(MV->getOperand(i))) { + } else if (!isa<UndefValue>(Op)) { return false; } } @@ -1701,8 +1714,7 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) // Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) { - for (unsigned CurIdx = 0; CurIdx != Idxs.size(); ++CurIdx) { - unsigned Index = Idxs[CurIdx]; + for (unsigned Index : Idxs) { // We can't use CompositeType::indexValid(Index) here. // indexValid() always returns true for arrays because getelementptr allows // out-of-bounds indices. Since we don't allow those for extractvalue and @@ -1711,13 +1723,13 @@ Type *ExtractValueInst::getIndexedType(Type *Agg, // as easy to check those manually as well. if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) { if (Index >= AT->getNumElements()) - return 0; + return nullptr; } else if (StructType *ST = dyn_cast<StructType>(Agg)) { if (Index >= ST->getNumElements()) - return 0; + return nullptr; } else { // Not a valid type to index into. - return 0; + return nullptr; } Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index); @@ -2114,8 +2126,27 @@ bool CastInst::isNoopCast(Type *IntPtrTy) const { return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy); } -/// This function determines if a pair of casts can be eliminated and what -/// opcode should be used in the elimination. This assumes that there are two +bool CastInst::isNoopCast(const DataLayout *DL) const { + if (!DL) { + // Assume maximum pointer size. + return isNoopCast(Type::getInt64Ty(getContext())); + } + + Type *PtrOpTy = nullptr; + if (getOpcode() == Instruction::PtrToInt) + PtrOpTy = getOperand(0)->getType(); + else if (getOpcode() == Instruction::IntToPtr) + PtrOpTy = getType(); + + Type *IntPtrTy = PtrOpTy + ? DL->getIntPtrType(PtrOpTy) + : DL->getIntPtrType(getContext(), 0); + + return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy); +} + +/// This function determines if a pair of casts can be eliminated and what +/// opcode should be used in the elimination. This assumes that there are two /// instructions like this: /// * %F = firstOpcode SrcTy %x to MidTy /// * %S = secondOpcode MidTy %F to DstTy @@ -2206,7 +2237,7 @@ unsigned CastInst::isEliminableCastPair( case 3: // 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. + // non-vector type. if (!SrcTy->isVectorTy() && DstTy->isIntegerTy()) return firstOp; return 0; @@ -2302,18 +2333,12 @@ unsigned CastInst::isEliminableCastPair( // 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; + // bitcast, addrspacecast -> addrspacecast if the element type of + // bitcast's source is the same as that of addrspacecast's destination. + if (SrcTy->getPointerElementType() == DstTy->getPointerElementType()) + return Instruction::AddrSpaceCast; + return 0; + 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 @@ -2453,11 +2478,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, 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); + return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertAtEnd); } /// @brief Create a BitCast or a PtrToInt cast instruction @@ -2475,14 +2496,36 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); - Type *STy = S->getType(); - if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore); +} + +CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( + Value *S, Type *Ty, + const Twine &Name, + BasicBlock *InsertAtEnd) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); + + return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); +} + +CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( + Value *S, Type *Ty, + const Twine &Name, + Instruction *InsertBefore) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } -CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, +CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned, const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && @@ -2817,30 +2860,55 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) { return false; return SrcTy->getScalarType()->isIntegerTy() && DstTy->getScalarType()->isPointerTy(); - case Instruction::BitCast: + case Instruction::BitCast: { + PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType()); + PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType()); + // BitCast implies a no-op cast of type only. No bits change. // However, you can't cast pointers to anything but pointers. - if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy()) + if (!SrcPtrTy != !DstPtrTy) return false; - // For non pointer cases, the cast is okay if the source and destination bit + // For non-pointer cases, the cast is okay if the source and destination bit // widths are identical. - if (!SrcTy->isPtrOrPtrVectorTy()) + if (!SrcPtrTy) 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()); + // If both are pointers then the address spaces must match. + if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) + return false; + + // A vector of pointers must have the same number of elements. + if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) { + if (VectorType *DstVecTy = dyn_cast<VectorType>(DstTy)) + return (SrcVecTy->getNumElements() == DstVecTy->getNumElements()); + + return false; + } + + return true; + } + case Instruction::AddrSpaceCast: { + PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType()); + if (!SrcPtrTy) + return false; + + PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType()); + if (!DstPtrTy) + return false; + + if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) + return false; + + if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) { + if (VectorType *DstVecTy = dyn_cast<VectorType>(DstTy)) + return (SrcVecTy->getNumElements() == DstVecTy->getNumElements()); + + return false; + } + + return true; + } } } @@ -3307,7 +3375,7 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) { SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, - 0, 0, InsertBefore) { + nullptr, 0, InsertBefore) { init(Value, Default, 2+NumCases*2); } @@ -3318,12 +3386,12 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, - 0, 0, InsertAtEnd) { + nullptr, 0, InsertAtEnd) { init(Value, Default, 2+NumCases*2); } SwitchInst::SwitchInst(const SwitchInst &SI) - : TerminatorInst(SI.getType(), Instruction::Switch, 0, 0) { + : TerminatorInst(SI.getType(), Instruction::Switch, nullptr, 0) { init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands()); NumOperands = SI.getNumOperands(); Use *OL = OperandList, *InOL = SI.OperandList; @@ -3371,8 +3439,8 @@ void SwitchInst::removeCase(CaseIt i) { } // Nuke the last value. - OL[NumOps-2].set(0); - OL[NumOps-2+1].set(0); + OL[NumOps-2].set(nullptr); + OL[NumOps-2+1].set(nullptr); NumOperands = NumOps-2; } @@ -3438,14 +3506,14 @@ void IndirectBrInst::growOperands() { IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr, - 0, 0, InsertBefore) { + nullptr, 0, InsertBefore) { init(Address, NumCases); } IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr, - 0, 0, InsertAtEnd) { + nullptr, 0, InsertAtEnd) { init(Address, NumCases); } @@ -3487,7 +3555,7 @@ void IndirectBrInst::removeDestination(unsigned idx) { OL[idx+1] = OL[NumOps-1]; // Nuke the last value. - OL[NumOps-1].set(0); + OL[NumOps-1].set(nullptr); NumOperands = NumOps-1; } @@ -3533,9 +3601,10 @@ InsertValueInst *InsertValueInst::clone_impl() const { } AllocaInst *AllocaInst::clone_impl() const { - return new AllocaInst(getAllocatedType(), - (Value*)getOperand(0), - getAlignment()); + AllocaInst *Result = new AllocaInst(getAllocatedType(), + (Value *)getOperand(0), getAlignment()); + Result->setUsedWithInAlloca(isUsedWithInAlloca()); + return Result; } LoadInst *LoadInst::clone_impl() const { @@ -3552,8 +3621,10 @@ StoreInst *StoreInst::clone_impl() const { AtomicCmpXchgInst *AtomicCmpXchgInst::clone_impl() const { AtomicCmpXchgInst *Result = new AtomicCmpXchgInst(getOperand(0), getOperand(1), getOperand(2), - getOrdering(), getSynchScope()); + getSuccessOrdering(), getFailureOrdering(), + getSynchScope()); Result->setVolatile(isVolatile()); + Result->setWeak(isWeak()); return Result; } diff --git a/contrib/llvm/lib/IR/IntrinsicInst.cpp b/contrib/llvm/lib/IR/IntrinsicInst.cpp index 51f88d2..5725284 100644 --- a/contrib/llvm/lib/IR/IntrinsicInst.cpp +++ b/contrib/llvm/lib/IR/IntrinsicInst.cpp @@ -1,4 +1,4 @@ -//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers -----*- C++ -*-===// +//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===// // // The LLVM Compiler Infrastructure // @@ -35,7 +35,7 @@ static Value *CastOperand(Value *C) { if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) if (CE->isCast()) return CE->getOperand(0); - return NULL; + return nullptr; } Value *DbgInfoIntrinsic::StripCast(Value *C) { @@ -57,7 +57,7 @@ Value *DbgDeclareInst::getAddress() const { if (MDNode* MD = cast_or_null<MDNode>(getArgOperand(0))) return MD->getOperand(0); else - return NULL; + return nullptr; } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/IR/LLVMContext.cpp b/contrib/llvm/lib/IR/LLVMContext.cpp index 883bb98..de825f0 100644 --- a/contrib/llvm/lib/IR/LLVMContext.cpp +++ b/contrib/llvm/lib/IR/LLVMContext.cpp @@ -15,6 +15,9 @@ #include "llvm/IR/LLVMContext.h" #include "LLVMContextImpl.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/ManagedStatic.h" @@ -98,31 +101,92 @@ void *LLVMContext::getInlineAsmDiagnosticContext() const { return pImpl->InlineAsmDiagContext; } +void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, + void *DiagnosticContext) { + pImpl->DiagnosticHandler = DiagnosticHandler; + pImpl->DiagnosticContext = DiagnosticContext; +} + +LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { + return pImpl->DiagnosticHandler; +} + +void *LLVMContext::getDiagnosticContext() const { + return pImpl->DiagnosticContext; +} + +void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) +{ + pImpl->YieldCallback = Callback; + pImpl->YieldOpaqueHandle = OpaqueHandle; +} + +void LLVMContext::yield() { + if (pImpl->YieldCallback) + pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); +} + void LLVMContext::emitError(const Twine &ErrorStr) { - emitError(0U, ErrorStr); + diagnose(DiagnosticInfoInlineAsm(ErrorStr)); } void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { - unsigned LocCookie = 0; - if (const MDNode *SrcLoc = I->getMetadata("srcloc")) { - if (SrcLoc->getNumOperands() != 0) - if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0))) - LocCookie = CI->getZExtValue(); - } - return emitError(LocCookie, ErrorStr); + assert (I && "Invalid instruction"); + diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); } -void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { - // If there is no error handler installed, just print the error and exit. - if (pImpl->InlineAsmDiagHandler == 0) { - errs() << "error: " << ErrorStr << "\n"; - exit(1); +void LLVMContext::diagnose(const DiagnosticInfo &DI) { + // If there is a report handler, use it. + if (pImpl->DiagnosticHandler) { + pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); + return; } - // If we do have an error handler, we can report the error and keep going. - SMDiagnostic Diag("", SourceMgr::DK_Error, ErrorStr.str()); + // Optimization remarks are selective. They need to check whether the regexp + // pattern, passed via one of the -pass-remarks* flags, matches the name of + // the pass that is emitting the diagnostic. If there is no match, ignore the + // diagnostic and return. + switch (DI.getKind()) { + case llvm::DK_OptimizationRemark: + if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled()) + return; + break; + case llvm::DK_OptimizationRemarkMissed: + if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled()) + return; + break; + case llvm::DK_OptimizationRemarkAnalysis: + if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled()) + return; + break; + default: + break; + } - pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie); + // Otherwise, print the message with a prefix based on the severity. + std::string MsgStorage; + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + DI.print(DP); + Stream.flush(); + switch (DI.getSeverity()) { + case DS_Error: + errs() << "error: " << MsgStorage << "\n"; + exit(1); + case DS_Warning: + errs() << "warning: " << MsgStorage << "\n"; + break; + case DS_Remark: + errs() << "remark: " << MsgStorage << "\n"; + break; + case DS_Note: + errs() << "note: " << MsgStorage << "\n"; + break; + } +} + +void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { + diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/IR/LLVMContextImpl.cpp b/contrib/llvm/lib/IR/LLVMContextImpl.cpp index 6a6a4d6..4c2791f 100644 --- a/contrib/llvm/lib/IR/LLVMContextImpl.cpp +++ b/contrib/llvm/lib/IR/LLVMContextImpl.cpp @@ -14,12 +14,13 @@ #include "LLVMContextImpl.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Module.h" #include <algorithm> using namespace llvm; LLVMContextImpl::LLVMContextImpl(LLVMContext &C) - : TheTrueVal(0), TheFalseVal(0), + : TheTrueVal(nullptr), TheFalseVal(nullptr), VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), HalfTy(C, Type::HalfTyID), @@ -35,8 +36,12 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64) { - InlineAsmDiagHandler = 0; - InlineAsmDiagContext = 0; + InlineAsmDiagHandler = nullptr; + InlineAsmDiagContext = nullptr; + DiagnosticHandler = nullptr; + DiagnosticContext = nullptr; + YieldCallback = nullptr; + YieldOpaqueHandle = nullptr; NamedStructTypesUniqueID = 0; } @@ -44,8 +49,7 @@ namespace { struct DropReferences { // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second' // is a Constant*. - template<typename PairT> - void operator()(const PairT &P) { + template <typename PairT> void operator()(const PairT &P) { P.second->dropAllReferences(); } }; @@ -62,12 +66,11 @@ struct DropFirst { } LLVMContextImpl::~LLVMContextImpl() { - // NOTE: We need to delete the contents of OwnedModules, but we have to - // duplicate it into a temporary vector, because the destructor of Module - // will try to remove itself from OwnedModules set. This would cause - // iterator invalidation if we iterated on the set directly. - std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end()); - DeleteContainerPointers(Modules); + // NOTE: We need to delete the contents of OwnedModules, but Module's dtor + // will call LLVMContextImpl::removeModule, thus invalidating iterators into + // the container. Avoid iterators during this operation: + while (!OwnedModules.empty()) + delete *OwnedModules.begin(); // Free the constants. This is important to do here to ensure that they are // freed before the LeakDetector is torn down. diff --git a/contrib/llvm/lib/IR/LLVMContextImpl.h b/contrib/llvm/lib/IR/LLVMContextImpl.h index 407b985..808c239 100644 --- a/contrib/llvm/lib/IR/LLVMContextImpl.h +++ b/contrib/llvm/lib/IR/LLVMContextImpl.h @@ -30,13 +30,16 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" -#include "llvm/Support/ValueHandle.h" +#include "llvm/IR/ValueHandle.h" #include <vector> namespace llvm { class ConstantInt; class ConstantFP; +class DiagnosticInfoOptimizationRemark; +class DiagnosticInfoOptimizationRemarkMissed; +class DiagnosticInfoOptimizationRemarkAnalysis; class LLVMContext; class Type; class Value; @@ -56,8 +59,8 @@ struct DenseMapAPIntKeyInfo { return hash_combine(Key.type, Key.val); } }; - static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); } - static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); } + static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), nullptr); } + static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), nullptr); } static unsigned getHashValue(const KeyTy &Key) { return static_cast<unsigned>(hash_value(Key)); } @@ -225,9 +228,9 @@ public: MDNode *get() const { return cast_or_null<MDNode>(getValPtr()); } - - virtual void deleted(); - virtual void allUsesReplacedWith(Value *VNew); + + void deleted() override; + void allUsesReplacedWith(Value *VNew) override; }; class LLVMContextImpl { @@ -238,9 +241,15 @@ public: LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; void *InlineAsmDiagContext; - - typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, - DenseMapAPIntKeyInfo> IntMapTy; + + LLVMContext::DiagnosticHandlerTy DiagnosticHandler; + void *DiagnosticContext; + + LLVMContext::YieldCallbackTy YieldCallback; + void *YieldOpaqueHandle; + + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *, + DenseMapAPIntKeyInfo> IntMapTy; IntMapTy IntConstants; typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, @@ -278,8 +287,8 @@ public: StringMap<ConstantDataSequential*> CDSConstants; - - DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses; + DenseMap<std::pair<const Function *, const BasicBlock *>, BlockAddress *> + BlockAddresses; ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr> ExprConstants; @@ -349,7 +358,12 @@ public: /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up /// to date. std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords; - + + /// DiscriminatorTable - This table maps file:line locations to an + /// integer representing the next DWARF path discriminator to assign to + /// instructions in different blocks at the same location. + DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable; + /// IntrinsicIDCache - Cache of intrinsic name (string) to numeric ID mappings /// requested in this context typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy; diff --git a/contrib/llvm/lib/IR/LeakDetector.cpp b/contrib/llvm/lib/IR/LeakDetector.cpp index 835e5e6..6f71627 100644 --- a/contrib/llvm/lib/IR/LeakDetector.cpp +++ b/contrib/llvm/lib/IR/LeakDetector.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/LeakDetector.h" +#include "llvm/IR/LeakDetector.h" #include "LLVMContextImpl.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/Value.h" diff --git a/contrib/llvm/lib/IR/LeaksContext.h b/contrib/llvm/lib/IR/LeaksContext.h index 5038dc9..52ac170 100644 --- a/contrib/llvm/lib/IR/LeaksContext.h +++ b/contrib/llvm/lib/IR/LeaksContext.h @@ -12,8 +12,12 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_IR_LEAKSCONTEXT_H +#define LLVM_IR_LEAKSCONTEXT_H + #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/Value.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -30,10 +34,10 @@ struct PrinterTrait<Value> { template <typename T> struct LeakDetectorImpl { explicit LeakDetectorImpl(const char* const name = "") : - Cache(0), Name(name) { } + Cache(nullptr), Name(name) { } void clear() { - Cache = 0; + Cache = nullptr; Ts.clear(); } @@ -57,15 +61,15 @@ struct LeakDetectorImpl { void removeGarbage(const T* o) { if (o == Cache) - Cache = 0; // Cache hit + Cache = nullptr; // Cache hit else Ts.erase(o); } bool hasGarbage(const std::string& Message) { - addGarbage(0); // Flush the Cache + addGarbage(nullptr); // Flush the Cache - assert(Cache == 0 && "No value should be cached anymore!"); + assert(!Cache && "No value should be cached anymore!"); if (!Ts.empty()) { errs() << "Leaked " << Name << " objects found: " << Message << ":\n"; @@ -90,3 +94,5 @@ private: }; } + +#endif // LLVM_IR_LEAKSCONTEXT_H diff --git a/contrib/llvm/lib/IR/LegacyPassManager.cpp b/contrib/llvm/lib/IR/LegacyPassManager.cpp index a431d82..d3f3482 100644 --- a/contrib/llvm/lib/IR/LegacyPassManager.cpp +++ b/contrib/llvm/lib/IR/LegacyPassManager.cpp @@ -12,17 +12,18 @@ //===----------------------------------------------------------------------===// -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Assembly/Writer.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" #include "llvm/IR/LegacyPassManagers.h" +#include "llvm/IR/LegacyPassNameParser.h" +#include "llvm/IR/Module.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/TimeValue.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -119,7 +120,7 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const { void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { - if (V == 0 && M == 0) + if (!V && !M) OS << "Releasing pass '"; else OS << "Running pass '"; @@ -130,7 +131,7 @@ void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { OS << " on module '" << M->getModuleIdentifier() << "'.\n"; return; } - if (V == 0) { + if (!V) { OS << '\n'; return; } @@ -144,7 +145,7 @@ void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { OS << "value"; OS << " '"; - WriteAsOperand(OS, V, /*PrintTy=*/false, M); + V->printAsOperand(OS, /*PrintTy=*/false, M); OS << "'\n"; } @@ -165,28 +166,28 @@ public: /// 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); + bool runOnFunction(Function &F) override; /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { + void getAnalysisUsage(AnalysisUsage &Info) const override { Info.setPreservesAll(); } - bool doInitialization(Module &M); + bool doInitialization(Module &M) override; bool doInitialization(Function &F); - bool doFinalization(Module &M); + bool doFinalization(Module &M) override; bool doFinalization(Function &F); - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } + PMDataManager *getAsPMDataManager() override { return this; } + Pass *getAsPass() override { return this; } - virtual const char *getPassName() const { + const char *getPassName() const override { return "BasicBlock Pass Manager"; } // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; + void dumpPassStructure(unsigned Offset) override { + dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); BP->dumpPassStructure(Offset + 1); @@ -200,7 +201,7 @@ public: return BP; } - virtual PassManagerType getPassManagerType() const { + PassManagerType getPassManagerType() const override { return PMT_BasicBlockPassManager; } }; @@ -235,8 +236,9 @@ public: } /// createPrinterPass - Get a function printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintFunctionPass(Banner, &O); + Pass *createPrinterPass(raw_ostream &O, + const std::string &Banner) const override { + return createPrintFunctionPass(O, Banner); } // Prepare for running an on the fly pass, freeing memory if needed @@ -249,21 +251,21 @@ public: /// doInitialization - Run all of the initializers for the function passes. /// - bool doInitialization(Module &M); + bool doInitialization(Module &M) override; /// doFinalization - Run all of the finalizers for the function passes. /// - bool doFinalization(Module &M); + bool doFinalization(Module &M) override; - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { + PMDataManager *getAsPMDataManager() override { return this; } + Pass *getAsPass() override { return this; } + PassManagerType getTopLevelPassManagerType() override { return PMT_FunctionPassManager; } /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { + void getAnalysisUsage(AnalysisUsage &Info) const override { Info.setPreservesAll(); } @@ -304,8 +306,9 @@ public: } /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); + Pass *createPrinterPass(raw_ostream &O, + const std::string &Banner) const override { + return createPrintModulePass(O, Banner); } /// run - Execute all of the passes scheduled for execution. Keep track of @@ -324,30 +327,30 @@ public: bool doFinalization(); /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { + void getAnalysisUsage(AnalysisUsage &Info) const override { 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); + void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) override; /// 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); + Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F) override; - virtual const char *getPassName() const { + const char *getPassName() const override { return "Module Pass Manager"; } - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } + PMDataManager *getAsPMDataManager() override { return this; } + Pass *getAsPass() override { return this; } // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; + void dumpPassStructure(unsigned Offset) override { + dbgs().indent(Offset*2) << "ModulePass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); MP->dumpPassStructure(Offset + 1); @@ -364,7 +367,7 @@ public: return static_cast<ModulePass *>(PassVector[N]); } - virtual PassManagerType getPassManagerType() const { + PassManagerType getPassManagerType() const override { return PMT_ModulePassManager; } @@ -404,8 +407,9 @@ public: } /// createPrinterPass - Get a module printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); + Pass *createPrinterPass(raw_ostream &O, + const std::string &Banner) const override { + return createPrintModulePass(O, Banner); } /// run - Execute all of the passes scheduled for execution. Keep track of @@ -424,13 +428,13 @@ public: bool doFinalization(); /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { + void getAnalysisUsage(AnalysisUsage &Info) const override { Info.setPreservesAll(); } - virtual PMDataManager *getAsPMDataManager() { return this; } - virtual Pass *getAsPass() { return this; } - virtual PassManagerType getTopLevelPassManagerType() { + PMDataManager *getAsPMDataManager() override { return this; } + Pass *getAsPass() override { return this; } + PassManagerType getTopLevelPassManagerType() override { return PMT_ModulePassManager; } @@ -475,18 +479,18 @@ public: } // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non null value (if the -time-passes option is enabled) or it leaves it + // 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; + return nullptr; sys::SmartScopedLock<true> Lock(*TimingInfoMutex); Timer *&T = TimingData[P]; - if (T == 0) + if (!T) T = new Timer(P->getPassName(), TG); return T; } @@ -577,7 +581,7 @@ void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, } AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { - AnalysisUsage *AnUsage = NULL; + AnalysisUsage *AnUsage = nullptr; DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); if (DMI != AnUsageMap.end()) AnUsage = DMI->second; @@ -624,7 +628,7 @@ void PMTopLevelManager::schedulePass(Pass *P) { if (!AnalysisPass) { const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I); - if (PI == NULL) { + if (!PI) { // 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"; @@ -731,7 +735,7 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { } } - return 0; + return nullptr; } // Print passes managed by this top level manager. @@ -828,7 +832,7 @@ void PMDataManager::recordAvailableAnalysis(Pass *P) { // 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; + if (!PInf) return; const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented(); for (unsigned i = 0, e = II.size(); i != e; ++i) AvailableAnalysis[II[i]->getTypeInfo()] = P; @@ -845,7 +849,7 @@ bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(), E = HigherLevelAnalysis.end(); I != E; ++I) { Pass *P1 = *I; - if (P1->getAsImmutablePass() == 0 && + if (P1->getAsImmutablePass() == nullptr && std::find(PreservedSet.begin(), PreservedSet.end(), P1->getPassID()) == PreservedSet.end()) @@ -885,7 +889,7 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(), E = AvailableAnalysis.end(); I != E; ) { DenseMap<AnalysisID, Pass*>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && + if (Info->second->getAsImmutablePass() == nullptr && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == PreservedSet.end()) { // Remove this analysis @@ -909,7 +913,7 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { I = InheritedAnalysis[Index]->begin(), E = InheritedAnalysis[Index]->end(); I != E; ) { DenseMap<AnalysisID, Pass *>::iterator Info = I++; - if (Info->second->getAsImmutablePass() == 0 && + if (Info->second->getAsImmutablePass() == nullptr && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == PreservedSet.end()) { // Remove this analysis @@ -1026,7 +1030,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { // 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) + if (!P->getAsPMDataManager()) LastUses.push_back(P); TPM->setLastUser(LastUses, P); @@ -1093,7 +1097,7 @@ void PMDataManager::initializeAnalysisImpl(Pass *P) { I = AnUsage->getRequiredSet().begin(), E = AnUsage->getRequiredSet().end(); I != E; ++I) { Pass *Impl = findAnalysisPass(*I, true); - if (Impl == 0) + if (!Impl) // 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; @@ -1117,7 +1121,7 @@ Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) { if (SearchParent) return TPM->findAnalysisPass(AID); - return NULL; + return nullptr; } // Print list of passes that are last used by P. @@ -1133,7 +1137,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(), E = LUses.end(); I != E; ++I) { - llvm::dbgs() << "--" << std::string(Offset*2, ' '); + dbgs() << "--" << std::string(Offset*2, ' '); (*I)->dumpPassStructure(0); } } @@ -1156,7 +1160,8 @@ void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, StringRef Msg) { if (PassDebugging < Executions) return; - dbgs() << (void*)this << std::string(getDepth()*2+1, ' '); + dbgs() << "[" << sys::TimeValue::now().str() << "] " << (void *)this + << std::string(getDepth() * 2 + 1, ' '); switch (S1) { case EXECUTION_MSG: dbgs() << "Executing Pass '" << P->getPassName(); @@ -1485,8 +1490,10 @@ bool FunctionPassManagerImpl::run(Function &F) { TimingInfo::createTheTimeInfo(); initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { Changed |= getContainedManager(Index)->runOnFunction(F); + F.getContext().yield(); + } for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) getContainedManager(Index)->cleanup(); @@ -1655,6 +1662,8 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { assert((P->getPotentialPassManagerType() < RequiredPass->getPotentialPassManagerType()) && "Unable to handle Pass that requires lower level Analysis pass"); + if (!RequiredPass) + return; FunctionPassManagerImpl *FPP = OnTheFlyManagers[P]; if (!FPP) { @@ -1664,14 +1673,24 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { OnTheFlyManagers[P] = FPP; } - FPP->add(RequiredPass); + const PassInfo * RequiredPassPI = + PassRegistry::getPassRegistry()->getPassInfo(RequiredPass->getPassID()); - // Register P as the last user of RequiredPass. - if (RequiredPass) { - SmallVector<Pass *, 1> LU; - LU.push_back(RequiredPass); - FPP->setLastUser(LU, P); + Pass *FoundPass = nullptr; + if (RequiredPassPI && RequiredPassPI->isAnalysis()) { + FoundPass = + ((PMTopLevelManager*)FPP)->findAnalysisPass(RequiredPass->getPassID()); + } + if (!FoundPass) { + FoundPass = RequiredPass; + // This should be guaranteed to add RequiredPass to the passmanager given + // that we checked for an avaiable analysis above. + FPP->add(RequiredPass); } + // Register P as the last user of FoundPass or RequiredPass. + SmallVector<Pass *, 1> LU; + LU.push_back(FoundPass); + FPP->setLastUser(LU, P); } /// Return function pass corresponding to PassInfo PI, that is @@ -1707,8 +1726,10 @@ bool PassManagerImpl::run(Module &M) { } initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { Changed |= getContainedManager(Index)->runOnModule(M); + M.getContext().yield(); + } for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), E = IPV.end(); I != E; ++I) { @@ -1755,7 +1776,7 @@ 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 +// 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; @@ -1771,7 +1792,7 @@ void TimingInfo::createTheTimeInfo() { Timer *llvm::getPassTimer(Pass *P) { if (TheTimeInfo) return TheTimeInfo->getPassTimer(P); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/IR/MDBuilder.cpp b/contrib/llvm/lib/IR/MDBuilder.cpp new file mode 100644 index 0000000..65cdf38 --- /dev/null +++ b/contrib/llvm/lib/IR/MDBuilder.cpp @@ -0,0 +1,139 @@ +//===---- llvm/MDBuilder.cpp - Builder for LLVM metadata ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MDBuilder class, which is used as a convenient way to +// create LLVM metadata with a consistent and simplified interface. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Metadata.h" +using namespace llvm; + +MDString *MDBuilder::createString(StringRef Str) { + return MDString::get(Context, Str); +} + +MDNode *MDBuilder::createFPMath(float Accuracy) { + if (Accuracy == 0.0) + return nullptr; + assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); + Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); + return MDNode::get(Context, Op); +} + +MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight, + uint32_t FalseWeight) { + uint32_t Weights[] = {TrueWeight, FalseWeight}; + return createBranchWeights(Weights); +} + +MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) { + assert(Weights.size() >= 2 && "Need at least two branch weights!"); + + SmallVector<Value *, 4> Vals(Weights.size() + 1); + Vals[0] = createString("branch_weights"); + + Type *Int32Ty = Type::getInt32Ty(Context); + for (unsigned i = 0, e = Weights.size(); i != e; ++i) + Vals[i + 1] = ConstantInt::get(Int32Ty, Weights[i]); + + return MDNode::get(Context, Vals); +} + +MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) { + assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); + // If the range is everything then it is useless. + if (Hi == Lo) + return nullptr; + + // Return the range [Lo, Hi). + Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); + Value *Range[2] = {ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi)}; + return MDNode::get(Context, Range); +} + +MDNode *MDBuilder::createAnonymousTBAARoot() { + // To ensure uniqueness the root node is self-referential. + MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value *>()); + MDNode *Root = MDNode::get(Context, Dummy); + // At this point we have + // !0 = metadata !{} <- dummy + // !1 = metadata !{metadata !0} <- root + // Replace the dummy operand with the root node itself and delete the dummy. + Root->replaceOperandWith(0, Root); + MDNode::deleteTemporary(Dummy); + // We now have + // !1 = metadata !{metadata !1} <- self-referential root + return Root; +} + +MDNode *MDBuilder::createTBAARoot(StringRef Name) { + return MDNode::get(Context, createString(Name)); +} + +/// \brief Return metadata for a non-root TBAA node with the given name, +/// parent in the TBAA tree, and value for 'pointsToConstantMemory'. +MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent, + bool isConstant) { + if (isConstant) { + Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); + Value *Ops[3] = {createString(Name), Parent, Flags}; + return MDNode::get(Context, Ops); + } else { + Value *Ops[2] = {createString(Name), Parent}; + return MDNode::get(Context, Ops); + } +} + +/// \brief Return metadata for a tbaa.struct node with the given +/// struct field descriptions. +MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { + SmallVector<Value *, 4> Vals(Fields.size() * 3); + Type *Int64 = Type::getInt64Ty(Context); + for (unsigned i = 0, e = Fields.size(); i != e; ++i) { + Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); + Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); + Vals[i * 3 + 2] = Fields[i].TBAA; + } + return MDNode::get(Context, Vals); +} + +/// \brief Return metadata for a TBAA struct node in the type DAG +/// with the given name, a list of pairs (offset, field type in the type DAG). +MDNode *MDBuilder::createTBAAStructTypeNode( + StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) { + SmallVector<Value *, 4> Ops(Fields.size() * 2 + 1); + Type *Int64 = Type::getInt64Ty(Context); + Ops[0] = createString(Name); + for (unsigned i = 0, e = Fields.size(); i != e; ++i) { + Ops[i * 2 + 1] = Fields[i].first; + Ops[i * 2 + 2] = ConstantInt::get(Int64, Fields[i].second); + } + return MDNode::get(Context, Ops); +} + +/// \brief Return metadata for a TBAA scalar type node with the +/// given name, an offset and a parent in the TBAA type DAG. +MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, + uint64_t Offset) { + ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset); + Value *Ops[3] = {createString(Name), Parent, Off}; + return MDNode::get(Context, Ops); +} + +/// \brief Return metadata for a TBAA tag node with the given +/// base type, access type and offset relative to the base type. +MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, + uint64_t Offset) { + Type *Int64 = Type::getInt64Ty(Context); + Value *Ops[3] = {BaseType, AccessType, ConstantInt::get(Int64, Offset)}; + return MDNode::get(Context, Ops); +} diff --git a/contrib/llvm/lib/IR/Mangler.cpp b/contrib/llvm/lib/IR/Mangler.cpp new file mode 100644 index 0000000..27d973b --- /dev/null +++ b/contrib/llvm/lib/IR/Mangler.cpp @@ -0,0 +1,144 @@ +//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Unified name mangler for assembly backends. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Mangler.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +static void getNameWithPrefixx(raw_ostream &OS, const Twine &GVName, + Mangler::ManglerPrefixTy PrefixTy, + const DataLayout &DL, bool UseAt) { + SmallString<256> TmpData; + StringRef Name = GVName.toStringRef(TmpData); + assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); + + if (PrefixTy == Mangler::Private) + OS << DL.getPrivateGlobalPrefix(); + else if (PrefixTy == Mangler::LinkerPrivate) + OS << DL.getLinkerPrivateGlobalPrefix(); + + if (UseAt) { + OS << '@'; + } else { + char Prefix = DL.getGlobalPrefix(); + if (Prefix != '\0') + OS << Prefix; + } + + // If this is a simple string that doesn't need escaping, just append it. + OS << Name; +} + +void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName, + ManglerPrefixTy PrefixTy) const { + return getNameWithPrefixx(OS, GVName, PrefixTy, *DL, false); +} + +void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, + const Twine &GVName, + ManglerPrefixTy PrefixTy) const { + raw_svector_ostream OS(OutName); + return getNameWithPrefix(OS, GVName, PrefixTy); +} + +/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require +/// a suffix on their name indicating the number of words of arguments they +/// take. +static void AddFastCallStdCallSuffix(raw_ostream &OS, const Function *F, + const DataLayout &TD) { + // Calculate arguments size total. + unsigned ArgWords = 0; + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + Type *Ty = AI->getType(); + // 'Dereference' type in case of byval or inalloca parameter attribute. + if (AI->hasByValOrInAllocaAttr()) + Ty = cast<PointerType>(Ty)->getElementType(); + // Size should be aligned to DWORD boundary + ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4; + } + + OS << '@' << ArgWords; +} + +void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, + bool CannotUsePrivateLabel) const { + ManglerPrefixTy PrefixTy = Mangler::Default; + if (GV->hasPrivateLinkage()) { + if (CannotUsePrivateLabel) + PrefixTy = Mangler::LinkerPrivate; + else + PrefixTy = Mangler::Private; + } + + if (!GV->hasName()) { + // Get the ID for the global, assigning a new one if we haven't got one + // already. + unsigned &ID = AnonGlobalIDs[GV]; + if (ID == 0) + ID = NextAnonGlobalID++; + + // Must mangle the global into a unique ID. + getNameWithPrefix(OS, "__unnamed_" + Twine(ID), PrefixTy); + return; + } + + StringRef Name = GV->getName(); + + // No need to do anything special if the global has the special "do not + // mangle" flag in the name. + if (Name[0] == '\1') { + OS << Name.substr(1); + return; + } + + bool UseAt = false; + const Function *MSFunc = nullptr; + CallingConv::ID CC; + if (DL->hasMicrosoftFastStdCallMangling()) { + if ((MSFunc = dyn_cast<Function>(GV))) { + CC = MSFunc->getCallingConv(); + // fastcall functions need to start with @ instead of _. + if (CC == CallingConv::X86_FastCall) + UseAt = true; + } + } + + getNameWithPrefixx(OS, Name, PrefixTy, *DL, UseAt); + + if (!MSFunc) + return; + + // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, + // add it. + // fastcall and stdcall functions usually need @42 at the end to specify + // the argument info. + FunctionType *FT = MSFunc->getFunctionType(); + if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) && + // "Pure" variadic functions do not receive @0 suffix. + (!FT->isVarArg() || FT->getNumParams() == 0 || + (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr()))) + AddFastCallStdCallSuffix(OS, MSFunc, *DL); +} + +void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, + const GlobalValue *GV, + bool CannotUsePrivateLabel) const { + raw_svector_ostream OS(OutName); + getNameWithPrefix(OS, GV, CannotUsePrivateLabel); +} diff --git a/contrib/llvm/lib/IR/Metadata.cpp b/contrib/llvm/lib/IR/Metadata.cpp index a32d25c..59137e4 100644 --- a/contrib/llvm/lib/IR/Metadata.cpp +++ b/contrib/llvm/lib/IR/Metadata.cpp @@ -16,14 +16,15 @@ #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" -#include "llvm/Support/ConstantRange.h" -#include "llvm/Support/LeakDetector.h" -#include "llvm/Support/ValueHandle.h" +#include "llvm/IR/ValueHandle.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -77,8 +78,8 @@ public: /// the list. void setAsFirstOperand(unsigned V) { this->setValPtrInt(V); } - virtual void deleted(); - virtual void allUsesReplacedWith(Value *NV); + void deleted() override; + void allUsesReplacedWith(Value *NV) override; }; } // end namespace llvm. @@ -86,7 +87,7 @@ public: MDNodeOperand::~MDNodeOperand() {} void MDNodeOperand::deleted() { - getParent()->replaceOperand(this, 0); + getParent()->replaceOperand(this, nullptr); } void MDNodeOperand::allUsesReplacedWith(Value *NV) { @@ -147,10 +148,10 @@ MDNode::~MDNode() { } static const Function *getFunctionForValue(Value *V) { - if (!V) return NULL; + if (!V) return nullptr; if (Instruction *I = dyn_cast<Instruction>(V)) { BasicBlock *BB = I->getParent(); - return BB ? BB->getParent() : 0; + return BB ? BB->getParent() : nullptr; } if (Argument *A = dyn_cast<Argument>(V)) return A->getParent(); @@ -158,15 +159,15 @@ static const Function *getFunctionForValue(Value *V) { return BB->getParent(); if (MDNode *MD = dyn_cast<MDNode>(V)) return MD->getFunction(); - return NULL; + return nullptr; } #ifndef NDEBUG static const Function *assertLocalFunction(const MDNode *N) { - if (!N->isFunctionLocal()) return 0; + if (!N->isFunctionLocal()) return nullptr; // FIXME: This does not handle cyclic function local metadata. - const Function *F = 0, *NewF = 0; + const Function *F = nullptr, *NewF = nullptr; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { if (Value *V = N->getOperand(i)) { if (MDNode *MD = dyn_cast<MDNode>(V)) @@ -174,10 +175,11 @@ static const Function *assertLocalFunction(const MDNode *N) { else NewF = getFunctionForValue(V); } - if (F == 0) + if (!F) F = NewF; - else - assert((NewF == 0 || F == NewF) &&"inconsistent function-local metadata"); + else + assert((NewF == nullptr || F == NewF) && + "inconsistent function-local metadata"); } return F; } @@ -191,11 +193,11 @@ const Function *MDNode::getFunction() const { #ifndef NDEBUG return assertLocalFunction(this); #else - if (!isFunctionLocal()) return NULL; + if (!isFunctionLocal()) return nullptr; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) if (const Function *F = getFunctionForValue(getOperand(i))) return F; - return NULL; + return nullptr; #endif } @@ -223,8 +225,8 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals, // Note that if the operands are later nulled out, the node will be // removed from the uniquing map. FoldingSetNodeID ID; - for (unsigned i = 0; i != Vals.size(); ++i) - ID.AddPointer(Vals[i]); + for (Value *V : Vals) + ID.AddPointer(V); void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -235,8 +237,7 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals, bool isFunctionLocal = false; switch (FL) { case FL_Unknown: - for (unsigned i = 0; i != Vals.size(); ++i) { - Value *V = Vals[i]; + for (Value *V : Vals) { if (!V) continue; if (isFunctionLocalValue(V)) { isFunctionLocal = true; @@ -335,14 +336,14 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { // Likewise if the MDNode is function-local but for a different function. if (To && isFunctionLocalValue(To)) { if (!isFunctionLocal()) - To = 0; + To = nullptr; else { const Function *F = getFunction(); const Function *FV = getFunctionForValue(To); // Metadata can be function-local without having an associated function. // So only consider functions to have changed if non-null. if (F && FV && F != FV) - To = 0; + To = nullptr; } } @@ -366,7 +367,7 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { // anymore. This commonly occurs during destruction, and uniquing these // brings little reuse. Also, this means we don't need to include // isFunctionLocal bits in FoldingSetNodeIDs for MDNodes. - if (To == 0) { + if (!To) { setIsNotUniqued(); return; } @@ -407,7 +408,7 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { if (!A || !B) - return NULL; + return nullptr; APFloat AVal = cast<ConstantFP>(A->getOperand(0))->getValueAPF(); APFloat BVal = cast<ConstantFP>(B->getOperand(0))->getValueAPF(); @@ -457,7 +458,7 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { // the ones that overlap. if (!A || !B) - return NULL; + return nullptr; if (A == B) return A; @@ -512,7 +513,7 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { ConstantRange Range(cast<ConstantInt>(EndPoints[0])->getValue(), cast<ConstantInt>(EndPoints[1])->getValue()); if (Range.isFullSet()) - return NULL; + return nullptr; } return MDNode::get(A->getContext(), EndPoints); @@ -527,7 +528,7 @@ static SmallVector<TrackingVH<MDNode>, 4> &getNMDOps(void *Operands) { } NamedMDNode::NamedMDNode(const Twine &N) - : Name(N.str()), Parent(0), + : Name(N.str()), Parent(nullptr), Operands(new SmallVector<TrackingVH<MDNode>, 4>()) { } @@ -575,7 +576,7 @@ StringRef NamedMDNode::getName() const { // void Instruction::setMetadata(StringRef Kind, MDNode *Node) { - if (Node == 0 && !hasMetadata()) return; + if (!Node && !hasMetadata()) return; setMetadata(getContext().getMDKindID(Kind), Node); } @@ -583,11 +584,55 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const { return getMetadataImpl(getContext().getMDKindID(Kind)); } +void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { + SmallSet<unsigned, 5> KnownSet; + KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); + + // Drop debug if needed + if (KnownSet.erase(LLVMContext::MD_dbg)) + DbgLoc = DebugLoc(); + + if (!hasMetadataHashEntry()) + return; // Nothing to remove! + + DenseMap<const Instruction *, LLVMContextImpl::MDMapTy> &MetadataStore = + getContext().pImpl->MetadataStore; + + if (KnownSet.empty()) { + // Just drop our entry at the store. + MetadataStore.erase(this); + setHasMetadataHashEntry(false); + return; + } + + LLVMContextImpl::MDMapTy &Info = MetadataStore[this]; + unsigned I; + unsigned E; + // Walk the array and drop any metadata we don't know. + for (I = 0, E = Info.size(); I != E;) { + if (KnownSet.count(Info[I].first)) { + ++I; + continue; + } + + Info[I] = Info.back(); + Info.pop_back(); + --E; + } + assert(E == Info.size()); + + if (E == 0) { + // Drop our entry at the store. + MetadataStore.erase(this); + setHasMetadataHashEntry(false); + } +} + /// 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; + if (!Node && !hasMetadata()) return; // Handle 'dbg' as a special case since it is not stored in the hash table. if (KindID == LLVMContext::MD_dbg) { @@ -604,9 +649,9 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { setHasMetadataHashEntry(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; + for (auto &P : Info) + if (P.first == KindID) { + P.second = Node; return; } } @@ -618,7 +663,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { // Otherwise, we're removing metadata from an instruction. assert((hasMetadataHashEntry() == - getContext().pImpl->MetadataStore.count(this)) && + (getContext().pImpl->MetadataStore.count(this) > 0)) && "HasMetadata bit out of date!"); if (!hasMetadataHashEntry()) return; // Nothing to remove! @@ -647,16 +692,15 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const { if (KindID == LLVMContext::MD_dbg) return DbgLoc.getAsMDNode(getContext()); - if (!hasMetadataHashEntry()) return 0; + if (!hasMetadataHashEntry()) return nullptr; LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; assert(!Info.empty() && "bit out of sync with hash table"); - for (LLVMContextImpl::MDMapTy::iterator I = Info.begin(), E = Info.end(); - I != E; ++I) - if (I->first == KindID) - return I->second; - return 0; + for (const auto &I : Info) + if (I.first == KindID) + return I.second; + return nullptr; } void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, diff --git a/contrib/llvm/lib/IR/Module.cpp b/contrib/llvm/lib/IR/Module.cpp index 4f240c7..f1b1f9a 100644 --- a/contrib/llvm/lib/IR/Module.cpp +++ b/contrib/llvm/lib/IR/Module.cpp @@ -17,12 +17,15 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/GVMaterializer.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/Support/LeakDetector.h" +#include "llvm/IR/LeakDetector.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/RandomNumberGenerator.h" #include <algorithm> #include <cstdarg> #include <cstdlib> @@ -42,8 +45,8 @@ template class llvm::SymbolTableListTraits<GlobalAlias, Module>; // Primitive Module methods. // -Module::Module(StringRef MID, LLVMContext& C) - : Context(C), Materializer(NULL), ModuleID(MID) { +Module::Module(StringRef MID, LLVMContext &C) + : Context(C), Materializer(), ModuleID(MID), RNG(nullptr), DL("") { ValSymTab = new ValueSymbolTable(); NamedMDSymTab = new StringMap<NamedMDNode *>(); Context.addModule(this); @@ -58,51 +61,7 @@ Module::~Module() { NamedMDList.clear(); delete ValSymTab; delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); -} - -/// Target endian information. -Module::Endianness Module::getEndianness() const { - StringRef temp = DataLayout; - Module::Endianness ret = AnyEndianness; - - while (!temp.empty()) { - std::pair<StringRef, StringRef> P = getToken(temp, "-"); - - StringRef token = P.first; - temp = P.second; - - if (token[0] == 'e') { - ret = LittleEndian; - } else if (token[0] == 'E') { - ret = BigEndian; - } - } - - return ret; -} - -/// Target Pointer Size information. -Module::PointerSize Module::getPointerSize() const { - StringRef temp = DataLayout; - Module::PointerSize ret = AnyPointerSize; - - while (!temp.empty()) { - std::pair<StringRef, StringRef> TmpP = getToken(temp, "-"); - temp = TmpP.second; - TmpP = getToken(TmpP.first, ":"); - StringRef token = TmpP.second, signalToken = TmpP.first; - - if (signalToken[0] == 'p') { - int size = 0; - getToken(token, ":").first.getAsInteger(10, size); - if (size == 32) - ret = Pointer32; - else if (size == 64) - ret = Pointer64; - } - } - - return ret; + delete RNG; } /// getNamedValue - Return the first global value in the module with @@ -140,7 +99,7 @@ Constant *Module::getOrInsertFunction(StringRef Name, AttributeSet AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); - if (F == 0) { + if (!F) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); if (!New->isIntrinsic()) // Intrinsics get attrs set on construction @@ -149,16 +108,6 @@ Constant *Module::getOrInsertFunction(StringRef Name, return New; // Return the new prototype. } - // Okay, the function exists. Does it have externally visible linkage? - if (F->hasLocalLinkage()) { - // Clear the function's name. - F->setName(""); - // Retry, now there won't be a conflict. - Constant *NewF = getOrInsertFunction(Name, Ty); - F->setName(Name); - return NewF; - } - // If the function exists but has the wrong type, return a bitcast to the // right type. if (F->getType() != PointerType::getUnqual(Ty)) @@ -238,7 +187,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { dyn_cast_or_null<GlobalVariable>(getNamedValue(Name))) if (AllowLocal || !Result->hasLocalLinkage()) return Result; - return 0; + return nullptr; } /// getOrInsertGlobal - Look up the specified global in the module symbol table. @@ -250,11 +199,11 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)); - if (GV == 0) { + if (!GV) { // Nope, add it GlobalVariable *New = new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, - 0, Name); + nullptr, Name); return New; // Return the new declaration. } @@ -316,8 +265,7 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { const NamedMDNode *ModFlags = getModuleFlagsMetadata(); if (!ModFlags) return; - for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { - MDNode *Flag = ModFlags->getOperand(i); + for (const MDNode *Flag : ModFlags->operands()) { if (Flag->getNumOperands() >= 3 && isa<ConstantInt>(Flag->getOperand(0)) && isa<MDString>(Flag->getOperand(1))) { // Check the operands of the MDNode before accessing the operands. @@ -336,12 +284,11 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { 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]; + for (const ModuleFlagEntry &MFE : ModuleFlags) { if (Key == MFE.Key->getString()) return MFE.Val; } - return 0; + return nullptr; } /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that @@ -383,6 +330,44 @@ void Module::addModuleFlag(MDNode *Node) { getOrInsertModuleFlagsMetadata()->addOperand(Node); } +void Module::setDataLayout(StringRef Desc) { + DL.reset(Desc); + + if (Desc.empty()) { + DataLayoutStr = ""; + } else { + DataLayoutStr = DL.getStringRepresentation(); + // DataLayoutStr is now equivalent to Desc, but since the representation + // is not unique, they may not be identical. + } +} + +void Module::setDataLayout(const DataLayout *Other) { + if (!Other) { + DataLayoutStr = ""; + DL.reset(""); + } else { + DL = *Other; + DataLayoutStr = DL.getStringRepresentation(); + } +} + +const DataLayout *Module::getDataLayout() const { + if (DataLayoutStr.empty()) + return nullptr; + return &DL; +} + +// We want reproducible builds, but ModuleID may be a full path so we just use +// the filename to salt the RNG (although it is not guaranteed to be unique). +RandomNumberGenerator &Module::getRNG() const { + if (RNG == nullptr) { + StringRef Salt = sys::path::filename(ModuleID); + RNG = new RandomNumberGenerator(Salt); + } + return *RNG; +} + //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. // @@ -409,7 +394,7 @@ bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { if (!Materializer) return false; - error_code EC = Materializer->Materialize(GV); + std::error_code EC = Materializer->Materialize(GV); if (!EC) return false; if (ErrInfo) @@ -422,22 +407,21 @@ void Module::Dematerialize(GlobalValue *GV) { return Materializer->Dematerialize(GV); } -bool Module::MaterializeAll(std::string *ErrInfo) { +std::error_code Module::materializeAll() { if (!Materializer) - return false; - error_code EC = Materializer->MaterializeModule(this); - if (!EC) - return false; - if (ErrInfo) - *ErrInfo = EC.message(); - return true; + return std::error_code(); + return Materializer->MaterializeModule(this); } -bool Module::MaterializeAllPermanently(std::string *ErrInfo) { - if (MaterializeAll(ErrInfo)) - return true; +std::error_code Module::materializeAllPermanently(bool ReleaseBuffer) { + if (std::error_code EC = materializeAll()) + return EC; + + if (ReleaseBuffer) + Materializer->releaseBuffer(); + Materializer.reset(); - return false; + return std::error_code(); } //===----------------------------------------------------------------------===// @@ -453,12 +437,27 @@ bool Module::MaterializeAllPermanently(std::string *ErrInfo) { // has "dropped all references", except operator delete. // void Module::dropAllReferences() { - for(Module::iterator I = begin(), E = end(); I != E; ++I) - I->dropAllReferences(); + for (Function &F : *this) + F.dropAllReferences(); + + for (GlobalVariable &GV : globals()) + GV.dropAllReferences(); - for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I) - I->dropAllReferences(); + for (GlobalAlias &GA : aliases()) + GA.dropAllReferences(); +} + +unsigned Module::getDwarfVersion() const { + Value *Val = getModuleFlag("Dwarf Version"); + if (!Val) + return dwarf::DWARF_VERSION; + return cast<ConstantInt>(Val)->getZExtValue(); +} - for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I) - I->dropAllReferences(); +Comdat *Module::getOrInsertComdat(StringRef Name) { + Comdat C; + StringMapEntry<Comdat> &Entry = + ComdatSymTab.GetOrCreateValue(Name, std::move(C)); + Entry.second.Name = &Entry; + return &Entry.second; } diff --git a/contrib/llvm/lib/IR/Pass.cpp b/contrib/llvm/lib/IR/Pass.cpp index 7fc4828..91d86ae 100644 --- a/contrib/llvm/lib/IR/Pass.cpp +++ b/contrib/llvm/lib/IR/Pass.cpp @@ -14,13 +14,16 @@ //===----------------------------------------------------------------------===// #include "llvm/Pass.h" -#include "llvm/Assembly/PrintModulePass.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LegacyPassNameParser.h" #include "llvm/PassRegistry.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/PassNameParser.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "ir" + //===----------------------------------------------------------------------===// // Pass Implementation // @@ -35,7 +38,7 @@ ModulePass::~ModulePass() { } Pass *ModulePass::createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintModulePass(&O, false, Banner); + return createPrintModulePass(O, Banner); } PassManagerType ModulePass::getPotentialPassManagerType() const { @@ -43,7 +46,7 @@ PassManagerType ModulePass::getPotentialPassManagerType() const { } bool Pass::mustPreserveAnalysisID(char &AID) const { - return Resolver->getAnalysisIfAvailable(&AID, true) != 0; + return Resolver->getAnalysisIfAvailable(&AID, true) != nullptr; } // dumpPassStructure - Implement the -debug-pass=Structure option @@ -89,11 +92,11 @@ void *Pass::getAdjustedAnalysisPointer(AnalysisID AID) { } ImmutablePass *Pass::getAsImmutablePass() { - return 0; + return nullptr; } PMDataManager *Pass::getAsPMDataManager() { - return 0; + return nullptr; } void Pass::setResolver(AnalysisResolver *AR) { @@ -111,7 +114,7 @@ void Pass::print(raw_ostream &O,const Module*) const { // dump - call print(cerr); void Pass::dump() const { - print(dbgs(), 0); + print(dbgs(), nullptr); } //===----------------------------------------------------------------------===// @@ -130,20 +133,29 @@ void ImmutablePass::initializePass() { Pass *FunctionPass::createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintFunctionPass(Banner, &O); + return createPrintFunctionPass(O, Banner); } PassManagerType FunctionPass::getPotentialPassManagerType() const { return PMT_FunctionPassManager; } +bool FunctionPass::skipOptnoneFunction(const Function &F) const { + if (F.hasFnAttribute(Attribute::OptimizeNone)) { + DEBUG(dbgs() << "Skipping pass '" << getPassName() + << "' on function " << F.getName() << "\n"); + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // BasicBlockPass Implementation // Pass *BasicBlockPass::createPrinterPass(raw_ostream &O, const std::string &Banner) const { - return createPrintBasicBlockPass(&O, false, Banner); + return createPrintBasicBlockPass(O, Banner); } bool BasicBlockPass::doInitialization(Function &) { @@ -156,6 +168,18 @@ bool BasicBlockPass::doFinalization(Function &) { return false; } +bool BasicBlockPass::skipOptnoneFunction(const BasicBlock &BB) const { + const Function *F = BB.getParent(); + if (F && F->hasFnAttribute(Attribute::OptimizeNone)) { + // Report this only once per function. + if (&BB == &F->getEntryBlock()) + DEBUG(dbgs() << "Skipping pass '" << getPassName() + << "' on function " << F->getName() << "\n"); + return true; + } + return false; +} + PassManagerType BasicBlockPass::getPotentialPassManagerType() const { return PMT_BasicBlockPassManager; } @@ -171,18 +195,10 @@ const PassInfo *Pass::lookupPassInfo(StringRef Arg) { Pass *Pass::createPass(AnalysisID ID) { const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID); if (!PI) - return NULL; + return nullptr; return PI->createPass(); } -Pass *PassInfo::createPass() const { - assert((!isAnalysisGroup() || NormalCtor) && - "No default implementation found for analysis group!"); - assert(NormalCtor && - "Cannot call createPass on PassInfo without default ctor!"); - return NormalCtor(); -} - //===----------------------------------------------------------------------===// // Analysis Group Implementation Code //===----------------------------------------------------------------------===// @@ -200,17 +216,6 @@ RegisterAGBase::RegisterAGBase(const char *Name, const void *InterfaceID, // PassRegistrationListener implementation // -// PassRegistrationListener ctor - Add the current object to the list of -// PassRegistrationListeners... -PassRegistrationListener::PassRegistrationListener() { - PassRegistry::getPassRegistry()->addRegistrationListener(this); -} - -// dtor - Remove object from list of listeners... -PassRegistrationListener::~PassRegistrationListener() { - PassRegistry::getPassRegistry()->removeRegistrationListener(this); -} - // enumeratePasses - Iterate over the registered passes, calling the // passEnumerate callback on each PassInfo object. // @@ -218,7 +223,16 @@ void PassRegistrationListener::enumeratePasses() { PassRegistry::getPassRegistry()->enumerateWith(this); } -PassNameParser::~PassNameParser() {} +PassNameParser::PassNameParser() + : Opt(nullptr) { + PassRegistry::getPassRegistry()->addRegistrationListener(this); +} + +PassNameParser::~PassNameParser() { + // This only gets called during static destruction, in which case the + // PassRegistry will have already been destroyed by llvm_shutdown(). So + // attempting to remove the registration listener is an error. +} //===----------------------------------------------------------------------===// // AnalysisUsage Class Implementation @@ -230,7 +244,7 @@ namespace { VectorType &CFGOnlyList; GetCFGOnlyPasses(VectorType &L) : CFGOnlyList(L) {} - void passEnumerate(const PassInfo *P) { + void passEnumerate(const PassInfo *P) override { if (P->isCFGOnlyPass()) CFGOnlyList.push_back(P->getTypeInfo()); } diff --git a/contrib/llvm/lib/IR/PassManager.cpp b/contrib/llvm/lib/IR/PassManager.cpp index 966af7d..2e2a7cb 100644 --- a/contrib/llvm/lib/IR/PassManager.cpp +++ b/contrib/llvm/lib/IR/PassManager.cpp @@ -1,4 +1,4 @@ -//===- PassManager.h - Infrastructure for managing & running IR passes ----===// +//===- PassManager.cpp - Infrastructure for managing & running IR passes --===// // // The LLVM Compiler Infrastructure // @@ -7,147 +7,143 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/PassManager.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" using namespace llvm; -void ModulePassManager::run() { - for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) - if (Passes[Idx]->run(M)) - if (AM) AM->invalidateAll(M); -} +static cl::opt<bool> +DebugPM("debug-pass-manager", cl::Hidden, + cl::desc("Print pass management debugging information")); + +PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { + PreservedAnalyses PA = PreservedAnalyses::all(); + + if (DebugPM) + dbgs() << "Starting module pass manager run.\n"; + + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { + if (DebugPM) + dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n"; + + PreservedAnalyses PassPA = Passes[Idx]->run(M, AM); + if (AM) + AM->invalidate(M, PassPA); + PA.intersect(std::move(PassPA)); + + M->getContext().yield(); + } + + if (DebugPM) + dbgs() << "Finished module pass manager run.\n"; -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); - } - return Changed; + return PA; } -void AnalysisManager::invalidateAll(Function *F) { - assert(F->getParent() == M && "Invalidating a function from another module!"); +ModuleAnalysisManager::ResultConceptT & +ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { + ModuleAnalysisResultMapT::iterator RI; + bool Inserted; + std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( + PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>())); - // 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); + // If we don't have a cached result for this module, look up the pass and run + // it to produce a result, which we then add to the cache. + if (Inserted) + RI->second = lookupPass(PassID).run(M, this); - // 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 { - ++I; - } - while (!InvalidatedPassIDs.empty()) - FunctionAnalysisResults.erase( - std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); + return *RI->second; +} + +ModuleAnalysisManager::ResultConceptT * +ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const { + ModuleAnalysisResultMapT::const_iterator RI = + ModuleAnalysisResults.find(PassID); + return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second; } -void AnalysisManager::invalidateAll(Module *M) { - // First invalidate any module results we still have laying about. +void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { + ModuleAnalysisResults.erase(PassID); +} + +void ModuleAnalysisManager::invalidateImpl(Module *M, + const PreservedAnalyses &PA) { // 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)) + if (I->second->invalidate(M, PA)) 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; - } - while (!InvalidatedPassIDs.empty()) - FunctionAnalysisResults.erase( - std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); - } } -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> >())); +PreservedAnalyses FunctionPassManager::run(Function *F, + FunctionAnalysisManager *AM) { + PreservedAnalyses PA = PreservedAnalyses::all(); - 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); + if (DebugPM) + dbgs() << "Starting function pass manager run.\n"; + + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { + if (DebugPM) + dbgs() << "Running function pass: " << Passes[Idx]->name() << "\n"; + + PreservedAnalyses PassPA = Passes[Idx]->run(F, AM); + if (AM) + AM->invalidate(F, PassPA); + PA.intersect(std::move(PassPA)); + + F->getContext().yield(); } - return *RI->second; + if (DebugPM) + dbgs() << "Finished function pass manager run.\n"; + + return PA; +} + +bool FunctionAnalysisManager::empty() const { + assert(FunctionAnalysisResults.empty() == + FunctionAnalysisResultLists.empty() && + "The storage and index of analysis results disagree on how many there " + "are!"); + return FunctionAnalysisResults.empty(); } -const AnalysisManager::AnalysisResultConcept<Function> & -AnalysisManager::getResultImpl(void *PassID, Function *F) { - assert(F->getParent() == M && "Analyzing a function from another module!"); +void FunctionAnalysisManager::clear() { + FunctionAnalysisResults.clear(); + FunctionAnalysisResultLists.clear(); +} +FunctionAnalysisManager::ResultConceptT & +FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { FunctionAnalysisResultMapT::iterator RI; bool Inserted; - llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( + std::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); + // If we don't have a cached result for this function, look up the pass and + // run it to produce a result, which we then add to the cache. 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()); + ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this)); + RI->second = std::prev(ResultList.end()); } return *RI->second->second; } -void AnalysisManager::invalidateImpl(void *PassID, Module *M) { - assert(M == this->M && "Invalidating a pass over a different module!"); - ModuleAnalysisResults.erase(PassID); +FunctionAnalysisManager::ResultConceptT * +FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const { + FunctionAnalysisResultMapT::const_iterator RI = + FunctionAnalysisResults.find(std::make_pair(PassID, F)); + return RI == FunctionAnalysisResults.end() ? nullptr : &*RI->second->second; } -void AnalysisManager::invalidateImpl(void *PassID, Function *F) { - assert(F->getParent() == M && - "Invalidating a pass over a function from another module!"); - +void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { FunctionAnalysisResultMapT::iterator RI = FunctionAnalysisResults.find(std::make_pair(PassID, F)); if (RI == FunctionAnalysisResults.end()) @@ -155,3 +151,54 @@ void AnalysisManager::invalidateImpl(void *PassID, Function *F) { FunctionAnalysisResultLists[F].erase(RI->second); } + +void FunctionAnalysisManager::invalidateImpl(Function *F, + const PreservedAnalyses &PA) { + // 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, PA)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); + } else { + ++I; + } + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); + if (ResultsList.empty()) + FunctionAnalysisResultLists.erase(F); +} + +char FunctionAnalysisManagerModuleProxy::PassID; + +FunctionAnalysisManagerModuleProxy::Result +FunctionAnalysisManagerModuleProxy::run(Module *M) { + assert(FAM->empty() && "Function analyses ran prior to the module proxy!"); + return Result(*FAM); +} + +FunctionAnalysisManagerModuleProxy::Result::~Result() { + // Clear out the analysis manager if we're being destroyed -- it means we + // didn't even see an invalidate call when we got invalidated. + FAM->clear(); +} + +bool FunctionAnalysisManagerModuleProxy::Result::invalidate( + Module *M, const PreservedAnalyses &PA) { + // If this proxy isn't marked as preserved, then we can't even invalidate + // individual function analyses, there may be an invalid set of Function + // objects in the cache making it impossible to incrementally preserve them. + // Just clear the entire manager. + if (!PA.preserved(ID())) + FAM->clear(); + + // Return false to indicate that this result is still a valid proxy. + return false; +} + +char ModuleAnalysisManagerFunctionProxy::PassID; diff --git a/contrib/llvm/lib/IR/PassRegistry.cpp b/contrib/llvm/lib/IR/PassRegistry.cpp index d3b2f1f..91940a9 100644 --- a/contrib/llvm/lib/IR/PassRegistry.cpp +++ b/contrib/llvm/lib/IR/PassRegistry.cpp @@ -13,14 +13,10 @@ //===----------------------------------------------------------------------===// #include "llvm/PassRegistry.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringMap.h" #include "llvm/IR/Function.h" #include "llvm/PassSupport.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Mutex.h" #include "llvm/Support/RWMutex.h" #include <vector> @@ -36,67 +32,23 @@ PassRegistry *PassRegistry::getPassRegistry() { return &*PassRegistryObj; } -static ManagedStatic<sys::SmartRWMutex<true> > Lock; - -//===----------------------------------------------------------------------===// -// PassRegistryImpl -// - -namespace { -struct PassRegistryImpl { - /// PassInfoMap - Keep track of the PassInfo object for each registered pass. - typedef DenseMap<const void*, const PassInfo*> MapType; - MapType PassInfoMap; - - typedef StringMap<const PassInfo*> StringMapType; - StringMapType PassInfoStringMap; - - /// AnalysisGroupInfo - Keep track of information for each analysis group. - struct AnalysisGroupInfo { - SmallPtrSet<const PassInfo *, 8> Implementations; - }; - DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; - - std::vector<const PassInfo*> ToFree; - std::vector<PassRegistrationListener*> Listeners; -}; -} // end anonymous namespace - -void *PassRegistry::getImpl() const { - if (!pImpl) - pImpl = new PassRegistryImpl(); - return pImpl; -} - //===----------------------------------------------------------------------===// // Accessors // PassRegistry::~PassRegistry() { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); - - for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(), - E = Impl->ToFree.end(); I != E; ++I) - delete *I; - - delete Impl; - pImpl = 0; } const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - 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; + sys::SmartScopedReader<true> Guard(Lock); + MapType::const_iterator I = PassInfoMap.find(TI); + return I != PassInfoMap.end() ? I->second : nullptr; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { - sys::SmartScopedReader<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::StringMapType::const_iterator - I = Impl->PassInfoStringMap.find(Arg); - return I != Impl->PassInfoStringMap.end() ? I->second : 0; + sys::SmartScopedReader<true> Guard(Lock); + StringMapType::const_iterator I = PassInfoStringMap.find(Arg); + return I != PassInfoStringMap.end() ? I->second : nullptr; } //===----------------------------------------------------------------------===// @@ -104,39 +56,34 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { // void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + sys::SmartScopedWriter<true> Guard(Lock); bool Inserted = - Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; + PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; assert(Inserted && "Pass registered multiple times!"); (void)Inserted; - Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; + PassInfoStringMap[PI.getPassArgument()] = &PI; // Notify any listeners. for (std::vector<PassRegistrationListener*>::iterator - I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) + I = Listeners.begin(), E = Listeners.end(); I != E; ++I) (*I)->passRegistered(&PI); - if (ShouldFree) Impl->ToFree.push_back(&PI); + if (ShouldFree) ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); } void PassRegistry::unregisterPass(const PassInfo &PI) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::MapType::iterator I = - Impl->PassInfoMap.find(PI.getTypeInfo()); - assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!"); + sys::SmartScopedWriter<true> Guard(Lock); + MapType::iterator I = PassInfoMap.find(PI.getTypeInfo()); + assert(I != PassInfoMap.end() && "Pass registered but not in map!"); // Remove pass from the map. - Impl->PassInfoMap.erase(I); - Impl->PassInfoStringMap.erase(PI.getPassArgument()); + PassInfoMap.erase(I); + PassInfoStringMap.erase(PI.getPassArgument()); } void PassRegistry::enumerateWith(PassRegistrationListener *L) { - 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) + sys::SmartScopedReader<true> Guard(Lock); + for (auto I = PassInfoMap.begin(), E = PassInfoMap.end(); I != E; ++I) L->passEnumerate(I->second); } @@ -148,7 +95,7 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, bool isDefault, bool ShouldFree) { PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID)); - if (InterfaceInfo == 0) { + if (!InterfaceInfo) { // First reference to Interface, register it now. registerPass(Registeree); InterfaceInfo = &Registeree; @@ -161,50 +108,39 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); - sys::SmartScopedWriter<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(Lock); // Make sure we keep track of the fact that the implementation implements // the interface. ImplementationInfo->addInterfaceImplemented(InterfaceInfo); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::AnalysisGroupInfo &AGI = - Impl->AnalysisGroupInfoMap[InterfaceInfo]; + AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo]; assert(AGI.Implementations.count(ImplementationInfo) == 0 && "Cannot add a pass to the same analysis group more than once!"); AGI.Implementations.insert(ImplementationInfo); if (isDefault) { - assert(InterfaceInfo->getNormalCtor() == 0 && + assert(InterfaceInfo->getNormalCtor() == nullptr && "Default implementation for analysis group already specified!"); assert(ImplementationInfo->getNormalCtor() && "Cannot specify pass as default if it does not have a default ctor"); InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); + InterfaceInfo->setTargetMachineCtor( + ImplementationInfo->getTargetMachineCtor()); } } - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - if (ShouldFree) Impl->ToFree.push_back(&Registeree); + if (ShouldFree) + ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - Impl->Listeners.push_back(L); + sys::SmartScopedWriter<true> Guard(Lock); + Listeners.push_back(L); } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { - 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 - // order of that sequence, we need to gracefully handle the case where the - // PassRegistry is destructed before the object that triggers this call. - if (!pImpl) return; + sys::SmartScopedWriter<true> Guard(Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - std::vector<PassRegistrationListener*>::iterator I = - std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); - assert(I != Impl->Listeners.end() && - "PassRegistrationListener not registered!"); - Impl->Listeners.erase(I); + auto I = std::find(Listeners.begin(), Listeners.end(), L); + Listeners.erase(I); } diff --git a/contrib/llvm/lib/IR/PrintModulePass.cpp b/contrib/llvm/lib/IR/PrintModulePass.cpp deleted file mode 100644 index 5026bc2..0000000 --- a/contrib/llvm/lib/IR/PrintModulePass.cpp +++ /dev/null @@ -1,136 +0,0 @@ -//===--- IR/PrintModulePass.cpp - Module/Function Printer -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// PrintModulePass and PrintFunctionPass implementations. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -namespace { - - class PrintModulePass : public ModulePass { - std::string Banner; - raw_ostream *Out; // raw_ostream to print on - bool DeleteStream; // Delete the ostream in our dtor? - public: - static char ID; - PrintModulePass() : ModulePass(ID), Out(&dbgs()), - DeleteStream(false) {} - PrintModulePass(const std::string &B, raw_ostream *o, bool DS) - : ModulePass(ID), Banner(B), Out(o), DeleteStream(DS) {} - - ~PrintModulePass() { - if (DeleteStream) delete Out; - } - - bool runOnModule(Module &M) { - (*Out) << Banner << M; - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - }; - - class PrintFunctionPass : public FunctionPass { - std::string Banner; // String to print before each function - raw_ostream *Out; // raw_ostream to print on - bool DeleteStream; // Delete the ostream in our dtor? - public: - static char ID; - PrintFunctionPass() : FunctionPass(ID), Banner(""), Out(&dbgs()), - DeleteStream(false) {} - PrintFunctionPass(const std::string &B, raw_ostream *o, bool DS) - : FunctionPass(ID), Banner(B), Out(o), DeleteStream(DS) {} - - ~PrintFunctionPass() { - if (DeleteStream) delete Out; - } - - // runOnFunction - This pass just prints a banner followed by the - // function as it's processed. - // - bool runOnFunction(Function &F) { - (*Out) << Banner << static_cast<Value&>(F); - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - }; - - class PrintBasicBlockPass : public BasicBlockPass { - std::string Banner; - raw_ostream *Out; // raw_ostream to print on - bool DeleteStream; // Delete the ostream in our dtor? - public: - static char ID; - PrintBasicBlockPass() : BasicBlockPass(ID), Out(&dbgs()), - DeleteStream(false) {} - PrintBasicBlockPass(const std::string &B, raw_ostream *o, bool DS) - : BasicBlockPass(ID), Banner(B), Out(o), DeleteStream(DS) {} - - ~PrintBasicBlockPass() { - if (DeleteStream) delete Out; - } - - bool runOnBasicBlock(BasicBlock &BB) { - (*Out) << Banner << BB; - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - }; -} - -char PrintModulePass::ID = 0; -INITIALIZE_PASS(PrintModulePass, "print-module", - "Print module to stderr", false, false) -char PrintFunctionPass::ID = 0; -INITIALIZE_PASS(PrintFunctionPass, "print-function", - "Print function to stderr", false, false) -char PrintBasicBlockPass::ID = 0; -INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", - "Print BB to stderr", false, false) - -/// createPrintModulePass - Create and return a pass that writes the -/// module to the specified raw_ostream. -ModulePass *llvm::createPrintModulePass(llvm::raw_ostream *OS, - bool DeleteStream, - const std::string &Banner) { - return new PrintModulePass(Banner, OS, DeleteStream); -} - -/// createPrintFunctionPass - Create and return a pass that prints -/// functions to the specified raw_ostream as they are processed. -FunctionPass *llvm::createPrintFunctionPass(const std::string &Banner, - llvm::raw_ostream *OS, - bool DeleteStream) { - return new PrintFunctionPass(Banner, OS, DeleteStream); -} - -/// createPrintBasicBlockPass - Create and return a pass that writes the -/// BB to the specified raw_ostream. -BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream *OS, - bool DeleteStream, - const std::string &Banner) { - return new PrintBasicBlockPass(Banner, OS, DeleteStream); -} - diff --git a/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h b/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h index 5a383ee..8302597 100644 --- a/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h +++ b/contrib/llvm/lib/IR/SymbolTableListTraitsImpl.h @@ -65,7 +65,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass> template<typename ValueSubClass, typename ItemParentClass> void SymbolTableListTraits<ValueSubClass,ItemParentClass> ::addNodeToList(ValueSubClass *V) { - assert(V->getParent() == 0 && "Value already in a container!!"); + assert(!V->getParent() && "Value already in a container!!"); ItemParentClass *Owner = getListOwner(); V->setParent(Owner); if (V->hasName()) @@ -76,7 +76,7 @@ void SymbolTableListTraits<ValueSubClass,ItemParentClass> template<typename ValueSubClass, typename ItemParentClass> void SymbolTableListTraits<ValueSubClass,ItemParentClass> ::removeNodeFromList(ValueSubClass *V) { - V->setParent(0); + V->setParent(nullptr); if (V->hasName()) if (ValueSymbolTable *ST = TraitsClass::getSymTab(getListOwner())) ST->removeValueName(V->getValueName()); diff --git a/contrib/llvm/lib/IR/Type.cpp b/contrib/llvm/lib/IR/Type.cpp index 432cbc9..1efde47 100644 --- a/contrib/llvm/lib/IR/Type.cpp +++ b/contrib/llvm/lib/IR/Type.cpp @@ -36,7 +36,7 @@ Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { case MetadataTyID : return getMetadataTy(C); case X86_MMXTyID : return getX86_MMXTy(C); default: - return 0; + return nullptr; } } @@ -132,7 +132,7 @@ unsigned Type::getPrimitiveSizeInBits() const { /// getScalarSizeInBits - If this is a vector type, return the /// getPrimitiveSizeInBits value for the element type. Otherwise return the /// getPrimitiveSizeInBits value for this type. -unsigned Type::getScalarSizeInBits() { +unsigned Type::getScalarSizeInBits() const { return getScalarType()->getPrimitiveSizeInBits(); } @@ -155,20 +155,14 @@ int Type::getFPMantissaWidth() const { /// isSizedDerivedType - Derived types like structures and arrays are sized /// iff all of the members of the type are sized as well. Since asking for /// their size is relatively uncommon, move this operation out of line. -bool Type::isSizedDerivedType() const { - if (this->isIntegerTy()) - return true; - +bool Type::isSizedDerivedType(SmallPtrSet<const Type*, 4> *Visited) const { if (const ArrayType *ATy = dyn_cast<ArrayType>(this)) - return ATy->getElementType()->isSized(); + return ATy->getElementType()->isSized(Visited); if (const VectorType *VTy = dyn_cast<VectorType>(this)) - return VTy->getElementType()->isSized(); - - if (!this->isStructTy()) - return false; + return VTy->getElementType()->isSized(Visited); - return cast<StructType>(this)->isSized(); + return cast<StructType>(this)->isSized(Visited); } //===----------------------------------------------------------------------===// @@ -318,8 +312,8 @@ IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { } IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits]; - - if (Entry == 0) + + if (!Entry) Entry = new (C.pImpl->TypeAllocator) IntegerType(C, NumBits); return Entry; @@ -454,7 +448,7 @@ void StructType::setName(StringRef Name) { if (SymbolTableEntry) { // Delete the old string data. ((EntryTy *)SymbolTableEntry)->Destroy(SymbolTable.getAllocator()); - SymbolTableEntry = 0; + SymbolTableEntry = nullptr; } return; } @@ -503,7 +497,7 @@ StructType *StructType::get(LLVMContext &Context, bool isPacked) { } StructType *StructType::get(Type *type, ...) { - assert(type != 0 && "Cannot create a struct type with no elements with this"); + assert(type && "Cannot create a struct type with no elements with this"); LLVMContext &Ctx = type->getContext(); va_list ap; SmallVector<llvm::Type*, 8> StructFields; @@ -544,7 +538,7 @@ StructType *StructType::create(ArrayRef<Type*> Elements) { } StructType *StructType::create(StringRef Name, Type *type, ...) { - assert(type != 0 && "Cannot create a struct type with no elements with this"); + assert(type && "Cannot create a struct type with no elements with this"); LLVMContext &Ctx = type->getContext(); va_list ap; SmallVector<llvm::Type*, 8> StructFields; @@ -556,17 +550,20 @@ StructType *StructType::create(StringRef Name, Type *type, ...) { return llvm::StructType::create(Ctx, StructFields, Name); } -bool StructType::isSized() const { +bool StructType::isSized(SmallPtrSet<const Type*, 4> *Visited) const { if ((getSubclassData() & SCDB_IsSized) != 0) return true; if (isOpaque()) return false; + if (Visited && !Visited->insert(this)) + return false; + // Okay, our struct is sized if all of the elements are, but if one of the // elements is opaque, the struct isn't sized *yet*, but may become sized in // the future, so just bail out without caching. for (element_iterator I = element_begin(), E = element_end(); I != E; ++I) - if (!(*I)->isSized()) + if (!(*I)->isSized(Visited)) return false; // Here we cheat a bit and cast away const-ness. The goal is to memoize when @@ -579,13 +576,13 @@ bool StructType::isSized() const { StringRef StructType::getName() const { assert(!isLiteral() && "Literal structs never have names"); - if (SymbolTableEntry == 0) return StringRef(); - + if (!SymbolTableEntry) return StringRef(); + return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey(); } void StructType::setBody(Type *type, ...) { - assert(type != 0 && "Cannot create a struct type with no elements with this"); + assert(type && "Cannot create a struct type with no elements with this"); va_list ap; SmallVector<llvm::Type*, 8> StructFields; va_start(ap, type); @@ -683,8 +680,8 @@ ArrayType *ArrayType::get(Type *elementType, uint64_t NumElements) { LLVMContextImpl *pImpl = ElementType->getContext().pImpl; ArrayType *&Entry = pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)]; - - if (Entry == 0) + + if (!Entry) Entry = new (pImpl->TypeAllocator) ArrayType(ElementType, NumElements); return Entry; } @@ -712,8 +709,8 @@ VectorType *VectorType::get(Type *elementType, unsigned NumElements) { LLVMContextImpl *pImpl = ElementType->getContext().pImpl; VectorType *&Entry = ElementType->getContext().pImpl ->VectorTypes[std::make_pair(ElementType, NumElements)]; - - if (Entry == 0) + + if (!Entry) Entry = new (pImpl->TypeAllocator) VectorType(ElementType, NumElements); return Entry; } @@ -737,7 +734,7 @@ PointerType *PointerType::get(Type *EltTy, unsigned AddressSpace) { PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy] : CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)]; - if (Entry == 0) + if (!Entry) Entry = new (CImpl->TypeAllocator) PointerType(EltTy, AddressSpace); return Entry; } diff --git a/contrib/llvm/lib/IR/Use.cpp b/contrib/llvm/lib/IR/Use.cpp index 1d343e8..047861c 100644 --- a/contrib/llvm/lib/IR/Use.cpp +++ b/contrib/llvm/lib/IR/Use.cpp @@ -6,111 +6,76 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements the algorithm for finding the User of a Use. -// -//===----------------------------------------------------------------------===// +#include "llvm/IR/Use.h" +#include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include <new> namespace llvm { -//===----------------------------------------------------------------------===// -// Use swap Implementation -//===----------------------------------------------------------------------===// - void Use::swap(Use &RHS) { - Value *V1(Val); - Value *V2(RHS.Val); - if (V1 != V2) { - if (V1) { - removeFromList(); - } - - if (V2) { - RHS.removeFromList(); - Val = V2; - V2->addUse(*this); - } else { - Val = 0; - } + if (Val == RHS.Val) + return; + + if (Val) + removeFromList(); + + Value *OldVal = Val; + if (RHS.Val) { + RHS.removeFromList(); + Val = RHS.Val; + Val->addUse(*this); + } else { + Val = nullptr; + } - if (V1) { - RHS.Val = V1; - V1->addUse(RHS); - } else { - RHS.Val = 0; - } + if (OldVal) { + RHS.Val = OldVal; + RHS.Val->addUse(RHS); + } else { + RHS.Val = nullptr; } } -//===----------------------------------------------------------------------===// -// Use getImpliedUser Implementation -//===----------------------------------------------------------------------===// - -const Use *Use::getImpliedUser() const { - const Use *Current = this; - - while (true) { - unsigned Tag = (Current++)->Prev.getInt(); - switch (Tag) { - case zeroDigitTag: - case oneDigitTag: - continue; - - case stopTag: { - ++Current; - ptrdiff_t Offset = 1; - while (true) { - unsigned Tag = Current->Prev.getInt(); - switch (Tag) { - case zeroDigitTag: - case oneDigitTag: - ++Current; - Offset = (Offset << 1) + Tag; - continue; - default: - return Current + Offset; - } - } - } - - case fullStopTag: - return Current; - } - } +User *Use::getUser() const { + const Use *End = getImpliedUser(); + const UserRef *ref = reinterpret_cast<const UserRef *>(End); + return ref->getInt() ? ref->getPointer() + : reinterpret_cast<User *>(const_cast<Use *>(End)); } -//===----------------------------------------------------------------------===// -// Use initTags Implementation -//===----------------------------------------------------------------------===// +unsigned Use::getOperandNo() const { + return this - getUser()->op_begin(); +} -Use *Use::initTags(Use * const Start, Use *Stop) { +// Sets up the waymarking algorithm's tags for a series of Uses. See the +// algorithm details here: +// +// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout +// +Use *Use::initTags(Use *const Start, Use *Stop) { ptrdiff_t Done = 0; while (Done < 20) { if (Start == Stop--) return Start; - static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag, - oneDigitTag, oneDigitTag, stopTag, - zeroDigitTag, oneDigitTag, oneDigitTag, - stopTag, zeroDigitTag, oneDigitTag, - zeroDigitTag, oneDigitTag, stopTag, - oneDigitTag, oneDigitTag, oneDigitTag, - oneDigitTag, stopTag - }; - new(Stop) Use(tags[Done++]); + static const PrevPtrTag tags[20] = { + fullStopTag, oneDigitTag, stopTag, oneDigitTag, oneDigitTag, + stopTag, zeroDigitTag, oneDigitTag, oneDigitTag, stopTag, + zeroDigitTag, oneDigitTag, zeroDigitTag, oneDigitTag, stopTag, + oneDigitTag, oneDigitTag, oneDigitTag, oneDigitTag, stopTag}; + new (Stop) Use(tags[Done++]); } ptrdiff_t Count = Done; while (Start != Stop) { --Stop; if (!Count) { - new(Stop) Use(stopTag); + new (Stop) Use(stopTag); ++Done; Count = Done; } else { - new(Stop) Use(PrevPtrTag(Count & 1)); + new (Stop) Use(PrevPtrTag(Count & 1)); Count >>= 1; ++Done; } @@ -119,10 +84,6 @@ Use *Use::initTags(Use * const Start, Use *Stop) { return Start; } -//===----------------------------------------------------------------------===// -// Use zap Implementation -//===----------------------------------------------------------------------===// - void Use::zap(Use *Start, const Use *Stop, bool del) { while (Start != Stop) (--Stop)->~Use(); @@ -130,16 +91,37 @@ void Use::zap(Use *Start, const Use *Stop, bool del) { ::operator delete(Start); } -//===----------------------------------------------------------------------===// -// Use getUser Implementation -//===----------------------------------------------------------------------===// +const Use *Use::getImpliedUser() const { + const Use *Current = this; -User *Use::getUser() const { - const Use *End = getImpliedUser(); - const UserRef *ref = reinterpret_cast<const UserRef*>(End); - return ref->getInt() - ? ref->getPointer() - : reinterpret_cast<User*>(const_cast<Use*>(End)); + while (true) { + unsigned Tag = (Current++)->Prev.getInt(); + switch (Tag) { + case zeroDigitTag: + case oneDigitTag: + continue; + + case stopTag: { + ++Current; + ptrdiff_t Offset = 1; + while (true) { + unsigned Tag = Current->Prev.getInt(); + switch (Tag) { + case zeroDigitTag: + case oneDigitTag: + ++Current; + Offset = (Offset << 1) + Tag; + continue; + default: + return Current + Offset; + } + } + } + + case fullStopTag: + return Current; + } + } } } // End llvm namespace diff --git a/contrib/llvm/lib/IR/Value.cpp b/contrib/llvm/lib/IR/Value.cpp index 62a3b31..1ab2183 100644 --- a/contrib/llvm/lib/IR/Value.cpp +++ b/contrib/llvm/lib/IR/Value.cpp @@ -15,20 +15,22 @@ #include "LLVMContextImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/ValueHandle.h" #include <algorithm> using namespace llvm; @@ -38,13 +40,12 @@ using namespace llvm; static inline Type *checkType(Type *Ty) { assert(Ty && "Value defined with a null type: Error!"); - return const_cast<Type*>(Ty); + return Ty; } Value::Value(Type *ty, unsigned scid) - : SubclassID(scid), HasValueHandle(0), - SubclassOptionalData(0), SubclassData(0), VTy((Type*)checkType(ty)), - UseList(0), Name(0) { + : VTy(checkType(ty)), UseList(nullptr), Name(nullptr), SubclassID(scid), + HasValueHandle(0), SubclassOptionalData(0), SubclassData(0) { // FIXME: Why isn't this in the subclass gunk?? // Note, we cannot call isa<CallInst> before the CallInst has been // constructed. @@ -119,7 +120,7 @@ bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { // 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(); + const_user_iterator UI = user_begin(), UE = user_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()) @@ -141,7 +142,7 @@ unsigned Value::getNumUses() const { } static bool getSymTab(Value *V, ValueSymbolTable *&ST) { - ST = 0; + ST = nullptr; if (Instruction *I = dyn_cast<Instruction>(V)) { if (BasicBlock *P = I->getParent()) if (Function *PP = P->getParent()) @@ -182,6 +183,8 @@ void Value::setName(const Twine &NewName) { SmallString<256> NameData; StringRef NameRef = NewName.toStringRef(NameData); + assert(NameRef.find_first_of(0) == StringRef::npos && + "Null bytes are not allowed in names"); // Name isn't changing? if (getName() == NameRef) @@ -201,7 +204,7 @@ void Value::setName(const Twine &NewName) { if (NameRef.empty()) { // Free the name for this value. Name->Destroy(); - Name = 0; + Name = nullptr; return; } @@ -212,7 +215,7 @@ void Value::setName(const Twine &NewName) { // then reallocated. // Create the new name. - Name = ValueName::Create(NameRef.begin(), NameRef.end()); + Name = ValueName::Create(NameRef); Name->setValue(this); return; } @@ -223,7 +226,7 @@ void Value::setName(const Twine &NewName) { // Remove old name. ST->removeValueName(Name); Name->Destroy(); - Name = 0; + Name = nullptr; if (NameRef.empty()) return; @@ -239,7 +242,7 @@ void Value::setName(const Twine &NewName) { void Value::takeName(Value *V) { assert(SubclassID != MDStringVal && "Cannot take the name of an MDString!"); - ValueSymbolTable *ST = 0; + ValueSymbolTable *ST = nullptr; // If this value has a name, drop it. if (hasName()) { // Get the symtab this is in. @@ -254,7 +257,7 @@ void Value::takeName(Value *V) { if (ST) ST->removeValueName(Name); Name->Destroy(); - Name = 0; + Name = nullptr; } // Now we know that this has no name. @@ -281,7 +284,7 @@ void Value::takeName(Value *V) { if (ST == VST) { // Take the name! Name = V->Name; - V->Name = 0; + V->Name = nullptr; Name->setValue(this); return; } @@ -292,17 +295,52 @@ void Value::takeName(Value *V) { if (VST) VST->removeValueName(V->Name); Name = V->Name; - V->Name = 0; + V->Name = nullptr; Name->setValue(this); if (ST) ST->reinsertValue(this); } +#ifndef NDEBUG +static bool contains(SmallPtrSet<ConstantExpr *, 4> &Cache, ConstantExpr *Expr, + Constant *C) { + if (!Cache.insert(Expr)) + return false; + + for (auto &O : Expr->operands()) { + if (O == C) + return true; + auto *CE = dyn_cast<ConstantExpr>(O); + if (!CE) + continue; + if (contains(Cache, CE, C)) + return true; + } + return false; +} + +static bool contains(Value *Expr, Value *V) { + if (Expr == V) + return true; + + auto *C = dyn_cast<Constant>(V); + if (!C) + return false; + + auto *CE = dyn_cast<ConstantExpr>(Expr); + if (!CE) + return false; + + SmallPtrSet<ConstantExpr *, 4> Cache; + return contains(Cache, CE, C); +} +#endif void Value::replaceAllUsesWith(Value *New) { assert(New && "Value::replaceAllUsesWith(<null>) is invalid!"); - assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); + assert(!contains(New, this) && + "this->replaceAllUsesWith(expr(this)) is NOT valid!"); assert(New->getType() == getType() && "replaceAllUses of value with new value of different type!"); @@ -314,7 +352,7 @@ void Value::replaceAllUsesWith(Value *New) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a // constant because they are uniqued. - if (Constant *C = dyn_cast<Constant>(U.getUser())) { + if (auto *C = dyn_cast<Constant>(U.getUser())) { if (!isa<GlobalValue>(C)) { C->replaceUsesOfWithOnConstant(this, New, &U); continue; @@ -417,7 +455,8 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, return V; Offset = GEPOffset; 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)) { V = GA->getAliasee(); @@ -436,32 +475,67 @@ Value *Value::stripInBoundsOffsets() { /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. -static bool isDereferenceablePointer(const Value *V, +static bool isDereferenceablePointer(const Value *V, const DataLayout *DL, SmallPtrSet<const Value *, 32> &Visited) { // Note that it is not safe to speculate into a malloc'd region because // malloc may return null. - // It's also not always safe to follow a bitcast, for example: - // bitcast i8* (alloca i8) to i32* - // would result in a 4-byte load from a 1-byte alloca. Some cases could - // be handled using DataLayout to check sizes and alignments though. // These are obviously ok. if (isa<AllocaInst>(V)) return true; + // It's not always safe to follow a bitcast, for example: + // bitcast i8* (alloca i8) to i32* + // would result in a 4-byte load from a 1-byte alloca. However, + // if we're casting from a pointer from a type of larger size + // to a type of smaller size (or the same size), and the alignment + // is at least as large as for the resulting pointer type, then + // we can look through the bitcast. + if (DL) + if (const BitCastInst* BC = dyn_cast<BitCastInst>(V)) { + Type *STy = BC->getSrcTy()->getPointerElementType(), + *DTy = BC->getDestTy()->getPointerElementType(); + if (STy->isSized() && DTy->isSized() && + (DL->getTypeStoreSize(STy) >= + DL->getTypeStoreSize(DTy)) && + (DL->getABITypeAlignment(STy) >= + DL->getABITypeAlignment(DTy))) + return isDereferenceablePointer(BC->getOperand(0), DL, Visited); + } + // Global variables which can't collapse to null are ok. if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) return !GV->hasExternalWeakLinkage(); - // byval arguments are ok. - if (const Argument *A = dyn_cast<Argument>(V)) - return A->hasByValAttr(); + // byval arguments are okay. Arguments specifically marked as + // dereferenceable are okay too. + if (const Argument *A = dyn_cast<Argument>(V)) { + if (A->hasByValAttr()) + return true; + else if (uint64_t Bytes = A->getDereferenceableBytes()) { + Type *Ty = V->getType()->getPointerElementType(); + if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes) + return true; + } + + return false; + } + + // Return values from call sites specifically marked as dereferenceable are + // also okay. + if (ImmutableCallSite CS = V) { + if (uint64_t Bytes = CS.getDereferenceableBytes(0)) { + Type *Ty = V->getType()->getPointerElementType(); + if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes) + return true; + } + } // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { // Conservatively require that the base pointer be fully dereferenceable. if (!Visited.insert(GEP->getOperand(0))) return false; - if (!isDereferenceablePointer(GEP->getOperand(0), Visited)) + if (!isDereferenceablePointer(GEP->getOperand(0), DL, Visited)) return false; // Check the indices. gep_type_iterator GTI = gep_type_begin(GEP); @@ -491,15 +565,39 @@ static bool isDereferenceablePointer(const Value *V, return true; } + if (const AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(V)) + return isDereferenceablePointer(ASC->getOperand(0), DL, Visited); + // If we don't know, assume the worst. return false; } /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. -bool Value::isDereferenceablePointer() const { +bool Value::isDereferenceablePointer(const DataLayout *DL) const { + // When dereferenceability information is provided by a dereferenceable + // attribute, we know exactly how many bytes are dereferenceable. If we can + // determine the exact offset to the attributed variable, we can use that + // information here. + Type *Ty = getType()->getPointerElementType(); + if (Ty->isSized() && DL) { + APInt Offset(DL->getTypeStoreSizeInBits(getType()), 0); + const Value *BV = stripAndAccumulateInBoundsConstantOffsets(*DL, Offset); + + APInt DerefBytes(Offset.getBitWidth(), 0); + if (const Argument *A = dyn_cast<Argument>(BV)) + DerefBytes = A->getDereferenceableBytes(); + else if (ImmutableCallSite CS = BV) + DerefBytes = CS.getDereferenceableBytes(0); + + if (DerefBytes.getBoolValue() && Offset.isNonNegative()) { + if (DerefBytes.uge(Offset + DL->getTypeStoreSize(Ty))) + return true; + } + } + SmallPtrSet<const Value *, 32> Visited; - return ::isDereferenceablePointer(this, Visited); + return ::isDereferenceablePointer(this, DL, Visited); } /// DoPHITranslation - If this value is a PHI node with CurBB as its parent, @@ -555,7 +653,7 @@ void ValueHandleBase::AddToUseList() { // If this value already has a ValueHandle, then it must be in the // ValueHandles map already. ValueHandleBase *&Entry = pImpl->ValueHandles[VP.getPointer()]; - assert(Entry != 0 && "Value doesn't have any handles?"); + assert(Entry && "Value doesn't have any handles?"); AddToExistingUseList(&Entry); return; } @@ -569,7 +667,7 @@ void ValueHandleBase::AddToUseList() { const void *OldBucketPtr = Handles.getPointerIntoBucketsArray(); ValueHandleBase *&Entry = Handles[VP.getPointer()]; - assert(Entry == 0 && "Value really did already have handles?"); + assert(!Entry && "Value really did already have handles?"); AddToExistingUseList(&Entry); VP.getPointer()->HasValueHandle = true; @@ -650,7 +748,7 @@ void ValueHandleBase::ValueIsDeleted(Value *V) { break; case Weak: // Weak just goes to null, which will unlink it from the list. - Entry->operator=(0); + Entry->operator=(nullptr); break; case Callback: // Forward to the subclass's implementation. diff --git a/contrib/llvm/lib/IR/ValueSymbolTable.cpp b/contrib/llvm/lib/IR/ValueSymbolTable.cpp index fffacb3..e9e979a 100644 --- a/contrib/llvm/lib/IR/ValueSymbolTable.cpp +++ b/contrib/llvm/lib/IR/ValueSymbolTable.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "valuesymtab" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/ADT/SmallString.h" #include "llvm/IR/GlobalValue.h" @@ -20,6 +19,8 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "valuesymtab" + // Class destructor ValueSymbolTable::~ValueSymbolTable() { #ifndef NDEBUG // Only do this in -g mode... @@ -56,7 +57,7 @@ void ValueSymbolTable::reinsertValue(Value* V) { // Try insert the vmap entry with this suffix. ValueName &NewName = vmap.GetOrCreateValue(UniqueName); - if (NewName.getValue() == 0) { + if (!NewName.getValue()) { // Newly inserted name. Success! NewName.setValue(V); V->Name = &NewName; @@ -78,7 +79,7 @@ void ValueSymbolTable::removeValueName(ValueName *V) { ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) { // In the common case, the name is not already in the symbol table. ValueName &Entry = vmap.GetOrCreateValue(Name); - if (Entry.getValue() == 0) { + if (!Entry.getValue()) { Entry.setValue(V); //DEBUG(dbgs() << " Inserted value: " << Entry.getKeyData() << ": " // << *V << "\n"); @@ -95,7 +96,7 @@ ValueName *ValueSymbolTable::createValueName(StringRef Name, Value *V) { // Try insert the vmap entry with this suffix. ValueName &NewName = vmap.GetOrCreateValue(UniqueName); - if (NewName.getValue() == 0) { + if (!NewName.getValue()) { // Newly inserted name. Success! NewName.setValue(V); //DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n"); diff --git a/contrib/llvm/lib/IR/Verifier.cpp b/contrib/llvm/lib/IR/Verifier.cpp index da6b573..9cf911b 100644 --- a/contrib/llvm/lib/IR/Verifier.cpp +++ b/contrib/llvm/lib/IR/Verifier.cpp @@ -45,31 +45,31 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/Verifier.h" +#include "llvm/IR/Verifier.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/DebugInfo.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/InlineAsm.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include "llvm/InstVisitor.h" +#include "llvm/IR/PassManager.h" #include "llvm/Pass.h" -#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" #include "llvm/Support/raw_ostream.h" @@ -77,328 +77,284 @@ #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 - - PreVerifier() : FunctionPass(ID) { - initializePreVerifierPass(*PassRegistry::getPassRegistry()); - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - - // Check that the prerequisites for successful DominatorTree construction - // are satisfied. - bool runOnFunction(Function &F) { - bool Broken = false; - - 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() - << "' does not have terminator!\n"; - WriteAsOperand(dbgs(), I, true); - dbgs() << "\n"; - Broken = true; - } - } - - if (Broken) - report_fatal_error("Broken module, no Basic Block terminator!"); - - return false; - } - }; -} - -char PreVerifier::ID = 0; -INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", - false, false) -static char &PreVerifyID = PreVerifier::ID; +static cl::opt<bool> VerifyDebugInfo("verify-debug-info", cl::init(false)); namespace { - struct Verifier : public FunctionPass, public InstVisitor<Verifier> { - static char ID; // Pass ID, replacement for typeid - bool Broken; // Is this module found to be broken? - VerifierFailureAction action; - // What to do if verification fails. - 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; - - /// InstInThisBlock - when verifying a basic block, keep track of all of the - /// instructions we have seen so far. This allows us to do efficient - /// dominance checks for the case when an instruction has an operand that is - /// an instruction in the same block. - SmallPtrSet<Instruction*, 16> InstsInThisBlock; - - /// MDNodes - keep track of the metadata nodes that have been checked - /// already. - SmallPtrSet<MDNode *, 32> MDNodes; - - /// PersonalityFn - The personality function referenced by the - /// LandingPadInsts. All LandingPadInsts within the same function must use - /// 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), 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), DL(0), MessagesStr(Messages), PersonalityFn(0) { - initializeVerifierPass(*PassRegistry::getPassRegistry()); - } +struct VerifierSupport { + raw_ostream &OS; + const Module *M; - bool doInitialization(Module &M) { - Mod = &M; - Context = &M.getContext(); + /// \brief Track the brokenness of the module while recursively visiting. + bool Broken; - DL = getAnalysisIfAvailable<DataLayout>(); + explicit VerifierSupport(raw_ostream &OS) + : OS(OS), M(nullptr), Broken(false) {} - // 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(); + void WriteValue(const Value *V) { + if (!V) + return; + if (isa<Instruction>(V)) { + OS << *V << '\n'; + } else { + V->printAsOperand(OS, true, M); + OS << '\n'; } + } - bool runOnFunction(Function &F) { - // Get dominator information if we are being run by PassManager - DT = &getAnalysis<DominatorTree>(); - - Mod = F.getParent(); - if (!Context) Context = &F.getContext(); + void WriteType(Type *T) { + if (!T) + return; + OS << ' ' << *T; + } - Finder.reset(); - visit(F); - InstsInThisBlock.clear(); - PersonalityFn = 0; + void WriteComdat(const Comdat *C) { + if (!C) + return; + OS << *C; + } - if (!DisableDebugInfoVerifier) - // Verify Debug Info. - verifyDebugInfo(); + // CheckFailed - A check failed, so print out the condition and the message + // that failed. This provides a nice place to put a breakpoint if you want + // to see why something is not correct. + void CheckFailed(const Twine &Message, const Value *V1 = nullptr, + const Value *V2 = nullptr, const Value *V3 = nullptr, + const Value *V4 = nullptr) { + OS << Message.str() << "\n"; + WriteValue(V1); + WriteValue(V2); + WriteValue(V3); + WriteValue(V4); + Broken = true; + } - // 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(); - } + void CheckFailed(const Twine &Message, const Value *V1, Type *T2, + const Value *V3 = nullptr) { + OS << Message.str() << "\n"; + WriteValue(V1); + WriteType(T2); + WriteValue(V3); + Broken = true; + } - bool doFinalization(Module &M) { - // Scan through, checking all of the external function's linkage now... - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - visitGlobalValue(*I); + void CheckFailed(const Twine &Message, Type *T1, Type *T2 = nullptr, + Type *T3 = nullptr) { + OS << Message.str() << "\n"; + WriteType(T1); + WriteType(T2); + WriteType(T3); + Broken = true; + } - // Check to make sure function prototypes are okay. - if (I->isDeclaration()) visitFunction(*I); + void CheckFailed(const Twine &Message, const Comdat *C) { + OS << Message.str() << "\n"; + WriteComdat(C); + Broken = true; + } +}; +class Verifier : public InstVisitor<Verifier>, VerifierSupport { + friend class InstVisitor<Verifier>; + + LLVMContext *Context; + const DataLayout *DL; + DominatorTree DT; + + /// \brief When verifying a basic block, keep track of all of the + /// instructions we have seen so far. + /// + /// This allows us to do efficient dominance checks for the case when an + /// instruction has an operand that is an instruction in the same block. + SmallPtrSet<Instruction *, 16> InstsInThisBlock; + + /// \brief Keep track of the metadata nodes that have been checked already. + SmallPtrSet<MDNode *, 32> MDNodes; + + /// \brief The personality function referenced by the LandingPadInsts. + /// All LandingPadInsts within the same function must use the same + /// personality function. + const Value *PersonalityFn; + +public: + explicit Verifier(raw_ostream &OS = dbgs()) + : VerifierSupport(OS), Context(nullptr), DL(nullptr), + PersonalityFn(nullptr) {} + + bool verify(const Function &F) { + M = F.getParent(); + Context = &M->getContext(); + + // First ensure the function is well-enough formed to compute dominance + // information. + if (F.empty()) { + OS << "Function '" << F.getName() + << "' does not contain an entry block!\n"; + return false; + } + for (Function::const_iterator I = F.begin(), E = F.end(); I != E; ++I) { + if (I->empty() || !I->back().isTerminator()) { + OS << "Basic Block in function '" << F.getName() + << "' does not have terminator!\n"; + I->printAsOperand(OS, true); + OS << "\n"; + return false; } + } - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - visitGlobalVariable(*I); + // Now directly compute a dominance tree. We don't rely on the pass + // manager to provide this as it isolates us from a potentially + // out-of-date dominator tree and makes it significantly more complex to + // run this code outside of a pass manager. + // FIXME: It's really gross that we have to cast away constness here. + DT.recalculate(const_cast<Function &>(F)); - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); - I != E; ++I) - visitGlobalAlias(*I); + Broken = false; + // FIXME: We strip const here because the inst visitor strips const. + visit(const_cast<Function &>(F)); + InstsInThisBlock.clear(); + PersonalityFn = nullptr; - for (Module::named_metadata_iterator I = M.named_metadata_begin(), - E = M.named_metadata_end(); I != E; ++I) - visitNamedMDNode(*I); + return !Broken; + } - visitModuleFlags(M); - visitModuleIdents(M); + bool verify(const Module &M) { + this->M = &M; + Context = &M.getContext(); + Broken = false; - if (!DisableDebugInfoVerifier) { - Finder.reset(); - Finder.processModule(M); - // Verify Debug Info. - verifyDebugInfo(); - } + // Scan through, checking all of the external function's linkage now... + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { + visitGlobalValue(*I); - // If the module is broken, abort at this time. - return abortIfBroken(); + // Check to make sure function prototypes are okay. + if (I->isDeclaration()) + visitFunction(*I); } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequiredID(PreVerifyID); - AU.addRequired<DominatorTree>(); - } - - /// abortIfBroken - If the module is broken and we are supposed to abort on - /// this condition, do so. - /// - bool abortIfBroken() { - if (!Broken) return false; - MessagesStr << "Broken module found, "; - switch (action) { - case AbortProcessAction: - MessagesStr << "compilation aborted!\n"; - dbgs() << MessagesStr.str(); - // Client should choose different reaction if abort is not desired - abort(); - case PrintMessageAction: - MessagesStr << "verification continues.\n"; - dbgs() << MessagesStr.str(); - return false; - case ReturnStatusAction: - MessagesStr << "compilation terminated.\n"; - return true; - } - llvm_unreachable("Invalid action"); - } + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + visitGlobalVariable(*I); + for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); + I != E; ++I) + visitGlobalAlias(*I); - // Verification methods... - void visitGlobalValue(GlobalValue &GV); - void visitGlobalVariable(GlobalVariable &GV); - 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); - void visitFunction(Function &F); - void visitBasicBlock(BasicBlock &BB); - using InstVisitor<Verifier>::visit; - - void visit(Instruction &I); - - void visitTruncInst(TruncInst &I); - void visitZExtInst(ZExtInst &I); - void visitSExtInst(SExtInst &I); - void visitFPTruncInst(FPTruncInst &I); - void visitFPExtInst(FPExtInst &I); - void visitFPToUIInst(FPToUIInst &I); - void visitFPToSIInst(FPToSIInst &I); - void visitUIToFPInst(UIToFPInst &I); - void visitSIToFPInst(SIToFPInst &I); - 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); - void visitFCmpInst(FCmpInst &FC); - void visitExtractElementInst(ExtractElementInst &EI); - void visitInsertElementInst(InsertElementInst &EI); - void visitShuffleVectorInst(ShuffleVectorInst &EI); - void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } - void visitCallInst(CallInst &CI); - void visitInvokeInst(InvokeInst &II); - void visitGetElementPtrInst(GetElementPtrInst &GEP); - void visitLoadInst(LoadInst &LI); - void visitStoreInst(StoreInst &SI); - void verifyDominatesUse(Instruction &I, unsigned i); - void visitInstruction(Instruction &I); - void visitTerminatorInst(TerminatorInst &I); - void visitBranchInst(BranchInst &BI); - void visitReturnInst(ReturnInst &RI); - void visitSwitchInst(SwitchInst &SI); - void visitIndirectBrInst(IndirectBrInst &BI); - void visitSelectInst(SelectInst &SI); - void visitUserOp1(Instruction &I); - void visitUserOp2(Instruction &I) { visitUserOp1(I); } - void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); - void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); - void visitAtomicRMWInst(AtomicRMWInst &RMWI); - void visitFenceInst(FenceInst &FI); - void visitAllocaInst(AllocaInst &AI); - void visitExtractValueInst(ExtractValueInst &EVI); - void visitInsertValueInst(InsertValueInst &IVI); - void visitLandingPadInst(LandingPadInst &LPI); - - void VerifyCallSite(CallSite CS); - bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, - int VT, unsigned ArgNo, std::string &Suffix); - 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); - void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, - bool isReturnValue, const Value *V); - 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)) { - MessagesStr << *V << '\n'; - } else { - WriteAsOperand(MessagesStr, V, true, Mod); - MessagesStr << '\n'; - } - } + for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); + I != E; ++I) + visitNamedMDNode(*I); - void WriteType(Type *T) { - if (!T) return; - MessagesStr << ' ' << *T; - } + for (const StringMapEntry<Comdat> &SMEC : M.getComdatSymbolTable()) + visitComdat(SMEC.getValue()); + visitModuleFlags(M); + visitModuleIdents(M); - // CheckFailed - A check failed, so print out the condition and the message - // that failed. This provides a nice place to put a breakpoint if you want - // to see why something is not correct. - void CheckFailed(const Twine &Message, - const Value *V1 = 0, const Value *V2 = 0, - const Value *V3 = 0, const Value *V4 = 0) { - MessagesStr << Message.str() << "\n"; - WriteValue(V1); - WriteValue(V2); - WriteValue(V3); - WriteValue(V4); - Broken = true; - } + return !Broken; + } - void CheckFailed(const Twine &Message, const Value *V1, - Type *T2, const Value *V3 = 0) { - MessagesStr << Message.str() << "\n"; - WriteValue(V1); - WriteType(T2); - WriteValue(V3); - Broken = true; - } +private: + // Verification methods... + void visitGlobalValue(const GlobalValue &GV); + void visitGlobalVariable(const GlobalVariable &GV); + void visitGlobalAlias(const GlobalAlias &GA); + void visitAliaseeSubExpr(const GlobalAlias &A, const Constant &C); + void visitAliaseeSubExpr(SmallPtrSet<const GlobalAlias *, 4> &Visited, + const GlobalAlias &A, const Constant &C); + void visitNamedMDNode(const NamedMDNode &NMD); + void visitMDNode(MDNode &MD, Function *F); + void visitComdat(const Comdat &C); + void visitModuleIdents(const Module &M); + void visitModuleFlags(const Module &M); + void visitModuleFlag(const MDNode *Op, + DenseMap<const MDString *, const MDNode *> &SeenIDs, + SmallVectorImpl<const MDNode *> &Requirements); + void visitFunction(const Function &F); + void visitBasicBlock(BasicBlock &BB); + + // InstVisitor overrides... + using InstVisitor<Verifier>::visit; + void visit(Instruction &I); + + void visitTruncInst(TruncInst &I); + void visitZExtInst(ZExtInst &I); + void visitSExtInst(SExtInst &I); + void visitFPTruncInst(FPTruncInst &I); + void visitFPExtInst(FPExtInst &I); + void visitFPToUIInst(FPToUIInst &I); + void visitFPToSIInst(FPToSIInst &I); + void visitUIToFPInst(UIToFPInst &I); + void visitSIToFPInst(SIToFPInst &I); + 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); + void visitFCmpInst(FCmpInst &FC); + void visitExtractElementInst(ExtractElementInst &EI); + void visitInsertElementInst(InsertElementInst &EI); + void visitShuffleVectorInst(ShuffleVectorInst &EI); + void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } + void visitCallInst(CallInst &CI); + void visitInvokeInst(InvokeInst &II); + void visitGetElementPtrInst(GetElementPtrInst &GEP); + void visitLoadInst(LoadInst &LI); + void visitStoreInst(StoreInst &SI); + void verifyDominatesUse(Instruction &I, unsigned i); + void visitInstruction(Instruction &I); + void visitTerminatorInst(TerminatorInst &I); + void visitBranchInst(BranchInst &BI); + void visitReturnInst(ReturnInst &RI); + void visitSwitchInst(SwitchInst &SI); + void visitIndirectBrInst(IndirectBrInst &BI); + void visitSelectInst(SelectInst &SI); + void visitUserOp1(Instruction &I); + void visitUserOp2(Instruction &I) { visitUserOp1(I); } + void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); + void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); + void visitAtomicRMWInst(AtomicRMWInst &RMWI); + void visitFenceInst(FenceInst &FI); + void visitAllocaInst(AllocaInst &AI); + void visitExtractValueInst(ExtractValueInst &EVI); + void visitInsertValueInst(InsertValueInst &IVI); + void visitLandingPadInst(LandingPadInst &LPI); + + void VerifyCallSite(CallSite CS); + void verifyMustTailCall(CallInst &CI); + bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT, + unsigned ArgNo, std::string &Suffix); + 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); + void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, + bool isReturnValue, const Value *V); + void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, + const Value *V); + + void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy); + void VerifyConstantExprBitcastType(const ConstantExpr *CE); +}; +class DebugInfoVerifier : public VerifierSupport { +public: + explicit DebugInfoVerifier(raw_ostream &OS = dbgs()) : VerifierSupport(OS) {} + + bool verify(const Module &M) { + this->M = &M; + verifyDebugInfo(); + return !Broken; + } - void CheckFailed(const Twine &Message, Type *T1, - Type *T2 = 0, Type *T3 = 0) { - MessagesStr << Message.str() << "\n"; - WriteType(T1); - WriteType(T2); - WriteType(T3); - Broken = true; - } - }; +private: + void verifyDebugInfo(); + void processInstructions(DebugInfoFinder &Finder); + void processCallInst(DebugInfoFinder &Finder, const CallInst &CI); +}; } // End anonymous namespace -char Verifier::ID = 0; -INITIALIZE_PASS_BEGIN(Verifier, "verify", "Module Verifier", false, false) -INITIALIZE_PASS_DEPENDENCY(PreVerifier) -INITIALIZE_PASS_DEPENDENCY(DominatorTree) -INITIALIZE_PASS_END(Verifier, "verify", "Module Verifier", false, false) - // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ do { if (!(C)) { CheckFailed(M); return; } } while (0) @@ -413,36 +369,30 @@ INITIALIZE_PASS_END(Verifier, "verify", "Module Verifier", false, false) void Verifier::visit(Instruction &I) { for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) - Assert1(I.getOperand(i) != 0, "Operand is null", &I); + Assert1(I.getOperand(i) != nullptr, "Operand is null", &I); InstVisitor<Verifier>::visit(I); } -void Verifier::visitGlobalValue(GlobalValue &GV) { - Assert1(!GV.isDeclaration() || - GV.isMaterializable() || - GV.hasExternalLinkage() || - GV.hasDLLImportLinkage() || - GV.hasExternalWeakLinkage() || - (isa<GlobalAlias>(GV) && - (GV.hasLocalLinkage() || GV.hasWeakLinkage())), - "Global is external, but doesn't have external or dllimport or weak linkage!", +void Verifier::visitGlobalValue(const GlobalValue &GV) { + Assert1(!GV.isDeclaration() || GV.isMaterializable() || + GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(), + "Global is external, but doesn't have external or weak linkage!", &GV); - Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(), - "Global is marked as dllimport, but not external", &GV); - + Assert1(GV.getAlignment() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &GV); Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV), "Only global variables can have appending linkage!", &GV); if (GV.hasAppendingLinkage()) { - GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV); + const GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV); Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } } -void Verifier::visitGlobalVariable(GlobalVariable &GV) { +void Verifier::visitGlobalVariable(const GlobalVariable &GV) { if (GV.hasInitializer()) { Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(), "Global variable initializer type does not match global " @@ -455,10 +405,10 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { "'common' global must have a zero initializer!", &GV); Assert1(!GV.isConstant(), "'common' global may not be marked constant!", &GV); + Assert1(!GV.hasComdat(), "'common' global may not be in a Comdat!", &GV); } } else { - Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() || - GV.hasExternalWeakLinkage(), + Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(), "invalid linkage type for global declaration", &GV); } @@ -468,14 +418,22 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { "invalid linkage for intrinsic global variable", &GV); // Don't worry about emitting an error for it not being an array, // visitGlobalValue will complain on appending non-array. - if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getType())) { + if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getType()->getElementType())) { StructType *STy = dyn_cast<StructType>(ATy->getElementType()); PointerType *FuncPtrTy = FunctionType::get(Type::getVoidTy(*Context), false)->getPointerTo(); - Assert1(STy && STy->getNumElements() == 2 && + // FIXME: Reject the 2-field form in LLVM 4.0. + Assert1(STy && (STy->getNumElements() == 2 || + STy->getNumElements() == 3) && STy->getTypeAtIndex(0u)->isIntegerTy(32) && STy->getTypeAtIndex(1) == FuncPtrTy, "wrong type for intrinsic global variable", &GV); + if (STy->getNumElements() == 3) { + Type *ETy = STy->getTypeAtIndex(2); + Assert1(ETy->isPointerTy() && + cast<PointerType>(ETy)->getElementType()->isIntegerTy(8), + "wrong type for intrinsic global variable", &GV); + } } } @@ -488,8 +446,8 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType()); Assert1(PTy, "wrong type for intrinsic global variable", &GV); if (GV.hasInitializer()) { - Constant *Init = GV.getInitializer(); - ConstantArray *InitArray = dyn_cast<ConstantArray>(Init); + const Constant *Init = GV.getInitializer(); + const ConstantArray *InitArray = dyn_cast<ConstantArray>(Init); Assert1(InitArray, "wrong initalizer for intrinsic global variable", Init); for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) { @@ -503,6 +461,11 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { } } + Assert1(!GV.hasDLLImportStorageClass() || + (GV.isDeclaration() && GV.hasExternalLinkage()) || + GV.hasAvailableExternallyLinkage(), + "Global is marked as dllimport, but not external", &GV); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; @@ -533,46 +496,62 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { visitGlobalValue(GV); } -void Verifier::visitGlobalAlias(GlobalAlias &GA) { - Assert1(!GA.getName().empty(), - "Alias name cannot be empty!", &GA); - Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()), - "Alias should have external or external weak linkage!", &GA); - Assert1(GA.getAliasee(), - "Aliasee cannot be NULL!", &GA); - Assert1(GA.getType() == GA.getAliasee()->getType(), - "Alias and aliasee types should match!", &GA); - Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); - - Constant *Aliasee = GA.getAliasee(); +void Verifier::visitAliaseeSubExpr(const GlobalAlias &GA, const Constant &C) { + SmallPtrSet<const GlobalAlias*, 4> Visited; + Visited.insert(&GA); + visitAliaseeSubExpr(Visited, GA, C); +} - 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); +void Verifier::visitAliaseeSubExpr(SmallPtrSet<const GlobalAlias *, 4> &Visited, + const GlobalAlias &GA, const Constant &C) { + if (const auto *GV = dyn_cast<GlobalValue>(&C)) { + Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA); - if (CE->getOpcode() == Instruction::BitCast) { - unsigned SrcAS = CE->getOperand(0)->getType()->getPointerAddressSpace(); - unsigned DstAS = CE->getType()->getPointerAddressSpace(); + if (const auto *GA2 = dyn_cast<GlobalAlias>(GV)) { + Assert1(Visited.insert(GA2), "Aliases cannot form a cycle", &GA); - Assert1(SrcAS == DstAS, - "Alias bitcasts cannot be between different address spaces", + Assert1(!GA2->mayBeOverridden(), "Alias cannot point to a weak alias", &GA); + } else { + // Only continue verifying subexpressions of GlobalAliases. + // Do not recurse into global initializers. + return; } } - const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false); - Assert1(Resolved, - "Aliasing chain should end with function or global variable", &GA); + if (const auto *CE = dyn_cast<ConstantExpr>(&C)) + VerifyConstantExprBitcastType(CE); + + for (const Use &U : C.operands()) { + Value *V = &*U; + if (const auto *GA2 = dyn_cast<GlobalAlias>(V)) + visitAliaseeSubExpr(Visited, GA, *GA2->getAliasee()); + else if (const auto *C2 = dyn_cast<Constant>(V)) + visitAliaseeSubExpr(Visited, GA, *C2); + } +} + +void Verifier::visitGlobalAlias(const GlobalAlias &GA) { + Assert1(!GA.getName().empty(), + "Alias name cannot be empty!", &GA); + Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()), + "Alias should have private, internal, linkonce, weak, linkonce_odr, " + "weak_odr, or external linkage!", + &GA); + const Constant *Aliasee = GA.getAliasee(); + Assert1(Aliasee, "Aliasee cannot be NULL!", &GA); + Assert1(GA.getType() == Aliasee->getType(), + "Alias and aliasee types should match!", &GA); + + Assert1(isa<GlobalValue>(Aliasee) || isa<ConstantExpr>(Aliasee), + "Aliasee should be either GlobalValue or ConstantExpr", &GA); + + visitAliaseeSubExpr(GA, *Aliasee); visitGlobalValue(GA); } -void Verifier::visitNamedMDNode(NamedMDNode &NMD) { +void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) { MDNode *MD = NMD.getOperand(i); if (!MD) @@ -580,7 +559,7 @@ void Verifier::visitNamedMDNode(NamedMDNode &NMD) { Assert1(!MD->isFunctionLocal(), "Named metadata operand cannot be function local!", MD); - visitMDNode(*MD, 0); + visitMDNode(*MD, nullptr); } } @@ -606,7 +585,7 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { // If this was an instruction, bb, or argument, verify that it is in the // function that we expect. - Function *ActualF = 0; + Function *ActualF = nullptr; if (Instruction *I = dyn_cast<Instruction>(Op)) ActualF = I->getParent()->getParent(); else if (BasicBlock *BB = dyn_cast<BasicBlock>(Op)) @@ -620,7 +599,22 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } -void Verifier::visitModuleIdents(Module &M) { +void Verifier::visitComdat(const Comdat &C) { + // All Comdat::SelectionKind values other than Comdat::Any require a + // GlobalValue with the same name as the Comdat. + const GlobalValue *GV = M->getNamedValue(C.getName()); + if (C.getSelectionKind() != Comdat::Any) + Assert1(GV, + "comdat selection kind requires a global value with the same name", + &C); + // The Module is invalid if the GlobalValue has private linkage. Entities + // with private linkage don't have entries in the symbol table. + if (GV) + Assert1(!GV->hasPrivateLinkage(), "comdat global value has private linkage", + GV); +} + +void Verifier::visitModuleIdents(const Module &M) { const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); if (!Idents) return; @@ -638,24 +632,24 @@ void Verifier::visitModuleIdents(Module &M) { } } -void Verifier::visitModuleFlags(Module &M) { +void Verifier::visitModuleFlags(const Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; // Scan each flag, and track the flags and requirements. - DenseMap<MDString*, MDNode*> SeenIDs; - SmallVector<MDNode*, 16> Requirements; + DenseMap<const MDString*, const MDNode*> SeenIDs; + SmallVector<const MDNode*, 16> Requirements; for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) { visitModuleFlag(Flags->getOperand(I), SeenIDs, Requirements); } // Validate that the requirements in the module are valid. for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { - MDNode *Requirement = Requirements[I]; - MDString *Flag = cast<MDString>(Requirement->getOperand(0)); - Value *ReqValue = Requirement->getOperand(1); + const MDNode *Requirement = Requirements[I]; + const MDString *Flag = cast<MDString>(Requirement->getOperand(0)); + const Value *ReqValue = Requirement->getOperand(1); - MDNode *Op = SeenIDs.lookup(Flag); + const MDNode *Op = SeenIDs.lookup(Flag); if (!Op) { CheckFailed("invalid requirement on flag, flag is not present in module", Flag); @@ -671,8 +665,10 @@ void Verifier::visitModuleFlags(Module &M) { } } -void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs, - SmallVectorImpl<MDNode*> &Requirements) { +void +Verifier::visitModuleFlag(const MDNode *Op, + DenseMap<const MDString *, const MDNode *> &SeenIDs, + SmallVectorImpl<const MDNode *> &Requirements) { // Each module flag should have three arguments, the merge behavior (a // constant int), the flag ID (an MDString), and the value. Assert1(Op->getNumOperands() == 3, @@ -778,7 +774,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::Builtin || I->getKindAsEnum() == Attribute::NoBuiltin || I->getKindAsEnum() == Attribute::Cold || - I->getKindAsEnum() == Attribute::OptimizeNone) { + I->getKindAsEnum() == Attribute::OptimizeNone || + I->getKindAsEnum() == Attribute::JumpTable) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -813,26 +810,25 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, !Attrs.hasAttribute(Idx, Attribute::Nest) && !Attrs.hasAttribute(Idx, Attribute::StructRet) && !Attrs.hasAttribute(Idx, Attribute::NoCapture) && - !Attrs.hasAttribute(Idx, Attribute::Returned), - "Attribute 'byval', 'nest', 'sret', 'nocapture', and 'returned' " - "do not apply to return values!", V); - - // Check for mutually incompatible attributes. - Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) && - Attrs.hasAttribute(Idx, Attribute::Nest)) || - (Attrs.hasAttribute(Idx, Attribute::ByVal) && - Attrs.hasAttribute(Idx, Attribute::StructRet)) || - (Attrs.hasAttribute(Idx, Attribute::Nest) && - Attrs.hasAttribute(Idx, Attribute::StructRet))), "Attributes " - "'byval, nest, and sret' are incompatible!", V); - - Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) && - Attrs.hasAttribute(Idx, Attribute::Nest)) || - (Attrs.hasAttribute(Idx, Attribute::ByVal) && - Attrs.hasAttribute(Idx, Attribute::InReg)) || - (Attrs.hasAttribute(Idx, Attribute::Nest) && - Attrs.hasAttribute(Idx, Attribute::InReg))), "Attributes " - "'byval, nest, and inreg' are incompatible!", V); + !Attrs.hasAttribute(Idx, Attribute::Returned) && + !Attrs.hasAttribute(Idx, Attribute::InAlloca), + "Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', and " + "'returned' do not apply to return values!", V); + + // Check for mutually incompatible attributes. Only inreg is compatible with + // sret. + unsigned AttrCount = 0; + AttrCount += Attrs.hasAttribute(Idx, Attribute::ByVal); + AttrCount += Attrs.hasAttribute(Idx, Attribute::InAlloca); + AttrCount += Attrs.hasAttribute(Idx, Attribute::StructRet) || + Attrs.hasAttribute(Idx, Attribute::InReg); + AttrCount += Attrs.hasAttribute(Idx, Attribute::Nest); + Assert1(AttrCount <= 1, "Attributes 'byval', 'inalloca', 'inreg', 'nest', " + "and 'sret' are incompatible!", V); + + Assert1(!(Attrs.hasAttribute(Idx, Attribute::InAlloca) && + Attrs.hasAttribute(Idx, Attribute::ReadOnly)), "Attributes " + "'inalloca and readonly' are incompatible!", V); Assert1(!(Attrs.hasAttribute(Idx, Attribute::StructRet) && Attrs.hasAttribute(Idx, Attribute::Returned)), "Attributes " @@ -855,14 +851,18 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, "Wrong types for attribute: " + AttributeFuncs::typeIncompatible(Ty, Idx).getAsString(Idx), V); - if (PointerType *PTy = dyn_cast<PointerType>(Ty)) - Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) || - PTy->getElementType()->isSized(), - "Attribute 'byval' does not support unsized types!", V); - else + if (PointerType *PTy = dyn_cast<PointerType>(Ty)) { + if (!PTy->getElementType()->isSized()) { + Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) && + !Attrs.hasAttribute(Idx, Attribute::InAlloca), + "Attributes 'byval' and 'inalloca' do not support unsized types!", + V); + } + } else { Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal), "Attribute 'byval' only applies to parameters with pointer type!", V); + } } // VerifyFunctionAttrs - Check parameter attributes against a function type. @@ -874,6 +874,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, bool SawNest = false; bool SawReturned = false; + bool SawSRet = false; for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { unsigned Idx = Attrs.getSlotIndex(i); @@ -904,8 +905,17 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, SawReturned = true; } - if (Attrs.hasAttribute(Idx, Attribute::StructRet)) - Assert1(Idx == 1, "Attribute sret is not on first parameter!", V); + if (Attrs.hasAttribute(Idx, Attribute::StructRet)) { + Assert1(!SawSRet, "Cannot have multiple 'sret' parameters!", V); + Assert1(Idx == 1 || Idx == 2, + "Attribute 'sret' is not on first or second parameter!", V); + SawSRet = true; + } + + if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) { + Assert1(Idx == FT->getNumParams(), + "inalloca isn't on the last parameter!", V); + } } if (!Attrs.hasAttributes(AttributeSet::FunctionIndex)) @@ -939,6 +949,14 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, Attribute::MinSize), "Attributes 'minsize and optnone' are incompatible!", V); } + + if (Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::JumpTable)) { + const GlobalValue *GV = cast<GlobalValue>(V); + Assert1(GV->hasUnnamedAddr(), + "Attribute 'jumptable' requires 'unnamed_addr'", V); + + } } void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) { @@ -1001,7 +1019,7 @@ bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) { // visitFunction - Verify that a function is ok. // -void Verifier::visitFunction(Function &F) { +void Verifier::visitFunction(const Function &F) { // Check function arguments. FunctionType *FT = F.getFunctionType(); unsigned NumArgs = F.arg_size(); @@ -1059,8 +1077,8 @@ void Verifier::visitFunction(Function &F) { // Check that the argument values match the function type for this function... unsigned i = 0; - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); - I != E; ++I, ++i) { + for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; + ++I, ++i) { Assert2(I->getType() == FT->getParamType(i), "Argument value does not match function argument type!", I, FT->getParamType(i)); @@ -1074,8 +1092,7 @@ void Verifier::visitFunction(Function &F) { if (F.isMaterializable()) { // Function has a body somewhere we can't see. } else if (F.isDeclaration()) { - Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() || - F.hasExternalWeakLinkage(), + Assert1(F.hasExternalLinkage() || F.hasExternalWeakLinkage(), "invalid linkage type for function declaration", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It @@ -1083,13 +1100,13 @@ void Verifier::visitFunction(Function &F) { Assert1(!isLLVMdotName, "llvm intrinsics cannot be defined!", &F); // Check the entry node - BasicBlock *Entry = &F.getEntryBlock(); + const 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(), + Assert1(!BlockAddress::lookup(Entry)->isConstantUsed(), "blockaddress may not be used with the entry block!", Entry); } } @@ -1101,6 +1118,11 @@ void Verifier::visitFunction(Function &F) { if (F.hasAddressTaken(&U)) Assert1(0, "Invalid user of intrinsic instruction!", U); } + + Assert1(!F.hasDLLImportStorageClass() || + (F.isDeclaration() && F.hasExternalLinkage()) || + F.hasAvailableExternallyLinkage(), + "Function is marked as dllimport, but not external.", &F); } // verifyBasicBlock - Verify that a basic block is well formed... @@ -1533,6 +1555,16 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); + // Conservatively check the inalloca argument. + // We have a bug if we can find that there is an underlying alloca without + // inalloca. + if (CS.hasInAllocaArgument()) { + Value *InAllocaArg = CS.getArgument(FTy->getNumParams() - 1); + if (auto AI = dyn_cast<AllocaInst>(InAllocaArg->stripInBoundsOffsets())) + Assert2(AI->isUsedWithInAlloca(), + "inalloca argument for call has mismatched alloca", AI, I); + } + if (FTy->isVarArg()) { // FIXME? is 'nest' even legal here? bool SawNest = false; @@ -1566,11 +1598,15 @@ void Verifier::VerifyCallSite(CallSite CS) { Assert1(!Attrs.hasAttribute(Idx, Attribute::StructRet), "Attribute 'sret' cannot be used for vararg call arguments!", I); + + if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) + Assert1(Idx == CS.arg_size(), "inalloca isn't on the last argument!", + I); } } // Verify that there's no metadata unless it's a direct call to an intrinsic. - if (CS.getCalledFunction() == 0 || + if (CS.getCalledFunction() == nullptr || !CS.getCalledFunction()->getName().startswith("llvm.")) { for (FunctionType::param_iterator PI = FTy->param_begin(), PE = FTy->param_end(); PI != PE; ++PI) @@ -1581,9 +1617,102 @@ void Verifier::VerifyCallSite(CallSite CS) { visitInstruction(*I); } +/// Two types are "congruent" if they are identical, or if they are both pointer +/// types with different pointee types and the same address space. +static bool isTypeCongruent(Type *L, Type *R) { + if (L == R) + return true; + PointerType *PL = dyn_cast<PointerType>(L); + PointerType *PR = dyn_cast<PointerType>(R); + if (!PL || !PR) + return false; + return PL->getAddressSpace() == PR->getAddressSpace(); +} + +static AttrBuilder getParameterABIAttributes(int I, AttributeSet Attrs) { + static const Attribute::AttrKind ABIAttrs[] = { + Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca, + Attribute::InReg, Attribute::Returned}; + AttrBuilder Copy; + for (auto AK : ABIAttrs) { + if (Attrs.hasAttribute(I + 1, AK)) + Copy.addAttribute(AK); + } + if (Attrs.hasAttribute(I + 1, Attribute::Alignment)) + Copy.addAlignmentAttr(Attrs.getParamAlignment(I + 1)); + return Copy; +} + +void Verifier::verifyMustTailCall(CallInst &CI) { + Assert1(!CI.isInlineAsm(), "cannot use musttail call with inline asm", &CI); + + // - The caller and callee prototypes must match. Pointer types of + // parameters or return types may differ in pointee type, but not + // address space. + Function *F = CI.getParent()->getParent(); + auto GetFnTy = [](Value *V) { + return cast<FunctionType>( + cast<PointerType>(V->getType())->getElementType()); + }; + FunctionType *CallerTy = GetFnTy(F); + FunctionType *CalleeTy = GetFnTy(CI.getCalledValue()); + Assert1(CallerTy->getNumParams() == CalleeTy->getNumParams(), + "cannot guarantee tail call due to mismatched parameter counts", &CI); + Assert1(CallerTy->isVarArg() == CalleeTy->isVarArg(), + "cannot guarantee tail call due to mismatched varargs", &CI); + Assert1(isTypeCongruent(CallerTy->getReturnType(), CalleeTy->getReturnType()), + "cannot guarantee tail call due to mismatched return types", &CI); + for (int I = 0, E = CallerTy->getNumParams(); I != E; ++I) { + Assert1( + isTypeCongruent(CallerTy->getParamType(I), CalleeTy->getParamType(I)), + "cannot guarantee tail call due to mismatched parameter types", &CI); + } + + // - The calling conventions of the caller and callee must match. + Assert1(F->getCallingConv() == CI.getCallingConv(), + "cannot guarantee tail call due to mismatched calling conv", &CI); + + // - All ABI-impacting function attributes, such as sret, byval, inreg, + // returned, and inalloca, must match. + AttributeSet CallerAttrs = F->getAttributes(); + AttributeSet CalleeAttrs = CI.getAttributes(); + for (int I = 0, E = CallerTy->getNumParams(); I != E; ++I) { + AttrBuilder CallerABIAttrs = getParameterABIAttributes(I, CallerAttrs); + AttrBuilder CalleeABIAttrs = getParameterABIAttributes(I, CalleeAttrs); + Assert2(CallerABIAttrs == CalleeABIAttrs, + "cannot guarantee tail call due to mismatched ABI impacting " + "function attributes", &CI, CI.getOperand(I)); + } + + // - The call must immediately precede a :ref:`ret <i_ret>` instruction, + // or a pointer bitcast followed by a ret instruction. + // - The ret instruction must return the (possibly bitcasted) value + // produced by the call or void. + Value *RetVal = &CI; + Instruction *Next = CI.getNextNode(); + + // Handle the optional bitcast. + if (BitCastInst *BI = dyn_cast_or_null<BitCastInst>(Next)) { + Assert1(BI->getOperand(0) == RetVal, + "bitcast following musttail call must use the call", BI); + RetVal = BI; + Next = BI->getNextNode(); + } + + // Check the return. + ReturnInst *Ret = dyn_cast_or_null<ReturnInst>(Next); + Assert1(Ret, "musttail call must be precede a ret with an optional bitcast", + &CI); + Assert1(!Ret->getReturnValue() || Ret->getReturnValue() == RetVal, + "musttail call result must be returned", Ret); +} + void Verifier::visitCallInst(CallInst &CI) { VerifyCallSite(&CI); + if (CI.isMustTailCall()) + verifyMustTailCall(CI); + if (Function *F = CI.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) visitIntrinsicFunctionCall(ID, CI); @@ -1764,6 +1893,8 @@ void Verifier::visitLoadInst(LoadInst &LI) { Type *ElTy = PTy->getElementType(); Assert2(ElTy == LI.getType(), "Load result type does not match pointer operand type!", &LI, ElTy); + Assert1(LI.getAlignment() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &LI); if (LI.isAtomic()) { Assert1(LI.getOrdering() != Release && LI.getOrdering() != AcquireRelease, "Load cannot have Release ordering", &LI); @@ -1771,11 +1902,11 @@ void Verifier::visitLoadInst(LoadInst &LI) { "Atomic load must specify explicit alignment", &LI); if (!ElTy->isPointerTy()) { Assert2(ElTy->isIntegerTy(), - "atomic store operand must have integer type!", + "atomic load operand must have integer type!", &LI, ElTy); unsigned Size = ElTy->getPrimitiveSizeInBits(); Assert2(Size >= 8 && !(Size & (Size - 1)), - "atomic store operand must be power-of-two byte-sized integer", + "atomic load operand must be power-of-two byte-sized integer", &LI, ElTy); } } else { @@ -1839,6 +1970,8 @@ void Verifier::visitStoreInst(StoreInst &SI) { Assert2(ElTy == SI.getOperand(0)->getType(), "Stored value type does not match pointer operand type!", &SI, ElTy); + Assert1(SI.getAlignment() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &SI); if (SI.isAtomic()) { Assert1(SI.getOrdering() != Acquire && SI.getOrdering() != AcquireRelease, "Store cannot have Acquire ordering", &SI); @@ -1861,22 +1994,39 @@ void Verifier::visitStoreInst(StoreInst &SI) { } void Verifier::visitAllocaInst(AllocaInst &AI) { + SmallPtrSet<const Type*, 4> Visited; PointerType *PTy = AI.getType(); Assert1(PTy->getAddressSpace() == 0, "Allocation instruction pointer not in the generic address space!", &AI); - Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type", + Assert1(PTy->getElementType()->isSized(&Visited), "Cannot allocate unsized type", &AI); Assert1(AI.getArraySize()->getType()->isIntegerTy(), "Alloca array size must have integer type", &AI); + Assert1(AI.getAlignment() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &AI); + visitInstruction(AI); } void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) { - Assert1(CXI.getOrdering() != NotAtomic, + + // FIXME: more conditions??? + Assert1(CXI.getSuccessOrdering() != NotAtomic, + "cmpxchg instructions must be atomic.", &CXI); + Assert1(CXI.getFailureOrdering() != NotAtomic, "cmpxchg instructions must be atomic.", &CXI); - Assert1(CXI.getOrdering() != Unordered, + Assert1(CXI.getSuccessOrdering() != Unordered, "cmpxchg instructions cannot be unordered.", &CXI); + Assert1(CXI.getFailureOrdering() != Unordered, + "cmpxchg instructions cannot be unordered.", &CXI); + Assert1(CXI.getSuccessOrdering() >= CXI.getFailureOrdering(), + "cmpxchg instructions be at least as constrained on success as fail", + &CXI); + Assert1(CXI.getFailureOrdering() != Release && + CXI.getFailureOrdering() != AcquireRelease, + "cmpxchg failure ordering cannot include release semantics", &CXI); + PointerType *PTy = dyn_cast<PointerType>(CXI.getOperand(0)->getType()); Assert1(PTy, "First cmpxchg operand must be a pointer.", &CXI); Type *ElTy = PTy->getElementType(); @@ -1981,8 +2131,7 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { Assert1(isa<Constant>(PersonalityFn), "Personality function is not constant!", &LPI); for (unsigned i = 0, e = LPI.getNumClauses(); i < e; ++i) { - Value *Clause = LPI.getClause(i); - Assert1(isa<Constant>(Clause), "Clause is not constant!", &LPI); + Constant *Clause = LPI.getClause(i); if (LPI.isCatch(i)) { Assert1(isa<PointerType>(Clause->getType()), "Catch operand does not have pointer type!", &LPI); @@ -2007,7 +2156,7 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { } const Use &U = I.getOperandUse(i); - Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, U), + Assert2(InstsInThisBlock.count(Op) || DT.dominates(Op, U), "Instruction does not dominate all uses!", Op, &I); } @@ -2018,10 +2167,10 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(BB, "Instruction not embedded in basic block!", &I); if (!isa<PHINode>(I)) { // Check that non-phi nodes are not self referential - for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) - Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB), + for (User *U : I.users()) { + Assert1(U != (User*)&I || !DT.isReachableFromEntry(BB), "Only PHI nodes may reference their own value!", &I); + } } // Check that void typed values don't have names @@ -2043,19 +2192,18 @@ void Verifier::visitInstruction(Instruction &I) { // Check that all uses of the instruction, if they are instructions // themselves, actually have parent basic blocks. If the use is not an // instruction, it is an error! - for (User::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) { - if (Instruction *Used = dyn_cast<Instruction>(*UI)) - Assert2(Used->getParent() != 0, "Instruction referencing instruction not" - " embedded in a basic block!", &I, Used); + for (Use &U : I.uses()) { + if (Instruction *Used = dyn_cast<Instruction>(U.getUser())) + Assert2(Used->getParent() != nullptr, "Instruction referencing" + " instruction not embedded in a basic block!", &I, Used); else { - CheckFailed("Use of instruction is not an instruction!", *UI); + CheckFailed("Use of instruction is not an instruction!", U); return; } } for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { - Assert1(I.getOperand(i) != 0, "Instruction has null operand!", &I); + Assert1(I.getOperand(i) != nullptr, "Instruction has null operand!", &I); // Check to make sure that only first-class-values are operands to // instructions. @@ -2071,7 +2219,7 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(!F->isIntrinsic() || isa<CallInst>(I) || F->getIntrinsicID() == Intrinsic::donothing, "Cannot invoke an intrinsinc other than donothing", &I); - Assert1(F->getParent() == Mod, "Referencing function in another module!", + Assert1(F->getParent() == M, "Referencing function in another module!", &I); } else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) { Assert1(OpBB->getParent() == BB->getParent(), @@ -2080,7 +2228,7 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(OpArg->getParent() == BB->getParent(), "Referring to an argument in another function!", &I); } else if (GlobalValue *GV = dyn_cast<GlobalValue>(I.getOperand(i))) { - Assert1(GV->getParent() == Mod, "Referencing global in another module!", + Assert1(GV->getParent() == M, "Referencing global in another module!", &I); } else if (isa<Instruction>(I.getOperand(i))) { verifyDominatesUse(I, i); @@ -2127,12 +2275,8 @@ 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)); - } + Assert1(!MD || isa<LoadInst>(I) || isa<CallInst>(I) || isa<InvokeInst>(I), + "Ranges are only for loads, calls and invokes!", &I); InstsInThisBlock.insert(&I); } @@ -2163,18 +2307,18 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); case IITDescriptor::Vector: { VectorType *VT = dyn_cast<VectorType>(Ty); - return VT == 0 || VT->getNumElements() != D.Vector_Width || + return !VT || VT->getNumElements() != D.Vector_Width || VerifyIntrinsicType(VT->getElementType(), Infos, ArgTys); } case IITDescriptor::Pointer: { PointerType *PT = dyn_cast<PointerType>(Ty); - return PT == 0 || PT->getAddressSpace() != D.Pointer_AddressSpace || + return !PT || 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) + if (!ST || ST->getNumElements() != D.Struct_NumElements) return true; for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) @@ -2202,18 +2346,41 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, } llvm_unreachable("all argument kinds not covered"); - case IITDescriptor::ExtendVecArgument: + case IITDescriptor::ExtendArgument: { // This may only be used when referring to a previous vector argument. - return D.getArgumentNumber() >= ArgTys.size() || - !isa<VectorType>(ArgTys[D.getArgumentNumber()]) || - VectorType::getExtendedElementVectorType( - cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty; + if (D.getArgumentNumber() >= ArgTys.size()) + return true; - case IITDescriptor::TruncVecArgument: + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) + NewTy = VectorType::getExtendedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth()); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::TruncArgument: { + // This may only be used when referring to a previous vector argument. + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast<VectorType>(NewTy)) + NewTy = VectorType::getTruncatedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::HalfVecArgument: // This may only be used when referring to a previous vector argument. return D.getArgumentNumber() >= ArgTys.size() || !isa<VectorType>(ArgTys[D.getArgumentNumber()]) || - VectorType::getTruncatedElementVectorType( + VectorType::getHalfElementsVectorType( cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty; } llvm_unreachable("unhandled"); @@ -2284,8 +2451,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // know they are legal for the intrinsic!) get the intrinsic name through the // usual means. This allows us to verify the mangling of argument types into // the name. - Assert1(Intrinsic::getName(ID, ArgTys) == IF->getName(), - "Intrinsic name not mangled correctly for type arguments!", IF); + const std::string ExpectedName = Intrinsic::getName(ID, ArgTys); + Assert1(ExpectedName == IF->getName(), + "Intrinsic name not mangled correctly for type arguments! " + "Should be: " + ExpectedName, IF); // If the intrinsic takes MDNode arguments, verify that they are either global // or are local to *this* function. @@ -2308,17 +2477,7 @@ 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: @@ -2380,63 +2539,176 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { } } -void Verifier::verifyDebugInfo() { +void DebugInfoVerifier::verifyDebugInfo() { + if (!VerifyDebugInfo) + return; + + DebugInfoFinder Finder; + Finder.processModule(*M); + processInstructions(Finder); + // 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); + // + // NOTE: The loud braces are necessary for MSVC compatibility. + for (DICompileUnit CU : Finder.compile_units()) { + Assert1(CU.Verify(), "DICompileUnit does not Verify!", CU); } + for (DISubprogram S : Finder.subprograms()) { + Assert1(S.Verify(), "DISubprogram does not Verify!", S); + } + for (DIGlobalVariable GV : Finder.global_variables()) { + Assert1(GV.Verify(), "DIGlobalVariable does not Verify!", GV); + } + for (DIType T : Finder.types()) { + Assert1(T.Verify(), "DIType does not Verify!", T); + } + for (DIScope S : Finder.scopes()) { + Assert1(S.Verify(), "DIScope does not Verify!", S); + } +} + +void DebugInfoVerifier::processInstructions(DebugInfoFinder &Finder) { + for (const Function &F : *M) + for (auto I = inst_begin(&F), E = inst_end(&F); I != E; ++I) { + if (MDNode *MD = I->getMetadata(LLVMContext::MD_dbg)) + Finder.processLocation(*M, DILocation(MD)); + if (const CallInst *CI = dyn_cast<CallInst>(&*I)) + processCallInst(Finder, *CI); + } +} + +void DebugInfoVerifier::processCallInst(DebugInfoFinder &Finder, + const CallInst &CI) { + if (Function *F = CI.getCalledFunction()) + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) + switch (ID) { + case Intrinsic::dbg_declare: + Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI)); + break; + case Intrinsic::dbg_value: + Finder.processValue(*M, cast<DbgValueInst>(&CI)); + break; + default: + break; + } } //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// -FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) { - return new Verifier(action); +bool llvm::verifyFunction(const Function &f, raw_ostream *OS) { + Function &F = const_cast<Function &>(f); + assert(!F.isDeclaration() && "Cannot verify external functions"); + + raw_null_ostream NullStr; + Verifier V(OS ? *OS : NullStr); + + // Note that this function's return value is inverted from what you would + // expect of a function called "verify". + return !V.verify(F); } +bool llvm::verifyModule(const Module &M, raw_ostream *OS) { + raw_null_ostream NullStr; + Verifier V(OS ? *OS : NullStr); -/// verifyFunction - Check a function for errors, printing messages on stderr. -/// Return true if the function is corrupt. -/// -bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) { - Function &F = const_cast<Function&>(f); - assert(!F.isDeclaration() && "Cannot verify external functions"); + bool Broken = false; + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) + Broken |= !V.verify(*I); - FunctionPassManager FPM(F.getParent()); - Verifier *V = new Verifier(action); - FPM.add(V); - FPM.doInitialization(); - FPM.run(F); - return V->Broken; + // Note that this function's return value is inverted from what you would + // expect of a function called "verify". + DebugInfoVerifier DIV(OS ? *OS : NullStr); + return !V.verify(M) || !DIV.verify(M) || Broken; } -/// verifyModule - Check a module for errors, printing messages on stderr. -/// Return true if the module is corrupt. -/// -bool llvm::verifyModule(const Module &M, VerifierFailureAction action, - std::string *ErrorInfo) { - PassManager PM; - Verifier *V = new Verifier(action); - PM.add(V); - PM.run(const_cast<Module&>(M)); - - if (ErrorInfo && V->Broken) - *ErrorInfo = V->MessagesStr.str(); - return V->Broken; +namespace { +struct VerifierLegacyPass : public FunctionPass { + static char ID; + + Verifier V; + bool FatalErrors; + + VerifierLegacyPass() : FunctionPass(ID), FatalErrors(true) { + initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + explicit VerifierLegacyPass(bool FatalErrors) + : FunctionPass(ID), V(dbgs()), FatalErrors(FatalErrors) { + initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override { + if (!V.verify(F) && FatalErrors) + report_fatal_error("Broken function found, compilation aborted!"); + + return false; + } + + bool doFinalization(Module &M) override { + if (!V.verify(M) && FatalErrors) + report_fatal_error("Broken module found, compilation aborted!"); + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; +struct DebugInfoVerifierLegacyPass : public ModulePass { + static char ID; + + DebugInfoVerifier V; + bool FatalErrors; + + DebugInfoVerifierLegacyPass() : ModulePass(ID), FatalErrors(true) { + initializeDebugInfoVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + explicit DebugInfoVerifierLegacyPass(bool FatalErrors) + : ModulePass(ID), V(dbgs()), FatalErrors(FatalErrors) { + initializeDebugInfoVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + if (!V.verify(M) && FatalErrors) + report_fatal_error("Broken debug info found, compilation aborted!"); + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; +} + +char VerifierLegacyPass::ID = 0; +INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false) + +char DebugInfoVerifierLegacyPass::ID = 0; +INITIALIZE_PASS(DebugInfoVerifierLegacyPass, "verify-di", "Debug Info Verifier", + false, false) + +FunctionPass *llvm::createVerifierPass(bool FatalErrors) { + return new VerifierLegacyPass(FatalErrors); +} + +ModulePass *llvm::createDebugInfoVerifierPass(bool FatalErrors) { + return new DebugInfoVerifierLegacyPass(FatalErrors); +} + +PreservedAnalyses VerifierPass::run(Module *M) { + if (verifyModule(*M, &dbgs()) && FatalErrors) + report_fatal_error("Broken module found, compilation aborted!"); + + return PreservedAnalyses::all(); +} + +PreservedAnalyses VerifierPass::run(Function *F) { + if (verifyFunction(*F, &dbgs()) && FatalErrors) + report_fatal_error("Broken function found, compilation aborted!"); + + return PreservedAnalyses::all(); } diff --git a/contrib/llvm/lib/IR/module.modulemap b/contrib/llvm/lib/IR/module.modulemap new file mode 100644 index 0000000..9698e91 --- /dev/null +++ b/contrib/llvm/lib/IR/module.modulemap @@ -0,0 +1 @@ +module IR { requires cplusplus umbrella "." module * { export * } } |