The iteartive basic block discovery process has been reorganized to
minimize the amount of passes we run (in particular SROA, constant
propagation and early CSE) and to proceed until we don't "pin" any new
branch instruction, and not only until we're not able to discover any
new basic block.
The logging output has also been reworked to be more informative.
* Isolate the SET algorithm from the SETPass
* Isolate the processing of an instruction in a function to be able to
use returns to easily signal if we were able to handle the instruction
or if we gave up
* Add some documentation
SET needs to create clones of instructions, which are not inserted in
any basic block, therefore we have to manually handle their
lifetime. This patch delegates this role to the `OperationsStack`: when
an element is being popped from the stack the OS checks if it belongs to
a basic block and if it doesn't, it deletes it.
Checking if a range of addresses belong to a segment should be
implemented by checking if the start and end address belong to the
address, the `Start <= Address && Address + Size < End` approach leads
to subtle errors when `Address` is close to the maximum representable
value due to an overflow.
Reduce the amount of "\n" and do not print again the original
instruction unless the last instruction that had a decoration, if any,
was associated with a different instruction.
Now `CodeGenerator::translate`, `CodeGenerator::translateCall` and
`CodeGenerator::newInstruction` all return
`CodeGenerator::TranslationResult` which covers all the possible results
that the caller needs to handle such abort, stop translation, force a
new basic block or simply proceed.
This patch also prevents reading a PTC temporary that has never been
written (typically due to a mistranslation) by emitting an abort.
* Import OSRA
* Improve the SET (aka `JumpTargetFromConstants`) by introducing the
`OperationsStack` class.
* Review `harvest` logic
* Allow to disable OSRA (along with the sumjump heuristic)
* Take the core of `getNextPC` out of it and move it to `getPC`, a
function returning both the current and the next PC. Also, fix a bug
when reaching the beginning of a basic block.
* Detect "reliable" jump targets: a "reliable" jump target is a jump
target obtained from a store to a PC but it's not a fallthrough jump.
`unknownPC` is an extern function we expect to be linked to the output
which is called when we have to crash due to an unexpected jump target.
* Remove unused references to register variables, now only need the
stack pointer
* Fix bug in how the auxiliary values were pushed on the stack.
* Push 0 HW_CAPs
* Implement some glib's functions
Since one of our requirements is to have all the accesses to the CPU
state explicit, we used to modify the helper functions depending on the
parameters used to call them. This was fine when we were supporting a
reduced set of helpers, but now this is not acceptable since the calling
code can call helpers in different ways. We circumvent the problem by
creating a distinct function specialization for call.
This patch implements `VariableManager::storeToCPUStateOffset` and
`VariableManager::loadFromCPUStateOffset`, which handle in a single
point all the accesses by offset to the CPU state.
* `getTypeAtOffset`: introduce a feature to easily debug how we compute
which field is at a specified offset in the CPU state (`--debug
type-at-offset`).
* Let `getTypeAtOffset` and its wrappers return the offset inside a
field of the CPU state (useful when accessing the third byte of an
integer).
* Use a dedicated class for the `CorrectCPUStateUsage` worklist
If before a call to an heper the PC is saved, it means that the helper
can change the PC, therefore we need to go the dispatcher on return. In
this case, we also have to force the PC after the call to be a jump
target.
When we meet a new PC from the PTC input, find immediately the next PC.
This makes the information available early and removes the necessity for
`closeLastInstruction`.
Give a new, useful, meaning to the `--entry` parameter: it's new purpose
is to be able to easily try to translate the code at a certain address.
In this sense, prevent global data harvesting if `--entry` is specified.
The handling of GVN options has also been improved.
Implement producing a CSV file containing information about the which
PCs have been translated. For each PC it is specified whether its a jump
target or not.
Pass local temporaries' allocas as parameters to newpc, so they can't be
promoted to SSA values by SROA, which creates problem when a basic block
must be split between a use and a def of such a value.