Skip to content
  1. Apr 18, 2004
  2. 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
      Add the ability to compute trip counts that are only controlled by constants · 4021d1af
      Chris Lattner authored
      even if the loop is using expressions that we can't compute as a closed-form.
      This allows us to calculate that this function always returns 55:
      
      int test() {
        double X;
        int Count = 0;
        for (X = 100; X > 1; X = sqrt(X), ++Count)
          /*empty*/;
        return Count;
      }
      
      And allows us to compute trip counts for loops like:
      
              int h = 1;
               do h = 3 * h + 1; while (h <= 256);
      
      (which occurs in bzip2), and for this function, which occurs after inlining
      and other optimizations:
      
      int popcount()
      {
         int x = 666;
        int result = 0;
        while (x != 0) {
          result = result + (x & 0x1);
          x = x >> 1;
        }
        return result;
      }
      
      We still cannot compute the exit values of result or h in the two loops above,
      which means we cannot delete the loop, but we are getting closer.  Being able to
      compute a constant trip count for these two loops will allow us to unroll them
      completely though.
      
      llvm-svn: 13017
      4021d1af
    • 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
    • Chris Lattner's avatar
      Add support for evaluation of exp/log/log10/pow · a43312d3
      Chris Lattner authored
      llvm-svn: 13011
      a43312d3
  3. Apr 16, 2004
Loading