[llvm] r264763 - [ThinLTO] Remove post-pass metadata linking support

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 29 13:56:13 PDT 2016


Nice!


On 29 March 2016 at 14:24, Teresa Johnson via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: tejohnson
> Date: Tue Mar 29 13:24:19 2016
> New Revision: 264763
>
> URL: http://llvm.org/viewvc/llvm-project?rev=264763&view=rev
> Log:
> [ThinLTO] Remove post-pass metadata linking support
>
> Since we have moved to a model where functions are imported in bulk from
> each source module after making summary-based importing decisions, there
> is no longer a need to link metadata as a postpass, and all users have
> been removed.
>
> This essentially reverts r255909 and follow-on fixes.
>
> Modified:
>     llvm/trunk/include/llvm/IR/GVMaterializer.h
>     llvm/trunk/include/llvm/IR/Metadata.h
>     llvm/trunk/include/llvm/Linker/IRMover.h
>     llvm/trunk/include/llvm/Linker/Linker.h
>     llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h
>     llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>     llvm/trunk/lib/IR/Metadata.cpp
>     llvm/trunk/lib/Linker/IRMover.cpp
>     llvm/trunk/lib/Linker/LinkModules.cpp
>     llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
>     llvm/trunk/unittests/IR/MetadataTest.cpp
>
> Modified: llvm/trunk/include/llvm/IR/GVMaterializer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GVMaterializer.h?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/GVMaterializer.h (original)
> +++ llvm/trunk/include/llvm/IR/GVMaterializer.h Tue Mar 29 13:24:19 2016
> @@ -18,14 +18,12 @@
>  #ifndef LLVM_IR_GVMATERIALIZER_H
>  #define LLVM_IR_GVMATERIALIZER_H
>
> -#include "llvm/ADT/DenseMap.h"
>  #include <system_error>
>  #include <vector>
>
>  namespace llvm {
>  class Function;
>  class GlobalValue;
> -class Metadata;
>  class Module;
>  class StructType;
>
> @@ -47,14 +45,6 @@ public:
>    virtual std::error_code materializeMetadata() = 0;
>    virtual void setStripDebugInfo() = 0;
>
> -  /// Client should define this interface if the mapping between metadata
> -  /// values and value ids needs to be preserved, e.g. across materializer
> -  /// instantiations. If OnlyTempMD is true, only those that have remained
> -  /// temporary metadata are recorded in the map.
> -  virtual void
> -  saveMetadataList(DenseMap<const Metadata *, unsigned> &MetadataToIDs,
> -                   bool OnlyTempMD) {}
> -
>    virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0;
>  };
>
>
> Modified: llvm/trunk/include/llvm/IR/Metadata.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Metadata.h (original)
> +++ llvm/trunk/include/llvm/IR/Metadata.h Tue Mar 29 13:24:19 2016
> @@ -283,20 +283,14 @@ private:
>    LLVMContext &Context;
>    uint64_t NextIndex;
>    SmallDenseMap<void *, std::pair<OwnerTy, uint64_t>, 4> UseMap;
> -  /// Flag that can be set to false if this metadata should not be
> -  /// RAUW'ed, e.g. if it is used as the key of a map.
> -  bool CanReplace;
>
>  public:
>    ReplaceableMetadataImpl(LLVMContext &Context)
> -      : Context(Context), NextIndex(0), CanReplace(true) {}
> +      : Context(Context), NextIndex(0) {}
>    ~ReplaceableMetadataImpl() {
>      assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");
>    }
>
> -  /// Set the CanReplace flag to the given value.
> -  void setCanReplace(bool Replaceable) { CanReplace = Replaceable; }
> -
>    LLVMContext &getContext() const { return Context; }
>
>    /// \brief Replace all uses of this with MD.
> @@ -906,29 +900,13 @@ public:
>      Context.getReplaceableUses()->replaceAllUsesWith(MD);
>    }
>
> -  /// Set the CanReplace flag to the given value.
> -  void setCanReplace(bool Replaceable) {
> -    Context.getReplaceableUses()->setCanReplace(Replaceable);
> -  }
> -
>    /// \brief Resolve cycles.
>    ///
>    /// Once all forward declarations have been resolved, force cycles to be
> -  /// resolved. This interface is used when there are no more temporaries,
> -  /// and thus unresolved nodes are part of cycles and no longer need RAUW
> -  /// support.
> +  /// resolved.
>    ///
>    /// \pre No operands (or operands' operands, etc.) have \a isTemporary().
> -  void resolveCycles() { resolveRecursivelyImpl(/* AllowTemps */ false); }
> -
> -  /// \brief Resolve cycles while ignoring temporaries.
> -  ///
> -  /// This drops RAUW support for any temporaries, which can no longer
> -  /// be uniqued.
> -  ///
> -  void resolveNonTemporaries() {
> -    resolveRecursivelyImpl(/* AllowTemps */ true);
> -  }
> +  void resolveCycles();
>
>    /// \brief Replace a temporary node with a permanent one.
>    ///
> @@ -986,11 +964,6 @@ private:
>    void decrementUnresolvedOperandCount();
>    unsigned countUnresolvedOperands();
>
> -  /// Resolve cycles recursively. If \p AllowTemps is true, then any temporary
> -  /// metadata is ignored, otherwise it asserts when encountering temporary
> -  /// metadata.
> -  void resolveRecursivelyImpl(bool AllowTemps);
> -
>    /// \brief Mutate this to be "uniqued".
>    ///
>    /// Mutate this so that \a isUniqued().
>
> Modified: llvm/trunk/include/llvm/Linker/IRMover.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Linker/IRMover.h?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Linker/IRMover.h (original)
> +++ llvm/trunk/include/llvm/Linker/IRMover.h Tue Mar 29 13:24:19 2016
> @@ -16,7 +16,6 @@
>
>  namespace llvm {
>  class GlobalValue;
> -class MDNode;
>  class Module;
>  class StructType;
>  class Type;
> @@ -69,9 +68,7 @@ public:
>    ///
>    /// Returns true on error.
>    bool move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
> -            std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor,
> -            DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr,
> -            bool IsMetadataLinkingPostpass = false);
> +            std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor);
>    Module &getModule() { return Composite; }
>
>  private:
>
> Modified: llvm/trunk/include/llvm/Linker/Linker.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Linker/Linker.h?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Linker/Linker.h (original)
> +++ llvm/trunk/include/llvm/Linker/Linker.h Tue Mar 29 13:24:19 2016
> @@ -41,23 +41,13 @@ public:
>    /// For ThinLTO function importing/exporting the \p ModuleSummaryIndex
>    /// is passed. If \p GlobalsToImport is provided, only the globals that
>    /// are part of the set will be imported from the source module.
> -  /// The \p ValIDToTempMDMap is populated by the linker when function
> -  /// importing is performed.
>    ///
>    /// Returns true on error.
>    bool linkInModule(std::unique_ptr<Module> Src, unsigned Flags = Flags::None,
> -                    DenseSet<const GlobalValue *> *GlobalsToImport = nullptr,
> -                    DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr);
> +                    DenseSet<const GlobalValue *> *GlobalsToImport = nullptr);
>
>    static bool linkModules(Module &Dest, std::unique_ptr<Module> Src,
>                            unsigned Flags = Flags::None);
> -
> -  /// \brief Link metadata from \p Src into the composite.
> -  ///
> -  /// The \p ValIDToTempMDMap sound have been populated earlier during function
> -  /// importing from \p Src.
> -  bool linkInMetadata(std::unique_ptr<Module> Src,
> -                      DenseMap<unsigned, MDNode *> *ValIDToTempMDMap);
>  };
>
>  } // End llvm namespace
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h Tue Mar 29 13:24:19 2016
> @@ -56,12 +56,6 @@ namespace llvm {
>      /// about recursion.
>      virtual void materializeInitFor(GlobalValue *New, GlobalValue *Old);
>
> -    /// If the client needs to handle temporary metadata it must implement
> -    /// these methods.
> -    virtual Metadata *mapTemporaryMetadata(Metadata *MD) { return nullptr; }
> -    virtual void replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                          Metadata *NewMD) {}
> -
>      /// The client should implement this method if some metadata need
>      /// not be mapped, for example DISubprogram metadata for functions not
>      /// linked into the destination module.
> @@ -89,11 +83,6 @@ namespace llvm {
>      /// Any global values not in value map are mapped to null instead of
>      /// mapping to self. Illegal if RF_IgnoreMissingEntries is also set.
>      RF_NullMapMissingGlobalValues = 8,
> -
> -    /// Set when there is still temporary metadata that must be handled,
> -    /// such as when we are doing function importing and will materialize
> -    /// and link metadata as a postpass.
> -    RF_HaveUnmaterializedMetadata = 16,
>    };
>
>    static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Mar 29 13:24:19 2016
> @@ -268,14 +268,6 @@ public:
>
>    void setStripDebugInfo() override;
>
> -  /// Save the mapping between the metadata values and the corresponding
> -  /// value id that were recorded in the MetadataList during parsing. If
> -  /// OnlyTempMD is true, then only record those entries that are still
> -  /// temporary metadata. This interface is used when metadata linking is
> -  /// performed as a postpass, such as during function importing.
> -  void saveMetadataList(DenseMap<const Metadata *, unsigned> &MetadataToIDs,
> -                        bool OnlyTempMD) override;
> -
>  private:
>    /// Parse the "IDENTIFICATION_BLOCK_ID" block, populate the
>    // ProducerIdentification data member, and do some basic enforcement on the
> @@ -3126,36 +3118,6 @@ std::error_code BitcodeReader::materiali
>
>  void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; }
>
> -void BitcodeReader::saveMetadataList(
> -    DenseMap<const Metadata *, unsigned> &MetadataToIDs, bool OnlyTempMD) {
> -  for (unsigned ID = 0; ID < MetadataList.size(); ++ID) {
> -    Metadata *MD = MetadataList[ID];
> -    auto *N = dyn_cast_or_null<MDNode>(MD);
> -    assert((!N || (N->isResolved() || N->isTemporary())) &&
> -           "Found non-resolved non-temp MDNode while saving metadata");
> -    // Save all values if !OnlyTempMD, otherwise just the temporary metadata.
> -    // Note that in the !OnlyTempMD case we need to save all Metadata, not
> -    // just MDNode, as we may have references to other types of module-level
> -    // metadata (e.g. ValueAsMetadata) from instructions.
> -    if (!OnlyTempMD || (N && N->isTemporary())) {
> -      // Will call this after materializing each function, in order to
> -      // handle remapping of the function's instructions/metadata.
> -      auto IterBool = MetadataToIDs.insert(std::make_pair(MD, ID));
> -      // See if we already have an entry in that case.
> -      if (OnlyTempMD && !IterBool.second) {
> -        assert(IterBool.first->second == ID &&
> -               "Inconsistent metadata value id");
> -        continue;
> -      }
> -      if (N && N->isTemporary())
> -        // Ensure that we assert if someone tries to RAUW this temporary
> -        // metadata while it is the key of a map. The flag will be set back
> -        // to true when the saved metadata list is destroyed.
> -        N->setCanReplace(false);
> -    }
> -  }
> -}
> -
>  /// When we see the block for a function body, remember where it is and then
>  /// skip it.  This lets us lazily deserialize the functions.
>  std::error_code BitcodeReader::rememberAndSkipFunctionBody() {
>
> Modified: llvm/trunk/lib/IR/Metadata.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/Metadata.cpp (original)
> +++ llvm/trunk/lib/IR/Metadata.cpp Tue Mar 29 13:24:19 2016
> @@ -188,9 +188,6 @@ void ReplaceableMetadataImpl::moveRef(vo
>  }
>
>  void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
> -  assert(CanReplace &&
> -         "Attempted to replace Metadata marked for no replacement");
> -
>    if (UseMap.empty())
>      return;
>
> @@ -550,7 +547,7 @@ void MDNode::decrementUnresolvedOperandC
>      resolve();
>  }
>
> -void MDNode::resolveRecursivelyImpl(bool AllowTemps) {
> +void MDNode::resolveCycles() {
>    if (isResolved())
>      return;
>
> @@ -563,8 +560,6 @@ void MDNode::resolveRecursivelyImpl(bool
>      if (!N)
>        continue;
>
> -    if (N->isTemporary() && AllowTemps)
> -      continue;
>      assert(!N->isTemporary() &&
>             "Expected all forward declarations to be resolved");
>      if (!N->isResolved())
>
> Modified: llvm/trunk/lib/Linker/IRMover.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Linker/IRMover.cpp (original)
> +++ llvm/trunk/lib/Linker/IRMover.cpp Tue Mar 29 13:24:19 2016
> @@ -351,9 +351,6 @@ public:
>    GlobalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {}
>    Value *materializeDeclFor(Value *V) override;
>    void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
> -  Metadata *mapTemporaryMetadata(Metadata *MD) override;
> -  void replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                Metadata *NewMD) override;
>    bool isMetadataNeeded(Metadata *MD) override;
>  };
>
> @@ -364,9 +361,6 @@ public:
>    LocalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {}
>    Value *materializeDeclFor(Value *V) override;
>    void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
> -  Metadata *mapTemporaryMetadata(Metadata *MD) override;
> -  void replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                Metadata *NewMD) override;
>    bool isMetadataNeeded(Metadata *MD) override;
>  };
>
> @@ -405,24 +399,9 @@ class IRLinker {
>
>    bool HasError = false;
>
> -  /// Flag indicating that we are just linking metadata (after function
> -  /// importing).
> -  bool IsMetadataLinkingPostpass;
> -
>    /// Flags to pass to value mapper invocations.
>    RemapFlags ValueMapperFlags = RF_MoveDistinctMDs;
>
> -  /// Association between metadata values created during bitcode parsing and
> -  /// the value id. Used to correlate temporary metadata created during
> -  /// function importing with the final metadata parsed during the subsequent
> -  /// metadata linking postpass.
> -  DenseMap<const Metadata *, unsigned> MetadataToIDs;
> -
> -  /// Association between metadata value id and temporary metadata that
> -  /// remains unmapped after function importing. Saved during function
> -  /// importing and consumed during the metadata linking postpass.
> -  DenseMap<unsigned, MDNode *> *ValIDToTempMDMap;
> -
>    /// Set of subprogram metadata that does not need to be linked into the
>    /// destination module, because the functions were not imported directly
>    /// or via an inlined body in an imported function.
> @@ -443,14 +422,6 @@ class IRLinker {
>      SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message));
>    }
>
> -  /// Check whether we should be linking metadata from the source module.
> -  bool shouldLinkMetadata() {
> -    // ValIDToTempMDMap will be non-null when we are importing or otherwise want
> -    // to link metadata lazily, and then when linking the metadata.
> -    // We only want to return true for the former case.
> -    return ValIDToTempMDMap == nullptr || IsMetadataLinkingPostpass;
> -  }
> -
>    /// Given a global in the source module, return the global in the
>    /// destination module that is being linked to, if any.
>    GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
> @@ -507,11 +478,6 @@ class IRLinker {
>    /// in an imported function.
>    void findNeededSubprograms();
>
> -  /// Recursive helper for findNeededSubprograms to locate any DISubprogram
> -  /// reached from the given Node, marking any found as needed.
> -  void findReachedSubprograms(const MDNode *Node,
> -                              SmallPtrSet<const MDNode *, 16> &Visited);
> -
>    /// The value mapper leaves nulls in the list of subprograms for any
>    /// in the UnneededSubprograms map. Strip those out of the mapped
>    /// compile unit.
> @@ -520,53 +486,17 @@ class IRLinker {
>  public:
>    IRLinker(Module &DstM, IRMover::IdentifiedStructTypeSet &Set,
>             std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink,
> -           std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor,
> -           DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr,
> -           bool IsMetadataLinkingPostpass = false)
> +           std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor)
>        : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(AddLazyFor), TypeMap(Set),
> -        GValMaterializer(*this), LValMaterializer(*this),
> -        IsMetadataLinkingPostpass(IsMetadataLinkingPostpass),
> -        ValIDToTempMDMap(ValIDToTempMDMap) {
> +        GValMaterializer(*this), LValMaterializer(*this) {
>      for (GlobalValue *GV : ValuesToLink)
>        maybeAdd(GV);
> -
> -    // If appropriate, tell the value mapper that it can expect to see
> -    // temporary metadata.
> -    if (!shouldLinkMetadata())
> -      ValueMapperFlags = ValueMapperFlags | RF_HaveUnmaterializedMetadata;
> -  }
> -
> -  ~IRLinker() {
> -    // In the case where we are not linking metadata, we unset the CanReplace
> -    // flag on all temporary metadata in the MetadataToIDs map to ensure
> -    // none was replaced while being a map key. Now that we are destructing
> -    // the map, set the flag back to true, so that it is replaceable during
> -    // metadata linking.
> -    if (!shouldLinkMetadata()) {
> -      for (auto MDI : MetadataToIDs) {
> -        Metadata *MD = const_cast<Metadata *>(MDI.first);
> -        MDNode *Node = dyn_cast<MDNode>(MD);
> -        assert((Node && Node->isTemporary()) &&
> -               "Found non-temp metadata in map when not linking metadata");
> -        Node->setCanReplace(true);
> -      }
> -    }
>    }
>
>    bool run();
>    Value *materializeDeclFor(Value *V, bool ForAlias);
>    void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias);
>
> -  /// Save the mapping between the given temporary metadata and its metadata
> -  /// value id. Used to support metadata linking as a postpass for function
> -  /// importing.
> -  Metadata *mapTemporaryMetadata(Metadata *MD);
> -
> -  /// Replace any temporary metadata saved for the source metadata's id with
> -  /// the new non-temporary metadata. Used when metadata linking as a postpass
> -  /// for function importing.
> -  void replaceTemporaryMetadata(const Metadata *OrigMD, Metadata *NewMD);
> -
>    /// Indicates whether we need to map the given metadata into the destination
>    /// module. Used to prevent linking of metadata only needed by functions not
>    /// linked into the dest module.
> @@ -604,15 +534,6 @@ void GlobalValueMaterializer::materializ
>    TheIRLinker.materializeInitFor(New, Old, false);
>  }
>
> -Metadata *GlobalValueMaterializer::mapTemporaryMetadata(Metadata *MD) {
> -  return TheIRLinker.mapTemporaryMetadata(MD);
> -}
> -
> -void GlobalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                                       Metadata *NewMD) {
> -  TheIRLinker.replaceTemporaryMetadata(OrigMD, NewMD);
> -}
> -
>  bool GlobalValueMaterializer::isMetadataNeeded(Metadata *MD) {
>    return TheIRLinker.isMetadataNeeded(MD);
>  }
> @@ -626,15 +547,6 @@ void LocalValueMaterializer::materialize
>    TheIRLinker.materializeInitFor(New, Old, true);
>  }
>
> -Metadata *LocalValueMaterializer::mapTemporaryMetadata(Metadata *MD) {
> -  return TheIRLinker.mapTemporaryMetadata(MD);
> -}
> -
> -void LocalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                                      Metadata *NewMD) {
> -  TheIRLinker.replaceTemporaryMetadata(OrigMD, NewMD);
> -}
> -
>  bool LocalValueMaterializer::isMetadataNeeded(Metadata *MD) {
>    return TheIRLinker.isMetadataNeeded(MD);
>  }
> @@ -666,50 +578,6 @@ void IRLinker::materializeInitFor(Global
>      linkGlobalValueBody(*New, *Old);
>  }
>
> -Metadata *IRLinker::mapTemporaryMetadata(Metadata *MD) {
> -  if (!ValIDToTempMDMap)
> -    return nullptr;
> -  // If this temporary metadata has a value id recorded during function
> -  // parsing, record that in the ValIDToTempMDMap if one was provided.
> -  auto I = MetadataToIDs.find(MD);
> -  if (I == MetadataToIDs.end())
> -    return nullptr;
> -  unsigned Idx = I->second;
> -  MDNode *Node = cast<MDNode>(MD);
> -  assert(Node->isTemporary());
> -  // If we created a temp MD when importing a different function from
> -  // this module, reuse the same temporary metadata.
> -  auto IterBool = ValIDToTempMDMap->insert(std::make_pair(Idx, Node));
> -  return IterBool.first->second;
> -}
> -
> -void IRLinker::replaceTemporaryMetadata(const Metadata *OrigMD,
> -                                        Metadata *NewMD) {
> -  if (!ValIDToTempMDMap)
> -    return;
> -#ifndef NDEBUG
> -  auto *N = dyn_cast_or_null<MDNode>(NewMD);
> -  assert(!N || !N->isTemporary());
> -#endif
> -  // If a mapping between metadata value ids and temporary metadata
> -  // created during function importing was provided, and the source
> -  // metadata has a value id recorded during metadata parsing, replace
> -  // the temporary metadata with the final mapped metadata now.
> -  auto I = MetadataToIDs.find(OrigMD);
> -  if (I == MetadataToIDs.end())
> -    return;
> -  unsigned Idx = I->second;
> -  auto VI = ValIDToTempMDMap->find(Idx);
> -  // Nothing to do if we didn't need to create a temporary metadata during
> -  // function importing.
> -  if (VI == ValIDToTempMDMap->end())
> -    return;
> -  MDNode *TempMD = VI->second;
> -  TempMD->replaceAllUsesWith(NewMD);
> -  MDNode::deleteTemporary(TempMD);
> -  ValIDToTempMDMap->erase(VI);
> -}
> -
>  bool IRLinker::isMetadataNeeded(Metadata *MD) {
>    // Currently only DISubprogram metadata is marked as being unneeded.
>    if (UnneededSubprograms.empty())
> @@ -1017,14 +885,6 @@ Constant *IRLinker::linkAppendingVarProt
>  }
>
>  bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) {
> -  // Already imported all the values. Just map to the Dest value
> -  // in case it is referenced in the metadata.
> -  if (IsMetadataLinkingPostpass) {
> -    assert(!ValuesToLink.count(&SGV) &&
> -           "Source value unexpectedly requested for link during metadata link");
> -    return false;
> -  }
> -
>    if (ValuesToLink.count(&SGV))
>      return true;
>
> @@ -1133,14 +993,6 @@ bool IRLinker::linkFunctionBody(Function
>    if (std::error_code EC = Src.materialize())
>      return emitError(EC.message());
>
> -  if (!shouldLinkMetadata())
> -    // This is only supported for lazy links. Do after materialization of
> -    // a function and before remapping metadata on instructions below
> -    // in RemapInstruction, as the saved mapping is used to handle
> -    // the temporary metadata hanging off instructions.
> -    SrcM->getMaterializer()->saveMetadataList(MetadataToIDs,
> -                                              /* OnlyTempMD = */ true);
> -
>    // Link in the prefix data.
>    if (Src.hasPrefixData())
>      Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, ValueMapperFlags,
> @@ -1212,21 +1064,6 @@ bool IRLinker::linkGlobalValueBody(Globa
>    return false;
>  }
>
> -void IRLinker::findReachedSubprograms(
> -    const MDNode *Node, SmallPtrSet<const MDNode *, 16> &Visited) {
> -  if (!Visited.insert(Node).second)
> -    return;
> -  DISubprogram *SP = getDISubprogram(Node);
> -  if (SP)
> -    UnneededSubprograms.erase(SP);
> -  for (auto &Op : Node->operands()) {
> -    const MDNode *OpN = dyn_cast_or_null<MDNode>(Op.get());
> -    if (!OpN)
> -      continue;
> -    findReachedSubprograms(OpN, Visited);
> -  }
> -}
> -
>  void IRLinker::findNeededSubprograms() {
>    // Track unneeded nodes to make it simpler to handle the case
>    // where we are checking if an already-mapped SP is needed.
> @@ -1251,32 +1088,13 @@ void IRLinker::findNeededSubprograms() {
>          ImportedEntitySPs.insert(SP);
>      }
>      for (auto *Op : CU->getSubprograms()) {
> -      // Unless we were doing function importing and deferred metadata linking,
> -      // any needed SPs should have been mapped as they would be reached
> +      // Any needed SPs should have been mapped as they would be reached
>        // from the function linked in (either on the function itself for linked
>        // function bodies, or from DILocation on inlined instructions).
> -      assert(!(ValueMap.MD()[Op] && IsMetadataLinkingPostpass) &&
> -             "DISubprogram shouldn't be mapped yet");
>        if (!ValueMap.MD()[Op] && !ImportedEntitySPs.count(Op))
>          UnneededSubprograms.insert(Op);
>      }
>    }
> -  if (!IsMetadataLinkingPostpass)
> -    return;
> -  // In the case of metadata linking as a postpass (e.g. for function
> -  // importing), see which MD from the source has an associated
> -  // temporary metadata node, which means that any DISubprogram
> -  // reached from that MD was needed by an imported function.
> -  SmallPtrSet<const MDNode *, 16> Visited;
> -  for (auto MDI : MetadataToIDs) {
> -    const MDNode *Node = dyn_cast<MDNode>(MDI.first);
> -    if (!Node)
> -      continue;
> -    if (!ValIDToTempMDMap->count(MDI.second))
> -      continue;
> -    // Find any SP needed recursively from this needed Node.
> -    findReachedSubprograms(Node, Visited);
> -  }
>  }
>
>  // Squash null subprograms from the given compile unit's subprogram list.
> @@ -1505,8 +1323,7 @@ static std::string mergeTriples(const Tr
>
>  bool IRLinker::run() {
>    // Ensure metadata materialized before value mapping.
> -  if (shouldLinkMetadata() && SrcM->getMaterializer())
> -    if (SrcM->getMaterializer()->materializeMetadata())
> +  if (SrcM->getMaterializer() && SrcM->getMaterializer()->materializeMetadata())
>        return true;
>
>    // Inherit the target data from the source module if the destination module
> @@ -1572,36 +1389,11 @@ bool IRLinker::run() {
>    // Remap all of the named MDNodes in Src into the DstM module. We do this
>    // after linking GlobalValues so that MDNodes that reference GlobalValues
>    // are properly remapped.
> -  if (shouldLinkMetadata()) {
> -    // Even if just linking metadata we should link decls above in case
> -    // any are referenced by metadata. IRLinker::shouldLink ensures that
> -    // we don't actually link anything from source.
> -    if (IsMetadataLinkingPostpass)
> -      SrcM->getMaterializer()->saveMetadataList(MetadataToIDs,
> -                                                /* OnlyTempMD = */ false);
> -
> -    linkNamedMDNodes();
> -
> -    if (IsMetadataLinkingPostpass) {
> -      // Handle anything left in the ValIDToTempMDMap, such as metadata nodes
> -      // not reached by the dbg.cu NamedMD (i.e. only reached from
> -      // instructions).
> -      // Walk the MetadataToIDs once to find the set of new (imported) MD
> -      // that still has corresponding temporary metadata, and invoke metadata
> -      // mapping on each one.
> -      for (auto MDI : MetadataToIDs) {
> -        if (!ValIDToTempMDMap->count(MDI.second))
> -          continue;
> -        MapMetadata(MDI.first, ValueMap, ValueMapperFlags, &TypeMap,
> -                    &GValMaterializer);
> -      }
> -      assert(ValIDToTempMDMap->empty());
> -    }
> +  linkNamedMDNodes();
>
> -    // Merge the module flags into the DstM module.
> -    if (linkModuleFlagsMetadata())
> -      return true;
> -  }
> +  // Merge the module flags into the DstM module.
> +  if (linkModuleFlagsMetadata())
> +    return true;
>
>    return false;
>  }
> @@ -1709,12 +1501,9 @@ IRMover::IRMover(Module &M) : Composite(
>
>  bool IRMover::move(
>      std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
> -    std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor,
> -    DenseMap<unsigned, MDNode *> *ValIDToTempMDMap,
> -    bool IsMetadataLinkingPostpass) {
> +    std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor) {
>    IRLinker TheIRLinker(Composite, IdentifiedStructTypes, std::move(Src),
> -                       ValuesToLink, AddLazyFor, ValIDToTempMDMap,
> -                       IsMetadataLinkingPostpass);
> +                       ValuesToLink, AddLazyFor);
>    bool RetCode = TheIRLinker.run();
>    Composite.dropTriviallyDeadConstantArrays();
>    return RetCode;
>
> Modified: llvm/trunk/lib/Linker/LinkModules.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Linker/LinkModules.cpp (original)
> +++ llvm/trunk/lib/Linker/LinkModules.cpp Tue Mar 29 13:24:19 2016
> @@ -39,11 +39,6 @@ class ModuleLinker {
>    /// imported as declarations instead of definitions.
>    DenseSet<const GlobalValue *> *GlobalsToImport;
>
> -  /// Association between metadata value id and temporary metadata that
> -  /// remains unmapped after function importing. Saved during function
> -  /// importing and consumed during the metadata linking postpass.
> -  DenseMap<unsigned, MDNode *> *ValIDToTempMDMap;
> -
>    /// Used as the callback for lazy linking.
>    /// The mover has just hit GV and we have to decide if it, and other members
>    /// of the same comdat, should be linked. Every member to be linked is passed
> @@ -119,10 +114,9 @@ class ModuleLinker {
>
>  public:
>    ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,
> -               DenseSet<const GlobalValue *> *GlobalsToImport = nullptr,
> -               DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr)
> +               DenseSet<const GlobalValue *> *GlobalsToImport = nullptr)
>        : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags),
> -        GlobalsToImport(GlobalsToImport), ValIDToTempMDMap(ValIDToTempMDMap) {}
> +        GlobalsToImport(GlobalsToImport) {}
>
>    bool run();
>  };
> @@ -590,8 +584,7 @@ bool ModuleLinker::run() {
>    if (Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
>                   [this](GlobalValue &GV, IRMover::ValueAdder Add) {
>                     addLazyFor(GV, Add);
> -                 },
> -                 ValIDToTempMDMap, false))
> +                 }))
>      return true;
>    for (auto &P : Internalize) {
>      GlobalValue *GV = DstM.getNamedValue(P.first());
> @@ -604,24 +597,11 @@ bool ModuleLinker::run() {
>  Linker::Linker(Module &M) : Mover(M) {}
>
>  bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags,
> -                          DenseSet<const GlobalValue *> *GlobalsToImport,
> -                          DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
> -  ModuleLinker ModLinker(Mover, std::move(Src), Flags, GlobalsToImport,
> -                         ValIDToTempMDMap);
> +                          DenseSet<const GlobalValue *> *GlobalsToImport) {
> +  ModuleLinker ModLinker(Mover, std::move(Src), Flags, GlobalsToImport);
>    return ModLinker.run();
>  }
>
> -bool Linker::linkInMetadata(std::unique_ptr<Module> Src,
> -                            DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
> -  SetVector<GlobalValue *> ValuesToLink;
> -  if (Mover.move(
> -          std::move(Src), ValuesToLink.getArrayRef(),
> -          [this](GlobalValue &GV, IRMover::ValueAdder Add) { assert(false); },
> -          ValIDToTempMDMap, true))
> -    return true;
> -  return false;
> -}
> -
>  //===----------------------------------------------------------------------===//
>  // LinkModules entrypoint.
>  //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Tue Mar 29 13:24:19 2016
> @@ -167,21 +167,13 @@ Value *llvm::MapValue(const Value *V, Va
>  }
>
>  static Metadata *mapToMetadata(ValueToValueMapTy &VM, const Metadata *Key,
> -                               Metadata *Val, ValueMaterializer *Materializer,
> -                               RemapFlags Flags) {
> +                               Metadata *Val) {
>    VM.MD()[Key].reset(Val);
> -  if (Materializer && !(Flags & RF_HaveUnmaterializedMetadata)) {
> -    auto *N = dyn_cast_or_null<MDNode>(Val);
> -    // Need to invoke this once we have non-temporary MD.
> -    if (!N || !N->isTemporary())
> -      Materializer->replaceTemporaryMetadata(Key, Val);
> -  }
>    return Val;
>  }
>
> -static Metadata *mapToSelf(ValueToValueMapTy &VM, const Metadata *MD,
> -                           ValueMaterializer *Materializer, RemapFlags Flags) {
> -  return mapToMetadata(VM, MD, const_cast<Metadata *>(MD), Materializer, Flags);
> +static Metadata *mapToSelf(ValueToValueMapTy &VM, const Metadata *MD) {
> +  return mapToMetadata(VM, MD, const_cast<Metadata *>(MD));
>  }
>
>  static Metadata *MapMetadataImpl(const Metadata *MD,
> @@ -218,22 +210,10 @@ static Metadata *mapMetadataOp(Metadata
>  }
>
>  /// Resolve uniquing cycles involving the given metadata.
> -static void resolveCycles(Metadata *MD, bool AllowTemps) {
> -  if (auto *N = dyn_cast_or_null<MDNode>(MD)) {
> -    if (AllowTemps && N->isTemporary())
> -      return;
> -    if (!N->isResolved()) {
> -      if (AllowTemps)
> -        // Note that this will drop RAUW support on any temporaries, which
> -        // blocks uniquing. If this ends up being an issue, in the future
> -        // we can experiment with delaying resolving these nodes until
> -        // after metadata is fully materialized (i.e. when linking metadata
> -        // as a postpass after function importing).
> -        N->resolveNonTemporaries();
> -      else
> -        N->resolveCycles();
> -    }
> -  }
> +static void resolveCycles(Metadata *MD) {
> +  if (auto *N = dyn_cast_or_null<MDNode>(MD))
> +    if (!N->isResolved())
> +      N->resolveCycles();
>  }
>
>  /// Remap the operands of an MDNode.
> @@ -262,7 +242,7 @@ static bool remapOperands(MDNode &Node,
>        // Resolve uniquing cycles underneath distinct nodes on the fly so they
>        // don't infect later operands.
>        if (IsDistinct)
> -        resolveCycles(New, Flags & RF_HaveUnmaterializedMetadata);
> +        resolveCycles(New);
>      }
>    }
>
> @@ -290,7 +270,7 @@ static Metadata *mapDistinctNode(const M
>
>    // Remap operands later.
>    DistinctWorklist.push_back(NewMD);
> -  return mapToMetadata(VM, Node, NewMD, Materializer, Flags);
> +  return mapToMetadata(VM, Node, NewMD);
>  }
>
>  /// \brief Map a uniqued MDNode.
> @@ -301,29 +281,22 @@ static Metadata *mapUniquedNode(const MD
>                                  ValueToValueMapTy &VM, RemapFlags Flags,
>                                  ValueMapTypeRemapper *TypeMapper,
>                                  ValueMaterializer *Materializer) {
> -  assert(((Flags & RF_HaveUnmaterializedMetadata) || Node->isUniqued()) &&
> -         "Expected uniqued node");
> +  assert(Node->isUniqued() && "Expected uniqued node");
>
>    // Create a temporary node and map it upfront in case we have a uniquing
>    // cycle.  If necessary, this mapping will get updated by RAUW logic before
>    // returning.
>    auto ClonedMD = Node->clone();
> -  mapToMetadata(VM, Node, ClonedMD.get(), Materializer, Flags);
> +  mapToMetadata(VM, Node, ClonedMD.get());
>    if (!remapOperands(*ClonedMD, DistinctWorklist, VM, Flags, TypeMapper,
>                       Materializer)) {
>      // No operands changed, so use the original.
>      ClonedMD->replaceAllUsesWith(const_cast<MDNode *>(Node));
> -    // Even though replaceAllUsesWith would have replaced the value map
> -    // entry, we need to explictly map with the final non-temporary node
> -    // to replace any temporary metadata via the callback.
> -    return mapToSelf(VM, Node, Materializer, Flags);
> +    return const_cast<MDNode *>(Node);
>    }
>
> -  // Uniquify the cloned node. Explicitly map it with the final non-temporary
> -  // node so that replacement of temporary metadata via the callback occurs.
> -  return mapToMetadata(VM, Node,
> -                       MDNode::replaceWithUniqued(std::move(ClonedMD)),
> -                       Materializer, Flags);
> +  // Uniquify the cloned node.
> +  return MDNode::replaceWithUniqued(std::move(ClonedMD));
>  }
>
>  static Metadata *MapMetadataImpl(const Metadata *MD,
> @@ -336,18 +309,18 @@ static Metadata *MapMetadataImpl(const M
>      return NewMD;
>
>    if (isa<MDString>(MD))
> -    return mapToSelf(VM, MD, Materializer, Flags);
> +    return mapToSelf(VM, MD);
>
>    if (isa<ConstantAsMetadata>(MD))
>      if ((Flags & RF_NoModuleLevelChanges))
> -      return mapToSelf(VM, MD, Materializer, Flags);
> +      return mapToSelf(VM, MD);
>
>    if (const auto *VMD = dyn_cast<ValueAsMetadata>(MD)) {
>      Value *MappedV =
>          MapValue(VMD->getValue(), VM, Flags, TypeMapper, Materializer);
>      if (VMD->getValue() == MappedV ||
>          (!MappedV && (Flags & RF_IgnoreMissingEntries)))
> -      return mapToSelf(VM, MD, Materializer, Flags);
> +      return mapToSelf(VM, MD);
>
>      // FIXME: This assert crashes during bootstrap, but I think it should be
>      // correct.  For now, just match behaviour from before the metadata/value
> @@ -356,8 +329,7 @@ static Metadata *MapMetadataImpl(const M
>      //    assert((MappedV || (Flags & RF_NullMapMissingGlobalValues)) &&
>      //           "Referenced metadata not in value map!");
>      if (MappedV)
> -      return mapToMetadata(VM, MD, ValueAsMetadata::get(MappedV), Materializer,
> -                           Flags);
> +      return mapToMetadata(VM, MD, ValueAsMetadata::get(MappedV));
>      return nullptr;
>    }
>
> @@ -368,25 +340,10 @@ static Metadata *MapMetadataImpl(const M
>    // If this is a module-level metadata and we know that nothing at the
>    // module level is changing, then use an identity mapping.
>    if (Flags & RF_NoModuleLevelChanges)
> -    return mapToSelf(VM, MD, Materializer, Flags);
> +    return mapToSelf(VM, MD);
>
>    // Require resolved nodes whenever metadata might be remapped.
> -  assert(((Flags & RF_HaveUnmaterializedMetadata) || Node->isResolved()) &&
> -         "Unexpected unresolved node");
> -
> -  if (Materializer && Node->isTemporary()) {
> -    assert(Flags & RF_HaveUnmaterializedMetadata);
> -    Metadata *TempMD =
> -        Materializer->mapTemporaryMetadata(const_cast<Metadata *>(MD));
> -    // If the above callback returned an existing temporary node, use it
> -    // instead of the current temporary node. This happens when earlier
> -    // function importing passes already created and saved a temporary
> -    // metadata node for the same value id.
> -    if (TempMD) {
> -      mapToMetadata(VM, MD, TempMD, Materializer, Flags);
> -      return TempMD;
> -    }
> -  }
> +  assert(Node->isResolved() && "Unexpected unresolved node");
>
>    if (Node->isDistinct())
>      return mapDistinctNode(Node, DistinctWorklist, VM, Flags, TypeMapper,
> @@ -410,7 +367,7 @@ Metadata *llvm::MapMetadata(const Metada
>      return NewMD;
>
>    // Resolve cycles involving the entry metadata.
> -  resolveCycles(NewMD, Flags & RF_HaveUnmaterializedMetadata);
> +  resolveCycles(NewMD);
>
>    // Remap the operands of distinct MDNodes.
>    while (!DistinctWorklist.empty())
>
> Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=264763&r1=264762&r2=264763&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
> +++ llvm/trunk/unittests/IR/MetadataTest.cpp Tue Mar 29 13:24:19 2016
> @@ -494,20 +494,6 @@ TEST_F(MDNodeTest, isTemporary) {
>    EXPECT_TRUE(T->isTemporary());
>  }
>
> -#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
> -
> -TEST_F(MDNodeTest, deathOnNoReplaceTemporaryRAUW) {
> -  auto Temp = MDNode::getTemporary(Context, None);
> -  Temp->setCanReplace(false);
> -  EXPECT_DEATH(Temp->replaceAllUsesWith(nullptr),
> -               "Attempted to replace Metadata marked for no replacement");
> -  Temp->setCanReplace(true);
> -  // Remove the references to Temp; required for teardown.
> -  Temp->replaceAllUsesWith(nullptr);
> -}
> -
> -#endif
> -
>  TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) {
>    // temporary !{}
>    auto Temp = MDTuple::getTemporary(Context, None);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list