Commit Graph

2366 Commits

Author SHA1 Message Date
Andrea Gussoni 20a419cff2 WeightTraits to expose a generic object weight
The method which computes the weight for a `BasicBlockNode` now relies
on a new `WeightTraits` which is specialized for `BasicBlock` and for
`DotNode`.

In this way, we can change the implementation of the `getWeight` method
without having to modify the implementation inside the `revng` project.
2019-05-24 15:36:45 +02:00
Alessandro Di Federico 5009074e9e Introduce AdvancedValueInfo for JT discovery
* Introduce `ShrinkInstructionOperandsPass`: a transformation shrinking
  operands and the results of instructions if they are
  zero/sign-extended immediately before and after the instruction.
* Introduce `ConstantRangeSet`: similar to `ConstantRange` but allows
  disjoint ranges.
* Introduce `MaterializedValue`: a class that can represent a constant
  value or a symbol plus offset pair.
* Introduce `DropHelperCallsPass`: a transformation removing calls to
  helpers and replacing them with a function call reading the CSVs that
  the helper reads and writing the CSVs that the helper writes
  (according to CSAA).
* Introduce `DropRangeMetadataPass`: a transformation dropping the
  `range` metadata, which, in certain situations, lowers the quality of
  the results provided by `LazyValueInfo`.
* Introduce `AdvancedValueInfo`: an analysis exploiting results of
  `LazyValueInfo` but collecting them as `ConstantRangeSet` with a
  monotone framework. It produces `MaterializedValue`.
* Anticipate linking of helpers: `AVI` requires `CSAA`, which requires
  helper functions to be linked in.
* Drop `--no-link`.
* Force x86-64 `DataLayout`.
* Reorganize harvesting to either collect simple literals or go with
  (incremental) `AVI`.
* Drop `SET`, `OSRA`, the reaching definition analysis, the
  `SimplifyComparisonsPass` and all the sumjump-related code: e now
  clone `root`, optimize it and analyze it with `AVI`.
* Temporarily drop the `NoReturnAnalysis`.
* Link `libLLVMInstCombine`, `libLLVMCodeGen` and `libLLVMPasses`.
* Introduce tests for `AdvancedValueInfo`,
  `ShrinkInstructionOperandsPass` and `ConstantRangeSet`.
* Fix test results.
* Add `llvm.bswap.i64` and `@pc` to the LLVM template module for unit
  tests.
2019-05-22 21:30:29 +02:00
Alessandro Di Federico c8998cdece StackAnalysis: election of return SP value
Any stack pointer value greater than or equal to the original one used
to be OK for stack analysis to recognize an instruction as a
return. This commit changes this policy by collecting the value of the
stack pointer on all the return points and, at the end, elect a final
stack pointer value. All non-compliant returns are marked a
`BranchType::BrokenReturn`. The function is now considered fake only if
all the return instructions agree on a specific value of the stack
pointer, and it's lower than the original one.

* Drop `BranchType::IndirectTail`.
* `s/BranchType::FunctionSummary/BranchType::RegularFunction/`.
2019-05-22 21:30:29 +02:00
Alessandro Di Federico a9de053243 Introduce GraphAlgorithms
A series of algorithms working on `llvm::GraphTraits`.

* `nodesBetween` computes the set of nodes on all the paths from a node
  A to B.
* Factor out code to iterate over infinite loops into
  `exitless_scc_range`.
* Introduce unit tests.
2019-05-22 18:42:32 +02:00
Alessandro Di Federico 467d25693e MonotoneFramework: support user-provided BB list
Let the user provide the list of the basic blocks to visit, in a
specific order. This is useful when the same graph has to be visited
multiple times to avoid having `MonotoneFramework` recompute the reverse
post order each time.
2019-05-22 18:42:32 +02:00
Alessandro Di Federico 0e9d453be3 ZipMapIterator changes
* Introduce `KeyContainer::compare` and drop the `getKey` method.
* Let users of ZipMapIterator specify a trait class instead of using the
  default one.
