IR: Metadata/Value split: RAUW in a deterministic order

RAUW in a deterministic order to try to recover the hexagon bot [1],
whose tests started failing once my GCC fixes were in for r223802.

Otherwise, I'm not sure why tests would fail there and not here.

[1]: http://lab.llvm.org:8011/builders/llvm-hexagon-elf/builds/13426

llvm-svn: 223829
This commit is contained in:
Duncan P. N. Exon Smith 2014-12-09 21:12:56 +00:00
parent 8ec8dfecd1
commit 21909e35cb
2 changed files with 41 additions and 22 deletions

View File

@ -141,9 +141,11 @@ public:
typedef MetadataTracking::OwnerTy OwnerTy; typedef MetadataTracking::OwnerTy OwnerTy;
private: private:
SmallDenseMap<void *, OwnerTy, 4> UseMap; uint64_t NextIndex;
SmallDenseMap<void *, std::pair<OwnerTy, uint64_t>, 4> UseMap;
public: public:
ReplaceableMetadataImpl() : NextIndex(0) {}
~ReplaceableMetadataImpl() { ~ReplaceableMetadataImpl() {
assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata"); assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");
} }

View File

@ -121,9 +121,14 @@ void MetadataAsValue::untrack() {
} }
void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) { void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
bool WasInserted = UseMap.insert(std::make_pair(Ref, Owner)).second; bool WasInserted =
UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex)))
.second;
(void)WasInserted; (void)WasInserted;
assert(WasInserted && "Expected to add a reference"); assert(WasInserted && "Expected to add a reference");
++NextIndex;
assert(NextIndex != 0 && "Unexpected overflow");
} }
void ReplaceableMetadataImpl::dropRef(void *Ref) { void ReplaceableMetadataImpl::dropRef(void *Ref) {
@ -136,15 +141,17 @@ void ReplaceableMetadataImpl::moveRef(void *Ref, void *New,
const Metadata &MD) { const Metadata &MD) {
auto I = UseMap.find(Ref); auto I = UseMap.find(Ref);
assert(I != UseMap.end() && "Expected to move a reference"); assert(I != UseMap.end() && "Expected to move a reference");
OwnerTy Owner = I->second; auto OwnerAndIndex = I->second;
UseMap.erase(I); UseMap.erase(I);
addRef(New, Owner); bool WasInserted = UseMap.insert(std::make_pair(New, OwnerAndIndex)).second;
(void)WasInserted;
assert(WasInserted && "Expected to add a reference");
// Check that the references are direct if there's no owner. // Check that the references are direct if there's no owner.
(void)MD; (void)MD;
assert((Owner || *static_cast<Metadata **>(Ref) == &MD) && assert((OwnerAndIndex.first || *static_cast<Metadata **>(Ref) == &MD) &&
"Reference without owner must be direct"); "Reference without owner must be direct");
assert((Owner || *static_cast<Metadata **>(New) == &MD) && assert((OwnerAndIndex.first || *static_cast<Metadata **>(New) == &MD) &&
"Reference without owner must be direct"); "Reference without owner must be direct");
} }
@ -155,9 +162,14 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
return; return;
// Copy out uses since UseMap will get touched below. // Copy out uses since UseMap will get touched below.
SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end()); typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
return L.second.second < R.second.second;
});
for (const auto &Pair : Uses) { for (const auto &Pair : Uses) {
if (!Pair.second) { OwnerTy Owner = Pair.second.first;
if (!Owner) {
// Update unowned tracking references directly. // Update unowned tracking references directly.
Metadata *&Ref = *static_cast<Metadata **>(Pair.first); Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
Ref = MD; Ref = MD;
@ -167,17 +179,17 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
} }
// Check for MetadataAsValue. // Check for MetadataAsValue.
if (Pair.second.is<MetadataAsValue *>()) { if (Owner.is<MetadataAsValue *>()) {
Pair.second.get<MetadataAsValue *>()->handleChangedMetadata(MD); Owner.get<MetadataAsValue *>()->handleChangedMetadata(MD);
continue; continue;
} }
// There's a Metadata owner -- dispatch. // There's a Metadata owner -- dispatch.
Metadata *Owner = Pair.second.get<Metadata *>(); Metadata *OwnerMD = Owner.get<Metadata *>();
switch (Owner->getMetadataID()) { switch (OwnerMD->getMetadataID()) {
#define HANDLE_METADATA_LEAF(CLASS) \ #define HANDLE_METADATA_LEAF(CLASS) \
case Metadata::CLASS##Kind: \ case Metadata::CLASS##Kind: \
cast<CLASS>(Owner)->handleChangedOperand(Pair.first, MD); \ cast<CLASS>(OwnerMD)->handleChangedOperand(Pair.first, MD); \
continue; continue;
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
default: default:
@ -197,23 +209,28 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
} }
// Copy out uses since UseMap could get touched below. // Copy out uses since UseMap could get touched below.
SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end()); typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
return L.second.second < R.second.second;
});
UseMap.clear(); UseMap.clear();
for (const auto &Pair : Uses) { for (const auto &Pair : Uses) {
if (!Pair.second) auto Owner = Pair.second.first;
if (!Owner)
continue; continue;
if (Pair.second.is<MetadataAsValue *>()) if (Owner.is<MetadataAsValue *>())
continue; continue;
// Resolve GenericMDNodes that point at this. // Resolve GenericMDNodes that point at this.
auto *Owner = dyn_cast<GenericMDNode>(Pair.second.get<Metadata *>()); auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>());
if (!Owner) if (!OwnerMD)
continue; continue;
if (Owner->isResolved()) if (OwnerMD->isResolved())
continue; continue;
Owner->decrementUnresolvedOperands(); OwnerMD->decrementUnresolvedOperands();
if (!Owner->hasUnresolvedOperands()) if (!OwnerMD->hasUnresolvedOperands())
Owner->resolve(); OwnerMD->resolve();
} }
} }