summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-09 18:38:53 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-09 18:38:53 +0000
commit5bf8fef58013e2c97180236fa6973faa40435d5f (patch)
treed43dbdd5a9ee2cf0031cf3cd953d365a5e4e141d /llvm/lib/IR
parentb39e22bdc504ba77e2cd385538b6634808cda66e (diff)
downloadbcm5719-llvm-5bf8fef58013e2c97180236fa6973faa40435d5f.tar.gz
bcm5719-llvm-5bf8fef58013e2c97180236fa6973faa40435d5f.zip
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of PR21532. Assembly and bitcode changes are in the wings, but this is the bulk of the change for the IR C++ API. I have a follow-up patch prepared for `clang`. If this breaks other sub-projects, I apologize in advance :(. Help me compile it on Darwin I'll try to fix it. FWIW, the errors should be easy to fix, so it may be simpler to just fix it yourself. This breaks the build for all metadata-related code that's out-of-tree. Rest assured the transition is mechanical and the compiler should catch almost all of the problems. Here's a quick guide for updating your code: - `Metadata` is the root of a class hierarchy with three main classes: `MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from the `Value` class hierarchy. It is typeless -- i.e., instances do *not* have a `Type`. - `MDNode`'s operands are all `Metadata *` (instead of `Value *`). - `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively. If you're referring solely to resolved `MDNode`s -- post graph construction -- just use `MDNode*`. - `MDNode` (and the rest of `Metadata`) have only limited support for `replaceAllUsesWith()`. As long as an `MDNode` is pointing at a forward declaration -- the result of `MDNode::getTemporary()` -- it maintains a side map of its uses and can RAUW itself. Once the forward declarations are fully resolved RAUW support is dropped on the ground. This means that uniquing collisions on changing operands cause nodes to become "distinct". (This already happened fairly commonly, whenever an operand went to null.) If you're constructing complex (non self-reference) `MDNode` cycles, you need to call `MDNode::resolveCycles()` on each node (or on a top-level node that somehow references all of the nodes). Also, don't do that. Metadata cycles (and the RAUW machinery needed to construct them) are expensive. - An `MDNode` can only refer to a `Constant` through a bridge called `ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`). As a side effect, accessing an operand of an `MDNode` that is known to be, e.g., `ConstantInt`, takes three steps: first, cast from `Metadata` to `ConstantAsMetadata`; second, extract the `Constant`; third, cast down to `ConstantInt`. The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have metadata schema owners transition away from using `Constant`s when the type isn't important (and they don't care about referring to `GlobalValue`s). In the meantime, I've added transitional API to the `mdconst` namespace that matches semantics with the old code, in order to avoid adding the error-prone three-step equivalent to every call site. If your old code was: MDNode *N = foo(); bar(isa <ConstantInt>(N->getOperand(0))); baz(cast <ConstantInt>(N->getOperand(1))); bak(cast_or_null <ConstantInt>(N->getOperand(2))); bat(dyn_cast <ConstantInt>(N->getOperand(3))); bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4))); you can trivially match its semantics with: MDNode *N = foo(); bar(mdconst::hasa <ConstantInt>(N->getOperand(0))); baz(mdconst::extract <ConstantInt>(N->getOperand(1))); bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2))); bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3))); bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4))); and when you transition your metadata schema to `MDInt`: MDNode *N = foo(); bar(isa <MDInt>(N->getOperand(0))); baz(cast <MDInt>(N->getOperand(1))); bak(cast_or_null <MDInt>(N->getOperand(2))); bat(dyn_cast <MDInt>(N->getOperand(3))); bay(dyn_cast_or_null<MDInt>(N->getOperand(4))); - A `CallInst` -- specifically, intrinsic instructions -- can refer to metadata through a bridge called `MetadataAsValue`. This is a subclass of `Value` where `getType()->isMetadataTy()`. `MetadataAsValue` is the *only* class that can legally refer to a `LocalAsMetadata`, which is a bridged form of non-`Constant` values like `Argument` and `Instruction`. It can also refer to any other `Metadata` subclass. (I'll break all your testcases in a follow-up commit, when I propagate this change to assembly.) llvm-svn: 223802
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp169
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp32
-rw-r--r--llvm/lib/IR/CMakeLists.txt1
-rw-r--r--llvm/lib/IR/Core.cpp124
-rw-r--r--llvm/lib/IR/DIBuilder.cpp634
-rw-r--r--llvm/lib/IR/DebugInfo.cpp91
-rw-r--r--llvm/lib/IR/DebugLoc.cpp297
-rw-r--r--llvm/lib/IR/DiagnosticInfo.cpp3
-rw-r--r--llvm/lib/IR/Instructions.cpp9
-rw-r--r--llvm/lib/IR/IntrinsicInst.cpp22
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp15
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h80
-rw-r--r--llvm/lib/IR/MDBuilder.cpp37
-rw-r--r--llvm/lib/IR/Metadata.cpp863
-rw-r--r--llvm/lib/IR/MetadataTracking.cpp58
-rw-r--r--llvm/lib/IR/Module.cpp31
-rw-r--r--llvm/lib/IR/TypeFinder.cpp27
-rw-r--r--llvm/lib/IR/Value.cpp70
-rw-r--r--llvm/lib/IR/ValueSymbolTable.cpp10
-rw-r--r--llvm/lib/IR/Verifier.cpp141
20 files changed, 1492 insertions, 1222 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 4af03465f41..8fe03c06166 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -634,13 +634,6 @@ static SlotTracker *createSlotTracker(const Value *V) {
if (const Function *Func = dyn_cast<Function>(V))
return new SlotTracker(Func);
- if (const MDNode *MD = dyn_cast<MDNode>(V)) {
- if (!MD->isFunctionLocal())
- return new SlotTracker(MD->getFunction());
-
- return new SlotTracker((Function *)nullptr);
- }
-
return nullptr;
}
@@ -653,16 +646,14 @@ 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(nullptr), FunctionProcessed(false),
- mNext(0), fNext(0), mdnNext(0), asNext(0) {
-}
+ : 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() : nullptr), 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) {
@@ -744,8 +735,9 @@ void SlotTracker::processFunction() {
if (Function *F = CI->getCalledFunction())
if (F->isIntrinsic())
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
- CreateMetadataSlot(N);
+ if (auto *V = dyn_cast_or_null<MetadataAsValue>(I->getOperand(i)))
+ if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
+ CreateMetadataSlot(N);
// Add all the call attributes to the table.
AttributeSet Attrs = CI->getAttributes().getFnAttributes();
@@ -856,16 +848,10 @@ void SlotTracker::CreateFunctionSlot(const Value *V) {
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
assert(N && "Can't insert a null Value into SlotTracker!");
- // Don't insert if N is a function-local metadata, these are always printed
- // inline.
- if (!N->isFunctionLocal()) {
- mdn_iterator I = mdnMap.find(N);
- if (I != mdnMap.end())
- return;
-
- unsigned DestSlot = mdnNext++;
- mdnMap[N] = DestSlot;
- }
+ unsigned DestSlot = mdnNext;
+ if (!mdnMap.insert(std::make_pair(N, DestSlot)).second)
+ return;
+ ++mdnNext;
// Recursively add any MDNodes referenced by operands.
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
@@ -894,6 +880,11 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
SlotTracker *Machine,
const Module *Context);
+static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine, const Module *Context,
+ bool FromValue = false);
+
static const char *getPredicateText(unsigned predicate) {
const char * pred = "unknown";
switch (predicate) {
@@ -1264,14 +1255,17 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
const Module *Context) {
Out << "!{";
for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
- const Value *V = Node->getOperand(mi);
- if (!V)
+ const Metadata *MD = Node->getOperand(mi);
+ if (!MD)
Out << "null";
- else {
+ else if (auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
+ Value *V = MDV->getValue();
TypePrinter->print(V->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, Node->getOperand(mi),
- TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context);
+ } else {
+ Out << "metadata ";
+ WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
}
if (mi + 1 != me)
Out << ", ";
@@ -1315,31 +1309,9 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
return;
}
- if (const MDNode *N = dyn_cast<MDNode>(V)) {
- if (N->isFunctionLocal()) {
- // Print metadata inline, not via slot reference number.
- WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context);
- return;
- }
-
- if (!Machine) {
- if (N->isFunctionLocal())
- Machine = new SlotTracker(N->getFunction());
- else
- Machine = new SlotTracker(Context);
- }
- int Slot = Machine->getMetadataSlot(N);
- if (Slot == -1)
- Out << "<badref>";
- else
- Out << '!' << Slot;
- return;
- }
-
- if (const MDString *MDS = dyn_cast<MDString>(V)) {
- Out << "!\"";
- PrintEscapedString(MDS->getString(), Out);
- Out << '"';
+ if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+ WriteAsOperandInternal(Out, MD->getMetadata(), TypePrinter, Machine,
+ Context, /* FromValue */ true);
return;
}
@@ -1382,6 +1354,42 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
Out << "<badref>";
}
+static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine, const Module *Context,
+ bool FromValue) {
+ if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+ if (!Machine)
+ Machine = new SlotTracker(Context);
+ int Slot = Machine->getMetadataSlot(N);
+ if (Slot == -1)
+ Out << "<badref>";
+ else
+ Out << '!' << Slot;
+ return;
+ }
+
+ if (const MDString *MDS = dyn_cast<MDString>(MD)) {
+ Out << "!\"";
+ PrintEscapedString(MDS->getString(), Out);
+ Out << '"';
+ return;
+ }
+
+ auto *V = cast<ValueAsMetadata>(MD);
+ assert(TypePrinter && "TypePrinter required for metadata values");
+ assert((FromValue || !isa<LocalAsMetadata>(V)) &&
+ "Unexpected function-local metadata outside of value argument");
+
+ if (FromValue)
+ Out << "!{";
+ TypePrinter->print(V->getValue()->getType(), Out);
+ Out << ' ';
+ WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
+ if (FromValue)
+ Out << "}";
+}
+
void AssemblyWriter::init() {
if (!TheModule)
return;
@@ -2351,7 +2359,7 @@ static void WriteMDNodeComment(const MDNode *Node,
if (Node->getNumOperands() < 1)
return;
- Value *Op = Node->getOperand(0);
+ Metadata *Op = Node->getOperand(0);
if (!Op || !isa<MDString>(Op))
return;
@@ -2522,18 +2530,14 @@ void Value::print(raw_ostream &ROS) const {
W.printFunction(F);
else
W.printAlias(cast<GlobalAlias>(GV));
- } else if (const MDNode *N = dyn_cast<MDNode>(this)) {
- const Function *F = N->getFunction();
- SlotTracker SlotTable(F);
- AssemblyWriter W(OS, SlotTable, F ? F->getParent() : nullptr, nullptr);
- W.printMDNodeBody(N);
+ } else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
+ V->getMetadata()->print(ROS);
} else if (const Constant *C = dyn_cast<Constant>(this)) {
TypePrinting TypePrinter;
TypePrinter.print(C->getType(), OS);
OS << ' ';
WriteConstantInternal(OS, C, TypePrinter, nullptr, nullptr);
- } else if (isa<InlineAsm>(this) || isa<MDString>(this) ||
- isa<Argument>(this)) {
+ } else if (isa<InlineAsm>(this) || isa<Argument>(this)) {
this->printAsOperand(OS);
} else {
llvm_unreachable("Unknown value to print out!");
@@ -2543,9 +2547,8 @@ void Value::print(raw_ostream &ROS) const {
void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) const {
// Fast path: Don't construct and populate a TypePrinting object if we
// won't be needing any types printed.
- if (!PrintType &&
- ((!isa<Constant>(this) && !isa<MDNode>(this)) ||
- hasName() || isa<GlobalValue>(this))) {
+ if (!PrintType && ((!isa<Constant>(this) && !isa<MetadataAsValue>(this)) ||
+ hasName() || isa<GlobalValue>(this))) {
WriteAsOperandInternal(O, this, nullptr, nullptr, M);
return;
}
@@ -2564,6 +2567,35 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) cons
WriteAsOperandInternal(O, this, &TypePrinter, nullptr, M);
}
+void Metadata::print(raw_ostream &ROS) const {
+ formatted_raw_ostream OS(ROS);
+ if (auto *N = dyn_cast<MDNode>(this)) {
+ OS << "metadata ";
+ SlotTracker SlotTable(static_cast<Function *>(nullptr));
+ AssemblyWriter W(OS, SlotTable, nullptr, nullptr);
+ W.printMDNodeBody(N);
+
+ return;
+ }
+ printAsOperand(OS);
+}
+
+void Metadata::printAsOperand(raw_ostream &ROS, bool PrintType,
+ const Module *M) const {
+ formatted_raw_ostream OS(ROS);
+ if (PrintType)
+ OS << "metadata ";
+
+ std::unique_ptr<TypePrinting> TypePrinter;
+ if (PrintType) {
+ TypePrinter.reset(new TypePrinting);
+ if (M)
+ TypePrinter->incorporateTypes(*M);
+ }
+ WriteAsOperandInternal(OS, this, TypePrinter.get(), nullptr, M,
+ /* FromValue */ true);
+}
+
// Value::dump - allow easy printing of Values from the debugger.
void Value::dump() const { print(dbgs()); dbgs() << '\n'; }
@@ -2578,3 +2610,8 @@ void Comdat::dump() const { print(dbgs()); }
// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
void NamedMDNode::dump() const { print(dbgs()); }
+
+void Metadata::dump() const {
+ print(dbgs());
+ dbgs() << '\n';
+}
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index c24dfead433..512bca1c018 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -260,14 +260,15 @@ static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
return dyn_cast_or_null<MDNode>(DbgNode->getOperand(Elt));
}
-static DIExpression getExpression(Value *VarOperand, Function *F) {
+static MetadataAsValue *getExpression(Value *VarOperand, Function *F) {
// Old-style DIVariables have an optional expression as the 8th element.
- DIExpression Expr(getNodeField(cast<MDNode>(VarOperand), 8));
+ DIExpression Expr(getNodeField(
+ cast<MDNode>(cast<MetadataAsValue>(VarOperand)->getMetadata()), 8));
if (!Expr) {
- DIBuilder DIB(*F->getParent());
+ DIBuilder DIB(*F->getParent(), /*AllowUnresolved*/ false);
Expr = DIB.createExpression();
}
- return Expr;
+ return MetadataAsValue::get(F->getContext(), Expr);
}
// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
@@ -306,8 +307,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Builder.SetInsertPoint(CI->getParent(), CI);
Module *M = F->getParent();
- SmallVector<Value *, 1> Elts;
- Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
+ SmallVector<Metadata *, 1> Elts;
+ Elts.push_back(
+ ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
MDNode *Node = MDNode::get(C, Elts);
Value *Arg0 = CI->getArgOperand(0);
@@ -578,22 +580,18 @@ void llvm::UpgradeInstWithTBAATag(Instruction *I) {
return;
if (MD->getNumOperands() == 3) {
- Value *Elts[] = {
- MD->getOperand(0),
- MD->getOperand(1)
- };
+ Metadata *Elts[] = {MD->getOperand(0), MD->getOperand(1)};
MDNode *ScalarType = MDNode::get(I->getContext(), Elts);
// Create a MDNode <ScalarType, ScalarType, offset 0, const>
- Value *Elts2[] = {
- ScalarType, ScalarType,
- Constant::getNullValue(Type::getInt64Ty(I->getContext())),
- MD->getOperand(2)
- };
+ Metadata *Elts2[] = {ScalarType, ScalarType,
+ ConstantAsMetadata::get(Constant::getNullValue(
+ Type::getInt64Ty(I->getContext()))),
+ MD->getOperand(2)};
I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2));
} else {
// Create a MDNode <MD, MD, offset 0>
- Value *Elts[] = {MD, MD,
- Constant::getNullValue(Type::getInt64Ty(I->getContext()))};
+ Metadata *Elts[] = {MD, MD, ConstantAsMetadata::get(Constant::getNullValue(
+ Type::getInt64Ty(I->getContext())))};
I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts));
}
}
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 144c086bf0e..3b149e8690a 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -32,6 +32,7 @@ add_llvm_library(LLVMCore
MDBuilder.cpp
Mangler.cpp
Metadata.cpp
+ MetadataTracking.cpp
Module.cpp
Pass.cpp
PassManager.cpp
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 3576137dd30..a25c4d66d3b 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -556,12 +556,17 @@ int LLVMHasMetadata(LLVMValueRef Inst) {
}
LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) {
- return wrap(unwrap<Instruction>(Inst)->getMetadata(KindID));
+ auto *I = unwrap<Instruction>(Inst);
+ assert(I && "Expected instruction");
+ if (auto *MD = I->getMetadata(KindID))
+ return wrap(MetadataAsValue::get(I->getContext(), MD));
+ return nullptr;
}
void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) {
- unwrap<Instruction>(Inst)
- ->setMetadata(KindID, MD ? unwrap<MDNode>(MD) : nullptr);
+ MDNode *N =
+ MD ? cast<MDNode>(unwrap<MetadataAsValue>(MD)->getMetadata()) : nullptr;
+ unwrap<Instruction>(Inst)->setMetadata(KindID, N);
}
/*--.. Conversion functions ................................................--*/
@@ -573,6 +578,21 @@ void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) {
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST)
+LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) {
+ if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
+ if (isa<MDNode>(MD->getMetadata()) ||
+ isa<ValueAsMetadata>(MD->getMetadata()))
+ return Val;
+ return nullptr;
+}
+
+LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) {
+ if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
+ if (isa<MDString>(MD->getMetadata()))
+ return Val;
+ return nullptr;
+}
+
/*--.. Operations on Uses ..................................................--*/
LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) {
Value *V = unwrap(Val);
@@ -598,10 +618,28 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) {
}
/*--.. Operations on Users .................................................--*/
+
+static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N,
+ unsigned Index) {
+ Metadata *Op = N->getOperand(Index);
+ if (!Op)
+ return nullptr;
+ if (auto *C = dyn_cast<ConstantAsMetadata>(Op))
+ return wrap(C->getValue());
+ return wrap(MetadataAsValue::get(Context, Op));
+}
+
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) {
Value *V = unwrap(Val);
- if (MDNode *MD = dyn_cast<MDNode>(V))
- return wrap(MD->getOperand(Index));
+ if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+ if (auto *L = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {
+ assert(Index == 0 && "Function-local metadata can only have one operand");
+ return wrap(L->getValue());
+ }
+ return getMDNodeOperandImpl(V->getContext(),
+ cast<MDNode>(MD->getMetadata()), Index);
+ }
+
return wrap(cast<User>(V)->getOperand(Index));
}
@@ -616,8 +654,9 @@ void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) {
int LLVMGetNumOperands(LLVMValueRef Val) {
Value *V = unwrap(Val);
- if (MDNode *MD = dyn_cast<MDNode>(V))
- return MD->getNumOperands();
+ if (isa<MetadataAsValue>(V))
+ return LLVMGetMDNodeNumOperands(Val);
+
return cast<User>(V)->getNumOperands();
}
@@ -658,7 +697,9 @@ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) {
LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
unsigned SLen) {
- return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen)));
+ LLVMContext &Context = *unwrap(C);
+ return wrap(MetadataAsValue::get(
+ Context, MDString::get(Context, StringRef(Str, SLen))));
}
LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) {
@@ -667,8 +708,29 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) {
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
unsigned Count) {
- return wrap(MDNode::get(*unwrap(C),
- makeArrayRef(unwrap<Value>(Vals, Count), Count)));
+ LLVMContext &Context = *unwrap(C);
+ SmallVector<Metadata *, 8> MDs;
+ for (auto *OV : makeArrayRef(Vals, Count)) {
+ Value *V = unwrap(OV);
+ Metadata *MD;
+ if (!V)
+ MD = nullptr;
+ else if (auto *C = dyn_cast<Constant>(V))
+ MD = ConstantAsMetadata::get(C);
+ else if (auto *MDV = dyn_cast<MetadataAsValue>(V)) {
+ MD = MDV->getMetadata();
+ assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata "
+ "outside of direct argument to call");
+ } else {
+ // This is function-local metadata. Pretend to make an MDNode.
+ assert(Count == 1 &&
+ "Expected only one operand to function-local metadata");
+ return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V)));
+ }
+
+ MDs.push_back(MD);
+ }
+ return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs)));
}
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
@@ -676,25 +738,35 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
}
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) {
- if (const MDString *S = dyn_cast<MDString>(unwrap(V))) {
- *Len = S->getString().size();
- return S->getString().data();
- }
+ if (const auto *MD = dyn_cast<MetadataAsValue>(unwrap(V)))
+ if (const MDString *S = dyn_cast<MDString>(MD->getMetadata())) {
+ *Len = S->getString().size();
+ return S->getString().data();
+ }
*Len = 0;
return nullptr;
}
unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V)
{
- return cast<MDNode>(unwrap(V))->getNumOperands();
+ auto *MD = cast<MetadataAsValue>(unwrap(V));
+ if (isa<ValueAsMetadata>(MD->getMetadata()))
+ return 1;
+ return cast<MDNode>(MD->getMetadata())->getNumOperands();
}
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest)
{
- const MDNode *N = cast<MDNode>(unwrap(V));
+ auto *MD = cast<MetadataAsValue>(unwrap(V));
+ if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {
+ *Dest = wrap(MDV->getValue());
+ return;
+ }
+ const auto *N = cast<MDNode>(MD->getMetadata());
const unsigned numOperands = N->getNumOperands();
+ LLVMContext &Context = unwrap(V)->getContext();
for (unsigned i = 0; i < numOperands; i++)
- Dest[i] = wrap(N->getOperand(i));
+ Dest[i] = getMDNodeOperandImpl(Context, N, i);
}
unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name)
@@ -710,8 +782,9 @@ void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRe
NamedMDNode *N = unwrap(M)->getNamedMetadata(name);
if (!N)
return;
+ LLVMContext &Context = unwrap(M)->getContext();
for (unsigned i=0;i<N->getNumOperands();i++)
- Dest[i] = wrap(N->getOperand(i));
+ Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i)));
}
void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name,
@@ -720,9 +793,9 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name,
NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name);
if (!N)
return;
- MDNode *Op = Val ? unwrap<MDNode>(Val) : nullptr;
- if (Op)
- N->addOperand(Op);
+ if (!Val)
+ return;
+ N->addOperand(cast<MDNode>(unwrap<MetadataAsValue>(Val)->getMetadata()));
}
/*--.. Operations on scalar constants ......................................--*/
@@ -2092,13 +2165,16 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
/*--.. Metadata builders ...................................................--*/
void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) {
- MDNode *Loc = L ? unwrap<MDNode>(L) : nullptr;
+ MDNode *Loc =
+ L ? cast<MDNode>(unwrap<MetadataAsValue>(L)->getMetadata()) : nullptr;
unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc));
}
LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) {
- return wrap(unwrap(Builder)->getCurrentDebugLocation()
- .getAsMDNode(unwrap(Builder)->getContext()));
+ LLVMContext &Context = unwrap(Builder)->getContext();
+ return wrap(MetadataAsValue::get(
+ Context,
+ unwrap(Builder)->getCurrentDebugLocation().getAsMDNode(Context)));
}
void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) {
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index fa2d5a19768..ee7e6a2b21b 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -48,21 +48,36 @@ public:
};
}
-DIBuilder::DIBuilder(Module &m)
+DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes)
: M(m), VMContext(M.getContext()), TempEnumTypes(nullptr),
TempRetainTypes(nullptr), TempSubprograms(nullptr), TempGVs(nullptr),
- DeclareFn(nullptr), ValueFn(nullptr) {}
+ DeclareFn(nullptr), ValueFn(nullptr),
+ AllowUnresolvedNodes(AllowUnresolvedNodes) {}
+
+static bool isUnresolved(MDNode *N) {
+ return N && (isa<MDNodeFwdDecl>(N) || !cast<GenericMDNode>(N)->isResolved());
+}
+
+void DIBuilder::trackIfUnresolved(MDNode *N) {
+ if (!AllowUnresolvedNodes) {
+ assert(!isUnresolved(N) && "Cannot handle unresolved nodes");
+ return;
+ }
+ if (isUnresolved(N))
+ UnresolvedNodes.emplace_back(N);
+ return;
+}
void DIBuilder::finalize() {
DIArray Enums = getOrCreateArray(AllEnumTypes);
DIType(TempEnumTypes).replaceAllUsesWith(Enums);
- SmallVector<Value *, 16> RetainValues;
+ SmallVector<Metadata *, 16> RetainValues;
// Declarations and definitions of the same type may be retained. Some
// clients RAUW these pairs, leaving duplicates in the retained types
// list. Use a set to remove the duplicates while we transform the
// TrackingVHs back into Values.
- SmallPtrSet<Value *, 16> RetainSet;
+ SmallPtrSet<Metadata *, 16> RetainSet;
for (unsigned I = 0, E = AllRetainTypes.size(); I < E; I++)
if (RetainSet.insert(AllRetainTypes[I]).second)
RetainValues.push_back(AllRetainTypes[I]);
@@ -74,8 +89,8 @@ void DIBuilder::finalize() {
for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
DISubprogram SP(SPs.getElement(i));
if (MDNode *Temp = SP.getVariablesNodes()) {
- SmallVector<Value *, 4> Variables;
- for (Value *V : PreservedVariables.lookup(SP))
+ SmallVector<Metadata *, 4> Variables;
+ for (Metadata *V : PreservedVariables.lookup(SP))
Variables.push_back(V);
DIArray AV = getOrCreateArray(Variables);
DIType(Temp).replaceAllUsesWith(AV);
@@ -85,11 +100,21 @@ void DIBuilder::finalize() {
DIArray GVs = getOrCreateArray(AllGVs);
DIType(TempGVs).replaceAllUsesWith(GVs);
- SmallVector<Value *, 16> RetainValuesI;
+ SmallVector<Metadata *, 16> RetainValuesI;
for (unsigned I = 0, E = AllImportedModules.size(); I < E; I++)
RetainValuesI.push_back(AllImportedModules[I]);
DIArray IMs = getOrCreateArray(RetainValuesI);
DIType(TempImportedModules).replaceAllUsesWith(IMs);
+
+ // Now that all temp nodes have been replaced or deleted, resolve remaining
+ // cycles.
+ for (const auto &N : UnresolvedNodes)
+ if (N)
+ cast<GenericMDNode>(N)->resolveCycles();
+ UnresolvedNodes.clear();
+
+ // Can't handle unresolved nodes anymore.
+ AllowUnresolvedNodes = false;
}
/// If N is compile unit return NULL otherwise return N.
@@ -102,10 +127,8 @@ static MDNode *getNonCompileUnitScope(MDNode *N) {
static MDNode *createFilePathPair(LLVMContext &VMContext, StringRef Filename,
StringRef Directory) {
assert(!Filename.empty() && "Unable to create file without name");
- Value *Pair[] = {
- MDString::get(VMContext, Filename),
- MDString::get(VMContext, Directory)
- };
+ Metadata *Pair[] = {MDString::get(VMContext, Filename),
+ MDString::get(VMContext, Directory)};
return MDNode::get(VMContext, Pair);
}
@@ -122,7 +145,7 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
"Invalid Language tag");
assert(!Filename.empty() &&
"Unable to create compile unit without filename");
- Value *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)};
+ Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)};
TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
TempRetainTypes = MDNode::getTemporary(VMContext, TElts);
@@ -133,18 +156,18 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
TempImportedModules = MDNode::getTemporary(VMContext, TElts);
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit)
- .concat(Lang)
- .concat(Producer)
- .concat(isOptimized)
- .concat(Flags)
- .concat(RunTimeVer)
- .concat(SplitName)
- .concat(Kind)
- .get(VMContext),
- createFilePathPair(VMContext, Filename, Directory),
- TempEnumTypes, TempRetainTypes, TempSubprograms, TempGVs,
- TempImportedModules};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit)
+ .concat(Lang)
+ .concat(Producer)
+ .concat(isOptimized)
+ .concat(Flags)
+ .concat(RunTimeVer)
+ .concat(SplitName)
+ .concat(Kind)
+ .get(VMContext),
+ createFilePathPair(VMContext, Filename, Directory),
+ TempEnumTypes, TempRetainTypes, TempSubprograms, TempGVs,
+ TempImportedModules};
MDNode *CUNode = MDNode::get(VMContext, Elts);
@@ -158,20 +181,21 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
NMD->addOperand(CUNode);
}
+ trackIfUnresolved(CUNode);
return DICompileUnit(CUNode);
}
static DIImportedEntity
createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope Context,
- Value *NS, unsigned Line, StringRef Name,
- SmallVectorImpl<TrackingVH<MDNode>> &AllImportedModules) {
+ Metadata *NS, unsigned Line, StringRef Name,
+ SmallVectorImpl<TrackingMDNodeRef> &AllImportedModules) {
const MDNode *R;
- Value *Elts[] = {HeaderBuilder::get(Tag).concat(Line).concat(Name).get(C),
- Context, NS};
+ Metadata *Elts[] = {HeaderBuilder::get(Tag).concat(Line).concat(Name).get(C),
+ Context, NS};
R = MDNode::get(C, Elts);
DIImportedEntity M(R);
assert(M.Verify() && "Imported module should be valid");
- AllImportedModules.push_back(TrackingVH<MDNode>(M));
+ AllImportedModules.emplace_back(M.get());
return M;
}
@@ -194,7 +218,8 @@ DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context,
unsigned Line, StringRef Name) {
// Make sure to use the unique identifier based metadata reference for
// types that have one.
- Value *V = Decl.isType() ? static_cast<Value*>(DIType(Decl).getRef()) : Decl;
+ Metadata *V =
+ Decl.isType() ? static_cast<Metadata *>(DIType(Decl).getRef()) : Decl;
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
Context, V, Line, Name,
AllImportedModules);
@@ -208,16 +233,18 @@ DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context,
}
DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_file_type).get(VMContext),
- createFilePathPair(VMContext, Filename, Directory)};
+ Metadata *Elts[] = {
+ HeaderBuilder::get(dwarf::DW_TAG_file_type).get(VMContext),
+ createFilePathPair(VMContext, Filename, Directory)};
return DIFile(MDNode::get(VMContext, Elts));
}
DIEnumerator DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
assert(!Name.empty() && "Unable to create enumerator without name");
- Value *Elts[] = {
- HeaderBuilder::get(dwarf::DW_TAG_enumerator).concat(Name).concat(Val).get(
- VMContext)};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_enumerator)
+ .concat(Name)
+ .concat(Val)
+ .get(VMContext)};
return DIEnumerator(MDNode::get(VMContext, Elts));
}
@@ -225,7 +252,7 @@ DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) {
assert(!Name.empty() && "Unable to create type without name");
// Unspecified types are encoded in DIBasicType format. Line number, filename,
// size, alignment, offset and flags are always empty here.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_unspecified_type)
.concat(Name)
.concat(0)
@@ -251,7 +278,7 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
assert(!Name.empty() && "Unable to create type without name");
// Basic types are encoded in DIBasicType format. Line number, filename,
// offset and flags are always empty here.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_base_type)
.concat(Name)
.concat(0) // Line
@@ -269,17 +296,17 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) {
// Qualified types are encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(Tag)
- .concat(StringRef()) // Name
- .concat(0) // Line
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- nullptr, // Filename
- nullptr, // Unused
- FromTy.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(Tag)
+ .concat(StringRef()) // Name
+ .concat(0) // Line
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ nullptr, // Filename
+ nullptr, // Unused
+ FromTy.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -287,68 +314,68 @@ DIDerivedType
DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits,
uint64_t AlignInBits, StringRef Name) {
// Pointer types are encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_pointer_type)
- .concat(Name)
- .concat(0) // Line
- .concat(SizeInBits)
- .concat(AlignInBits)
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- nullptr, // Filename
- nullptr, // Unused
- PointeeTy.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_pointer_type)
+ .concat(Name)
+ .concat(0) // Line
+ .concat(SizeInBits)
+ .concat(AlignInBits)
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ nullptr, // Filename
+ nullptr, // Unused
+ PointeeTy.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy,
DIType Base) {
// Pointer types are encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type)
- .concat(StringRef())
- .concat(0) // Line
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- nullptr, // Filename
- nullptr, // Unused
- PointeeTy.getRef(), Base.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type)
+ .concat(StringRef())
+ .concat(0) // Line
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ nullptr, // Filename
+ nullptr, // Unused
+ PointeeTy.getRef(), Base.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) {
assert(RTy.isType() && "Unable to create reference type");
// References are encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(Tag)
- .concat(StringRef()) // Name
- .concat(0) // Line
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- nullptr, // Filename
- nullptr, // TheCU,
- RTy.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(Tag)
+ .concat(StringRef()) // Name
+ .concat(0) // Line
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ nullptr, // Filename
+ nullptr, // TheCU,
+ RTy.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File,
unsigned LineNo, DIDescriptor Context) {
// typedefs are encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef)
- .concat(Name)
- .concat(LineNo)
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- File.getFileNode(),
- DIScope(getNonCompileUnitScope(Context)).getRef(),
- Ty.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef)
+ .concat(Name)
+ .concat(LineNo)
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ File.getFileNode(),
+ DIScope(getNonCompileUnitScope(Context)).getRef(),
+ Ty.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -356,15 +383,15 @@ DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) {
// typedefs are encoded in DIDerivedType format.
assert(Ty.isType() && "Invalid type!");
assert(FriendTy.isType() && "Invalid friend type!");
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend)
- .concat(StringRef()) // Name
- .concat(0) // Line
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(0) // Flags
- .get(VMContext),
- nullptr, Ty.getRef(), FriendTy.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend)
+ .concat(StringRef()) // Name
+ .concat(0) // Line
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(0) // Flags
+ .get(VMContext),
+ nullptr, Ty.getRef(), FriendTy.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -373,15 +400,15 @@ DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy,
unsigned Flags) {
assert(Ty.isType() && "Unable to create inheritance");
// TAG_inheritance is encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance)
- .concat(StringRef()) // Name
- .concat(0) // Line
- .concat(0) // Size
- .concat(0) // Align
- .concat(BaseOffset)
- .concat(Flags)
- .get(VMContext),
- nullptr, Ty.getRef(), BaseTy.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance)
+ .concat(StringRef()) // Name
+ .concat(0) // Line
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(BaseOffset)
+ .concat(Flags)
+ .get(VMContext),
+ nullptr, Ty.getRef(), BaseTy.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -392,20 +419,26 @@ DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
uint64_t OffsetInBits, unsigned Flags,
DIType Ty) {
// TAG_member is encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
- .concat(Name)
- .concat(LineNumber)
- .concat(SizeInBits)
- .concat(AlignInBits)
- .concat(OffsetInBits)
- .concat(Flags)
- .get(VMContext),
- File.getFileNode(),
- DIScope(getNonCompileUnitScope(Scope)).getRef(),
- Ty.getRef()};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
+ .concat(Name)
+ .concat(LineNumber)
+ .concat(SizeInBits)
+ .concat(AlignInBits)
+ .concat(OffsetInBits)
+ .concat(Flags)
+ .get(VMContext),
+ File.getFileNode(),
+ DIScope(getNonCompileUnitScope(Scope)).getRef(),
+ Ty.getRef()};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
+static Metadata *getConstantOrNull(Constant *C) {
+ if (C)
+ return ConstantAsMetadata::get(C);
+ return nullptr;
+}
+
DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope,
StringRef Name, DIFile File,
unsigned LineNumber, DIType Ty,
@@ -413,17 +446,17 @@ DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope,
llvm::Constant *Val) {
// TAG_member is encoded in DIDerivedType format.
Flags |= DIDescriptor::FlagStaticMember;
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
- .concat(Name)
- .concat(LineNumber)
- .concat(0) // Size
- .concat(0) // Align
- .concat(0) // Offset
- .concat(Flags)
- .get(VMContext),
- File.getFileNode(),
- DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef(),
- Val};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
+ .concat(Name)
+ .concat(LineNumber)
+ .concat(0) // Size
+ .concat(0) // Align
+ .concat(0) // Offset
+ .concat(Flags)
+ .get(VMContext),
+ File.getFileNode(),
+ DIScope(getNonCompileUnitScope(Scope)).getRef(),
+ Ty.getRef(), getConstantOrNull(Val)};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -434,16 +467,16 @@ DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File,
uint64_t OffsetInBits, unsigned Flags,
DIType Ty, MDNode *PropertyNode) {
// TAG_member is encoded in DIDerivedType format.
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
- .concat(Name)
- .concat(LineNumber)
- .concat(SizeInBits)
- .concat(AlignInBits)
- .concat(OffsetInBits)
- .concat(Flags)
- .get(VMContext),
- File.getFileNode(), getNonCompileUnitScope(File), Ty,
- PropertyNode};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member)
+ .concat(Name)
+ .concat(LineNumber)
+ .concat(SizeInBits)
+ .concat(AlignInBits)
+ .concat(OffsetInBits)
+ .concat(Flags)
+ .get(VMContext),
+ File.getFileNode(), getNonCompileUnitScope(File), Ty,
+ PropertyNode};
return DIDerivedType(MDNode::get(VMContext, Elts));
}
@@ -451,14 +484,14 @@ DIObjCProperty
DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber,
StringRef GetterName, StringRef SetterName,
unsigned PropertyAttributes, DIType Ty) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_APPLE_property)
- .concat(Name)
- .concat(LineNumber)
- .concat(GetterName)
- .concat(SetterName)
- .concat(PropertyAttributes)
- .get(VMContext),
- File, Ty};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_APPLE_property)
+ .concat(Name)
+ .concat(LineNumber)
+ .concat(GetterName)
+ .concat(SetterName)
+ .concat(PropertyAttributes)
+ .get(VMContext),
+ File, Ty};
return DIObjCProperty(MDNode::get(VMContext, Elts));
}
@@ -466,24 +499,23 @@ DITemplateTypeParameter
DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name,
DIType Ty, MDNode *File, unsigned LineNo,
unsigned ColumnNo) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_template_type_parameter)
- .concat(Name)
- .concat(LineNo)
- .concat(ColumnNo)
- .get(VMContext),
- DIScope(getNonCompileUnitScope(Context)).getRef(),
- Ty.getRef(), File};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_template_type_parameter)
+ .concat(Name)
+ .concat(LineNo)
+ .concat(ColumnNo)
+ .get(VMContext),
+ DIScope(getNonCompileUnitScope(Context)).getRef(),
+ Ty.getRef(), File};
return DITemplateTypeParameter(MDNode::get(VMContext, Elts));
}
static DITemplateValueParameter createTemplateValueParameterHelper(
LLVMContext &VMContext, unsigned Tag, DIDescriptor Context, StringRef Name,
- DIType Ty, Value *Val, MDNode *File, unsigned LineNo, unsigned ColumnNo) {
- Value *Elts[] = {
+ DIType Ty, Metadata *MD, MDNode *File, unsigned LineNo, unsigned ColumnNo) {
+ Metadata *Elts[] = {
HeaderBuilder::get(Tag).concat(Name).concat(LineNo).concat(ColumnNo).get(
VMContext),
- DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef(), Val,
- File};
+ DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef(), MD, File};
return DITemplateValueParameter(MDNode::get(VMContext, Elts));
}
@@ -492,8 +524,8 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name,
DIType Ty, Constant *Val, MDNode *File,
unsigned LineNo, unsigned ColumnNo) {
return createTemplateValueParameterHelper(
- VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, Val,
- File, LineNo, ColumnNo);
+ VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,
+ getConstantOrNull(Val), File, LineNo, ColumnNo);
}
DITemplateValueParameter
@@ -529,7 +561,7 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name,
assert((!Context || Context.isScope() || Context.isType()) &&
"createClassType should be called with a valid Context");
// TAG_class_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_class_type)
.concat(Name)
.concat(LineNumber)
@@ -562,7 +594,7 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context,
DIType VTableHolder,
StringRef UniqueIdentifier) {
// TAG_structure_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_structure_type)
.concat(Name)
.concat(LineNumber)
@@ -592,7 +624,7 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
unsigned RunTimeLang,
StringRef UniqueIdentifier) {
// TAG_union_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_union_type)
.concat(Name)
.concat(LineNumber)
@@ -616,7 +648,7 @@ DISubroutineType DIBuilder::createSubroutineType(DIFile File,
DITypeArray ParameterTypes,
unsigned Flags) {
// TAG_subroutine_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_subroutine_type)
.concat(StringRef())
.concat(0) // Line
@@ -637,7 +669,7 @@ DICompositeType DIBuilder::createEnumerationType(
uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements,
DIType UnderlyingType, StringRef UniqueIdentifier) {
// TAG_enumeration_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_enumeration_type)
.concat(Name)
.concat(LineNumber)
@@ -661,7 +693,7 @@ DICompositeType DIBuilder::createEnumerationType(
DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
DIType Ty, DIArray Subscripts) {
// TAG_array_type is encoded in DICompositeType format.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_array_type)
.concat(StringRef())
.concat(0) // Line
@@ -682,7 +714,7 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits,
DIType Ty, DIArray Subscripts) {
// A vector is an array type with the FlagVector flag applied.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(dwarf::DW_TAG_array_type)
.concat("")
.concat(0) // Line
@@ -716,7 +748,7 @@ static HeaderBuilder setTypeFlagsInHeader(StringRef Header,
static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty,
unsigned FlagsToSet) {
- SmallVector<Value *, 9> Elts;
+ SmallVector<Metadata *, 9> Elts;
MDNode *N = Ty;
assert(N && "Unexpected input DIType!");
// Update header field.
@@ -740,9 +772,7 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) {
return createTypeWithFlags(VMContext, Ty, Flags);
}
-void DIBuilder::retainType(DIType T) {
- AllRetainTypes.push_back(TrackingVH<MDNode>(T));
-}
+void DIBuilder::retainType(DIType T) { AllRetainTypes.emplace_back(T); }
DIBasicType DIBuilder::createUnspecifiedParameter() {
return DIBasicType();
@@ -754,7 +784,7 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
uint64_t SizeInBits, uint64_t AlignInBits,
StringRef UniqueIdentifier) {
// Create a temporary MDNode.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(Tag)
.concat(Name)
.concat(Line)
@@ -783,7 +813,7 @@ DICompositeType DIBuilder::createReplaceableForwardDecl(
unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
StringRef UniqueIdentifier) {
// Create a temporary MDNode.
- Value *Elts[] = {
+ Metadata *Elts[] = {
HeaderBuilder::get(Tag)
.concat(Name)
.concat(Line)
@@ -798,8 +828,7 @@ DICompositeType DIBuilder::createReplaceableForwardDecl(
nullptr, // TemplateParams
UniqueIdentifier.empty() ? nullptr
: MDString::get(VMContext, UniqueIdentifier)};
- MDNode *Node = MDNode::getTemporary(VMContext, Elts);
- DICompositeType RetTy(Node);
+ DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts));
assert(RetTy.isCompositeType() &&
"createReplaceableForwardDecl result should be a DIType");
if (!UniqueIdentifier.empty())
@@ -807,12 +836,12 @@ DICompositeType DIBuilder::createReplaceableForwardDecl(
return RetTy;
}
-DIArray DIBuilder::getOrCreateArray(ArrayRef<Value *> Elements) {
+DIArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) {
return DIArray(MDNode::get(VMContext, Elements));
}
-DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef<Value *> Elements) {
- SmallVector<llvm::Value *, 16> Elts;
+DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) {
+ SmallVector<llvm::Metadata *, 16> Elts;
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
if (Elements[i] && isa<MDNode>(Elements[i]))
Elts.push_back(DIType(cast<MDNode>(Elements[i])).getRef());
@@ -823,10 +852,10 @@ DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef<Value *> Elements) {
}
DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subrange_type)
- .concat(Lo)
- .concat(Count)
- .get(VMContext)};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subrange_type)
+ .concat(Lo)
+ .concat(Count)
+ .get(VMContext)};
return DISubrange(MDNode::get(VMContext, Elts));
}
@@ -835,7 +864,7 @@ static DIGlobalVariable createGlobalVariableHelper(
LLVMContext &VMContext, DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile F, unsigned LineNumber, DITypeRef Ty,
bool isLocalToUnit, Constant *Val, MDNode *Decl, bool isDefinition,
- std::function<MDNode *(ArrayRef<Value *>)> CreateFunc) {
+ std::function<MDNode *(ArrayRef<Metadata *>)> CreateFunc) {
MDNode *TheCtx = getNonCompileUnitScope(Context);
if (DIScope(TheCtx).isCompositeType()) {
@@ -843,16 +872,16 @@ static DIGlobalVariable createGlobalVariableHelper(
"Context of a global variable should not be a type with identifier");
}
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_variable)
- .concat(Name)
- .concat(Name)
- .concat(LinkageName)
- .concat(LineNumber)
- .concat(isLocalToUnit)
- .concat(isDefinition)
- .get(VMContext),
- TheCtx, F, Ty, Val,
- DIDescriptor(Decl)};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_variable)
+ .concat(Name)
+ .concat(Name)
+ .concat(LinkageName)
+ .concat(LineNumber)
+ .concat(isLocalToUnit)
+ .concat(isDefinition)
+ .get(VMContext),
+ TheCtx, F, Ty, getConstantOrNull(Val),
+ DIDescriptor(Decl)};
return DIGlobalVariable(CreateFunc(Elts));
}
@@ -861,13 +890,13 @@ DIGlobalVariable DIBuilder::createGlobalVariable(
DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F,
unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val,
MDNode *Decl) {
- return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, Val, Decl, true,
- [&] (ArrayRef<Value *> Elts) -> MDNode * {
- MDNode *Node = MDNode::get(VMContext, Elts);
- AllGVs.push_back(Node);
- return Node;
- });
+ return createGlobalVariableHelper(
+ VMContext, Context, Name, LinkageName, F, LineNumber, Ty, isLocalToUnit,
+ Val, Decl, true, [&](ArrayRef<Metadata *> Elts) -> MDNode *{
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ AllGVs.push_back(Node);
+ return Node;
+ });
}
DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl(
@@ -875,10 +904,10 @@ DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl(
unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val,
MDNode *Decl) {
return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, Val, Decl, false,
- [&] (ArrayRef<Value *> Elts) {
- return MDNode::getTemporary(VMContext, Elts);
- });
+ LineNumber, Ty, isLocalToUnit, Val, Decl,
+ false, [&](ArrayRef<Metadata *> Elts) {
+ return MDNode::getTemporary(VMContext, Elts);
+ });
}
DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
@@ -889,12 +918,12 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
DIDescriptor Context(getNonCompileUnitScope(Scope));
assert((!Context || Context.isScope()) &&
"createLocalVariable should be called with a valid Context");
- Value *Elts[] = {HeaderBuilder::get(Tag)
- .concat(Name)
- .concat(LineNo | (ArgNo << 24))
- .concat(Flags)
- .get(VMContext),
- getNonCompileUnitScope(Scope), File, Ty};
+ Metadata *Elts[] = {HeaderBuilder::get(Tag)
+ .concat(Name)
+ .concat(LineNo | (ArgNo << 24))
+ .concat(Flags)
+ .get(VMContext),
+ getNonCompileUnitScope(Scope), File, Ty};
MDNode *Node = MDNode::get(VMContext, Elts);
if (AlwaysPreserve) {
// The optimizer may remove local variable. If there is an interest
@@ -902,7 +931,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
// named mdnode.
DISubprogram Fn(getDISubprogram(Scope));
assert(Fn && "Missing subprogram for local variable");
- PreservedVariables[Fn].push_back(Node);
+ PreservedVariables[Fn].emplace_back(Node);
}
DIVariable RetVar(Node);
assert(RetVar.isVariable() &&
@@ -914,7 +943,7 @@ DIExpression DIBuilder::createExpression(ArrayRef<int64_t> Addr) {
auto Header = HeaderBuilder::get(DW_TAG_expression);
for (int64_t I : Addr)
Header.concat(I);
- Value *Elts[] = {Header.get(VMContext)};
+ Metadata *Elts[] = {Header.get(VMContext)};
return DIExpression(MDNode::get(VMContext, Elts));
}
@@ -939,31 +968,30 @@ DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
Flags, isOptimized, Fn, TParams, Decl);
}
-static DISubprogram
-createFunctionHelper(LLVMContext &VMContext, DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine, unsigned Flags, bool isOptimized,
- Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars,
- std::function<MDNode *(ArrayRef<Value *>)> CreateFunc) {
+static DISubprogram createFunctionHelper(
+ LLVMContext &VMContext, DIDescriptor Context, StringRef Name,
+ StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags,
+ bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars,
+ std::function<MDNode *(ArrayRef<Metadata *>)> CreateFunc) {
assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type &&
"function types should be subroutines");
- Value *Elts[] = {
- HeaderBuilder::get(dwarf::DW_TAG_subprogram)
- .concat(Name)
- .concat(Name)
- .concat(LinkageName)
- .concat(LineNo)
- .concat(isLocalToUnit)
- .concat(isDefinition)
- .concat(0)
- .concat(0)
- .concat(Flags)
- .concat(isOptimized)
- .concat(ScopeLine)
- .get(VMContext),
- File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), Ty,
- nullptr, Fn, TParams, Decl, Vars};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram)
+ .concat(Name)
+ .concat(Name)
+ .concat(LinkageName)
+ .concat(LineNo)
+ .concat(isLocalToUnit)
+ .concat(isDefinition)
+ .concat(0)
+ .concat(0)
+ .concat(Flags)
+ .concat(isOptimized)
+ .concat(ScopeLine)
+ .get(VMContext),
+ File.getFileNode(),
+ DIScope(getNonCompileUnitScope(Context)).getRef(), Ty,
+ nullptr, getConstantOrNull(Fn), TParams, Decl, Vars};
DISubprogram S(CreateFunc(Elts));
assert(S.isSubprogram() &&
@@ -980,17 +1008,17 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
bool isOptimized, Function *Fn,
MDNode *TParams, MDNode *Decl) {
return createFunctionHelper(VMContext, Context, Name, LinkageName, File,
- LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine,
- Flags, isOptimized, Fn, TParams, Decl,
+ LineNo, Ty, isLocalToUnit, isDefinition,
+ ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
MDNode::getTemporary(VMContext, None),
- [&] (ArrayRef<Value *> Elts) -> MDNode *{
- MDNode *Node = MDNode::get(VMContext, Elts);
- // Create a named metadata so that we
- // do not lose this mdnode.
- if (isDefinition)
- AllSubprograms.push_back(Node);
- return Node;
- });
+ [&](ArrayRef<Metadata *> Elts) -> MDNode *{
+ MDNode *Node = MDNode::get(VMContext, Elts);
+ // Create a named metadata so that we
+ // do not lose this mdnode.
+ if (isDefinition)
+ AllSubprograms.push_back(Node);
+ return Node;
+ });
}
DISubprogram
@@ -1002,11 +1030,11 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name,
bool isOptimized, Function *Fn,
MDNode *TParams, MDNode *Decl) {
return createFunctionHelper(VMContext, Context, Name, LinkageName, File,
- LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine,
- Flags, isOptimized, Fn, TParams, Decl, nullptr,
- [&] (ArrayRef<Value *> Elts) {
- return MDNode::getTemporary(VMContext, Elts);
- });
+ LineNo, Ty, isLocalToUnit, isDefinition,
+ ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
+ nullptr, [&](ArrayRef<Metadata *> Elts) {
+ return MDNode::getTemporary(VMContext, Elts);
+ });
}
DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
@@ -1022,22 +1050,23 @@ 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 *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram)
- .concat(Name)
- .concat(Name)
- .concat(LinkageName)
- .concat(LineNo)
- .concat(isLocalToUnit)
- .concat(isDefinition)
- .concat(VK)
- .concat(VIndex)
- .concat(Flags)
- .concat(isOptimized)
- .concat(LineNo)
- // FIXME: Do we want to use different scope/lines?
- .get(VMContext),
- F.getFileNode(), DIScope(Context).getRef(), Ty,
- VTableHolder.getRef(), Fn, TParam, nullptr, nullptr};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram)
+ .concat(Name)
+ .concat(Name)
+ .concat(LinkageName)
+ .concat(LineNo)
+ .concat(isLocalToUnit)
+ .concat(isDefinition)
+ .concat(VK)
+ .concat(VIndex)
+ .concat(Flags)
+ .concat(isOptimized)
+ .concat(LineNo)
+ // FIXME: Do we want to use different scope/lines?
+ .get(VMContext),
+ F.getFileNode(), DIScope(Context).getRef(), Ty,
+ VTableHolder.getRef(), getConstantOrNull(Fn), TParam,
+ nullptr, nullptr};
MDNode *Node = MDNode::get(VMContext, Elts);
if (isDefinition)
AllSubprograms.push_back(Node);
@@ -1048,11 +1077,11 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name,
DIFile File, unsigned LineNo) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace)
- .concat(Name)
- .concat(LineNo)
- .get(VMContext),
- File.getFileNode(), getNonCompileUnitScope(Scope)};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace)
+ .concat(Name)
+ .concat(LineNo)
+ .get(VMContext),
+ File.getFileNode(), getNonCompileUnitScope(Scope)};
DINameSpace R(MDNode::get(VMContext, Elts));
assert(R.Verify() &&
"createNameSpace should return a verifiable DINameSpace");
@@ -1062,10 +1091,10 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name,
DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
DIFile File,
unsigned Discriminator) {
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block)
- .concat(Discriminator)
- .get(VMContext),
- File.getFileNode(), Scope};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block)
+ .concat(Discriminator)
+ .get(VMContext),
+ File.getFileNode(), Scope};
DILexicalBlockFile R(MDNode::get(VMContext, Elts));
assert(
R.Verify() &&
@@ -1084,41 +1113,52 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
// Defeat MDNode uniquing for lexical blocks by using unique id.
static unsigned int unique_id = 0;
- Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block)
- .concat(Line)
- .concat(Col)
- .concat(unique_id++)
- .get(VMContext),
- File.getFileNode(), getNonCompileUnitScope(Scope)};
+ Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block)
+ .concat(Line)
+ .concat(Col)
+ .concat(unique_id++)
+ .get(VMContext),
+ File.getFileNode(), getNonCompileUnitScope(Scope)};
DILexicalBlock R(MDNode::get(VMContext, Elts));
assert(R.Verify() &&
"createLexicalBlock should return a verifiable DILexicalBlock");
return R;
}
+static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {
+ assert(V && "no value passed to dbg intrinsic");
+ return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V));
+}
+
Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
DIExpression Expr,
Instruction *InsertBefore) {
- assert(Storage && "no storage passed to dbg.declare");
assert(VarInfo.isVariable() &&
"empty or invalid DIVariable passed to dbg.declare");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
- Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr};
+ trackIfUnresolved(VarInfo);
+ trackIfUnresolved(Expr);
+ Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),
+ MetadataAsValue::get(VMContext, VarInfo),
+ MetadataAsValue::get(VMContext, Expr)};
return CallInst::Create(DeclareFn, Args, "", InsertBefore);
}
Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
DIExpression Expr,
BasicBlock *InsertAtEnd) {
- assert(Storage && "no storage passed to dbg.declare");
assert(VarInfo.isVariable() &&
"empty or invalid DIVariable passed to dbg.declare");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
- Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr};
+ trackIfUnresolved(VarInfo);
+ trackIfUnresolved(Expr);
+ Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),
+ MetadataAsValue::get(VMContext, VarInfo),
+ MetadataAsValue::get(VMContext, Expr)};
// If this block already has a terminator then insert this intrinsic
// before the terminator.
@@ -1138,9 +1178,12 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
- Value *Args[] = {MDNode::get(V->getContext(), V),
- ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
- VarInfo, Expr};
+ trackIfUnresolved(VarInfo);
+ trackIfUnresolved(Expr);
+ Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Offset),
+ MetadataAsValue::get(VMContext, VarInfo),
+ MetadataAsValue::get(VMContext, Expr)};
return CallInst::Create(ValueFn, Args, "", InsertBefore);
}
@@ -1154,8 +1197,11 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
- Value *Args[] = {MDNode::get(V->getContext(), V),
- ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
- VarInfo, Expr};
+ trackIfUnresolved(VarInfo);
+ trackIfUnresolved(Expr);
+ Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),
+ ConstantInt::get(Type::getInt64Ty(VMContext), Offset),
+ MetadataAsValue::get(VMContext, VarInfo),
+ MetadataAsValue::get(VMContext, Expr)};
return CallInst::Create(ValueFn, Args, "", InsertAtEnd);
}
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index c6e4c872c1b..c31cd6dd915 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -52,7 +52,7 @@ bool DIDescriptor::Verify() const {
DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify());
}
-static Value *getField(const MDNode *DbgNode, unsigned Elt) {
+static Metadata *getField(const MDNode *DbgNode, unsigned Elt) {
if (!DbgNode || Elt >= DbgNode->getNumOperands())
return nullptr;
return DbgNode->getOperand(Elt);
@@ -73,25 +73,17 @@ StringRef DIDescriptor::getStringField(unsigned Elt) const {
}
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
- if (!DbgNode)
- return 0;
-
- if (Elt < DbgNode->getNumOperands())
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))
+ if (auto *C = getConstantField(Elt))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(C))
return CI->getZExtValue();
return 0;
}
int64_t DIDescriptor::getInt64Field(unsigned Elt) const {
- if (!DbgNode)
- return 0;
-
- if (Elt < DbgNode->getNumOperands())
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))
- return CI->getSExtValue();
+ if (auto *C = getConstantField(Elt))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(C))
+ return CI->getZExtValue();
return 0;
}
@@ -102,12 +94,7 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
}
GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
- if (!DbgNode)
- return nullptr;
-
- if (Elt < DbgNode->getNumOperands())
- return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt));
- return nullptr;
+ return dyn_cast_or_null<GlobalVariable>(getConstantField(Elt));
}
Constant *DIDescriptor::getConstantField(unsigned Elt) const {
@@ -115,17 +102,14 @@ Constant *DIDescriptor::getConstantField(unsigned Elt) const {
return nullptr;
if (Elt < DbgNode->getNumOperands())
- return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt));
+ if (auto *C =
+ dyn_cast_or_null<ConstantAsMetadata>(DbgNode->getOperand(Elt)))
+ return C->getValue();
return nullptr;
}
Function *DIDescriptor::getFunctionField(unsigned Elt) const {
- if (!DbgNode)
- return nullptr;
-
- if (Elt < DbgNode->getNumOperands())
- return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt));
- return nullptr;
+ return dyn_cast_or_null<Function>(getConstantField(Elt));
}
void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
@@ -134,7 +118,7 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
if (Elt < DbgNode->getNumOperands()) {
MDNode *Node = const_cast<MDNode *>(DbgNode);
- Node->replaceOperandWith(Elt, F);
+ Node->replaceOperandWith(Elt, F ? ConstantAsMetadata::get(F) : nullptr);
}
}
@@ -347,27 +331,23 @@ void DIDescriptor::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) {
// itself.
const MDNode *DN = D;
if (DbgNode == DN) {
- SmallVector<Value*, 10> Ops(DbgNode->getNumOperands());
+ SmallVector<Metadata *, 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));
+ auto *Node = cast<MDNodeFwdDecl>(const_cast<MDNode *>(DbgNode));
+ Node->replaceAllUsesWith(const_cast<MDNode *>(DN));
MDNode::deleteTemporary(Node);
DbgNode = DN;
}
void DIDescriptor::replaceAllUsesWith(MDNode *D) {
-
assert(DbgNode && "Trying to replace an unverified type!");
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));
+ auto *Node = cast<MDNodeFwdDecl>(const_cast<MDNode *>(DbgNode));
+ Node->replaceAllUsesWith(D);
MDNode::deleteTemporary(Node);
}
@@ -398,7 +378,7 @@ bool DIObjCProperty::Verify() const {
static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) {
// FIXME: This function should return true, if the field is null or the field
// is indeed a MDNode: return !Fld || isa<MDNode>(Fld).
- Value *Fld = getField(DbgNode, Elt);
+ Metadata *Fld = getField(DbgNode, Elt);
if (Fld && isa<MDString>(Fld) && !cast<MDString>(Fld)->getString().empty())
return false;
return true;
@@ -406,7 +386,7 @@ static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) {
/// \brief Check if a field at position Elt of a MDNode is a MDString.
static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
- Value *Fld = getField(DbgNode, Elt);
+ Metadata *Fld = getField(DbgNode, Elt);
return !Fld || isa<MDString>(Fld);
}
@@ -533,7 +513,6 @@ bool DISubprogram::Verify() const {
// If a DISubprogram has an llvm::Function*, then scope chains from all
// instructions within the function should lead to this DISubprogram.
if (auto *F = getFunction()) {
- LLVMContext &Ctxt = F->getContext();
for (auto &BB : *F) {
for (auto &I : BB) {
DebugLoc DL = I.getDebugLoc();
@@ -543,15 +522,15 @@ bool DISubprogram::Verify() const {
MDNode *Scope = nullptr;
MDNode *IA = nullptr;
// walk the inlined-at scopes
- while (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA)
+ while ((IA = DL.getInlinedAt()))
DL = DebugLoc::getFromDILocation(IA);
- DL.getScopeAndInlinedAt(Scope, IA, Ctxt);
+ DL.getScopeAndInlinedAt(Scope, IA);
assert(!IA);
while (!DIDescriptor(Scope).isSubprogram()) {
DILexicalBlockFile D(Scope);
Scope = D.isLexicalBlockFile()
? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt);
+ : DebugLoc::getFromDILexicalBlock(Scope).getScope();
}
if (!DISubprogram(Scope).describes(F))
return false;
@@ -678,7 +657,7 @@ MDString *DICompositeType::getIdentifier() const {
static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) {
for (unsigned i = 0; i != LHS->getNumOperands(); ++i) {
// Skip the 'empty' list (that's a single i32 0, rather than truly empty).
- if (i == 0 && isa<ConstantInt>(LHS->getOperand(i)))
+ if (i == 0 && mdconst::hasa<ConstantInt>(LHS->getOperand(i)))
continue;
const MDNode *E = cast<MDNode>(LHS->getOperand(i));
bool found = false;
@@ -690,7 +669,7 @@ static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) {
#endif
void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) {
- TrackingVH<MDNode> N(*this);
+ TrackingMDNodeRef N(*this);
if (Elements) {
#ifndef NDEBUG
// Check that the new list of members contains all the old members as well.
@@ -714,7 +693,7 @@ DIScopeRef DIScope::getRef() const {
}
void DICompositeType::setContainingType(DICompositeType ContainingType) {
- TrackingVH<MDNode> N(*this);
+ TrackingMDNodeRef N(*this);
N->replaceOperandWith(5, ContainingType.getRef());
DbgNode = N;
}
@@ -748,8 +727,8 @@ DIArray DISubprogram::getVariables() const {
return DIArray(getNodeField(DbgNode, 8));
}
-Value *DITemplateValueParameter::getValue() const {
- return getField(DbgNode, 3);
+Metadata *DITemplateValueParameter::getValue() const {
+ return DbgNode->getOperand(3);
}
DIScopeRef DIScope::getContext() const {
@@ -851,7 +830,7 @@ void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) {
DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
DILexicalBlockFile NewScope) {
- SmallVector<Value *, 10> Elts;
+ SmallVector<Metadata *, 10> Elts;
assert(Verify());
for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) {
if (I != 2)
@@ -875,7 +854,7 @@ DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
return cleanseInlinedVariable(DV, VMContext);
// Insert inlined scope.
- SmallVector<Value *, 8> Elts;
+ SmallVector<Metadata *, 8> Elts;
for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I)
Elts.push_back(DV->getOperand(I));
Elts.push_back(InlinedScope);
@@ -891,7 +870,7 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
return DIVariable(DV);
// Remove inlined scope.
- SmallVector<Value *, 8> Elts;
+ SmallVector<Metadata *, 8> Elts;
for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I)
Elts.push_back(DV->getOperand(I));
@@ -923,7 +902,7 @@ DISubprogram llvm::getDISubprogram(const Function *F) {
if (Inst == BB.end())
continue;
DebugLoc DLoc = Inst->getDebugLoc();
- const MDNode *Scope = DLoc.getScopeNode(F->getParent()->getContext());
+ const MDNode *Scope = DLoc.getScopeNode();
DISubprogram Subprogram = getDISubprogram(Scope);
return Subprogram.describes(F) ? Subprogram : DISubprogram();
}
@@ -1533,10 +1512,10 @@ bool llvm::StripDebugInfo(Module &M) {
}
unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
- Value *Val = M.getModuleFlag("Debug Info Version");
- if (!Val)
- return 0;
- return cast<ConstantInt>(Val)->getZExtValue();
+ if (auto *Val = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("Debug Info Version")))
+ return Val->getZExtValue();
+ return 0;
}
llvm::DenseMap<const llvm::Function *, llvm::DISubprogram>
diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp
index 718da852fec..88f2dbc5410 100644
--- a/llvm/lib/IR/DebugLoc.cpp
+++ b/llvm/lib/IR/DebugLoc.cpp
@@ -17,67 +17,29 @@ using namespace llvm;
// DebugLoc Implementation
//===----------------------------------------------------------------------===//
-MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const {
- if (ScopeIdx == 0) return nullptr;
-
- if (ScopeIdx > 0) {
- // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
- // position specified.
- assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
- "Invalid ScopeIdx!");
- return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
- }
-
- // Otherwise, the index is in the ScopeInlinedAtRecords array.
- assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
- "Invalid ScopeIdx");
- return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
-}
+unsigned DebugLoc::getLine() const { return DILocation(Loc).getLineNumber(); }
+unsigned DebugLoc::getCol() const { return DILocation(Loc).getColumnNumber(); }
+
+MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); }
-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 nullptr;
-
- // Otherwise, the index is in the ScopeInlinedAtRecords array.
- assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
- "Invalid ScopeIdx");
- return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
+MDNode *DebugLoc::getInlinedAt() const {
+ return DILocation(Loc).getOrigLocation();
}
/// Return both the Scope and the InlinedAt values.
-void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
- const LLVMContext &Ctx) const {
- if (ScopeIdx == 0) {
- Scope = IA = nullptr;
- return;
- }
-
- if (ScopeIdx > 0) {
- // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
- // position specified.
- assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
- "Invalid ScopeIdx!");
- Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
- IA = nullptr;
- return;
- }
-
- // Otherwise, the index is in the ScopeInlinedAtRecords array.
- assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
- "Invalid ScopeIdx");
- Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
- IA = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
+void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const {
+ Scope = getScope();
+ IA = getInlinedAt();
}
-MDNode *DebugLoc::getScopeNode(const LLVMContext &Ctx) const {
- if (MDNode *InlinedAt = getInlinedAt(Ctx))
- return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(Ctx);
- return getScope(Ctx);
+MDNode *DebugLoc::getScopeNode() const {
+ if (MDNode *InlinedAt = getInlinedAt())
+ return DebugLoc::getFromDILocation(InlinedAt).getScopeNode();
+ return getScope();
}
-DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const {
- const MDNode *Scope = getScopeNode(Ctx);
+DebugLoc DebugLoc::getFnDebugLoc() const {
+ const MDNode *Scope = getScopeNode();
DISubprogram SP = getDISubprogram(Scope);
if (SP.isSubprogram())
return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
@@ -87,53 +49,32 @@ DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const {
DebugLoc DebugLoc::get(unsigned Line, unsigned Col,
MDNode *Scope, MDNode *InlinedAt) {
- DebugLoc Result;
-
// If no scope is available, this is an unknown location.
- if (!Scope) return Result;
+ if (!Scope)
+ return DebugLoc();
// Saturate line and col to "unknown".
+ // FIXME: Allow 16-bits for columns.
if (Col > 255) Col = 0;
if (Line >= (1 << 24)) Line = 0;
- Result.LineCol = Line | (Col << 24);
-
- LLVMContext &Ctx = Scope->getContext();
-
- // If there is no inlined-at location, use the ScopeRecords array.
- if (!InlinedAt)
- Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0);
- else
- Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope,
- InlinedAt, 0);
- return Result;
+ LLVMContext &Context = Scope->getContext();
+ Type *Int32 = Type::getInt32Ty(Context);
+ Metadata *Elts[] = {ConstantAsMetadata::get(ConstantInt::get(Int32, Line)),
+ ConstantAsMetadata::get(ConstantInt::get(Int32, Col)),
+ Scope, InlinedAt};
+ return getFromDILocation(MDNode::get(Context, Elts));
}
/// getAsMDNode - This method converts the compressed DebugLoc node into a
/// DILocation-compatible MDNode.
-MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
- if (isUnknown()) return nullptr;
-
- MDNode *Scope, *IA;
- getScopeAndInlinedAt(Scope, IA, Ctx);
- assert(Scope && "If scope is null, this should be isUnknown()");
-
- LLVMContext &Ctx2 = Scope->getContext();
- Type *Int32 = Type::getInt32Ty(Ctx2);
- Value *Elts[] = {
- ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
- Scope, IA
- };
- return MDNode::get(Ctx2, Elts);
-}
+MDNode *DebugLoc::getAsMDNode() const { return Loc; }
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
DebugLoc DebugLoc::getFromDILocation(MDNode *N) {
- DILocation Loc(N);
- MDNode *Scope = Loc.getScope();
- if (!Scope) return DebugLoc();
- return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope,
- Loc.getOrigLocation());
+ DebugLoc Loc;
+ Loc.Loc.reset(N);
+ return Loc;
}
/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
@@ -145,26 +86,26 @@ DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) {
nullptr);
}
-void DebugLoc::dump(const LLVMContext &Ctx) const {
+void DebugLoc::dump() const {
#ifndef NDEBUG
if (!isUnknown()) {
dbgs() << getLine();
if (getCol() != 0)
dbgs() << ',' << getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx));
+ DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
if (!InlinedAtDL.isUnknown()) {
dbgs() << " @ ";
- InlinedAtDL.dump(Ctx);
+ InlinedAtDL.dump();
} else
dbgs() << "\n";
}
#endif
}
-void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const {
+void DebugLoc::print(raw_ostream &OS) const {
if (!isUnknown()) {
// Print source line info.
- DIScope Scope(getScope(Ctx));
+ DIScope Scope(getScope());
assert((!Scope || Scope.isScope()) &&
"Scope of a DebugLoc should be null or a DIScope.");
if (Scope)
@@ -174,179 +115,11 @@ void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const {
OS << ':' << getLine();
if (getCol() != 0)
OS << ':' << getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx));
+ DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
if (!InlinedAtDL.isUnknown()) {
OS << " @[ ";
- InlinedAtDL.print(Ctx, OS);
+ InlinedAtDL.print(OS);
OS << " ]";
}
}
}
-
-//===----------------------------------------------------------------------===//
-// DenseMap specialization
-//===----------------------------------------------------------------------===//
-
-unsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) {
- return static_cast<unsigned>(hash_combine(Key.LineCol, Key.ScopeIdx));
-}
-
-//===----------------------------------------------------------------------===//
-// LLVMContextImpl Implementation
-//===----------------------------------------------------------------------===//
-
-int LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope,
- int ExistingIdx) {
- // If we already have an entry for this scope, return it.
- int &Idx = ScopeRecordIdx[Scope];
- if (Idx) return Idx;
-
- // If we don't have an entry, but ExistingIdx is specified, use it.
- if (ExistingIdx)
- return Idx = ExistingIdx;
-
- // Otherwise add a new entry.
-
- // Start out ScopeRecords with a minimal reasonable size to avoid
- // excessive reallocation starting out.
- if (ScopeRecords.empty())
- ScopeRecords.reserve(128);
-
- // Index is biased by 1 for index.
- Idx = ScopeRecords.size()+1;
- ScopeRecords.push_back(DebugRecVH(Scope, this, Idx));
- return Idx;
-}
-
-int LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,
- int ExistingIdx) {
- // If we already have an entry, return it.
- int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)];
- if (Idx) return Idx;
-
- // If we don't have an entry, but ExistingIdx is specified, use it.
- if (ExistingIdx)
- return Idx = ExistingIdx;
-
- // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid
- // excessive reallocation starting out.
- if (ScopeInlinedAtRecords.empty())
- ScopeInlinedAtRecords.reserve(128);
-
- // Index is biased by 1 and negated.
- Idx = -ScopeInlinedAtRecords.size()-1;
- ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx),
- DebugRecVH(IA, this, Idx)));
- return Idx;
-}
-
-
-//===----------------------------------------------------------------------===//
-// DebugRecVH Implementation
-//===----------------------------------------------------------------------===//
-
-/// deleted - The MDNode this is pointing to got deleted, so this pointer needs
-/// to drop to null and we need remove our entry from the DenseMap.
-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(nullptr);
- return;
- }
-
- MDNode *Cur = get();
-
- // If the index is positive, it is an entry in ScopeRecords.
- if (Idx > 0) {
- assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!");
- Ctx->ScopeRecordIdx.erase(Cur);
- // Reset this VH to null and we're done.
- setValPtr(nullptr);
- Idx = 0;
- return;
- }
-
- // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
- // is the scope or the inlined-at record entry.
- assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
- std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
- assert((this == &Entry.first || this == &Entry.second) &&
- "Mapping out of date!");
-
- MDNode *OldScope = Entry.first.get();
- MDNode *OldInlinedAt = Entry.second.get();
- 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.
- assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
- "Mapping out of date");
- Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
-
- // Reset this VH to null. Drop both 'Idx' values to null to indicate that
- // we're in non-canonical form now.
- setValPtr(nullptr);
- Entry.first.Idx = Entry.second.Idx = 0;
-}
-
-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) 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) {
- setValPtr(NewVa);
- return;
- }
-
- MDNode *OldVal = get();
- assert(OldVal != NewVa && "Node replaced with self?");
-
- // If the index is positive, it is an entry in ScopeRecords.
- if (Idx > 0) {
- assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!");
- Ctx->ScopeRecordIdx.erase(OldVal);
- setValPtr(NewVal);
-
- int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx);
-
- // If NewVal already has an entry, this becomes a non-canonical reference,
- // just drop Idx to 0 to signify this.
- if (NewEntry != Idx)
- Idx = 0;
- return;
- }
-
- // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
- // is the scope or the inlined-at record entry.
- assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
- std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
- assert((this == &Entry.first || this == &Entry.second) &&
- "Mapping out of date!");
-
- MDNode *OldScope = Entry.first.get();
- MDNode *OldInlinedAt = Entry.second.get();
- 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.
- assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
- "Mapping out of date");
- Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
-
- // Reset this VH to the new value.
- setValPtr(NewVal);
-
- int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(),
- Entry.second.get(), Idx);
- // If NewVal already has an entry, this becomes a non-canonical reference,
- // just drop Idx to 0 to signify this.
- if (NewIdx != Idx) {
- std::pair<DebugRecVH, DebugRecVH> &Entry=Ctx->ScopeInlinedAtRecords[-Idx-1];
- Entry.first.Idx = Entry.second.Idx = 0;
- }
-}
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index 37cce2b0d78..cfb699a3171 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -98,7 +98,8 @@ DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
Instr(&I) {
if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
if (SrcLoc->getNumOperands() != 0)
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
+ if (const auto *CI =
+ mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
LocCookie = CI->getZExtValue();
}
}
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index f4c6a289b80..132800efeeb 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -796,11 +796,8 @@ void BranchInst::swapSuccessors() {
return;
// The first operand is the name. Fetch them backwards and build a new one.
- Value *Ops[] = {
- ProfileData->getOperand(0),
- ProfileData->getOperand(2),
- ProfileData->getOperand(1)
- };
+ Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
+ ProfileData->getOperand(1)};
setMetadata(LLVMContext::MD_prof,
MDNode::get(ProfileData->getContext(), Ops));
}
@@ -2076,7 +2073,7 @@ float FPMathOperator::getFPAccuracy() const {
cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath);
if (!MD)
return 0.0;
- ConstantFP *Accuracy = cast<ConstantFP>(MD->getOperand(0));
+ ConstantFP *Accuracy = mdconst::extract<ConstantFP>(MD->getOperand(0));
return Accuracy->getValueAPF().convertToFloat();
}
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 57252840bf0..b9b5a29091d 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -49,15 +49,25 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) {
return dyn_cast<GlobalVariable>(C);
}
+static Value *getValueImpl(Value *Op) {
+ auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
+ if (auto *V = dyn_cast<ValueAsMetadata>(MD))
+ return V->getValue();
+
+ // When the value goes to null, it gets replaced by an empty MDNode.
+ assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
+ return nullptr;
+}
+
//===----------------------------------------------------------------------===//
/// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
///
Value *DbgDeclareInst::getAddress() const {
- if (MDNode* MD = cast_or_null<MDNode>(getArgOperand(0)))
- return MD->getOperand(0);
- else
+ if (!getArgOperand(0))
return nullptr;
+
+ return getValueImpl(getArgOperand(0));
}
//===----------------------------------------------------------------------===//
@@ -65,9 +75,7 @@ Value *DbgDeclareInst::getAddress() const {
///
const Value *DbgValueInst::getValue() const {
- return cast<MDNode>(getArgOperand(0))->getOperand(0);
+ return const_cast<DbgValueInst *>(this)->getValue();
}
-Value *DbgValueInst::getValue() {
- return cast<MDNode>(getArgOperand(0))->getOperand(0);
-}
+Value *DbgValueInst::getValue() { return getValueImpl(getArgOperand(0)); }
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 3fd0bb37a4d..7c34f0949a4 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -120,6 +120,21 @@ LLVMContextImpl::~LLVMContextImpl() {
delete &*Elem;
}
+ // Destroy MetadataAsValues.
+ {
+ SmallVector<MetadataAsValue *, 8> MDVs;
+ MDVs.reserve(MetadataAsValues.size());
+ for (auto &Pair : MetadataAsValues)
+ MDVs.push_back(Pair.second);
+ MetadataAsValues.clear();
+ for (auto *V : MDVs)
+ delete V;
+ }
+
+ // Destroy ValuesAsMetadata.
+ for (auto &Pair : ValuesAsMetadata)
+ delete Pair.second;
+
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
// and the NonUniquedMDNodes sets, so copy the values out first.
SmallVector<GenericMDNode *, 8> MDNodes;
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 09102b1d56b..a9de5c78822 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -172,29 +172,29 @@ struct FunctionTypeKeyInfo {
/// the operands.
struct GenericMDNodeInfo {
struct KeyTy {
- ArrayRef<Value *> Ops;
+ ArrayRef<Metadata *> RawOps;
+ ArrayRef<MDOperand> Ops;
unsigned Hash;
- KeyTy(ArrayRef<Value *> Ops)
- : Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
+ KeyTy(ArrayRef<Metadata *> Ops)
+ : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
- KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) {
- Storage.resize(N->getNumOperands());
- for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
- Storage[I] = N->getOperand(I);
- Ops = Storage;
- Hash = hash_combine_range(Ops.begin(), Ops.end());
- }
+ KeyTy(GenericMDNode *N)
+ : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
bool operator==(const GenericMDNode *RHS) const {
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
return false;
- if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands())
+ if (Hash != RHS->getHash())
return false;
- for (unsigned I = 0, E = Ops.size(); I != E; ++I)
- if (Ops[I] != RHS->getOperand(I))
- return false;
- return true;
+ assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
+ return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
+ }
+ template <class T>
+ static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) {
+ if (Ops.size() != RHS->getNumOperands())
+ return false;
+ return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
}
};
static inline GenericMDNode *getEmptyKey() {
@@ -215,29 +215,6 @@ struct GenericMDNodeInfo {
}
};
-/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
-/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
-class DebugRecVH : public CallbackVH {
- /// Ctx - This is the LLVM Context being referenced.
- LLVMContextImpl *Ctx;
-
- /// Idx - The index into either ScopeRecordIdx or ScopeInlinedAtRecords that
- /// this reference lives in. If this is zero, then it represents a
- /// non-canonical entry that has no DenseMap value. This can happen due to
- /// RAUW.
- int Idx;
-public:
- DebugRecVH(MDNode *n, LLVMContextImpl *ctx, int idx)
- : CallbackVH(n), Ctx(ctx), Idx(idx) {}
-
- MDNode *get() const {
- return cast_or_null<MDNode>(getValPtr());
- }
-
- void deleted() override;
- void allUsesReplacedWith(Value *VNew) override;
-};
-
class LLVMContextImpl {
public:
/// OwnedModules - The set of modules instantiated in this context, and which
@@ -265,6 +242,8 @@ public:
FoldingSet<AttributeSetNode> AttrsSetNodes;
StringMap<MDString> MDStringCache;
+ DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
+ DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;
@@ -301,7 +280,8 @@ public:
ConstantInt *TheFalseVal;
LeakDetectorImpl<Value> LLVMObjects;
-
+ LeakDetectorImpl<Metadata> LLVMMDObjects;
+
// Basic type instances.
Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;
@@ -335,32 +315,14 @@ public:
/// CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMap<unsigned> CustomMDKindNames;
-
- typedef std::pair<unsigned, TrackingVH<MDNode> > MDPairTy;
+
+ typedef std::pair<unsigned, TrackingMDNodeRef> MDPairTy;
typedef SmallVector<MDPairTy, 2> MDMapTy;
/// MetadataStore - Collection of per-instruction metadata used in this
/// context.
DenseMap<const Instruction *, MDMapTy> MetadataStore;
- /// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope
- /// entry with no "inlined at" element.
- DenseMap<MDNode*, int> ScopeRecordIdx;
-
- /// ScopeRecords - These are the actual mdnodes (in a value handle) for an
- /// index. The ValueHandle ensures that ScopeRecordIdx stays up to date if
- /// the MDNode is RAUW'd.
- std::vector<DebugRecVH> ScopeRecords;
-
- /// ScopeInlinedAtIdx - This is the index in ScopeInlinedAtRecords for an
- /// scope/inlined-at pair.
- DenseMap<std::pair<MDNode*, MDNode*>, int> ScopeInlinedAtIdx;
-
- /// ScopeInlinedAtRecords - These are the actual mdnodes (in value handles)
- /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up
- /// to date.
- std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords;
-
/// DiscriminatorTable - This table maps file:line locations to an
/// integer representing the next DWARF path discriminator to assign to
/// instructions in different blocks at the same location.
diff --git a/llvm/lib/IR/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp
index 3ec613c2f66..c7fcf7a2c34 100644
--- a/llvm/lib/IR/MDBuilder.cpp
+++ b/llvm/lib/IR/MDBuilder.cpp
@@ -21,11 +21,16 @@ MDString *MDBuilder::createString(StringRef Str) {
return MDString::get(Context, Str);
}
+ConstantAsMetadata *MDBuilder::createConstant(Constant *C) {
+ return ConstantAsMetadata::get(C);
+}
+
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);
+ auto *Op =
+ createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy));
return MDNode::get(Context, Op);
}
@@ -38,12 +43,12 @@ MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
assert(Weights.size() >= 2 && "Need at least two branch weights!");
- SmallVector<Value *, 4> Vals(Weights.size() + 1);
+ SmallVector<Metadata *, 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]);
+ Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));
return MDNode::get(Context, Vals);
}
@@ -56,7 +61,8 @@ MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
// Return the range [Lo, Hi).
Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
- Value *Range[2] = {ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi)};
+ Metadata *Range[2] = {createConstant(ConstantInt::get(Ty, Lo)),
+ createConstant(ConstantInt::get(Ty, Hi))};
return MDNode::get(Context, Range);
}
@@ -64,7 +70,7 @@ MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
// To ensure uniqueness the root node is self-referential.
MDNode *Dummy = MDNode::getTemporary(Context, None);
- SmallVector<Value *, 3> Args(1, Dummy);
+ SmallVector<Metadata *, 3> Args(1, Dummy);
if (Extra)
Args.push_back(Extra);
if (!Name.empty())
@@ -92,10 +98,10 @@ 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};
+ Metadata *Ops[3] = {createString(Name), Parent, createConstant(Flags)};
return MDNode::get(Context, Ops);
} else {
- Value *Ops[2] = {createString(Name), Parent};
+ Metadata *Ops[2] = {createString(Name), Parent};
return MDNode::get(Context, Ops);
}
}
@@ -105,18 +111,18 @@ MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
}
MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
- Value *Ops[2] = { createString(Name), Domain };
+ Metadata *Ops[2] = {createString(Name), Domain};
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);
+ SmallVector<Metadata *, 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 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset));
+ Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size));
Vals[i * 3 + 2] = Fields[i].TBAA;
}
return MDNode::get(Context, Vals);
@@ -126,12 +132,12 @@ MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
/// 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);
+ SmallVector<Metadata *, 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);
+ Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second));
}
return MDNode::get(Context, Ops);
}
@@ -141,7 +147,7 @@ MDNode *MDBuilder::createTBAAStructTypeNode(
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};
+ Metadata *Ops[3] = {createString(Name), Parent, createConstant(Off)};
return MDNode::get(Context, Ops);
}
@@ -150,6 +156,7 @@ MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
uint64_t Offset) {
Type *Int64 = Type::getInt64Ty(Context);
- Value *Ops[3] = {BaseType, AccessType, ConstantInt::get(Int64, Offset)};
+ Metadata *Ops[3] = {BaseType, AccessType,
+ createConstant(ConstantInt::get(Int64, Offset))};
return MDNode::get(Context, Ops);
}
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index a2c7838bb83..150a186424c 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -28,352 +28,580 @@
using namespace llvm;
-Metadata::Metadata(LLVMContext &Context, unsigned ID)
- : Value(Type::getMetadataTy(Context), ID) {}
+MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD)
+ : Value(Ty, MetadataAsValueVal), MD(MD) {
+ track();
+}
-//===----------------------------------------------------------------------===//
-// MDString implementation.
-//
+MetadataAsValue::~MetadataAsValue() {
+ getType()->getContext().pImpl->MetadataAsValues.erase(MD);
+ untrack();
+}
-void MDString::anchor() { }
+/// \brief Canonicalize metadata arguments to intrinsics.
+///
+/// To support bitcode upgrades (and assembly semantic sugar) for \a
+/// MetadataAsValue, we need to canonicalize certain metadata.
+///
+/// - nullptr is replaced by an empty MDNode.
+/// - An MDNode with a single null operand is replaced by an empty MDNode.
+/// - An MDNode whose only operand is a \a ConstantAsMetadata gets skipped.
+///
+/// This maintains readability of bitcode from when metadata was a type of
+/// value, and these bridges were unnecessary.
+static Metadata *canonicalizeMetadataForValue(LLVMContext &Context,
+ Metadata *MD) {
+ if (!MD)
+ // !{}
+ return MDNode::get(Context, None);
+
+ // Return early if this isn't a single-operand MDNode.
+ auto *N = dyn_cast<MDNode>(MD);
+ if (!N || N->getNumOperands() != 1)
+ return MD;
+
+ if (!N->getOperand(0))
+ // !{}
+ return MDNode::get(Context, None);
+
+ if (auto *C = dyn_cast<ConstantAsMetadata>(N->getOperand(0)))
+ // Look through the MDNode.
+ return C;
+
+ return MD;
+}
+
+MetadataAsValue *MetadataAsValue::get(LLVMContext &Context, Metadata *MD) {
+ MD = canonicalizeMetadataForValue(Context, MD);
+ auto *&Entry = Context.pImpl->MetadataAsValues[MD];
+ if (!Entry)
+ Entry = new MetadataAsValue(Type::getMetadataTy(Context), MD);
+ return Entry;
+}
+
+MetadataAsValue *MetadataAsValue::getIfExists(LLVMContext &Context,
+ Metadata *MD) {
+ MD = canonicalizeMetadataForValue(Context, MD);
+ auto &Store = Context.pImpl->MetadataAsValues;
+ auto I = Store.find(MD);
+ return I == Store.end() ? nullptr : I->second;
+}
+
+void MetadataAsValue::handleChangedMetadata(Metadata *MD) {
+ LLVMContext &Context = getContext();
+ MD = canonicalizeMetadataForValue(Context, MD);
+ auto &Store = Context.pImpl->MetadataAsValues;
+
+ // Stop tracking the old metadata.
+ Store.erase(this->MD);
+ untrack();
+ this->MD = nullptr;
+
+ // Start tracking MD, or RAUW if necessary.
+ auto *&Entry = Store[MD];
+ if (Entry) {
+ replaceAllUsesWith(Entry);
+ delete this;
+ return;
+ }
-MDString *MDString::get(LLVMContext &Context, StringRef Str) {
- auto &Store = Context.pImpl->MDStringCache;
- auto I = Store.find(Str);
- if (I != Store.end())
- return &I->second;
+ this->MD = MD;
+ track();
+ Entry = this;
+}
- auto *Entry =
- StringMapEntry<MDString>::Create(Str, Store.getAllocator(), Context);
- bool WasInserted = Store.insert(Entry);
+void MetadataAsValue::track() {
+ if (MD)
+ MetadataTracking::track(&MD, *MD, *this);
+}
+
+void MetadataAsValue::untrack() {
+ if (MD)
+ MetadataTracking::untrack(MD);
+}
+
+void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
+ bool WasInserted = UseMap.insert(std::make_pair(Ref, Owner)).second;
(void)WasInserted;
- assert(WasInserted && "Expected entry to be inserted");
- Entry->second.Entry = Entry;
- return &Entry->second;
+ assert(WasInserted && "Expected to add a reference");
}
-StringRef MDString::getString() const {
- assert(Entry && "Expected to find string map entry");
- return Entry->first();
+void ReplaceableMetadataImpl::dropRef(void *Ref) {
+ bool WasErased = UseMap.erase(Ref);
+ (void)WasErased;
+ assert(WasErased && "Expected to drop a reference");
}
-//===----------------------------------------------------------------------===//
-// MDNodeOperand implementation.
-//
+void ReplaceableMetadataImpl::moveRef(void *Ref, void *New,
+ const Metadata &MD) {
+ auto I = UseMap.find(Ref);
+ assert(I != UseMap.end() && "Expected to move a reference");
+ OwnerTy Owner = I->second;
+ UseMap.erase(I);
+ addRef(New, Owner);
-// Use CallbackVH to hold MDNode operands.
-namespace llvm {
-class MDNodeOperand : public CallbackVH {
- MDNode *getParent() {
- MDNodeOperand *Cur = this;
+ // Check that the references are direct if there's no owner.
+ (void)MD;
+ assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
+ "Reference without owner must be direct");
+ assert((Owner || *static_cast<Metadata **>(New) == &MD) &&
+ "Reference without owner must be direct");
+}
+
+void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
+ assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Expected non-temp node");
+
+ if (UseMap.empty())
+ return;
- while (Cur->getValPtrInt() != 1)
- ++Cur;
+ // Copy out uses since UseMap will get touched below.
+ SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end());
+ for (const auto &Pair : Uses) {
+ if (!Pair.second) {
+ // Update unowned tracking references directly.
+ Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
+ Ref = MD;
+ MetadataTracking::track(Ref);
+ UseMap.erase(Pair.first);
+ continue;
+ }
+
+ // Check for MetadataAsValue.
+ if (Pair.second.is<MetadataAsValue *>()) {
+ Pair.second.get<MetadataAsValue *>()->handleChangedMetadata(MD);
+ continue;
+ }
+
+ // There's a Metadata owner -- dispatch.
+ Metadata *Owner = Pair.second.get<Metadata *>();
+ switch (Owner->getMetadataID()) {
+#define HANDLE_METADATA_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ cast<CLASS>(Owner)->handleChangedOperand(Pair.first, MD); \
+ continue;
+#include "llvm/IR/Metadata.def"
+ default:
+ llvm_unreachable("Invalid metadata subclass");
+ }
+ }
+ assert(UseMap.empty() && "Expected all uses to be replaced");
+}
+
+void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
+ if (UseMap.empty())
+ return;
- assert(Cur->getValPtrInt() == 1 &&
- "Couldn't find the end of the operand list!");
- return reinterpret_cast<MDNode *>(Cur + 1);
+ if (!ResolveUsers) {
+ UseMap.clear();
+ return;
}
-public:
- MDNodeOperand() {}
- virtual ~MDNodeOperand();
+ // Copy out uses since UseMap could get touched below.
+ SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end());
+ UseMap.clear();
+ for (const auto &Pair : Uses) {
+ if (!Pair.second)
+ continue;
+ if (Pair.second.is<MetadataAsValue *>())
+ continue;
- void set(Value *V) {
- unsigned IsLast = this->getValPtrInt();
- this->setValPtr(V);
- this->setAsLastOperand(IsLast);
+ // Resolve GenericMDNodes that point at this.
+ auto *Owner = dyn_cast<GenericMDNode>(Pair.second.get<Metadata *>());
+ if (!Owner)
+ continue;
+ if (Owner->isResolved())
+ continue;
+ Owner->decrementUnresolvedOperands();
+ if (!Owner->hasUnresolvedOperands())
+ Owner->resolve();
}
+}
- /// \brief Accessor method to mark the operand as the first in the list.
- void setAsLastOperand(unsigned I) { this->setValPtrInt(I); }
+static Function *getLocalFunction(Value *V) {
+ assert(V && "Expected value");
+ if (auto *A = dyn_cast<Argument>(V))
+ return A->getParent();
+ if (BasicBlock *BB = cast<Instruction>(V)->getParent())
+ return BB->getParent();
+ return nullptr;
+}
- void deleted() override;
- void allUsesReplacedWith(Value *NV) override;
-};
-} // end namespace llvm.
+ValueAsMetadata *ValueAsMetadata::get(Value *V) {
+ assert(V && "Unexpected null Value");
+
+ auto &Context = V->getContext();
+ auto *&Entry = Context.pImpl->ValuesAsMetadata[V];
+ if (!Entry) {
+ assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) &&
+ "Expected constant or function-local value");
+ assert(!V->NameAndIsUsedByMD.getInt() &&
+ "Expected this to be the only metadata use");
+ V->NameAndIsUsedByMD.setInt(true);
+ if (auto *C = dyn_cast<Constant>(V))
+ Entry = new ConstantAsMetadata(Context, C);
+ else
+ Entry = new LocalAsMetadata(Context, V);
+ }
-// Provide out-of-line definition to prevent weak vtable.
-MDNodeOperand::~MDNodeOperand() {}
+ return Entry;
+}
-void MDNodeOperand::deleted() {
- getParent()->replaceOperand(this, nullptr);
+ValueAsMetadata *ValueAsMetadata::getIfExists(Value *V) {
+ assert(V && "Unexpected null Value");
+ return V->getContext().pImpl->ValuesAsMetadata.lookup(V);
}
-void MDNodeOperand::allUsesReplacedWith(Value *NV) {
- getParent()->replaceOperand(this, NV);
+void ValueAsMetadata::handleDeletion(Value *V) {
+ assert(V && "Expected valid value");
+
+ auto &Store = V->getType()->getContext().pImpl->ValuesAsMetadata;
+ auto I = Store.find(V);
+ if (I == Store.end())
+ return;
+
+ // Remove old entry from the map.
+ ValueAsMetadata *MD = I->second;
+ assert(MD && "Expected valid metadata");
+ assert(MD->getValue() == V && "Expected valid mapping");
+ Store.erase(I);
+
+ // Delete the metadata.
+ MD->replaceAllUsesWith(nullptr);
+ delete MD;
+}
+
+void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
+ assert(From && "Expected valid value");
+ assert(To && "Expected valid value");
+ assert(From != To && "Expected changed value");
+ assert(From->getType() == To->getType() && "Unexpected type change");
+
+ LLVMContext &Context = From->getType()->getContext();
+ auto &Store = Context.pImpl->ValuesAsMetadata;
+ auto I = Store.find(From);
+ if (I == Store.end()) {
+ assert(!From->NameAndIsUsedByMD.getInt() &&
+ "Expected From not to be used by metadata");
+ return;
+ }
+
+ // Remove old entry from the map.
+ assert(From->NameAndIsUsedByMD.getInt() &&
+ "Expected From to be used by metadata");
+ From->NameAndIsUsedByMD.setInt(false);
+ ValueAsMetadata *MD = I->second;
+ assert(MD && "Expected valid metadata");
+ assert(MD->getValue() == From && "Expected valid mapping");
+ Store.erase(I);
+
+ if (isa<LocalAsMetadata>(MD)) {
+ if (auto *C = dyn_cast<Constant>(To)) {
+ // Local became a constant.
+ MD->replaceAllUsesWith(ConstantAsMetadata::get(C));
+ delete MD;
+ return;
+ }
+ if (getLocalFunction(From) && getLocalFunction(To) &&
+ getLocalFunction(From) != getLocalFunction(To)) {
+ // Function changed.
+ MD->replaceAllUsesWith(nullptr);
+ delete MD;
+ return;
+ }
+ } else if (!isa<Constant>(To)) {
+ // Changed to function-local value.
+ MD->replaceAllUsesWith(nullptr);
+ delete MD;
+ return;
+ }
+
+ auto *&Entry = Store[To];
+ if (Entry) {
+ // The target already exists.
+ MD->replaceAllUsesWith(Entry);
+ delete MD;
+ return;
+ }
+
+ // Update MD in place (and update the map entry).
+ assert(!To->NameAndIsUsedByMD.getInt() &&
+ "Expected this to be the only metadata use");
+ To->NameAndIsUsedByMD.setInt(true);
+ MD->V = To;
+ Entry = MD;
}
//===----------------------------------------------------------------------===//
-// MDNode implementation.
+// MDString implementation.
//
-/// \brief Get the MDNodeOperand's coallocated on the end of the MDNode.
-static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
- // Use <= instead of < to permit a one-past-the-end address.
- assert(Op <= N->getNumOperands() && "Invalid operand number");
- return reinterpret_cast<MDNodeOperand *>(N) - N->getNumOperands() + Op;
+MDString *MDString::get(LLVMContext &Context, StringRef Str) {
+ auto &Store = Context.pImpl->MDStringCache;
+ auto I = Store.find(Str);
+ if (I != Store.end())
+ return &I->second;
+
+ auto *Entry = StringMapEntry<MDString>::Create(Str, Store.getAllocator());
+ bool WasInserted = Store.insert(Entry);
+ (void)WasInserted;
+ assert(WasInserted && "Expected entry to be inserted");
+ Entry->second.Entry = Entry;
+ return &Entry->second;
}
-void MDNode::replaceOperandWith(unsigned i, Value *Val) {
- MDNodeOperand *Op = getOperandPtr(this, i);
- replaceOperand(Op, Val);
+StringRef MDString::getString() const {
+ assert(Entry && "Expected to find string map entry");
+ return Entry->first();
}
+//===----------------------------------------------------------------------===//
+// MDNode implementation.
+//
+
void *MDNode::operator new(size_t Size, unsigned NumOps) {
- void *Ptr = ::operator new(Size + NumOps * sizeof(MDNodeOperand));
- MDNodeOperand *Op = static_cast<MDNodeOperand *>(Ptr);
- if (NumOps) {
- MDNodeOperand *Last = Op + NumOps;
- for (; Op != Last; ++Op)
- new (Op) MDNodeOperand();
- (Op - 1)->setAsLastOperand(1);
- }
- return Op;
+ void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand));
+ MDOperand *First = new (Ptr) MDOperand[NumOps];
+ return First + NumOps;
}
void MDNode::operator delete(void *Mem) {
MDNode *N = static_cast<MDNode *>(Mem);
- MDNodeOperand *Op = static_cast<MDNodeOperand *>(Mem);
- for (unsigned I = 0, E = N->NumOperands; I != E; ++I)
- (--Op)->~MDNodeOperand();
- ::operator delete(Op);
+ MDOperand *Last = static_cast<MDOperand *>(Mem);
+ ::operator delete(Last - N->NumOperands);
+}
+
+MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
+ : Metadata(ID), Context(Context), NumOperands(MDs.size()),
+ MDNodeSubclassData(0) {
+ for (unsigned I = 0, E = MDs.size(); I != E; ++I)
+ setOperand(I, MDs[I]);
}
-MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
- bool isFunctionLocal)
- : Metadata(C, ID) {
- NumOperands = Vals.size();
+bool MDNode::isResolved() const {
+ if (isa<MDNodeFwdDecl>(this))
+ return false;
+ return cast<GenericMDNode>(this)->isResolved();
+}
+
+static bool isOperandUnresolved(Metadata *Op) {
+ if (auto *N = dyn_cast_or_null<MDNode>(Op))
+ return !N->isResolved();
+ return false;
+}
- if (isFunctionLocal)
- setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
+GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals)
+ : MDNode(C, GenericMDNodeKind, Vals) {
+ // Check whether any operands are unresolved, requiring re-uniquing.
+ for (const auto &Op : operands())
+ if (isOperandUnresolved(Op))
+ incrementUnresolvedOperands();
- // Initialize the operand list.
- unsigned i = 0;
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
- Op != E; ++Op, ++i)
- Op->set(Vals[i]);
+ if (hasUnresolvedOperands())
+ ReplaceableUses.reset(new ReplaceableMetadataImpl);
}
GenericMDNode::~GenericMDNode() {
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- if (isNotUniqued()) {
+ LLVMContextImpl *pImpl = getContext().pImpl;
+ if (isStoredDistinctInContext())
pImpl->NonUniquedMDNodes.erase(this);
- } else {
+ else
pImpl->MDNodeSet.erase(this);
- }
}
-void GenericMDNode::dropAllReferences() {
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
- Op != E; ++Op)
- Op->set(nullptr);
+void GenericMDNode::resolve() {
+ assert(!isResolved() && "Expected this to be unresolved");
+
+ // Move the map, so that this immediately looks resolved.
+ auto Uses = std::move(ReplaceableUses);
+ SubclassData32 = 0;
+ assert(isResolved() && "Expected this to be resolved");
+
+ // Drop RAUW support.
+ Uses->resolveAllUses();
}
-static const Function *getFunctionForValue(Value *V) {
- if (!V) return nullptr;
- if (Instruction *I = dyn_cast<Instruction>(V)) {
- BasicBlock *BB = I->getParent();
- return BB ? BB->getParent() : nullptr;
+void GenericMDNode::resolveCycles() {
+ if (isResolved())
+ return;
+
+ // Resolve this node immediately.
+ resolve();
+
+ // Resolve all operands.
+ for (const auto &Op : operands()) {
+ if (!Op)
+ continue;
+ assert(!isa<MDNodeFwdDecl>(Op) &&
+ "Expected all forward declarations to be resolved");
+ if (auto *N = dyn_cast<GenericMDNode>(Op))
+ if (!N->isResolved())
+ N->resolveCycles();
}
- if (Argument *A = dyn_cast<Argument>(V))
- return A->getParent();
- if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
- return BB->getParent();
- if (MDNode *MD = dyn_cast<MDNode>(V))
- return MD->getFunction();
- return nullptr;
}
-// getFunction - If this metadata is function-local and recursively has a
-// function-local operand, return the first such operand's parent function.
-// Otherwise, return null. getFunction() should not be used for performance-
-// critical code because it recursively visits all the MDNode's operands.
-const Function *MDNode::getFunction() const {
- if (!isFunctionLocal())
- return nullptr;
- assert(getNumOperands() == 1 &&
- "Expected one operand for function-local metadata");
- assert(getOperand(0) &&
- "Expected non-null operand for function-local metadata");
- assert(!getOperand(0)->getType()->isMetadataTy() &&
- "Expected non-metadata as operand of function-local metadata");
- return getFunctionForValue(getOperand(0));
+void MDNode::dropAllReferences() {
+ for (unsigned I = 0, E = NumOperands; I != E; ++I)
+ setOperand(I, nullptr);
+ if (auto *G = dyn_cast<GenericMDNode>(this))
+ if (!G->isResolved()) {
+ G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
+ G->ReplaceableUses.reset();
+ }
}
-/// \brief Check if the Value would require a function-local MDNode.
-static bool isFunctionLocalValue(Value *V) {
- return isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
- (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal());
+namespace llvm {
+/// \brief Make MDOperand transparent for hashing.
+///
+/// This overload of an implementation detail of the hashing library makes
+/// MDOperand hash to the same value as a \a Metadata pointer.
+///
+/// Note that overloading \a hash_value() as follows:
+///
+/// \code
+/// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
+/// \endcode
+///
+/// does not cause MDOperand to be transparent. In particular, a bare pointer
+/// doesn't get hashed before it's combined, whereas \a MDOperand would.
+static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
}
-MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
- FunctionLocalness FL, bool Insert) {
- auto &Store = Context.pImpl->MDNodeSet;
+void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
+ unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
+ assert(Op < getNumOperands() && "Expected valid operand");
- GenericMDNodeInfo::KeyTy Key(Vals);
- auto I = Store.find_as(Key);
- if (I != Store.end())
- return *I;
- if (!Insert)
- return nullptr;
+ if (isStoredDistinctInContext()) {
+ assert(isResolved() && "Expected distinct node to be resolved");
- bool isFunctionLocal = false;
- switch (FL) {
- case FL_Unknown:
- for (Value *V : Vals) {
- if (!V) continue;
- if (isFunctionLocalValue(V)) {
- isFunctionLocal = true;
- break;
- }
- }
- break;
- case FL_No:
- isFunctionLocal = false;
- break;
- case FL_Yes:
- isFunctionLocal = true;
- break;
+ // This node is not uniqued. Just set the operand and be done with it.
+ setOperand(Op, New);
+ return;
}
- if (isFunctionLocal) {
- assert(Vals.size() == 1 &&
- "Expected exactly one operand for function-local metadata");
- assert(Vals[0] && "Expected non-null operand for function-local metadata");
- assert(!Vals[0]->getType()->isMetadataTy() &&
- "Expected non-metadata as operand of function-local metadata");
+ auto &Store = getContext().pImpl->MDNodeSet;
+ Store.erase(this);
+
+ Metadata *Old = getOperand(Op);
+ setOperand(Op, New);
+
+ // Drop uniquing for self-reference cycles or if an operand drops to null.
+ //
+ // FIXME: Stop dropping uniquing when an operand drops to null. The original
+ // motivation was to prevent madness during teardown of LLVMContextImpl, but
+ // dropAllReferences() fixes that problem in a better way. (It's just here
+ // now for better staging of semantic changes.)
+ if (New == this || !New) {
+ storeDistinctInContext();
+ setHash(0);
+ if (!isResolved())
+ resolve();
+ return;
}
- // Coallocate space for the node and Operands together, then placement new.
- GenericMDNode *N =
- new (Vals.size()) GenericMDNode(Context, Vals, isFunctionLocal);
+ // Re-calculate the hash.
+ setHash(hash_combine_range(op_begin(), op_end()));
+#ifndef NDEBUG
+ {
+ SmallVector<Metadata *, 8> MDs(op_begin(), op_end());
+ unsigned RawHash = hash_combine_range(MDs.begin(), MDs.end());
+ assert(getHash() == RawHash &&
+ "Expected hash of MDOperand to equal hash of Metadata*");
+ }
+#endif
- N->Hash = Key.Hash;
- Store.insert(N);
- return N;
-}
+ // Re-unique the node.
+ GenericMDNodeInfo::KeyTy Key(this);
+ auto I = Store.find_as(Key);
+ if (I == Store.end()) {
+ Store.insert(this);
+
+ if (!isResolved()) {
+ // Check if the last unresolved operand has just been resolved; if so,
+ // resolve this as well.
+ if (isOperandUnresolved(Old))
+ decrementUnresolvedOperands();
+ if (isOperandUnresolved(New))
+ incrementUnresolvedOperands();
+ if (!hasUnresolvedOperands())
+ resolve();
+ }
-MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Value*> Vals) {
- return getMDNode(Context, Vals, FL_Unknown);
-}
+ return;
+ }
-MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context,
- ArrayRef<Value*> Vals,
- bool isFunctionLocal) {
- return getMDNode(Context, Vals, isFunctionLocal ? FL_Yes : FL_No);
+ // Collision.
+ if (!isResolved()) {
+ // Still unresolved, so RAUW.
+ ReplaceableUses->replaceAllUsesWith(*I);
+ delete this;
+ return;
+ }
+
+ // Store in non-uniqued form if this node has already been resolved.
+ setHash(0);
+ storeDistinctInContext();
}
-MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals) {
- return getMDNode(Context, Vals, FL_Unknown, false);
+MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
+ bool Insert) {
+ auto &Store = Context.pImpl->MDNodeSet;
+
+ GenericMDNodeInfo::KeyTy Key(MDs);
+ auto I = Store.find_as(Key);
+ if (I != Store.end())
+ return *I;
+ if (!Insert)
+ return nullptr;
+
+ // Coallocate space for the node and Operands together, then placement new.
+ GenericMDNode *N = new (MDs.size()) GenericMDNode(Context, MDs);
+ N->setHash(Key.Hash);
+ Store.insert(N);
+ return N;
}
-MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
- MDNode *N = new (Vals.size()) MDNodeFwdDecl(Context, Vals, FL_No);
- N->setValueSubclassData(N->getSubclassDataFromValue() | NotUniquedBit);
+MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs) {
+ MDNodeFwdDecl *N = new (MDs.size()) MDNodeFwdDecl(Context, MDs);
LeakDetector::addGarbageObject(N);
return N;
}
void MDNode::deleteTemporary(MDNode *N) {
- assert(N->use_empty() && "Temporary MDNode has uses!");
assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");
- assert((N->getSubclassDataFromValue() & NotUniquedBit) &&
- "Temporary MDNode does not have NotUniquedBit set!");
LeakDetector::removeGarbageObject(N);
delete cast<MDNodeFwdDecl>(N);
}
-/// \brief Return specified operand.
-Value *MDNode::getOperand(unsigned i) const {
- assert(i < getNumOperands() && "Invalid operand number");
- return *getOperandPtr(const_cast<MDNode*>(this), i);
-}
-
-void MDNode::setIsNotUniqued() {
- setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit);
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
+void MDNode::storeDistinctInContext() {
+ assert(!IsDistinctInContext && "Expected newly distinct metadata");
+ IsDistinctInContext = true;
auto *G = cast<GenericMDNode>(this);
- G->Hash = 0;
- pImpl->NonUniquedMDNodes.insert(G);
+ G->setHash(0);
+ getContext().pImpl->NonUniquedMDNodes.insert(G);
}
// Replace value from this node's operand list.
-void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
- Value *From = *Op;
-
- // If is possible that someone did GV->RAUW(inst), replacing a global variable
- // with an instruction or some other function-local object. If this is a
- // non-function-local MDNode, it can't point to a function-local object.
- // Handle this case by implicitly dropping the MDNode reference to null.
- // Likewise if the MDNode is function-local but for a different function.
- if (To && isFunctionLocalValue(To)) {
- assert(!To->getType()->isMetadataTy() &&
- "Expected non-metadata as operand of function-local metadata");
- if (!isFunctionLocal())
- 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 = nullptr;
- }
- }
-
- if (From == To)
+void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
+ if (getOperand(I) == New)
return;
- // If this MDValue was previously function-local but no longer is, clear
- // its function-local flag.
- if (isFunctionLocal() && !(To && isFunctionLocalValue(To))) {
- assert(getNumOperands() == 1 &&
- "Expected function-local metadata to have exactly one operand");
- setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit);
- }
-
- // If this node is already not being uniqued (because one of the operands
- // already went to null), then there is nothing else to do here.
- if (isNotUniqued()) {
- Op->set(To);
- return;
- }
-
- auto &Store = getContext().pImpl->MDNodeSet;
- auto *N = cast<GenericMDNode>(this);
-
- // Remove "this" from the context map.
- Store.erase(N);
-
- // Update the operand.
- Op->set(To);
-
- // If we are dropping an argument to null, we choose to not unique the MDNode
- // anymore. This commonly occurs during destruction, and uniquing these
- // brings little reuse. Also, this means we don't need to include
- // isFunctionLocal bits in the hash for MDNodes.
- //
- // Also drop uniquing if this has a reference to itself.
- if (!To || To == this) {
- setIsNotUniqued();
+ if (auto *N = dyn_cast<GenericMDNode>(this)) {
+ N->handleChangedOperand(mutable_begin() + I, New);
return;
}
- // Now that the node is out of the table, get ready to reinsert it. First,
- // check to see if another node with the same operands already exists in the
- // set. If so, then this node is redundant.
- SmallVector<Value *, 8> Vals;
- GenericMDNodeInfo::KeyTy Key(N, Vals);
- auto I = Store.find_as(Key);
- if (I != Store.end()) {
- N->replaceAllUsesWith(*I);
- delete N;
- return;
- }
+ assert(isa<MDNodeFwdDecl>(this) && "Expected an MDNode");
+ setOperand(I, New);
+}
- N->Hash = Key.Hash;
- Store.insert(N);
+void MDNode::setOperand(unsigned I, Metadata *New) {
+ assert(I < NumOperands);
+ if (isStoredDistinctInContext() || isa<MDNodeFwdDecl>(this))
+ // No need for a callback, this isn't uniqued.
+ mutable_begin()[I].reset(New, nullptr);
+ else
+ mutable_begin()[I].reset(New, this);
}
/// \brief Get a node, or a self-reference that looks like it.
@@ -382,7 +610,8 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
/// MDNode::concatenate() and \a MDNode::intersect() to maintain behaviour from
/// when self-referencing nodes were still uniqued. If the first operand has
/// the same operands as \c Ops, return the first operand instead.
-static MDNode *getOrSelfReference(LLVMContext &Context, ArrayRef<Value *> Ops) {
+static MDNode *getOrSelfReference(LLVMContext &Context,
+ ArrayRef<Metadata *> Ops) {
if (!Ops.empty())
if (MDNode *N = dyn_cast_or_null<MDNode>(Ops[0]))
if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) {
@@ -401,45 +630,44 @@ MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
if (!B)
return A;
- SmallVector<Value *, 4> Vals(A->getNumOperands() +
- B->getNumOperands());
+ SmallVector<Metadata *, 4> MDs(A->getNumOperands() + B->getNumOperands());
unsigned j = 0;
for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i)
- Vals[j++] = A->getOperand(i);
+ MDs[j++] = A->getOperand(i);
for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i)
- Vals[j++] = B->getOperand(i);
+ MDs[j++] = B->getOperand(i);
// FIXME: This preserves long-standing behaviour, but is it really the right
// behaviour? Or was that an unintended side-effect of node uniquing?
- return getOrSelfReference(A->getContext(), Vals);
+ return getOrSelfReference(A->getContext(), MDs);
}
MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
if (!A || !B)
return nullptr;
- SmallVector<Value *, 4> Vals;
+ SmallVector<Metadata *, 4> MDs;
for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) {
- Value *V = A->getOperand(i);
+ Metadata *MD = A->getOperand(i);
for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j)
- if (V == B->getOperand(j)) {
- Vals.push_back(V);
+ if (MD == B->getOperand(j)) {
+ MDs.push_back(MD);
break;
}
}
// FIXME: This preserves long-standing behaviour, but is it really the right
// behaviour? Or was that an unintended side-effect of node uniquing?
- return getOrSelfReference(A->getContext(), Vals);
+ return getOrSelfReference(A->getContext(), MDs);
}
MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
if (!A || !B)
return nullptr;
- APFloat AVal = cast<ConstantFP>(A->getOperand(0))->getValueAPF();
- APFloat BVal = cast<ConstantFP>(B->getOperand(0))->getValueAPF();
+ APFloat AVal = mdconst::extract<ConstantFP>(A->getOperand(0))->getValueAPF();
+ APFloat BVal = mdconst::extract<ConstantFP>(B->getOperand(0))->getValueAPF();
if (AVal.compare(BVal) == APFloat::cmpLessThan)
return A;
return B;
@@ -453,25 +681,27 @@ static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) {
return !A.intersectWith(B).isEmptySet() || isContiguous(A, B);
}
-static bool tryMergeRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low,
- ConstantInt *High) {
+static bool tryMergeRange(SmallVectorImpl<ConstantInt *> &EndPoints,
+ ConstantInt *Low, ConstantInt *High) {
ConstantRange NewRange(Low->getValue(), High->getValue());
unsigned Size = EndPoints.size();
- APInt LB = cast<ConstantInt>(EndPoints[Size - 2])->getValue();
- APInt LE = cast<ConstantInt>(EndPoints[Size - 1])->getValue();
+ APInt LB = EndPoints[Size - 2]->getValue();
+ APInt LE = EndPoints[Size - 1]->getValue();
ConstantRange LastRange(LB, LE);
if (canBeMerged(NewRange, LastRange)) {
ConstantRange Union = LastRange.unionWith(NewRange);
Type *Ty = High->getType();
- EndPoints[Size - 2] = ConstantInt::get(Ty, Union.getLower());
- EndPoints[Size - 1] = ConstantInt::get(Ty, Union.getUpper());
+ EndPoints[Size - 2] =
+ cast<ConstantInt>(ConstantInt::get(Ty, Union.getLower()));
+ EndPoints[Size - 1] =
+ cast<ConstantInt>(ConstantInt::get(Ty, Union.getUpper()));
return true;
}
return false;
}
-static void addRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low,
- ConstantInt *High) {
+static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
+ ConstantInt *Low, ConstantInt *High) {
if (!EndPoints.empty())
if (tryMergeRange(EndPoints, Low, High))
return;
@@ -493,31 +723,33 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// First, walk both lists in older of the lower boundary of each interval.
// At each step, try to merge the new interval to the last one we adedd.
- SmallVector<Value*, 4> EndPoints;
+ SmallVector<ConstantInt *, 4> EndPoints;
int AI = 0;
int BI = 0;
int AN = A->getNumOperands() / 2;
int BN = B->getNumOperands() / 2;
while (AI < AN && BI < BN) {
- ConstantInt *ALow = cast<ConstantInt>(A->getOperand(2 * AI));
- ConstantInt *BLow = cast<ConstantInt>(B->getOperand(2 * BI));
+ ConstantInt *ALow = mdconst::extract<ConstantInt>(A->getOperand(2 * AI));
+ ConstantInt *BLow = mdconst::extract<ConstantInt>(B->getOperand(2 * BI));
if (ALow->getValue().slt(BLow->getValue())) {
- addRange(EndPoints, ALow, cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ addRange(EndPoints, ALow,
+ mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
} else {
- addRange(EndPoints, BLow, cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ addRange(EndPoints, BLow,
+ mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
}
while (AI < AN) {
- addRange(EndPoints, cast<ConstantInt>(A->getOperand(2 * AI)),
- cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ addRange(EndPoints, mdconst::extract<ConstantInt>(A->getOperand(2 * AI)),
+ mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
}
while (BI < BN) {
- addRange(EndPoints, cast<ConstantInt>(B->getOperand(2 * BI)),
- cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ addRange(EndPoints, mdconst::extract<ConstantInt>(B->getOperand(2 * BI)),
+ mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
@@ -525,8 +757,8 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// the last and first ones.
unsigned Size = EndPoints.size();
if (Size > 4) {
- ConstantInt *FB = cast<ConstantInt>(EndPoints[0]);
- ConstantInt *FE = cast<ConstantInt>(EndPoints[1]);
+ ConstantInt *FB = EndPoints[0];
+ ConstantInt *FE = EndPoints[1];
if (tryMergeRange(EndPoints, FB, FE)) {
for (unsigned i = 0; i < Size - 2; ++i) {
EndPoints[i] = EndPoints[i + 2];
@@ -538,26 +770,29 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// If in the end we have a single range, it is possible that it is now the
// full range. Just drop the metadata in that case.
if (EndPoints.size() == 2) {
- ConstantRange Range(cast<ConstantInt>(EndPoints[0])->getValue(),
- cast<ConstantInt>(EndPoints[1])->getValue());
+ ConstantRange Range(EndPoints[0]->getValue(), EndPoints[1]->getValue());
if (Range.isFullSet())
return nullptr;
}
- return MDNode::get(A->getContext(), EndPoints);
+ SmallVector<Metadata *, 4> MDs;
+ MDs.reserve(EndPoints.size());
+ for (auto *I : EndPoints)
+ MDs.push_back(ConstantAsMetadata::get(I));
+ return MDNode::get(A->getContext(), MDs);
}
//===----------------------------------------------------------------------===//
// NamedMDNode implementation.
//
-static SmallVector<TrackingVH<MDNode>, 4> &getNMDOps(void *Operands) {
- return *(SmallVector<TrackingVH<MDNode>, 4> *)Operands;
+static SmallVector<TrackingMDRef, 4> &getNMDOps(void *Operands) {
+ return *(SmallVector<TrackingMDRef, 4> *)Operands;
}
NamedMDNode::NamedMDNode(const Twine &N)
: Name(N.str()), Parent(nullptr),
- Operands(new SmallVector<TrackingVH<MDNode>, 4>()) {}
+ Operands(new SmallVector<TrackingMDRef, 4>()) {}
NamedMDNode::~NamedMDNode() {
dropAllReferences();
@@ -570,14 +805,13 @@ unsigned NamedMDNode::getNumOperands() const {
MDNode *NamedMDNode::getOperand(unsigned i) const {
assert(i < getNumOperands() && "Invalid Operand number!");
- return &*getNMDOps(Operands)[i];
+ auto *N = getNMDOps(Operands)[i].get();
+ if (N && i > 10000)
+ N->dump();
+ return cast_or_null<MDNode>(N);
}
-void NamedMDNode::addOperand(MDNode *M) {
- assert(!M->isFunctionLocal() &&
- "NamedMDNode operands must not be function-local!");
- getNMDOps(Operands).push_back(TrackingVH<MDNode>(M));
-}
+void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); }
void NamedMDNode::eraseFromParent() {
getParent()->eraseNamedMetadata(this);
@@ -636,7 +870,7 @@ void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
continue;
}
- Info[I] = Info.back();
+ Info[I] = std::move(Info.back());
Info.pop_back();
--E;
}
@@ -664,8 +898,6 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle the case when we're adding/updating metadata on an instruction.
if (Node) {
- assert(!Node->isFunctionLocal() &&
- "Function-local metadata cannot be attached to instructions");
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
assert(!Info.empty() == hasMetadataHashEntry() &&
"HasMetadata bit is wonked");
@@ -675,13 +907,14 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle replacement of an existing value.
for (auto &P : Info)
if (P.first == KindID) {
- P.second = Node;
+ P.second.reset(Node);
return;
}
}
// No replacement, just add it to the list.
- Info.push_back(std::make_pair(KindID, Node));
+ Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID),
+ std::make_tuple(Node));
return;
}
@@ -703,7 +936,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle removal of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == KindID) {
- Info[i] = Info.back();
+ Info[i] = std::move(Info.back());
Info.pop_back();
assert(!Info.empty() && "Removing last entry should be handled above");
return;
@@ -720,8 +953,8 @@ void Instruction::setAAMetadata(const AAMDNodes &N) {
MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
// Handle 'dbg' as a special case since it is not stored in the hash table.
if (KindID == LLVMContext::MD_dbg)
- return DbgLoc.getAsMDNode(getContext());
-
+ return DbgLoc.getAsMDNode();
+
if (!hasMetadataHashEntry()) return nullptr;
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
@@ -739,8 +972,8 @@ void Instruction::getAllMetadataImpl(
// Handle 'dbg' as a special case since it is not stored in the hash table.
if (!DbgLoc.isUnknown()) {
- Result.push_back(std::make_pair((unsigned)LLVMContext::MD_dbg,
- DbgLoc.getAsMDNode(getContext())));
+ Result.push_back(
+ std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode()));
if (!hasMetadataHashEntry()) return;
}
@@ -751,7 +984,9 @@ void Instruction::getAllMetadataImpl(
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
- Result.append(Info.begin(), Info.end());
+ Result.reserve(Result.size() + Info.size());
+ for (auto &I : Info)
+ Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
// Sort the resulting array so it is stable.
if (Result.size() > 1)
@@ -767,7 +1002,9 @@ void Instruction::getAllMetadataOtherThanDebugLocImpl(
const LLVMContextImpl::MDMapTy &Info =
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
- Result.append(Info.begin(), Info.end());
+ Result.reserve(Result.size() + Info.size());
+ for (auto &I : Info)
+ Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
// Sort the resulting array so it is stable.
if (Result.size() > 1)
diff --git a/llvm/lib/IR/MetadataTracking.cpp b/llvm/lib/IR/MetadataTracking.cpp
new file mode 100644
index 00000000000..5b4b55586a9
--- /dev/null
+++ b/llvm/lib/IR/MetadataTracking.cpp
@@ -0,0 +1,58 @@
+//===- MetadataTracking.cpp - Implement metadata tracking -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Metadata tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/MetadataTracking.h"
+#include "llvm/IR/Metadata.h"
+
+using namespace llvm;
+
+ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
+ if (auto *N = dyn_cast<MDNode>(&MD)) {
+ if (auto *G = dyn_cast<GenericMDNode>(N))
+ return G->ReplaceableUses.get();
+ return cast<MDNodeFwdDecl>(N);
+ }
+ return dyn_cast<ValueAsMetadata>(&MD);
+}
+
+bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
+ assert(Ref && "Expected live reference");
+ assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
+ "Reference without owner must be direct");
+ if (auto *R = ReplaceableMetadataImpl::get(MD)) {
+ R->addRef(Ref, Owner);
+ return true;
+ }
+ return false;
+}
+
+void MetadataTracking::untrack(void *Ref, Metadata &MD) {
+ assert(Ref && "Expected live reference");
+ if (auto *R = ReplaceableMetadataImpl::get(MD))
+ R->dropRef(Ref);
+}
+
+bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
+ assert(Ref && "Expected live reference");
+ assert(New && "Expected live reference");
+ assert(Ref != New && "Expected change");
+ if (auto *R = ReplaceableMetadataImpl::get(MD)) {
+ R->moveRef(Ref, New, MD);
+ return true;
+ }
+ return false;
+}
+
+bool MetadataTracking::isReplaceable(const Metadata &MD) {
+ return ReplaceableMetadataImpl::get(const_cast<Metadata &>(MD));
+}
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 065c66e1491..0781ea4b808 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -260,8 +260,8 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) {
NamedMDList.erase(NMD);
}
-bool Module::isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB) {
- if (ConstantInt *Behavior = dyn_cast<ConstantInt>(V)) {
+bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
+ if (ConstantInt *Behavior = mdconst::dyn_extract<ConstantInt>(MD)) {
uint64_t Val = Behavior->getLimitedValue();
if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) {
MFB = static_cast<ModFlagBehavior>(Val);
@@ -285,7 +285,7 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
// Check the operands of the MDNode before accessing the operands.
// The verifier will actually catch these failures.
MDString *Key = cast<MDString>(Flag->getOperand(1));
- Value *Val = Flag->getOperand(2);
+ Metadata *Val = Flag->getOperand(2);
Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
}
}
@@ -293,7 +293,7 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
/// Return the corresponding value if Key appears in module flags, otherwise
/// return null.
-Value *Module::getModuleFlag(StringRef Key) const {
+Metadata *Module::getModuleFlag(StringRef Key) const {
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
getModuleFlagsMetadata(ModuleFlags);
for (const ModuleFlagEntry &MFE : ModuleFlags) {
@@ -321,14 +321,18 @@ NamedMDNode *Module::getOrInsertModuleFlagsMetadata() {
/// metadata. It will create the module-level flags named metadata if it doesn't
/// already exist.
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
- Value *Val) {
+ Metadata *Val) {
Type *Int32Ty = Type::getInt32Ty(Context);
- Value *Ops[3] = {
- ConstantInt::get(Int32Ty, Behavior), MDString::get(Context, Key), Val
- };
+ Metadata *Ops[3] = {
+ ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)),
+ MDString::get(Context, Key), Val};
getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops));
}
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
+ Constant *Val) {
+ addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val));
+}
+void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
uint32_t Val) {
Type *Int32Ty = Type::getInt32Ty(Context);
addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
@@ -336,7 +340,7 @@ void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
void Module::addModuleFlag(MDNode *Node) {
assert(Node->getNumOperands() == 3 &&
"Invalid number of operands for module flag!");
- assert(isa<ConstantInt>(Node->getOperand(0)) &&
+ assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) &&
isa<MDString>(Node->getOperand(1)) &&
"Invalid operand types for module flag!");
getOrInsertModuleFlagsMetadata()->addOperand(Node);
@@ -459,10 +463,10 @@ void Module::dropAllReferences() {
}
unsigned Module::getDwarfVersion() const {
- Value *Val = getModuleFlag("Dwarf Version");
+ auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version"));
if (!Val)
return dwarf::DWARF_VERSION;
- return cast<ConstantInt>(Val)->getZExtValue();
+ return cast<ConstantInt>(Val->getValue())->getZExtValue();
}
Comdat *Module::getOrInsertComdat(StringRef Name) {
@@ -472,12 +476,13 @@ Comdat *Module::getOrInsertComdat(StringRef Name) {
}
PICLevel::Level Module::getPICLevel() const {
- Value *Val = getModuleFlag("PIC Level");
+ auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level"));
if (Val == NULL)
return PICLevel::Default;
- return static_cast<PICLevel::Level>(cast<ConstantInt>(Val)->getZExtValue());
+ return static_cast<PICLevel::Level>(
+ cast<ConstantInt>(Val->getValue())->getZExtValue());
}
void Module::setPICLevel(PICLevel::Level PL) {
diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp
index 7e92818db5e..e2fb8f84b18 100644
--- a/llvm/lib/IR/TypeFinder.cpp
+++ b/llvm/lib/IR/TypeFinder.cpp
@@ -125,8 +125,13 @@ void TypeFinder::incorporateType(Type *Ty) {
/// other ways. GlobalValues, basic blocks, instructions, and inst operands are
/// all explicitly enumerated.
void TypeFinder::incorporateValue(const Value *V) {
- if (const MDNode *M = dyn_cast<MDNode>(V))
- return incorporateMDNode(M);
+ if (const auto *M = dyn_cast<MetadataAsValue>(V)) {
+ if (const auto *N = dyn_cast<MDNode>(M->getMetadata()))
+ return incorporateMDNode(N);
+ if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
+ return incorporateValue(MDV->getValue());
+ return;
+ }
if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
@@ -152,11 +157,21 @@ void TypeFinder::incorporateValue(const Value *V) {
/// find types hiding within.
void TypeFinder::incorporateMDNode(const MDNode *V) {
// Already visited?
- if (!VisitedConstants.insert(V).second)
+ if (!VisitedMetadata.insert(V).second)
return;
// Look in operands for types.
- for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
- if (Value *Op = V->getOperand(i))
- incorporateValue(Op);
+ for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) {
+ Metadata *Op = V->getOperand(i);
+ if (!Op)
+ continue;
+ if (auto *N = dyn_cast<MDNode>(Op)) {
+ incorporateMDNode(N);
+ continue;
+ }
+ if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) {
+ incorporateValue(C->getValue());
+ continue;
+ }
+ }
}
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 33b9ed20d14..d790f9e1089 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -44,9 +44,8 @@ static inline Type *checkType(Type *Ty) {
}
Value::Value(Type *ty, unsigned scid)
- : VTy(checkType(ty)), UseList(nullptr), Name(nullptr), SubclassID(scid),
- HasValueHandle(0), SubclassOptionalData(0), SubclassData(0),
- NumOperands(0) {
+ : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid), HasValueHandle(0),
+ SubclassOptionalData(0), SubclassData(0), NumOperands(0) {
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
// constructed.
@@ -63,6 +62,8 @@ Value::~Value() {
// Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle)
ValueHandleBase::ValueIsDeleted(this);
+ if (isUsedByMetadata())
+ ValueAsMetadata::handleDeletion(this);
#ifndef NDEBUG // Only in -g mode...
// Check to make sure that there are no uses of this value that are still
@@ -82,13 +83,19 @@ Value::~Value() {
// If this value is named, destroy the name. This should not be in a symtab
// at this point.
- if (Name && SubclassID != MDStringVal)
- Name->Destroy();
+ destroyValueName();
// There should be no uses of this object anymore, remove it.
LeakDetector::removeGarbageObject(this);
}
+void Value::destroyValueName() {
+ ValueName *Name = getValueName();
+ if (Name)
+ Name->Destroy();
+ setValueName(nullptr);
+}
+
bool Value::hasNUses(unsigned N) const {
const_use_iterator UI = use_begin(), E = use_end();
@@ -146,9 +153,7 @@ static bool getSymTab(Value *V, ValueSymbolTable *&ST) {
} else if (Argument *A = dyn_cast<Argument>(V)) {
if (Function *P = A->getParent())
ST = &P->getValueSymbolTable();
- } else if (isa<MDString>(V))
- return true;
- else {
+ } else {
assert(isa<Constant>(V) && "Unknown value type!");
return true; // no name is setable for this.
}
@@ -159,14 +164,12 @@ StringRef Value::getName() const {
// Make sure the empty string is still a C string. For historical reasons,
// some clients want to call .data() on the result and expect it to be null
// terminated.
- if (!Name) return StringRef("", 0);
- return Name->getKey();
+ if (!getValueName())
+ return StringRef("", 0);
+ return getValueName()->getKey();
}
void Value::setName(const Twine &NewName) {
- assert(SubclassID != MDStringVal &&
- "Cannot set the name of MDString with this method!");
-
// Fast path for common IRBuilder case of setName("") when there is no name.
if (NewName.isTriviallyEmpty() && !hasName())
return;
@@ -193,20 +196,17 @@ void Value::setName(const Twine &NewName) {
if (!ST) { // No symbol table to update? Just do the change.
if (NameRef.empty()) {
// Free the name for this value.
- Name->Destroy();
- Name = nullptr;
+ destroyValueName();
return;
}
- if (Name)
- Name->Destroy();
-
// NOTE: Could optimize for the case the name is shrinking to not deallocate
// then reallocated.
+ destroyValueName();
// Create the new name.
- Name = ValueName::Create(NameRef);
- Name->setValue(this);
+ setValueName(ValueName::Create(NameRef));
+ getValueName()->setValue(this);
return;
}
@@ -214,21 +214,18 @@ void Value::setName(const Twine &NewName) {
// then reallocated.
if (hasName()) {
// Remove old name.
- ST->removeValueName(Name);
- Name->Destroy();
- Name = nullptr;
+ ST->removeValueName(getValueName());
+ destroyValueName();
if (NameRef.empty())
return;
}
// Name is changing to something new.
- Name = ST->createValueName(NameRef, this);
+ setValueName(ST->createValueName(NameRef, this));
}
void Value::takeName(Value *V) {
- assert(SubclassID != MDStringVal && "Cannot take the name of an MDString!");
-
ValueSymbolTable *ST = nullptr;
// If this value has a name, drop it.
if (hasName()) {
@@ -242,9 +239,8 @@ void Value::takeName(Value *V) {
// Remove old name.
if (ST)
- ST->removeValueName(Name);
- Name->Destroy();
- Name = nullptr;
+ ST->removeValueName(getValueName());
+ destroyValueName();
}
// Now we know that this has no name.
@@ -270,9 +266,9 @@ void Value::takeName(Value *V) {
// This works even if both values have no symtab yet.
if (ST == VST) {
// Take the name!
- Name = V->Name;
- V->Name = nullptr;
- Name->setValue(this);
+ setValueName(V->getValueName());
+ V->setValueName(nullptr);
+ getValueName()->setValue(this);
return;
}
@@ -280,10 +276,10 @@ void Value::takeName(Value *V) {
// then reinsert it into ST.
if (VST)
- VST->removeValueName(V->Name);
- Name = V->Name;
- V->Name = nullptr;
- Name->setValue(this);
+ VST->removeValueName(V->getValueName());
+ setValueName(V->getValueName());
+ V->setValueName(nullptr);
+ getValueName()->setValue(this);
if (ST)
ST->reinsertValue(this);
@@ -334,6 +330,8 @@ void Value::replaceAllUsesWith(Value *New) {
// Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle)
ValueHandleBase::ValueIsRAUWd(this, New);
+ if (isUsedByMetadata())
+ ValueAsMetadata::handleRAUW(this, New);
while (!use_empty()) {
Use &U = *UseList;
diff --git a/llvm/lib/IR/ValueSymbolTable.cpp b/llvm/lib/IR/ValueSymbolTable.cpp
index 2b23f6dd15b..4f078f09c22 100644
--- a/llvm/lib/IR/ValueSymbolTable.cpp
+++ b/llvm/lib/IR/ValueSymbolTable.cpp
@@ -38,8 +38,8 @@ void ValueSymbolTable::reinsertValue(Value* V) {
assert(V->hasName() && "Can't insert nameless Value into symbol table");
// Try inserting the name, assuming it won't conflict.
- if (vmap.insert(V->Name)) {
- //DEBUG(dbgs() << " Inserted value: " << V->Name << ": " << *V << "\n");
+ if (vmap.insert(V->getValueName())) {
+ //DEBUG(dbgs() << " Inserted value: " << V->getValueName() << ": " << *V << "\n");
return;
}
@@ -47,8 +47,8 @@ void ValueSymbolTable::reinsertValue(Value* V) {
SmallString<256> UniqueName(V->getName().begin(), V->getName().end());
// The name is too already used, just free it so we can allocate a new name.
- V->Name->Destroy();
-
+ V->getValueName()->Destroy();
+
unsigned BaseSize = UniqueName.size();
while (1) {
// Trim any suffix off and append the next number.
@@ -59,7 +59,7 @@ void ValueSymbolTable::reinsertValue(Value* V) {
auto IterBool = vmap.insert(std::make_pair(UniqueName, V));
if (IterBool.second) {
// Newly inserted name. Success!
- V->Name = &*IterBool.first;
+ V->setValueName(&*IterBool.first);
//DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n");
return;
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c025a958385..6545361793e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -102,6 +102,13 @@ struct VerifierSupport {
}
}
+ void WriteMetadata(const Metadata *MD) {
+ if (!MD)
+ return;
+ MD->printAsOperand(OS, true, M);
+ OS << '\n';
+ }
+
void WriteType(Type *T) {
if (!T)
return;
@@ -128,6 +135,24 @@ struct VerifierSupport {
Broken = true;
}
+ void CheckFailed(const Twine &Message, const Metadata *V1, const Metadata *V2,
+ const Metadata *V3 = nullptr, const Metadata *V4 = nullptr) {
+ OS << Message.str() << "\n";
+ WriteMetadata(V1);
+ WriteMetadata(V2);
+ WriteMetadata(V3);
+ WriteMetadata(V4);
+ Broken = true;
+ }
+
+ void CheckFailed(const Twine &Message, const Metadata *V1,
+ const Value *V2 = nullptr) {
+ OS << Message.str() << "\n";
+ WriteMetadata(V1);
+ WriteValue(V2);
+ Broken = true;
+ }
+
void CheckFailed(const Twine &Message, const Value *V1, Type *T2,
const Value *V3 = nullptr) {
OS << Message.str() << "\n";
@@ -167,7 +192,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
SmallPtrSet<Instruction *, 16> InstsInThisBlock;
/// \brief Keep track of the metadata nodes that have been checked already.
- SmallPtrSet<MDNode *, 32> MDNodes;
+ SmallPtrSet<Metadata *, 32> MDNodes;
/// \brief The personality function referenced by the LandingPadInsts.
/// All LandingPadInsts within the same function must use the same
@@ -261,7 +286,9 @@ private:
void visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias *> &Visited,
const GlobalAlias &A, const Constant &C);
void visitNamedMDNode(const NamedMDNode &NMD);
- void visitMDNode(MDNode &MD, Function *F);
+ void visitMDNode(MDNode &MD);
+ void visitMetadataAsValue(MetadataAsValue &MD, Function *F);
+ void visitValueAsMetadata(ValueAsMetadata &MD, Function *F);
void visitComdat(const Comdat &C);
void visitModuleIdents(const Module &M);
void visitModuleFlags(const Module &M);
@@ -560,46 +587,77 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) {
if (!MD)
continue;
- Assert1(!MD->isFunctionLocal(),
- "Named metadata operand cannot be function local!", MD);
- visitMDNode(*MD, nullptr);
+ visitMDNode(*MD);
}
}
-void Verifier::visitMDNode(MDNode &MD, Function *F) {
+void Verifier::visitMDNode(MDNode &MD) {
// Only visit each node once. Metadata can be mutually recursive, so this
// avoids infinite recursion here, as well as being an optimization.
if (!MDNodes.insert(&MD).second)
return;
for (unsigned i = 0, e = MD.getNumOperands(); i != e; ++i) {
- Value *Op = MD.getOperand(i);
+ Metadata *Op = MD.getOperand(i);
if (!Op)
continue;
- if (isa<Constant>(Op) || isa<MDString>(Op))
+ Assert2(!isa<LocalAsMetadata>(Op), "Invalid operand for global metadata!",
+ &MD, Op);
+ if (auto *N = dyn_cast<MDNode>(Op)) {
+ visitMDNode(*N);
continue;
- if (MDNode *N = dyn_cast<MDNode>(Op)) {
- Assert2(MD.isFunctionLocal() || !N->isFunctionLocal(),
- "Global metadata operand cannot be function local!", &MD, N);
- visitMDNode(*N, F);
+ }
+ if (auto *V = dyn_cast<ValueAsMetadata>(Op)) {
+ visitValueAsMetadata(*V, nullptr);
continue;
}
- Assert2(MD.isFunctionLocal(), "Invalid operand for global metadata!", &MD, Op);
-
- // If this was an instruction, bb, or argument, verify that it is in the
- // function that we expect.
- Function *ActualF = nullptr;
- if (Instruction *I = dyn_cast<Instruction>(Op))
- ActualF = I->getParent()->getParent();
- else if (BasicBlock *BB = dyn_cast<BasicBlock>(Op))
- ActualF = BB->getParent();
- else if (Argument *A = dyn_cast<Argument>(Op))
- ActualF = A->getParent();
- assert(ActualF && "Unimplemented function local metadata case!");
-
- Assert2(ActualF == F, "function-local metadata used in wrong function",
- &MD, Op);
}
+
+ // Check these last, so we diagnose problems in operands first.
+ Assert1(!isa<MDNodeFwdDecl>(MD), "Expected no forward declarations!", &MD);
+ Assert1(MD.isResolved(), "All nodes should be resolved!", &MD);
+}
+
+void Verifier::visitValueAsMetadata(ValueAsMetadata &MD, Function *F) {
+ Assert1(MD.getValue(), "Expected valid value", &MD);
+ Assert2(!MD.getValue()->getType()->isMetadataTy(),
+ "Unexpected metadata round-trip through values", &MD, MD.getValue());
+
+ auto *L = dyn_cast<LocalAsMetadata>(&MD);
+ if (!L)
+ return;
+
+ Assert1(F, "function-local metadata used outside a function", L);
+
+ // If this was an instruction, bb, or argument, verify that it is in the
+ // function that we expect.
+ Function *ActualF = nullptr;
+ if (Instruction *I = dyn_cast<Instruction>(L->getValue())) {
+ Assert2(I->getParent(), "function-local metadata not in basic block", L, I);
+ ActualF = I->getParent()->getParent();
+ } else if (BasicBlock *BB = dyn_cast<BasicBlock>(L->getValue()))
+ ActualF = BB->getParent();
+ else if (Argument *A = dyn_cast<Argument>(L->getValue()))
+ ActualF = A->getParent();
+ assert(ActualF && "Unimplemented function local metadata case!");
+
+ Assert1(ActualF == F, "function-local metadata used in wrong function", L);
+}
+
+void Verifier::visitMetadataAsValue(MetadataAsValue &MDV, Function *F) {
+ Metadata *MD = MDV.getMetadata();
+ if (auto *N = dyn_cast<MDNode>(MD)) {
+ visitMDNode(*N);
+ return;
+ }
+
+ // Only visit each node once. Metadata can be mutually recursive, so this
+ // avoids infinite recursion here, as well as being an optimization.
+ if (!MDNodes.insert(MD).second)
+ return;
+
+ if (auto *V = dyn_cast<ValueAsMetadata>(MD))
+ visitValueAsMetadata(*V, F);
}
void Verifier::visitComdat(const Comdat &C) {
@@ -650,7 +708,7 @@ void Verifier::visitModuleFlags(const Module &M) {
for (unsigned I = 0, E = Requirements.size(); I != E; ++I) {
const MDNode *Requirement = Requirements[I];
const MDString *Flag = cast<MDString>(Requirement->getOperand(0));
- const Value *ReqValue = Requirement->getOperand(1);
+ const Metadata *ReqValue = Requirement->getOperand(1);
const MDNode *Op = SeenIDs.lookup(Flag);
if (!Op) {
@@ -679,7 +737,7 @@ Verifier::visitModuleFlag(const MDNode *Op,
Module::ModFlagBehavior MFB;
if (!Module::isValidModFlagBehavior(Op->getOperand(0), MFB)) {
Assert1(
- dyn_cast<ConstantInt>(Op->getOperand(0)),
+ mdconst::dyn_extract<ConstantInt>(Op->getOperand(0)),
"invalid behavior operand in module flag (expected constant integer)",
Op->getOperand(0));
Assert1(false,
@@ -1907,9 +1965,11 @@ void Verifier::visitRangeMetadata(Instruction& I,
ConstantRange LastRange(1); // Dummy initial value
for (unsigned i = 0; i < NumRanges; ++i) {
- ConstantInt *Low = dyn_cast<ConstantInt>(Range->getOperand(2*i));
+ ConstantInt *Low =
+ mdconst::dyn_extract<ConstantInt>(Range->getOperand(2 * i));
Assert1(Low, "The lower limit must be an integer!", Low);
- ConstantInt *High = dyn_cast<ConstantInt>(Range->getOperand(2*i + 1));
+ ConstantInt *High =
+ mdconst::dyn_extract<ConstantInt>(Range->getOperand(2 * i + 1));
Assert1(High, "The upper limit must be an integer!", High);
Assert1(High->getType() == Low->getType() &&
High->getType() == Ty, "Range types must match instruction type!",
@@ -1932,9 +1992,9 @@ void Verifier::visitRangeMetadata(Instruction& I,
}
if (NumRanges > 2) {
APInt FirstLow =
- dyn_cast<ConstantInt>(Range->getOperand(0))->getValue();
+ mdconst::dyn_extract<ConstantInt>(Range->getOperand(0))->getValue();
APInt FirstHigh =
- dyn_cast<ConstantInt>(Range->getOperand(1))->getValue();
+ mdconst::dyn_extract<ConstantInt>(Range->getOperand(1))->getValue();
ConstantRange FirstRange(FirstLow, FirstHigh);
Assert1(FirstRange.intersectWith(LastRange).isEmptySet(),
"Intervals are overlapping", Range);
@@ -2278,8 +2338,8 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(I.getType()->isFPOrFPVectorTy(),
"fpmath requires a floating point result!", &I);
Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I);
- Value *Op0 = MD->getOperand(0);
- if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) {
+ if (ConstantFP *CFP0 =
+ mdconst::dyn_extract_or_null<ConstantFP>(MD->getOperand(0))) {
APFloat Accuracy = CFP0->getValueAPF();
Assert1(Accuracy.isFiniteNonZero() && !Accuracy.isNegative(),
"fpmath accuracy not a positive number!", &I);
@@ -2496,8 +2556,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
// If the intrinsic takes MDNode arguments, verify that they are either global
// or are local to *this* function.
for (unsigned i = 0, e = CI.getNumArgOperands(); i != e; ++i)
- if (MDNode *MD = dyn_cast<MDNode>(CI.getArgOperand(i)))
- visitMDNode(*MD, CI.getParent()->getParent());
+ if (auto *MD = dyn_cast<MetadataAsValue>(CI.getArgOperand(i)))
+ visitMetadataAsValue(*MD, CI.getParent()->getParent());
switch (ID) {
default:
@@ -2509,11 +2569,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
"constant int", &CI);
break;
case Intrinsic::dbg_declare: { // llvm.dbg.declare
- Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)),
- "invalid llvm.dbg.declare intrinsic call 1", &CI);
- MDNode *MD = cast<MDNode>(CI.getArgOperand(0));
- Assert1(MD->getNumOperands() == 1,
- "invalid llvm.dbg.declare intrinsic call 2", &CI);
+ Assert1(CI.getArgOperand(0) && isa<MetadataAsValue>(CI.getArgOperand(0)),
+ "invalid llvm.dbg.declare intrinsic call 1", &CI);
} break;
case Intrinsic::memcpy:
case Intrinsic::memmove:
OpenPOWER on IntegriCloud