Skip to content
Snippets Groups Projects
  1. Jul 23, 2014
  2. Jul 22, 2014
  3. Jul 21, 2014
  4. Jul 19, 2014
  5. Jul 18, 2014
  6. Jul 17, 2014
  7. Jul 16, 2014
  8. Jul 11, 2014
  9. Jul 09, 2014
  10. Jul 07, 2014
  11. Jul 04, 2014
  12. Jul 03, 2014
  13. Jul 02, 2014
  14. Jun 28, 2014
  15. Jun 27, 2014
  16. Jun 25, 2014
    • Serge Pavlov's avatar
      Fix treatment of types defined in function prototype · 525f68c5
      Serge Pavlov authored
      Types defined in function prototype are diagnosed earlier in C++ compilation.
      They are put into declaration context where the prototype is introduced. Later on,
      when FunctionDecl object is created, these types are moved into the function context.
      
      This patch fixes PR19018 and PR18963.
      
      Differential Revision: http://reviews.llvm.org/D4145
      
      
      git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211718 91177308-0d34-0410-b5e6-96231b3b80d8
      525f68c5
    • David Majnemer's avatar
      AST: Initialization with dllimport functions in C · ab6dc444
      David Majnemer authored
      The C++ language requires that the address of a function be the same
      across all translation units.  To make __declspec(dllimport) useful,
      this means that a dllimported function must also obey this rule.  MSVC
      implements this by dynamically querying the import address table located
      in the linked executable.  This means that the address of such a
      function in C++ is not constant (which violates other rules).
      
      However, the C language has no notion of ODR nor does it permit dynamic
      initialization whatsoever.  This requires implementations to _not_
      dynamically query the import address table and instead utilize a wrapper
      function that will be synthesized by the linker which will eventually
      query the import address table.  The effect this has is, to say the
      least, perplexing.
      
      Consider the following C program:
      __declspec(dllimport) void f(void);
      
      typedef void (*fp)(void);
      
      static const fp var = &f;
      
      const fp fun() { return &f; }
      
      int main() { return fun() == var; }
      
      MSVC will statically initialize "var" with the address of the wrapper
      function and "fun" returns the address of the actual imported function.
      This means that "main" will return false!
      
      Note that LLVM's optimizers are strong enough to figure out that "main"
      should return true.  However, this result is dependent on having
      optimizations enabled!
      
      N.B.  This change also permits the usage of dllimport declarators inside
      of template arguments; they are sufficiently constant for such a
      purpose.  Add tests to make sure we don't regress here.
      
      git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211677 91177308-0d34-0410-b5e6-96231b3b80d8
      ab6dc444
  17. Jun 20, 2014
    • James Molloy's avatar
      The ability to use vector initializer lists is a GNU vector extension · 8d4b65e9
      James Molloy authored
      and is unrelated to the NEON intrinsics in arm_neon.h. On little
      endian machines it works fine, however on big endian machines it
      exhibits surprising behaviour:
      
          uint32x2_t x = {42, 64};
          return vget_lane_u32(x, 0); // Will return 64.
      
      Because of this, explicitly call out that it is unsupported on big
      endian machines.
      
      This patch will emit the following warning in big-endian mode:
      
          test.c:3:15: warning: vector initializers are a GNU extension and are not compatible with NEON intrinsics [-Wgnu]
          int32x4_t x = {0, 1, 2, 3};
                        ^
          test.c:3:15: note: consider using vld1q_s32() to initialize a vector from memory, or vcombine_s32(vcreate_s32(), vcreate_s32()) to initialize from integer constants
          1 warning generated.
      
      git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211362 91177308-0d34-0410-b5e6-96231b3b80d8
      8d4b65e9
  18. Jun 19, 2014
  19. Jun 17, 2014
    • James Molloy's avatar
      Rewrite ARM NEON intrinsic emission completely. · ac41a1b7
      James Molloy authored
      There comes a time in the life of any amateur code generator when dumb string
      concatenation just won't cut it any more. For NeonEmitter.cpp, that time has
      come.
      
      There were a bunch of magic type codes which meant different things depending on
      the context. There were a bunch of special cases that really had no reason to be
      there but the whole thing was so creaky that removing them would cause something
      weird to fall over. There was a 1000 line switch statement for code generation
      involving string concatenation, which actually did lexical scoping to an extent
      (!!) with a bunch of semi-repeated cases.
      
      I tried to refactor this three times in three different ways without
      success. The only way forward was to rewrite the entire thing. Luckily the
      testing coverage on this stuff is absolutely massive, both with regression tests
      and the "emperor" random test case generator.
      
      The main change is that previously, in arm_neon.td a bunch of "Operation"s were
      defined with special names. NeonEmitter.cpp knew about these Operations and
      would emit code based on a huge switch. Actually this doesn't make much sense -
      the type information was held as strings, so type checking was impossible. Also
      TableGen's DAG type actually suits this sort of code generation very well
      (surprising that...)
      
      So now every operation is defined in terms of TableGen DAGs. There are a bunch
      of operators to use, including "op" (a generic unary or binary operator), "call"
      (to call other intrinsics) and "shuffle" (take a guess...). One of the main
      advantages of this apart from making it more obvious what is going on, is that
      we have proper type inference. This has two obvious advantages:
      
        1) TableGen can error on bad intrinsic definitions easier, instead of just
           generating wrong code.
        2) Calls to other intrinsics are typechecked too. So
           we no longer need to work out whether the thing we call needs to be the Q-lane
           version or the D-lane version - TableGen knows that itself!
      
      Here's an example: before:
      
        case OpAbdl: {
          std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)";
          if (typestr[0] != 'U') {
            // vabd results are always unsigned and must be zero-extended.
            std::string utype = "U" + typestr.str();
            s += "(" + TypeString(proto[0], typestr) + ")";
            abd = "(" + TypeString('d', utype) + ")" + abd;
            s += Extend(utype, abd) + ";";
          } else {
            s += Extend(typestr, abd) + ";";
          }
          break;
        }
      
      after:
      
        def OP_ABDL     : Op<(cast "R", (call "vmovl", (cast $p0, "U",
                                                             (call "vabd", $p0, $p1))))>;
      
      As an example of what happens if you do something wrong now, here's what happens
      if you make $p0 unsigned before the call to "vabd" - that is, $p0 -> (cast "U",
      $p0):
      
      arm_neon.td:574:1: error: No compatible intrinsic found - looking up intrinsic 'vabd(uint8x8_t, int8x8_t)'
      Available overloads:
        - float64x2_t vabdq_v(float64x2_t, float64x2_t)
        - float64x1_t vabd_v(float64x1_t, float64x1_t)
        - float64_t vabdd_f64(float64_t, float64_t)
        - float32_t vabds_f32(float32_t, float32_t)
      ... snip ...
      
      This makes it seriously easy to work out what you've done wrong in fairly nasty
      intrinsics.
      
      As part of this I've massively beefed up the documentation in arm_neon.td too.
      
      Things still to do / on the radar:
        - Testcase generation. This was implemented in the previous version and not in
          the new one, because
          - Autogenerated tests are not being run. The testcase in test/ differs from
            the autogenerated version.
          - There were a whole slew of special cases in the testcase generation that just
            felt (and looked) like hacks.
          If someone really feels strongly about this, I can try and reimplement it too.
        - Big endian. That's coming soon and should be a very small diff on top of this one.
      
      git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211101 91177308-0d34-0410-b5e6-96231b3b80d8
      ac41a1b7
  20. Jun 11, 2014
  21. Jun 05, 2014
  22. Jun 04, 2014
  23. Jun 03, 2014
  24. May 31, 2014
Loading