Jlm
Loading...
Searching...
No Matches
concat.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2010 2011 2012 2014 Helge Bahmann <hcb@chaoticmind.net>
3 * Copyright 2011 2012 2013 2014 Nico Reißmann <nico.reissmann@gmail.com>
4 * See COPYING for terms of redistribution.
5 */
6
11
12namespace jlm::rvsdg
13{
14
16bitconcat(const std::vector<jlm::rvsdg::Output *> & operands)
17{
18 std::vector<std::shared_ptr<const jlm::rvsdg::BitType>> types;
19 for (const auto operand : operands)
20 types.push_back(std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(operand->Type()));
21
22 return CreateOpNode<BitConcatOperation>(operands, std::move(types)).output(0);
23}
24
25std::shared_ptr<const BitType>
27 const std::vector<std::shared_ptr<const BitType>> & types) noexcept
28{
29 size_t total = 0;
30 for (const auto & t : types)
31 {
32 total += t->nbits();
33 }
34 return BitType::Create(total);
35}
36
38
39bool
41{
42 auto op = dynamic_cast<const BitConcatOperation *>(&other);
43 if (!op || op->narguments() != narguments())
44 return false;
45
46 for (size_t n = 0; n < narguments(); n++)
47 {
48 if (op->argument(n) != argument(n))
49 return false;
50 }
51
52 return true;
53}
54
58 const jlm::rvsdg::Output * arg2) const noexcept
59{
62
63 if (!node1 || !node2)
65
66 auto arg1_constant = is<BitConstantOperation>(node1->GetOperation());
67 auto arg2_constant = is<BitConstantOperation>(node2->GetOperation());
68
70 {
72 }
73
74 auto arg1_slice = dynamic_cast<const BitSliceOperation *>(&node1->GetOperation());
75 auto arg2_slice = dynamic_cast<const BitSliceOperation *>(&node2->GetOperation());
76
78 {
79 auto origin1 = node1->input(0)->origin();
80 auto origin2 = node2->input(0)->origin();
81
82 if (origin1 == origin2 && arg1_slice->high() == arg2_slice->low())
83 {
85 }
86
87 /* FIXME: support sign bit */
88 }
89
91}
92
98{
101
102 if (path == binop_reduction_constants)
103 {
104 auto & arg1_constant = static_cast<const BitConstantOperation &>(node1.GetOperation());
105 auto & arg2_constant = static_cast<const BitConstantOperation &>(node2.GetOperation());
106
108 bits.Append(arg2_constant.value());
109 return &BitConstantOperation::create(*arg1->region(), std::move(bits));
110 }
111
112 if (path == binop_reduction_merge)
113 {
114 auto arg1_slice = static_cast<const BitSliceOperation *>(&node1.GetOperation());
115 auto arg2_slice = static_cast<const BitSliceOperation *>(&node2.GetOperation());
116 return jlm::rvsdg::bitslice(node1.input(0)->origin(), arg1_slice->low(), arg2_slice->high());
117
118 /* FIXME: support sign bit */
119 }
120
121 return NULL;
122}
123
129
130std::string
132{
133 return "BitConcat";
134}
135
136std::unique_ptr<Operation>
138{
139 return std::make_unique<BitConcatOperation>(*this);
140}
141
142static std::vector<std::shared_ptr<const BitType>>
143GetTypesFromOperands(const std::vector<rvsdg::Output *> & args)
144{
145 std::vector<std::shared_ptr<const BitType>> types;
146 for (const auto arg : args)
147 {
148 types.push_back(std::dynamic_pointer_cast<const BitType>(arg->Type()));
149 }
150 return types;
151}
152
153std::optional<std::vector<rvsdg::Output *>>
154FlattenBitConcatOperation(const BitConcatOperation &, const std::vector<rvsdg::Output *> & operands)
155{
156 JLM_ASSERT(!operands.empty());
157
159 operands,
160 [](jlm::rvsdg::Output * arg)
161 {
162 // FIXME: switch to comparing operator, not just typeid, after
163 // converting "concat" to not be a binary operator anymore
164 auto sn = TryGetOwnerNode<SimpleNode>(*arg);
165 return sn && is<BitConcatOperation>(sn->GetOperation());
166 });
167
168 if (operands == newOperands)
169 {
170 JLM_ASSERT(newOperands.size() == 2);
171 return std::nullopt;
172 }
173
174 JLM_ASSERT(newOperands.size() > 2);
176}
177
178}
std::string debug_string() const override
Definition concat.cpp:131
enum BinaryOperation::flags flags() const noexcept override
Definition concat.cpp:125
binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *arg1, const jlm::rvsdg::Output *arg2) const noexcept override
Definition concat.cpp:56
std::unique_ptr< Operation > copy() const override
Definition concat.cpp:137
static std::shared_ptr< const BitType > aggregate_arguments(const std::vector< std::shared_ptr< const BitType > > &types) noexcept
Definition concat.cpp:26
jlm::rvsdg::Output * reduce_operand_pair(binop_reduction_path_t path, jlm::rvsdg::Output *arg1, jlm::rvsdg::Output *arg2) const override
Definition concat.cpp:94
~BitConcatOperation() noexcept override
static Output & create(Region &region, BitValueRepresentation value)
Definition constant.hpp:44
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition type.cpp:45
#define JLM_ASSERT(x)
Definition common.hpp:16
std::vector< jlm::rvsdg::Output * > associative_flatten(std::vector< jlm::rvsdg::Output * > args, const FlattenTester &flatten_tester)
static const binop_reduction_path_t binop_reduction_constants
Definition binary.hpp:205
static std::vector< std::shared_ptr< const BitType > > GetTypesFromOperands(const std::vector< rvsdg::Output * > &args)
Definition concat.cpp:143
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition node.hpp:1049
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition node.hpp:1058
size_t binop_reduction_path_t
Definition binary.hpp:19
std::optional< std::vector< rvsdg::Output * > > FlattenBitConcatOperation(const BitConcatOperation &, const std::vector< rvsdg::Output * > &operands)
Definition concat.cpp:154
jlm::rvsdg::Output * bitconcat(const std::vector< jlm::rvsdg::Output * > &operands)
Definition concat.cpp:16
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
static const binop_reduction_path_t binop_reduction_none
Definition binary.hpp:203
jlm::rvsdg::Output * bitslice(jlm::rvsdg::Output *argument, size_t low, size_t high)
Create bitslice.
Definition slice.cpp:130
static const binop_reduction_path_t binop_reduction_merge
Definition binary.hpp:207