Linker: Share a single Metadata map for the lifetime of IRMover
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 17 Apr 2016 23:30:31 +0000 (23:30 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 17 Apr 2016 23:30:31 +0000 (23:30 +0000)
Cache the result of mapping metadata nodes between instances of IRLinker
(i.e., for the lifetime of IRMover).  There shouldn't be any real
functional change here, but this should give a major speedup.  I had
loaned this to Mehdi when he tested performance of r266446, and the two
patches together gave a 10x speedup in metadata mapping.

llvm-svn: 266579

llvm/include/llvm/Linker/IRMover.h
llvm/lib/Linker/IRMover.cpp

index 63e86f0..a1a2d50 100644 (file)
 
 namespace llvm {
 class GlobalValue;
+class Metadata;
 class Module;
 class StructType;
+class TrackingMDRef;
 class Type;
 
 class IRMover {
@@ -38,6 +40,9 @@ class IRMover {
     static bool isEqual(const StructType *LHS, const StructType *RHS);
   };
 
+  /// Type of the Metadata map in \a ValueToValueMapTy.
+  typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
+
 public:
   class IdentifiedStructTypeSet {
     // The set of opaque types is the composite module.
@@ -74,6 +79,7 @@ public:
 private:
   Module &Composite;
   IdentifiedStructTypeSet IdentifiedStructTypes;
+  MDMapT SharedMDs; ///< A Metadata map to use for all calls to \a move().
 };
 
 } // End llvm namespace
index 02fe58d..5b52ea8 100644 (file)
@@ -362,6 +362,9 @@ public:
   void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
 };
 
+/// Type of the Metadata map in \a ValueToValueMapTy.
+typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
+
 /// This is responsible for keeping track of the state used for moving data
 /// from SrcM to DstM.
 class IRLinker {
@@ -375,6 +378,9 @@ class IRLinker {
   GlobalValueMaterializer GValMaterializer;
   LocalValueMaterializer LValMaterializer;
 
+  /// A metadata map that's shared between IRLinker instances.
+  MDMapT &SharedMDs;
+
   /// Mapping of values from what they used to be in Src, to what they are now
   /// in DstM.  ValueToValueMapTy is a ValueMap, which involves some overhead
   /// due to the use of Value handles which the Linker doesn't actually need,
@@ -467,18 +473,21 @@ class IRLinker {
   void linkNamedMDNodes();
 
 public:
-  IRLinker(Module &DstM, IRMover::IdentifiedStructTypeSet &Set,
-           std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink,
+  IRLinker(Module &DstM, MDMapT &SharedMDs,
+           IRMover::IdentifiedStructTypeSet &Set, std::unique_ptr<Module> SrcM,
+           ArrayRef<GlobalValue *> ValuesToLink,
            std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor)
       : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(AddLazyFor), TypeMap(Set),
-        GValMaterializer(*this), LValMaterializer(*this),
+        GValMaterializer(*this), LValMaterializer(*this), SharedMDs(SharedMDs),
         Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
                &GValMaterializer),
         AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
                                                          &LValMaterializer)) {
+    ValueMap.MD().swap(SharedMDs);
     for (GlobalValue *GV : ValuesToLink)
       maybeAdd(GV);
   }
+  ~IRLinker() { ValueMap.MD().swap(SharedMDs); }
 
   bool run();
   Value *materializeDeclFor(Value *V, bool ForAlias);
@@ -1350,8 +1359,8 @@ IRMover::IRMover(Module &M) : Composite(M) {
 bool IRMover::move(
     std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
     std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor) {
-  IRLinker TheIRLinker(Composite, IdentifiedStructTypes, std::move(Src),
-                       ValuesToLink, AddLazyFor);
+  IRLinker TheIRLinker(Composite, SharedMDs, IdentifiedStructTypes,
+                       std::move(Src), ValuesToLink, AddLazyFor);
   bool RetCode = TheIRLinker.run();
   Composite.dropTriviallyDeadConstantArrays();
   return RetCode;