1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MAPLEBE_INCLUDE_BE_SWITCH_LOWERER_H 17 #define MAPLEBE_INCLUDE_BE_SWITCH_LOWERER_H 18 #include "mir_nodes.h" 19 #include "mir_module.h" 20 21 namespace maplebe { 22 class BELowerer; 23 24 class SwitchLowerer { 25 public: SwitchLowerer(maple::MIRModule & mod,maple::SwitchNode & stmt,maple::MapleAllocator & allocator)26 SwitchLowerer(maple::MIRModule &mod, maple::SwitchNode &stmt, maple::MapleAllocator &allocator) 27 : mirModule(mod), stmt(&stmt), switchItems(allocator.Adapter()), ownAllocator(&allocator) 28 { 29 } 30 31 ~SwitchLowerer() = default; 32 33 maple::BlockNode *LowerSwitch(); 34 35 private: 36 using Cluster = std::pair<maple::int32, maple::int32>; 37 using SwitchItem = std::pair<maple::int32, maple::int32>; 38 39 maple::MIRModule &mirModule; 40 maple::SwitchNode *stmt; 41 /* 42 * the original switch table is sorted and then each dense (in terms of the 43 * case tags) region is condensed into 1 switch item; in the switchItems 44 * table, each item either corresponds to an original entry in the original 45 * switch table (pair's second is 0), or to a dense region (pair's second 46 * gives the upper limit of the dense range) 47 */ 48 maple::MapleVector<SwitchItem> switchItems; /* uint32 is index in switchTable */ 49 maple::MapleAllocator *ownAllocator; 50 const maple::int32 kClusterSwitchCutoff = 5; 51 const float kClusterSwitchDensityHigh = 0.4; 52 const float kClusterSwitchDensityLow = 0.2; 53 const maple::int32 kMaxRangeGotoTableSize = 127; 54 bool jumpToDefaultBlockGenerated = false; 55 56 void FindClusters(maple::MapleVector<Cluster> &clusters) const; 57 void InitSwitchItems(maple::MapleVector<Cluster> &clusters); 58 maple::RangeGotoNode *BuildRangeGotoNode(maple::int32 startIdx, maple::int32 endIdx); 59 maple::CompareNode *BuildCmpNode(maple::Opcode opCode, maple::uint32 idx); 60 maple::GotoNode *BuildGotoNode(maple::int32 idx); 61 maple::CondGotoNode *BuildCondGotoNode(maple::int32 idx, maple::Opcode opCode, maple::BaseNode &cond); 62 maple::BlockNode *BuildCodeForSwitchItems(maple::int32 start, maple::int32 end, bool lowBNdChecked, 63 bool highBNdChecked); 64 }; 65 } /* namespace maplebe */ 66 67 #endif /* MAPLEBE_INCLUDE_BE_SWITCH_LOWERER_H */ 68