2019-05-22 18:42:32 +02:00
Pietro Fezzardi e5e7d760e7 Improve debug print for nullptr Value * 2019-05-21 16:46:20 +02:00
Alessandro Di Federico 6ae3b6f22f Whitespace and other minor changes
* `GeneratedCodeBasicInfo::getCSVUsedByHelperCall` and
  `GeneratedCodeBasicInfo::extractCSVs`: make the call argument an
  `Instruction`.
* Introduce `blockByName`
* Introduce `getUniqueUser`.
* Fix linking issues.
2019-05-14 16:27:13 +02:00
Andrea Gussoni 603b80e695 getWeight implementation for BasicBlockNode
Implement a new `getWeight` method for the `BasicBlockNode` class.
This method is later used in the `untangle` pass to obtain an estimate
of the weight in terms of original instructions of the node under
analysis.

In case of a collapsed node the method recursively explore all the
collapsed region and return the sum of the weights of the nodes
composing the collapsed region.
2019-05-10 17:55:55 +02:00
Andrea Gussoni b2deb54dea Improve weight computation
Improve the computation of the weight for the nodes between the
immediate postdominator and all the exits from the region.

To do this we exploit the `findReachableNodes` helper function, since at
this point all the exits from the region are connected to the `Sink`
node.
2019-05-10 17:55:55 +02:00
Andrea Gussoni 1bca91fff9 Fix untangle when postdominator direct successor
Fix the untangle optimization when the immediate postdominator is an
immediate successor of the conditional node that triggered the inlining.
2019-05-10 17:55:55 +02:00
Andrea Gussoni 8095e1851c Handle CheckNodes in the untangle
Handle the cloning of the `CheckNode`s and their successors during the
untangle optimization.
2019-05-10 17:55:55 +02:00
Andrea Gussoni 7df3a13629 Untangle first draft
Introduce the untangle pass.

This preprocessing phase is in charge of the untangling optimization.
This optimization searches for conditional node, where, if a branch is
completely inlined (i.e., the entire path until reaching the exit is
duplicated and directly attached to it) we can save duplication in the
combing phase.

The untanle is based on a euristics, which consists of estimating the
duplication that could be introduced by the combing (computing the
weight for the nodes not dominated from the conditional node, of both
branches), with respect to the weight of duplicating the path that will
be inlined (the weight of all the nodes of the branch inlined plus the
weight of the nodes from the immediate postdominator of the conditional
until the exits).

The current implementation of the untangle is very conservative (no
untangle is performed if the `then` and `else` branches share some
nodes, or if there isn't at least one of the two branches which
dominates all the nodes until the postdominator).

The euristics also does not take into consideration the weight for
collapsed nodes.
2019-05-10 17:55:55 +02:00
Andrea Gussoni 560aaac9c8 New comb implementation
Implementation of the `comb` algorithm without dominator and
postdominator trees.

The comb now uses a list of nodes kept in reverse postorder (and updated
at each dummy insertion, node duplication and node removal), and various
sets of nodes that contains elements still to eplore under a certain
conditional node, nodes already visited, and so on.

Also the set of immediate post dominator (the point at which the comb
stops during its exploration) is computed only once at the beginning of
the algorithm, and simply kept updated at dummy insertion and removal.

The phase that checked if a conditional node dominates all the nodes
until the postdominator, has been replaced by a check which looks if all
the predecessors of a certain node have been visited during the current
exploration (which is perfomed in reverse postorder). If this condition
does not verify, it means that there is an incoming arc incoming in the
node under analysis which is not dominated by the current conditional
node.

There is still margin for improving the performance of this, this is
only a first implementation.
2019-05-10 17:55:22 +02:00
Andrea Gussoni 60e8c4a507 Add file serialization for decompiled functions
If the `-decompiled-prefix` is passed to the `revng opt` command the
decompilation pass takes care of serializing the decompiled code of each
function in a different file.

