Commit Graph

1642 Commits

Author SHA1 Message Date
Alessandro Di Federico ce09875c36 Make translateIndirectJumps private
`JumpTargetManager::translateIndirectJumps` has been pushed into
`JumpTargetManager::finalizeJumpTargets`. Moreover, an safety check
about the removal of `exitTB` has been introduced.
2017-08-12 16:56:23 +02:00
Alessandro Di Federico b1590dfd6d Record stack register in architecture description 2017-08-12 16:56:23 +02:00
Alessandro Di Federico 355b8c8ad3 Tag the default case of the dispatcher
The basic block handling the default case of the dispatcher used not to
be tagged with `revamb.block.type`, now it is.
2017-08-12 16:56:23 +02:00
Alessandro Di Federico 9c0c9995dd Improve the QueueImpl API
This commit introduces the `head` and `clear` methods for `QueueImpl`
(i.e., `UniquedQueue` and `OnceQueue`).
2017-08-12 16:56:23 +02:00
Alessandro Di Federico cf6e02bbef Several new helper functions
* QuickMetadata has been expanded to get a `MDString` or a `MDTuple`
  from a `StringRef`.
* Introducing `skipCasts`, which, given a `Value`, returns the innermost
  part of the expression, skipping over casts.
* Introducing `isCallTo`, which, given an `Instruction`, returns whether
  it's a call to a specific function or not. `getCallTo` is a sister
  function to be used in `if` statements.
* Moving `skip` and `erase_if` in `ir-helpers.h` so that all the
  translation unit can benefit from their usage.
2017-08-12 16:56:22 +02:00
Alessandro Di Federico 9cb8d45552 Indirect function calls might end with unreachable 2017-08-12 16:56:22 +02:00
Alessandro Di Federico 45c02dc1a2 Drop alloca's bitcasts
`alloca` instruction are passed as variadic arguments to `newpc` to
prevent the optimizer from moving code around them. We used to cast them
all to `i8*`, however these casts where breaking the convention of
having all the `alloca` instructions at the beginning of the function.

Since these casts were not really necessary, they have now been dropped.
2017-08-12 16:34:40 +02:00
Alessandro Di Federico f5a950ad26 Move assertModuleIsMaterialized to debug.cpp 2017-08-12 11:28:07 +02:00
Alessandro Di Federico cad55f6331 Export jump target reasons in metadata
This commit introduces a new metadata (`revamb.jt.reasons`) containing a
list of reasons why the initial PC of the current basic block has been
identified as a jump target.
2017-08-01 09:14:01 +02:00
Alessandro Di Federico b6702d6ea7 Tag return basic blocks with func.return metadata 2017-08-01 09:14:01 +02:00
Alessandro Di Federico 1f1ca01df5 Set pipefail in the translate script 2017-08-01 09:00:47 +02:00
Alessandro Di Federico 9db62b288c Handle .bss-only data segment
This commit fixes an assertion triggered by the fact that a segment
includes exclusively zero-initialized data (i.e., size on file is 0,
memory size is not). In this case LLVM detects the fact that the global
variable associated to the segment is composed exclusively composed by
0s and uses a `ConstantAggregateZero` as an initializer instead of a
`ConstantDataArray`.

Currently the solution is ignore that data, however, in the future it
might be beneficial to be able to read data from `.bss`, even if we just
have zeros there.

Thanks to Thorbjoern Schulz for reporting this bug.
2017-07-07 15:39:01 +02:00
Alessandro Di Federico 4c8689016b Set default stack size to 16 MiB 2017-04-27 16:46:22 +02:00
Alessandro Di Federico 24c1df3540 Fix GCC 6.3.0 warnings
This commit fixes some warnings given by GCC 6.3.0.

* Some `assert(false)` are not recognized as `noreturn`ing. They have
  been replaced with `llvm_unreachable`.
* Added `-Wno-ignored-attributes`: attributes are not part the function
  name mangling, and therefore they might create some problems when they
  are involved in template arguments. We don't care.
* Specializations of `readPointer` functions in `binaryfile.h` are now
  `inline`, so they don't appear as "unused" functions.
