mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
733f5008b3
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.
31 lines
714 B
C++
31 lines
714 B
C++
//
|
|
// Copyright rev.ng Labs Srl. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng/Support/Debug.h"
|
|
|
|
#include "revng-c/RestructureCFG/ExprNode.h"
|
|
|
|
void ExprNode::deleteExprNode(ExprNode *E) {
|
|
switch (E->getKind()) {
|
|
case NodeKind::NK_ValueCompare:
|
|
delete static_cast<ValueCompareNode *>(E);
|
|
break;
|
|
case NodeKind::NK_LoopStateCompare:
|
|
delete static_cast<LoopStateCompareNode *>(E);
|
|
break;
|
|
case NodeKind::NK_Atomic:
|
|
delete static_cast<AtomicNode *>(E);
|
|
break;
|
|
case NodeKind::NK_Not:
|
|
delete static_cast<NotNode *>(E);
|
|
break;
|
|
case NodeKind::NK_And:
|
|
delete static_cast<AndNode *>(E);
|
|
break;
|
|
case NodeKind::NK_Or:
|
|
delete static_cast<OrNode *>(E);
|
|
break;
|
|
}
|
|
}
|