Skip to content
  1. Apr 22, 2004
    • Chris Lattner's avatar
      This code really wants to iterate over the OPERANDS of an instruction, not · fb9a299f
      Chris Lattner authored
      over its USES.  If it's dead it doesn't have any uses!  :)
      
      Thanks to the fabulous and mysterious Bill Wendling for pointing this out.  :)
      
      llvm-svn: 13102
      fb9a299f
    • Chris Lattner's avatar
      Implement a fixme. The helps loops that have induction variables of different · dc7cc350
      Chris Lattner authored
      types in them.  Instead of creating an induction variable for all types, it
      creates a single induction variable and casts to the other sizes.  This generates
      this code:
      
      no_exit:                ; preds = %entry, %no_exit
              %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=4]
      ***     %j.0.0 = cast uint %indvar to short             ; <short> [#uses=1]
              %indvar = cast uint %indvar to int              ; <int> [#uses=1]
              %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
              store short %j.0.0, short* %tmp.7
              %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
              %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
              %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
              br bool %tmp.2, label %no_exit, label %loopexit
      
      instead of:
      
      no_exit:                ; preds = %entry, %no_exit
              %indvar = phi ushort [ %indvar.next, %no_exit ], [ 0, %entry ]          ; <ushort> [#uses=2]
      ***     %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=3]
              %indvar = cast uint %indvar to int              ; <int> [#uses=1]
              %indvar = cast ushort %indvar to short          ; <short> [#uses=1]
              %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
              store short %indvar, short* %tmp.7
              %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
              %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
              %indvar.next = add uint %indvar, 1
      ***     %indvar.next = add ushort %indvar, 1
              br bool %tmp.2, label %no_exit, label %loopexit
      
      This is an improvement in register pressure, but probably doesn't happen that
      often.
      
      The more important fix will be to get rid of the redundant add.
      
      llvm-svn: 13101
      dc7cc350
  2. Apr 20, 2004
  3. Apr 19, 2004
  4. Apr 18, 2004
  5. Apr 17, 2004
    • Chris Lattner's avatar
      If the loop executes a constant number of times, try a bit harder to replace · a8140800
      Chris Lattner authored
      exit values.
      
      llvm-svn: 13018
      a8140800
    • Chris Lattner's avatar
      Fix a HUGE pessimization on X86. The indvars pass was taking this · 1e9ac1a4
      Chris Lattner authored
      (familiar) function:
      
      int _strlen(const char *str) {
          int len = 0;
          while (*str++) len++;
          return len;
      }
      
      And transforming it to use a ulong induction variable, because the type of
      the pointer index was left as a constant long.  This is obviously very bad.
      
      The fix is to shrink long constants in getelementptr instructions to intptr_t,
      making the indvars pass insert a uint induction variable, which is much more
      efficient.
      
      Here's the before code for this function:
      
      int %_strlen(sbyte* %str) {
      entry:
              %tmp.13 = load sbyte* %str              ; <sbyte> [#uses=1]
              %tmp.24 = seteq sbyte %tmp.13, 0                ; <bool> [#uses=1]
              br bool %tmp.24, label %loopexit, label %no_exit
      
      no_exit:                ; preds = %entry, %no_exit
      ***     %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=2]
      ***     %indvar = phi ulong [ %indvar.next, %no_exit ], [ 0, %entry ]           ; <ulong> [#uses=2]
              %indvar1 = cast ulong %indvar to uint           ; <uint> [#uses=1]
              %inc.02.sum = add uint %indvar1, 1              ; <uint> [#uses=1]
              %inc.0.0 = getelementptr sbyte* %str, uint %inc.02.sum          ; <sbyte*> [#uses=1]
              %tmp.1 = load sbyte* %inc.0.0           ; <sbyte> [#uses=1]
              %tmp.2 = seteq sbyte %tmp.1, 0          ; <bool> [#uses=1]
              %indvar.next = add ulong %indvar, 1             ; <ulong> [#uses=1]
              %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
              br bool %tmp.2, label %loopexit.loopexit, label %no_exit
      
      loopexit.loopexit:              ; preds = %no_exit
              %indvar = cast uint %indvar to int              ; <int> [#uses=1]
              %inc.1 = add int %indvar, 1             ; <int> [#uses=1]
              ret int %inc.1
      
      loopexit:               ; preds = %entry
              ret int 0
      }
      
      
      Here's the after code:
      
      int %_strlen(sbyte* %str) {
      entry:
              %inc.02 = getelementptr sbyte* %str, uint 1             ; <sbyte*> [#uses=1]
              %tmp.13 = load sbyte* %str              ; <sbyte> [#uses=1]
              %tmp.24 = seteq sbyte %tmp.13, 0                ; <bool> [#uses=1]
              br bool %tmp.24, label %loopexit, label %no_exit
      
      no_exit:                ; preds = %entry, %no_exit
      ***     %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=3]
              %indvar = cast uint %indvar to int              ; <int> [#uses=1]
              %inc.0.0 = getelementptr sbyte* %inc.02, uint %indvar           ; <sbyte*> [#uses=1]
              %inc.1 = add int %indvar, 1             ; <int> [#uses=1]
              %tmp.1 = load sbyte* %inc.0.0           ; <sbyte> [#uses=1]
              %tmp.2 = seteq sbyte %tmp.1, 0          ; <bool> [#uses=1]
              %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
              br bool %tmp.2, label %loopexit, label %no_exit
      
      loopexit:               ; preds = %entry, %no_exit
              %len.0.1 = phi int [ 0, %entry ], [ %inc.1, %no_exit ]          ; <int> [#uses=1]
              ret int %len.0.1
      }
      
      llvm-svn: 13016
      1e9ac1a4
    • Chris Lattner's avatar
      Even if there are not any induction variables in the loop, if we can compute · 885a6eb7
      Chris Lattner authored
      the trip count for the loop, insert one so that we can canonicalize the exit
      condition.
      
      llvm-svn: 13015
      885a6eb7
  6. Apr 16, 2004
  7. Apr 15, 2004
    • Chris Lattner's avatar
      Fix a bug in the previous checkin: if the exit block is not the same as · d7a559e3
      Chris Lattner authored
      the back-edge block, we must check the preincremented value.
      
      llvm-svn: 12968
      d7a559e3
    • Chris Lattner's avatar
      Change the canonical induction variable that we insert. · 0cec5cb9
      Chris Lattner authored
      Instead of producing code like this:
      
      Loop:
        X = phi 0, X2
        ...
      
        X2 = X + 1
        if (X != N-1) goto Loop
      
      We now generate code that looks like this:
      
      Loop:
        X = phi 0, X2
        ...
      
        X2 = X + 1
        if (X2 != N) goto Loop
      
      This has two big advantages:
        1. The trip count of the loop is now explicit in the code, allowing
           the direct implementation of Loop::getTripCount()
        2. This reduces register pressure in the loop, and allows X and X2 to be
           put into the same register.
      
      As a consequence of the second point, the code we generate for loops went
      from:
      
      .LBB2:  # no_exit.1
      	...
              mov %EDI, %ESI
              inc %EDI
              cmp %ESI, 2
              mov %ESI, %EDI
              jne .LBB2 # PC rel: no_exit.1
      
      To:
      
      .LBB2:  # no_exit.1
      	...
              inc %ESI
              cmp %ESI, 3
              jne .LBB2 # PC rel: no_exit.1
      
      ... which has two fewer moves, and uses one less register.
      
      llvm-svn: 12961
      0cec5cb9
  8. Apr 14, 2004
  9. Apr 13, 2004
  10. Apr 12, 2004
  11. Apr 11, 2004
  12. Apr 10, 2004
Loading