Skip to content
  1. Apr 28, 2017
  2. Mar 30, 2017
    • Ahmed Bougacha's avatar
      [CodeGen] Pass SDAG an ORE, and replace FastISel stats with remarks. · 6dd60824
      Ahmed Bougacha authored
      In the long-term, we want to replace statistics with something
      finer-grained that lets us gather per-function data.
      Remarks are that replacement.
      
      Create an ORE instance in SelectionDAGISel, and pass it to
      SelectionDAG.
      
      SelectionDAG was used so that we can emit remarks from all
      SelectionDAG-related code, including TargetLowering and DAGCombiner.
      This isn't used in the current patch but Adam tells me he's interested
      for the fp-contract combines.
      
      Use the ORE instance to emit FastISel failures as remarks (instead of
      the mix of dbgs() dumps and statistics that we currently have).
      
      Eventually, we want to have an API that tells us whether remarks are
      enabled (http://llvm.org/PR32352) so that we don't emit expensive
      remarks (in this case, dumping IR) when it's not needed.  For now, use
      'isEnabled' as a crude replacement.
      
      This does mean that the replacement for '-fast-isel-verbose' is now
      '-pass-remarks-missed=isel'.  Additionally, clang users also need to
      enable remark diagnostics, using '-Rpass-missed=isel'.
      
      This also removes '-fast-isel-verbose2': there are no static statistics
      that we want to only enable in asserts builds, so we can always use
      the remarks regardless of the build type.
      
      Differential Revision: https://reviews.llvm.org/D31405
      
      llvm-svn: 299093
      6dd60824
  3. Mar 14, 2017
    • Nirav Dave's avatar
      Recommitting Craig Topper's patch now that r296476 has been recommitted. · 4fc8401a
      Nirav Dave authored
      When checking if chain node is foldable, make sure the intermediate nodes have a single use across all results not just the result that was used to reach the chain node.
      
      This recovers a test case that was severely broken by r296476, my making sure we don't create ADD/ADC that loads and stores when there is also a flag dependency.
      
      llvm-svn: 297698
      4fc8401a
  4. Mar 03, 2017
    • Chandler Carruth's avatar
      [SDAG] Revert r296476 (and r296486, r296668, r296690). · ce52b807
      Chandler Carruth authored
      This patch causes compile times for some patterns to explode. I have
      a (large, unreduced) test case that slows down by more than 20x and
      several test cases slow down by 2x. I'm sending some of the test cases
      directly to Nirav and following up with more details in the review log,
      but this should unblock anyone else hitting this.
      
      llvm-svn: 296862
      ce52b807
  5. Mar 01, 2017
    • Reid Kleckner's avatar
      Elide argument copies during instruction selection · f7c0980c
      Reid Kleckner authored
      Summary:
      Avoids tons of prologue boilerplate when arguments are passed in memory
      and left in memory. This can happen in a debug build or in a release
      build when an argument alloca is escaped.  This will dramatically affect
      the code size of x86 debug builds, because X86 fast isel doesn't handle
      arguments passed in memory at all. It only handles the x86_64 case of up
      to 6 basic register parameters.
      
      This is implemented by analyzing the entry block before ISel to identify
      copy elision candidates. A copy elision candidate is an argument that is
      used to fully initialize an alloca before any other possibly escaping
      uses of that alloca. If an argument is a copy elision candidate, we set
      a flag on the InputArg. If the the target generates loads from a fixed
      stack object that matches the size and alignment requirements of the
      alloca, the SelectionDAG builder will delete the stack object created
      for the alloca and replace it with the fixed stack object. The load is
      left behind to satisfy any remaining uses of the argument value. The
      store is now dead and is therefore elided. The fixed stack object is
      also marked as mutable, as it may now be modified by the user, and it
      would be invalid to rematerialize the initial load from it.
      
      Supersedes D28388
      
      Fixes PR26328
      
      Reviewers: chandlerc, MatzeB, qcolombet, inglorion, hans
      
      Subscribers: igorb, llvm-commits
      
      Differential Revision: https://reviews.llvm.org/D29668
      
      llvm-svn: 296683
      f7c0980c
    • Ahmed Bougacha's avatar
      [CodeGen] Remove dead FastISel code after SDAG emitted a tailcall. · 20b3e9a8
      Ahmed Bougacha authored
      When SDAGISel (top-down) selects a tail-call, it skips the remainder
      of the block.
      
      If, before that, FastISel (bottom-up) selected some of the (no-op) next
      few instructions, we can end up with dead instructions following the
      terminator (selected by SDAGISel).
      
      We need to erase them, as we know they aren't necessary (in addition to
      being incorrect).
      
      We already do this when FastISel falls back on the tail-call itself.
      Also remove the FastISel-emitted code if we fallback on the
      instructions between the tail-call and the return.
      
      llvm-svn: 296552
      20b3e9a8
  6. Feb 28, 2017
    • Craig Topper's avatar
      [DAGISel] When checking if chain node is foldable, make sure the intermediate... · 419f145e
      Craig Topper authored
      [DAGISel] When checking if chain node is foldable, make sure the intermediate nodes have a single use across all results not just the result that was used to reach the chain node.
      
      This recovers a test case that was severely broken by r296476, my making sure we don't create ADD/ADC that loads and stores when there is also a flag dependency.
      
      llvm-svn: 296486
      419f145e
  7. Feb 27, 2017
  8. Feb 14, 2017
    • Aditya Nandakumar's avatar
      [Tablegen] Instrumenting table gen DAGGenISelDAG · bb0483bc
      Aditya Nandakumar authored
      To help assist in debugging ISEL or to prioritize GlobalISel backend
      work, this patch adds two more tables to <Target>GenISelDAGISel.inc -
      one which contains the patterns that are used during selection and the
      other containing include source location of the patterns
      Enabled through CMake varialbe LLVM_ENABLE_DAGISEL_COV
      
      llvm-svn: 295081
      bb0483bc
  9. Feb 13, 2017
    • Quentin Colombet's avatar
      [FastISel] Add a diagnostic to warm on fallback. · fbae5fcb
      Quentin Colombet authored
      This is consistent with what we do for GlobalISel. That way, it is easy
      to see whether or not FastISel is able to fully select a function.
      At some point we may want to switch that to an optimization remark.
      
      llvm-svn: 294970
      fbae5fcb
  10. Feb 10, 2017
    • Simon Pilgrim's avatar
      [DAGCombine] Allow vector constant folding of any value type before type legalization · bfb17478
      Simon Pilgrim authored
      The patch comes in 2 parts:
      
      1 - it makes use of the SelectionDAG::NewNodesMustHaveLegalTypes flag to tell when it can safely constant fold illegal types.
      
      2 - it correctly resets SelectionDAG::NewNodesMustHaveLegalTypes at the start of each call to SelectionDAGISel::CodeGenAndEmitDAG so all the pre-legalization stages can make use of it - not just the first basic block that gets handled.
      
      Fix for PR30760
      
      Differential Revision: https://reviews.llvm.org/D29568
      
      llvm-svn: 294749
      bfb17478
    • Craig Topper's avatar
      [SelectionDAG] Dump the DAG after legalizing vector ops and after the second type legalization · a9f11218
      Craig Topper authored
      Summary:
      With -debug, we aren't dumping the DAG after legalizing vector ops. In particular, on X86 with AVX1 only, we don't dump the DAG after we split 256-bit integer ops into pairs of 128-bit ADDs since this occurs during vector legalization.
      
      I'm only dumping if the legalize vector ops changes something since we don't print anything during legalize vector ops. So this dump shows up right after the first type-legalization dump happens. So if nothing changed this second dump is unnecessary.
      
      Having said that though, I think we should probably fix legalize vector ops to log what its doing.
      
      Reviewers: RKSimon, eli.friedman, spatel, arsenm, chandlerc
      
      Reviewed By: RKSimon
      
      Subscribers: wdng, llvm-commits
      
      Differential Revision: https://reviews.llvm.org/D29554
      
      llvm-svn: 294711
      a9f11218
  11. Feb 07, 2017
    • Reid Kleckner's avatar
      [SDAGISel] Simplify some SDAGISel code, NFC · 0887d44a
      Reid Kleckner authored
      Hoist entry block code for arguments and swift error values out of the
      basic block instruction selection loop. Lowering arguments once up front
      seems much more readable than doing it conditionally inside the loop. It
      also makes it clear that argument lowering can update StaticAllocaMap
      because no instructions have been selected yet.
      
      Also use range-based for loops where possible.
      
      llvm-svn: 294329
      0887d44a
  12. Feb 04, 2017
  13. Feb 03, 2017
  14. Jan 30, 2017
  15. Jan 28, 2017
    • Matthias Braun's avatar
      Cleanup dump() functions. · 8c209aa8
      Matthias Braun authored
      We had various variants of defining dump() functions in LLVM. Normalize
      them (this should just consistently implement the things discussed in
      http://lists.llvm.org/pipermail/cfe-dev/2014-January/034323.html
      
      For reference:
      - Public headers should just declare the dump() method but not use
        LLVM_DUMP_METHOD or #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
      - The definition of a dump method should look like this:
        #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
        LLVM_DUMP_METHOD void MyClass::dump() {
          // print stuff to dbgs()...
        }
        #endif
      
      llvm-svn: 293359
      8c209aa8
  16. Jan 27, 2017
    • Andrew Kaylor's avatar
      Add intrinsics for constrained floating point operations · a0a1164c
      Andrew Kaylor authored
      This commit introduces a set of experimental intrinsics intended to prevent
      optimizations that make assumptions about the rounding mode and floating point
      exception behavior.  These intrinsics will later be extended to specify
      flush-to-zero behavior.  More work is also required to model instruction
      dependencies in machine code and to generate these instructions from clang
      (when required by pragmas and/or command line options that are not currently
      supported).
      
      Differential Revision: https://reviews.llvm.org/D27028
      
      llvm-svn: 293226
      a0a1164c
  17. Dec 01, 2016
    • Matthias Braun's avatar
      Move most EH from MachineModuleInfo to MachineFunction · d0ee66c2
      Matthias Braun authored
      Recommitting r288293 with some extra fixes for GlobalISel code.
      
      Most of the exception handling members in MachineModuleInfo is actually
      per function data (talks about the "current function") so it is better
      to keep it at the function instead of the module.
      
      This is a necessary step to have machine module passes work properly.
      
      Also:
      - Rename TidyLandingPads() to tidyLandingPads()
      - Use doxygen member groups instead of "//===- EH ---"... so it is clear
        where a group ends.
      - I had to add an ugly const_cast at two places in the AsmPrinter
        because the available MachineFunction pointers are const, but the code
        wants to call tidyLandingPads() in between
        (markFunctionEnd()/endFunction()).
      
      Differential Revision: https://reviews.llvm.org/D27227
      
      llvm-svn: 288405
      d0ee66c2
    • Eric Christopher's avatar
      Temporarily Revert "Move most EH from MachineModuleInfo to MachineFunction" · e70b7c3d
      Eric Christopher authored
      This apprears to have broken the global isel bot:
      http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-globalisel_build/5174/console
      
      This reverts commit r288293.
      
      llvm-svn: 288322
      e70b7c3d
    • Matthias Braun's avatar
      Move most EH from MachineModuleInfo to MachineFunction · ed14cb06
      Matthias Braun authored
      Most of the exception handling members in MachineModuleInfo is actually
      per function data (talks about the "current function") so it is better
      to keep it at the function instead of the module.
      
      This is a necessary step to have machine module passes work properly.
      
      Also:
      - Rename TidyLandingPads() to tidyLandingPads()
      - Use doxygen member groups instead of "//===- EH ---"... so it is clear
        where a group ends.
      - I had to add an ugly const_cast at two places in the AsmPrinter
        because the available MachineFunction pointers are const, but the code
        wants to call tidyLandingPads() in between
        (markFunctionEnd()/endFunction()).
      
      Differential Revision: https://reviews.llvm.org/D27227
      
      llvm-svn: 288293
      ed14cb06
  18. Nov 18, 2016
    • Matthias Braun's avatar
      Timer: Track name and description. · 9f15a79e
      Matthias Braun authored
      The previously used "names" are rather descriptions (they use multiple
      words and contain spaces), use short programming language identifier
      like strings for the "names" which should be used when exporting to
      machine parseable formats.
      
      Also removed a unused TimerGroup from Hexxagon.
      
      Differential Revision: https://reviews.llvm.org/D25583
      
      llvm-svn: 287369
      9f15a79e
  19. Oct 11, 2016
  20. Oct 08, 2016
    • Arnold Schwaighofer's avatar
      swifterror: Don't compute swifterror vregs during instruction selection · 3f256581
      Arnold Schwaighofer authored
      The code used llvm basic block predecessors to decided where to insert phi
      nodes. Instruction selection can and will liberally insert new machine basic
      block predecessors. There is not a guaranteed one-to-one mapping from pred.
      llvm basic blocks and machine basic blocks.
      
      Therefore the current approach does not work as it assumes we can mark
      predecessor machine basic block as needing a copy, and needs to know the set of
      all predecessor machine basic blocks to decide when to insert phis.
      
      Instead of computing the swifterror vregs as we select instructions, propagate
      them at the end of instruction selection when the MBB CFG is complete.
      
      When an instruction needs a swifterror vreg and we don't know the value yet,
      generate a new vreg and remember this "upward exposed" use, and reconcile this
      at the end of instruction selection.
      
      This will only happen if the target supports promoting swifterror parameters to
      registers and the swifterror attribute is used.
      
      rdar://28300923
      
      llvm-svn: 283617
      3f256581
  21. Sep 14, 2016
  22. Sep 09, 2016
  23. Aug 27, 2016
  24. Aug 23, 2016
    • Pete Cooper's avatar
      Fix some more asserts after r279466. · 036b94da
      Pete Cooper authored
      That commit added a new version of Intrinsic::getName which should only
      be called when the intrinsic has no overloaded types.  There are several
      debugging paths, such as SDNode::dump which are printing the name of the
      intrinsic but don't have the overloaded types.  These paths should be ok
      to just print the name instead of crashing.
      
      The fix here is ultimately to just add a 'None' second argument as that
      calls the overload capable getName, which is less efficient, but this is a
      debugging path anyway, and not perf critical.
      
      Thanks to Björn Pettersson for pointing out that there were more crashes.
      
      llvm-svn: 279528
      036b94da
  25. Aug 12, 2016
  26. Jul 28, 2016
  27. Jul 18, 2016
    • Simon Dardis's avatar
      [inlineasm] Propagate operand constraints to the backend · d32a2d30
      Simon Dardis authored
      When SelectionDAGISel transforms a node representing an inline asm
      block, memory constraint information is not preserved. This can cause
      constraints to be broken when a memory offset is of the form:
      
      offset + frame index
      
      when the frame is resolved.
      
      By propagating the constraints all the way to the backend, targets can
      enforce memory operands of inline assembly to conform to their constraints.
      
      For MIPSR6, some instructions had their offsets reduced to 9 bits from
      16 bits such as ll/sc. This becomes problematic when using inline assembly
      to perform atomic operations, as an offset can generated that is too big to
      encode in the instruction.
      
      Reviewers: dsanders, vkalintris
      
      Differential Review: https://reviews.llvm.org/D21615
      
      llvm-svn: 275786
      d32a2d30
  28. Jul 08, 2016
  29. Jul 07, 2016
  30. Jul 01, 2016
    • Duncan P. N. Exon Smith's avatar
      CodeGen: Use MachineInstr& in TargetLowering, NFC · e4f5e4f4
      Duncan P. N. Exon Smith authored
      This is a mechanical change to make TargetLowering API take MachineInstr&
      (instead of MachineInstr*), since the argument is expected to be a valid
      MachineInstr.  In one case, changed a parameter from MachineInstr* to
      MachineBasicBlock::iterator, since it was used as an insertion point.
      
      As a side effect, this removes a bunch of MachineInstr* to
      MachineBasicBlock::iterator implicit conversions, a necessary step
      toward fixing PR26753.
      
      llvm-svn: 274287
      e4f5e4f4
  31. Jun 30, 2016
  32. Jun 12, 2016
    • Benjamin Kramer's avatar
      Pass DebugLoc and SDLoc by const ref. · bdc4956b
      Benjamin Kramer authored
      This used to be free, copying and moving DebugLocs became expensive
      after the metadata rewrite. Passing by reference eliminates a ton of
      track/untrack operations. No functionality change intended.
      
      llvm-svn: 272512
      bdc4956b
  33. Jun 07, 2016
    • Etienne Bergeron's avatar
      [stack-protection] Add support for MSVC buffer security check · 22bfa832
      Etienne Bergeron authored
      Summary:
      This patch is adding support for the MSVC buffer security check implementation
      
      The buffer security check is turned on with the '/GS' compiler switch.
        * https://msdn.microsoft.com/en-us/library/8dbf701c.aspx
        * To be added to clang here: http://reviews.llvm.org/D20347
      
      Some overview of buffer security check feature and implementation:
        * https://msdn.microsoft.com/en-us/library/aa290051(VS.71).aspx
        * http://www.ksyash.com/2011/01/buffer-overflow-protection-3/
        * http://blog.osom.info/2012/02/understanding-vs-c-compilers-buffer.html
      
      
      For the following example:
      ```
      int example(int offset, int index) {
        char buffer[10];
        memset(buffer, 0xCC, index);
        return buffer[index];
      }
      ```
      
      The MSVC compiler is adding these instructions to perform stack integrity check:
      ```
              push        ebp  
              mov         ebp,esp  
              sub         esp,50h  
        [1]   mov         eax,dword ptr [__security_cookie (01068024h)]  
        [2]   xor         eax,ebp  
        [3]   mov         dword ptr [ebp-4],eax  
              push        ebx  
              push        esi  
              push        edi  
              mov         eax,dword ptr [index]  
              push        eax  
              push        0CCh  
              lea         ecx,[buffer]  
              push        ecx  
              call        _memset (010610B9h)  
              add         esp,0Ch  
              mov         eax,dword ptr [index]  
              movsx       eax,byte ptr buffer[eax]  
              pop         edi  
              pop         esi  
              pop         ebx  
        [4]   mov         ecx,dword ptr [ebp-4]  
        [5]   xor         ecx,ebp  
        [6]   call        @__security_check_cookie@4 (01061276h)  
              mov         esp,ebp  
              pop         ebp  
              ret  
      ```
      
      The instrumentation above is:
        * [1] is loading the global security canary,
        * [3] is storing the local computed ([2]) canary to the guard slot,
        * [4] is loading the guard slot and ([5]) re-compute the global canary,
        * [6] is validating the resulting canary with the '__security_check_cookie' and performs error handling.
      
      Overview of the current stack-protection implementation:
        * lib/CodeGen/StackProtector.cpp
          * There is a default stack-protection implementation applied on intermediate representation.
          * The target can overload 'getIRStackGuard' method if it has a standard location for the stack protector cookie.
          * An intrinsic 'Intrinsic::stackprotector' is added to the prologue. It will be expanded by the instruction selection pass (DAG or Fast).
          * Basic Blocks are added to every instrumented function to receive the code for handling stack guard validation and errors handling.
          * Guard manipulation and comparison are added directly to the intermediate representation.
      
        * lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
        * lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
          * There is an implementation that adds instrumentation during instruction selection (for better handling of sibbling calls).
            * see long comment above 'class StackProtectorDescriptor' declaration.
          * The target needs to override 'getSDagStackGuard' to activate SDAG stack protection generation. (note: getIRStackGuard MUST be nullptr).
            * 'getSDagStackGuard' returns the appropriate stack guard (security cookie)
          * The code is generated by 'SelectionDAGBuilder.cpp' and 'SelectionDAGISel.cpp'.
      
        * include/llvm/Target/TargetLowering.h
          * Contains function to retrieve the default Guard 'Value'; should be overriden by each target to select which implementation is used and provide Guard 'Value'.
      
        * lib/Target/X86/X86ISelLowering.cpp
          * Contains the x86 specialisation; Guard 'Value' used by the SelectionDAG algorithm.
      
      Function-based Instrumentation:
        * The MSVC doesn't inline the stack guard comparison in every function. Instead, a call to '__security_check_cookie' is added to the epilogue before every return instructions.
        * To support function-based instrumentation, this patch is
          * adding a function to get the function-based check (llvm 'Value', see include/llvm/Target/TargetLowering.h),
            * If provided, the stack protection instrumentation won't be inlined and a call to that function will be added to the prologue.
          * modifying (SelectionDAGISel.cpp) do avoid producing basic blocks used for inline instrumentation,
          * generating the function-based instrumentation during the ISEL pass (SelectionDAGBuilder.cpp),
          * if FastISEL (not SelectionDAG), using the fallback which rely on the same function-based implemented over intermediate representation (StackProtector.cpp).
      
      Modifications
        * adding support for MSVC (lib/Target/X86/X86ISelLowering.cpp)
        * adding support function-based instrumentation (lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp, .h)
      
      Results
      
        * IR generated instrumentation:
      ```
      clang-cl /GS test.cc /Od /c -mllvm -print-isel-input
      ```
      
      ```
      *** Final LLVM Code input to ISel ***
      
      ; Function Attrs: nounwind sspstrong
      define i32 @"\01?example@@YAHHH@Z"(i32 %offset, i32 %index) #0 {
      entry:
        %StackGuardSlot = alloca i8*                                                  <<<-- Allocated guard slot
        %0 = call i8* @llvm.stackguard()                                              <<<-- Loading Stack Guard value
        call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot)                  <<<-- Prologue intrinsic call (store to Guard slot)
        %index.addr = alloca i32, align 4
        %offset.addr = alloca i32, align 4
        %buffer = alloca [10 x i8], align 1
        store i32 %index, i32* %index.addr, align 4
        store i32 %offset, i32* %offset.addr, align 4
        %arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %buffer, i32 0, i32 0
        %1 = load i32, i32* %index.addr, align 4
        call void @llvm.memset.p0i8.i32(i8* %arraydecay, i8 -52, i32 %1, i32 1, i1 false)
        %2 = load i32, i32* %index.addr, align 4
        %arrayidx = getelementptr inbounds [10 x i8], [10 x i8]* %buffer, i32 0, i32 %2
        %3 = load i8, i8* %arrayidx, align 1
        %conv = sext i8 %3 to i32
        %4 = load volatile i8*, i8** %StackGuardSlot                                  <<<-- Loading Guard slot
        call void @__security_check_cookie(i8* %4)                                    <<<-- Epilogue function-based check
        ret i32 %conv
      }
      ```
      
        * SelectionDAG generated instrumentation:
      
      ```
      clang-cl /GS test.cc /O1 /c /FA
      ```
      
      ```
      "?example@@YAHHH@Z":                    # @"\01?example@@YAHHH@Z"
      # BB#0:                                 # %entry
              pushl   %esi
              subl    $16, %esp
              movl    ___security_cookie, %eax                                        <<<-- Loading Stack Guard value
              movl    28(%esp), %esi
              movl    %eax, 12(%esp)                                                  <<<-- Store to Guard slot
              leal    2(%esp), %eax
              pushl   %esi
              pushl   $204
              pushl   %eax
              calll   _memset
              addl    $12, %esp
              movsbl  2(%esp,%esi), %esi
              movl    12(%esp), %ecx                                                  <<<-- Loading Guard slot
              calll   @__security_check_cookie@4                                      <<<-- Epilogue function-based check
              movl    %esi, %eax
              addl    $16, %esp
              popl    %esi
              retl
      ```
      
      Reviewers: kcc, pcc, eugenis, rnk
      
      Subscribers: majnemer, llvm-commits, hans, thakis, rnk
      
      Differential Revision: http://reviews.llvm.org/D20346
      
      llvm-svn: 272053
      22bfa832
  34. Jun 03, 2016
    • Justin Bogner's avatar
      Re-apply "SDAG: Update ChainNodesMatched as nodes are deleted" · 07bf5349
      Justin Bogner authored
      My first attempt at this had an overly aggressive assert - chain nodes
      will only be removed, but we could hit the assert if a non-chain node
      was CSE'd (NodeToMatch, for instance).
      
      This reapplies r271706 by reverting r271713 and fixing an assert.
      
      Original message:
      
      Avoid relying on UB by looking into deleted nodes for a marker value.
      Instead, update the list of chain nodes as we go.
      
      llvm-svn: 271733
      07bf5349
Loading