1/*
2 * Copyright (C) 2015-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#include "config.h"
27#include "B3Validate.h"
28
29#if ENABLE(B3_JIT)
30
31#include "AirCode.h"
32#include "B3ArgumentRegValue.h"
33#include "B3AtomicValue.h"
34#include "B3BasicBlockInlines.h"
35#include "B3Dominators.h"
36#include "B3MemoryValue.h"
37#include "B3Procedure.h"
38#include "B3SlotBaseValue.h"
39#include "B3StackSlot.h"
40#include "B3SwitchValue.h"
41#include "B3UpsilonValue.h"
42#include "B3ValueInlines.h"
43#include "B3Variable.h"
44#include "B3VariableValue.h"
45#include "B3WasmBoundsCheckValue.h"
46#include <wtf/HashSet.h>
47#include <wtf/StringPrintStream.h>
48#include <wtf/text/CString.h>
49
50namespace JSC { namespace B3 {
51
52namespace {
53
54class Validater {
55public:
56 Validater(Procedure& procedure, const char* dumpBefore)
57 : m_procedure(procedure)
58 , m_dumpBefore(dumpBefore)
59 {
60 }
61
62#define VALIDATE(condition, message) do { \
63 if (condition) \
64 break; \
65 fail(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #condition, toCString message); \
66 } while (false)
67
68 void run()
69 {
70 HashSet<BasicBlock*> blocks;
71 HashSet<Value*> valueInProc;
72 HashMap<Value*, unsigned> valueInBlock;
73 HashMap<Value*, BasicBlock*> valueOwner;
74 HashMap<Value*, unsigned> valueIndex;
75 HashMap<Value*, Vector<Optional<Type>>> extractions;
76
77 for (unsigned tuple = 0; tuple < m_procedure.tuples().size(); ++tuple) {
78 VALIDATE(m_procedure.tuples()[tuple].size(), ("In tuple ", tuple));
79 for (unsigned i = 0; i < m_procedure.tuples()[tuple].size(); ++i)
80 VALIDATE(m_procedure.tuples()[tuple][i].isNumeric(), ("In tuple ", tuple, " at index", i));
81 }
82
83 for (BasicBlock* block : m_procedure) {
84 blocks.add(block);
85 for (unsigned i = 0; i < block->size(); ++i) {
86 Value* value = block->at(i);
87 valueInBlock.add(value, 0).iterator->value++;
88 valueOwner.add(value, block);
89 valueIndex.add(value, i);
90 }
91 }
92
93 for (Value* value : m_procedure.values())
94 valueInProc.add(value);
95
96 for (Value* value : valueInProc)
97 VALIDATE(valueInBlock.contains(value), ("At ", *value));
98 for (auto& entry : valueInBlock) {
99 VALIDATE(valueInProc.contains(entry.key), ("At ", *entry.key));
100 VALIDATE(entry.value == 1, ("At ", *entry.key));
101 }
102
103 // Compute dominators ourselves to avoid perturbing Procedure.
104 Dominators dominators(m_procedure);
105
106 for (Value* value : valueInProc) {
107 for (Value* child : value->children()) {
108 VALIDATE(child, ("At ", *value));
109 VALIDATE(valueInProc.contains(child), ("At ", *value, "->", pointerDump(child)));
110 if (valueOwner.get(child) == valueOwner.get(value))
111 VALIDATE(valueIndex.get(value) > valueIndex.get(child), ("At ", *value, "->", pointerDump(child)));
112 else
113 VALIDATE(dominators.dominates(valueOwner.get(child), valueOwner.get(value)), ("at ", *value, "->", pointerDump(child)));
114 }
115 }
116
117 HashMap<BasicBlock*, HashSet<BasicBlock*>> allPredecessors;
118 for (BasicBlock* block : blocks) {
119 VALIDATE(block->size() >= 1, ("At ", *block));
120 for (unsigned i = 0; i < block->size() - 1; ++i)
121 VALIDATE(!block->at(i)->effects().terminal, ("At ", *block->at(i)));
122 VALIDATE(block->last()->effects().terminal, ("At ", *block->last()));
123
124 for (BasicBlock* successor : block->successorBlocks()) {
125 allPredecessors.add(successor, HashSet<BasicBlock*>()).iterator->value.add(block);
126 VALIDATE(
127 blocks.contains(successor), ("At ", *block, "->", pointerDump(successor)));
128 }
129 }
130
131 // Note that this totally allows dead code.
132 for (auto& entry : allPredecessors) {
133 BasicBlock* successor = entry.key;
134 HashSet<BasicBlock*>& predecessors = entry.value;
135 VALIDATE(predecessors == successor->predecessors(), ("At ", *successor));
136 }
137
138 for (Value* value : m_procedure.values()) {
139 for (Value* child : value->children())
140 VALIDATE(child->type() != Void, ("At ", *value, "->", *child));
141 switch (value->opcode()) {
142 case Nop:
143 case Fence:
144 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
145 VALIDATE(!value->numChildren(), ("At ", *value));
146 VALIDATE(value->type() == Void, ("At ", *value));
147 break;
148 case Identity:
149 case Opaque:
150 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
151 VALIDATE(value->numChildren() == 1, ("At ", *value));
152 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
153 VALIDATE(value->type() != Void, ("At ", *value));
154 break;
155 case Const32:
156 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
157 VALIDATE(!value->numChildren(), ("At ", *value));
158 VALIDATE(value->type() == Int32, ("At ", *value));
159 break;
160 case Const64:
161 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
162 VALIDATE(!value->numChildren(), ("At ", *value));
163 VALIDATE(value->type() == Int64, ("At ", *value));
164 break;
165 case ConstDouble:
166 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
167 VALIDATE(!value->numChildren(), ("At ", *value));
168 VALIDATE(value->type() == Double, ("At ", *value));
169 break;
170 case ConstFloat:
171 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
172 VALIDATE(!value->numChildren(), ("At ", *value));
173 VALIDATE(value->type() == Float, ("At ", *value));
174 break;
175 case Set:
176 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
177 VALIDATE(value->numChildren() == 1, ("At ", *value));
178 VALIDATE(value->child(0)->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value));
179 break;
180 case Get:
181 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
182 VALIDATE(!value->numChildren(), ("At ", *value));
183 VALIDATE(value->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value));
184 break;
185 case SlotBase:
186 case FramePointer:
187 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
188 VALIDATE(!value->numChildren(), ("At ", *value));
189 VALIDATE(value->type() == pointerType(), ("At ", *value));
190 break;
191 case ArgumentReg:
192 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
193 VALIDATE(!value->numChildren(), ("At ", *value));
194 VALIDATE(
195 (value->as<ArgumentRegValue>()->argumentReg().isGPR() ? pointerType() : Double)
196 == value->type(), ("At ", *value));
197 break;
198 case Add:
199 case Sub:
200 case Mul:
201 case Div:
202 case UDiv:
203 case Mod:
204 case UMod:
205 case BitAnd:
206 case BitOr:
207 case BitXor:
208 VALIDATE(!value->kind().traps(), ("At ", *value));
209 switch (value->opcode()) {
210 case Div:
211 case Mod:
212 if (value->isChill()) {
213 VALIDATE(value->opcode() == Div || value->opcode() == Mod, ("At ", *value));
214 VALIDATE(value->type().isInt(), ("At ", *value));
215 }
216 break;
217 default:
218 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
219 break;
220 }
221 VALIDATE(value->numChildren() == 2, ("At ", *value));
222 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
223 VALIDATE(value->type() == value->child(1)->type(), ("At ", *value));
224 VALIDATE(value->type().isNumeric(), ("At ", *value));
225 break;
226 case Neg:
227 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
228 VALIDATE(value->numChildren() == 1, ("At ", *value));
229 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
230 VALIDATE(value->type().isNumeric(), ("At ", *value));
231 break;
232 case Shl:
233 case SShr:
234 case ZShr:
235 case RotR:
236 case RotL:
237 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
238 VALIDATE(value->numChildren() == 2, ("At ", *value));
239 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
240 VALIDATE(value->child(1)->type() == Int32, ("At ", *value));
241 VALIDATE(value->type().isInt(), ("At ", *value));
242 break;
243 case BitwiseCast:
244 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
245 VALIDATE(value->numChildren() == 1, ("At ", *value));
246 VALIDATE(value->type() != value->child(0)->type(), ("At ", *value));
247 VALIDATE(
248 (value->type() == Int64 && value->child(0)->type() == Double)
249 || (value->type() == Double && value->child(0)->type() == Int64)
250 || (value->type() == Float && value->child(0)->type() == Int32)
251 || (value->type() == Int32 && value->child(0)->type() == Float),
252 ("At ", *value));
253 break;
254 case SExt8:
255 case SExt16:
256 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
257 VALIDATE(value->numChildren() == 1, ("At ", *value));
258 VALIDATE(value->child(0)->type() == Int32, ("At ", *value));
259 VALIDATE(value->type() == Int32, ("At ", *value));
260 break;
261 case SExt32:
262 case ZExt32:
263 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
264 VALIDATE(value->numChildren() == 1, ("At ", *value));
265 VALIDATE(value->child(0)->type() == Int32, ("At ", *value));
266 VALIDATE(value->type() == Int64, ("At ", *value));
267 break;
268 case Clz:
269 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
270 VALIDATE(value->numChildren() == 1, ("At ", *value));
271 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
272 VALIDATE(value->type().isInt(), ("At ", *value));
273 break;
274 case Trunc:
275 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
276 VALIDATE(value->numChildren() == 1, ("At ", *value));
277 VALIDATE(
278 (value->type() == Int32 && value->child(0)->type() == Int64)
279 || (value->type() == Float && value->child(0)->type() == Double),
280 ("At ", *value));
281 break;
282 case Abs:
283 case Ceil:
284 case Floor:
285 case Sqrt:
286 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
287 VALIDATE(value->numChildren() == 1, ("At ", *value));
288 VALIDATE(value->child(0)->type().isFloat(), ("At ", *value));
289 VALIDATE(value->type().isFloat(), ("At ", *value));
290 break;
291 case IToD:
292 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
293 VALIDATE(value->numChildren() == 1, ("At ", *value));
294 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
295 VALIDATE(value->type() == Double, ("At ", *value));
296 break;
297 case IToF:
298 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
299 VALIDATE(value->numChildren() == 1, ("At ", *value));
300 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
301 VALIDATE(value->type() == Float, ("At ", *value));
302 break;
303 case FloatToDouble:
304 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
305 VALIDATE(value->numChildren() == 1, ("At ", *value));
306 VALIDATE(value->child(0)->type() == Float, ("At ", *value));
307 VALIDATE(value->type() == Double, ("At ", *value));
308 break;
309 case DoubleToFloat:
310 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
311 VALIDATE(value->numChildren() == 1, ("At ", *value));
312 VALIDATE(value->child(0)->type() == Double, ("At ", *value));
313 VALIDATE(value->type() == Float, ("At ", *value));
314 break;
315 case Equal:
316 case NotEqual:
317 case LessThan:
318 case GreaterThan:
319 case LessEqual:
320 case GreaterEqual:
321 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
322 VALIDATE(value->numChildren() == 2, ("At ", *value));
323 VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value));
324 VALIDATE(value->type() == Int32, ("At ", *value));
325 break;
326 case Above:
327 case Below:
328 case AboveEqual:
329 case BelowEqual:
330 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
331 VALIDATE(value->numChildren() == 2, ("At ", *value));
332 VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value));
333 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
334 VALIDATE(value->type() == Int32, ("At ", *value));
335 break;
336 case EqualOrUnordered:
337 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
338 VALIDATE(value->numChildren() == 2, ("At ", *value));
339 VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value));
340 VALIDATE(value->child(0)->type().isFloat(), ("At ", *value));
341 VALIDATE(value->type() == Int32, ("At ", *value));
342 break;
343 case Select:
344 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
345 VALIDATE(value->numChildren() == 3, ("At ", *value));
346 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
347 VALIDATE(value->type() == value->child(1)->type(), ("At ", *value));
348 VALIDATE(value->type() == value->child(2)->type(), ("At ", *value));
349 break;
350 case Load8Z:
351 case Load8S:
352 case Load16Z:
353 case Load16S:
354 VALIDATE(!value->kind().isChill(), ("At ", *value));
355 VALIDATE(value->numChildren() == 1, ("At ", *value));
356 VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value));
357 VALIDATE(value->type() == Int32, ("At ", *value));
358 validateFence(value);
359 validateStackAccess(value);
360 break;
361 case Load:
362 VALIDATE(!value->kind().isChill(), ("At ", *value));
363 VALIDATE(value->numChildren() == 1, ("At ", *value));
364 VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value));
365 VALIDATE(value->type().isNumeric(), ("At ", *value));
366 validateFence(value);
367 validateStackAccess(value);
368 break;
369 case Store8:
370 case Store16:
371 VALIDATE(!value->kind().isChill(), ("At ", *value));
372 VALIDATE(value->numChildren() == 2, ("At ", *value));
373 VALIDATE(value->child(0)->type() == Int32, ("At ", *value));
374 VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value));
375 VALIDATE(value->type() == Void, ("At ", *value));
376 validateFence(value);
377 validateStackAccess(value);
378 break;
379 case Store:
380 VALIDATE(!value->kind().isChill(), ("At ", *value));
381 VALIDATE(value->numChildren() == 2, ("At ", *value));
382 VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value));
383 VALIDATE(value->type() == Void, ("At ", *value));
384 validateFence(value);
385 validateStackAccess(value);
386 break;
387 case AtomicWeakCAS:
388 VALIDATE(!value->kind().isChill(), ("At ", *value));
389 VALIDATE(value->numChildren() == 3, ("At ", *value));
390 VALIDATE(value->type() == Int32, ("At ", *value));
391 VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value));
392 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
393 VALIDATE(value->child(2)->type() == pointerType(), ("At ", *value));
394 validateAtomic(value);
395 validateStackAccess(value);
396 break;
397 case AtomicStrongCAS:
398 VALIDATE(!value->kind().isChill(), ("At ", *value));
399 VALIDATE(value->numChildren() == 3, ("At ", *value));
400 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
401 VALIDATE(value->type() == value->child(1)->type(), ("At ", *value));
402 VALIDATE(value->type().isInt(), ("At ", *value));
403 VALIDATE(value->child(2)->type() == pointerType(), ("At ", *value));
404 validateAtomic(value);
405 validateStackAccess(value);
406 break;
407 case AtomicXchgAdd:
408 case AtomicXchgAnd:
409 case AtomicXchgOr:
410 case AtomicXchgSub:
411 case AtomicXchgXor:
412 case AtomicXchg:
413 VALIDATE(!value->kind().isChill(), ("At ", *value));
414 VALIDATE(value->numChildren() == 2, ("At ", *value));
415 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
416 VALIDATE(value->type().isInt(), ("At ", *value));
417 VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value));
418 validateAtomic(value);
419 validateStackAccess(value);
420 break;
421 case Depend:
422 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
423 VALIDATE(value->numChildren() == 1, ("At ", *value));
424 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
425 VALIDATE(value->type().isInt(), ("At ", *value));
426 break;
427 case WasmAddress:
428 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
429 VALIDATE(value->numChildren() == 1, ("At ", *value));
430 VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value));
431 VALIDATE(value->type() == pointerType(), ("At ", *value));
432 break;
433 case CCall:
434 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
435 VALIDATE(value->numChildren() >= 1, ("At ", *value));
436 VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value));
437 break;
438 case Patchpoint:
439 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
440 if (value->type() == Void) {
441 VALIDATE(value->as<PatchpointValue>()->resultConstraints.size() == 1, ("At ", *value));
442 VALIDATE(value->as<PatchpointValue>()->resultConstraints[0] == ValueRep::WarmAny, ("At ", *value));
443 } else {
444 if (value->type().isNumeric()) {
445 VALIDATE(value->as<PatchpointValue>()->resultConstraints.size() == 1, ("At ", *value));
446 validateStackmapConstraint(value, ConstrainedValue(value, value->as<PatchpointValue>()->resultConstraints[0]), ConstraintRole::Def);
447 } else {
448 VALIDATE(m_procedure.isValidTuple(value->type()), ("At ", *value));
449 VALIDATE(value->as<PatchpointValue>()->resultConstraints.size() == m_procedure.tupleForType(value->type()).size(), ("At ", *value));
450 for (unsigned i = 0; i < value->as<PatchpointValue>()->resultConstraints.size(); ++i)
451 validateStackmapConstraint(value, ConstrainedValue(value, value->as<PatchpointValue>()->resultConstraints[i]), ConstraintRole::Def, i);
452 }
453 }
454 validateStackmap(value);
455 break;
456 case Extract: {
457 VALIDATE(value->numChildren() == 1, ("At ", *value));
458 VALIDATE(value->child(0)->type() == Tuple, ("At ", *value));
459 VALIDATE(value->type().isNumeric(), ("At ", *value));
460 break;
461 }
462 case CheckAdd:
463 case CheckSub:
464 case CheckMul:
465 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
466 VALIDATE(value->numChildren() >= 2, ("At ", *value));
467 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
468 VALIDATE(value->child(1)->type().isInt(), ("At ", *value));
469 VALIDATE(value->as<StackmapValue>()->constrainedChild(0).rep() == ValueRep::WarmAny, ("At ", *value));
470 VALIDATE(value->as<StackmapValue>()->constrainedChild(1).rep() == ValueRep::WarmAny, ("At ", *value));
471 validateStackmap(value);
472 break;
473 case Check:
474 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
475 VALIDATE(value->numChildren() >= 1, ("At ", *value));
476 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
477 VALIDATE(value->as<StackmapValue>()->constrainedChild(0).rep() == ValueRep::WarmAny, ("At ", *value));
478 validateStackmap(value);
479 break;
480 case WasmBoundsCheck:
481 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
482 VALIDATE(value->numChildren() == 1, ("At ", *value));
483 VALIDATE(value->child(0)->type() == Int32, ("At ", *value));
484 switch (value->as<WasmBoundsCheckValue>()->boundsType()) {
485 case WasmBoundsCheckValue::Type::Pinned:
486 VALIDATE(m_procedure.code().isPinned(value->as<WasmBoundsCheckValue>()->bounds().pinnedSize), ("At ", *value));
487 break;
488 case WasmBoundsCheckValue::Type::Maximum:
489 break;
490 }
491 VALIDATE(m_procedure.code().wasmBoundsCheckGenerator(), ("At ", *value));
492 break;
493 case Upsilon:
494 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
495 VALIDATE(value->numChildren() == 1, ("At ", *value));
496 VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value));
497 VALIDATE(value->as<UpsilonValue>()->phi()->opcode() == Phi, ("At ", *value));
498 VALIDATE(value->child(0)->type() != Void, ("At ", *value));
499 VALIDATE(value->child(0)->type() == value->as<UpsilonValue>()->phi()->type(), ("At ", *value));
500 VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value));
501 break;
502 case Phi:
503 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
504 VALIDATE(!value->numChildren(), ("At ", *value));
505 VALIDATE(value->type() != Void, ("At ", *value));
506 break;
507 case Jump:
508 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
509 VALIDATE(!value->numChildren(), ("At ", *value));
510 VALIDATE(value->type() == Void, ("At ", *value));
511 VALIDATE(valueOwner.get(value)->numSuccessors() == 1, ("At ", *value));
512 break;
513 case Oops:
514 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
515 VALIDATE(!value->numChildren(), ("At ", *value));
516 VALIDATE(value->type() == Void, ("At ", *value));
517 VALIDATE(!valueOwner.get(value)->numSuccessors(), ("At ", *value));
518 break;
519 case Return:
520 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
521 VALIDATE(value->numChildren() <= 1, ("At ", *value));
522 VALIDATE(value->type() == Void, ("At ", *value));
523 VALIDATE(!valueOwner.get(value)->numSuccessors(), ("At ", *value));
524 break;
525 case Branch:
526 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
527 VALIDATE(value->numChildren() == 1, ("At ", *value));
528 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
529 VALIDATE(value->type() == Void, ("At ", *value));
530 VALIDATE(valueOwner.get(value)->numSuccessors() == 2, ("At ", *value));
531 break;
532 case Switch: {
533 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
534 VALIDATE(value->numChildren() == 1, ("At ", *value));
535 VALIDATE(value->child(0)->type().isInt(), ("At ", *value));
536 VALIDATE(value->type() == Void, ("At ", *value));
537 VALIDATE(value->as<SwitchValue>()->hasFallThrough(valueOwner.get(value)), ("At ", *value));
538 // This validates the same thing as hasFallThrough, but more explicitly. We want to
539 // make sure that if anyone tries to change the definition of hasFallThrough, they
540 // will feel some pain here, since this is fundamental.
541 VALIDATE(valueOwner.get(value)->numSuccessors() == value->as<SwitchValue>()->numCaseValues() + 1, ("At ", *value));
542
543 // Check that there are no duplicate cases.
544 Vector<int64_t> caseValues = value->as<SwitchValue>()->caseValues();
545 std::sort(caseValues.begin(), caseValues.end());
546 for (unsigned i = 1; i < caseValues.size(); ++i)
547 VALIDATE(caseValues[i - 1] != caseValues[i], ("At ", *value, ", caseValue = ", caseValues[i]));
548 break;
549 }
550 case EntrySwitch:
551 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
552 VALIDATE(!value->numChildren(), ("At ", *value));
553 VALIDATE(value->type() == Void, ("At ", *value));
554 VALIDATE(valueOwner.get(value)->numSuccessors() == m_procedure.numEntrypoints(), ("At ", *value));
555 break;
556 }
557
558 VALIDATE(!(value->effects().writes && value->key()), ("At ", *value));
559 }
560
561 for (Variable* variable : m_procedure.variables())
562 VALIDATE(variable->type() != Void, ("At ", *variable));
563
564 for (BasicBlock* block : m_procedure) {
565 // We expect the predecessor list to be de-duplicated.
566 HashSet<BasicBlock*> predecessors;
567 for (BasicBlock* predecessor : block->predecessors())
568 predecessors.add(predecessor);
569 VALIDATE(block->numPredecessors() == predecessors.size(), ("At ", *block));
570 }
571 }
572
573private:
574 void validateStackmap(Value* value)
575 {
576 StackmapValue* stackmap = value->as<StackmapValue>();
577 VALIDATE(stackmap, ("At ", *value));
578 VALIDATE(stackmap->numChildren() >= stackmap->reps().size(), ("At ", *stackmap));
579 for (ConstrainedValue child : stackmap->constrainedChildren())
580 validateStackmapConstraint(stackmap, child);
581 }
582
583 enum class ConstraintRole {
584 Use,
585 Def
586 };
587 void validateStackmapConstraint(Value* context, const ConstrainedValue& value, ConstraintRole role = ConstraintRole::Use, unsigned tupleIndex = 0)
588 {
589 switch (value.rep().kind()) {
590 case ValueRep::WarmAny:
591 case ValueRep::SomeRegister:
592 case ValueRep::StackArgument:
593 break;
594 case ValueRep::LateColdAny:
595 case ValueRep::ColdAny:
596 VALIDATE(role == ConstraintRole::Use, ("At ", *context, ": ", value));
597 break;
598 case ValueRep::SomeRegisterWithClobber:
599 VALIDATE(role == ConstraintRole::Use, ("At ", *context, ": ", value));
600 VALIDATE(context->as<PatchpointValue>(), ("At ", *context));
601 break;
602 case ValueRep::SomeEarlyRegister:
603 VALIDATE(role == ConstraintRole::Def, ("At ", *context, ": ", value));
604 break;
605 case ValueRep::Register:
606 case ValueRep::LateRegister:
607 case ValueRep::SomeLateRegister:
608 if (value.rep().kind() == ValueRep::LateRegister)
609 VALIDATE(role == ConstraintRole::Use, ("At ", *context, ": ", value));
610 if (value.rep().reg().isGPR()) {
611 if (value.value()->type().isTuple())
612 VALIDATE(m_procedure.extractFromTuple(value.value()->type(), tupleIndex).isInt(), ("At ", *context, ": ", value));
613 else
614 VALIDATE(value.value()->type().isInt(), ("At ", *context, ": ", value));
615 } else {
616 if (value.value()->type().isTuple())
617 VALIDATE(m_procedure.extractFromTuple(value.value()->type(), tupleIndex).isFloat(), ("At ", *context, ": ", value));
618 else
619 VALIDATE(value.value()->type().isFloat(), ("At ", *context, ": ", value));
620 }
621 break;
622 default:
623 VALIDATE(false, ("At ", *context, ": ", value));
624 break;
625 }
626 }
627
628 void validateFence(Value* value)
629 {
630 MemoryValue* memory = value->as<MemoryValue>();
631 if (memory->hasFence())
632 VALIDATE(memory->accessBank() == GP, ("Fence at ", *memory));
633 }
634
635 void validateAtomic(Value* value)
636 {
637 AtomicValue* atomic = value->as<AtomicValue>();
638
639 VALIDATE(bestType(GP, atomic->accessWidth()) == atomic->accessType(), ("At ", *value));
640 }
641
642 void validateStackAccess(Value* value)
643 {
644 MemoryValue* memory = value->as<MemoryValue>();
645 SlotBaseValue* slotBase = value->lastChild()->as<SlotBaseValue>();
646 if (!slotBase)
647 return;
648
649 VALIDATE(memory->offset() >= 0, ("At ", *value));
650 }
651
652 NO_RETURN_DUE_TO_CRASH void fail(
653 const char* filename, int lineNumber, const char* function, const char* condition,
654 CString message)
655 {
656 CString failureMessage;
657 {
658 StringPrintStream out;
659 out.print("B3 VALIDATION FAILURE\n");
660 out.print(" ", condition, " (", filename, ":", lineNumber, ")\n");
661 out.print(" ", message, "\n");
662 out.print(" After ", m_procedure.lastPhaseName(), "\n");
663 failureMessage = out.toCString();
664 }
665
666 dataLog(failureMessage);
667 if (m_dumpBefore) {
668 dataLog("Before ", m_procedure.lastPhaseName(), ":\n");
669 dataLog(m_dumpBefore);
670 }
671 dataLog("At time of failure:\n");
672 dataLog(m_procedure);
673
674 dataLog(failureMessage);
675 WTFReportAssertionFailure(filename, lineNumber, function, condition);
676 CRASH();
677 }
678
679 Procedure& m_procedure;
680 const char* m_dumpBefore;
681};
682
683} // anonymous namespace
684
685void validate(Procedure& procedure, const char* dumpBefore)
686{
687 Validater validater(procedure, dumpBefore);
688 validater.run();
689}
690
691} } // namespace JSC::B3
692
693#endif // ENABLE(B3_JIT)
694