Commit Graph

41 Commits

Author SHA1 Message Date
Alessandro Di Federico 143c315196 Merge revng-c into revng 2024-11-21 10:50:55 +01:00
Alessandro Di Federico 36e2faad3d Introduce -Wunreachable-code-break 2024-10-31 17:19:55 +01:00
Andrea Gussoni 6af6c8ffa8 RemoveDeadCode: dead code removal beautify
We introduce a "dead code" optimization like pass on the AST.

The goal is to simplify away, in a `SequenceNode`, everything that
follows a node with sports a `nofallthrough behavior.
2024-05-07 14:17:05 +02:00
Andrea Gussoni 3763d781d3 InlineDispatcherSwitch: improve function signature 2024-05-07 14:17:05 +02:00
Andrea Gussoni 67e7b54eda BeautifyGHAST: reorder SwitchBreaksFixer pass
Delay the `SwitchBreaksFixer` beautify pass run.
Specifically, we run it last, as this pass computes information used
only by the backend, and the information it depends upon may be
invalidated by some passes that transform `switch`es (as the
`simplifyDualSwitch` pass).
2024-05-07 09:18:20 +02:00
Andrea Gussoni 0fb60b5c0c BeautifyGHAST: remove unused using 2024-05-07 09:18:20 +02:00
Andrea Gussoni f05723707f BeautifyGHAST: delay loop promotion passes
Delay as much as possible the loop promotion passes, in order to catch
more opportunities.

Specifically, we now perform the loop promotion after the dual case
`switch` promotion pass.
2024-03-26 17:08:20 +01:00
Pietro Fezzardi 70c8ae48ff Retire MarkAssignment for SwitchToStatements 2024-03-19 09:44:00 +01:00
Andrea Gussoni 55959f3fe5 InlineDispatcherSwitch: simplifySwitchBreak
Implement a new beautify pass which simplifies away `SwitchBreakNode`s
that constitute the entire body of `case`s in `switch`es, that do not,
have a `default` case. In such situations indeed, the semantics is,
preserved by removing the `SwitchBreakNode`s.
2024-03-15 14:50:42 +01:00
Andrea Gussoni 6c8d963f69 RestructureCFG: Reorganize debug graphs
Various improvements to the debug graphs for `restructure-cfg` and
`beautify`:
- Normalize casing and syntax of debug graphs.
- Improve the graph folders name and layout.
- Implement `CFGDumper` and `ASTDumper` for when we need a serialization
  with incremental indexes.
- Remove old and stale graph serializations.
2024-03-11 19:08:34 +01:00
Alessandro Di Federico 0c212b66d9 Relicense to MIT 2024-02-29 17:03:36 +01:00
Pietro Fezzardi 9db3c53f1e Convert FIXMEs to TODOs 2024-01-26 16:45:20 +01:00
Andrea Gussoni 078cc1222a InlineDispatcherSwitch: introduce beautify pass
We introduce the `InlineDispatcherSwitch` beautify pass. Its goal is to
try and inline the body of some of the `case`s of a exit dispatcher, in
place of the `SetNode` corresponding to that `case`, if this doesn't
introduce duplication in the code (i.e., a single `SetNode` for that
specific case value is present).

Additionally, if the inlining procedure is able to completely remove the
necessity of an exit dispatcher altogether, the pass removes it.

The pass is able to handle chains of weaved dispatcher `switch`es
referring to the same original dispatcher `switch`, by handling the
inline operation and the possible simplification level-wise.

The inlining procedure, cannot take place if a `SetNode` is contained in
the body of the case we are trying to inline, since this can possibly
break the semantics of the state variable of a loop, by placing a
`SetNode` in a more internal loop.
2023-11-28 16:19:08 +01:00
Andrea Gussoni ca422bafd2 PromoteCallNoReturn: introduce beautify pass
We introduce the PromoteCallNoReturn beautification pass. Its goal is to
restructure sequence of statements, in order to have `call`s to
`noreturn` functions as _inlined_ in the middle of the statement
sequence, and leave _non local control flow statements_ at the end of
that scope. E.g., we prefer:
```
if (cond)
  call noreturnfunc();
