Commit Graph

904 Commits

Author SHA1 Message Date
Pietro Fezzardi 5d0f5fef71 Drop TransformIterator
LLVM already implements an analogous `mapped_iterator` type in
`STLExtras.h` header.  `llvm::mapped_iterator` has been used to
substitute `TransformIterator` in the project so that we don't need to
reinvent the wheel.
2020-02-27 12:28:28 +01:00
Alain Carlucci 469ef9cae8 Rename emit to flush in Debug.h
The `emit` keyword is used in Qt and, if the method is called `emit`,
rev.ng headers cannot be included in a Qt project.
2020-02-27 12:12:25 +01:00
Pietro Fezzardi 890be7d6a2 Uniform dumpToString interface
Before this commit, the `dumpToString()` function defined in
`include/revng/Support/IRHelpers.h` was only defined with arguments of
type `const llvm::Module *` and `const llvm::Value *`.
This is not very ergonomic, because lots of types in LLVM have a
`print()` method that dumps the representation on a
`llvm::raw_ostream``.

This commit introduces function templates to handle all possible types
in LLVM that have a method `void print(llvm::raw_ostream &)`.

The templates are defined so that they should work with every possible
combination of references and pointer types, along with const
qualifiers.

To achieve this, the code makes use of `std::enable_if`` to provide
different definitions of the `dumpToString()` template helper function,
which only participate in overload resolution for specific types:
1. for `llvm::Module` and `llvm::Function`, which share the same
prototype for the `print()` method
2. for `llvm::Value` which has yet another prototype for the `print()`
method
3. for all other types that provide a method with the signature
`void print(llvm::raw_ostream &)`.

The last implementation (3) also works for all non-LLVM types provide a
method with the signature `void print(llvm::raw_ostream &)`.
In this sense, if in the future we want our own type to be easily dumped
to string (handy for logging), we can just implement the method
`void print(llvm::raw_ostream &)` and the `dumpToString()` function
template added in this commit will work out ot the box.
2020-02-27 11:55:09 +01:00
Andrea Gussoni 0c05c0c75b AVI: handle ConstantPointerNull and UndefValue
Handle `ConstantPointerNull` explicitly in Advanced Value Info, instead
of trying to obtain the analysis result for its operand (which is by
design a `nullptr`).
2020-02-27 11:55:09 +01:00
Pietro Fezzardi 433ce5613b Drop old useless header MemoryAccess.h
This was a leftover from the OSRA era.
2020-02-27 10:48:17 +01:00
Pietro Fezzardi ae948500eb Move LLVM header where it's really needed
Before this commit, the header `revng/Support/DebugHelper.h` could only
be included after explicitly including
`llvm/IR/AssemblyAnnotationWriter.h`, since `DebugHelper.h` used the
LLVM class `AssemblyAnnotationWriter`, that is not defined in
`DebugHelper.h`.

This commit includes `llvm/IR/AssemblyAnnotationWriter.h` directly into
`revng/Support/DebugHelper.h`, which can now be included alone without
compilation errors.
2020-02-27 10:47:07 +01:00
Pietro Fezzardi 58428bdd4a IteratorWrapper: use implicit copy constructor 2020-01-27 11:29:01 +01:00
Pietro Fezzardi 67e762d668 Add breaks to switch to remove warnings 2020-01-27 11:29:01 +01: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 0eb1bb583f Remove TerminatorInst
LLVM 9 drops the `TerminatorInst` class. This commit replaces it with
`Instruction` where possible and asserts
`Instruction::isTerminator()`. It also switches from
`TerminatorInst::successors` to `successors(TerminatorInst *)`.
2019-11-21 20:50:55 +01:00
Alessandro Di Federico 3818a4fcc6 Drop ConstantRange::ConstantRange
LLVM 9 prevents us from using the `ConstantRange` constructor. This
commit switches to use factory methods.
2019-11-21 20:50:03 +01:00
Alessandro Di Federico e445201b94 Restore getBasicBlockPC and fix FunctionIsolation
This commit restores the old implementation of `getBasicBlockPC` (which
was changed in an incompatible and wrong way) and fixes the bug the
original change tried to fix: in function isolation, jumping from a
function to a basic block that doesn't start with `newpc` now leads to a
basic block containing an `unreachable`.
2019-05-28 17:03:30 +02:00
Alessandro Di Federico b9ef70c8dc AdvancedValueInfo: handle pointer types 2019-05-27 19:36:12 +02:00
Alessandro Di Federico 877ba895af Rewrite get{BasicBlockPC,PrevPCWrite}
This commit reimplements `getBasicBlockPC` and `getPrevPCWrite` using
`BackwardBFSVisitor`, making them much more effective.
2019-05-27 19:36:12 +02:00
Alessandro Di Federico d0e5f61b20 CSAA: allow recursion in untainted paths 2019-05-27 19:36:12 +02:00
Alessandro Di Federico 7815c551db Support for file names in Logger
`Logger` can now print the file name from which it was called
(`--debug-location-max-length`).
2019-05-27 19:36:12 +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 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
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
Pietro Fezzardi 76135b76fb Add RemoveDbgMetadata FunctionPass 2019-03-08 15:00:59 +01:00
Alessandro Di Federico 9b070d8856 SA: use deque were appropriate
In certain locations we were using a `std::vector`, taking a reference
to it, adding elements and ending up in a reference invalidation issue.