The filename is composed by the prefix string passed as parameter and by
the function name.
2019-05-10 17:37:18 +02:00
Pietro Fezzardi b058c326c6 Enforce coding style 2019-05-08 17:40:53 +02:00
Pietro Fezzardi 8ab637df8a Fix missing default statements from switches 2019-05-06 11:19:41 +02:00
Pietro Fezzardi de7089cbc4 Handle breaks from loops from within switches 2019-05-06 11:19:41 +02:00
Pietro Fezzardi 08f68994bd Add SwitchBreakNodes in fixSwitchBreaks() 2019-05-06 11:19:41 +02:00
Pietro Fezzardi 0d38a5cc8d Remove unused member function from ASTTree 2019-05-06 11:19:41 +02:00
Pietro Fezzardi a946f2ba9a Add SwitchBreakNode 2019-05-06 11:19:41 +02:00
Andrea Gussoni e8ad1e542b Fixes and improvements suggested by MR 2019-05-03 15:46:07 +02:00
Andrea Gussoni dee4db8216 DOT and AST only enabled in debug mode
To avoid skeing the results the serialization of `DOT` intermediate file
for both restructuring and AST semplification passes are now serialized
only when the corresponding loggers (`CombLogger` and `BeautifyLogger`)
are enabled.
2019-04-24 16:21:34 +02:00
Andrea Gussoni 3e18b199bb Use DotFileObject library provided in revng
Now use the `DotFileObject provided by `revng` instead of using our own.
2019-04-23 16:35:37 +02:00
Andrea Gussoni 2999e442c4 Move internal SetNode before extern CheckNode
When a retreating edge involves as source node a `SetNode` belonging to
an internal region (which should be the default `SetNode` that remains
outside the collpased node), move it just after the `CheckNode` that is
being introduced, so that the semantics of the code remains untouched.
2019-04-23 14:37:13 +02:00
Andrea Gussoni 616c162523 DotGraph and DotNode
This commit implements a simple wrapper class able to parse a GraphViz
file in an object implementing the LLVM `GraphTraits`.
2019-04-22 05:40:27 +02:00
Andrea Gussoni 0bbfeff053 clang-format 2019-04-19 12:30:13 +02:00
Andrea Gussoni cfa2ba41f4 Use llvm::SmallString' for BBNode` name field
Use a `llvm::SmallString` for the `Name` field of `BasicBlockNode`.
This enables us to modify the name of the node, which is very useful
during debugging and manual inspection of the graph serialized in
output.
2019-04-19 12:13:22 +02:00
Andrea Gussoni 485a253dec Improve serialization on files 2019-04-19 10:34:31 +02:00
Andrea Gussoni abb72c3b23 Coding style and improvements in MR 2019-04-16 17:37:57 +02:00
Andrea Gussoni e6ec54c9bc Enforce const on member functions 2019-04-16 10:19:34 +02:00
Andrea Gussoni 95ddb2b36b BasicBlockNode and RegionCFG now template
`BasicBlockNode` and `RegionCFG` classes are now template classes. This
means that the `BasicBlockNode` class can be used as a generic wrapper
for any type of object in the original graph (it is usually used to wrap
a `llvm::BasicBlock *` for decompilation purposes, but in tests it can
be used to wrap a `DotNode` object) that implementes `GraphTraits`.
2019-04-15 17:30:37 +02:00
Andrea Gussoni 6574255e8a Improve StringRef use for BasicBlockNode
Improved the interaction with the `StringRef` name field of
`BasicBlockNode`.

In case of artificial nodes, the name is left empty and created
on-the-fly for serialization purposes.
2019-04-15 10:22:11 +02:00
Andrea Gussoni 20b380c0d1 NDuplicates passed as reference to Mark
Removed the computation of the information contained in the
`NDuplicates` prevously done in the `MarkForSerialization` pass, since
the information is now precomputed in the `RestructureCFG` pass and
exposed with a dedicated method.
2019-04-15 10:16:05 +02:00
Andrea Gussoni 076f7069de RegionCFG helpers for tests
Add a couple of method wrappers and helpers for the `RegionCFG` class,
which are necessary for the testing infrastructure.
2019-04-15 10:11:26 +02:00
Andrea Gussoni 479c6c5fb7 DotGrap class to load RegionCFG from .dot
Add a `DotGraph` and `DotNode` classes, which implements `GraphTraits`,
so that we can create a `RegionCFG` starting from a graph specified in
a `.dot` file.

