Files
clang-p2996/llvm/lib/IR/Metadata.cpp
Duncan P. N. Exon Smith 5bf8fef580 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
2014-12-09 18:38:53 +00:00

1022 lines
30 KiB
C++

//===-- Metadata.cpp - Implement Metadata classes -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Metadata classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/Metadata.h"
#include "LLVMContextImpl.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LeakDetector.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
using namespace llvm;
MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD)
: Value(Ty, MetadataAsValueVal), MD(MD) {
track();
}
MetadataAsValue::~MetadataAsValue() {
getType()->getContext().pImpl->MetadataAsValues.erase(MD);
untrack();
}
/// \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;
}
this->MD = MD;
track();
Entry = this;
}
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 to add a reference");
}
void ReplaceableMetadataImpl::dropRef(void *Ref) {
bool WasErased = UseMap.erase(Ref);
(void)WasErased;
assert(WasErased && "Expected to drop a reference");
}
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);
// 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;
// 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;
if (!ResolveUsers) {
UseMap.clear();
return;
}
// 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;
// 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();
}
}
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;
}
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);
}
return Entry;
}
ValueAsMetadata *ValueAsMetadata::getIfExists(Value *V) {
assert(V && "Unexpected null Value");
return V->getContext().pImpl->ValuesAsMetadata.lookup(V);
}
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;
}
//===----------------------------------------------------------------------===//
// MDString implementation.
//
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;
}
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(MDOperand));
MDOperand *First = new (Ptr) MDOperand[NumOps];
return First + NumOps;
}
void MDNode::operator delete(void *Mem) {
MDNode *N = static_cast<MDNode *>(Mem);
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]);
}
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;
}
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();
if (hasUnresolvedOperands())
ReplaceableUses.reset(new ReplaceableMetadataImpl);
}
GenericMDNode::~GenericMDNode() {
LLVMContextImpl *pImpl = getContext().pImpl;
if (isStoredDistinctInContext())
pImpl->NonUniquedMDNodes.erase(this);
else
pImpl->MDNodeSet.erase(this);
}
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();
}
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();
}
}
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();
}
}
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(); }
}
void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
assert(Op < getNumOperands() && "Expected valid operand");
if (isStoredDistinctInContext()) {
assert(isResolved() && "Expected distinct node to be resolved");
// This node is not uniqued. Just set the operand and be done with it.
setOperand(Op, New);
return;
}
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;
}
// 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
// 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();
}
return;
}
// 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::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;
}
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(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");
LeakDetector::removeGarbageObject(N);
delete cast<MDNodeFwdDecl>(N);
}
void MDNode::storeDistinctInContext() {
assert(!IsDistinctInContext && "Expected newly distinct metadata");
IsDistinctInContext = true;
auto *G = cast<GenericMDNode>(this);
G->setHash(0);
getContext().pImpl->NonUniquedMDNodes.insert(G);
}
// Replace value from this node's operand list.
void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
if (getOperand(I) == New)
return;
if (auto *N = dyn_cast<GenericMDNode>(this)) {
N->handleChangedOperand(mutable_begin() + I, New);
return;
}
assert(isa<MDNodeFwdDecl>(this) && "Expected an MDNode");
setOperand(I, New);
}
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.
///
/// Special handling for finding self-references, for use by \a
/// 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<Metadata *> Ops) {
if (!Ops.empty())
if (MDNode *N = dyn_cast_or_null<MDNode>(Ops[0]))
if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) {
for (unsigned I = 1, E = Ops.size(); I != E; ++I)
if (Ops[I] != N->getOperand(I))
return MDNode::get(Context, Ops);
return N;
}
return MDNode::get(Context, Ops);
}
MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
if (!A)
return B;
if (!B)
return A;
SmallVector<Metadata *, 4> MDs(A->getNumOperands() + B->getNumOperands());
unsigned j = 0;
for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i)
MDs[j++] = A->getOperand(i);
for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++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(), MDs);
}
MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
if (!A || !B)
return nullptr;
SmallVector<Metadata *, 4> MDs;
for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) {
Metadata *MD = A->getOperand(i);
for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j)
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(), MDs);
}
MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
if (!A || !B)
return nullptr;
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;
}
static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
}
static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) {
return !A.intersectWith(B).isEmptySet() || isContiguous(A, B);
}
static bool tryMergeRange(SmallVectorImpl<ConstantInt *> &EndPoints,
ConstantInt *Low, ConstantInt *High) {
ConstantRange NewRange(Low->getValue(), High->getValue());
unsigned Size = EndPoints.size();
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] =
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<ConstantInt *> &EndPoints,
ConstantInt *Low, ConstantInt *High) {
if (!EndPoints.empty())
if (tryMergeRange(EndPoints, Low, High))
return;
EndPoints.push_back(Low);
EndPoints.push_back(High);
}
MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// Given two ranges, we want to compute the union of the ranges. This
// is slightly complitade by having to combine the intervals and merge
// the ones that overlap.
if (!A || !B)
return nullptr;
if (A == B)
return A;
// 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<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 = 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,
mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
} else {
addRange(EndPoints, BLow,
mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
}
while (AI < AN) {
addRange(EndPoints, mdconst::extract<ConstantInt>(A->getOperand(2 * AI)),
mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
}
while (BI < BN) {
addRange(EndPoints, mdconst::extract<ConstantInt>(B->getOperand(2 * BI)),
mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
// If we have more than 2 ranges (4 endpoints) we have to try to merge
// the last and first ones.
unsigned Size = EndPoints.size();
if (Size > 4) {
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];
}
EndPoints.resize(Size - 2);
}
}
// 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(EndPoints[0]->getValue(), EndPoints[1]->getValue());
if (Range.isFullSet())
return nullptr;
}
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<TrackingMDRef, 4> &getNMDOps(void *Operands) {
return *(SmallVector<TrackingMDRef, 4> *)Operands;
}
NamedMDNode::NamedMDNode(const Twine &N)
: Name(N.str()), Parent(nullptr),
Operands(new SmallVector<TrackingMDRef, 4>()) {}
NamedMDNode::~NamedMDNode() {
dropAllReferences();
delete &getNMDOps(Operands);
}
unsigned NamedMDNode::getNumOperands() const {
return (unsigned)getNMDOps(Operands).size();
}
MDNode *NamedMDNode::getOperand(unsigned i) const {
assert(i < getNumOperands() && "Invalid Operand number!");
auto *N = getNMDOps(Operands)[i].get();
if (N && i > 10000)
N->dump();
return cast_or_null<MDNode>(N);
}
void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); }
void NamedMDNode::eraseFromParent() {
getParent()->eraseNamedMetadata(this);
}
void NamedMDNode::dropAllReferences() {
getNMDOps(Operands).clear();
}
StringRef NamedMDNode::getName() const {
return StringRef(Name);
}
//===----------------------------------------------------------------------===//
// Instruction Metadata method implementations.
//
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
if (!Node && !hasMetadata())
return;
setMetadata(getContext().getMDKindID(Kind), Node);
}
MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
return getMetadataImpl(getContext().getMDKindID(Kind));
}
void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
SmallSet<unsigned, 5> KnownSet;
KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
// Drop debug if needed
if (KnownSet.erase(LLVMContext::MD_dbg))
DbgLoc = DebugLoc();
if (!hasMetadataHashEntry())
return; // Nothing to remove!
DenseMap<const Instruction *, LLVMContextImpl::MDMapTy> &MetadataStore =
getContext().pImpl->MetadataStore;
if (KnownSet.empty()) {
// Just drop our entry at the store.
MetadataStore.erase(this);
setHasMetadataHashEntry(false);
return;
}
LLVMContextImpl::MDMapTy &Info = MetadataStore[this];
unsigned I;
unsigned E;
// Walk the array and drop any metadata we don't know.
for (I = 0, E = Info.size(); I != E;) {
if (KnownSet.count(Info[I].first)) {
++I;
continue;
}
Info[I] = std::move(Info.back());
Info.pop_back();
--E;
}
assert(E == Info.size());
if (E == 0) {
// Drop our entry at the store.
MetadataStore.erase(this);
setHasMetadataHashEntry(false);
}
}
/// setMetadata - Set the metadata of of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
if (!Node && !hasMetadata())
return;
// Handle 'dbg' as a special case since it is not stored in the hash table.
if (KindID == LLVMContext::MD_dbg) {
DbgLoc = DebugLoc::getFromDILocation(Node);
return;
}
// Handle the case when we're adding/updating metadata on an instruction.
if (Node) {
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
assert(!Info.empty() == hasMetadataHashEntry() &&
"HasMetadata bit is wonked");
if (Info.empty()) {
setHasMetadataHashEntry(true);
} else {
// Handle replacement of an existing value.
for (auto &P : Info)
if (P.first == KindID) {
P.second.reset(Node);
return;
}
}
// No replacement, just add it to the list.
Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID),
std::make_tuple(Node));
return;
}
// Otherwise, we're removing metadata from an instruction.
assert((hasMetadataHashEntry() ==
(getContext().pImpl->MetadataStore.count(this) > 0)) &&
"HasMetadata bit out of date!");
if (!hasMetadataHashEntry())
return; // Nothing to remove!
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
// Common case is removing the only entry.
if (Info.size() == 1 && Info[0].first == KindID) {
getContext().pImpl->MetadataStore.erase(this);
setHasMetadataHashEntry(false);
return;
}
// Handle removal of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == KindID) {
Info[i] = std::move(Info.back());
Info.pop_back();
assert(!Info.empty() && "Removing last entry should be handled above");
return;
}
// Otherwise, removing an entry that doesn't exist on the instruction.
}
void Instruction::setAAMetadata(const AAMDNodes &N) {
setMetadata(LLVMContext::MD_tbaa, N.TBAA);
setMetadata(LLVMContext::MD_alias_scope, N.Scope);
setMetadata(LLVMContext::MD_noalias, N.NoAlias);
}
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();
if (!hasMetadataHashEntry()) return nullptr;
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
assert(!Info.empty() && "bit out of sync with hash table");
for (const auto &I : Info)
if (I.first == KindID)
return I.second;
return nullptr;
}
void Instruction::getAllMetadataImpl(
SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
Result.clear();
// 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()));
if (!hasMetadataHashEntry()) return;
}
assert(hasMetadataHashEntry() &&
getContext().pImpl->MetadataStore.count(this) &&
"Shouldn't have called this");
const LLVMContextImpl::MDMapTy &Info =
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
Result.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)
array_pod_sort(Result.begin(), Result.end());
}
void Instruction::getAllMetadataOtherThanDebugLocImpl(
SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
Result.clear();
assert(hasMetadataHashEntry() &&
getContext().pImpl->MetadataStore.count(this) &&
"Shouldn't have called this");
const LLVMContextImpl::MDMapTy &Info =
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
Result.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)
array_pod_sort(Result.begin(), Result.end());
}
/// clearMetadataHashEntries - Clear all hashtable-based metadata from
/// this instruction.
void Instruction::clearMetadataHashEntries() {
assert(hasMetadataHashEntry() && "Caller should check");
getContext().pImpl->MetadataStore.erase(this);
setHasMetadataHashEntry(false);
}