diff options
author | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
commit | dce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch) | |
tree | dcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/IR | |
parent | 220b921aed042f9e520c26cffd8282a94c66c3d5 (diff) | |
download | external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2 |
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'lib/IR')
42 files changed, 1687 insertions, 912 deletions
diff --git a/lib/IR/Android.mk b/lib/IR/Android.mk index 071bb04..dd95703 100644 --- a/lib/IR/Android.mk +++ b/lib/IR/Android.mk @@ -30,6 +30,7 @@ vmcore_SRC_FILES := \ LeakDetector.cpp \ LegacyPassManager.cpp \ Mangler.cpp \ + MDBuilder.cpp \ Metadata.cpp \ Module.cpp \ Pass.cpp \ diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index d4670e4..0fef0d0 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -51,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) { @@ -78,7 +78,6 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break; case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break; case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break; - case CallingConv::X86_CDeclMethod:Out << "x86_cdeclmethodcc"; break; case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; break; case CallingConv::ARM_APCS: Out << "arm_apcscc"; break; case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break; @@ -421,10 +420,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 +435,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) @@ -560,7 +559,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"); } @@ -1048,7 +1047,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); @@ -1126,12 +1125,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. @@ -1160,7 +1153,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Slot = Machine->getLocalSlot(V); } delete Machine; - Machine = 0; + Machine = nullptr; } else { Slot = -1; } @@ -1194,7 +1187,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; } @@ -1259,7 +1252,7 @@ void AssemblyWriter::writeAtomicCmpXchg(AtomicOrdering SuccessOrdering, void AssemblyWriter::writeParamOperand(const Value *Operand, AttributeSet Attrs, unsigned Idx) { - if (Operand == 0) { + if (!Operand) { Out << "<null operand!>"; return; } @@ -1500,10 +1493,16 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { PrintLinkage(GA->getLinkage(), Out); + PointerType *Ty = GA->getType(); const Constant *Aliasee = GA->getAliasee(); + if (!Aliasee || Ty != Aliasee->getType()) { + if (unsigned AddressSpace = Ty->getAddressSpace()) + Out << "addrspace(" << AddressSpace << ") "; + TypePrinter.print(Ty->getElementType(), Out); + Out << ", "; + } - if (Aliasee == 0) { - TypePrinter.print(GA->getType(), Out); + if (!Aliasee) { Out << " <<NULL ALIASEE>>"; } else { writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee)); @@ -1707,7 +1706,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? @@ -1774,8 +1773,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(); @@ -1804,7 +1807,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()) { @@ -2147,15 +2150,15 @@ 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) { + if (!this) { OS << "<null Type>"; return; } @@ -2170,24 +2173,24 @@ void Type::print(raw_ostream &OS) const { } } -void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { - if (this == 0) { +void Value::print(raw_ostream &ROS) const { + if (!this) { ROS << "printing a <null> value\n"; return; } 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)) @@ -2197,20 +2200,18 @@ 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)) { 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!"); } } @@ -2220,7 +2221,7 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) cons if (!PrintType && ((!isa<Constant>(this) && !isa<MDNode>(this)) || hasName() || isa<GlobalValue>(this))) { - WriteAsOperandInternal(O, this, 0, 0, M); + WriteAsOperandInternal(O, this, nullptr, nullptr, M); return; } @@ -2235,12 +2236,7 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) cons O << ' '; } - WriteAsOperandInternal(O, this, &TypePrinter, 0, M); -} - -// Value::printCustom - subclasses should override this to implement printing. -void Value::printCustom(raw_ostream &OS) const { - llvm_unreachable("Unknown value to print out!"); + WriteAsOperandInternal(O, this, &TypePrinter, nullptr, M); } // Value::dump - allow easy printing of Values from the debugger. @@ -2250,7 +2246,7 @@ 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); } // 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/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 9d9d948..a9074bb 100644 --- a/lib/IR/Attributes.cpp +++ b/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" @@ -192,6 +193,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)) @@ -391,6 +394,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { case Attribute::Builtin: return 1ULL << 41; case Attribute::OptimizeNone: return 1ULL << 42; case Attribute::InAlloca: return 1ULL << 43; + case Attribute::NonNull: return 1ULL << 44; } llvm_unreachable("Unsupported attribute type"); } @@ -402,7 +406,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; @@ -595,7 +599,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(); @@ -617,9 +622,9 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, AttrBuilder &B) { } // 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); } @@ -836,7 +841,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), @@ -877,14 +882,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 { @@ -1175,6 +1180,7 @@ AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { .addAttribute(Attribute::Nest) .addAttribute(Attribute::NoAlias) .addAttribute(Attribute::NoCapture) + .addAttribute(Attribute::NonNull) .addAttribute(Attribute::ReadNone) .addAttribute(Attribute::ReadOnly) .addAttribute(Attribute::StructRet) diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index b7429b3..e255113 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -115,7 +115,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name == "x86.avx.movnt.ps.256" || Name == "x86.sse42.crc32.64.8" || (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) { - NewFn = 0; + NewFn = nullptr; return true; } // SSE4.1 ptest functions may have an old signature. @@ -158,7 +158,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. @@ -170,7 +170,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; } @@ -453,9 +508,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()) { @@ -469,12 +524,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() && @@ -489,7 +544,7 @@ 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 diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index 3079f0a..ba07433 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -27,7 +27,7 @@ using namespace llvm; ValueSymbolTable *BasicBlock::getValueSymbolTable() { if (Function *F = getParent()) return &F->getValueSymbolTable(); - return 0; + return nullptr; } const DataLayout *BasicBlock::getDataLayout() const { @@ -45,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); @@ -81,7 +81,7 @@ BasicBlock::~BasicBlock() { } } - assert(getParent() == 0 && "BasicBlock still linked into the program!"); + assert(getParent() == nullptr && "BasicBlock still linked into the program!"); dropAllReferences(); InstList.clear(); } @@ -122,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()); } @@ -186,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, @@ -199,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. } @@ -277,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); diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt index 09117aa..b027ae5 100644 --- a/lib/IR/CMakeLists.txt +++ b/lib/IR/CMakeLists.txt @@ -7,12 +7,12 @@ add_llvm_library(LLVMCore ConstantRange.cpp Constants.cpp Core.cpp - DiagnosticInfo.cpp - DiagnosticPrinter.cpp DIBuilder.cpp DataLayout.cpp DebugInfo.cpp DebugLoc.cpp + DiagnosticInfo.cpp + DiagnosticPrinter.cpp Dominators.cpp Function.cpp GCOV.cpp @@ -28,6 +28,7 @@ add_llvm_library(LLVMCore LLVMContextImpl.cpp LeakDetector.cpp LegacyPassManager.cpp + MDBuilder.cpp Mangler.cpp Metadata.cpp Module.cpp diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 612aba0..706e66f 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -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); @@ -582,7 +582,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 +595,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 +643,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 +655,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 +685,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; } } @@ -746,7 +746,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2)); } - return 0; + return nullptr; } Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, @@ -766,14 +766,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; @@ -803,7 +803,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(); @@ -842,7 +842,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, @@ -863,8 +863,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)); @@ -1209,7 +1209,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 @@ -1289,7 +1289,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()) @@ -1355,7 +1355,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()) @@ -1885,7 +1885,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 @@ -1951,7 +1951,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())); } @@ -1965,7 +1965,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())); } @@ -1977,7 +1977,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; @@ -2072,7 +2072,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])) { @@ -2130,7 +2130,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/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index 2a3a5fd..bb8d60b 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -182,13 +182,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 +197,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; } @@ -309,7 +310,7 @@ bool Constant::isThreadDependent() const { bool Constant::isConstantUsed() const { for (const User *U : users()) { const Constant *UC = dyn_cast<Constant>(U); - if (UC == 0 || isa<GlobalValue>(UC)) + if (!UC || isa<GlobalValue>(UC)) return true; if (UC->isConstantUsed()) @@ -397,7 +398,7 @@ void Constant::removeDeadConstantUsers() const { 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; @@ -431,7 +432,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"); } @@ -644,7 +645,7 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) { } 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"); } @@ -1235,7 +1236,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; @@ -1283,7 +1284,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 @@ -1294,7 +1295,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; } @@ -1315,7 +1316,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; @@ -1335,7 +1336,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; @@ -1353,14 +1354,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"); @@ -1377,10 +1378,10 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { if (!BB->hasAddressTaken()) - return 0; + return nullptr; const Function *F = BB->getParent(); - assert(F != 0 && "Block must have a parent"); + 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!"); @@ -1411,7 +1412,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 @@ -1792,7 +1793,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 }; @@ -1936,8 +1937,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. @@ -1957,7 +1958,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)) @@ -2145,7 +2146,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: @@ -2168,7 +2169,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); @@ -2285,7 +2286,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; @@ -2312,7 +2313,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"); @@ -2333,7 +2334,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(); @@ -2561,7 +2562,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); @@ -2609,7 +2610,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)) { @@ -2695,7 +2696,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) { diff --git a/lib/IR/ConstantsContext.h b/lib/IR/ConstantsContext.h index 59b9d4d..f06509f 100644 --- a/lib/IR/ConstantsContext.h +++ b/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> @@ -584,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? @@ -720,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/lib/IR/Core.cpp b/lib/IR/Core.cpp index f52f466..27ce503 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -17,6 +17,8 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" @@ -28,6 +30,7 @@ #include "llvm/PassManager.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/Threading.h" @@ -39,6 +42,8 @@ using namespace llvm; +#define DEBUG_TYPE "ir" + void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreeWrapperPassPass(Registry); initializePrintModulePassWrapperPass(Registry); @@ -76,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); } @@ -89,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 ---------------------------------------------===*/ @@ -136,7 +190,7 @@ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, return true; } - unwrap(M)->print(dest, NULL); + unwrap(M)->print(dest, nullptr); if (!error.empty()) { *ErrorMessage = strdup(error.c_str()); @@ -150,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()); @@ -374,7 +428,7 @@ const char *LLVMGetStructName(LLVMTypeRef Ty) { StructType *Type = unwrap<StructType>(Ty); if (!Type->hasName()) - return 0; + return nullptr; return Type->getName().data(); } @@ -496,7 +550,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 ................................................--*/ @@ -513,7 +568,7 @@ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value *V = unwrap(Val); Value::use_iterator I = V->use_begin(); if (I == V->use_end()) - return 0; + return nullptr; return wrap(&*I); } @@ -521,7 +576,7 @@ LLVMUseRef LLVMGetNextUse(LLVMUseRef U) { Use *Next = unwrap(U)->getNext(); if (Next) return wrap(Next); - return 0; + return nullptr; } LLVMValueRef LLVMGetUser(LLVMUseRef U) { @@ -611,7 +666,7 @@ const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) { return S->getString().data(); } *Len = 0; - return 0; + return nullptr; } unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) @@ -650,7 +705,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); } @@ -1235,7 +1290,7 @@ const char *LLVMGetSection(LLVMValueRef Global) { } void LLVMSetSection(LLVMValueRef Global, const char *Section) { - unwrap<GlobalValue>(Global)->setSection(Section); + unwrap<GlobalObject>(Global)->setSection(Section); } LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { @@ -1285,7 +1340,7 @@ unsigned LLVMGetAlignment(LLVMValueRef V) { 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); @@ -1302,15 +1357,16 @@ void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { 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) { @@ -1321,7 +1377,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); } @@ -1329,7 +1385,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); } @@ -1337,7 +1393,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); } @@ -1345,7 +1401,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); } @@ -1356,7 +1412,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()); } @@ -1432,8 +1488,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 .............................................--*/ @@ -1452,7 +1510,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); } @@ -1460,7 +1518,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); } @@ -1468,7 +1526,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); } @@ -1476,7 +1534,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); } @@ -1501,7 +1559,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) { @@ -1582,7 +1640,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); } @@ -1590,7 +1648,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); } @@ -1598,7 +1656,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); } @@ -1606,7 +1664,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); } @@ -1676,7 +1734,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); } @@ -1684,7 +1742,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); } @@ -1692,7 +1750,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); } @@ -1700,7 +1758,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); } @@ -1752,7 +1810,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); } @@ -1760,7 +1818,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); } @@ -1768,7 +1826,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); } @@ -1776,7 +1834,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); } @@ -1939,7 +1997,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)); } @@ -2195,7 +2253,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))); } @@ -2206,13 +2264,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, diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 1ea381a..92edacc 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -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() { @@ -80,7 +81,7 @@ void DIBuilder::finalize() { /// N. static MDNode *getNonCompileUnitScope(MDNode *N) { if (DIDescriptor(N).isCompileUnit()) - return NULL; + return nullptr; return N; } @@ -103,7 +104,7 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, StringRef SplitName, DebugEmissionKind Kind) { - assert(((Lang <= dwarf::DW_LANG_Python && Lang >= dwarf::DW_LANG_C89) || + 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() && @@ -146,13 +147,13 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, } static DIImportedEntity -createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, - unsigned Line, StringRef Name, - SmallVectorImpl<TrackingVH<MDNode> > &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), @@ -160,7 +161,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), @@ -175,33 +176,32 @@ createImportedModule(LLVMContext &C, DIScope Context, DIDescriptor NS, } 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, - AllImportedModules); + unsigned Line) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, + Context, NS, Line, StringRef(), AllImportedModules); } DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, DIScope Decl, - unsigned Line) { - Value *Elts[] = { - GetTagConstant(VMContext, dwarf::DW_TAG_imported_declaration), - Context, - Decl.getRef(), - ConstantInt::get(Type::getInt32Ty(VMContext), Line), - }; - DIImportedEntity M(MDNode::get(VMContext, Elts)); - assert(M.Verify() && "Imported module should be valid"); - AllImportedModules.push_back(TrackingVH<MDNode>(M)); - return M; + unsigned Line, StringRef Name) { + return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, + Context, Decl.getRef(), Line, Name, + AllImportedModules); +} + +DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, + 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 @@ -232,8 +232,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 @@ -260,8 +260,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), @@ -279,8 +279,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 @@ -299,8 +299,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), @@ -317,9 +317,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 @@ -338,9 +338,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 @@ -355,7 +355,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(), @@ -378,9 +377,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 @@ -400,9 +399,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 @@ -631,7 +630,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() && @@ -667,8 +667,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() && @@ -697,12 +698,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()) @@ -718,19 +720,19 @@ DICompositeType DIBuilder::createSubroutineType(DIFile File, 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), Flags), // Flags - NULL, + nullptr, ParameterTypes, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - NULL, - NULL, - NULL // Type Identifer + nullptr, + nullptr, + nullptr // Type Identifer }; return DICompositeType(MDNode::get(VMContext, Elts)); } @@ -755,9 +757,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); @@ -772,8 +775,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), @@ -783,9 +786,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)); } @@ -796,8 +799,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), @@ -807,9 +810,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)); } @@ -890,12 +893,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), + 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), - NULL, - NULL, //TemplateParams - UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) + nullptr, + nullptr, //TemplateParams + UniqueIdentifier.empty() ? nullptr + : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); DICompositeType RetTy(Node); @@ -932,7 +970,7 @@ DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, 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), @@ -1087,7 +1125,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, @@ -1121,7 +1159,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(), @@ -1141,7 +1178,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) }; @@ -1189,6 +1226,13 @@ DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, 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[] = { diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index 6c18387..dea05fb 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -178,7 +178,7 @@ static const LayoutAlignElem DefaultAlignments[] = { void DataLayout::reset(StringRef Desc) { clear(); - LayoutMap = 0; + LayoutMap = nullptr; LittleEndian = false; StackNaturalAlign = 0; ManglingMode = MM_None; @@ -344,7 +344,7 @@ void DataLayout::parseSpecifier(StringRef Desc) { } } -DataLayout::DataLayout(const Module *M) : LayoutMap(0) { +DataLayout::DataLayout(const Module *M) : LayoutMap(nullptr) { const DataLayout *Other = M->getDataLayout(); if (Other) *this = *Other; @@ -357,7 +357,7 @@ bool DataLayout::operator==(const DataLayout &Other) const { StackNaturalAlign == Other.StackNaturalAlign && ManglingMode == Other.ManglingMode && LegalIntWidths == Other.LegalIntWidths && - Alignments == Other.Alignments && Pointers == Pointers; + Alignments == Other.Alignments && Pointers == Other.Pointers; assert(Ret == (getStringRepresentation() == Other.getStringRepresentation())); return Ret; } @@ -488,7 +488,7 @@ void DataLayout::clear() { Alignments.clear(); Pointers.clear(); delete static_cast<StructLayoutMap *>(LayoutMap); - LayoutMap = 0; + LayoutMap = nullptr; } DataLayout::~DataLayout() { @@ -687,7 +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); + return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr); } unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const { @@ -708,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()); @@ -719,7 +719,7 @@ Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const for (unsigned LegalIntWidth : LegalIntWidths) if (Width <= LegalIntWidth) return Type::getIntNTy(C, LegalIntWidth); - return 0; + return nullptr; } unsigned DataLayout::getLargestLegalIntTypeSize() const { diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index c9d68af..db9e56d 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -53,8 +53,8 @@ bool DIDescriptor::Verify() const { } 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); } @@ -73,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()) @@ -85,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()) @@ -102,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()) { @@ -335,7 +335,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!"); @@ -344,13 +344,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 @@ -358,19 +364,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. @@ -759,7 +758,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. diff --git a/lib/IR/DebugLoc.cpp b/lib/IR/DebugLoc.cpp index 1a2521e..43360d3 100644 --- a/lib/IR/DebugLoc.cpp +++ b/lib/IR/DebugLoc.cpp @@ -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; } @@ -96,8 +96,8 @@ DebugLoc DebugLoc::get(unsigned Line, unsigned Col, 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; @@ -106,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, @@ -118,7 +118,7 @@ DebugLoc DebugLoc::get(unsigned Line, unsigned Col, /// getAsMDNode - This method converts the compressed DebugLoc node into a /// 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); @@ -137,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()); } @@ -146,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 { @@ -166,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 //===----------------------------------------------------------------------===// @@ -234,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; } @@ -245,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; } @@ -259,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. @@ -269,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; } @@ -277,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) { @@ -313,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/lib/IR/DiagnosticInfo.cpp b/lib/IR/DiagnosticInfo.cpp index d59d4cf..6eeb162 100644 --- a/lib/IR/DiagnosticInfo.cpp +++ b/lib/IR/DiagnosticInfo.cpp @@ -12,18 +12,80 @@ // 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); @@ -64,3 +126,66 @@ void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const { DP << getFileName() << ": "; DP << getMsg(); } + +bool DiagnosticInfoOptimizationRemarkBase::isLocationAvailable() const { + return getFunction().getParent()->getNamedMetadata("llvm.dbg.cu") != nullptr; +} + +void DiagnosticInfoOptimizationRemarkBase::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 DiagnosticInfoOptimizationRemarkBase::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 DiagnosticInfoOptimizationRemarkBase::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)); +} diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index c2ea0e1..fe32c46 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -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,14 @@ unsigned Argument::getArgNo() const { return ArgIdx; } +/// hasNonNullAttr - Return true if this argument has the nonnull attribute on +/// it in its containing function. +bool Argument::hasNonNullAttr() const { + if (!getType()->isPointerTy()) return false; + return getParent()->getAttributes(). + hasAttribute(getArgNo()+1, Attribute::NonNull); +} + /// hasByValAttr - Return true if this argument has the byval attribute on it /// in its containing function. bool Argument::hasByValAttr() const { @@ -209,8 +217,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(); @@ -293,7 +301,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) { @@ -348,10 +356,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; } } } @@ -361,7 +369,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()); @@ -372,7 +380,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 diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp index f69bdc4..f2099d6 100644 --- a/lib/IR/GCOV.cpp +++ b/lib/IR/GCOV.cpp @@ -26,11 +26,6 @@ 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; @@ -39,10 +34,10 @@ bool GCOVFile::readGCNO(GCOVBuffer &Buffer) { if (!Buffer.readInt(Checksum)) return false; while (true) { if (!Buffer.readFunctionTag()) break; - GCOVFunction *GFun = new GCOVFunction(*this); + auto GFun = make_unique<GCOVFunction>(*this); if (!GFun->readGCNO(Buffer, Version)) return false; - Functions.push_back(GFun); + Functions.push_back(std::move(GFun)); } GCNOInitialized = true; @@ -97,17 +92,15 @@ bool GCOVFile::readGCDA(GCOVBuffer &Buffer) { /// dump - Dump GCOVFile content to dbgs() for debugging purposes. void GCOVFile::dump() const { - for (SmallVectorImpl<GCOVFunction *>::const_iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) - (*I)->dump(); + 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); } @@ -115,12 +108,6 @@ void GCOVFile::collectLineCounts(FileInfo &FI) { //===----------------------------------------------------------------------===// // GCOVFunction implementation. -/// ~GCOVFunction - Delete GCOVFunction and its content. -GCOVFunction::~GCOVFunction() { - DeleteContainerPointers(Blocks); - DeleteContainerPointers(Edges); -} - /// readGCNO - Read a function from the GCNO buffer. Return false if an error /// occurs. bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { @@ -150,7 +137,7 @@ bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { 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. @@ -168,8 +155,8 @@ bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { for (uint32_t i = 0, e = EdgeCount; i != e; ++i) { uint32_t Dst; if (!Buff.readInt(Dst)) return false; - GCOVEdge *Edge = new GCOVEdge(Blocks[BlockNo], Blocks[Dst]); - Edges.push_back(Edge); + 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 @@ -179,34 +166,46 @@ bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { // 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: " << 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 (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; } - if (!Buff.readInt(Dummy)) return false; // flag + // 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; } @@ -300,9 +299,8 @@ uint64_t GCOVFunction::getExitCount() const { /// dump - Dump GCOVFunction content to dbgs() for debugging purposes. void GCOVFunction::dump() const { dbgs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; - for (SmallVectorImpl<GCOVBlock *>::const_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 @@ -313,9 +311,8 @@ void GCOVFunction::collectLineCounts(FileInfo &FI) { if (LineNumber == 0) return; - for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - (*I)->collectLineCounts(FI); + for (const auto &Block : Blocks) + Block->collectLineCounts(FI); FI.addFunctionLine(Filename, LineNumber, this); } @@ -335,8 +332,8 @@ 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; + if (!DstEdges[DstEdgeNo]->Dst.getNumDstEdges()) + DstEdges[DstEdgeNo]->Dst.Counter += N; } /// sortDstEdges - Sort destination edges by block number, nop if already @@ -363,7 +360,7 @@ void GCOVBlock::dump() const { 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() << Edge->Src.Number << " (" << Edge->Count << "), "; } dbgs() << "\n"; } @@ -371,7 +368,7 @@ void GCOVBlock::dump() const { 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() << Edge->Dst.Number << " (" << Edge->Count << "), "; } dbgs() << "\n"; } @@ -435,11 +432,35 @@ static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) { return OS; } +namespace { +class LineConsumer { + std::unique_ptr<MemoryBuffer> Buffer; + StringRef Remaining; +public: + LineConsumer(StringRef Filename) { + if (error_code EC = MemoryBuffer::getFileOrSTDIN(Filename, Buffer)) { + errs() << Filename << ": " << EC.message() << "\n"; + Remaining = ""; + } else + 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) + ".gcov").str(); + 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 @@ -467,28 +488,52 @@ static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) { if (S < I) Result.append(S, I); - Result.append(".gcov"); 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(StringRef GCNOFile, StringRef GCDAFile) { +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(); - std::unique_ptr<MemoryBuffer> Buff; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; - return; - } - StringRef AllLines = Buff->getBuffer(); + auto AllLines = LineConsumer(Filename); - std::string CoveragePath = mangleCoveragePath(Filename, - Options.PreservePaths); - std::string ErrorInfo; - raw_fd_ostream OS(CoveragePath.c_str(), ErrorInfo, sys::fs::F_Text); - if (!ErrorInfo.empty()) - errs() << ErrorInfo << "\n"; + 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"; @@ -498,7 +543,8 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) { const LineData &Line = I->second; GCOVCoverage FileCoverage(Filename); - for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) { + 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()) @@ -509,9 +555,7 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) { if (BlocksIt == Line.Blocks.end()) { // No basic blocks are on this line. Not an executable line of code. OS << " -:"; - std::pair<StringRef, StringRef> P = AllLines.split('\n'); - OS << format("%5u:", LineIndex+1) << P.first << "\n"; - AllLines = P.second; + AllLines.printNext(OS, LineIndex + 1); } else { const BlockVector &Blocks = BlocksIt->second; @@ -573,9 +617,7 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) { } ++FileCoverage.LogicalLines; - std::pair<StringRef, StringRef> P = AllLines.split('\n'); - OS << format("%5u:", LineIndex+1) << P.first << "\n"; - AllLines = P.second; + AllLines.printNext(OS, LineIndex + 1); uint32_t BlockNo = 0; uint32_t EdgeNo = 0; @@ -605,10 +647,11 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) { if (Options.FuncCoverage) printFuncCoverage(); printFileCoverage(); + return; } /// printFunctionSummary - Print function and block summary. -void FileInfo::printFunctionSummary(raw_fd_ostream &OS, +void FileInfo::printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const { for (FunctionVector::const_iterator I = Funcs.begin(), E = Funcs.end(); I != E; ++I) { @@ -617,8 +660,8 @@ void FileInfo::printFunctionSummary(raw_fd_ostream &OS, 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()) + const GCOVBlock &Block = **I; + if (Block.getNumDstEdges() && Block.getCount()) ++BlocksExec; } @@ -630,7 +673,7 @@ void FileInfo::printFunctionSummary(raw_fd_ostream &OS, } /// printBlockInfo - Output counts for each block. -void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block, +void FileInfo::printBlockInfo(raw_ostream &OS, const GCOVBlock &Block, uint32_t LineIndex, uint32_t &BlockNo) const { if (Block.getCount() == 0) OS << " $$$$$:"; @@ -640,7 +683,7 @@ void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block, } /// printBranchInfo - Print conditional branch probabilities. -void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block, +void FileInfo::printBranchInfo(raw_ostream &OS, const GCOVBlock &Block, GCOVCoverage &Coverage, uint32_t &EdgeNo) { SmallVector<uint64_t, 16> BranchCounts; uint64_t TotalCounts = 0; @@ -670,7 +713,7 @@ void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block, } /// printUncondBranchInfo - Print unconditional branch probabilities. -void FileInfo::printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo, +void FileInfo::printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo, uint64_t Count) const { OS << format("unconditional %2u ", EdgeNo++) << formatBranchInfo(Options, Count, Count) << "\n"; @@ -716,6 +759,8 @@ void FileInfo::printFileCoverage() const { const GCOVCoverage &Coverage = I->second; outs() << "File '" << Coverage.Name << "'\n"; printCoverage(Coverage); - outs() << Coverage.Name << ":creating '" << Filename << "'\n\n"; + if (!Options.NoOutput) + outs() << Coverage.Name << ":creating '" << Filename << "'\n"; + outs() << "\n"; } } diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index f338dd7..c905cfe 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -53,23 +53,41 @@ 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()); } -void GlobalValue::setAlignment(unsigned Align) { - assert((!isa<GlobalAlias>(this) || !Align) && - "GlobalAlias should not have an alignment!"); +unsigned GlobalValue::getAlignment() const { + if (auto *GA = dyn_cast<GlobalAlias>(this)) + return GA->getAliasee()->getAlignment(); + + return cast<GlobalObject>(this)->getAlignment(); +} + +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 std::string &GlobalValue::getSection() const { + if (auto *GA = dyn_cast<GlobalAlias>(this)) + return GA->getAliasee()->getSection(); + return cast<GlobalObject>(this)->getSection(); +} + +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)) @@ -83,22 +101,20 @@ 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), threadLocalMode(TLMode), + isExternallyInitializedConstant(isExternallyInitialized) { if (InitVal) { assert(InitVal->getType() == Ty && "Initializer should be the same type as the GlobalVariable!"); @@ -110,24 +126,22 @@ 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), threadLocalMode(TLMode), + isExternallyInitializedConstant(isExternallyInitialized) { 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 @@ -171,9 +185,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 { @@ -189,7 +203,7 @@ 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); setThreadLocalMode(SrcVar->getThreadLocalMode()); } @@ -199,20 +213,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, GlobalObject *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, + GlobalObject *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, + GlobalObject *Aliasee) { + return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent()); +} + +GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, + GlobalObject *Aliasee) { + PointerType *PTy = Aliasee->getType(); + return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name, + Aliasee); +} + +GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalObject *Aliasee) { + return create(Aliasee->getLinkage(), Name, Aliasee); +} + void GlobalAlias::setParent(Module *parent) { if (getParent()) LeakDetector::addGarbageObject(this); @@ -229,42 +270,4 @@ void GlobalAlias::eraseFromParent() { getParent()->getAliasList().erase(this); } -void GlobalAlias::setAliasee(Constant *Aliasee) { - assert((!Aliasee || Aliasee->getType() == getType()) && - "Alias and aliasee types should match!"); - - setOperand(0, Aliasee); -} - -static GlobalValue *getAliaseeGV(GlobalAlias *GA) { - Constant *C = GA->getAliasee(); - assert(C && "Must alias something"); - - if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) - return GV; - - ConstantExpr *CE = cast<ConstantExpr>(C); - assert((CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::AddrSpaceCast || - CE->getOpcode() == Instruction::GetElementPtr) && - "Unsupported aliasee"); - - return cast<GlobalValue>(CE->getOperand(0)); -} - -GlobalValue *GlobalAlias::getAliasedGlobal() { - SmallPtrSet<GlobalValue*, 3> Visited; - - GlobalAlias *GA = this; - - for (;;) { - GlobalValue *GV = getAliaseeGV(GA); - if (!Visited.insert(GV)) - return 0; - - // Iterate over aliasing chain. - GA = dyn_cast<GlobalAlias>(GV); - if (!GA) - return GV; - } -} +void GlobalAlias::setAliasee(GlobalObject *Aliasee) { setOperand(0, Aliasee); } diff --git a/lib/IR/IRPrintingPasses.cpp b/lib/IR/IRPrintingPasses.cpp index 099c27c..c8a1747 100644 --- a/lib/IR/IRPrintingPasses.cpp +++ b/lib/IR/IRPrintingPasses.cpp @@ -94,7 +94,7 @@ public: return false; } - void getAnalysisUsage(AnalysisUsage &AU) const override{ + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } }; diff --git a/lib/IR/InlineAsm.cpp b/lib/IR/InlineAsm.cpp index 62d191d..a3e1da3b1 100644 --- a/lib/IR/InlineAsm.cpp +++ b/lib/IR/InlineAsm.cpp @@ -274,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/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index d31a92e..28cc4cb 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -23,7 +23,7 @@ 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); @@ -41,7 +41,7 @@ const DataLayout *Instruction::getDataLayout() const { 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); @@ -53,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(); } @@ -262,6 +262,58 @@ 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->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. @@ -284,51 +336,13 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { 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->getSuccessOrdering() == - cast<AtomicCmpXchgInst>(I)->getSuccessOrdering() && - CXI->getFailureOrdering() == - cast<AtomicCmpXchgInst>(I)->getFailureOrdering() && - 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); return std::equal(thisPHI->block_begin(), thisPHI->block_end(), otherPHI->block_begin()); } - return true; + + return haveSameSpecialState(this, I); } // isSameOperationAs @@ -355,50 +369,7 @@ 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->getSuccessOrdering() == - cast<AtomicCmpXchgInst>(I)->getSuccessOrdering() && - CXI->getFailureOrdering() == - cast<AtomicCmpXchgInst>(I)->getFailureOrdering() && - 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 @@ -410,7 +381,7 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { // instructions, just check to see whether the parent of the use matches up. const Instruction *I = cast<Instruction>(U.getUser()); const PHINode *PN = dyn_cast<PHINode>(I); - if (PN == 0) { + if (!PN) { if (I->getParent() != BB) return true; continue; diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 3aa8413..13c51b8 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -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); } @@ -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); @@ -1323,7 +1323,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); } @@ -1331,7 +1331,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); } @@ -1369,7 +1369,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. @@ -1379,17 +1379,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) { @@ -1479,7 +1479,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; } @@ -1526,7 +1526,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; } @@ -1579,7 +1579,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. @@ -1721,13 +1721,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); @@ -2130,7 +2130,7 @@ bool CastInst::isNoopCast(const DataLayout *DL) const { return isNoopCast(Type::getInt64Ty(getContext())); } - Type *PtrOpTy = 0; + Type *PtrOpTy = nullptr; if (getOpcode() == Instruction::PtrToInt) PtrOpTy = getOperand(0)->getType(); else if (getOpcode() == Instruction::IntToPtr) @@ -3361,7 +3361,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); } @@ -3372,12 +3372,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; @@ -3425,8 +3425,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; } @@ -3492,14 +3492,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); } @@ -3541,7 +3541,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; } @@ -3587,9 +3587,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 { diff --git a/lib/IR/IntrinsicInst.cpp b/lib/IR/IntrinsicInst.cpp index 554f2be..5725284 100644 --- a/lib/IR/IntrinsicInst.cpp +++ b/lib/IR/IntrinsicInst.cpp @@ -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/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index 1bfc515..de825f0 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -15,6 +15,7 @@ #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" @@ -114,6 +115,17 @@ 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) { diagnose(DiagnosticInfoInlineAsm(ErrorStr)); } @@ -125,10 +137,32 @@ void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. - if (pImpl->DiagnosticHandler != 0) { + if (pImpl->DiagnosticHandler) { pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); return; } + + // 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; + } + // Otherwise, print the message with a prefix based on the severity. std::string MsgStorage; raw_string_ostream Stream(MsgStorage); diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp index ebff9d3..4c2791f 100644 --- a/lib/IR/LLVMContextImpl.cpp +++ b/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,10 +36,12 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64) { - InlineAsmDiagHandler = 0; - InlineAsmDiagContext = 0; - DiagnosticHandler = 0; - DiagnosticContext = 0; + InlineAsmDiagHandler = nullptr; + InlineAsmDiagContext = nullptr; + DiagnosticHandler = nullptr; + DiagnosticContext = nullptr; + YieldCallback = nullptr; + YieldOpaqueHandle = nullptr; NamedStructTypesUniqueID = 0; } @@ -46,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(); } }; @@ -64,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/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index dc77d29..808c239 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -37,6 +37,9 @@ 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)); } @@ -242,6 +245,9 @@ public: LLVMContext::DiagnosticHandlerTy DiagnosticHandler; void *DiagnosticContext; + LLVMContext::YieldCallbackTy YieldCallback; + void *YieldOpaqueHandle; + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *, DenseMapAPIntKeyInfo> IntMapTy; IntMapTy IntConstants; diff --git a/lib/IR/LeaksContext.h b/lib/IR/LeaksContext.h index 5038dc9..52ac170 100644 --- a/lib/IR/LeaksContext.h +++ b/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/lib/IR/LegacyPassManager.cpp b/lib/IR/LegacyPassManager.cpp index 7c5cc68..d3f3482 100644 --- a/lib/IR/LegacyPassManager.cpp +++ b/lib/IR/LegacyPassManager.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManagers.h" @@ -22,6 +23,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/TimeValue.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -118,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 '"; @@ -129,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; } @@ -484,11 +486,11 @@ public: /// 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; } @@ -579,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; @@ -626,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"; @@ -733,7 +735,7 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { } } - return 0; + return nullptr; } // Print passes managed by this top level manager. @@ -830,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; @@ -847,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()) @@ -887,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 @@ -911,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 @@ -1028,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); @@ -1095,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; @@ -1119,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. @@ -1158,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(); @@ -1487,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(); @@ -1657,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) { @@ -1666,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 @@ -1709,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) { @@ -1773,7 +1792,7 @@ void TimingInfo::createTheTimeInfo() { Timer *llvm::getPassTimer(Pass *P) { if (TheTimeInfo) return TheTimeInfo->getPassTimer(P); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// diff --git a/lib/IR/MDBuilder.cpp b/lib/IR/MDBuilder.cpp new file mode 100644 index 0000000..65cdf38 --- /dev/null +++ b/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/lib/IR/Mangler.cpp b/lib/IR/Mangler.cpp index d82388f..27d973b 100644 --- a/lib/IR/Mangler.cpp +++ b/lib/IR/Mangler.cpp @@ -108,7 +108,7 @@ void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, } bool UseAt = false; - const Function *MSFunc = NULL; + const Function *MSFunc = nullptr; CallingConv::ID CC; if (DL->hasMicrosoftFastStdCallMangling()) { if ((MSFunc = dyn_cast<Function>(GV))) { diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index ba39334..4d932d0 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -87,7 +87,7 @@ public: MDNodeOperand::~MDNodeOperand() {} void MDNodeOperand::deleted() { - getParent()->replaceOperand(this, 0); + getParent()->replaceOperand(this, nullptr); } void MDNodeOperand::allUsesReplacedWith(Value *NV) { @@ -148,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(); @@ -159,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)) @@ -175,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; } @@ -192,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 } @@ -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); } @@ -631,7 +632,7 @@ void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { /// 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) { @@ -691,7 +692,7 @@ 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"); @@ -699,7 +700,7 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const { for (const auto &I : Info) if (I.first == KindID) return I.second; - return 0; + return nullptr; } void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 1accd47..5dbed69 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LeakDetector.h" +#include "llvm/Support/Dwarf.h" #include <algorithm> #include <cstdarg> #include <cstdlib> @@ -95,7 +96,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 @@ -183,7 +184,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. @@ -195,11 +196,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. } @@ -284,7 +285,7 @@ Value *Module::getModuleFlag(StringRef Key) const { if (Key == MFE.Key->getString()) return MFE.Val; } - return 0; + return nullptr; } /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that @@ -350,7 +351,7 @@ void Module::setDataLayout(const DataLayout *Other) { const DataLayout *Module::getDataLayout() const { if (DataLayoutStr.empty()) - return 0; + return nullptr; return &DL; } @@ -429,3 +430,10 @@ void Module::dropAllReferences() { for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I) I->dropAllReferences(); } + +unsigned Module::getDwarfVersion() const { + Value *Val = getModuleFlag("Dwarf Version"); + if (!Val) + return dwarf::DWARF_VERSION; + return cast<ConstantInt>(Val)->getZExtValue(); +} diff --git a/lib/IR/Pass.cpp b/lib/IR/Pass.cpp index e16c5b7..bb55d2a 100644 --- a/lib/IR/Pass.cpp +++ b/lib/IR/Pass.cpp @@ -22,6 +22,8 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "ir" + //===----------------------------------------------------------------------===// // Pass Implementation // @@ -44,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 @@ -90,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) { @@ -112,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); } //===----------------------------------------------------------------------===// @@ -193,7 +195,7 @@ 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(); } diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index ea15455..0defb6a 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #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" @@ -32,6 +33,8 @@ PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { if (AM) AM->invalidate(M, PassPA); PA.intersect(std::move(PassPA)); + + M->getContext().yield(); } if (DebugPM) @@ -59,7 +62,7 @@ ModuleAnalysisManager::ResultConceptT * ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const { ModuleAnalysisResultMapT::const_iterator RI = ModuleAnalysisResults.find(PassID); - return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second; + return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second; } void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { @@ -92,6 +95,8 @@ PreservedAnalyses FunctionPassManager::run(Function *F, if (AM) AM->invalidate(F, PassPA); PA.intersect(std::move(PassPA)); + + F->getContext().yield(); } if (DebugPM) @@ -135,7 +140,7 @@ FunctionAnalysisManager::ResultConceptT * FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const { FunctionAnalysisResultMapT::const_iterator RI = FunctionAnalysisResults.find(std::make_pair(PassID, F)); - return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second; + return RI == FunctionAnalysisResults.end() ? nullptr : &*RI->second->second; } void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { @@ -165,6 +170,8 @@ void FunctionAnalysisManager::invalidateImpl(Function *F, while (!InvalidatedPassIDs.empty()) FunctionAnalysisResults.erase( std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); + if (ResultsList.empty()) + FunctionAnalysisResultLists.erase(F); } char FunctionAnalysisManagerModuleProxy::PassID; diff --git a/lib/IR/PassRegistry.cpp b/lib/IR/PassRegistry.cpp index 74dc0f1..6a5bee2 100644 --- a/lib/IR/PassRegistry.cpp +++ b/lib/IR/PassRegistry.cpp @@ -57,7 +57,7 @@ struct PassRegistryImpl { }; DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; - std::vector<const PassInfo*> ToFree; + std::vector<std::unique_ptr<const PassInfo>> ToFree; std::vector<PassRegistrationListener*> Listeners; }; } // end anonymous namespace @@ -75,20 +75,15 @@ void *PassRegistry::getImpl() const { 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; + pImpl = nullptr; } 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; + return I != Impl->PassInfoMap.end() ? I->second : nullptr; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { @@ -96,7 +91,7 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl::StringMapType::const_iterator I = Impl->PassInfoStringMap.find(Arg); - return I != Impl->PassInfoStringMap.end() ? I->second : 0; + return I != Impl->PassInfoStringMap.end() ? I->second : nullptr; } //===----------------------------------------------------------------------===// @@ -117,7 +112,7 @@ void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) (*I)->passRegistered(&PI); - if (ShouldFree) Impl->ToFree.push_back(&PI); + if (ShouldFree) Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); } void PassRegistry::unregisterPass(const PassInfo &PI) { @@ -148,7 +143,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; @@ -174,7 +169,7 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, "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"); @@ -185,7 +180,8 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, } PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - if (ShouldFree) Impl->ToFree.push_back(&Registeree); + if (ShouldFree) + Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { diff --git a/lib/IR/SymbolTableListTraitsImpl.h b/lib/IR/SymbolTableListTraitsImpl.h index 5a383ee..8302597 100644 --- a/lib/IR/SymbolTableListTraitsImpl.h +++ b/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/lib/IR/Type.cpp b/lib/IR/Type.cpp index b02509f..1efde47 100644 --- a/lib/IR/Type.cpp +++ b/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; } } @@ -312,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; @@ -448,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; } @@ -497,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; @@ -538,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; @@ -576,13 +576,13 @@ bool StructType::isSized(SmallPtrSet<const Type*, 4> *Visited) 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); @@ -680,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; } @@ -709,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; } @@ -734,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/lib/IR/Use.cpp b/lib/IR/Use.cpp index 60a0c56..047861c 100644 --- a/lib/IR/Use.cpp +++ b/lib/IR/Use.cpp @@ -27,14 +27,14 @@ void Use::swap(Use &RHS) { Val = RHS.Val; Val->addUse(*this); } else { - Val = 0; + Val = nullptr; } if (OldVal) { RHS.Val = OldVal; RHS.Val->addUse(RHS); } else { - RHS.Val = 0; + RHS.Val = nullptr; } } @@ -49,7 +49,7 @@ unsigned Use::getOperandNo() const { return this - getUser()->op_begin(); } -// Sets up the waymarking algoritm's tags for a series of Uses. See the +// 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 diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index 97a562e..d734e4e 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -44,7 +44,7 @@ static inline Type *checkType(Type *Ty) { Value::Value(Type *ty, unsigned scid) : SubclassID(scid), HasValueHandle(0), SubclassOptionalData(0), SubclassData(0), VTy((Type*)checkType(ty)), - UseList(0), Name(0) { + UseList(nullptr), Name(nullptr) { // FIXME: Why isn't this in the subclass gunk?? // Note, we cannot call isa<CallInst> before the CallInst has been // constructed. @@ -141,7 +141,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()) @@ -203,7 +203,7 @@ void Value::setName(const Twine &NewName) { if (NameRef.empty()) { // Free the name for this value. Name->Destroy(); - Name = 0; + Name = nullptr; return; } @@ -225,7 +225,7 @@ void Value::setName(const Twine &NewName) { // Remove old name. ST->removeValueName(Name); Name->Destroy(); - Name = 0; + Name = nullptr; if (NameRef.empty()) return; @@ -241,7 +241,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. @@ -256,7 +256,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. @@ -283,7 +283,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; } @@ -294,17 +294,73 @@ 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); } +static GlobalObject &findReplacementForAliasUse(Value &C) { + if (auto *GO = dyn_cast<GlobalObject>(&C)) + return *GO; + if (auto *GA = dyn_cast<GlobalAlias>(&C)) + return *GA->getAliasee(); + auto *CE = cast<ConstantExpr>(&C); + assert(CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::GetElementPtr || + CE->getOpcode() == Instruction::AddrSpaceCast); + if (CE->getOpcode() == Instruction::GetElementPtr) + assert(cast<GEPOperator>(CE)->hasAllZeroIndices()); + return findReplacementForAliasUse(*CE->getOperand(0)); +} + +static void replaceAliasUseWith(Use &U, Value *New) { + GlobalObject &Replacement = findReplacementForAliasUse(*New); + assert(&cast<GlobalObject>(*U) != &Replacement && + "replaceAliasUseWith cannot form an alias cycle"); + U.set(&Replacement); +} + +#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!"); @@ -316,7 +372,11 @@ 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<GlobalAlias>(C)) { + replaceAliasUseWith(U, New); + continue; + } if (!isa<GlobalValue>(C)) { C->replaceUsesOfWithOnConstant(this, New, &U); continue; @@ -557,7 +617,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; } @@ -571,7 +631,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; @@ -652,7 +712,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/lib/IR/ValueSymbolTable.cpp b/lib/IR/ValueSymbolTable.cpp index fffacb3..e9e979a 100644 --- a/lib/IR/ValueSymbolTable.cpp +++ b/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/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 089ad1c..bcc38c1 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -61,6 +61,7 @@ #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" @@ -76,15 +77,71 @@ #include <cstdarg> using namespace llvm; -static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier", - cl::init(true)); +static cl::opt<bool> VerifyDebugInfo("verify-debug-info", cl::init(false)); namespace { -class Verifier : public InstVisitor<Verifier> { - friend class InstVisitor<Verifier>; - +struct VerifierSupport { raw_ostream &OS; const Module *M; + + /// \brief Track the brokenness of the module while recursively visiting. + bool Broken; + + explicit VerifierSupport(raw_ostream &OS) + : OS(OS), M(nullptr), Broken(false) {} + + void WriteValue(const Value *V) { + if (!V) + return; + if (isa<Instruction>(V)) { + OS << *V << '\n'; + } else { + V->printAsOperand(OS, true, M); + OS << '\n'; + } + } + + void WriteType(Type *T) { + if (!T) + return; + OS << ' ' << *T; + } + + // 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; + } + + 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; + } + + 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; + } +}; +class Verifier : public InstVisitor<Verifier>, VerifierSupport { + friend class InstVisitor<Verifier>; + LLVMContext *Context; const DataLayout *DL; DominatorTree DT; @@ -104,15 +161,10 @@ class Verifier : public InstVisitor<Verifier> { /// personality function. const Value *PersonalityFn; - /// \brief Finder keeps track of all debug info MDNodes in a Module. - DebugInfoFinder Finder; - - /// \brief Track the brokenness of the module while recursively visiting. - bool Broken; - public: explicit Verifier(raw_ostream &OS = dbgs()) - : OS(OS), M(0), Context(0), DL(0), PersonalityFn(0), Broken(false) {} + : VerifierSupport(OS), Context(nullptr), DL(nullptr), + PersonalityFn(nullptr) {} bool verify(const Function &F) { M = F.getParent(); @@ -142,16 +194,11 @@ public: // FIXME: It's really gross that we have to cast away constness here. DT.recalculate(const_cast<Function &>(F)); - Finder.reset(); Broken = false; // FIXME: We strip const here because the inst visitor strips const. visit(const_cast<Function &>(F)); InstsInThisBlock.clear(); - PersonalityFn = 0; - - if (!DisableDebugInfoVerifier) - // Verify Debug Info. - verifyDebugInfo(); + PersonalityFn = nullptr; return !Broken; } @@ -159,7 +206,6 @@ public: bool verify(const Module &M) { this->M = &M; Context = &M.getContext(); - Finder.reset(); Broken = false; // Scan through, checking all of the external function's linkage now... @@ -187,13 +233,6 @@ public: visitModuleFlags(M); visitModuleIdents(M); - if (!DisableDebugInfoVerifier) { - Finder.reset(); - Finder.processModule(M); - // Verify Debug Info. - verifyDebugInfo(); - } - return !Broken; } @@ -262,6 +301,7 @@ private: 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, @@ -278,56 +318,21 @@ private: 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) {} - void verifyDebugInfo(); - - void WriteValue(const Value *V) { - if (!V) - return; - if (isa<Instruction>(V)) { - OS << *V << '\n'; - } else { - V->printAsOperand(OS, true, M); - OS << '\n'; - } - } - - void WriteType(Type *T) { - if (!T) - return; - OS << ' ' << *T; - } - - // 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) { - OS << Message.str() << "\n"; - WriteValue(V1); - WriteValue(V2); - WriteValue(V3); - WriteValue(V4); - Broken = true; - } - - void CheckFailed(const Twine &Message, const Value *V1, Type *T2, - const Value *V3 = 0) { - OS << Message.str() << "\n"; - WriteValue(V1); - WriteType(T2); - WriteValue(V3); - Broken = true; + bool verify(const Module &M) { + this->M = &M; + verifyDebugInfo(); + return !Broken; } - void CheckFailed(const Twine &Message, Type *T1, Type *T2 = 0, Type *T3 = 0) { - OS << 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 @@ -345,18 +350,14 @@ private: 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(const GlobalValue &GV) { - Assert1(!GV.isDeclaration() || - GV.isMaterializable() || - GV.hasExternalLinkage() || - GV.hasExternalWeakLinkage() || - (isa<GlobalAlias>(GV) && - (GV.hasLocalLinkage() || GV.hasWeakLinkage())), + Assert1(!GV.isDeclaration() || GV.isMaterializable() || + GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(), "Global is external, but doesn't have external or weak linkage!", &GV); @@ -395,14 +396,22 @@ void Verifier::visitGlobalVariable(const 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); + } } } @@ -472,11 +481,7 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { "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); - Assert1(!GA.hasSection(), "Alias cannot have a section!", &GA); - Assert1(!GA.getAlignment(), "Alias connot have an alignment", &GA); const Constant *Aliasee = GA.getAliasee(); const GlobalValue *GV = dyn_cast<GlobalValue>(Aliasee); @@ -492,14 +497,7 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { "addrspacecast of GlobalValue", &GA); - if (CE->getOpcode() == Instruction::BitCast) { - unsigned SrcAS = GV->getType()->getPointerAddressSpace(); - unsigned DstAS = CE->getType()->getPointerAddressSpace(); - - Assert1(SrcAS == DstAS, - "Alias bitcasts cannot be between different address spaces", - &GA); - } + VerifyConstantExprBitcastType(CE); } Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA); if (const GlobalAlias *GAAliasee = dyn_cast<GlobalAlias>(GV)) { @@ -507,10 +505,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { &GA); } - const GlobalValue *AG = GA.getAliasedGlobal(); - Assert1(AG, "Aliasing chain should end with function or global variable", - &GA); - visitGlobalValue(GA); } @@ -522,7 +516,7 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { Assert1(!MD->isFunctionLocal(), "Named metadata operand cannot be function local!", MD); - visitMDNode(*MD, 0); + visitMDNode(*MD, nullptr); } } @@ -548,7 +542,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)) @@ -821,6 +815,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); @@ -851,8 +846,12 @@ 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(), @@ -1489,6 +1488,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; @@ -1530,7 +1539,7 @@ void Verifier::VerifyCallSite(CallSite CS) { } // 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) @@ -1541,9 +1550,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); @@ -1731,11 +1833,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 { @@ -2020,8 +2122,8 @@ void Verifier::visitInstruction(Instruction &I) { // instruction, it is an error! for (Use &U : I.uses()) { if (Instruction *Used = dyn_cast<Instruction>(U.getUser())) - Assert2(Used->getParent() != 0, "Instruction referencing instruction not" - " embedded in a basic block!", &I, Used); + Assert2(Used->getParent() != nullptr, "Instruction referencing" + " instruction not embedded in a basic block!", &I, Used); else { CheckFailed("Use of instruction is not an instruction!", U); return; @@ -2029,7 +2131,7 @@ void Verifier::visitInstruction(Instruction &I) { } 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. @@ -2103,11 +2205,6 @@ 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(*M, DILocation(MD)); - } - InstsInThisBlock.insert(&I); } @@ -2137,18 +2234,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) @@ -2307,17 +2404,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(*M, 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(*M, cast<DbgValueInst>(&CI)); - } - break; - } case Intrinsic::memcpy: case Intrinsic::memmove: case Intrinsic::memset: @@ -2379,25 +2466,58 @@ 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 (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); - } + // + // 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; + } } //===----------------------------------------------------------------------===// @@ -2427,7 +2547,8 @@ bool llvm::verifyModule(const Module &M, raw_ostream *OS) { // Note that this function's return value is inverted from what you would // expect of a function called "verify". - return !V.verify(M) || Broken; + DebugInfoVerifier DIV(OS ? *OS : NullStr); + return !V.verify(M) || !DIV.verify(M) || Broken; } namespace { @@ -2463,15 +2584,48 @@ struct VerifierLegacyPass : public FunctionPass { 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!"); diff --git a/lib/IR/module.modulemap b/lib/IR/module.modulemap new file mode 100644 index 0000000..9698e91 --- /dev/null +++ b/lib/IR/module.modulemap @@ -0,0 +1 @@ +module IR { requires cplusplus umbrella "." module * { export * } } |