Commit Graph

96 Commits

Author SHA1 Message Date
Pietro Fezzardi baeae84c65 UpcastablePointer: use std::is_void 2021-06-09 20:13:27 +02:00
Pietro Fezzardi b4395794dd KeyedObjectTraits: drop useless template parameter
The second template parameter, defaulted to void, was only used for
SFINAE with enable_if. Now that all uses of enable_if are gone replaced
by concepts, this parameter does not serve any purpose anymore.
2021-06-09 20:13:27 +02:00
Alessandro Di Federico 871931b9cd Test TupleTreeDiff on Model
`TupleTreeDiff` was not being tested.

This commit implements several `operator==` that are required to
successfully instantiate `TupleTreeDiff`.
2021-05-06 15:42:16 +02:00
Alessandro Di Federico e62f888381 Drop KeyTraits
This commit drops the KeyTraits in favor of a std::any-like solution.
Basically, we type erase any key the user wants to employ, just exposing
a virtual version of the destructor, a comparison operator and a clone
primitive.
2021-05-06 15:42:00 +02:00
Pietro Fezzardi b58693b8e8 RecursiveCoroutine: enable direct continuation
Before this commit, the execution logic of RecursiveCoroutine used an
underlying std::stack allocated on the heap to hold all the
coroutine_handles. It also manually managed passing return values from
callees to callers.

This commit drops this unnecessary auxiliary stack.
When a RecursiveCoroutine co_awaits another one, the handle of the
awaiter is injected into the awaitee, so that when the awaitee is done
it can directly execute the remaining part of the awaiter as a
continuation.
2021-05-05 17:48:04 +02:00
Alessandro Di Federico 0d77258109 Introduce HasKeyObjectTraits concept 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 508bc4eb00 Minor changes 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 6fd8a87572 TupleTree, visit: rename and make more usable 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 582dee6fcc TupleTree: support UpcastablePointer 2021-05-05 17:10:12 +02:00
Alessandro Di Federico 702f4230ac Import UpcastablePointer 2021-05-05 17:10:12 +02:00
Alessandro Di Federico a6468d8d22 Minor changes 2021-05-05 17:10:12 +02:00
Pietro Fezzardi 50681284c0 Conceptify revng
Use concepts across revng wherever possible, to keep the code concise
and easier to understand.
2021-05-05 17:10:12 +02:00
Alessandro Di Federico 694b76a8e2 GenericGraph: propagate graph properties to nodes 2021-04-22 18:03:53 +02:00
Alessandro Di Federico e3157ffdd4 GenericGraph: initialize EntryNode 2021-04-22 18:03:53 +02:00
Alessandro Di Federico 8a5cc6a020 Import TypeShrinking 2021-03-08 10:15:50 +01:00
Alessandro Di Federico 47e34bf897 Make MutableSet copiable
We were using a `std::map<const key_t, value_t>` as internal storage,
which was not copiable. This commit drops the `const`.
2021-03-06 16:56:25 +01:00
Alessandro Di Federico ee9f2192f3 KOC::batch_insert: return newly created object 2021-02-18 18:46:49 +01:00
Alessandro Di Federico 685dbfd3f7 Whitespace and other minor changes 2021-02-18 08:48:39 +01:00
Alessandro Di Federico 49287e9de7 Improve Model and TupleTree
This commit:

* Drops `KeyTraits::toString`: if needed, use `getNameFromYAMLScalar`.
* Makes many methods in TupleTree.h return `nullptr` or `std::optional`
  in order to gracefully handle failures.
* Provides `KeyTraits` specializations for integral types and tuple-like
  composed by types providing `KeyTraits`.
* Introduces `CompositeScalar`, which enables tuple-like objects to be
  YAML-serializable scalars by joining the YAML-serialization of its
  members through a customziable character.
* Implements `PathMatcher`, a very simple "regular expression" mechanism
  for paths on tuple trees.
* Introduce testing for the Model.
2021-02-17 11:48:46 +01:00
Pietro Fezzardi 8ffcd49dd2 RecursiveCoroutine: fix reference arguments
Before this commit, recursive coroutines did not work properly if they
had out arguments with reference type.
The reason is that `rc_run` was inferring the type of its arguments from
the arguments themselves, not from the prototype of the recursive
coroutine.

Hence, code snippets like the following did not work properly, because
`rc_run` was taking x by value, not by reference.

