Skip to content
  1. Feb 28, 2004
    • Chris Lattner's avatar
      Implement switch->br and br->switch folding by ripping out the switch->switch · d3e6ae26
      Chris Lattner authored
      and br->br code and generalizing it.  This allows us to compile code like this:
      
      int test(Instruction *I) {
        if (isa<CastInst>(I))
          return foo(7);
        else if (isa<BranchInst>(I))
          return foo(123);
        else if (isa<UnwindInst>(I))
          return foo(1241);
        else if (isa<SetCondInst>(I))
          return foo(1);
        else if (isa<VAArgInst>(I))
          return foo(42);
        return foo(-1);
      }
      
      into:
      
      int %_Z4testPN4llvm11InstructionE("struct.llvm::Instruction"* %I) {
      entry:
              %tmp.1.i.i.i.i.i.i.i = getelementptr "struct.llvm::Instruction"* %I, long 0, ubyte 4            ; <uint*> [#uses=1]
              %tmp.2.i.i.i.i.i.i.i = load uint* %tmp.1.i.i.i.i.i.i.i          ; <uint> [#uses=2]
              %tmp.2.i.i.i.i.i.i = seteq uint %tmp.2.i.i.i.i.i.i.i, 27                ; <bool> [#uses=0]
              switch uint %tmp.2.i.i.i.i.i.i.i, label %endif.0 [
                       uint 27, label %then.0
                       uint 2, label %then.1
                       uint 5, label %then.2
                       uint 14, label %then.3
                       uint 15, label %then.3
                       uint 16, label %then.3
                       uint 17, label %then.3
                       uint 18, label %then.3
                       uint 19, label %then.3
                       uint 32, label %then.4
              ]
      ...
      
      As well as handling the cases in 176.gcc and many other programs more effectively.
      
      llvm-svn: 11964
      d3e6ae26
    • Misha Brukman's avatar
      Right, it's really Extractor, not Extraction. · 8a2c28fd
      Misha Brukman authored
      llvm-svn: 11939
      8a2c28fd
    • Misha Brukman's avatar
      A pass that uses the generic CodeExtractor to rip out *every* loop in every · 03a11340
      Misha Brukman authored
      function, as long as the loop isn't the only one in that function. This should
      help debugging passes easier with BugPoint.
      
      llvm-svn: 11936
      03a11340
    • Misha Brukman's avatar
      A generic code extractor: given a list of BasicBlocks, it will rip them out into · caa1a5ab
      Misha Brukman authored
      a new function, taking care of inputs and outputs.
      
      llvm-svn: 11935
      caa1a5ab
  2. Feb 26, 2004
    • Chris Lattner's avatar
      turn things like: · 21e941fb
      Chris Lattner authored
         if (X == 0 || X == 2)
      
      ...where the comparisons and branches are in different blocks... into a switch
      instruction.  This comes up a lot in various programs, and works well with
      the switch/switch merging code I checked earlier.  For example, this testcase:
      
      int switchtest(int C) {
        return C == 0 ? f(123) :
               C == 1 ? f(3123) :
               C == 4 ? f(312) :
               C == 5 ? f(1234): f(444);
      }
      
      is converted into this:
              switch int %C, label %cond_false.3 [
                       int 0, label %cond_true.0
                       int 1, label %cond_true.1
                       int 4, label %cond_true.2
                       int 5, label %cond_true.3
              ]
      
      instead of a whole bunch of conditional branches.
      
      Admittedly the code is ugly, and incomplete.  To be complete, we need to add
      br -> switch merging and switch -> br merging.  For example, this testcase:
      
      struct foo { int Q, R, Z; };
      #define A (X->Q+X->R * 123)
      int test(struct foo *X) {
        return A  == 123 ? X1() :
              A == 12321 ? X2():
              (A == 111 || A == 222) ? X3() :
              A == 875 ? X4() : X5();
      }
      
      Gets compiled to this:
              switch int %tmp.7, label %cond_false.2 [
                       int 123, label %cond_true.0
                       int 12321, label %cond_true.1
                       int 111, label %cond_true.2
                       int 222, label %cond_true.2
              ]
      ...
      cond_false.2:           ; preds = %entry
              %tmp.52 = seteq int %tmp.7, 875         ; <bool> [#uses=1]
              br bool %tmp.52, label %cond_true.3, label %cond_false.3
      
      where the branch could be folded into the switch.
      
      This kind of thing occurs *ALL OF THE TIME*, especially in programs like
      176.gcc, which is a horrible mess of code.  It contains stuff like *shudder*:
      
      #define SWITCH_TAKES_ARG(CHAR) \
        (   (CHAR) == 'D' \
         || (CHAR) == 'U' \
         || (CHAR) == 'o' \
         || (CHAR) == 'e' \
         || (CHAR) == 'u' \
         || (CHAR) == 'I' \
         || (CHAR) == 'm' \
         || (CHAR) == 'L' \
         || (CHAR) == 'A' \
         || (CHAR) == 'h' \
         || (CHAR) == 'z')
      
      and
      
      #define CONST_OK_FOR_LETTER_P(VALUE, C)                 \
        ((C) == 'I' ? SMALL_INTVAL (VALUE)                    \
         : (C) == 'J' ? SMALL_INTVAL (-(VALUE))               \
         : (C) == 'K' ? (unsigned)(VALUE) < 32                \
         : (C) == 'L' ? ((VALUE) & 0xffff) == 0               \
         : (C) == 'M' ? integer_ok_for_set (VALUE)            \
         : (C) == 'N' ? (VALUE) < 0                           \
         : (C) == 'O' ? (VALUE) == 0                          \
         : (C) == 'P' ? (VALUE) >= 0                          \
         : 0)
      
      and
      
      #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                     \
      {                                                               \
        if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
          (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),                   \
                         copy_to_mode_reg (SImode, XEXP (X, 1)));     \
        if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \
          (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),                   \
                         copy_to_mode_reg (SImode, XEXP (X, 0)));     \
        if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT)   \
          (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),                   \
                         force_operand (XEXP (X, 0), 0));             \
        if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT)   \
          (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),                   \
                         force_operand (XEXP (X, 1), 0));             \
        if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS)   \
          (X) = gen_rtx (PLUS, Pmode, force_operand (XEXP (X, 0), NULL_RTX),\
                         XEXP (X, 1));                                \
        if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS)   \
          (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),                    \
                         force_operand (XEXP (X, 1), NULL_RTX));      \
        if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST       \
                 || GET_CODE (X) == LABEL_REF)                        \
          (X) = legitimize_address (flag_pic, X, 0, 0);               \
        if (memory_address_p (MODE, X))                               \
          goto WIN; }
      
      and others.  These macros get used multiple times of course.  These are such
      lovely candidates for macros, aren't they?  :)
      
      This code also nicely handles LLVM constructs that look like this:
      
        if (isa<CastInst>(I))
         ...
        else if (isa<BranchInst>(I))
         ...
        else if (isa<SetCondInst>(I))
         ...
        else if (isa<UnwindInst>(I))
         ...
        else if (isa<VAArgInst>(I))
         ...
      
      where the isa can obviously be a dyn_cast as well.  Switch instructions are a
      good thing.
      
      llvm-svn: 11870
      21e941fb
  3. Feb 24, 2004
  4. Feb 17, 2004
  5. Feb 16, 2004
  6. Feb 15, 2004
  7. Feb 13, 2004
  8. Feb 11, 2004
  9. Feb 08, 2004
  10. Feb 04, 2004
  11. Feb 03, 2004
  12. Jan 12, 2004
  13. Jan 09, 2004
  14. Dec 19, 2003
  15. Nov 21, 2003
  16. Nov 20, 2003
  17. Nov 11, 2003
  18. Nov 10, 2003
  19. Nov 06, 2003
  20. Nov 05, 2003
Loading