ValueMapper: Add support for seeding metadata with nullptr

Support seeding a ValueMap with nullptr for Metadata entries, a
situation I didn't consider in the Metadata/Value split.

I added a ValueMapper::getMappedMD accessor that returns an
Optional<Metadata*> with the mapped (possibly null) metadata.  IRMover
needs to use this to avoid modifying the map when it's checking for
unneeded subprograms.  I updated a call from bugpoint since I find the
new code clearer.

llvm-svn: 265228
This commit is contained in:
Duncan P. N. Exon Smith 2016-04-02 17:04:38 +00:00
parent ddbb1cd45a
commit da4a56d1ab
5 changed files with 43 additions and 6 deletions

View File

@ -27,6 +27,7 @@
#define LLVM_IR_VALUEMAP_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/TrackingMDRef.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Mutex.h"
@ -106,6 +107,16 @@ public:
return *MDMap;
}
/// Get the mapped metadata, if it's in the map.
Optional<Metadata *> getMappedMD(const Metadata *MD) const {
if (!MDMap)
return None;
auto Where = MDMap->find(MD);
if (Where == MDMap->end())
return None;
return Where->second.get();
}
typedef ValueMapIterator<MapT, KeyT> iterator;
typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
inline iterator begin() { return iterator(Map.begin()); }

View File

@ -1091,7 +1091,7 @@ void IRLinker::findNeededSubprograms() {
// Any needed SPs should have been mapped as they would be reached
// from the function linked in (either on the function itself for linked
// function bodies, or from DILocation on inlined instructions).
if (!ValueMap.MD()[Op] && !ImportedEntitySPs.count(Op))
if (!ValueMap.getMappedMD(Op) && !ImportedEntitySPs.count(Op))
UnneededSubprograms.insert(Op);
}
}

View File

@ -305,8 +305,8 @@ static Metadata *MapMetadataImpl(const Metadata *MD,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
// If the value already exists in the map, use it.
if (Metadata *NewMD = VM.MD().lookup(MD).get())
return NewMD;
if (Optional<Metadata *> NewMD = VM.getMappedMD(MD))
return *NewMD;
if (isa<MDString>(MD))
return mapToSelf(VM, MD);
@ -380,8 +380,8 @@ Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
return cast<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM, Flags,
TypeMapper, Materializer));
return cast_or_null<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM,
Flags, TypeMapper, Materializer));
}
/// RemapInstruction - Convert the instruction operands from referencing the

View File

@ -639,7 +639,7 @@ bool ReduceCrashingNamedMDOps::TestNamedMDOps(
// module, and that they don't include any deleted blocks.
NamedMDOps.clear();
for (const MDNode *Node : OldMDNodeOps)
NamedMDOps.push_back(cast<MDNode>(VMap.MD()[Node].get()));
NamedMDOps.push_back(cast<MDNode>(*VMap.getMappedMD(Node)));
BD.setNewProgram(M); // It crashed, keep the trimmed version...
return true;

View File

@ -55,4 +55,30 @@ TEST(ValueMapperTest, MapMetadataDistinctOperands) {
EXPECT_EQ(New, D->getOperand(0));
}
TEST(ValueMapperTest, MapMetadataSeeded) {
LLVMContext Context;
auto *D = MDTuple::getDistinct(Context, None);
// The node should be moved.
ValueToValueMapTy VM;
EXPECT_EQ(None, VM.getMappedMD(D));
VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
EXPECT_EQ(D, *VM.getMappedMD(D));
EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
}
TEST(ValueMapperTest, MapMetadataSeededWithNull) {
LLVMContext Context;
auto *D = MDTuple::getDistinct(Context, None);
// The node should be moved.
ValueToValueMapTy VM;
EXPECT_EQ(None, VM.getMappedMD(D));
VM.MD().insert(std::make_pair(D, TrackingMDRef()));
EXPECT_EQ(nullptr, *VM.getMappedMD(D));
EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
}
} // end namespace