• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 COMPILER_OPTIMIZER_IR_MARKER_H
17 #define COMPILER_OPTIMIZER_IR_MARKER_H
18 
19 #include <array>
20 #include <bitset>
21 #include <cstdint>
22 #include "macros.h"
23 
24 namespace panda::compiler {
25 using Marker = uint32_t;
26 constexpr uint32_t MARKERS_SHIFT = 2;
27 constexpr uint32_t MARKERS_NUM = (1U << MARKERS_SHIFT);
28 constexpr uint32_t MARKERS_MASK = (MARKERS_NUM - 1U);
29 constexpr uint32_t MARKER_SIZE = 32;
30 constexpr uint32_t MAX_MARKER = ((1U << (MARKER_SIZE - MARKERS_NUM)) - 1U);
31 constexpr uint32_t UNDEF_MARKER = 0;
32 
33 class MarkerMgr {
34 public:
MarkerMgr()35     MarkerMgr() : current_index_(0) {}
36 
37     NO_COPY_SEMANTIC(MarkerMgr);
38     NO_MOVE_SEMANTIC(MarkerMgr);
39     virtual ~MarkerMgr() = default;
40 
NewMarker()41     Marker NewMarker() const
42     {
43         ASSERT_PRINT(current_index_ < MAX_MARKER, "Markers overflow. Please check recursion");
44         ++current_index_;
45         for (uint32_t i = 0; i < MARKERS_NUM; i++) {
46             if (!spaces_[i]) {
47                 Marker mrk = (current_index_ << MARKERS_SHIFT) | i;
48                 spaces_[i] = true;
49                 ASSERT(mrk != UNDEF_MARKER);
50                 return mrk;
51             }
52         }
53         UNREACHABLE();
54     }
55 
EraseMarker(Marker mrk)56     void EraseMarker(Marker mrk) const
57     {
58         spaces_[mrk & MARKERS_MASK] = false;
59     }
60 
GetCurrentMarkerIdx()61     uint32_t GetCurrentMarkerIdx()
62     {
63         return current_index_;
64     }
SetMaxMarkerIdx(uint32_t ixd)65     void SetMaxMarkerIdx(uint32_t ixd)
66     {
67         current_index_ = std::max(current_index_, ixd);
68     }
69 
70 private:
71     mutable uint32_t current_index_ {0};
72     mutable std::bitset<MARKERS_NUM> spaces_ {};
73 };
74 
75 class MarkerSet {
76 public:
MarkerSet()77     MarkerSet()
78     {
79         ClearMarkers();
80     }
81 
82     NO_COPY_SEMANTIC(MarkerSet);
83     NO_MOVE_SEMANTIC(MarkerSet);
84     virtual ~MarkerSet() = default;
85 
86     // returns true if the marker was set before, otherwise set marker and return false
SetMarker(Marker mrk)87     bool SetMarker(Marker mrk)
88     {
89         uint32_t index = mrk & MARKERS_MASK;
90         uint32_t value = mrk >> MARKERS_SHIFT;
91         ASSERT(index < MARKERS_NUM);
92         if (markers_[index] == value) {
93             return true;
94         }
95         markers_[index] = value;
96         return false;
97     }
98 
99     // returns true if the marker was set before, otherwise false
IsMarked(Marker mrk)100     bool IsMarked(Marker mrk)
101     {
102         uint32_t index = mrk & MARKERS_MASK;
103         uint32_t value = mrk >> MARKERS_SHIFT;
104         ASSERT(index < MARKERS_NUM);
105         return markers_[index] == value;
106     }
107 
108     // unset marker and returns true if the marker was set before, otherwise false
ResetMarker(Marker mrk)109     bool ResetMarker(Marker mrk)
110     {
111         uint32_t index = mrk & MARKERS_MASK;
112         uint32_t value = mrk >> MARKERS_SHIFT;
113         bool was_set = (markers_[index] == value);
114         ASSERT(index < MARKERS_NUM);
115         markers_[index] = UNDEF_MARKER;
116         return was_set;
117     }
118 
ClearMarkers()119     void ClearMarkers()
120     {
121         for (unsigned int &marker : markers_) {
122             marker = UNDEF_MARKER;
123         }
124     }
125 
126 private:
127     friend class MarkerMgr;
128     std::array<Marker, MARKERS_NUM> markers_ {};
129 };
130 }  // namespace panda::compiler
131 
132 #endif  // COMPILER_OPTIMIZER_IR_MARKER_H
133