```
RecursiveCoroutine<void> accumulate_on_i(int &i) {
  // ...
}

int f() {
  int x = 0;
  rc_run(accumulate_on_i, x);
  return x;
}
```

This commit fixes the problem. Now the arguments of `rc_run` are
properly forwarded to the recursive coroutine.
2021-02-17 11:37:00 +01:00
Alain Carlucci 8e275ed957 ADT: Add SerializableGraph 2021-02-09 22:44:01 +01:00
Alessandro Di Federico 4982ba6922 KeyedObjectContainers: ensure serializability
This commit fixes a couple of bugs preventing SortedVector and
MutableSet from being serialized.
Also, it introduces minimal testing for serialization.
2021-01-28 17:45:14 +01:00
Massimo Fioravanti 8ba9930638 Invert inheritance of GenericGraph nodes
GenericGraphs no longer require CRTP.
2021-01-27 19:46:53 +01:00
Alessandro Di Federico 38031f2f8a Import preliminary model
This commit imports:

* support for (de-)serializing tuple-like objects in YAML
* the Model data structure
* the {Load,Serialize}ModelPass
2021-01-27 19:46:53 +01:00
Alessandro Di Federico 28cb935d39 ZipMapIterator: handle dishomogeneous containers
ZipMapIterator can now handle containers of different type, as long as
their keys are comparable.
2021-01-27 19:46:52 +01:00
Alessandro Di Federico 8aab914037 Import MutableSet and SortedVector
These data structures are substitutes for a `std::map<Key, Value>` where
`Key` is embedded in `Value`. Their main goal is to be serializable in a
YAML sequence while preserving the order enforced by the key.

`MutableSet` is implemented using a map.
`SortedVector` is implemented using a sorted vector.
2021-01-27 19:46:52 +01:00
Alessandro Di Federico 6359edebb7 GenericGraph: Node::has{Successors,Predecessors} 2021-01-26 17:44:21 +01:00
Alvise de Faveri 9eb9e9b1a1 ADT: fix neighbor constness for GenericGraph
Problem:
1. `ForwardNode::getConstNeighbor` returns a reference to a non-`const`
    object, but the referenced pointer is `const`
2. `FowardNode::toNeighborRange` checks if the type of the argument is
const, but since `Successors` is not declared const the resulting
`toNeighborRange(Successors)` is never executed in the const version

Solution:
1. Make `getConstNeighbor()` return a reference to a `const` pointer
2. Explicitly declare a separate `toNeighborRange()` function which
returns a `const_child_iterator` and remove the template parameter
2021-01-26 17:41:58 +01:00
Pietro Fezzardi e1b283b0b6 Add RecursiveCoroutine headers and tests
RecursiveCoroutines are a facility intended to be used as-drop in
replacement of recursive functions.

They provide the following features.
- They can be written almost as regular recursive functions,
  with 4 caveats.
  1. A recursive coroutine that returns a type `T`, needs to be declared
     to return a `RecursiveCoroutine<T>`.
  2. Inside the body of a recursive coroutine, when recursively calling
     another recursive coroutine, the recursive call needs to be
     prepended by the new keyword `rc_recur`.
  3. Inside the body of a recursive coroutine, the `return` statement
     needs to be substituted with `rc_return`.
  4. When launching a recursive coroutine `A` from a function that is
     not a recursive coroutine, `A` needs to be called with the provided
     dedicated template wrapper `rc_run`.
     The syntax is the following `rc_run(A, arg0, arg1, ...)`.
     This is necessary to enable swapping off recursive coroutine and
     fall back to regular recursion for debug.
     See below for how to do it.
- Unlike regular recursive functions, they don't use the system stack
  for recursion. They use a custom heap-allocated stack to manage
  recursion. This makes them more robust for implementing recursive
  functions that manipulate user-defined input, because they are much
  less likely to trigger stack overflow.
- They can be turned off compiling with
  `-DDISABLE_RECURSIVE_COROUTINES`, falling back to regular recursion,
  for debug purposes.
- They support both direct and indirect recursion, i.e. a recursive
  coroutine A can recursively call itself, or it can recursively call
  another recursive coroutine B, which in turns recursively calls A.
