Commit Graph

22 Commits

Author SHA1 Message Date
Alessandro Di Federico b3ba517c8b Minor whitespace fixes and cleanups 2017-08-12 16:56:23 +02:00
Alessandro Di Federico bfcd504448 Minor fixes to make clang happy 2017-03-31 10:10:16 +02: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 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 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 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
Alessandro Di Federico 1bbe758ea3 OSRA: heavily reduce constraint propagation
This commit reduces the amount of constraint we propagate. We do this in
two ways. First, by computing the set of all the instruction that will
ever be affected by the current instruction (recursively). Second, by
preventing propagation on constraints across function calls.

In quick test on `ls` compiled for MIPS we reduce the execution time by
55% of the peak memory usage by 68%. This makes me quite happy.
2016-12-08 21:56:11 +01:00
Alessandro Di Federico 5c619ab063 Introduce the GCBI and FCI passes
This commit introduces two new passes:

* `GeneratedCodeBasicInfo`: recovers from the IR some basic information
  like the size of delay slots in the input architecture, the name of
  the program counter and so on. It can also identify the type of a
  basic block (e.g., dispatcher, jump target...).  *
* `FunctionCallIdentification`: identifies function calls and injects a
  marker before the associated terminator instruction.

The idea of these two passes is to try to progressively move information
we used to keep in `JumpTargetManager` into the IR, so that it is more
easily accessible and passes do not need a reference to `JTM`.

In particular by having markers for function calls available during jump
target discovery we don't have to have duplicated and suboptimal
implementation of `isCall`.

This commit also introduce some additional helper functions and an
helper class to quickly.
2016-12-08 21:56:11 +01:00
Alessandro Di Federico c8806c7dae Improve the ConditionalReachingDefinitionPass
This commit reworks quite heavily the `ConditionNumberingPass` and the
`ConditionalReachingDefinitionPass`.

* Increase debugging information for both passes.

* `ConditionNumberingPass`: rename the concept basic blocks "defining" a
  condition to the concept of basic blocks "resetting" a condition.
* `ConditionNumberingPass`: add to the list of basic blocks resetting a
  condition also the basic block post-dominating all the branches
  associated to that condition. In this way,
  `ConditionalReachingDefinitionPass` will not propagate the condition
  after them.
* `ConditionalBasicBlockInfo::mergeDefinition`: merge policy for
  condition bits is now simply or-merging them.
2016-12-04 00:28:58 +01:00
Alessandro Di Federico 387f2c6688 Improve ConditionalReachingDefintionPass
This commit introduces the following feature in
`ConditionalReachingDefintionPass`:

* Propagation of conditions associated to branch instructions across
  basic blocks, unless a basic block defines them or the condition is
  being propagated by theh current branch.
* Before propagating a definition, sopress in it all the conditions
  defined in the target basic block.
* Before propagating a definition, force the condition being propagated
  by the current branch to be active in it and its opposite do be
  inactive.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico ec12b5ec0d ConditionNumberingPass: track the defining BBs
`ConditionNumberingPass` now also keeps track of which basic blocks
define the value of a certain condition. This helps the conditional
reaching definition analysis to reset all the definitions associated to
that condition when they are propagated to a basic block which defines
that condition.
2016-12-04 00:28:57 +01:00
Alessandro Di Federico d01ee1f437 Copyright notices, license and credits 2016-09-21 01:45:26 +02:00
Alessandro Di Federico 4acae6beed Limit propagation of reaching definitions
This commit handles two cases related to function calls where we want to
limit the propagation of reaching definitions. In the first case down
through function calls, in the second case back up through return
instructions.

For the call instructions, we choose to stop the propagation of reaching
definitions to the callee, since we assume each function should check
its arguments if they affect the control-flow. In particular, this
allows a larger coverage of the function body in case, being able to
enumerate all the calls, we consider dead code those parts that, in the
current program would nevere be executed. Right now we do it in all
cases, it would be more appropriate to do this only if the address of
the function is taken. Also, we should expand this also for tail calls.

For what concerns return instructions, a function called from a lot of
different locations in the code receives a huge number of reaching
definitions. If its close to a no-op, it will also propagate most of
them through the return path. This is an hack to limit how such
definitions spread around the code.

A proper solution, requires to detect the calling convention and allow
to propagate along return paths only return values.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico cc87ad607d Introduce NoreturnAnalysis
This commit introduces the `noreturn` analysis, whose aim is to detect
all the basic blocks the are doomed to lead to a `noreturn` syscall such
as `execve` or `exit`.

* Implement `NoreturnAnalysis`.
* Include and initialize in the `Architecture` data structure all the
  necessary information to detect `noreturn` syscalls. Specifically, the
  name of the QEMU helper for syscalls, the name of the register holding
  the syscall number and the syscall numbers representing `noreturn`
  syscalls.
* `ReachingDefinitionsPass`: make reaching definitions available both in
  reaching definitions mode and reached loads mode. This part needs
  further cleanup. We also might be willing to implement this with a
  `Boost.Bimap`.
* Use `SET` to collect information useful for the
  `NoreturnAnalysis`. Also restructure how the `OperationsStack` works
  to be more streamlined and keep track of multiple information about
  the instruction currently being tracked.
2016-09-17 15:33:57 +02:00
Alessandro Di Federico bdc0c221bd Consider AllocaInst in RDA 2016-09-17 15:33:56 +02:00
Alessandro Di Federico 51d73d6b18 Register analysis passes as such 2016-09-17 15:33:56 +02:00
Alessandro Di Federico 46fe86225b Free memory after analyses
* Clear all the data that's not part of the analysis results at the end
  of the `runOnFunction` method
* Clear all the data that's part of the analysis results when the
  `PassManager` tells us so (`Pass::releaseMemory`)
* Do not use the `clear()` method, since it doesn't release memory
* Add some debugging information
2016-09-17 15:33:56 +02:00
Alessandro Di Federico 7e8ac596b5 Minimize pathSensitiveMerge usage
Record amount of reaching definitions for each load, even in
`ReachedLoads` mode, so that we can run the `pathSensitiveMerge` only
when we're sure we've collected all of them.
2016-09-17 15:33:55 +02:00
Alessandro Di Federico 785e74dafe CRDP: use an hash table of SmallVectors for RD
In `ConditionalReachingDefinitionsPass` switch from a `std::vector` of
pairs to an `std::unordered_map` of `llvm::SmallVector`. This is a
non-negligible impact on performances.
2016-09-17 15:33:55 +02:00
Alessandro Di Federico 5671806fe0 Anticipate specializations in Reachingdefinitions
This commit fixes a bug preventing clang from compiling the code
correctly.
2016-09-17 15:33:55 +02:00
Alessandro Di Federico 475ed2390e Introduce ConditionalReachingDefinitionsPass
Three new passes have been introduced:

* `ReachingDefinitionsPass`: classical reaching definitions analysis
  working on load/stores with the main difference that a load without a
  definition behaves similarly to a definition and that we ignore
  certain basic blocks (i.e., the dispatcher).
* `ConditionNumberingPass`: goes through all the branch instructions to
  check if some of them use an equivalent condition, this is
  particularly useful to understand that consecutive ARM instructions
  using the same predicate are working on the same condition.
* `ConditionalReachingDefinitionsPass`: identical to
  `ReachingDefinitionsPass` but uses information from
  `ConditionNumberingPass` to stop certain definitions from reaching
  certain loads.

The first and the last analyses have `Reached*` variants which expose
information from the point of view of the definintion instead of from
the point of view of the load.
2016-09-17 15:33:53 +02:00