Previously, GetElementType() would end up causing dynamic allocation to
happen to compute the final element type (turning types with unbound
variability into the same type with the struct's variability) each it was
called, which was wasteful and slow. Now we cache the result.
Another 20% perf on compiling that problematic program.
We don't need to explicitly create the non-const Types to do type
comparison when ignoring const-ness in the check.
We can also save some unnecessary dynamic memory allocation by
keeping strings returned from GetStructName() as references to strings.
This gives another 10% on front-end perf on that big program.
We now have a set of template functions CastType<AtomicType>, etc., that in
turn use a new typeId field in each Type instance, allowing them to be inlined
and to be quite efficient.
This improves front-end performance for a particular large program by 28%.
In one very large program, we were spending quite a bit of time repeatedly
getting const variants of StructTypes. This speeds up the front-end by
about 40% for that test case.
(This is something of a band-aid, pending uniquing types.)
Before, if the function was declared before being defined, then the symbol's
SourcePos would be left set to the position of the declaration. This ended
up getting the debugging symbols mixed up in this case, which was undesirable.
It's now possible to successfully print out the value of programIndex,
programCount, etc., in the debugger. The issue was that they were
defined as having InternalLinkage, which meant that DCE removed them
at the end of compilation. Now they're declared to have WeakODRLinkage,
which ensures that one copy survives (but there aren't multiply-defined
symbols when compiling multiple files.)
The DIType passed to this method should correspond to the
FunctionType of the function, not its return type.
The first parameter should be the DIScope for the compile unit,
not the DIFile.
We previously had the unmangled function name and the mangled
function name interchanged.
The argument corresponding to "first line number of the function" was
missing, which in turn led to subsequent arguments being off, and thus
providing bogus values vs. what was supposed to be passed.
Rename FunctionEmitContext::diFunction to diSubprogram, to better
reflect its type.
Debugging information for functions that are inlined or static and
not used still hangs around after compilation; now we go through the
debugging info and remove the entries for any DISubprograms that
don't have their original functions left in the Module after
optimization.
We now try harder to keep the names of instructions related to the
initial names of variables they're derived from and so forth. This
is useful for making both LLVM IR as well as generated C++ code
easier to correlate back to the original ispc source code.
Issue #244.
Now, when we're printing out a constant vector value, we check to see
if it's a splat and call out to one of the __splat_* functions in
the generated code if to.