• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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