2017-04-22 00:26:55 +02:00
Alessandro Di Federico f92ccfa54d Merge delay slots into branch instruction
QEMU marks each input instruction with a special
pseudo-instruction. This commit makes revamb ignore such instructions
coming after a write to a `btarget` variable, which is an indication
that a delay slot is starting. In this way, the instruction will look
larger and re-translating part of it will not break the branch
instruction.
2017-04-06 15:41:30 +02:00
Alessandro Di Federico c6aeebe889 Merge branch 'feature/support-spec' 2017-04-04 16:44:57 +02:00
Alessandro Di Federico e031583308 Set CSVs linkage to internal
This simple commit should improve performance of the generated program
sensibly. Basically all the global variables will have internal linkage
from now on (unless the `--external` parameter is specified on the
command line). This way, the compiler will be able to avoid load/store
instructions when leaving code in the current translation unit.
2017-04-03 15:57:50 +02:00
Alessandro Di Federico e01f0cc28d Bugfix: use opt output in translate
In `translate -O2` we optimize the LLVM IR both with `llc` and
`opt`. However due to a bug in `translate`, `opt` was invoked but its
output was never used.
2017-04-03 15:25:42 +02:00
Alessandro Di Federico 12ed8219da Disable slow backend optimization
Introduce the `-disable-machine-licm` argument when the `translate`
script invokes `llc` with `-O2`.
2017-04-03 13:57:56 +02:00
Alessandro Di Federico 0ba8bb80e2 OSRA: clear BoundedVvalue::Bounds before merging
We used to assert that a `BoundedValue` must not have any entries in the
`Bounds` field before translating a `boost::icl` interval to a
`BoundedValue`. However, if the `Value` associated to the `BoundedValue`
is a `Constant`, we might have an entry in `BoundedValue::Bounds`
immediately after constructing the object. This commit fixes this
problem by simply updating the assertion and clearing the field before
re-populating it.
2017-04-02 17:10:39 +02:00
Alessandro Di Federico d4168436db Install documentation
This commit introduces a docs target which translates `.rst` files into
man pages or HTML documents and installs them in `/usr/share/man/man1`
or `/usr/share/doc/revamb`.
2017-03-31 16:14:15 +02:00
Alessandro Di Federico 89d49789fb docs: reflect recent changes to root and linking
Update `GeneratedIRReference.rst:` to reflect recent changes to the
`root` function. Specifically, the presence of the stack pointer
argument and initialization of the program counter and the stack
pointer.

`FromIRToExecutable.rst` has been updated too, to take into account the
new way we link `support.c`.

Finally, the `--tracing` argument has been removed from
`RevambUsage.rst` and the `-trace` argument is no documented in
`TranslateUsage.rst`.
2017-03-31 16:12:14 +02:00
Alessandro Di Federico 3c2e779159 Merge branch 'feature/exception-handling' 2017-03-31 10:11:32 +02:00
Alessandro Di Federico bfcd504448 Minor fixes to make clang happy 2017-03-31 10:10:16 +02:00
Alessandro Di Federico e540400f14 Fix typo in CMakeLists.txt
To compare strings, `STREQUAL` should be used, not `EQUAL`. This
prevented some inaccurate GCC warnings to be considered as non-errors.
2017-03-31 10:10:16 +02:00
Alessandro Di Federico 6d9b0c4354 SET: use the appropriate type while materializing
While materializing values in SET through the `OperationStack` we used
to use as a type the type of the value associate to the currently used
`BoundedValue`. This was wrong, this patch uses the type on the free
operand on the top of the `OperationsStack` to perform the required
computations.
2017-03-31 10:10:16 +02:00
Alessandro Di Federico d8f13c799d Detect try/catch landing pads
Landing pads are basically the `catch` blocks in C++ `try`/`catch`
statements. So far we were missing them since they are encoded in a
particular way in a way similar to DWARF debugging information in the
`.eh_frame` and, more specifically, in the `.gcc_except_table` sections
of ELF programs.

This commit parses these sections so that the basic blocks associated to
landing pads are correctly identified. Personality functions are
detected too. A test is also introduced to assess the effectiveness of
our code.
2017-03-31 10:10:16 +02:00
Alessandro Di Federico c81dd3231a Merge branch 'feature/disjoint-ranges' 2017-03-31 10:09:06 +02:00
Alessandro Di Federico 815c72a417 OSRA: introduce a new test for disjoint ranges
Since we now support disjoint ranges in ORSA, let's test it. This commit
also introduces some license disclaimers in tests assembly files.
2017-03-29 14:04:35 +02:00
Alessandro Di Federico 66ef40f9fe Rewrite OSRA::handleComparison
`OSRA:handleComparison` was too big and complex, it has been mostly
rewritten.

