Commit Graph

13 Commits

Author SHA1 Message Date
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