The `DotClass` implements a minimal parser for graph specified in `.dot`
format.

The `.dot` should begin with the specification of the name of the graph
`digraph TestGraph {`, followed by an arbitrary number of lines which
specify the edges in the graph (no attributes allowed, e.g., `a -> b;`).
The file should end with a single line ending in `}`.
2019-04-15 10:11:26 +02:00
Andrea Gussoni 7a04f6e52f Add topological graph equivalence function.
Add helpers to test if two `RegionCFG` objects can be considered
equivalent.

This will be used in the test environment to check if the comb
transformation is consistent with the expected behavior.
2019-04-15 10:11:26 +02:00
Andrea Gussoni 2b53f04f31 Compute information about node cloning
Compute how many times an original `llvm::BasicBlock` has been
duplicated during the comb pass.
2019-04-15 10:05:17 +02:00
Andrea Gussoni 3aaf4d939e Update OriginalBB map when moving nodes.
Update the `OriginalBB` map (which will be later used for retrieving the
original basic block linked to a certain BBNode) during nested
`RegionCFG` creation and during flattening, which are steps that modify
the allocation of the `BBNode` objects.
2019-04-15 10:05:17 +02:00
Andrea Gussoni f4f877c569 Change SetNode interface 2019-04-15 10:05:17 +02:00
Andrea Gussoni 1c66c145cb RegionCFG::initialize method now template
The `RegionCFG::initialize` method is now a template method, which
accepts as input any kind of object which exposes the `GraphTraits`.

In this way we can build a `RegionCFG` object not only starting from
LLVM IR, which can be very useful for testing purpose.

Since we also removed the information about the original
`llvm::BasicBlock` inside the `BasicBlockNode`, we need to keep this
link to later feed this information to the GHAST in an external data
structure (potentially a `std::map`).
2019-04-15 10:04:40 +02:00
Andrea Gussoni afbb3531f5 Name of the BasicBlockNode is now a StringRef
The `Name` field of the `BasicBlockNode` class is now of
`llvm::StringRef` type instead of a simple `std::string`.
2019-04-15 10:03:08 +02:00
Andrea Gussoni 2c3056527d Remove any pointer to BasicBlock inside BBNode
The `BasicBlockNode` does not contain anymore any pointer to the
`llvm::BasicBlock` object that generated the `BasicBlockNode`.

This change is necessary for decoupling completely the `BasicBlockNode`
and `RegionCFG` classes from the LLVM IR, so that we can build up a
`RegionCFG` from any object which implements the `GraphTraits`.

The `RegionCFG` does not contain anymore a map between
`llvm::BasicBlock` and `BasicBlockNode`.
2019-04-15 10:03:08 +02:00
Pietro Fezzardi 743b2e522c Fix switches with empty cases 2019-04-12 18:25:15 +02:00
Alessandro Di Federico d75e5f3b6a Improve detection of external function calls
This commit enlarges the set of external function calls we
detect. Basically, instead of assuming that the instruction jumping to
the external function is the call, we now also consider instructions in
previous basic blocks, as long as there's only one possible path
backward.
2019-04-11 19:51:32 +02:00
Alessandro Di Federico d77ad08917 Drop leftover references to revamb 2019-04-11 17:44:39 +02:00
Andrea Gussoni 0afaa0412c Create new break/continue for each edge
Create a new `break` node for each outgoing edge from the SCS, and a new
`continue` node for each retreating edge.
2019-04-11 16:32:56 +02:00
Andrea Gussoni b1cf76ef4b removeNotReachables removes from MetaRegion
The `removeNotReachables` method now can take care of removing any
reference of the removed nodes from any `MetaRegion` which contains any
reference to it.
2019-04-09 20:12:41 +02:00
Andrea Gussoni 17d6256de7 Add isDAG method for RegionCFG
Added a new method which can be used to check that the `RegionCFG` under
analysis does not contain any cycle.
2019-04-09 20:11:04 +02:00
Pietro Fezzardi 3f01eed105 Fix setTrue, setFalse, and removePredecessor 2019-04-09 11:27:48 +02:00