Air should use RegisterSet for RegLiveness
[WebKit-https.git] / Source / JavaScriptCore / jit / RegisterSet.h
1 /*
2  * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #if ENABLE(JIT)
29
30 #include "FPRInfo.h"
31 #include "GPRInfo.h"
32 #include "MacroAssembler.h"
33 #include "Reg.h"
34 #include "TempRegisterSet.h"
35 #include <wtf/Bitmap.h>
36
37 namespace JSC {
38
39 typedef Bitmap<MacroAssembler::numGPRs + MacroAssembler::numFPRs + 1> RegisterBitmap;
40
41 class RegisterSet {
42 public:
43     template<typename... Regs>
44     explicit RegisterSet(Regs... regs)
45     {
46         setMany(regs...);
47     }
48     
49     JS_EXPORT_PRIVATE static RegisterSet stackRegisters();
50     JS_EXPORT_PRIVATE static RegisterSet reservedHardwareRegisters();
51     static RegisterSet runtimeRegisters();
52     static RegisterSet specialRegisters(); // The union of stack, reserved hardware, and runtime registers.
53     JS_EXPORT_PRIVATE static RegisterSet calleeSaveRegisters();
54     static RegisterSet vmCalleeSaveRegisters(); // Callee save registers that might be saved and used by any tier.
55     static RegisterSet llintBaselineCalleeSaveRegisters(); // Registers saved and used by the LLInt.
56     static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
57     static RegisterSet ftlCalleeSaveRegisters(); // Registers that might be saved and used by the FTL JIT.
58 #if ENABLE(WEBASSEMBLY)
59     static RegisterSet webAssemblyCalleeSaveRegisters(); // Registers saved and used by the WebAssembly JIT.
60 #endif
61     static RegisterSet volatileRegistersForJSCall();
62     static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
63     JS_EXPORT_PRIVATE static RegisterSet macroScratchRegisters();
64     JS_EXPORT_PRIVATE static RegisterSet allGPRs();
65     JS_EXPORT_PRIVATE static RegisterSet allFPRs();
66     static RegisterSet allRegisters();
67     static RegisterSet argumentGPRS();
68
69     static RegisterSet registersToNotSaveForJSCall();
70     static RegisterSet registersToNotSaveForCCall();
71     
72     void set(Reg reg, bool value = true)
73     {
74         ASSERT(!!reg);
75         m_bits.set(reg.index(), value);
76     }
77     
78     void set(JSValueRegs regs, bool value = true)
79     {
80         if (regs.tagGPR() != InvalidGPRReg)
81             set(regs.tagGPR(), value);
82         set(regs.payloadGPR(), value);
83     }
84     
85     void clear(Reg reg)
86     {
87         ASSERT(!!reg);
88         set(reg, false);
89     }
90     
91     bool get(Reg reg) const
92     {
93         ASSERT(!!reg);
94         return m_bits.get(reg.index());
95     }
96     
97     template<typename Iterable>
98     void setAll(const Iterable& iterable)
99     {
100         for (Reg reg : iterable)
101             set(reg);
102     }
103     
104     // Also allow add/remove/contains terminology, which means the same thing as set/clear/get.
105     void add(Reg reg) { set(reg); }
106     void remove(Reg reg) { clear(reg); }
107     bool contains(Reg reg) const { return get(reg); }
108     
109     void merge(const RegisterSet& other) { m_bits.merge(other.m_bits); }
110     void filter(const RegisterSet& other) { m_bits.filter(other.m_bits); }
111     void exclude(const RegisterSet& other) { m_bits.exclude(other.m_bits); }
112     
113     bool subsumes(const RegisterSet& other) const { return m_bits.subsumes(other.m_bits); }
114     
115     size_t numberOfSetGPRs() const;
116     size_t numberOfSetFPRs() const;
117     size_t numberOfSetRegisters() const { return m_bits.count(); }
118     
119     bool isEmpty() const { return m_bits.isEmpty(); }
120     
121     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
122     
123     enum EmptyValueTag { EmptyValue };
124     enum DeletedValueTag { DeletedValue };
125     
126     RegisterSet(EmptyValueTag)
127     {
128         m_bits.set(hashSpecialBitIndex);
129     }
130     
131     RegisterSet(DeletedValueTag)
132     {
133         m_bits.set(hashSpecialBitIndex);
134         m_bits.set(deletedBitIndex);
135     }
136     
137     bool isEmptyValue() const
138     {
139         return m_bits.get(hashSpecialBitIndex) && !m_bits.get(deletedBitIndex);
140     }
141     
142     bool isDeletedValue() const
143     {
144         return m_bits.get(hashSpecialBitIndex) && m_bits.get(deletedBitIndex);
145     }
146     
147     bool operator==(const RegisterSet& other) const { return m_bits == other.m_bits; }
148     bool operator!=(const RegisterSet& other) const { return m_bits != other.m_bits; }
149     
150     unsigned hash() const { return m_bits.hash(); }
151     
152     template<typename Func>
153     void forEach(const Func& func) const
154     {
155         m_bits.forEachSetBit(
156             [&] (size_t index) {
157                 func(Reg::fromIndex(index));
158             });
159     }
160     
161     class iterator {
162     public:
163         iterator()
164         {
165         }
166         
167         iterator(const RegisterBitmap::iterator& iter)
168             : m_iter(iter)
169         {
170         }
171         
172         Reg operator*() const { return Reg::fromIndex(*m_iter); }
173         
174         iterator& operator++()
175         {
176             ++m_iter;
177             return *this;
178         }
179         
180         bool operator==(const iterator& other)
181         {
182             return m_iter == other.m_iter;
183         }
184         
185         bool operator!=(const iterator& other)
186         {
187             return !(*this == other);
188         }
189         
190     private:
191         RegisterBitmap::iterator m_iter;
192     };
193     
194     iterator begin() const { return iterator(m_bits.begin()); }
195     iterator end() const { return iterator(m_bits.end()); }
196     
197 private:
198     void setAny(Reg reg) { set(reg); }
199     void setAny(const RegisterSet& set) { merge(set); }
200     void setMany() { }
201     template<typename RegType, typename... Regs>
202     void setMany(RegType reg, Regs... regs)
203     {
204         setAny(reg);
205         setMany(regs...);
206     }
207
208     // These offsets mirror the logic in Reg.h.
209     static const unsigned gprOffset = 0;
210     static const unsigned fprOffset = gprOffset + MacroAssembler::numGPRs;
211     static const unsigned hashSpecialBitIndex = fprOffset + MacroAssembler::numFPRs;
212     static const unsigned deletedBitIndex = 0;
213     
214     RegisterBitmap m_bits;
215 };
216
217 struct RegisterSetHash {
218     static unsigned hash(const RegisterSet& set) { return set.hash(); }
219     static bool equal(const RegisterSet& a, const RegisterSet& b) { return a == b; }
220     static const bool safeToCompareToEmptyOrDeleted = false;
221 };
222
223 } // namespace JSC
224
225 namespace WTF {
226
227 template<typename T> struct DefaultHash;
228 template<> struct DefaultHash<JSC::RegisterSet> {
229     typedef JSC::RegisterSetHash Hash;
230 };
231
232 template<typename T> struct HashTraits;
233 template<> struct HashTraits<JSC::RegisterSet> : public CustomHashTraits<JSC::RegisterSet> { };
234
235 } // namespace WTF
236
237 #endif // ENABLE(JIT)