Clean up resetting reachability in B3/Air
[WebKit-https.git] / Source / JavaScriptCore / b3 / air / AirCode.cpp
1 /*
2  * Copyright (C) 2015-2016 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 #include "config.h"
27 #include "AirCode.h"
28
29 #if ENABLE(B3_JIT)
30
31 #include "AirCCallSpecial.h"
32 #include "B3BasicBlockUtils.h"
33 #include "B3StackSlot.h"
34
35 namespace JSC { namespace B3 { namespace Air {
36
37 Code::Code(Procedure& proc)
38     : m_proc(proc)
39     , m_lastPhaseName("initial")
40 {
41 }
42
43 Code::~Code()
44 {
45 }
46
47 BasicBlock* Code::addBlock(double frequency)
48 {
49     std::unique_ptr<BasicBlock> block(new BasicBlock(m_blocks.size(), frequency));
50     BasicBlock* result = block.get();
51     m_blocks.append(WTFMove(block));
52     return result;
53 }
54
55 StackSlot* Code::addStackSlot(unsigned byteSize, StackSlotKind kind, B3::StackSlot* b3Slot)
56 {
57     return m_stackSlots.addNew(byteSize, kind, b3Slot);
58 }
59
60 StackSlot* Code::addStackSlot(B3::StackSlot* b3Slot)
61 {
62     return addStackSlot(b3Slot->byteSize(), StackSlotKind::Locked, b3Slot);
63 }
64
65 Special* Code::addSpecial(std::unique_ptr<Special> special)
66 {
67     special->m_code = this;
68     return m_specials.add(WTFMove(special));
69 }
70
71 CCallSpecial* Code::cCallSpecial()
72 {
73     if (!m_cCallSpecial) {
74         m_cCallSpecial = static_cast<CCallSpecial*>(
75             addSpecial(std::make_unique<CCallSpecial>()));
76     }
77
78     return m_cCallSpecial;
79 }
80
81 void Code::resetReachability()
82 {
83     recomputePredecessors(m_blocks);
84     
85     for (auto& block : m_blocks) {
86         if (isBlockDead(block.get()))
87             block = nullptr;
88     }
89 }
90
91 void Code::dump(PrintStream& out) const
92 {
93     for (BasicBlock* block : *this)
94         out.print(deepDump(block));
95     if (stackSlots().size()) {
96         out.print("Stack slots:\n");
97         for (StackSlot* slot : stackSlots())
98             out.print("    ", pointerDump(slot), ": ", deepDump(slot), "\n");
99     }
100     if (specials().size()) {
101         out.print("Specials:\n");
102         for (Special* special : specials())
103             out.print("    ", deepDump(special), "\n");
104     }
105     if (m_frameSize)
106         out.print("Frame size: ", m_frameSize, "\n");
107     if (m_callArgAreaSize)
108         out.print("Call arg area size: ", m_callArgAreaSize, "\n");
109     if (m_calleeSaveRegisters.size())
110         out.print("Callee saves: ", m_calleeSaveRegisters, "\n");
111 }
112
113 unsigned Code::findFirstBlockIndex(unsigned index) const
114 {
115     while (index < size() && !at(index))
116         index++;
117     return index;
118 }
119
120 unsigned Code::findNextBlockIndex(unsigned index) const
121 {
122     return findFirstBlockIndex(index + 1);
123 }
124
125 BasicBlock* Code::findNextBlock(BasicBlock* block) const
126 {
127     unsigned index = findNextBlockIndex(block->index());
128     if (index < size())
129         return at(index);
130     return nullptr;
131 }
132
133 void Code::addFastTmp(Tmp tmp)
134 {
135     m_fastTmps.add(tmp);
136 }
137
138 unsigned Code::jsHash() const
139 {
140     unsigned result = 0;
141     
142     for (BasicBlock* block : *this) {
143         result *= 1000001;
144         for (Inst& inst : *block) {
145             result *= 97;
146             result += inst.jsHash();
147         }
148         for (BasicBlock* successor : block->successorBlocks()) {
149             result *= 7;
150             result += successor->index();
151         }
152     }
153     for (StackSlot* slot : stackSlots()) {
154         result *= 101;
155         result += slot->jsHash();
156     }
157     
158     return result;
159 }
160
161 } } } // namespace JSC::B3::Air
162
163 #endif // ENABLE(B3_JIT)