[PATCH] D46417: wasm: Add a flag to control merging data segments

Nick Fitzgerald via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 3 19:12:25 PDT 2018


fitzgen created this revision.
fitzgen added a reviewer: sbc100.
Herald added subscribers: llvm-commits, sunfish, JDevlieghere, aheejin, jfb.

  Merging data segments produces smaller code sizes because each segment has some
  boilerplate. Therefore, merging data segments is generally the right approach,
  especially with wasm where binaries are typically delivered over the network.
  
  However, when analyzing wasm binaries, it can be helpful to get a conservative
  picture of which functions are using which data segments[0]. Perhaps there is a
  large data segment that you didn't expect to be included in the wasm, introduced
  by some library you're using, and you'd like to know which library it was. In
  this scenario, merging data segments only makes the analysis worse.
  
  Alternatively, perhaps you will remove some dead functions by-hand[1] that can't
  be statically proven dead by the compiler or lld, and removing these functions
  might make some data garbage collect-able, and you'd like to run `--gc-sections`
  again so that this now-unused data can be collected. If the segments were
  originally merged, then a single use of the merged data segment will entrench
  all of the data.
  
  [0] https://github.com/rustwasm/twiggy
  [1] https://github.com/fitzgen/wasm-snip


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D46417

Files:
  wasm/Config.h
  wasm/Driver.cpp
  wasm/Options.td
  wasm/Writer.cpp


Index: wasm/Writer.cpp
===================================================================
--- wasm/Writer.cpp
+++ wasm/Writer.cpp
@@ -870,19 +870,33 @@
 }
 
 void Writer::createOutputSegments() {
-  for (ObjFile *File : Symtab->ObjectFiles) {
-    for (InputSegment *Segment : File->Segments) {
-      if (!Segment->Live)
-        continue;
-      StringRef Name = getOutputDataSegmentName(Segment->getName());
-      OutputSegment *&S = SegmentMap[Name];
-      if (S == nullptr) {
-        DEBUG(dbgs() << "new segment: " << Name << "\n");
-        S = make<OutputSegment>(Name, Segments.size());
+  if (!Config->MergeDataSegments) {
+    for (ObjFile *File : Symtab->ObjectFiles) {
+      for (InputSegment *Segment : File->Segments) {
+        if (!Segment->Live)
+          continue;
+        StringRef Name = getOutputDataSegmentName(Segment->getName());
+        OutputSegment *S = make<OutputSegment>(Name, Segments.size());
         Segments.push_back(S);
+        S->addInputSegment(Segment);
+        DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
+      }
+    }
+  } else {
+    for (ObjFile *File : Symtab->ObjectFiles) {
+      for (InputSegment *Segment : File->Segments) {
+        if (!Segment->Live)
+          continue;
+        StringRef Name = getOutputDataSegmentName(Segment->getName());
+        OutputSegment *&S = SegmentMap[Name];
+        if (S == nullptr) {
+          DEBUG(dbgs() << "new segment: " << Name << "\n");
+          S = make<OutputSegment>(Name, Segments.size());
+          Segments.push_back(S);
+        }
+        S->addInputSegment(Segment);
+        DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
       }
-      S->addInputSegment(Segment);
-      DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
     }
   }
 }
Index: wasm/Options.td
===================================================================
--- wasm/Options.td
+++ wasm/Options.td
@@ -40,6 +40,10 @@
     "Enable garbage collection of unused sections",
     "Disable garbage collection of unused sections">;
 
+defm merge_data_segments: B<"merge-data-segments",
+    "Enable merging data segments",
+    "Disable merging data segments">;
+
 def help: F<"help">, HelpText<"Print option help">;
 
 def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
Index: wasm/Driver.cpp
===================================================================
--- wasm/Driver.cpp
+++ wasm/Driver.cpp
@@ -293,6 +293,9 @@
   Config->Relocatable = Args.hasArg(OPT_relocatable);
   Config->GcSections =
       Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
+  Config->MergeDataSegments =
+      Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
+                   !Config->Relocatable);
   Config->PrintGcSections =
       Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
   Config->SearchPaths = args::getStrings(Args, OPT_L);
Index: wasm/Config.h
===================================================================
--- wasm/Config.h
+++ wasm/Config.h
@@ -25,6 +25,7 @@
   bool GcSections;
   bool ImportMemory;
   bool ImportTable;
+  bool MergeDataSegments;
   bool PrintGcSections;
   bool Relocatable;
   bool StripAll;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46417.145136.patch
Type: text/x-patch
Size: 3250 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180504/11dbb52f/attachment.bin>


More information about the llvm-commits mailing list