Skip to content
  1. Feb 28, 2017
  2. Feb 27, 2017
    • Rui Ueyama's avatar
      Move SymbolTable<ELFT>::Sections out of the class. · 536a2670
      Rui Ueyama authored
      The list of all input sections was defined in SymbolTable class for a
      historical reason. The list itself is not a template. However, because
      SymbolTable class is a template, we needed to pass around ELFT to access
      the list. This patch moves the list out of the class so that it doesn't
      need ELFT.
      
      llvm-svn: 296309
      536a2670
  3. Feb 23, 2017
    • Rafael Espindola's avatar
      Make InputSection a class. NFC. · 774ea7d0
      Rafael Espindola authored
      With the current design an InputSection is basically anything that
      goes directly in a OutputSection. That includes plain input section
      but also synthetic sections, so this should probably not be a
      template.
      
      llvm-svn: 295993
      774ea7d0
    • Rafael Espindola's avatar
      Convert InputSectionBase to a class. · b4c9b81a
      Rafael Espindola authored
      Removing this template is not a big win by itself, but opens the way
      for removing more templates.
      
      llvm-svn: 295923
      b4c9b81a
  4. Jan 20, 2017
  5. Jan 15, 2017
  6. Dec 05, 2016
  7. Dec 04, 2016
  8. Dec 03, 2016
  9. Dec 02, 2016
    • Rui Ueyama's avatar
      Remove a wrong performance optimization. · 5419861a
      Rui Ueyama authored
      This is a hack for single thread execution. We are using Color[0] and
      Color[1] alternately on each iteration. This optimization is to look
      at the next slot as opposted to the current slot to get recent results
      early. Turns out that the assumption is wrong, because the other slots
      are not always have the most recent values, but instead it may have
      stale values of the previous iteration. This patch removes that
      performance hack.
      
      llvm-svn: 288527
      5419861a
    • Rui Ueyama's avatar
      Removed a wrong assertion about non-colorable sections. · 83ec681a
      Rui Ueyama authored
      The assertion asserted that colorable sections can never have
      a reference to non-colorable sections, but that was simply wrong.
      They can have references to non-colorable sections. If that's the
      case, referenced sections must be the same in terms of pointer
      comparison.
      
      llvm-svn: 288511
      83ec681a
    • Rui Ueyama's avatar
      Fix the worse case performance of ICF. · 1b6bab01
      Rui Ueyama authored
      r288228 seems to have regressed ICF performance in some cases in which
      a lot of sections are actually mergeable. In r288228, I made a change
      to create a Range object for each new color group. So every time we
      split a group, we allocated and added a new group to a list of groups.
      
      This patch essentially reverted r288228 with an improvement to
      parallelize the original algorithm.
      
      Now the ICF main loop is entirely allocation-free and lock-free.
      
      Just like pre-r288228, we search for group boundaries by linear scan
      instead of managing the information using Range class. r288228 was
      neutral in performance-wise, and so is this patch.
      
      I confirmed that this produces the exact same result as before
      using chromium and clang as tests.
      
      llvm-svn: 288480
      1b6bab01
    • Rui Ueyama's avatar
      Fix undefined behavior. · 395859bd
      Rui Ueyama authored
      New items can be added to Ranges here, and that invalidates
      an iterater that previously pointed the end of the vector.
      
      llvm-svn: 288443
      395859bd
  10. Dec 01, 2016
    • Rui Ueyama's avatar
      Add an assert instead of ignoring an impossible condition. · a6cd5fe4
      Rui Ueyama authored
      llvm-svn: 288419
      a6cd5fe4
    • Rui Ueyama's avatar
      Updates file comments and variable names. · 91ae861a
      Rui Ueyama authored
      Use "color" instead of "group id" to describe the ICF algorithm.
      
      llvm-svn: 288409
      91ae861a
    • Rui Ueyama's avatar
      Parallelize ICF to make LLD's ICF really fast. · c1835319
      Rui Ueyama authored
      ICF is short for Identical Code Folding. It is a size optimization to
      identify two or more functions that happened to have the same contents
      to merges them. It usually reduces output size by a few percent.
      
      ICF is slow because it is computationally intensive process. I tried
      to paralellize it before but failed because I couldn't make a
      parallelized version produce consistent outputs. Although it didn't
      create broken executables, every invocation of the linker generated
      slightly different output, and I couldn't figure out why.
      
      I think I now understand what was going on, and also came up with a
      simple algorithm to fix it. So is this patch.
      
      The result is very exciting. Chromium for example has 780,662 input
      sections in which 20,774 are reducible by ICF. LLD previously took
      7.980 seconds for ICF. Now it finishes in 1.065 seconds.
      
      As a result, LLD can now link a Chromium binary (output size 1.59 GB)
      in 10.28 seconds on my machine with ICF enabled. Compared to gold
      which takes 40.94 seconds to do the same thing, this is an amazing
      number.
      
      From here, I'll describe what we are doing for ICF, what was the
      previous problem, and what I did in this patch.
      
      In ICF, two sections are considered identical if they have the same
      section flags, section data, and relocations. Relocations are tricky,
      becuase two relocations are considered the same if they have the same
      relocation type, values, and if they point to the same section _in
      terms of ICF_.
      
      Here is an example. If foo and bar defined below are compiled to the
      same machine instructions, ICF can (and should) merge the two,
      although their relocations point to each other.
      
        void foo() { bar(); }
        void bar() { foo(); }
      
      This is not an easy problem to solve.
      
      What we are doing in LLD is some sort of coloring algorithm. We color
      non-identical sections using different colors repeatedly, and sections
      in the same color when the algorithm terminates are considered
      identical. Here is the details:
      
        1. First, we color all sections using their hash values of section
        types, section contents, and numbers of relocations. At this moment,
        relocation targets are not taken into account. We just color
        sections that apparently differ in different colors.
      
        2. Next, for each color C, we visit sections having color C to see
        if their relocations are the same. Relocations are considered equal
        if their targets have the same color. We then recolor sections that
        have different relocation targets in new colors.
      
        3. If we recolor some section in step 2, relocations that were
        previously pointing to the same color targets may now be pointing to
        different colors. Therefore, repeat 2 until a convergence is
        obtained.
      
      Step 2 is a heavy operation. For Chromium, the first iteration of step
      2 takes 2.882 seconds, and the second iteration takes 1.038 seconds,
      and in total it needs 23 iterations.
      
      Parallelizing step 1 is easy because we can color each section
      independently. This patch does that.
      
      Parallelizing step 2 is tricky. We could work on each color
      independently, but we cannot recolor sections in place, because it
      will break the invariance that two possibly-identical sections must
      have the same color at any moment.
      
      Consider sections S1, S2, S3, S4 in the same color C, where S1 and S2
      are identical, S3 and S4 are identical, but S2 and S3 are not. Thread
      A is about to recolor S1 and S2 in C'. After thread A recolor S1 in
      C', but before recolor S2 in C', other thread B might observe S1 and
      S2. Then thread B will conclude that S1 and S2 are different, and it
      will split thread B's sections into smaller groups wrongly. Over-
      splitting doesn't produce broken results, but it loses a chance to
      merge some identical sections. That was the cause of indeterminism.
      
      To fix the problem, I made sections have two colors, namely current
      color and next color. At the beginning of each iteration, both colors
      are the same. Each thread reads from current color and writes to next
      color. In this way, we can avoid threads from reading partial
      results. After each iteration, we flip current and next.
      
      This is a very simple solution and is implemented in less than 50
      lines of code.
      
      I tested this patch with Chromium and confirmed that this parallelized
      ICF produces the identical output as the non-parallelized one.
      
      Differential Revision: https://reviews.llvm.org/D27247
      
      llvm-svn: 288373
      c1835319
  11. Nov 30, 2016
    • Rui Ueyama's avatar
      Change how we manage groups in ICF. · 9dedfb1f
      Rui Ueyama authored
      Previously, on each iteration in ICF, we scan the entire vector of
      input sections to find boundaries of groups having the same ID.
      
      This patch changes the algorithm so that we now have a vector of ranges.
      Each range contains a starting index and an ending index of the group.
      So we no longer have to search boundaries on each iteration.
      
      Performance-wise, this seems neutral. Instead of searching boundaries,
      we now have to maintain ranges. But I think this is more readable
      than the previous implementation.
      
      Moreover, this makes easy to parallelize the main loop of ICF,
      which I'll do in a follow-up patch.
      
      llvm-svn: 288228
      9dedfb1f
  12. Nov 21, 2016
  13. Nov 20, 2016
    • Rui Ueyama's avatar
      Use auto for obvious types. · 9f8cb730
      Rui Ueyama authored
      llvm-svn: 287481
      9f8cb730
    • Rui Ueyama's avatar
      Do not expose ICF class from the file. · bd1f0630
      Rui Ueyama authored
      Also this patch uses file-scope functions instead of class member function.
      
      Now that ICF class is not visible from outside, InputSection class
      can no longer be "friend" of it. So I removed the friend relation
      and just make it expose the features to public.
      
      llvm-svn: 287480
      bd1f0630
    • Rui Ueyama's avatar
      Refactor ICF. · e2dfbc17
      Rui Ueyama authored
      In order to use forEachGroup in the final loop in ICF::run,
      I changed some function parameter types.
      
      llvm-svn: 287466
      e2dfbc17
  14. Nov 19, 2016
  15. Nov 10, 2016
    • Rafael Espindola's avatar
      Parse relocations only once. · 9f0c4bb7
      Rafael Espindola authored
      Relocations are the last thing that we wore storing a raw section
      pointer to and parsing on demand.
      
      With this patch we parse it only once and store a pointer to the
      actual data.
      
      The patch also changes where we store it. It is now in
      InputSectionBase. Not all sections have relocations, but most do and
      this simplifies the logic. It also means that we now only support one
      relocation section per section. Given that that constraint is
      maintained even with -r with gold bfd and lld, I think it is OK.
      
      llvm-svn: 286459
      9f0c4bb7
  16. Nov 09, 2016
  17. Nov 08, 2016
  18. Nov 05, 2016
    • Rui Ueyama's avatar
      Create a vector containing all input sections. · 8c6a5aaf
      Rui Ueyama authored
      Previously, we do this piece of code to iterate over all input sections.
      
        for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles())
          for (InputSectionBase<ELFT> *S : F->getSections())
      
      It turned out that this mechanisms doesn't work well with synthetic
      input sections because synthetic input sections don't belong to any
      input file.
      
      This patch defines a vector that contains all input sections including
      synthetic ones.
      
      llvm-svn: 286051
      8c6a5aaf
  19. Nov 03, 2016
  20. Oct 26, 2016
  21. Oct 25, 2016
    • Rafael Espindola's avatar
      Delete getSectionHdr. · 58139d17
      Rafael Espindola authored
      We were fairly inconsistent as to what information should be accessed
      with getSectionHdr and what information (like alignment) was stored
      elsewhere.
      
      Now all section info has a dedicated getter. The code is also a bit
      more compact.
      
      llvm-svn: 285079
      58139d17
  22. Sep 14, 2016
    • Rui Ueyama's avatar
      Simplify InputFile ownership management. · 38dbd3ee
      Rui Ueyama authored
      Previously, all input files were owned by the symbol table.
      Files were created at various places, such as the Driver, the lazy
      symbols, or the bitcode compiler, and the ownership of new files
      was transferred to the symbol table using std::unique_ptr.
      All input files were then free'd when the symbol table is freed
      which is on program exit.
      
      I think we don't have to transfer ownership just to free all
      instance at once on exit.
      
      In this patch, all instances are automatically collected to a
      vector and freed on exit. In this way, we no longer have to
      use std::unique_ptr.
      
      Differential Revision: https://reviews.llvm.org/D24493
      
      llvm-svn: 281425
      38dbd3ee
  23. Sep 12, 2016
  24. Sep 08, 2016
    • Rafael Espindola's avatar
      Compute section names only once. · 042a3f20
      Rafael Espindola authored
      This simplifies error handling as there is now only one place in the
      code that needs to consider the possibility that the name is
      corrupted. Before we would do it in every access.
      
      llvm-svn: 280937
      042a3f20
  25. Aug 22, 2016
  26. May 02, 2016
  27. Apr 27, 2016
  28. Apr 26, 2016
  29. Apr 05, 2016
Loading