Skip to content

Commit

Permalink
Convert binary operation normalizations to new normalization interface (
Browse files Browse the repository at this point in the history
  • Loading branch information
phate authored Dec 21, 2024
1 parent dd6f2ba commit 0ac4805
Show file tree
Hide file tree
Showing 3 changed files with 364 additions and 5 deletions.
63 changes: 63 additions & 0 deletions jlm/rvsdg/binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,69 @@ binary_op::flags() const noexcept
return jlm::rvsdg::binary_op::flags::none;
}

std::optional<std::vector<rvsdg::output *>>
FlattenAssociativeBinaryOperation(
const binary_op & operation,
const std::vector<rvsdg::output *> & operands)
{
JLM_ASSERT(!operands.empty());
auto region = operands[0]->region();

if (!operation.is_associative())
{
return std::nullopt;
}

auto newOperands = base::detail::associative_flatten(
operands,
[&operation](rvsdg::output * operand)
{
auto node = TryGetOwnerNode<Node>(*operand);
if (node == nullptr)
return false;

auto flattenedBinaryOperation =
dynamic_cast<const flattened_binary_op *>(&node->GetOperation());
return node->GetOperation() == operation
|| (flattenedBinaryOperation && flattenedBinaryOperation->bin_operation() == operation);
});

if (operands == newOperands)
{
JLM_ASSERT(newOperands.size() == 2);
return std::nullopt;
}

JLM_ASSERT(newOperands.size() > 2);
auto flattenedBinaryOperation =
std::make_unique<flattened_binary_op>(operation, newOperands.size());
return outputs(SimpleNode::create(region, *flattenedBinaryOperation, newOperands));
}

std::optional<std::vector<rvsdg::output *>>
NormalizeBinaryOperation(const binary_op & operation, const std::vector<rvsdg::output *> & operands)
{
JLM_ASSERT(!operands.empty());
auto region = operands[0]->region();

auto newOperands = reduce_operands(operation, operands);

if (newOperands == operands)
{
// The operands did not change, which means that none of the normalizations triggered.
return std::nullopt;
}

if (newOperands.size() == 1)
{
// The operands could be reduced to a single value by applying constant folding.
return newOperands;
}

JLM_ASSERT(newOperands.size() == 2);
return outputs(SimpleNode::create(region, operation, newOperands));
}

/* flattened binary operator */

flattened_binary_op::~flattened_binary_op() noexcept
Expand Down
39 changes: 39 additions & 0 deletions jlm/rvsdg/binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <jlm/rvsdg/simple-normal-form.hpp>
#include <jlm/util/common.hpp>

#include <optional>

namespace jlm::rvsdg
{

Expand Down Expand Up @@ -167,6 +169,43 @@ class binary_op : public SimpleOperation
}
};

/**
* \brief Flattens a cascade of the same binary operations into a single flattened binary operation.
*
* o1 = binaryNode i1 i2
* o2 = binaryNode o1 i3
* =>
* o2 = flattenedBinaryNode i1 i2 i3
*
* \pre The binary operation must be associative.
*
* @param operation The binary operation on which the transformation is performed.
* @param operands The operands of the binary node.
* @return If the normalization could be applied, then the results of the binary operation after
* the transformation. Otherwise, std::nullopt.
*/
std::optional<std::vector<rvsdg::output *>>
FlattenAssociativeBinaryOperation(
const binary_op & operation,
const std::vector<rvsdg::output *> & operands);

/**
* \brief Applies the reductions implemented in the binary operations reduction functions.
*
* @param operation The binary operation on which the transformation is performed.
* @param operands The operands of the binary node.
*
* @return If the normalization could be applied, then the results of the binary operation after
* the transformation. Otherwise, std::nullopt.
*
* \see binary_op::can_reduce_operand_pair()
* \see binary_op::reduce_operand_pair()
*/
std::optional<std::vector<rvsdg::output *>>
NormalizeBinaryOperation(
const binary_op & operation,
const std::vector<rvsdg::output *> & operands);

class flattened_binary_op final : public SimpleOperation
{
public:
Expand Down
Loading

0 comments on commit 0ac4805

Please sign in to comment.