* Create `OSRA::identifyComparisonOperands` which expands the argument
  of the comparison in a list of possible values (constants or
  OSRs). The new way in which we handle possible operands also fixes a
  bug showing up in case a constant OSR was being compared with an LLVM
  constant, which was checked for being a tautology/contradiction,
  preventing the reaching definitions of the operand to be considered
  too.
* Squeeze more information from uge/ugt. Unsigned comparisons lead to
  two pieces information: the result of the comparison itself, and the
  fact the left-hand side is greather than or equal 0. This secondo
  information is precious, but we were not able to exploit it in the
  case the original comparison is already "greater than" or "greater
  than or equal". In fact, `x - 4 > 10` gives us `x >= 4` and `x > 14`,
  which boils down to `x > 14`.  This commit introduces a change that
  handles this case as `NOT x - 4 <= 10` leading to the negation of `x
  >= 4` and `x < 14` which is way more informative.
* Improve `OSRA::mergePredicate` and `OSRA::applyConstraints`
  interfaces.
* In case a comparison instructions leads to multiple constraints on the
  same `Value`, these constraints are now first or-merged together and
  then propagated. This change improves the quality of the analysis in
  certain situations.
2017-03-23 17:58:06 +01:00
Alessandro Di Federico 5b8fb1af14 BoundedValue: support for multiple ranges
This commit introduces radically changes the implementation of
`BoundedValue`: it no longer represents a single, contiguous range, but
an arbitrary number of ranges.

The bounds are now represented through a
`llvm::SmallVector<std::pair<uint64_t, uint64_t>, 3>`.

* Introduce the `BoundedValue::bounds()` method, which allows to iterate
  over all the ranges that a `BoundedValue` represents. The `bounds`
  method returns a `Bounds` object, which can be used as a range
  composed by `BoundsIterator`.
* All the methods dealing with the `BoundedValue`'s bounds have been
  rewritten.
* New debugging information: "bv-merge". Print all the computations
  performed by `BoundedValue::mergeImpl`.
* Drop dead code: `BoundedValue::setBound` and `isPositive`
* Introduce `BoundedValue::isRightOpen` and drop
  `BoundedValue::isSingleRange`
2017-03-23 17:58:05 +01:00
Alessandro Di Federico 4089c203fc Improve OSRA::pathSensitiveMerge
Some subtle bugs have been fixed in `OSRA::pathSensitiveMerge`:

* Do not alter the current `BoundedValue` if merging a component would
  lead to bottom.
* Do not deactivate a reacher in case an incoherent condition is met.
2017-03-23 17:58:05 +01:00
Alessandro Di Federico 1d967349bd ReachingDefinitionsPass: free loads are definers
In our reaching definition analysis we used to consider all the loads
not reached by any store as definitions. However we forgot to actually
register them as such, with the result that two consecutive loads from
the same CSV would end up being two free loads.
2017-03-23 17:58:05 +01:00
Alessandro Di Federico 244f0dc901 ConditionNumberingPass: last user, still user
In `ConditionNumberingPass` we used to consider as resetting the last
basic block possibly interested in a certain numbered
condition. However, what we really meant, was that its successors were
resetting basic blocks. This commit fixes this issue.
2017-03-23 17:58:05 +01:00
Alessandro Di Federico f409fd6546 OSR::constant(): consider Base and Factor
`OSR::constant()` used to forward the result of
`BoundedValue::constant()`, but this is wrong, since the factor and the
base value have to be considered too.
2017-03-23 17:58:05 +01:00
Alessandro Di Federico bddc0d03d6 OSRA: x | bottom = x, not bottom
or-merging bottom with anything used to produce a bottom value, which is
wrong. The non-bottom value should be produced instead.
2017-03-23 17:57:31 +01:00
Alessandro Di Federico 0f70a6ef8a Propagated constraints should be and-merged
Constraints associated to a memory instruction are propagated to
reached loads. However, if a constraint on the same `Value` is already
present, the new constraint should be and-merged, not or-merged.
2017-03-23 17:57:31 +01:00
Alessandro Di Federico ab160b039a Do not remove predecessors while iterating on them 2017-03-23 17:57:31 +01:00
Alessandro Di Federico 8bb3a38246 Minor improvements
* Introduce some additional helpers
* Spread some `const`ness
* Improve documentation
* New debugging information: "osr-bv". Prints every update operation
  performed in `BVMap::update`.