This commit replaces those `std::vectors` with `std::deque` which do not
present this issue.
2019-03-08 15:00:59 +01:00
Alessandro Di Federico 467d916aac Ignore pc and sp in ABI analysis
They are not really part of the ABI.
2019-03-08 15:00:59 +01:00
Alessandro Di Federico 5dc8056b8c Introduce enforce-abi pass
This commit introduces the `enforce-abi` pass, which consumes the
information provided by the ABI analysis and enforces them in the
isolated functions adding actual arguments.

This commit also rewrites the logic of `ResultsPool::finalize` and
changes the semantic of `Yes` statements on arguments to `YesOrDead`.
2019-03-08 15:00:59 +01:00
Alessandro Di Federico 2bd8c468bc Introduce empty-newpc pass
`empty-newpc` is a simple pass suppose to provide an empty body for
the `newpc` function, allowing further optimization pass to take out
all its calls.
2019-03-06 10:31:23 +01:00
Alessandro Di Federico cb2bd9a3ce IRHelpers: introduce getCallToHelper 2019-03-06 10:31:23 +01: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 7476eb5cbf MonotoneFramework: allow successors in final BBs
This will be necessary to correctly handle infinite loops.
2019-03-06 10:31:23 +01:00
Alessandro Di Federico b232678477 GCBI: collect and expose ABI registers 2019-03-06 10:31:23 +01:00
Alessandro Di Federico b7b82a55a9 Marker functions: add the function isolation ones 2019-03-06 10:31:23 +01:00
Alessandro Di Federico 52f847a4df IRHelpers: introduce getName(Function *) 2019-03-06 10:31:23 +01:00
Alessandro Di Federico 103df1e46c Backward BFSVisitor: include starting instruction
The `BFSVisitorBase` can go forward and backward starting from a certain
instruction. When going backward, it used to skip the starting
instruction.

For simmetry purposes, this commit changes that.
2019-03-06 10:31:22 +01:00
Alessandro Di Federico 2d521285bb Handle helper functions in StackAnalysis
In the stack analysis, we used to consider helper functions as indirect
calls. However, the `CPUStateAccessAnalysis` provides us accurate
information about what an helper function does.

This commit transforms calls to helper functions in a series of ABI IR
instructions reading all the input registers of the helper functions and
a series of instructions writing the output registers.

Note that, while this is a serious improvement over considering them
indirect function calls, it's still suboptimal since
`CPUStateAccessAnalysis` doesn't provide us information as fine-grained
as the ABI analysis.
2019-03-06 10:31:19 +01:00
Alessandro Di Federico 17b1eb19a9 Introduce revng.csv for listing CSVs
Previously, to enumerate all the CSVs we had to go through the
`GlobalVariable` of a `Module` and see if the were being used in
rev.ng-generated code.

Now we have a named metadata for that: `revng.csv`.
2019-03-06 09:04:58 +01:00
Alessandro Di Federico 75914742d7 Use BlockType by name in metadata
We used to save the type of a block in the `revng.block.type` metadata
as a number. This commit serializes it as a string.

In order to do this, the `BlockType` enum has been promoted to a
namespace with the usual `getName` and `fromName` functions.
2019-03-06 09:04:58 +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 baa68faaf9 Fix linking erros with librevngSupport.so
`extern` declarations of template specializations for Logger<true> and
Logger<false> caused weak symbols to be emitted in librevngSupport.so
and into its users.
Dynamic loading then failed because both symbols were weak.
This commit removes the `extern` declarations so that dynamic loading
succeeds.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi 33a8aeb64c MonotoneFramework: drop greaterThan from Lattices
All the definitions of `greaterThan` were `!lowerThanOrEqual`, and all
the uses were implicitly assuming this semantic.
However, this was confusing because in a Lattice the ordering is not
total, hence `!lowerThanOrEqual` is not equivalent to `greaterThan`.

This commit drops the `greaterThan` method altogether to avoid
confusion.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi db2e4b5bdb Improve interface types for MonotoneSet 2019-03-06 09:04:58 +01:00
Alessandro Di Federico 773b33e5f5 Add InterruptCreator in MonotoneFramework
This commit introduces the helper templated struct InterruptCreator,
that is used to provide defaults for the methods
MonotoneFramework::createSummaryInterrupt() and
MonotoneFramework::createNoReturnInterrupt() whenever the Interrupt
template parameter for Monotoneframework is of type
DefaultInterrupt<LatticeElement>.
This frees the implementor of a new MonotoneFramework from the need
to implement those methods in the most common cases.

Whenever Interrupt is DefaultInterrupt<LatticeElement>,
MonotoneFramework::createSummaryInterrupt() aborts, since a summary
should never be generated for those kind of analyses.
Instead, MonotoneFramework::createNoReturnInterrupt() generates a
default Interrupt, since it will never be used.
2019-03-06 09:04:58 +01:00
Alessandro Di Federico 8c49f47f26 Use DefaultInterrupt<LatticeElement> as default
In most cases, a user of MonotoneFramework does not need a
interprocedural analysis, nor an analysis whose results on
terminal labels have to be aggregated in a FinalResults.
DefaultInterrupt<LatticeElement> is designed exactly for those
cases, and is hence used as default template parameter for
MonotoneFramework.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi d16e02a4c4 Add DefaultInterrupt template class
This class provides the simplest possible implementation for an Interrupt
for a Monotone Framework.

In particular this interrupt is suitable for MonotoneFrameworks that are NOT
interprocedural, and that DO NOT need to combine all the results on the
terminal labels at the end of the analysis in a single FinalResult.

With these assumption, the resulting Interrupt is pretty simple and it just
forwards the results of the transfer function.
2019-03-06 09:04:58 +01:00
Pietro Fezzardi 186b2d9a07 Rename isReturn method to isPartOfFinalResults 2019-03-06 09:04:58 +01:00