1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef COMPILER_OPTIMIZER_OPTIMIZATIONS_VN_H 17b1994897Sopenharmony_ci#define COMPILER_OPTIMIZER_OPTIMIZATIONS_VN_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <unordered_map> 20b1994897Sopenharmony_ci#include <array> 21b1994897Sopenharmony_ci#include "utils/hash.h" 22b1994897Sopenharmony_ci#include "optimizer/pass.h" 23b1994897Sopenharmony_ci 24b1994897Sopenharmony_cinamespace panda::compiler { 25b1994897Sopenharmony_ciclass Inst; 26b1994897Sopenharmony_ciclass VnObject; 27b1994897Sopenharmony_ciclass Graph; 28b1994897Sopenharmony_ci 29b1994897Sopenharmony_ciclass VnObject { 30b1994897Sopenharmony_cipublic: 31b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 32b1994897Sopenharmony_ci explicit VnObject() 33b1994897Sopenharmony_ci { 34b1994897Sopenharmony_ci for (uint8_t i = 0; i < MAX_ARRAY_SIZE; i++) { 35b1994897Sopenharmony_ci objs_[i] = 0; 36b1994897Sopenharmony_ci } 37b1994897Sopenharmony_ci } 38b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(VnObject); 39b1994897Sopenharmony_ci NO_COPY_SEMANTIC(VnObject); 40b1994897Sopenharmony_ci ~VnObject() = default; 41b1994897Sopenharmony_ci 42b1994897Sopenharmony_ci void Add(Inst *inst); 43b1994897Sopenharmony_ci void Add(uint32_t obj); 44b1994897Sopenharmony_ci void Add(uint64_t obj); 45b1994897Sopenharmony_ci bool Compare(VnObject *obj); 46b1994897Sopenharmony_ci uint32_t GetSize() const 47b1994897Sopenharmony_ci { 48b1994897Sopenharmony_ci return size_objs_; 49b1994897Sopenharmony_ci } 50b1994897Sopenharmony_ci uint64_t GetElement(uint32_t index) const 51b1994897Sopenharmony_ci { 52b1994897Sopenharmony_ci ASSERT(index < size_objs_); 53b1994897Sopenharmony_ci return objs_[index]; 54b1994897Sopenharmony_ci } 55b1994897Sopenharmony_ci uint32_t *GetArray() 56b1994897Sopenharmony_ci { 57b1994897Sopenharmony_ci return objs_.data(); 58b1994897Sopenharmony_ci } 59b1994897Sopenharmony_ci 60b1994897Sopenharmony_ciprivate: 61b1994897Sopenharmony_ci uint8_t size_objs_ {0}; 62b1994897Sopenharmony_ci // opcode, type, 2 inputs, 2 advanced property 63b1994897Sopenharmony_ci static constexpr uint8_t MAX_ARRAY_SIZE = 6; 64b1994897Sopenharmony_ci std::array<uint32_t, MAX_ARRAY_SIZE> objs_; 65b1994897Sopenharmony_ci}; 66b1994897Sopenharmony_ci 67b1994897Sopenharmony_cistruct VnObjEqual { 68b1994897Sopenharmony_ci bool operator()(VnObject *obj1, VnObject *obj2) const 69b1994897Sopenharmony_ci { 70b1994897Sopenharmony_ci return obj1->Compare(obj2); 71b1994897Sopenharmony_ci } 72b1994897Sopenharmony_ci}; 73b1994897Sopenharmony_ci 74b1994897Sopenharmony_cistruct VnObjHash { 75b1994897Sopenharmony_ci uint32_t operator()(VnObject *obj) const 76b1994897Sopenharmony_ci { 77b1994897Sopenharmony_ci return GetHash32(reinterpret_cast<const uint8_t *>(obj->GetArray()), obj->GetSize()); 78b1994897Sopenharmony_ci } 79b1994897Sopenharmony_ci}; 80b1994897Sopenharmony_ci 81b1994897Sopenharmony_ci/* 82b1994897Sopenharmony_ci * Optimization assigns numbers(named vn) to all instructions. 83b1994897Sopenharmony_ci * Equivalent instructions have equivalent vn. 84b1994897Sopenharmony_ci * If instruction A dominates B and they have equivalent vn, users B are moved to A and DCE removes B at the end. 85b1994897Sopenharmony_ci * The instruction with the property NO_CSE has unique vn and they can't be removed. 86b1994897Sopenharmony_ci * The optimization creates VnObject for instruction without NO_CSE. 87b1994897Sopenharmony_ci * The VnObject is key for the instruction. 88b1994897Sopenharmony_ci * The unordered_map is used for searching equivalent instruction by the key(VnObject). 89b1994897Sopenharmony_ci */ 90b1994897Sopenharmony_ciclass ValNum : public Optimization { 91b1994897Sopenharmony_cipublic: 92b1994897Sopenharmony_ci explicit ValNum(Graph *graph); 93b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(ValNum); 94b1994897Sopenharmony_ci NO_COPY_SEMANTIC(ValNum); 95b1994897Sopenharmony_ci ~ValNum() override = default; 96b1994897Sopenharmony_ci 97b1994897Sopenharmony_ci bool RunImpl() override; 98b1994897Sopenharmony_ci 99b1994897Sopenharmony_ci const char *GetPassName() const override 100b1994897Sopenharmony_ci { 101b1994897Sopenharmony_ci return "GVN"; 102b1994897Sopenharmony_ci } 103b1994897Sopenharmony_ci 104b1994897Sopenharmony_ci bool IsEnable() const override 105b1994897Sopenharmony_ci { 106b1994897Sopenharmony_ci return options.IsCompilerVn(); 107b1994897Sopenharmony_ci } 108b1994897Sopenharmony_ci 109b1994897Sopenharmony_ci void InvalidateAnalyses() override; 110b1994897Sopenharmony_ci 111b1994897Sopenharmony_ci void FindEqualVnOrCreateNew(Inst *inst); 112b1994897Sopenharmony_ci 113b1994897Sopenharmony_ciprivate: 114b1994897Sopenharmony_ci using InstVector = ArenaVector<Inst *>; 115b1994897Sopenharmony_ci 116b1994897Sopenharmony_ci // Sets vn for the inst 117b1994897Sopenharmony_ci void SetInstValNum(Inst *inst); 118b1994897Sopenharmony_ci 119b1994897Sopenharmony_ci bool TryToApplyCse(Inst *inst, InstVector *equiv_insts); 120b1994897Sopenharmony_ci 121b1994897Sopenharmony_ci // !TODO add own allocator 122b1994897Sopenharmony_ci ArenaUnorderedMap<VnObject *, InstVector, VnObjHash, VnObjEqual> map_insts_; 123b1994897Sopenharmony_ci 124b1994897Sopenharmony_ci uint32_t curr_vn_ {0}; 125b1994897Sopenharmony_ci bool cse_is_appied_ {false}; 126b1994897Sopenharmony_ci}; 127b1994897Sopenharmony_ci} // namespace panda::compiler 128b1994897Sopenharmony_ci 129b1994897Sopenharmony_ci#endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_VN_H 130