llvm-project/llvm/lib/Transforms/Utils/ValueMapper.cpp

836 lines
27 KiB
C++
Raw Normal View History

//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue function, which is shared by various parts of
// the lib/Transforms/Utils library.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h"
using namespace llvm;
// Out of line method to get vtable etc for class.
void ValueMapTypeRemapper::anchor() {}
void ValueMaterializer::anchor() {}
void ValueMaterializer::materializeInitFor(GlobalValue *New, GlobalValue *Old) {
}
namespace {
/// A GlobalValue whose initializer needs to be materialized.
struct DelayedGlobalValueInit {
GlobalValue *Old;
GlobalValue *New;
DelayedGlobalValueInit(const GlobalValue *Old, GlobalValue *New)
: Old(const_cast<GlobalValue *>(Old)), New(New) {}
};
/// A basic block used in a BlockAddress whose function body is not yet
/// materialized.
struct DelayedBasicBlock {
BasicBlock *OldBB;
std::unique_ptr<BasicBlock> TempBB;
// Explicit move for MSVC.
DelayedBasicBlock(DelayedBasicBlock &&X)
: OldBB(std::move(X.OldBB)), TempBB(std::move(X.TempBB)) {}
DelayedBasicBlock &operator=(DelayedBasicBlock &&X) {
OldBB = std::move(X.OldBB);
TempBB = std::move(X.TempBB);
return *this;
}
DelayedBasicBlock(const BlockAddress &Old)
: OldBB(Old.getBasicBlock()),
TempBB(BasicBlock::Create(Old.getContext())) {}
};
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
class MDNodeMapper;
class Mapper {
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
friend class MDNodeMapper;
ValueToValueMapTy &VM;
RemapFlags Flags;
ValueMapTypeRemapper *TypeMapper;
ValueMaterializer *Materializer;
SmallVector<DelayedGlobalValueInit, 8> DelayedInits;
SmallVector<DelayedBasicBlock, 1> DelayedBBs;
public:
Mapper(ValueToValueMapTy &VM, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer)
: VM(VM), Flags(Flags), TypeMapper(TypeMapper),
Materializer(Materializer) {}
~Mapper();
Value *mapValue(const Value *V);
void remapInstruction(Instruction *I);
void remapFunction(Function &F);
/// Map metadata.
///
/// Find the mapping for MD. Guarantees that the return will be resolved
/// (not an MDNode, or MDNode::isResolved() returns true).
Metadata *mapMetadata(const Metadata *MD);
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
// Map LocalAsMetadata, which never gets memoized.
//
// If the referenced local is not mapped, the principled return is nullptr.
// However, optimization passes sometimes move metadata operands *before* the
// SSA values they reference. To prevent crashes in \a RemapInstruction(),
// return "!{}" when RF_IgnoreMissingLocals is not set.
//
// \note Adding a mapping for LocalAsMetadata is unsupported. Add a mapping
// to the value map for the SSA value in question instead.
//
// FIXME: Once we have a verifier check for forward references to SSA values
// through metadata operands, always return nullptr on unmapped locals.
Metadata *mapLocalAsMetadata(const LocalAsMetadata &LAM);
private:
Value *mapBlockAddress(const BlockAddress &BA);
/// Map metadata that doesn't require visiting operands.
Optional<Metadata *> mapSimpleMetadata(const Metadata *MD);
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
Metadata *mapToMetadata(const Metadata *Key, Metadata *Val);
Metadata *mapToSelf(const Metadata *MD);
};
class MDNodeMapper {
Mapper &M;
struct Data {
bool HasChangedOps = false;
bool HasChangedAddress = false;
unsigned ID = ~0u;
TempMDNode Placeholder;
Data() {}
Data(Data &&X)
: HasChangedOps(std::move(X.HasChangedOps)),
HasChangedAddress(std::move(X.HasChangedAddress)),
ID(std::move(X.ID)), Placeholder(std::move(X.Placeholder)) {}
Data &operator=(Data &&X) {
HasChangedOps = std::move(X.HasChangedOps);
HasChangedAddress = std::move(X.HasChangedAddress);
ID = std::move(X.ID);
Placeholder = std::move(X.Placeholder);
return *this;
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
};
SmallDenseMap<const Metadata *, Data, 32> Info;
SmallVector<std::pair<MDNode *, bool>, 16> Worklist;
SmallVector<MDNode *, 16> POT;
public:
MDNodeMapper(Mapper &M) : M(M) {}
/// Map a metadata node (and its transitive operands).
///
/// This is the only entry point into MDNodeMapper. It works as follows:
///
/// 1. \a createPOT(): use a worklist to perform a post-order traversal of
/// the transitively referenced unmapped nodes.
///
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// 2. \a propagateChangedOperands(): track which nodes will change
/// operands, and which will have new addresses in the mapped scheme.
/// Propagate the changes through the POT until fixed point, to pick up
/// uniquing cycles that need to change.
///
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// 3. \a mapDistinctNodes(): map all the distinct nodes without touching
/// their operands. If RF_MoveDistinctMetadata, they get mapped to
/// themselves; otherwise, they get mapped to clones.
///
/// 4. \a mapUniquedNodes(): map the uniqued nodes (bottom-up), lazily
/// creating temporaries for forward references as needed.
///
/// 5. \a remapDistinctOperands(): remap the operands of the distinct nodes.
Metadata *map(const MDNode &FirstN);
private:
/// Return \c true as long as there's work to do.
bool hasWork() const { return !Worklist.empty(); }
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// Get the current node in the worklist.
MDNode &getCurrentNode() const { return *Worklist.back().first; }
/// Push a node onto the worklist.
///
/// Adds \c N to \a Worklist and \a Info, unless it's already inserted. If
/// \c N.isDistinct(), \a Data::HasChangedAddress will be set based on \a
/// RF_MoveDistinctMDs.
///
/// Returns the data for the node.
///
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// \post Data::HasChangedAddress iff !RF_MoveDistinctMDs && N.isDistinct().
/// \post Worklist.back().first == &N.
/// \post Worklist.back().second == false.
Data &push(const MDNode &N);
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// Map a node operand, and return true if it changes.
///
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// \post getMappedOp(Op) does not return None.
bool mapOperand(const Metadata *Op);
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
/// Get a previously mapped node.
Optional<Metadata *> getMappedOp(const Metadata *Op) const;
/// Try to pop a node off the worklist and store it in POT.
///
/// Returns \c true if it popped; \c false if its operands need to be
/// visited.
///
/// \post If Worklist.back().second == false: Worklist.back().second == true.
/// \post Else: Worklist.back() has been popped off and added to \a POT.
bool tryToPop();
/// Get a forward reference to a node to use as an operand.
///
/// Returns \c Op if it's not changing; otherwise, lazily creates a temporary
/// node and returns it.
Metadata &getFwdReference(const Data &D, MDNode &Op);
/// Create a post-order traversal from the given node.
///
/// This traverses the metadata graph deeply enough to map \c FirstN. It
/// uses \a mapOperand() (indirectly, \a Mapper::mapSimplifiedNode()), so any
/// metadata that has already been mapped will not be part of the POT.
///
/// \post \a POT is a post-order traversal ending with \c FirstN.
bool createPOT(const MDNode &FirstN);
/// Propagate changed operands through post-order traversal.
///
/// Until fixed point, iteratively update:
///
/// - \a Data::HasChangedOps based on \a Data::HasChangedAddress of operands;
/// - \a Data::HasChangedAddress based on Data::HasChangedOps.
///
/// This algorithm never changes \a Data::HasChangedAddress for distinct
/// nodes.
///
/// \post \a POT is a post-order traversal ending with \c FirstN.
void propagateChangedOperands();
/// Map all distinct nodes in POT.
///
/// \post \a getMappedOp() returns the correct node for every distinct node.
void mapDistinctNodes();
/// Map all uniqued nodes in POT with the correct operands.
///
/// \pre Distinct nodes are mapped (\a mapDistinctNodes() has been called).
/// \post \a getMappedOp() returns the correct node for every node.
/// \post \a MDNode::operands() is correct for every uniqued node.
/// \post \a MDNode::isResolved() returns true for every node.
void mapUniquedNodes();
/// Re-map the operands for distinct nodes in POT.
///
/// \pre Distinct nodes are mapped (\a mapDistinctNodes() has been called).
/// \pre Uniqued nodes are mapped (\a mapUniquedNodes() has been called).
/// \post \a MDNode::operands() is correct for every distinct node.
void remapDistinctOperands();
/// Remap a node's operands.
///
/// Iterate through operands and update them in place using \a getMappedOp()
/// and \a getFwdReference().
///
/// \pre N.isDistinct() or N.isTemporary().
/// \pre Distinct nodes are mapped (\a mapDistinctNodes() has been called).
/// \pre If \c N is distinct, all uniqued nodes are already mapped.
void remapOperands(const Data &D, MDNode &N);
};
} // end namespace
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
return Mapper(VM, Flags, TypeMapper, Materializer).mapValue(V);
}
Value *Mapper::mapValue(const Value *V) {
ValueToValueMapTy::iterator I = VM.find(V);
// If the value already exists in the map, use it.
if (I != VM.end() && I->second) return I->second;
// If we have a materializer and it can materialize a value, use that.
if (Materializer) {
if (Value *NewV =
Materializer->materializeDeclFor(const_cast<Value *>(V))) {
VM[V] = NewV;
if (auto *NewGV = dyn_cast<GlobalValue>(NewV))
DelayedInits.push_back(
DelayedGlobalValueInit(cast<GlobalValue>(V), NewGV));
return NewV;
}
}
// Global values do not need to be seeded into the VM if they
// are using the identity mapping.
Fix mapping of unmaterialized global values during metadata linking Summary: The patch to move metadata linking after global value linking didn't correctly map unmaterialized global values to null as desired. They were in fact mapped to the source copy. It largely worked by accident since most module linker clients destroyed the source module which caused the source GVs to be replaced by null, but caused a failure with LTO linking on Windows: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312869.html The problem is that a null return value from materializeValueFor is handled by mapping the value to self. This is the desired behavior when materializeValueFor is passed a non-GlobalValue. The problem is how to distinguish that case from the case where we really do want to map to null. This patch addresses this by passing in a new flag to the value mapper indicating that unmapped global values should be mapped to null. Other Value types are handled as before. Note that the documented behavior of asserting on unmapped values when the flag RF_IgnoreMissingValues isn't set is currently disabled with FIXME notes due to bootstrap failures. I modified these disabled asserts so when they are eventually enabled again it won't assert for the unmapped values when the new RF_NullMapMissingGlobalValues flag is set. I also considered using a callback into the value materializer, but a flag seemed cleaner given that there are already existing flags. I also considered modifying materializeValueFor to return the input value when we want to map to source and then treat a null return to mean map to null. However, there are other value materializer subclasses that implement materializeValueFor, and they would all need to be audited and the return values possibly changed, which seemed error-prone. Reviewers: dexonsmith, joker.eph Subscribers: pcc, llvm-commits Differential Revision: http://reviews.llvm.org/D14682 llvm-svn: 253170
2015-11-15 22:50:14 +08:00
if (isa<GlobalValue>(V)) {
if (Flags & RF_NullMapMissingGlobalValues)
Fix mapping of unmaterialized global values during metadata linking Summary: The patch to move metadata linking after global value linking didn't correctly map unmaterialized global values to null as desired. They were in fact mapped to the source copy. It largely worked by accident since most module linker clients destroyed the source module which caused the source GVs to be replaced by null, but caused a failure with LTO linking on Windows: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312869.html The problem is that a null return value from materializeValueFor is handled by mapping the value to self. This is the desired behavior when materializeValueFor is passed a non-GlobalValue. The problem is how to distinguish that case from the case where we really do want to map to null. This patch addresses this by passing in a new flag to the value mapper indicating that unmapped global values should be mapped to null. Other Value types are handled as before. Note that the documented behavior of asserting on unmapped values when the flag RF_IgnoreMissingValues isn't set is currently disabled with FIXME notes due to bootstrap failures. I modified these disabled asserts so when they are eventually enabled again it won't assert for the unmapped values when the new RF_NullMapMissingGlobalValues flag is set. I also considered using a callback into the value materializer, but a flag seemed cleaner given that there are already existing flags. I also considered modifying materializeValueFor to return the input value when we want to map to source and then treat a null return to mean map to null. However, there are other value materializer subclasses that implement materializeValueFor, and they would all need to be audited and the return values possibly changed, which seemed error-prone. Reviewers: dexonsmith, joker.eph Subscribers: pcc, llvm-commits Differential Revision: http://reviews.llvm.org/D14682 llvm-svn: 253170
2015-11-15 22:50:14 +08:00
return nullptr;
return VM[V] = const_cast<Value*>(V);
Fix mapping of unmaterialized global values during metadata linking Summary: The patch to move metadata linking after global value linking didn't correctly map unmaterialized global values to null as desired. They were in fact mapped to the source copy. It largely worked by accident since most module linker clients destroyed the source module which caused the source GVs to be replaced by null, but caused a failure with LTO linking on Windows: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312869.html The problem is that a null return value from materializeValueFor is handled by mapping the value to self. This is the desired behavior when materializeValueFor is passed a non-GlobalValue. The problem is how to distinguish that case from the case where we really do want to map to null. This patch addresses this by passing in a new flag to the value mapper indicating that unmapped global values should be mapped to null. Other Value types are handled as before. Note that the documented behavior of asserting on unmapped values when the flag RF_IgnoreMissingValues isn't set is currently disabled with FIXME notes due to bootstrap failures. I modified these disabled asserts so when they are eventually enabled again it won't assert for the unmapped values when the new RF_NullMapMissingGlobalValues flag is set. I also considered using a callback into the value materializer, but a flag seemed cleaner given that there are already existing flags. I also considered modifying materializeValueFor to return the input value when we want to map to source and then treat a null return to mean map to null. However, there are other value materializer subclasses that implement materializeValueFor, and they would all need to be audited and the return values possibly changed, which seemed error-prone. Reviewers: dexonsmith, joker.eph Subscribers: pcc, llvm-commits Differential Revision: http://reviews.llvm.org/D14682 llvm-svn: 253170
2015-11-15 22:50:14 +08:00
}
if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
// Inline asm may need *type* remapping.
FunctionType *NewTy = IA->getFunctionType();
if (TypeMapper) {
NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));
if (NewTy != IA->getFunctionType())
V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
IA->hasSideEffects(), IA->isAlignStack());
}
return VM[V] = const_cast<Value*>(V);
}
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-10 02:38:53 +08:00
if (const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
const Metadata *MD = MDV->getMetadata();
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
if (auto *LAM = dyn_cast<LocalAsMetadata>(MD)) {
// Look through to grab the local value.
if (Value *LV = mapValue(LAM->getValue())) {
if (V == LAM->getValue())
return const_cast<Value *>(V);
return MetadataAsValue::get(V->getContext(), ValueAsMetadata::get(LV));
}
// FIXME: always return nullptr once Verifier::verifyDominatesUse()
// ensures metadata operands only reference defined SSA values.
return (Flags & RF_IgnoreMissingLocals)
? nullptr
: MetadataAsValue::get(V->getContext(),
MDTuple::get(V->getContext(), None));
}
// If this is a module-level metadata and we know that nothing at the module
// level is changing, then use an identity mapping.
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
if (Flags & RF_NoModuleLevelChanges)
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-10 02:38:53 +08:00
return VM[V] = const_cast<Value *>(V);
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
// Map the metadata and turn it into a value.
auto *MappedMD = mapMetadata(MD);
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
if (MD == MappedMD)
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-10 02:38:53 +08:00
return VM[V] = const_cast<Value *>(V);
return VM[V] = MetadataAsValue::get(V->getContext(), MappedMD);
}
// Okay, this either must be a constant (which may or may not be mappable) or
// is something that is not in the mapping table.
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
if (!C)
return nullptr;
if (BlockAddress *BA = dyn_cast<BlockAddress>(C))
return mapBlockAddress(*BA);
// Otherwise, we have some other constant to remap. Start by checking to see
// if all operands have an identity remapping.
unsigned OpNo = 0, NumOperands = C->getNumOperands();
Value *Mapped = nullptr;
for (; OpNo != NumOperands; ++OpNo) {
Value *Op = C->getOperand(OpNo);
Mapped = mapValue(Op);
if (Mapped != C) break;
}
// See if the type mapper wants to remap the type as well.
Type *NewTy = C->getType();
if (TypeMapper)
NewTy = TypeMapper->remapType(NewTy);
// If the result type and all operands match up, then just insert an identity
// mapping.
if (OpNo == NumOperands && NewTy == C->getType())
return VM[V] = C;
// Okay, we need to create a new constant. We've already processed some or
// all of the operands, set them all up now.
SmallVector<Constant*, 8> Ops;
Ops.reserve(NumOperands);
for (unsigned j = 0; j != OpNo; ++j)
Ops.push_back(cast<Constant>(C->getOperand(j)));
// If one of the operands mismatch, push it and the other mapped operands.
if (OpNo != NumOperands) {
Ops.push_back(cast<Constant>(Mapped));
// Map the rest of the operands that aren't processed yet.
for (++OpNo; OpNo != NumOperands; ++OpNo)
Ops.push_back(cast<Constant>(mapValue(C->getOperand(OpNo))));
}
Type *NewSrcTy = nullptr;
if (TypeMapper)
if (auto *GEPO = dyn_cast<GEPOperator>(C))
NewSrcTy = TypeMapper->remapType(GEPO->getSourceElementType());
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
return VM[V] = CE->getWithOperands(Ops, NewTy, false, NewSrcTy);
if (isa<ConstantArray>(C))
return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
if (isa<ConstantStruct>(C))
return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
if (isa<ConstantVector>(C))
return VM[V] = ConstantVector::get(Ops);
// If this is a no-operand constant, it must be because the type was remapped.
if (isa<UndefValue>(C))
return VM[V] = UndefValue::get(NewTy);
if (isa<ConstantAggregateZero>(C))
return VM[V] = ConstantAggregateZero::get(NewTy);
assert(isa<ConstantPointerNull>(C));
return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}
Value *Mapper::mapBlockAddress(const BlockAddress &BA) {
Function *F = cast<Function>(mapValue(BA.getFunction()));
// F may not have materialized its initializer. In that case, create a
// dummy basic block for now, and replace it once we've materialized all
// the initializers.
BasicBlock *BB;
if (F->empty()) {
DelayedBBs.push_back(DelayedBasicBlock(BA));
BB = DelayedBBs.back().TempBB.get();
} else {
BB = cast_or_null<BasicBlock>(mapValue(BA.getBasicBlock()));
}
return VM[&BA] = BlockAddress::get(F, BB ? BB : BA.getBasicBlock());
}
Metadata *Mapper::mapToMetadata(const Metadata *Key, Metadata *Val) {
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-10 02:38:53 +08:00
VM.MD()[Key].reset(Val);
return Val;
}
Metadata *Mapper::mapToSelf(const Metadata *MD) {
return mapToMetadata(MD, const_cast<Metadata *>(MD));
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-10 02:38:53 +08:00
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
bool MDNodeMapper::mapOperand(const Metadata *Op) {
if (!Op)
return false;
if (Optional<Metadata *> MappedOp = M.mapSimpleMetadata(Op)) {
assert((isa<MDString>(Op) || M.VM.getMappedMD(Op)) &&
"Expected result to be memoized");
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
return *MappedOp != Op;
}
return push(*cast<MDNode>(Op)).HasChangedAddress;
}
Optional<Metadata *> MDNodeMapper::getMappedOp(const Metadata *Op) const {
if (!Op)
return nullptr;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
if (Optional<Metadata *> MappedOp = M.VM.getMappedMD(Op))
return *MappedOp;
if (isa<MDString>(Op))
return const_cast<Metadata *>(Op);
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
return None;
}
Metadata &MDNodeMapper::getFwdReference(const Data &D, MDNode &Op) {
auto Where = Info.find(&Op);
assert(Where != Info.end() && "Expected a valid reference");
auto &OpD = Where->second;
assert(OpD.ID > D.ID && "Expected a forward reference");
if (!OpD.HasChangedAddress)
return Op;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
// Lazily construct a temporary node.
if (!OpD.Placeholder)
OpD.Placeholder = Op.clone();
return *OpD.Placeholder;
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
void MDNodeMapper::remapOperands(const Data &D, MDNode &N) {
for (unsigned I = 0, E = N.getNumOperands(); I != E; ++I) {
Metadata *Old = N.getOperand(I);
Metadata *New;
if (Optional<Metadata *> MappedOp = getMappedOp(Old)){
New = *MappedOp;
} else {
assert(!N.isDistinct() &&
"Expected all nodes to be pre-mapped for distinct operands");
MDNode &OldN = *cast<MDNode>(Old);
assert(!OldN.isDistinct() && "Expected distinct nodes to be pre-mapped");
New = &getFwdReference(D, OldN);
}
if (Old != New)
N.replaceOperandWith(I, New);
}
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
MDNodeMapper::Data &MDNodeMapper::push(const MDNode &N) {
auto Insertion = Info.insert(std::make_pair(&N, Data()));
auto &D = Insertion.first->second;
if (!Insertion.second)
return D;
// Add to the worklist; check for distinct nodes that are required to be
// copied.
Worklist.push_back(std::make_pair(&const_cast<MDNode &>(N), false));
D.HasChangedAddress = !(M.Flags & RF_MoveDistinctMDs) && N.isDistinct();
return D;
}
bool MDNodeMapper::tryToPop() {
if (!Worklist.back().second) {
Worklist.back().second = true;
return false;
}
MDNode *N = Worklist.pop_back_val().first;
Info[N].ID = POT.size();
POT.push_back(N);
return true;
}
bool MDNodeMapper::createPOT(const MDNode &FirstN) {
bool AnyChanges = false;
// Do a traversal of the unmapped subgraph, tracking whether operands change.
// In some cases, these changes will propagate naturally, but
// propagateChangedOperands() catches the general case.
AnyChanges |= push(FirstN).HasChangedAddress;
while (hasWork()) {
if (tryToPop())
continue;
MDNode &N = getCurrentNode();
bool LocalChanges = false;
for (const Metadata *Op : N.operands())
LocalChanges |= mapOperand(Op);
if (!LocalChanges)
continue;
AnyChanges = true;
auto &D = Info[&N];
D.HasChangedOps = true;
// Uniqued nodes change address when operands change.
if (!N.isDistinct())
D.HasChangedAddress = true;
}
return AnyChanges;
}
void MDNodeMapper::propagateChangedOperands() {
bool AnyChangedAddresses;
do {
AnyChangedAddresses = false;
for (MDNode *N : POT) {
auto &NI = Info[N];
if (NI.HasChangedOps)
continue;
if (!llvm::any_of(N->operands(), [&](const Metadata *Op) {
auto Where = Info.find(Op);
return Where != Info.end() && Where->second.HasChangedAddress;
}))
continue;
NI.HasChangedOps = true;
if (!N->isDistinct()) {
NI.HasChangedAddress = true;
AnyChangedAddresses = true;
}
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
} while (AnyChangedAddresses);
}
void MDNodeMapper::mapDistinctNodes() {
// Map all the distinct nodes in POT.
for (MDNode *N : POT) {
if (!N->isDistinct())
continue;
if (M.Flags & RF_MoveDistinctMDs)
M.mapToSelf(N);
else
M.mapToMetadata(N, MDNode::replaceWithDistinct(N->clone()));
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
}
void MDNodeMapper::mapUniquedNodes() {
// Construct uniqued nodes, building forward references as necessary.
SmallVector<MDNode *, 16> CyclicNodes;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
for (auto *N : POT) {
if (N->isDistinct())
continue;
auto &D = Info[N];
assert(D.HasChangedAddress == D.HasChangedOps &&
"Uniqued nodes should change address iff ops change");
if (!D.HasChangedAddress) {
M.mapToSelf(N);
continue;
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
TempMDNode ClonedN = D.Placeholder ? std::move(D.Placeholder) : N->clone();
remapOperands(D, *ClonedN);
CyclicNodes.push_back(MDNode::replaceWithUniqued(std::move(ClonedN)));
M.mapToMetadata(N, CyclicNodes.back());
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
}
// Resolve cycles.
for (auto *N : CyclicNodes)
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
if (!N->isResolved())
N->resolveCycles();
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
void MDNodeMapper::remapDistinctOperands() {
for (auto *N : POT) {
if (!N->isDistinct())
continue;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
auto &D = Info[N];
if (!D.HasChangedOps)
continue;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
assert(D.HasChangedAddress == !bool(M.Flags & RF_MoveDistinctMDs) &&
"Distinct nodes should change address iff they cannot be moved");
remapOperands(D, D.HasChangedAddress ? *cast<MDNode>(*getMappedOp(N)) : *N);
}
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
Metadata *MDNodeMapper::map(const MDNode &FirstN) {
assert(!(M.Flags & RF_NoModuleLevelChanges) &&
"MDNodeMapper::map assumes module-level changes");
assert(POT.empty() && "MDNodeMapper::map is not re-entrant");
// Require resolved nodes whenever metadata might be remapped.
assert(FirstN.isResolved() && "Unexpected unresolved node");
// Return early if nothing at all changed.
if (!createPOT(FirstN)) {
for (const MDNode *N : POT)
M.mapToSelf(N);
return &const_cast<MDNode &>(FirstN);
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
propagateChangedOperands();
mapDistinctNodes();
mapUniquedNodes();
remapDistinctOperands();
// Return the original node, remapped.
return *getMappedOp(&FirstN);
}
Optional<Metadata *> Mapper::mapSimpleMetadata(const Metadata *MD) {
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-10 02:38:53 +08:00
// If the value already exists in the map, use it.
if (Optional<Metadata *> NewMD = VM.getMappedMD(MD))
return *NewMD;
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-10 02:38:53 +08:00
if (isa<MDString>(MD))
return const_cast<Metadata *>(MD);
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-10 02:38:53 +08:00
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
// This is a module-level metadata. If nothing at the module level is
// changing, use an identity mapping.
if ((Flags & RF_NoModuleLevelChanges))
return const_cast<Metadata *>(MD);
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-10 02:38:53 +08:00
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
if (auto *CMD = dyn_cast<ConstantAsMetadata>(MD)) {
// Disallow recursion into metadata mapping through mapValue.
VM.disableMapMetadata();
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
Value *MappedV = mapValue(CMD->getValue());
VM.enableMapMetadata();
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
if (CMD->getValue() == MappedV)
return mapToSelf(MD);
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-10 02:38:53 +08:00
return mapToMetadata(MD, MappedV ? ValueAsMetadata::get(MappedV) : nullptr);
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-10 02:38:53 +08:00
}
assert(isa<MDNode>(MD) && "Expected a metadata node");
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-10 02:38:53 +08:00
return None;
}
Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
return Mapper(VM, Flags, TypeMapper, Materializer).mapMetadata(MD);
}
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
Metadata *Mapper::mapLocalAsMetadata(const LocalAsMetadata &LAM) {
// Lookup the mapping for the value itself, and return the appropriate
// metadata.
if (Value *V = mapValue(LAM.getValue())) {
if (V == LAM.getValue())
return const_cast<LocalAsMetadata *>(&LAM);
return ValueAsMetadata::get(V);
}
// FIXME: always return nullptr once Verifier::verifyDominatesUse() ensures
// metadata operands only reference defined SSA values.
return (Flags & RF_IgnoreMissingLocals)
? nullptr
: MDTuple::get(LAM.getContext(), None);
}
Metadata *Mapper::mapMetadata(const Metadata *MD) {
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values" This reverts commit r265765, reapplying r265759 after changing a call from LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug intrinsic operand may no longer be pointing at a local. http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/ The previous coommit message follows: -- This is a partial re-commit -- maybe more of a re-implementation -- of r265631 (reverted in r265637). This makes RF_IgnoreMissingLocals behave (almost) consistently between the Value and the Metadata hierarchy. In particular: - MapValue returns nullptr or "metadata !{}" for missing locals in MetadataAsValue/LocalAsMetadata bridging paris, depending on the RF_IgnoreMissingLocals flag. - MapValue doesn't memoize LocalAsMetadata-related results. - MapMetadata no longer deals with LocalAsMetadata or RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but I realized during testing it would make the patch simpler with no loss of generality.) r265631 went too far, making both functions universally ignore RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt. Reassociate (and possibly other passes) don't currently maintain dominates-use invariants for metadata operands, resulting in IR like this: define void @foo(i32 %arg) { call void @llvm.some.intrinsic(metadata i32 %x) %x = add i32 1, i32 %arg } If the inliner chooses to inline @foo into another function, then RemapInstruction will call `MapValue(metadata i32 %x)` and assert that the return is not nullptr. I've filed PR27273 to add a Verifier check and fix the underlying problem in the optimization passes. As a workaround, return `!{}` instead of nullptr for unmapped LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match the behaviour of r265631. Original commit message: ValueMapper: Make LocalAsMetadata match function-local Values Start treating LocalAsMetadata similarly to function-local members of the Value hierarchy in MapValue and MapMetadata. - Don't memoize them. - Return nullptr if they are missing. This also cleans up ConstantAsMetadata to stop listening to the RF_IgnoreMissingLocals flag. llvm-svn: 265768
2016-04-08 11:13:22 +08:00
assert(MD && "Expected valid metadata");
assert(!isa<LocalAsMetadata>(MD) && "Unexpected local metadata");
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
if (Optional<Metadata *> NewMD = mapSimpleMetadata(MD))
return *NewMD;
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
return MDNodeMapper(*this).map(*cast<MDNode>(MD));
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-10 02:38:53 +08:00
}
Mapper::~Mapper() {
// Materialize global initializers.
while (!DelayedInits.empty()) {
auto Init = DelayedInits.pop_back_val();
Materializer->materializeInitFor(Init.New, Init.Old);
}
// Process block addresses delayed until global inits.
while (!DelayedBBs.empty()) {
DelayedBasicBlock DBB = DelayedBBs.pop_back_val();
BasicBlock *BB = cast_or_null<BasicBlock>(mapValue(DBB.OldBB));
DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
}
ValueMapper: Rewrite Mapper::mapMetadata without recursion This commit completely rewrites Mapper::mapMetadata (the implementation of llvm::MapMetadata) using an iterative algorithm. The guts of the new algorithm are in MDNodeMapper::map, the entry function in a new class. Previously, Mapper::mapMetadata performed a recursive exploration of the graph with eager "just in case there's a reason" malloc traffic. The new algorithm has these benefits: - New nodes and temporaries are not created eagerly. - Uniquing cycles are not duplicated (see new unit test). - No recursion. Given a node to map, it does this: 1. Use a worklist to perform a post-order traversal of the transitively referenced unmapped nodes. 2. Track which nodes will change operands, and which will have new addresses in the mapped scheme. Propagate the changes through the POT until fixed point, to pick up uniquing cycles that need to change. 3. Map all the distinct nodes without touching their operands. If RF_MoveDistinctMetadata, they get mapped to themselves; otherwise, they get mapped to clones. 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for forward references as needed. 5. Remap the operands of the distinct nodes. Mehdi helped me out by profiling this with -flto=thin. On his workload (importing/etc. for opt.cpp), MapMetadata sped up by 15%, contributed about 50% less to persistent memory, and made about 100x fewer calls to malloc. The speedup is less than I'd hoped. The profile mainly blames DenseMap lookups; perhaps there's a way to reduce them (e.g., by disallowing remapping of MDString). It would be nice to break the strange remaining recursion on the Value side: MapValue => materializeInitFor => RemapInstruction => MapValue. I think we could do this by having materializeInitFor return a worklist of things to be remapped. llvm-svn: 265456
2016-04-06 04:23:21 +08:00
// We don't expect these to grow after clearing.
assert(DelayedInits.empty());
assert(DelayedBBs.empty());
}
MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
return cast_or_null<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM,
Flags, TypeMapper, Materializer));
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-10 02:38:53 +08:00
}
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
Mapper(VM, Flags, TypeMapper, Materializer).remapInstruction(I);
}
void Mapper::remapInstruction(Instruction *I) {
// Remap operands.
for (Use &Op : I->operands()) {
Value *V = mapValue(Op);
// If we aren't ignoring missing entries, assert that something happened.
if (V)
Op = V;
else
assert((Flags & RF_IgnoreMissingLocals) &&
"Referenced value not in value map!");
}
// Remap phi nodes' incoming blocks.
if (PHINode *PN = dyn_cast<PHINode>(I)) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *V = mapValue(PN->getIncomingBlock(i));
// If we aren't ignoring missing entries, assert that something happened.
if (V)
PN->setIncomingBlock(i, cast<BasicBlock>(V));
else
assert((Flags & RF_IgnoreMissingLocals) &&
"Referenced block not in value map!");
}
}
// Remap attached metadata.
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
I->getAllMetadata(MDs);
for (const auto &MI : MDs) {
MDNode *Old = MI.second;
MDNode *New = cast_or_null<MDNode>(mapMetadata(Old));
if (New != Old)
I->setMetadata(MI.first, New);
}
if (!TypeMapper)
return;
// If the instruction's type is being remapped, do so now.
if (auto CS = CallSite(I)) {
SmallVector<Type *, 3> Tys;
FunctionType *FTy = CS.getFunctionType();
Tys.reserve(FTy->getNumParams());
for (Type *Ty : FTy->params())
Tys.push_back(TypeMapper->remapType(Ty));
CS.mutateFunctionType(FunctionType::get(
TypeMapper->remapType(I->getType()), Tys, FTy->isVarArg()));
return;
}
if (auto *AI = dyn_cast<AllocaInst>(I))
AI->setAllocatedType(TypeMapper->remapType(AI->getAllocatedType()));
if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
GEP->setSourceElementType(
TypeMapper->remapType(GEP->getSourceElementType()));
GEP->setResultElementType(
TypeMapper->remapType(GEP->getResultElementType()));
}
I->mutateType(TypeMapper->remapType(I->getType()));
}
void llvm::RemapFunction(Function &F, ValueToValueMapTy &VM, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
Mapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
}
void Mapper::remapFunction(Function &F) {
// Remap the operands.
for (Use &Op : F.operands())
if (Op)
Op = mapValue(Op);
// Remap the metadata attachments.
SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
F.getAllMetadata(MDs);
for (const auto &I : MDs)
F.setMetadata(I.first, cast_or_null<MDNode>(mapMetadata(I.second)));
// Remap the argument types.
if (TypeMapper)
for (Argument &A : F.args())
A.mutateType(TypeMapper->remapType(A.getType()));
// Remap the instructions.
for (BasicBlock &BB : F)
for (Instruction &I : BB)
remapInstruction(&I);
}