aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
committerStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
commitdce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch)
treedcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/IR
parent220b921aed042f9e520c26cffd8282a94c66c3d5 (diff)
downloadexternal_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')
-rw-r--r--lib/IR/Android.mk1
-rw-r--r--lib/IR/AsmWriter.cpp100
-rw-r--r--lib/IR/Attributes.cpp22
-rw-r--r--lib/IR/AutoUpgrade.cpp69
-rw-r--r--lib/IR/BasicBlock.cpp20
-rw-r--r--lib/IR/CMakeLists.txt5
-rw-r--r--lib/IR/ConstantFold.cpp108
-rw-r--r--lib/IR/Constants.cpp65
-rw-r--r--lib/IR/ConstantsContext.h7
-rw-r--r--lib/IR/Core.cpp140
-rw-r--r--lib/IR/DIBuilder.cpp204
-rw-r--r--lib/IR/DataLayout.cpp14
-rw-r--r--lib/IR/DebugInfo.cpp69
-rw-r--r--lib/IR/DebugLoc.cpp59
-rw-r--r--lib/IR/DiagnosticInfo.cpp125
-rw-r--r--lib/IR/Function.cpp24
-rw-r--r--lib/IR/GCOV.cpp183
-rw-r--r--lib/IR/Globals.cpp155
-rw-r--r--lib/IR/IRPrintingPasses.cpp2
-rw-r--r--lib/IR/InlineAsm.cpp2
-rw-r--r--lib/IR/Instruction.cpp147
-rw-r--r--lib/IR/Instructions.cpp91
-rw-r--r--lib/IR/IntrinsicInst.cpp4
-rw-r--r--lib/IR/LLVMContext.cpp36
-rw-r--r--lib/IR/LLVMContextImpl.cpp27
-rw-r--r--lib/IR/LLVMContextImpl.h10
-rw-r--r--lib/IR/LeaksContext.h16
-rw-r--r--lib/IR/LegacyPassManager.cpp67
-rw-r--r--lib/IR/MDBuilder.cpp139
-rw-r--r--lib/IR/Mangler.cpp2
-rw-r--r--lib/IR/Metadata.cpp45
-rw-r--r--lib/IR/Module.cpp20
-rw-r--r--lib/IR/Pass.cpp12
-rw-r--r--lib/IR/PassManager.cpp11
-rw-r--r--lib/IR/PassRegistry.cpp22
-rw-r--r--lib/IR/SymbolTableListTraitsImpl.h4
-rw-r--r--lib/IR/Type.cpp28
-rw-r--r--lib/IR/Use.cpp6
-rw-r--r--lib/IR/Value.cpp86
-rw-r--r--lib/IR/ValueSymbolTable.cpp9
-rw-r--r--lib/IR/Verifier.cpp442
-rw-r--r--lib/IR/module.modulemap1
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 * } }