2020-12-29 16:15:31 +01:00
Pietro Fezzardi 9869f057b9 Use #pragma once for header include guards 2020-11-13 14:12:18 +01:00
Pietro Fezzardi cd9bc34d9d Enforce new include conventions 2020-11-13 10:00:24 +01:00
Alessandro Di Federico d72f69c975 Import GenericGraph
This commit imports `GenericGraph`, its tests and fixes some related
issues in `FilteredGraphTraits`.
2020-10-21 10:34:01 +02:00
Pietro Fezzardi 227e649175 Fix use of comparison parameter C in SmallMap 2020-06-14 23:51:36 +02:00
Pietro Fezzardi e4c8e7962a Make Iteratall a bidirectional iterator 2020-06-14 23:51:36 +02:00
Pietro Fezzardi 2bc5a52ef9 Iteratall: add constructors and public typedefs
These are necessary for this iterator to be a forward_iterator according
to the standard.
Missing these causes compilation errors in some cases when using
functions from the Standard Template Library with these iterators.
2020-06-14 23:51:36 +02:00
Pietro Fezzardi ddebd55629 Add FilteredGraphTraits with tests
This patch adds a two markers for llvm::GraphTraits:
 - NodePairFilteredGraph
 - EdgeFilteredGraph

Both these markers allow to specify a static predicate that is used to
filter edges.
This predicate is a boolean function such that:
  - for NodePairFilteredGraph, it takes a pair of const NodeRef & that
    are used to represent an edge, and it evaluates a given property of
    that pair;
  - for EdgeFilteredGraph, it takes a const EdgeRef & that represents an
    edge, and it evaluates a given property on the edge.
The filtered graph contains only the edges for which the predicate
evaluates true.

Notice that the predicate must have static lifetime, meaning that all
the edge properties must be entirely evaluated on the pair of node (for
NodePairFilteredGraph) or on the edge (for EdgeFilteredGraph).
This means that you cannot pass mutable state to the predicate at
runtime.

The new markers are designed to interoperate well with llvm::Inverse and
to allow you to traverse the marked graphs with llvm::depth_first,
llvm::inverse_depth_first, llvm::breadth_first, and to compute dominator
trees and post-dominator trees on filtered graphs.
2020-06-13 10:36:08 +02:00
Alessandro Di Federico 34d7a8e364 Let ConstantRangeSet::dump work on any stream 2020-05-14 11:59:05 +02:00
Alessandro Di Federico 8deab9c7ea Whitespace and other minor changes
* Drop unused argument names from function prototypes
* Make `static` some methods
* Disable some copy constructors
* Fix casing of Doxygen `\file` directives
* Add some casts to make the compiler happy
* Initialize `hasRelocationAddend` for AArch64
* Use references in range-for where possible
* Drop default for `switch` statements covering all the entries of an `enum`
* Make some global variables `static`
* Drop dead functions
2020-05-14 11:58:18 +02:00
Alessandro Di Federico b6658df052 Fix various warnings 2019-11-24 22:52:23 +01:00
Alessandro Di Federico 72f9c633d4 Make ConstantRangeSet LLVM 9-compliant
A `ConstantRange` such as `[5,0)` was not handled correctly in
`ConstantRangeSet` due to a spurious 0 at the end of the range.

This commit also fixes the testing infrastructure that was not checking
the size of the range before making the comparison with the reference
vector.
2019-11-21 23:50:59 +01: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 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
Alessandro Di Federico 0fa2d79fe4 Introduce ZipMapIterator
`ZipMapIterator` allows you to iterate in parallel over two
`std::map`-like containers.

In the ABI analysis, this allows us to be much more efficient. In
practice, if we have two maps with M and N elements, we pass from
performing N*log(N) + M*log(M) queries to the size of the union of the
set of keys of the two maps.
2019-03-06 10:31:23 +01:00
Alessandro Di Federico 45172f52d9 LazySmallBitVector: introduce operator<
`LazySmallBitVector` was lacking a comparison operator, which prevented
it from being used as the key of a `std::map`.

This commit implements such operator, along with the `reserve` method.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi f4603dc10c Add operator[] and at() members to SmallMap 2019-03-06 09:04:58 +01:00
Alessandro Di Federico 076aeac7f3 Move and rename all files
This commit moves around most files. The new directory structure is as
follows:

* `lib/$LIBRARY/`: contains a library, i.e., a set of `.cpp` files used
  by multiple libraries/tools.
* `include/revng/$LIBRARY/`: contains the public headers associated to
  the library in `lib/$LIBRARY/`.
* `tools/$TOOL/`: directory where all the `.cpp` files (and private
  headers) for a tool reside. Currently we have two tools: `revamb` and
  `revamb-dump`.

On top of this, all file names are now in camel case.
2018-10-03 23:11:12 +02:00