compiler: Add UnboxEarly conniver pass

This moves any unboxing steps to after the last use of the input boxed
value. It reduces GC overhead by allowing the GC managed boxed value to
be replaced with its unboxed equivalent as soon as possible. This
requires less values to be GC rooted and saved/restored across GC
barriers.

This is motivated by some silly code generated for Life R7RS example
that pulled boxed integers across multiple GC barriers.
compiler: Don't box when phi'ing consts and native

This makes phi'ed values between conditional branches use the unboxed
value when phiing constant values with native values or other constants.
Previously they would use a boxed value which would cause boxing if the
other values was a native value.

This is a less clear advantage when phi'ing two constant values. If the
value later needed to be boxed we'll needlessly create a GC allocated
cell instead of phi'ing two constant values. However, if that phi'ed
constant value is returned from a procedure or phi'ed with another
non-constant value it will no longer be known to be a constant and will
require GC rooting.

- Add a new iv.UnboxedValue trait that indicates values that can be
  immediately represented by a native value

- Have all NativeValue classes implement UnboxedValue

- Have Constant{Flonum,ExactInteger,Char,Boolean}Value implement
  UnboxedValue

- Change PlanResultValuesPhi to look for the UnboxedValue trait instead
  of NativeValue
compiler: Limit inlining depth

Inlining was mostly restricted by inlining being disabled for recursive
lambdas. However, it's possible for mutually recursive lambdas and
recursive (case-lambda)s to cause unbounded inlining. Keep track of the
current inline depth in the PlannerState and refuse to inline once it
hits 8.
Split number and arithmetic functional tests

This reflects this existing split in the runtime and the planner. This
is purely to reduce the size of NumberSuite.scm to a more manageable
size
stdlib: Implement (gcd) and (lcm)

The 0 and 1 argument cases are handled in Scheme while the 2+ argument
case is implemented in C++. This is so the common case of 2 arguments
doe not require building a rest argument list to pass to C++.
stdlib: Implement (exact-integer-sqrt)

This implements integer square root on top of C++11's integral std::sqrt
stdlib: Implement (utf8->string), (string->utf8)

This is a wrapper around the StringCell::toUtf8Bytevector and
BytevectorCell::utf8ToString
compiler: Add planning for (bytevector-length)

This is identical to how (vector-length) is handled. This speeds up
slicing operations on bytevectors such as (utf8->string).
runtime: Introduce StringCellBuilder

This replaces StringCell::fromUnicodeChars. Instead of creating a
temporary std::vector of UnicodeChars callers can now append single
characters to a Unicode string in one pass. This has two performance
advantages:

- Only one temporary buffer is required for the output UTF-8 data.
  Previously an input vector would be allocated which would then be
  encoded in to a destination buffer.

- We allocate enough data up front to avoid range checkng and
  reallocation while building UTF-8 data

On Linux this reduces the library code size and speeds up the
generate-cxr-library test by >5%
stdlib: Implement string->vector, vector->string
compiler: Ensure lambda arguments names are unique

With macros its possible for a lambda to have the an argument with the
same name in different scopes. Currently this will cause us to generate
invalid IR due to duplicate argument names. Use SourceNameUniquer which
will assign duplicate names distinct suffixes.

This is difficult to trigger due to a macro expander bug but it will be
indirectly tested by a following commit.
compiler: Rescope all symbols in expanded template

This is to support the (let-values) macro which recursively expands
itself introducing multiple arguments named "x" to an expanded lambda.
This currently fails as we're not implementing the following behaviour
mentioned in R7RS:

"If a macro transformer inserts a binding for an identifier (variable or
keyword), the identifier will in effect be renamed throughout its scope
to avoid conflicts with other identifiers"

This can be implemented by our frontend by assigning all symbols fresh
scopes that contain their existing scope as a parent. They will then be
considered distinct symbols even if they were expanded from the exact
same symbol in the source.

This is difficult to directly test but will be validated by the
(let-values) test in an upcoming commit.
stdlib: Implement (let-values), (let*-values)

These are taken verbatim from R7RS. They convert to simple combinations
of (lambda) and (let) which are easily optimisable by our planner.
stdlib: Switch arithemtic tests to (let-values)

Now that (let-values) is supported we don't need to directly use
(call-with-values) to test multiple value procedures.