return;
```
to
```
if (!cond)
  return;
call noreturnfunc();
```

In order to do this, contextually, we restructure the routine computing
the `fallthrough` property, in order to be able to differentiate between
the _non local control flow statements_, a call to a `noreturn`
function, or a generic mix of the two (useful when combining results
from the two situations above).

The new analysis is also used in the `promoteNoFallThrough` promotion
pass.
2023-11-28 16:19:08 +01:00
Andrea Gussoni a8634b385c BeautifyGHAST: debug graph counter
Automatically compute the debug graph serialization indexes in the
beautify phase.
2023-11-28 16:19:08 +01:00
Pietro Fezzardi deddbda41d BeautifyGHAST: match do-while before while loops
This commits reorders the beautifiers so that do-while loops are matched
before while loops.
This has the effect that loops that can be matched both as while and
do-while loops end up matched as do-while.
The consequence is that we generate C code with a layout that is much
more similar to assembly, and prevents duplicating code to recompute the
condition of the while.
2023-11-28 15:46:19 +01:00
Pietro Fezzardi 24c9fbe3fb Fix emission of do-while loops 2023-11-28 15:46:19 +01:00
Andrea Gussoni fb336d1461 BeautifyGHAST: reorder simplifyImplicitContinue
Move the `simplifyImplicitContinue` at the end of the beautify pass,
after all the pass that modify the anatomy of the ASTTree.

Before this change, the pass was run before some changes that moved some
`continue`s in positions where they are not considered implicit.

Added an assertion which checks that during the `noFallThrough`
promotion phase, no implicit `ContinueNode` is present.
2023-11-03 11:44:23 +01:00
Andrea Gussoni 9248130bab BeautifyGHAST: reassign RootNode
Reassign the `RootNode` after the `simplifyAtomicSequence` beautify pass
has run.
2023-11-03 11:44:00 +01:00
Giacomo Vercesi ce446576a4 Fix typos 2023-11-02 16:49:49 +01:00
Andrea Gussoni 3e13765267 BeautifyGHAST: handle noreturn calls in beautify
Improve the `fallThroughScope` computation, in order to handle calls to
`NoReturn` functions in the analysis, representing the fact that they
induce a `noFallthrough` scope (i.e., execution will not ever resume
after the call, and therefore we can later improve the nesting of the
code with the `promoteNoFallthrough` pass).
2023-10-23 18:16:20 +02:00
Andrea Gussoni 733f5008b3 BeautifyGHAST: implement DualSwitch simplify
We introduce a simplification step, which looks for `switch`es that can
be reduced to simpler `if` statements.

Specifically, the logic is the following:
1) When we identify a `switch` statement composed by a single `case` and
   a possible default, we transform it into an `if` with the `case` now
   corresponding to the `then`, and the `default` corresponding to the
   `else`, if present.
2) When we identify a `switch` statement composed by two `case`s, and no
   `default` is present, we can promote it to an `if` with `then` `else`
   branches.

Other key details:
- The promotion happens only if we can identify at least one of the
  `case`s that have a single element in the `case` label. If this is not
  the case, we do not promote one to RHS of the `if` condition.
- A new `CompareNode` class, inheriting from `ExprNode`, is created, in
  order to represent the equality or inequality condition of an `IfNode`
  instance that is the result of the promotion. This `CompareNode` can
  represent for the LHS both an `llvm::Value` or the `loop_state_var`,
  while it embeds the RHS constant which completes the comparison.
- We remove `SwitchBreak` AST nodes that may now appear as children of
  an `if` node promoted from a `switch`.
- We introduce in the `CompareNode` the `weaved` concept. Indeed, if a
  promotion of a weaved `switch` happens, we should avoid the
  serialization of the instructions leading to the computation of the
  condition of the original `switch`, because they have been already
  emitted by the main related dominating `switch`.

We also introduce an additional simplification step, which takes care
of:
- Promoting `!(==)` to `(!=)` and `!(!=)` to `(==)`, if the inner
  equal/not equal is represented via a `CompareNode`.
- Promoting `x == 0` to `!x` and `x != 0` to `x`.

To be able to correctly emit (or not) the instructions computing a
condition of an `IfNode`, we need to add the `EmittBB` flag, an
additional parameter to the `buildGHASTCondition` function, which
controls the emission of the statements of a basic block computing a
condition.

Consequently, the `IfNode` acquires a `IsWeaved` field, which is used to
mirror the property having the same name on `SwitchNode`. Being now
possible a promotion from a dual `SwitchNode` to an `IfNode`, we need to
represent this property on the `IfNode` too.
2023-10-23 18:16:20 +02:00
Andrea Gussoni 2cef075697 ASTNode: refactor default in SwitchNode
The `default` `case` is now a standard `case`, and it is identified only
by having the `label` set empty.

Therefore, a list of beautify and transformation actions now do not need
special casing in order to handle the `default` `case`, which is reached
during the standard iteration over the `case`s.

A special accessor is still necessary, in order to correctly emit the
`default` `case` in the backend.
2023-10-23 18:16:20 +02:00
Andrea Gussoni 061bc52bc2 BeautifyGHAST: implicit statements simplification
Introduce implicit statements simplification phase, specifically:
- A implicit `return` simplification: `return` statements in `void`
  type functions, which are not followed by any other scope, can be
  omitted.
- A implicit `continue` simplification: `continue` statements whose
  fallthrough leads directly to the end of the cycle scope (i.e., to
  execute another iteration of the enclosing loop), can be omitted.

In order to avoid the printing of the implicit `return`, we need an
additional `emitReturn` parameter in the `emitBasicBlock` method of the
`CCodeGenerator` class.
2023-10-23 18:16:20 +02:00
Andrea Gussoni f98e72d9a7 BeautifyGHAST: move SimplifyHybridNot header 2023-10-23 18:16:20 +02:00
Pietro Fezzardi 8df32f84cc BeautifyGHAST: drop broken code in hasSideEffects
This commit drops some old broken code that was a leftover from when
MarkAssignments didn't inject calls to Assign, and that was poorly
migrated to Assign, causing it to be dead code.
2023-10-02 17:10:15 +02:00
Pietro Fezzardi dd76d3bef9 BeautifyGHAST: fix hasSideEffects for NotNode
This commit fixes a bug in the hasSideEffects function, used to evaluate
if an ExprNode has side effects.
Before this commit, when calling hasSideEffects on a NotNode, the
return value was true if the operand of NotNode **did not** have side
effects, which is wrong.
This commit changes the behaviour so that a NotNode has side effects if
and only if its only operand has side effects.
2023-09-27 16:48:22 +02:00
Pietro Fezzardi 398f0888d0 BeautifyGHAST: fix hasSideEffects for AndNode
This commit fixes a bug in the hasSideEffects function, used to evaluate
if an ExprNode has side effects.
Before this commit, when calling hasSideEffects on an AndNode, the
return value was true if **both** the LHS and RHS of the AndNode had
side effects, which is wrong.
This commit changes the behaviour so that if **either** LHS **or** the
RHS of the And have any side effect, than hasSideEffects returns true
for the And.
2023-09-27 16:48:19 +02:00
Pietro Fezzardi ce6935bec7 BeautifyGHAST: simplifyShortCircuit recurs on if
Before this commit, the simplifyShortCircuit beautifier did not recur on
the then/else branch of an IfNode, basically stopping recursion very
early and potentially missing a lot of beautification opportunities.
2023-09-27 16:48:10 +02:00
Ivan Krysak 888e5371eb Formatting: change PenaltyReturnTypeOnItsOwnLine
The new value is 21.
2023-07-05 06:06:07 +00:00
Andrea Gussoni 3b07a6fba6 BeautifyGHAST: Introduce the hybrid not simplify
Introduce the hybrid beautifier aiming to simplify double `not`s (one on
the IR side (e.g., a `icmp ne`), and one on the `ExprNode` side on the
`GHAST` in the form of a `NotNode`.

To do this hybrid beautifier, we basically need to do the following:
- Implement a preliminary collection phase which computes which
  `ExprNode`s are affected by which `BasicBlock`.
- Compute the so-called consesus, i.e., verify that for all the
  `ExprNode`s affected by a certain `BasicBlock`, the transformation
  would be beneficial in terms of output. Basically:
    1) That the number of `!(!=)` transformed into `(==)` outscores the
       number of correlated `(!=)` which are transformed into `!(==)`.
    2) That the number of `!(==)` transformed into `(!=)` outscores the
       number of correlated `(==)` which are transformed into `!(!=)`.
- Actually perform the transformation for those situations where the
  consensus agrees.
2023-06-26 15:23:00 +02:00
Pietro Fezzardi 4c9df76673 BeautifyGHAST: fix numbering of debug filenames 2023-06-23 16:39:04 +02:00
Giacomo Vercesi a4ad571e61 rcc: Fix typos
Fix the typos detected by `codespell`
2023-05-11 10:04:32 +02:00
Andrea Gussoni 659aff1bbf Fix loop promotion criterion
A bug introduced no loop promotion by mistake, we now correctly exit the
loop promotion routine if the loop has been already promoted to `while`
or `do-while` loop.
2023-04-19 16:07:46 +02:00
Alessandro Di Federico 4c469e5180 Adopt getCallToTagged
`isCallToTagged` used to return a pointer in case of success.
We now have `getCallToTagged` for that.

Also, these functions have been moved to revng.
2023-04-14 14:54:14 +02:00
Alessandro Di Federico cad027abb2 Add missing includes 2023-04-14 14:54:14 +02:00
Pietro Fezzardi e9d84264ff Reduce the number of emitted local variables in C
This commit does various things oriented at reducing the number of local
variables emitted in C:
- MarkAssignments now know that @Copy and @Assign involving
  @LocalVariable only have side effects that affect the local variable
  itself; this enables to reduce the number of times we're forced to
  emit a local variable due to interfering side effects
- Drop the @AssignmentMarker FunctionTag; AddAssignmentMarkerPass now
  doesn't emit @AssignmentMarker anymore; instead it emits groups of
  @LocalVariable, @Copy, and @Assign, which benefit from the previous
  point
- Drop 2 MarkAssignments::Reasons: HasManyUses and HasUsesOutsideOfBB;
  both these have now been aggregated into the AlwaysAssign reason for
  simplicity, representing all reasons non involving side effects
- Update BeautifyGHAST and how it reasons about side effects when
  beautifying; before this commit it used @AssignmentMarker, now it
  looks at @Assign
- Simplify ExitSSA; before this commit it was trying hard to be smart on
  where it emitted the store instructions representing the incoming
  values of the PHI that was being destroyed; this seemed smart when we
  originally did it but it generated C code that was not really better
  to read, so this useless complexity is finally gone
2022-12-24 02:47:10 +01:00
Pietro Fezzardi d9d9294fe5 MarkAssignment: fix taint set and aggregate types 2022-06-28 10:28:08 +02:00
Pietro Fezzardi ad81bc7020 Enable addtional compilation warnings
These warnings are not enabled by default with -Wall nor with -Wextra.
2022-06-14 12:48:54 +02:00
Alvise de Faveri 99b06894c4 GHAST: Fix NotAAnd(Not)B short-circuiting 2022-06-01 11:24:20 +02:00
Pietro Fezzardi 4188b709be Merge BeautifyGHAST back into RestructureCFG
The beautification library was split into a separate library for
historical reason, having to do with LLVM passes, their dependencies,
and dirty hacks we had around.

Now the LLVM passes, and the hacks are gone, so we can merge back
everything together.
2022-05-11 15:19:34 +02:00