#include "Transforms/CopyLowering.h"
#include "Transforms/ConcatLowering.h"
#include "Transforms/FreeInstrElimination.h"
+#include "Transforms/FreeOpElimination.h"
#include "Transforms/DeadBagElimination.h"
#include "Transforms/Optimizations.h"
#include "Transforms/Split.h"
generate_bypass_shuffle(code(sess));
eliminate_free_instr(code(sess));
+ // NOTE Free Op Elimination should be applied after Free Instr Elimination
+ // - Free Instr Elimination may generate additional free Op(s)
+ eliminate_free_op(code(sess));
eliminate_dead_bag(code(sess));
// Split instructions into a set of phases (each block serves as a phase)
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FreeOpElimination.h"
+
+#include <cassert>
+#include <set>
+#include <queue>
+
+namespace
+{
+
+/**
+ * @brief Return the set of Free Op Elimination candidates
+ */
+std::set<coco::Op *> candidates(const coco::Module *m)
+{
+ std::set<coco::Op *> res;
+
+ for (uint32_t n = 0; n < m->entity()->op()->size(); ++n)
+ {
+ if (auto op = m->entity()->op()->at(n))
+ {
+ if ((op->parent() == nullptr) && (op->up() == nullptr))
+ {
+ res.insert(op);
+ }
+ }
+ }
+
+ return res;
+}
+
+/**
+ * @brief Destroy op tree
+ */
+void destroy(coco::Op *op)
+{
+ assert(coco::root(op) == op);
+ auto m = op->module();
+
+ std::queue<coco::Op *> q;
+
+ q.emplace(op);
+
+ while (q.size() > 0)
+ {
+ auto cur = q.front();
+ q.pop();
+
+ // Insert child op nodes
+ for (uint32_t n = 0; n < cur->arity(); ++n)
+ {
+ q.emplace(cur->arg(n));
+ }
+
+ // Destroy the current op node
+ m->entity()->op()->destroy(cur);
+ }
+}
+
+} // namespace
+
+namespace enco
+{
+
+void eliminate_free_op(coco::Module *m)
+{
+ for (auto op : candidates(m))
+ {
+ destroy(op);
+ }
+}
+
+} // namespace enco
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ENCO_TRANSFORM_FREE_OP_ELIMINATION_H__
+#define __ENCO_TRANSFORM_FREE_OP_ELIMINATION_H__
+
+#include "Code.h"
+
+namespace enco
+{
+
+/**
+ * @brief Eliminate free op
+ *
+ * An op is referred to as "free" if it is not bound to any "instruction"
+ */
+void eliminate_free_op(coco::Module *mod);
+
+/**
+ * @brief Eliminate free op
+ */
+static inline void eliminate_free_op(enco::Code *code)
+{
+ // This function is just a wrapper of the above "void eliminate_free_op(coco::Module *mod)"
+ eliminate_free_op(code->module());
+}
+
+} // namespace enco
+
+#endif // __ENCO_TRANSFORM_FREE_OP_ELIMINATION_H__
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FreeOpElimination.h"
+
+#include <gtest/gtest.h>
+
+TEST(FreeOpEliminationTest, case_000)
+{
+ auto m = coco::Module::create();
+
+ // Create a "free" Load op
+ m->entity()->op()->create<coco::Load>();
+
+ ASSERT_EQ(m->entity()->op()->size(), 1);
+
+ // Apply "Free Op Elimination"
+ enco::eliminate_free_op(m.get());
+
+ ASSERT_EQ(m->entity()->op()->size(), 0);
+}