blob: aab853c20145fd43eb0bd86005f2ec3ddec0933a [file] [log] [blame]
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +00001/*
mark.lam@apple.come668c9e2020-04-09 09:27:40 +00002 * Copyright (C) 2015-2020 Apple Inc. All rights reserved.
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +00003 *
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 "B3LowerMacrosAfterOptimizations.h"
28
29#if ENABLE(B3_JIT)
30
keith_miller@apple.com504d5852017-09-13 01:31:07 +000031#include "AirArg.h"
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000032#include "B3BlockInsertionSet.h"
commit-queue@webkit.org868c9732015-12-14 22:44:22 +000033#include "B3CCallValue.h"
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000034#include "B3ConstDoubleValue.h"
35#include "B3ConstFloatValue.h"
commit-queue@webkit.org868c9732015-12-14 22:44:22 +000036#include "B3ConstPtrValue.h"
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000037#include "B3InsertionSetInlines.h"
38#include "B3PhaseScope.h"
pmatos@igalia.comb78530b2020-05-23 14:57:15 +000039#include "B3ValueInlines.h"
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000040
41namespace JSC { namespace B3 {
42
keith_miller@apple.com504d5852017-09-13 01:31:07 +000043using Arg = Air::Arg;
44using Code = Air::Code;
45using Tmp = Air::Tmp;
46
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000047namespace {
48
keith_miller@apple.com504d5852017-09-13 01:31:07 +000049class LowerMacrosAfterOptimizations {
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000050public:
keith_miller@apple.com504d5852017-09-13 01:31:07 +000051 LowerMacrosAfterOptimizations(Procedure& proc)
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000052 : m_proc(proc)
53 , m_blockInsertionSet(proc)
54 , m_insertionSet(proc)
55 {
56 }
57
58 bool run()
59 {
60 for (BasicBlock* block : m_proc) {
61 m_block = block;
62 processCurrentBlock();
63 }
64 m_changed |= m_blockInsertionSet.execute();
65 if (m_changed) {
66 m_proc.resetReachability();
67 m_proc.invalidateCFG();
68 }
69 return m_changed;
70 }
71
72private:
73 void processCurrentBlock()
74 {
75 for (m_index = 0; m_index < m_block->size(); ++m_index) {
76 m_value = m_block->at(m_index);
77 m_origin = m_value->origin();
78 switch (m_value->opcode()) {
79 case Abs: {
80 // ARM supports this instruction natively.
81 if (isARM64())
82 break;
83
84 Value* mask = nullptr;
85 if (m_value->type() == Double)
peavo@outlook.com76ed6aa2016-01-19 21:49:12 +000086 mask = m_insertionSet.insert<ConstDoubleValue>(m_index, m_origin, bitwise_cast<double>(~(1ll << 63)));
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +000087 else if (m_value->type() == Float)
88 mask = m_insertionSet.insert<ConstFloatValue>(m_index, m_origin, bitwise_cast<float>(~(1 << 31)));
89 else
90 RELEASE_ASSERT_NOT_REACHED();
91 Value* result = m_insertionSet.insert<Value>(m_index, BitAnd, m_origin, m_value->child(0), mask);
92 m_value->replaceWithIdentity(result);
93 break;
94 }
commit-queue@webkit.org868c9732015-12-14 22:44:22 +000095 case Ceil: {
utatane.tea@gmail.com9971c632016-03-01 02:30:46 +000096 if (MacroAssembler::supportsFloatingPointRounding())
commit-queue@webkit.org868c9732015-12-14 22:44:22 +000097 break;
98
99 Value* functionAddress = nullptr;
utatane.tea@gmail.comeedf1882016-03-17 13:57:03 +0000100 if (m_value->type() == Double) {
101 double (*ceilDouble)(double) = ceil;
mark.lam@apple.come668c9e2020-04-09 09:27:40 +0000102 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<B3CCallPtrTag>(ceilDouble));
utatane.tea@gmail.comeedf1882016-03-17 13:57:03 +0000103 } else if (m_value->type() == Float)
mark.lam@apple.come668c9e2020-04-09 09:27:40 +0000104 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<B3CCallPtrTag>(ceilf));
commit-queue@webkit.org868c9732015-12-14 22:44:22 +0000105 else
106 RELEASE_ASSERT_NOT_REACHED();
107
108 Value* result = m_insertionSet.insert<CCallValue>(m_index,
109 m_value->type(),
110 m_origin,
111 Effects::none(),
112 functionAddress,
113 m_value->child(0));
114 m_value->replaceWithIdentity(result);
115 break;
116 }
utatane.tea@gmail.com9971c632016-03-01 02:30:46 +0000117 case Floor: {
118 if (MacroAssembler::supportsFloatingPointRounding())
119 break;
120
121 Value* functionAddress = nullptr;
utatane.tea@gmail.comeedf1882016-03-17 13:57:03 +0000122 if (m_value->type() == Double) {
123 double (*floorDouble)(double) = floor;
mark.lam@apple.come668c9e2020-04-09 09:27:40 +0000124 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<B3CCallPtrTag>(floorDouble));
utatane.tea@gmail.comeedf1882016-03-17 13:57:03 +0000125 } else if (m_value->type() == Float)
mark.lam@apple.come668c9e2020-04-09 09:27:40 +0000126 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, tagCFunction<B3CCallPtrTag>(floorf));
utatane.tea@gmail.com9971c632016-03-01 02:30:46 +0000127 else
128 RELEASE_ASSERT_NOT_REACHED();
129
130 Value* result = m_insertionSet.insert<CCallValue>(m_index,
131 m_value->type(),
132 m_origin,
133 Effects::none(),
134 functionAddress,
135 m_value->child(0));
136 m_value->replaceWithIdentity(result);
137 break;
138 }
fpizlo@apple.com46d35042016-01-09 00:01:55 +0000139 case Neg: {
keith_miller@apple.com70c51b82019-08-02 21:02:05 +0000140 if (!m_value->type().isFloat())
fpizlo@apple.com46d35042016-01-09 00:01:55 +0000141 break;
142
143 // X86 is odd in that it requires this.
144 if (!isX86())
145 break;
146
147 Value* mask = nullptr;
148 if (m_value->type() == Double)
149 mask = m_insertionSet.insert<ConstDoubleValue>(m_index, m_origin, -0.0);
150 else {
151 RELEASE_ASSERT(m_value->type() == Float);
152 mask = m_insertionSet.insert<ConstFloatValue>(m_index, m_origin, -0.0f);
153 }
154
155 Value* result = m_insertionSet.insert<Value>(
156 m_index, BitXor, m_origin, m_value->child(0), mask);
157 m_value->replaceWithIdentity(result);
158 break;
159 }
keith_miller@apple.com49cfb9a2016-11-17 19:21:42 +0000160
161 case RotL: {
162 // ARM64 doesn't have a rotate left.
163 if (isARM64()) {
fpizlo@apple.com42624fe2017-03-10 17:49:42 +0000164 Value* newShift = m_insertionSet.insert<Value>(m_index, Neg, m_value->origin(), m_value->child(1));
165 Value* rotate = m_insertionSet.insert<Value>(m_index, RotR, m_value->origin(), m_value->child(0), newShift);
166 m_value->replaceWithIdentity(rotate);
167 break;
keith_miller@apple.com49cfb9a2016-11-17 19:21:42 +0000168 }
169 break;
170 }
fpizlo@apple.com42624fe2017-03-10 17:49:42 +0000171
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +0000172 default:
173 break;
174 }
175 }
176 m_insertionSet.execute(m_block);
177 }
178
179 Procedure& m_proc;
180 BlockInsertionSet m_blockInsertionSet;
181 InsertionSet m_insertionSet;
182 BasicBlock* m_block;
183 unsigned m_index;
184 Value* m_value;
185 Origin m_origin;
186 bool m_changed { false };
187};
188
189bool lowerMacrosImpl(Procedure& proc)
190{
keith_miller@apple.com504d5852017-09-13 01:31:07 +0000191 LowerMacrosAfterOptimizations lowerMacros(proc);
commit-queue@webkit.org9fad4952015-12-12 06:10:07 +0000192 return lowerMacros.run();
193}
194
195} // anonymous namespace
196
197bool lowerMacrosAfterOptimizations(Procedure& proc)
198{
199 PhaseScope phaseScope(proc, "lowerMacrosAfterOptimizations");
200 bool result = lowerMacrosImpl(proc);
201 if (shouldValidateIR())
202 RELEASE_ASSERT(!lowerMacrosImpl(proc));
203 return result;
204}
205
206} } // namespace JSC::B3
207
208#endif // ENABLE(B3_JIT)
209