| OLD | NEW |
| 1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===// | 1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 case kExprI32LtS: | 222 case kExprI32LtS: |
| 223 case kExprI64LtS: | 223 case kExprI64LtS: |
| 224 case kExprI32LtU: | 224 case kExprI32LtU: |
| 225 case kExprI64LtU: | 225 case kExprI64LtU: |
| 226 case kExprI32GeS: | 226 case kExprI32GeS: |
| 227 case kExprI64GeS: | 227 case kExprI64GeS: |
| 228 case kExprI32GtS: | 228 case kExprI32GtS: |
| 229 case kExprI64GtS: | 229 case kExprI64GtS: |
| 230 case kExprI32GtU: | 230 case kExprI32GtU: |
| 231 case kExprI64GtU: | 231 case kExprI64GtU: |
| 232 case kExprF32Eq: |
| 233 case kExprF64Eq: |
| 232 case kExprF32Ne: | 234 case kExprF32Ne: |
| 233 case kExprF64Ne: | 235 case kExprF64Ne: |
| 234 case kExprF32Le: | 236 case kExprF32Le: |
| 235 case kExprF64Le: | 237 case kExprF64Le: |
| 238 case kExprF32Lt: |
| 239 case kExprF64Lt: |
| 240 case kExprF32Ge: |
| 241 case kExprF64Ge: |
| 242 case kExprF32Gt: |
| 243 case kExprF64Gt: |
| 236 case kExprI32LeS: | 244 case kExprI32LeS: |
| 237 case kExprI64LeS: | 245 case kExprI64LeS: |
| 238 case kExprI32GeU: | 246 case kExprI32GeU: |
| 239 case kExprI64GeU: | 247 case kExprI64GeU: |
| 240 case kExprI32LeU: | 248 case kExprI32LeU: |
| 241 case kExprI64LeU: | 249 case kExprI64LeU: |
| 242 return true; | 250 return true; |
| 243 default: | 251 default: |
| 244 return false; | 252 return false; |
| 245 } | 253 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 assert(Count == InEdges.size()); | 325 assert(Count == InEdges.size()); |
| 318 | 326 |
| 319 assert(Count > 0); | 327 assert(Count > 0); |
| 320 | 328 |
| 321 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); | 329 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); |
| 322 | 330 |
| 323 // Multiply by 10 in case more things get added later. | 331 // Multiply by 10 in case more things get added later. |
| 324 | 332 |
| 325 // TODO(eholk): find a better way besides multiplying by some arbitrary | 333 // TODO(eholk): find a better way besides multiplying by some arbitrary |
| 326 // constant. | 334 // constant. |
| 327 auto *Phi = InstPhi::create(Func, Count * 10, Dest); | 335 auto *Phi = InstPhi::create(Func, Count * 200, Dest); |
| 328 for (uint32_t i = 0; i < Count; ++i) { | 336 for (uint32_t i = 0; i < Count; ++i) { |
| 329 auto *Op = Vals[i].toOperand(); | 337 auto *Op = Vals[i].toOperand(); |
| 330 assert(Op); | 338 assert(Op); |
| 331 Phi->addArgument(Op, InEdges[i]); | 339 Phi->addArgument(Op, InEdges[i]); |
| 332 } | 340 } |
| 333 setDefiningInst(Dest, Phi); | 341 setDefiningInst(Dest, Phi); |
| 334 Control.toCfgNode()->appendInst(Phi); | 342 Control.toCfgNode()->appendInst(Phi); |
| 335 LOG(out << Node(Dest) << "\n"); | 343 LOG(out << Node(Dest) << "\n"); |
| 336 return OperandNode(Dest); | 344 return OperandNode(Dest); |
| 337 } | 345 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 case kExprF32Add: | 394 case kExprF32Add: |
| 387 case kExprF64Add: | 395 case kExprF64Add: |
| 388 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fadd, | 396 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fadd, |
| 389 Dest, Left, Right)); | 397 Dest, Left, Right)); |
| 390 break; | 398 break; |
| 391 case kExprI32Sub: | 399 case kExprI32Sub: |
| 392 case kExprI64Sub: | 400 case kExprI64Sub: |
| 393 Control()->appendInst( | 401 Control()->appendInst( |
| 394 InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right)); | 402 InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right)); |
| 395 break; | 403 break; |
| 404 case kExprF32Sub: |
| 405 case kExprF64Sub: |
| 406 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fsub, |
| 407 Dest, Left, Right)); |
| 408 break; |
| 396 case kExprI32Mul: | 409 case kExprI32Mul: |
| 397 case kExprI64Mul: | 410 case kExprI64Mul: |
| 398 Control()->appendInst( | 411 Control()->appendInst( |
| 399 InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right)); | 412 InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right)); |
| 400 break; | 413 break; |
| 414 case kExprF32Mul: |
| 415 case kExprF64Mul: |
| 416 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fmul, |
| 417 Dest, Left, Right)); |
| 418 break; |
| 419 case kExprI32DivS: |
| 420 case kExprI64DivS: |
| 421 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Sdiv, |
| 422 Dest, Left, Right)); |
| 423 break; |
| 401 case kExprI32DivU: | 424 case kExprI32DivU: |
| 402 case kExprI64DivU: | 425 case kExprI64DivU: |
| 403 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv, | 426 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv, |
| 404 Dest, Left, Right)); | 427 Dest, Left, Right)); |
| 405 break; | 428 break; |
| 429 case kExprF32Div: |
| 430 case kExprF64Div: |
| 431 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fdiv, |
| 432 Dest, Left, Right)); |
| 433 break; |
| 406 case kExprI32RemU: | 434 case kExprI32RemU: |
| 407 case kExprI64RemU: | 435 case kExprI64RemU: |
| 408 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem, | 436 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem, |
| 409 Dest, Left, Right)); | 437 Dest, Left, Right)); |
| 410 break; | 438 break; |
| 411 case kExprI32RemS: | 439 case kExprI32RemS: |
| 412 case kExprI64RemS: | 440 case kExprI64RemS: |
| 413 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Srem, | 441 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Srem, |
| 414 Dest, Left, Right)); | 442 Dest, Left, Right)); |
| 415 break; | 443 break; |
| 416 case kExprI32Ior: | 444 case kExprI32Ior: |
| 417 case kExprI64Ior: | 445 case kExprI64Ior: |
| 418 Control()->appendInst( | 446 Control()->appendInst( |
| 419 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Left, Right)); | 447 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Left, Right)); |
| 420 break; | 448 break; |
| 421 case kExprI32Xor: | 449 case kExprI32Xor: |
| 422 case kExprI64Xor: | 450 case kExprI64Xor: |
| 423 Control()->appendInst( | 451 Control()->appendInst( |
| 424 InstArithmetic::create(Func, InstArithmetic::Xor, Dest, Left, Right)); | 452 InstArithmetic::create(Func, InstArithmetic::Xor, Dest, Left, Right)); |
| 425 break; | 453 break; |
| 426 case kExprI32Shl: | 454 case kExprI32Shl: |
| 427 case kExprI64Shl: | 455 case kExprI64Shl: |
| 428 Control()->appendInst( | 456 Control()->appendInst( |
| 429 InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right)); | 457 InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right)); |
| 430 break; | 458 break; |
| 431 case kExprI32Rol: { | 459 case kExprI32Rol: |
| 460 case kExprI64Rol: { |
| 432 // TODO(eholk): add rotate as an ICE instruction to make it easier to take | 461 // TODO(eholk): add rotate as an ICE instruction to make it easier to take |
| 433 // advantage of hardware support. | 462 // advantage of hardware support. |
| 434 | 463 |
| 435 // TODO(eholk): don't hardcode so many numbers. | 464 const auto DestTy = Left.toOperand()->getType(); |
| 436 auto *Masked = makeVariable(IceType_i32); | 465 const SizeT BitCount = typeWidthInBytes(DestTy) * 8; |
| 437 auto *Bottom = makeVariable(IceType_i32); | 466 |
| 438 auto *Top = makeVariable(IceType_i32); | 467 auto *Masked = makeVariable(DestTy); |
| 439 Control()->appendInst(InstArithmetic::create( | 468 auto *Bottom = makeVariable(DestTy); |
| 440 Func, InstArithmetic::And, Masked, Right, Ctx->getConstantInt32(31))); | 469 auto *Top = makeVariable(DestTy); |
| 470 Control()->appendInst( |
| 471 InstArithmetic::create(Func, InstArithmetic::And, Masked, Right, |
| 472 Ctx->getConstantInt(DestTy, BitCount - 1))); |
| 441 Control()->appendInst( | 473 Control()->appendInst( |
| 442 InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked)); | 474 InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked)); |
| 443 auto *RotShift = makeVariable(IceType_i32); | 475 auto *RotShift = makeVariable(DestTy); |
| 476 Control()->appendInst(InstArithmetic::create( |
| 477 Func, InstArithmetic::Sub, RotShift, |
| 478 Ctx->getConstantInt(DestTy, BitCount), Masked)); |
| 479 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
| 480 Bottom, Left, RotShift)); |
| 444 Control()->appendInst( | 481 Control()->appendInst( |
| 445 InstArithmetic::create(Func, InstArithmetic::Sub, RotShift, | 482 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); |
| 446 Ctx->getConstantInt32(32), Masked)); | 483 break; |
| 484 } |
| 485 case kExprI32Ror: |
| 486 case kExprI64Ror: { |
| 487 // TODO(eholk): add rotate as an ICE instruction to make it easier to take |
| 488 // advantage of hardware support. |
| 489 |
| 490 const auto DestTy = Left.toOperand()->getType(); |
| 491 const SizeT BitCount = typeWidthInBytes(DestTy) * 8; |
| 492 |
| 493 auto *Masked = makeVariable(DestTy); |
| 494 auto *Bottom = makeVariable(DestTy); |
| 495 auto *Top = makeVariable(DestTy); |
| 496 Control()->appendInst( |
| 497 InstArithmetic::create(Func, InstArithmetic::And, Masked, Right, |
| 498 Ctx->getConstantInt(DestTy, BitCount - 1))); |
| 447 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, | 499 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
| 448 Bottom, Left, Masked)); | 500 Top, Left, Masked)); |
| 501 auto *RotShift = makeVariable(DestTy); |
| 502 Control()->appendInst(InstArithmetic::create( |
| 503 Func, InstArithmetic::Sub, RotShift, |
| 504 Ctx->getConstantInt(DestTy, BitCount), Masked)); |
| 505 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Shl, |
| 506 Bottom, Left, RotShift)); |
| 449 Control()->appendInst( | 507 Control()->appendInst( |
| 450 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); | 508 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); |
| 451 break; | 509 break; |
| 452 } | 510 } |
| 453 case kExprI32ShrU: | 511 case kExprI32ShrU: |
| 454 case kExprI64ShrU: | 512 case kExprI64ShrU: |
| 513 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
| 514 Dest, Left, Right)); |
| 515 break; |
| 455 case kExprI32ShrS: | 516 case kExprI32ShrS: |
| 456 case kExprI64ShrS: | 517 case kExprI64ShrS: |
| 457 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr, | 518 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr, |
| 458 Dest, Left, Right)); | 519 Dest, Left, Right)); |
| 459 break; | 520 break; |
| 460 case kExprI32And: | 521 case kExprI32And: |
| 461 case kExprI64And: | 522 case kExprI64And: |
| 462 Control()->appendInst( | 523 Control()->appendInst( |
| 463 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); | 524 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); |
| 464 break; | 525 break; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 586 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 526 break; | 587 break; |
| 527 } | 588 } |
| 528 case kExprI32GeS: | 589 case kExprI32GeS: |
| 529 case kExprI64GeS: { | 590 case kExprI64GeS: { |
| 530 auto *TmpDest = makeVariable(IceType_i1); | 591 auto *TmpDest = makeVariable(IceType_i1); |
| 531 Control()->appendInst( | 592 Control()->appendInst( |
| 532 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); | 593 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); |
| 533 Control()->appendInst( | 594 Control()->appendInst( |
| 534 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 595 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 596 break; |
| 535 } | 597 } |
| 536 case kExprI32GtS: | 598 case kExprI32GtS: |
| 537 case kExprI64GtS: { | 599 case kExprI64GtS: { |
| 538 auto *TmpDest = makeVariable(IceType_i1); | 600 auto *TmpDest = makeVariable(IceType_i1); |
| 539 Control()->appendInst( | 601 Control()->appendInst( |
| 540 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); | 602 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); |
| 541 Control()->appendInst( | 603 Control()->appendInst( |
| 542 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 604 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 543 break; | 605 break; |
| 544 } | 606 } |
| 545 case kExprI32GtU: | 607 case kExprI32GtU: |
| 546 case kExprI64GtU: { | 608 case kExprI64GtU: { |
| 547 auto *TmpDest = makeVariable(IceType_i1); | 609 auto *TmpDest = makeVariable(IceType_i1); |
| 548 Control()->appendInst( | 610 Control()->appendInst( |
| 549 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); | 611 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); |
| 550 Control()->appendInst( | 612 Control()->appendInst( |
| 551 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 613 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 552 break; | 614 break; |
| 553 } | 615 } |
| 616 case kExprF32Eq: |
| 617 case kExprF64Eq: { |
| 618 auto *TmpDest = makeVariable(IceType_i1); |
| 619 Control()->appendInst( |
| 620 InstFcmp::create(Func, InstFcmp::Ueq, TmpDest, Left, Right)); |
| 621 Control()->appendInst( |
| 622 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 623 break; |
| 624 } |
| 554 case kExprF32Ne: | 625 case kExprF32Ne: |
| 555 case kExprF64Ne: { | 626 case kExprF64Ne: { |
| 556 auto *TmpDest = makeVariable(IceType_i1); | 627 auto *TmpDest = makeVariable(IceType_i1); |
| 557 Control()->appendInst( | 628 Control()->appendInst( |
| 558 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); | 629 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); |
| 559 Control()->appendInst( | 630 Control()->appendInst( |
| 560 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 631 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 561 break; | 632 break; |
| 562 } | 633 } |
| 563 case kExprF32Le: | 634 case kExprF32Le: |
| 564 case kExprF64Le: { | 635 case kExprF64Le: { |
| 565 auto *TmpDest = makeVariable(IceType_i1); | 636 auto *TmpDest = makeVariable(IceType_i1); |
| 566 Control()->appendInst( | 637 Control()->appendInst( |
| 567 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); | 638 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); |
| 568 Control()->appendInst( | 639 Control()->appendInst( |
| 569 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 640 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 570 break; | 641 break; |
| 571 } | 642 } |
| 643 case kExprF32Lt: |
| 644 case kExprF64Lt: { |
| 645 auto *TmpDest = makeVariable(IceType_i1); |
| 646 Control()->appendInst( |
| 647 InstFcmp::create(Func, InstFcmp::Ult, TmpDest, Left, Right)); |
| 648 Control()->appendInst( |
| 649 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 650 break; |
| 651 } |
| 652 case kExprF32Ge: |
| 653 case kExprF64Ge: { |
| 654 auto *TmpDest = makeVariable(IceType_i1); |
| 655 Control()->appendInst( |
| 656 InstFcmp::create(Func, InstFcmp::Uge, TmpDest, Left, Right)); |
| 657 Control()->appendInst( |
| 658 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 659 break; |
| 660 } |
| 661 case kExprF32Gt: |
| 662 case kExprF64Gt: { |
| 663 auto *TmpDest = makeVariable(IceType_i1); |
| 664 Control()->appendInst( |
| 665 InstFcmp::create(Func, InstFcmp::Ugt, TmpDest, Left, Right)); |
| 666 Control()->appendInst( |
| 667 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 668 break; |
| 669 } |
| 572 default: | 670 default: |
| 573 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); | 671 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); |
| 574 llvm::report_fatal_error("Uncovered or invalid binop."); | 672 llvm::report_fatal_error("Uncovered or invalid binop."); |
| 575 return OperandNode(nullptr); | 673 return OperandNode(nullptr); |
| 576 } | 674 } |
| 577 LOG(out << Dest << "\n"); | 675 LOG(out << Dest << "\n"); |
| 578 return OperandNode(Dest); | 676 return OperandNode(Dest); |
| 579 } | 677 } |
| 580 Node Unop(wasm::WasmOpcode Opcode, Node Input) { | 678 Node Unop(wasm::WasmOpcode Opcode, Node Input) { |
| 581 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input | 679 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input |
| 582 << ") = "); | 680 << ") = "); |
| 583 Ice::Variable *Dest = nullptr; | 681 Ice::Variable *Dest = nullptr; |
| 584 switch (Opcode) { | 682 switch (Opcode) { |
| 585 case kExprI32Eqz: { | 683 case kExprI32Eqz: { |
| 586 Dest = makeVariable(IceType_i32); | 684 Dest = makeVariable(IceType_i32); |
| 587 auto *Tmp = makeVariable(IceType_i1); | 685 auto *Tmp = makeVariable(IceType_i1); |
| 588 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | 686 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, |
| 589 Ctx->getConstantInt32(0))); | 687 Ctx->getConstantInt32(0))); |
| 590 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); | 688 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); |
| 591 break; | 689 break; |
| 592 } | 690 } |
| 593 case kExprI64Eqz: { | 691 case kExprI64Eqz: { |
| 594 Dest = makeVariable(IceType_i32); | 692 Dest = makeVariable(IceType_i32); |
| 595 auto *Tmp = makeVariable(IceType_i1); | 693 auto *Tmp = makeVariable(IceType_i1); |
| 596 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | 694 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, |
| 597 Ctx->getConstantInt64(0))); | 695 Ctx->getConstantInt64(0))); |
| 598 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); | 696 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); |
| 599 break; | 697 break; |
| 600 } | 698 } |
| 699 case kExprI32Ctz: { |
| 700 Dest = makeVariable(IceType_i32); |
| 701 const auto FnName = Ctx->getGlobalString("llvm.cttz.i32"); |
| 702 bool BadInstrinsic = false; |
| 703 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 704 assert(!BadInstrinsic); |
| 705 assert(Info); |
| 706 |
| 707 auto *Call = InstIntrinsicCall::create( |
| 708 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 709 Call->addArg(Input); |
| 710 Control()->appendInst(Call); |
| 711 break; |
| 712 } |
| 601 case kExprF32Neg: { | 713 case kExprF32Neg: { |
| 602 Dest = makeVariable(IceType_f32); | 714 Dest = makeVariable(IceType_f32); |
| 603 Control()->appendInst(InstArithmetic::create( | 715 Control()->appendInst(InstArithmetic::create( |
| 604 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); | 716 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); |
| 605 break; | 717 break; |
| 606 } | 718 } |
| 607 case kExprF64Neg: { | 719 case kExprF64Neg: { |
| 608 Dest = makeVariable(IceType_f64); | 720 Dest = makeVariable(IceType_f64); |
| 609 Control()->appendInst(InstArithmetic::create( | 721 Control()->appendInst(InstArithmetic::create( |
| 610 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input)); | 722 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input)); |
| 611 break; | 723 break; |
| 612 } | 724 } |
| 725 case kExprF32Abs: { |
| 726 Dest = makeVariable(IceType_f32); |
| 727 const auto FnName = Ctx->getGlobalString("llvm.fabs.f32"); |
| 728 bool BadInstrinsic = false; |
| 729 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 730 assert(!BadInstrinsic); |
| 731 assert(Info); |
| 732 |
| 733 auto *Call = InstIntrinsicCall::create( |
| 734 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 735 Call->addArg(Input); |
| 736 Control()->appendInst(Call); |
| 737 break; |
| 738 } |
| 739 case kExprF64Abs: { |
| 740 Dest = makeVariable(IceType_f64); |
| 741 const auto FnName = Ctx->getGlobalString("llvm.fabs.f64"); |
| 742 bool BadInstrinsic = false; |
| 743 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 744 assert(!BadInstrinsic); |
| 745 assert(Info); |
| 746 |
| 747 auto *Call = InstIntrinsicCall::create( |
| 748 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 749 Call->addArg(Input); |
| 750 Control()->appendInst(Call); |
| 751 break; |
| 752 } |
| 753 case kExprF32Floor: { |
| 754 Dest = makeVariable(IceType_f64); |
| 755 const auto FnName = Ctx->getGlobalString("_ZN3env5floorEf"); |
| 756 constexpr bool HasTailCall = false; |
| 757 |
| 758 auto *Call = InstCall::create( |
| 759 Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall); |
| 760 Call->addArg(Input); |
| 761 Control()->appendInst(Call); |
| 762 break; |
| 763 } |
| 764 case kExprF64Floor: { |
| 765 Dest = makeVariable(IceType_f64); |
| 766 const auto FnName = Ctx->getGlobalString("_ZN3env5floorEd"); |
| 767 constexpr bool HasTailCall = false; |
| 768 |
| 769 auto *Call = InstCall::create( |
| 770 Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall); |
| 771 Call->addArg(Input); |
| 772 Control()->appendInst(Call); |
| 773 break; |
| 774 } |
| 613 case kExprI64UConvertI32: | 775 case kExprI64UConvertI32: |
| 614 Dest = makeVariable(IceType_i64); | 776 Dest = makeVariable(IceType_i64); |
| 615 Control()->appendInst( | 777 Control()->appendInst( |
| 616 InstCast::create(Func, InstCast::Zext, Dest, Input)); | 778 InstCast::create(Func, InstCast::Zext, Dest, Input)); |
| 617 break; | 779 break; |
| 618 case kExprI64SConvertI32: | 780 case kExprI64SConvertI32: |
| 619 Dest = makeVariable(IceType_i64); | 781 Dest = makeVariable(IceType_i64); |
| 620 Control()->appendInst( | 782 Control()->appendInst( |
| 621 InstCast::create(Func, InstCast::Sext, Dest, Input)); | 783 InstCast::create(Func, InstCast::Sext, Dest, Input)); |
| 622 break; | 784 break; |
| 785 case kExprI32SConvertF32: |
| 786 Dest = makeVariable(IceType_i32); |
| 787 Control()->appendInst( |
| 788 InstCast::create(Func, InstCast::Fptosi, Dest, Input)); |
| 789 break; |
| 790 case kExprI32UConvertF32: |
| 791 Dest = makeVariable(IceType_i32); |
| 792 Control()->appendInst( |
| 793 InstCast::create(Func, InstCast::Fptoui, Dest, Input)); |
| 794 break; |
| 795 case kExprI32SConvertF64: |
| 796 Dest = makeVariable(IceType_i32); |
| 797 Control()->appendInst( |
| 798 InstCast::create(Func, InstCast::Fptosi, Dest, Input)); |
| 799 break; |
| 800 case kExprI32UConvertF64: |
| 801 Dest = makeVariable(IceType_i32); |
| 802 Control()->appendInst( |
| 803 InstCast::create(Func, InstCast::Fptoui, Dest, Input)); |
| 804 break; |
| 805 case kExprI32ReinterpretF32: |
| 806 Dest = makeVariable(IceType_i32); |
| 807 Control()->appendInst( |
| 808 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 809 break; |
| 810 case kExprI64ReinterpretF64: |
| 811 Dest = makeVariable(IceType_i64); |
| 812 Control()->appendInst( |
| 813 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 814 break; |
| 815 case kExprF64ReinterpretI64: |
| 816 Dest = makeVariable(IceType_f64); |
| 817 Control()->appendInst( |
| 818 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 819 break; |
| 623 case kExprI32ConvertI64: | 820 case kExprI32ConvertI64: |
| 624 Dest = makeVariable(IceType_i32); | 821 Dest = makeVariable(IceType_i32); |
| 625 Control()->appendInst( | 822 Control()->appendInst( |
| 626 InstCast::create(Func, InstCast::Trunc, Dest, Input)); | 823 InstCast::create(Func, InstCast::Trunc, Dest, Input)); |
| 627 break; | 824 break; |
| 628 case kExprF64SConvertI32: | 825 case kExprF64SConvertI32: |
| 629 Dest = makeVariable(IceType_f64); | 826 Dest = makeVariable(IceType_f64); |
| 630 Control()->appendInst( | 827 Control()->appendInst( |
| 631 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); | 828 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); |
| 632 break; | 829 break; |
| 830 case kExprF64UConvertI32: |
| 831 Dest = makeVariable(IceType_f64); |
| 832 Control()->appendInst( |
| 833 InstCast::create(Func, InstCast::Uitofp, Dest, Input)); |
| 834 break; |
| 835 case kExprF64ConvertF32: |
| 836 Dest = makeVariable(IceType_f64); |
| 837 Control()->appendInst( |
| 838 InstCast::create(Func, InstCast::Fpext, Dest, Input)); |
| 839 break; |
| 840 case kExprF32SConvertI32: |
| 841 Dest = makeVariable(IceType_f32); |
| 842 Control()->appendInst( |
| 843 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); |
| 844 break; |
| 845 case kExprF32UConvertI32: |
| 846 Dest = makeVariable(IceType_f32); |
| 847 Control()->appendInst( |
| 848 InstCast::create(Func, InstCast::Uitofp, Dest, Input)); |
| 849 break; |
| 850 case kExprF32ReinterpretI32: |
| 851 Dest = makeVariable(IceType_f32); |
| 852 Control()->appendInst( |
| 853 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 854 break; |
| 855 case kExprF32ConvertF64: |
| 856 Dest = makeVariable(IceType_f32); |
| 857 Control()->appendInst( |
| 858 InstCast::create(Func, InstCast::Fptrunc, Dest, Input)); |
| 859 break; |
| 633 default: | 860 default: |
| 634 LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); | 861 LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); |
| 635 llvm::report_fatal_error("Uncovered or invalid unop."); | 862 llvm::report_fatal_error("Uncovered or invalid unop."); |
| 636 return OperandNode(nullptr); | 863 return OperandNode(nullptr); |
| 637 } | 864 } |
| 638 LOG(out << Dest << "\n"); | 865 LOG(out << Dest << "\n"); |
| 639 return OperandNode(Dest); | 866 return OperandNode(Dest); |
| 640 } | 867 } |
| 641 uint32_t InputCount(CfgNode *Node) const { return Node->getInEdges().size(); } | 868 uint32_t InputCount(CfgNode *Node) const { return Node->getInEdges().size(); } |
| 642 bool IsPhiWithMerge(Node Phi, Node Merge) const { | 869 bool IsPhiWithMerge(Node Phi, Node Merge) const { |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 | 1173 |
| 947 RealAddr = RealAddrV; | 1174 RealAddr = RealAddrV; |
| 948 } else { | 1175 } else { |
| 949 RealAddr = MemBase; | 1176 RealAddr = MemBase; |
| 950 } | 1177 } |
| 951 return RealAddr; | 1178 return RealAddr; |
| 952 } | 1179 } |
| 953 | 1180 |
| 954 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, | 1181 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, |
| 955 uint32_t Offset) { | 1182 uint32_t Offset) { |
| 956 LOG(out << "LoadMem(" << Index << "[" << Offset << "]) = "); | 1183 LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset |
| 1184 << "]) = "); |
| 957 | 1185 |
| 958 auto *RealAddr = sanitizeAddress(Index, Offset); | 1186 auto *RealAddr = sanitizeAddress(Index, Offset); |
| 959 | 1187 |
| 960 auto *LoadResult = makeVariable(toIceType(MemType)); | 1188 auto *LoadResult = makeVariable(toIceType(MemType)); |
| 961 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr)); | 1189 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr)); |
| 962 | 1190 |
| 963 // and cast, if needed | 1191 // and cast, if needed |
| 964 Ice::Variable *Result = nullptr; | 1192 Ice::Variable *Result = nullptr; |
| 965 if (toIceType(Type) != toIceType(MemType)) { | 1193 if (toIceType(Type) != toIceType(MemType)) { |
| 966 auto DestType = toIceType(Type); | 1194 auto DestType = toIceType(Type); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 981 llvm::report_fatal_error("Unsupported type for memory load"); | 1209 llvm::report_fatal_error("Unsupported type for memory load"); |
| 982 } | 1210 } |
| 983 } else { | 1211 } else { |
| 984 Result = LoadResult; | 1212 Result = LoadResult; |
| 985 } | 1213 } |
| 986 | 1214 |
| 987 LOG(out << Result << "\n"); | 1215 LOG(out << Result << "\n"); |
| 988 return OperandNode(Result); | 1216 return OperandNode(Result); |
| 989 } | 1217 } |
| 990 void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) { | 1218 void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) { |
| 991 LOG(out << "StoreMem(" << Index << "[" << Offset << "] = " << Val << ")" | 1219 LOG(out << "StoreMem." << toIceType(Type) << "(" << Index << "[" << Offset |
| 1220 << "] = " << Val << ")" |
| 992 << "\n"); | 1221 << "\n"); |
| 993 | 1222 |
| 994 auto *RealAddr = sanitizeAddress(Index, Offset); | 1223 auto *RealAddr = sanitizeAddress(Index, Offset); |
| 995 | 1224 |
| 996 // cast the value to the right type, if needed | 1225 // cast the value to the right type, if needed |
| 997 Operand *StoreVal = nullptr; | 1226 Operand *StoreVal = nullptr; |
| 998 if (toIceType(Type) != Val.toOperand()->getType()) { | 1227 if (toIceType(Type) != Val.toOperand()->getType()) { |
| 999 auto *LocalStoreVal = makeVariable(toIceType(Type)); | 1228 auto *LocalStoreVal = makeVariable(toIceType(Type)); |
| 1000 Control()->appendInst( | 1229 Control()->appendInst( |
| 1001 InstCast::create(Func, InstCast::Trunc, LocalStoreVal, Val)); | 1230 InstCast::create(Func, InstCast::Trunc, LocalStoreVal, Val)); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 | 1323 |
| 1095 // We don't always know where the incoming branches are in phi nodes, so this | 1324 // We don't always know where the incoming branches are in phi nodes, so this |
| 1096 // function finds them. | 1325 // function finds them. |
| 1097 Func->fixPhiNodes(); | 1326 Func->fixPhiNodes(); |
| 1098 | 1327 |
| 1099 Func->computeInOutEdges(); | 1328 Func->computeInOutEdges(); |
| 1100 | 1329 |
| 1101 return Func; | 1330 return Func; |
| 1102 } | 1331 } |
| 1103 | 1332 |
| 1333 // TODO(eholk): compute the correct buffer size. This uses 256k by default, |
| 1334 // which has been big enough for testing but is not a general solution. |
| 1335 constexpr SizeT BUFFER_SIZE = 256 << 10; |
| 1336 |
| 1104 WasmTranslator::WasmTranslator(GlobalContext *Ctx) | 1337 WasmTranslator::WasmTranslator(GlobalContext *Ctx) |
| 1105 : Translator(Ctx), Buffer(new uint8_t[24 << 10]), BufferSize(24 << 10) { | 1338 : Translator(Ctx), Buffer(new uint8_t[BUFFER_SIZE]), |
| 1106 // TODO(eholk): compute the correct buffer size. This uses 24k by default, | 1339 BufferSize(BUFFER_SIZE) {} |
| 1107 // which has been big enough for testing but is not a general solution. | |
| 1108 } | |
| 1109 | 1340 |
| 1110 void WasmTranslator::translate( | 1341 void WasmTranslator::translate( |
| 1111 const std::string &IRFilename, | 1342 const std::string &IRFilename, |
| 1112 std::unique_ptr<llvm::DataStreamer> InputStream) { | 1343 std::unique_ptr<llvm::DataStreamer> InputStream) { |
| 1113 LOG(out << "Initializing v8/wasm stuff..." | 1344 LOG(out << "Initializing v8/wasm stuff..." |
| 1114 << "\n"); | 1345 << "\n"); |
| 1115 Zone Zone; | 1346 Zone Zone; |
| 1116 ZoneScope _(&Zone); | 1347 ZoneScope _(&Zone); |
| 1117 | 1348 |
| 1118 SizeT BytesRead = InputStream->GetBytes(Buffer.get(), BufferSize); | 1349 SizeT BytesRead = InputStream->GetBytes(Buffer.get(), BufferSize); |
| 1119 LOG(out << "Read " << BytesRead << " bytes" | 1350 LOG(out << "Read " << BytesRead << " bytes" |
| 1120 << "\n"); | 1351 << "\n"); |
| 1352 assert(BytesRead < BufferSize); |
| 1121 | 1353 |
| 1122 LOG(out << "Decoding module " << IRFilename << "\n"); | 1354 LOG(out << "Decoding module " << IRFilename << "\n"); |
| 1123 | 1355 |
| 1124 constexpr v8::internal::Isolate *NoIsolate = nullptr; | 1356 constexpr v8::internal::Isolate *NoIsolate = nullptr; |
| 1125 auto Result = DecodeWasmModule(NoIsolate, &Zone, Buffer.get(), | 1357 auto Result = DecodeWasmModule(NoIsolate, &Zone, Buffer.get(), |
| 1126 Buffer.get() + BytesRead, false, kWasmOrigin); | 1358 Buffer.get() + BytesRead, false, kWasmOrigin); |
| 1127 | 1359 |
| 1128 auto Module = Result.val; | 1360 auto Module = Result.val; |
| 1129 | 1361 |
| 1130 LOG(out << "Module info:" | 1362 LOG(out << "Module info:" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 Func->setFunctionName(Ctx->getGlobalString(FnName)); | 1497 Func->setFunctionName(Ctx->getGlobalString(FnName)); |
| 1266 | 1498 |
| 1267 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); | 1499 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); |
| 1268 LOG(out << "done.\n"); | 1500 LOG(out << "done.\n"); |
| 1269 } | 1501 } |
| 1270 | 1502 |
| 1271 return; | 1503 return; |
| 1272 } | 1504 } |
| 1273 | 1505 |
| 1274 #endif // ALLOW_WASM | 1506 #endif // ALLOW_WASM |
| OLD | NEW |