* Remove dead code
* Whitespace fixes
* Some new TODOs
* Fix some typos in comments
2017-03-23 17:57:30 +01:00
Alessandro Di Federico 850fc09a69 Switch BoundedValue::merge to boost:icl
This commit drops the original handcrafted implementation of
`BoundedValue` merging, in favor of an implementation based on Boost
intervals. The old implementation was the source of intermittend bugs,
using Boost should be a more reliable solution. Moreover, this commit
enables moves us towards supporting multiple ranges in `BoundedValues`.
2017-03-10 08:32:46 +01:00
Alessandro Di Federico af209172a6 BoundedValue: information hiding 2017-03-09 19:48:03 +01:00
Alessandro Di Federico 51019ddfba Minor fixes to BoundedValue::merge 2017-03-09 19:47:01 +01:00
Alessandro Di Federico fd10c8d880 Introduce OSRA::dump() 2017-03-09 12:05:59 +01:00
Alessandro Di Federico b21f3b1865 OSRA: track register+constant pointers too
In OSRA we used to track `GlobalVariable`s and `AllocaInst` only,
despite the `MemoryAccess` infrastructure supported memory accesses of
the type register + constant. Enabling this, we're able to handle the
following x86-64 snippet found in the `omnetpp` SPEC benchmark:

    cmp    DWORD PTR [rbx+0x8],0x5
    ja     elsewhere
    mov    eax,DWORD PTR [rbx+0x8]
2017-03-08 10:04:11 +01:00
Alessandro Di Federico 14f4cd74c9 Improve handling of load insturctions in SET
SET, when getting data from OSRA, used to check that the first and last
materialized address were within a certain range, under the assumption
that the last value would be greater that the first one. Turns out that
this is not always the case when in the operation stack we have a load
instruction. This commit improve the way such a situation is handled.
2017-03-06 14:31:30 +01:00
Alessandro Di Federico d398213aa2 Purge translated code in post-order
This commit changes the way instruction and basic block are purged when
re-translation is necessary. Specifically, the purge is now performed
through a post-order visit, which should prevent the removal of any
instructions still holding users.

This commit also introduces the `SubGraph` class, which is useful to be
able to navigate portions of a graph (e.g., a `Function`) in post-order
easily.
2017-03-06 14:31:30 +01:00
Alessandro Di Federico 87dc88c284 Reorganize OSRA
The main goal of this patch is to reduce the size of
`OSRAPass::runOnFunction()`. To do this we created the `OSRA` class
which handles everything `runOnFunction` was taking care of but without
the ugly lambdas nor being an endless function. Each class of
instruction is now handled by a dedicated function.

This also has the side effect of heavily reducing the amount of clutter
exposed by `OSRAPass` to its users.
2017-03-06 14:31:29 +01:00
Alessandro Di Federico 1e9163c73d Anticipate cpu_loop_exit removal
Fix of another bug showing up only with LLVM in debug mode: splitting a
malformed basic block is not allowed, and we had a function call after a
`ret` instruction.
2017-03-02 11:16:32 +01:00
Alessandro Di Federico 04a4591f5c When splitting a basic block, retranslate
This commit should fix some bugs due to the fact that when we're
splitting a basic block we don't retranslate the basic block at the
split point but preserve the existing code. This lead to problems, in
particular in x86-64 where certain QEMU local variables were not
available. This change should fix it.

Basically, every time we split a basic block in
`JumpTargetManager::registerJT` we note down that the new basic block
must be purged, and in `JumpTargetManager::harvest` we perform the
purge. `harvest` has been chosen since it's a particularly quiet moment,
i.e., there should be no pending references/iterator to code we have to
delete.
2017-03-02 08:21:11 +01:00
Alessandro Di Federico 7babafacc0 Fix deletion order of temporary parts in RDA
This commit fixes a bug that appears only with debug builds of LLVM: in
RDA we were erasing a temporary common predecessor basic block before
removing the references to it in a `switch` statement.
2017-03-02 08:21:11 +01:00