1. 19 Sep, 2016 2 commits
    • Damien George's avatar
      py: Combine 3 comprehension opcodes (list/dict/set) into 1. · adaf0d86
      Damien George authored
      With the previous patch combining 3 emit functions into 1, it now makes
      sense to also combine the corresponding VM opcodes, which is what this
      patch does.  This eliminates 2 opcodes which simplifies the VM and reduces
      code size, in bytes: bare-arm:44, minimal:64, unix(NDEBUG,x86-64):272,
      stmhal:92, esp8266:200.  Profiling (with a simple script that creates many
      list/dict/set comprehensions) shows no measurable change in performance.
      adaf0d86
    • Damien George's avatar
      py: Combine 3 comprehension emit functions (list/dict/set) into 1. · a5624bf3
      Damien George authored
      The 3 kinds of comprehensions are similar enough that merging their emit
      functions reduces code size.  Decreases in code size in bytes are:
      bare-arm:24, minimal:96, unix(NDEBUG,x86-64):328, stmhal:80, esp8266:76.
      a5624bf3
  2. 07 Apr, 2016 1 commit
  3. 25 Feb, 2016 1 commit
    • Damien George's avatar
      py: Add MICROPY_DYNAMIC_COMPILER option to config compiler at runtime. · ea235204
      Damien George authored
      This new compile-time option allows to make the bytecode compiler
      configurable at runtime by setting the fields in the mp_dynamic_compiler
      structure.  By using this feature, the compiler can generate bytecode
      that targets any MicroPython runtime/VM, regardless of the host and
      target compile-time settings.
      
      Options so far that fall under this dynamic setting are:
      - maximum number of bits that a small int can hold;
      - whether caching of lookups is used in the bytecode;
      - whether to use unicode strings or not (lexer behaviour differs, and
        therefore generated string constants differ).
      ea235204
  4. 18 Dec, 2015 1 commit
    • Damien George's avatar
      py: Add MICROPY_ENABLE_COMPILER and MICROPY_PY_BUILTINS_EVAL_EXEC opts. · dd5353a4
      Damien George authored
      MICROPY_ENABLE_COMPILER can be used to enable/disable the entire compiler,
      which is useful when only loading of pre-compiled bytecode is supported.
      It is enabled by default.
      
      MICROPY_PY_BUILTINS_EVAL_EXEC controls support of eval and exec builtin
      functions.  By default they are only included if MICROPY_ENABLE_COMPILER
      is enabled.
      
      Disabling both options saves about 40k of code size on 32-bit x86.
      dd5353a4
  5. 10 Dec, 2015 1 commit
    • Damien George's avatar
      py: Make UNARY_OP_NOT a first-class op, to agree with Py not semantics. · bdbe8c9a
      Damien George authored
      Fixes #1684 and makes "not" match Python semantics.  The code is also
      simplified (the separate MP_BC_NOT opcode is removed) and the patch saves
      68 bytes for bare-arm/ and 52 bytes for minimal/.
      
      Previously "not x" was implemented as !mp_unary_op(x, MP_UNARY_OP_BOOL),
      so any given object only needs to implement MP_UNARY_OP_BOOL (and the VM
      had a special opcode to do the ! bit).
      
      With this patch "not x" is implemented as mp_unary_op(x, MP_UNARY_OP_NOT),
      but this operation is caught at the start of mp_unary_op and dispatched as
      !mp_obj_is_true(x).  mp_obj_is_true has special logic to test for
      truthness, and is the correct way to handle the not operation.
      bdbe8c9a
  6. 29 Nov, 2015 2 commits
  7. 13 Nov, 2015 5 commits
  8. 23 Sep, 2015 1 commit
  9. 04 Sep, 2015 1 commit
  10. 17 Aug, 2015 1 commit
    • Damien George's avatar
      unix-cpy: Remove unix-cpy. It's no longer needed. · 65dc960e
      Damien George authored
      unix-cpy was originally written to get semantic equivalent with CPython
      without writing functional tests.  When writing the initial
      implementation of uPy it was a long way between lexer and functional
      tests, so the half-way test was to make sure that the bytecode was
      correct.  The idea was that if the uPy bytecode matched CPython 1-1 then
      uPy would be proper Python if the bytecodes acted correctly.  And having
      matching bytecode meant that it was less likely to miss some deep
      subtlety in the Python semantics that would require an architectural
      change later on.
      
      But that is all history and it no longer makes sense to retain the
      ability to output CPython bytecode, because:
      
      1. It outputs CPython 3.3 compatible bytecode.  CPython's bytecode
      changes from version to version, and seems to have changed quite a bit
      in 3.5.  There's no point in changing the bytecode output to match
      CPython anymore.
      
      2. uPy and CPy do different optimisations to the bytecode which makes it
      harder to match.
      
      3. The bytecode tests are not run.  They were never part of Travis and
      are not run locally anymore.
      
      4. The EMIT_CPYTHON option needs a lot of extra source code which adds
      heaps of noise, especially in compile.c.
      
      5. Now that there is an extensive test suite (which tests functionality)
      there is no need to match the bytecode.  Some very subtle behaviour is
      tested with the test suite and passing these tests is a much better
      way to stay Python-language compliant, rather than trying to match
      CPy bytecode.
      65dc960e
  11. 25 Jun, 2015 1 commit
    • Damien George's avatar
      py: Remove mp_load_const_bytes and instead load precreated bytes object. · 59fba2d6
      Damien George authored
      Previous to this patch each time a bytes object was referenced a new
      instance (with the same data) was created.  With this patch a single
      bytes object is created in the compiler and is loaded directly at execute
      time as a true constant (similar to loading bignum and float objects).
      This saves on allocating RAM and means that bytes objects can now be
      used when the memory manager is locked (eg in interrupts).
      
      The MP_BC_LOAD_CONST_BYTES bytecode was removed as part of this.
      
      Generated bytecode is slightly larger due to storing a pointer to the
      bytes object instead of the qstr identifier.
      
      Code size is reduced by about 60 bytes on Thumb2 architectures.
      59fba2d6
  12. 06 May, 2015 1 commit
  13. 05 May, 2015 1 commit
  14. 24 Apr, 2015 1 commit
  15. 16 Apr, 2015 1 commit
  16. 09 Apr, 2015 2 commits
  17. 06 Apr, 2015 1 commit
  18. 26 Mar, 2015 3 commits
    • Damien George's avatar
      py, compiler: When just bytecode, make explicit calls instead of table. · 4112590a
      Damien George authored
      When just the bytecode emitter is needed there is no need to have a
      dynamic method table for the emitter back-end, and we can instead
      directly call the mp_emit_bc_XXX functions.  This gives a significant
      reduction in code size and a very slight performance boost for the
      compiler.
      
      This patch saves 1160 bytes code on Thumb2 and 972 bytes on x86, when
      native emitters are disabled.
      
      Overall savings in code over the last 3 commits are:
      
      bare-arm: 1664 bytes.
      minimal:  2136 bytes.
      stmhal:    584 bytes (it has native emitter enabled).
      cc3200:   1736 bytes.
      4112590a
    • Damien George's avatar
      py, compiler: Remove emit_pass1 code, using emit_bc to do its job. · a210c774
      Damien George authored
      First pass for the compiler is computing the scope (eg if an identifier
      is local or not) and originally had an entire table of methods dedicated
      to this, most of which did nothing.  With changes from previous commit,
      this set of methods can be removed and the methods from the bytecode
      emitter used instead, with very little modification -- this is what is
      done in this commit.
      
      This factoring has little to no impact on the speed of the compiler
      (tested by compiling 3763 Python scripts and timing it).
      
      This factoring reduces code size by about 270-300 bytes on Thumb2 archs,
      and 400 bytes on x86.
      a210c774
    • Damien George's avatar
      py, compiler: Refactor load/store/delete_id logic to reduce code size. · 542bd6b4
      Damien George authored
      Saves around 230 bytes on Thumb2 and 750 bytes on x86.
      542bd6b4
  19. 28 Feb, 2015 1 commit
  20. 08 Feb, 2015 1 commit
    • Damien George's avatar
      py: Parse big-int/float/imag constants directly in parser. · 7d414a1b
      Damien George authored
      Previous to this patch, a big-int, float or imag constant was interned
      (made into a qstr) and then parsed at runtime to create an object each
      time it was needed.  This is wasteful in RAM and not efficient.  Now,
      these constants are parsed straight away in the parser and turned into
      objects.  This allows constants with large numbers of digits (so
      addresses issue #1103) and takes us a step closer to #722.
      7d414a1b
  21. 20 Jan, 2015 1 commit
  22. 16 Jan, 2015 2 commits
  23. 14 Jan, 2015 1 commit
  24. 13 Jan, 2015 1 commit
  25. 07 Jan, 2015 2 commits
    • Damien George's avatar
      py: Add option to cache map lookup results in bytecode. · 7ee91cf8
      Damien George authored
      This is a simple optimisation inspired by JITing technology: we cache in
      the bytecode (using 1 byte) the offset of the last successful lookup in
      a map. This allows us next time round to check in that location in the
      hash table (mp_map_t) for the desired entry, and if it's there use that
      entry straight away.  Otherwise fallback to a normal map lookup.
      
      Works for LOAD_NAME, LOAD_GLOBAL, LOAD_ATTR and STORE_ATTR opcodes.
      
      On a few tests it gives >90% cache hit and greatly improves speed of
      code.
      
      Disabled by default.  Enabled for unix and stmhal ports.
      7ee91cf8
    • Damien George's avatar
      py: Put all global state together in state structures. · b4b10fd3
      Damien George authored
      This patch consolidates all global variables in py/ core into one place,
      in a global structure.  Root pointers are all located together to make
      GC tracing easier and more efficient.
      b4b10fd3
  26. 01 Jan, 2015 1 commit
  27. 27 Dec, 2014 2 commits
    • Damien George's avatar
      py: Allow to properly disable builtin slice operation. · 83204f34
      Damien George authored
      This patch makes the MICROPY_PY_BUILTINS_SLICE compile-time option
      fully disable the builtin slice operation (when set to 0).  This
      includes removing the slice sytanx from the grammar.  Now, enabling
      slice costs 4228 bytes on unix x64, and 1816 bytes on stmhal.
      83204f34
    • Damien George's avatar
      py: Allow to properly disable builtin "set" object. · e37dcaaf
      Damien George authored
      This patch makes MICROPY_PY_BUILTINS_SET compile-time option fully
      disable the builtin set object (when set to 0).  This includes removing
      set constructor/comprehension from the grammar, the compiler and the
      emitters.  Now, enabling set costs 8168 bytes on unix x64, and 3576
      bytes on stmhal.
      e37dcaaf
  28. 25 Oct, 2014 1 commit
    • Damien George's avatar
      py: Compress load-int, load-fast, store-fast, unop, binop bytecodes. · 8456cc01
      Damien George authored
      There is a lot potential in compress bytecodes and make more use of the
      coding space.  This patch introduces "multi" bytecodes which have their
      argument included in the bytecode (by addition).
      
      UNARY_OP and BINARY_OP now no longer take a 1 byte argument for the
      opcode.  Rather, the opcode is included in the first byte itself.
      
      LOAD_FAST_[0,1,2] and STORE_FAST_[0,1,2] are removed in favour of their
      multi versions, which can take an argument between 0 and 15 inclusive.
      The majority of LOAD_FAST/STORE_FAST codes fit in this range and so this
      saves a byte for each of these.
      
      LOAD_CONST_SMALL_INT_MULTI is used to load small ints between -16 and 47
      inclusive.  Such ints are quite common and now only need 1 byte to
      store, and now have much faster decoding.
      
      In all this patch saves about 2% RAM for typically bytecode (1.8% on
      64-bit test, 2.5% on pyboard test).  It also reduces the binary size
      (because bytecodes are simplified) and doesn't harm performance.
      8456cc01