Home | History | Annotate | Download | only in WebAssembly
      1 //===-- WebAssemblyFastISel.cpp - WebAssembly FastISel implementation -----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief This file defines the WebAssembly-specific support for the FastISel
     12 /// class. Some of the target-specific code is generated by tablegen in the file
     13 /// WebAssemblyGenFastISel.inc, which is #included here.
     14 ///
     15 /// TODO: kill flags
     16 ///
     17 //===----------------------------------------------------------------------===//
     18 
     19 #include "WebAssembly.h"
     20 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
     21 #include "WebAssemblyMachineFunctionInfo.h"
     22 #include "WebAssemblySubtarget.h"
     23 #include "WebAssemblyTargetMachine.h"
     24 #include "llvm/Analysis/BranchProbabilityInfo.h"
     25 #include "llvm/CodeGen/FastISel.h"
     26 #include "llvm/CodeGen/FunctionLoweringInfo.h"
     27 #include "llvm/CodeGen/MachineConstantPool.h"
     28 #include "llvm/CodeGen/MachineFrameInfo.h"
     29 #include "llvm/CodeGen/MachineInstrBuilder.h"
     30 #include "llvm/CodeGen/MachineRegisterInfo.h"
     31 #include "llvm/IR/DataLayout.h"
     32 #include "llvm/IR/DerivedTypes.h"
     33 #include "llvm/IR/Function.h"
     34 #include "llvm/IR/GetElementPtrTypeIterator.h"
     35 #include "llvm/IR/GlobalAlias.h"
     36 #include "llvm/IR/GlobalVariable.h"
     37 #include "llvm/IR/Instructions.h"
     38 #include "llvm/IR/IntrinsicInst.h"
     39 #include "llvm/IR/Operator.h"
     40 using namespace llvm;
     41 
     42 #define DEBUG_TYPE "wasm-fastisel"
     43 
     44 namespace {
     45 
     46 class WebAssemblyFastISel final : public FastISel {
     47   // All possible address modes.
     48   class Address {
     49   public:
     50     typedef enum { RegBase, FrameIndexBase } BaseKind;
     51 
     52   private:
     53     BaseKind Kind;
     54     union {
     55       unsigned Reg;
     56       int FI;
     57     } Base;
     58 
     59     int64_t Offset;
     60 
     61     const GlobalValue *GV;
     62 
     63   public:
     64     // Innocuous defaults for our address.
     65     Address() : Kind(RegBase), Offset(0), GV(0) { Base.Reg = 0; }
     66     void setKind(BaseKind K) { Kind = K; }
     67     BaseKind getKind() const { return Kind; }
     68     bool isRegBase() const { return Kind == RegBase; }
     69     bool isFIBase() const { return Kind == FrameIndexBase; }
     70     void setReg(unsigned Reg) {
     71       assert(isRegBase() && "Invalid base register access!");
     72       Base.Reg = Reg;
     73     }
     74     unsigned getReg() const {
     75       assert(isRegBase() && "Invalid base register access!");
     76       return Base.Reg;
     77     }
     78     void setFI(unsigned FI) {
     79       assert(isFIBase() && "Invalid base frame index access!");
     80       Base.FI = FI;
     81     }
     82     unsigned getFI() const {
     83       assert(isFIBase() && "Invalid base frame index access!");
     84       return Base.FI;
     85     }
     86 
     87     void setOffset(int64_t Offset_) { Offset = Offset_; }
     88     int64_t getOffset() const { return Offset; }
     89     void setGlobalValue(const GlobalValue *G) { GV = G; }
     90     const GlobalValue *getGlobalValue() const { return GV; }
     91   };
     92 
     93   /// Keep a pointer to the WebAssemblySubtarget around so that we can make the
     94   /// right decision when generating code for different targets.
     95   const WebAssemblySubtarget *Subtarget;
     96   LLVMContext *Context;
     97 
     98 private:
     99   // Utility helper routines
    100   MVT::SimpleValueType getSimpleType(Type *Ty) {
    101     EVT VT = TLI.getValueType(DL, Ty, /*HandleUnknown=*/true);
    102     return VT.isSimple() ? VT.getSimpleVT().SimpleTy :
    103                            MVT::INVALID_SIMPLE_VALUE_TYPE;
    104   }
    105   MVT::SimpleValueType getLegalType(MVT::SimpleValueType VT) {
    106     switch (VT) {
    107     case MVT::i1:
    108     case MVT::i8:
    109     case MVT::i16:
    110       return MVT::i32;
    111     case MVT::i32:
    112     case MVT::i64:
    113     case MVT::f32:
    114     case MVT::f64:
    115       return VT;
    116     default:
    117       break;
    118     }
    119     return MVT::INVALID_SIMPLE_VALUE_TYPE;
    120   }
    121   bool computeAddress(const Value *Obj, Address &Addr);
    122   void materializeLoadStoreOperands(Address &Addr);
    123   void addLoadStoreOperands(const Address &Addr, const MachineInstrBuilder &MIB,
    124                             MachineMemOperand *MMO);
    125   unsigned maskI1Value(unsigned Reg, const Value *V);
    126   unsigned getRegForI1Value(const Value *V, bool &Not);
    127   unsigned zeroExtendToI32(unsigned Reg, const Value *V,
    128                            MVT::SimpleValueType From);
    129   unsigned signExtendToI32(unsigned Reg, const Value *V,
    130                            MVT::SimpleValueType From);
    131   unsigned zeroExtend(unsigned Reg, const Value *V,
    132                       MVT::SimpleValueType From,
    133                       MVT::SimpleValueType To);
    134   unsigned signExtend(unsigned Reg, const Value *V,
    135                       MVT::SimpleValueType From,
    136                       MVT::SimpleValueType To);
    137   unsigned getRegForUnsignedValue(const Value *V);
    138   unsigned getRegForSignedValue(const Value *V);
    139   unsigned getRegForPromotedValue(const Value *V, bool IsSigned);
    140   unsigned notValue(unsigned Reg);
    141   unsigned copyValue(unsigned Reg);
    142 
    143   // Backend specific FastISel code.
    144   unsigned fastMaterializeAlloca(const AllocaInst *AI) override;
    145   unsigned fastMaterializeConstant(const Constant *C) override;
    146   bool fastLowerArguments() override;
    147 
    148   // Selection routines.
    149   bool selectCall(const Instruction *I);
    150   bool selectSelect(const Instruction *I);
    151   bool selectTrunc(const Instruction *I);
    152   bool selectZExt(const Instruction *I);
    153   bool selectSExt(const Instruction *I);
    154   bool selectICmp(const Instruction *I);
    155   bool selectFCmp(const Instruction *I);
    156   bool selectBitCast(const Instruction *I);
    157   bool selectLoad(const Instruction *I);
    158   bool selectStore(const Instruction *I);
    159   bool selectBr(const Instruction *I);
    160   bool selectRet(const Instruction *I);
    161   bool selectUnreachable(const Instruction *I);
    162 
    163 public:
    164   // Backend specific FastISel code.
    165   WebAssemblyFastISel(FunctionLoweringInfo &FuncInfo,
    166                       const TargetLibraryInfo *LibInfo)
    167       : FastISel(FuncInfo, LibInfo, /*SkipTargetIndependentISel=*/true) {
    168     Subtarget = &FuncInfo.MF->getSubtarget<WebAssemblySubtarget>();
    169     Context = &FuncInfo.Fn->getContext();
    170   }
    171 
    172   bool fastSelectInstruction(const Instruction *I) override;
    173 
    174 #include "WebAssemblyGenFastISel.inc"
    175 };
    176 
    177 } // end anonymous namespace
    178 
    179 bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
    180 
    181   const User *U = nullptr;
    182   unsigned Opcode = Instruction::UserOp1;
    183   if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
    184     // Don't walk into other basic blocks unless the object is an alloca from
    185     // another block, otherwise it may not have a virtual register assigned.
    186     if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
    187         FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
    188       Opcode = I->getOpcode();
    189       U = I;
    190     }
    191   } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
    192     Opcode = C->getOpcode();
    193     U = C;
    194   }
    195 
    196   if (auto *Ty = dyn_cast<PointerType>(Obj->getType()))
    197     if (Ty->getAddressSpace() > 255)
    198       // Fast instruction selection doesn't support the special
    199       // address spaces.
    200       return false;
    201 
    202   if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
    203     if (Addr.getGlobalValue())
    204       return false;
    205     Addr.setGlobalValue(GV);
    206     return true;
    207   }
    208 
    209   switch (Opcode) {
    210   default:
    211     break;
    212   case Instruction::BitCast: {
    213     // Look through bitcasts.
    214     return computeAddress(U->getOperand(0), Addr);
    215   }
    216   case Instruction::IntToPtr: {
    217     // Look past no-op inttoptrs.
    218     if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
    219         TLI.getPointerTy(DL))
    220       return computeAddress(U->getOperand(0), Addr);
    221     break;
    222   }
    223   case Instruction::PtrToInt: {
    224     // Look past no-op ptrtoints.
    225     if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
    226       return computeAddress(U->getOperand(0), Addr);
    227     break;
    228   }
    229   case Instruction::GetElementPtr: {
    230     Address SavedAddr = Addr;
    231     uint64_t TmpOffset = Addr.getOffset();
    232     // Iterate through the GEP folding the constants into offsets where
    233     // we can.
    234     for (gep_type_iterator GTI = gep_type_begin(U), E = gep_type_end(U);
    235          GTI != E; ++GTI) {
    236       const Value *Op = GTI.getOperand();
    237       if (StructType *STy = dyn_cast<StructType>(*GTI)) {
    238         const StructLayout *SL = DL.getStructLayout(STy);
    239         unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
    240         TmpOffset += SL->getElementOffset(Idx);
    241       } else {
    242         uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
    243         for (;;) {
    244           if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
    245             // Constant-offset addressing.
    246             TmpOffset += CI->getSExtValue() * S;
    247             break;
    248           }
    249           if (S == 1 && Addr.isRegBase() && Addr.getReg() == 0) {
    250             // An unscaled add of a register. Set it as the new base.
    251             Addr.setReg(getRegForValue(Op));
    252             break;
    253           }
    254           if (canFoldAddIntoGEP(U, Op)) {
    255             // A compatible add with a constant operand. Fold the constant.
    256             ConstantInt *CI =
    257                 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
    258             TmpOffset += CI->getSExtValue() * S;
    259             // Iterate on the other operand.
    260             Op = cast<AddOperator>(Op)->getOperand(0);
    261             continue;
    262           }
    263           // Unsupported
    264           goto unsupported_gep;
    265         }
    266       }
    267     }
    268     // Try to grab the base operand now.
    269     Addr.setOffset(TmpOffset);
    270     if (computeAddress(U->getOperand(0), Addr))
    271       return true;
    272     // We failed, restore everything and try the other options.
    273     Addr = SavedAddr;
    274   unsupported_gep:
    275     break;
    276   }
    277   case Instruction::Alloca: {
    278     const AllocaInst *AI = cast<AllocaInst>(Obj);
    279     DenseMap<const AllocaInst *, int>::iterator SI =
    280         FuncInfo.StaticAllocaMap.find(AI);
    281     if (SI != FuncInfo.StaticAllocaMap.end()) {
    282       Addr.setKind(Address::FrameIndexBase);
    283       Addr.setFI(SI->second);
    284       return true;
    285     }
    286     break;
    287   }
    288   case Instruction::Add: {
    289     // Adds of constants are common and easy enough.
    290     const Value *LHS = U->getOperand(0);
    291     const Value *RHS = U->getOperand(1);
    292 
    293     if (isa<ConstantInt>(LHS))
    294       std::swap(LHS, RHS);
    295 
    296     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
    297       Addr.setOffset(Addr.getOffset() + CI->getSExtValue());
    298       return computeAddress(LHS, Addr);
    299     }
    300 
    301     Address Backup = Addr;
    302     if (computeAddress(LHS, Addr) && computeAddress(RHS, Addr))
    303       return true;
    304     Addr = Backup;
    305 
    306     break;
    307   }
    308   case Instruction::Sub: {
    309     // Subs of constants are common and easy enough.
    310     const Value *LHS = U->getOperand(0);
    311     const Value *RHS = U->getOperand(1);
    312 
    313     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
    314       Addr.setOffset(Addr.getOffset() - CI->getSExtValue());
    315       return computeAddress(LHS, Addr);
    316     }
    317     break;
    318   }
    319   }
    320   Addr.setReg(getRegForValue(Obj));
    321   return Addr.getReg() != 0;
    322 }
    323 
    324 void WebAssemblyFastISel::materializeLoadStoreOperands(Address &Addr) {
    325   if (Addr.isRegBase()) {
    326     unsigned Reg = Addr.getReg();
    327     if (Reg == 0) {
    328       Reg = createResultReg(Subtarget->hasAddr64() ?
    329                             &WebAssembly::I64RegClass :
    330                             &WebAssembly::I32RegClass);
    331       unsigned Opc = Subtarget->hasAddr64() ?
    332                      WebAssembly::CONST_I64 :
    333                      WebAssembly::CONST_I32;
    334       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), Reg)
    335          .addImm(0);
    336       Addr.setReg(Reg);
    337     }
    338   }
    339 }
    340 
    341 void WebAssemblyFastISel::addLoadStoreOperands(const Address &Addr,
    342                                                const MachineInstrBuilder &MIB,
    343                                                MachineMemOperand *MMO) {
    344   if (const GlobalValue *GV = Addr.getGlobalValue())
    345     MIB.addGlobalAddress(GV, Addr.getOffset());
    346   else
    347     MIB.addImm(Addr.getOffset());
    348 
    349   if (Addr.isRegBase())
    350     MIB.addReg(Addr.getReg());
    351   else
    352     MIB.addFrameIndex(Addr.getFI());
    353 
    354   // Set the alignment operand (this is rewritten in SetP2AlignOperands).
    355   // TODO: Disable SetP2AlignOperands for FastISel and just do it here.
    356   MIB.addImm(0);
    357 
    358   MIB.addMemOperand(MMO);
    359 }
    360 
    361 unsigned WebAssemblyFastISel::maskI1Value(unsigned Reg, const Value *V) {
    362   return zeroExtendToI32(Reg, V, MVT::i1);
    363 }
    364 
    365 unsigned WebAssemblyFastISel::getRegForI1Value(const Value *V, bool &Not) {
    366   if (const ICmpInst *ICmp = dyn_cast<ICmpInst>(V))
    367     if (const ConstantInt *C = dyn_cast<ConstantInt>(ICmp->getOperand(1)))
    368       if (ICmp->isEquality() && C->isZero() && C->getType()->isIntegerTy(32)) {
    369         Not = ICmp->isTrueWhenEqual();
    370         return getRegForValue(ICmp->getOperand(0));
    371       }
    372 
    373   if (BinaryOperator::isNot(V)) {
    374     Not = true;
    375     return getRegForValue(BinaryOperator::getNotArgument(V));
    376   }
    377 
    378   Not = false;
    379   return maskI1Value(getRegForValue(V), V);
    380 }
    381 
    382 unsigned WebAssemblyFastISel::zeroExtendToI32(unsigned Reg, const Value *V,
    383                                               MVT::SimpleValueType From) {
    384   switch (From) {
    385   case MVT::i1:
    386     // If the value is naturally an i1, we don't need to mask it.
    387     // TODO: Recursively examine selects, phis, and, or, xor, constants.
    388     if (From == MVT::i1 && V != nullptr) {
    389       if (isa<CmpInst>(V) ||
    390           (isa<Argument>(V) && cast<Argument>(V)->hasZExtAttr()))
    391         return copyValue(Reg);
    392     }
    393   case MVT::i8:
    394   case MVT::i16:
    395     break;
    396   case MVT::i32:
    397     return copyValue(Reg);
    398   default:
    399     return 0;
    400   }
    401 
    402   unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
    403   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    404           TII.get(WebAssembly::CONST_I32), Imm)
    405     .addImm(~(~uint64_t(0) << MVT(From).getSizeInBits()));
    406 
    407   unsigned Result = createResultReg(&WebAssembly::I32RegClass);
    408   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    409           TII.get(WebAssembly::AND_I32), Result)
    410     .addReg(Reg)
    411     .addReg(Imm);
    412 
    413   return Result;
    414 }
    415 
    416 unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
    417                                               MVT::SimpleValueType From) {
    418   switch (From) {
    419   case MVT::i1:
    420   case MVT::i8:
    421   case MVT::i16:
    422     break;
    423   case MVT::i32:
    424     return copyValue(Reg);
    425   default:
    426     return 0;
    427   }
    428 
    429   unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
    430   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    431           TII.get(WebAssembly::CONST_I32), Imm)
    432     .addImm(32 - MVT(From).getSizeInBits());
    433 
    434   unsigned Left = createResultReg(&WebAssembly::I32RegClass);
    435   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    436           TII.get(WebAssembly::SHL_I32), Left)
    437     .addReg(Reg)
    438     .addReg(Imm);
    439 
    440   unsigned Right = createResultReg(&WebAssembly::I32RegClass);
    441   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    442           TII.get(WebAssembly::SHR_S_I32), Right)
    443     .addReg(Left)
    444     .addReg(Imm);
    445 
    446   return Right;
    447 }
    448 
    449 unsigned WebAssemblyFastISel::zeroExtend(unsigned Reg, const Value *V,
    450                                          MVT::SimpleValueType From,
    451                                          MVT::SimpleValueType To) {
    452   if (To == MVT::i64) {
    453     if (From == MVT::i64)
    454       return copyValue(Reg);
    455 
    456     Reg = zeroExtendToI32(Reg, V, From);
    457 
    458     unsigned Result = createResultReg(&WebAssembly::I64RegClass);
    459     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    460             TII.get(WebAssembly::I64_EXTEND_U_I32), Result)
    461         .addReg(Reg);
    462     return Result;
    463   }
    464 
    465   return zeroExtendToI32(Reg, V, From);
    466 }
    467 
    468 unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
    469                                          MVT::SimpleValueType From,
    470                                          MVT::SimpleValueType To) {
    471   if (To == MVT::i64) {
    472     if (From == MVT::i64)
    473       return copyValue(Reg);
    474 
    475     Reg = signExtendToI32(Reg, V, From);
    476 
    477     unsigned Result = createResultReg(&WebAssembly::I64RegClass);
    478     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    479             TII.get(WebAssembly::I64_EXTEND_S_I32), Result)
    480         .addReg(Reg);
    481     return Result;
    482   }
    483 
    484   return signExtendToI32(Reg, V, From);
    485 }
    486 
    487 unsigned WebAssemblyFastISel::getRegForUnsignedValue(const Value *V) {
    488   MVT::SimpleValueType From = getSimpleType(V->getType());
    489   MVT::SimpleValueType To = getLegalType(From);
    490   return zeroExtend(getRegForValue(V), V, From, To);
    491 }
    492 
    493 unsigned WebAssemblyFastISel::getRegForSignedValue(const Value *V) {
    494   MVT::SimpleValueType From = getSimpleType(V->getType());
    495   MVT::SimpleValueType To = getLegalType(From);
    496   return zeroExtend(getRegForValue(V), V, From, To);
    497 }
    498 
    499 unsigned WebAssemblyFastISel::getRegForPromotedValue(const Value *V,
    500                                                      bool IsSigned) {
    501   return IsSigned ? getRegForSignedValue(V) :
    502                     getRegForUnsignedValue(V);
    503 }
    504 
    505 unsigned WebAssemblyFastISel::notValue(unsigned Reg) {
    506   assert(MRI.getRegClass(Reg) == &WebAssembly::I32RegClass);
    507 
    508   unsigned NotReg = createResultReg(&WebAssembly::I32RegClass);
    509   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    510           TII.get(WebAssembly::EQZ_I32), NotReg)
    511     .addReg(Reg);
    512   return NotReg;
    513 }
    514 
    515 unsigned WebAssemblyFastISel::copyValue(unsigned Reg) {
    516   unsigned ResultReg = createResultReg(MRI.getRegClass(Reg));
    517   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    518           TII.get(WebAssembly::COPY), ResultReg)
    519     .addReg(Reg);
    520   return ResultReg;
    521 }
    522 
    523 unsigned WebAssemblyFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
    524   DenseMap<const AllocaInst *, int>::iterator SI =
    525       FuncInfo.StaticAllocaMap.find(AI);
    526 
    527   if (SI != FuncInfo.StaticAllocaMap.end()) {
    528     unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
    529                                          &WebAssembly::I64RegClass :
    530                                          &WebAssembly::I32RegClass);
    531     unsigned Opc = Subtarget->hasAddr64() ?
    532                    WebAssembly::COPY_LOCAL_I64 :
    533                    WebAssembly::COPY_LOCAL_I32;
    534     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    535         .addFrameIndex(SI->second);
    536     return ResultReg;
    537   }
    538 
    539   return 0;
    540 }
    541 
    542 unsigned WebAssemblyFastISel::fastMaterializeConstant(const Constant *C) {
    543   if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
    544     unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
    545                                          &WebAssembly::I64RegClass :
    546                                          &WebAssembly::I32RegClass);
    547     unsigned Opc = Subtarget->hasAddr64() ?
    548                    WebAssembly::CONST_I64 :
    549                    WebAssembly::CONST_I32;
    550     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    551        .addGlobalAddress(GV);
    552     return ResultReg;
    553   }
    554 
    555   // Let target-independent code handle it.
    556   return 0;
    557 }
    558 
    559 bool WebAssemblyFastISel::fastLowerArguments() {
    560   if (!FuncInfo.CanLowerReturn)
    561     return false;
    562 
    563   const Function *F = FuncInfo.Fn;
    564   if (F->isVarArg())
    565     return false;
    566 
    567   unsigned i = 0;
    568   for (auto const &Arg : F->args()) {
    569     const AttributeSet &Attrs = F->getAttributes();
    570     if (Attrs.hasAttribute(i+1, Attribute::ByVal) ||
    571         Attrs.hasAttribute(i+1, Attribute::SwiftSelf) ||
    572         Attrs.hasAttribute(i+1, Attribute::SwiftError) ||
    573         Attrs.hasAttribute(i+1, Attribute::InAlloca) ||
    574         Attrs.hasAttribute(i+1, Attribute::Nest))
    575       return false;
    576 
    577     Type *ArgTy = Arg.getType();
    578     if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy())
    579       return false;
    580 
    581     unsigned Opc;
    582     const TargetRegisterClass *RC;
    583     switch (getSimpleType(ArgTy)) {
    584     case MVT::i1:
    585     case MVT::i8:
    586     case MVT::i16:
    587     case MVT::i32:
    588       Opc = WebAssembly::ARGUMENT_I32;
    589       RC = &WebAssembly::I32RegClass;
    590       break;
    591     case MVT::i64:
    592       Opc = WebAssembly::ARGUMENT_I64;
    593       RC = &WebAssembly::I64RegClass;
    594       break;
    595     case MVT::f32:
    596       Opc = WebAssembly::ARGUMENT_F32;
    597       RC = &WebAssembly::F32RegClass;
    598       break;
    599     case MVT::f64:
    600       Opc = WebAssembly::ARGUMENT_F64;
    601       RC = &WebAssembly::F64RegClass;
    602       break;
    603     default:
    604       return false;
    605     }
    606     unsigned ResultReg = createResultReg(RC);
    607     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    608       .addImm(i);
    609     updateValueMap(&Arg, ResultReg);
    610 
    611     ++i;
    612   }
    613 
    614   MRI.addLiveIn(WebAssembly::ARGUMENTS);
    615 
    616   auto *MFI = MF->getInfo<WebAssemblyFunctionInfo>();
    617   for (auto const &Arg : F->args())
    618     MFI->addParam(getLegalType(getSimpleType(Arg.getType())));
    619 
    620   return true;
    621 }
    622 
    623 bool WebAssemblyFastISel::selectCall(const Instruction *I) {
    624   const CallInst *Call = cast<CallInst>(I);
    625 
    626   if (Call->isMustTailCall() || Call->isInlineAsm() ||
    627       Call->getFunctionType()->isVarArg())
    628     return false;
    629 
    630   Function *Func = Call->getCalledFunction();
    631   if (Func && Func->isIntrinsic())
    632     return false;
    633 
    634   FunctionType *FuncTy = Call->getFunctionType();
    635   unsigned Opc;
    636   bool IsDirect = Func != nullptr;
    637   bool IsVoid = FuncTy->getReturnType()->isVoidTy();
    638   unsigned ResultReg;
    639   if (IsVoid) {
    640     Opc = IsDirect ? WebAssembly::CALL_VOID : WebAssembly::CALL_INDIRECT_VOID;
    641   } else {
    642     MVT::SimpleValueType RetTy = getSimpleType(Call->getType());
    643     switch (RetTy) {
    644     case MVT::i1:
    645     case MVT::i8:
    646     case MVT::i16:
    647     case MVT::i32:
    648       Opc = IsDirect ? WebAssembly::CALL_I32 : WebAssembly::CALL_INDIRECT_I32;
    649       ResultReg = createResultReg(&WebAssembly::I32RegClass);
    650       break;
    651     case MVT::i64:
    652       Opc = IsDirect ? WebAssembly::CALL_I64 : WebAssembly::CALL_INDIRECT_I64;
    653       ResultReg = createResultReg(&WebAssembly::I64RegClass);
    654       break;
    655     case MVT::f32:
    656       Opc = IsDirect ? WebAssembly::CALL_F32 : WebAssembly::CALL_INDIRECT_F32;
    657       ResultReg = createResultReg(&WebAssembly::F32RegClass);
    658       break;
    659     case MVT::f64:
    660       Opc = IsDirect ? WebAssembly::CALL_F64 : WebAssembly::CALL_INDIRECT_F64;
    661       ResultReg = createResultReg(&WebAssembly::F64RegClass);
    662       break;
    663     default:
    664       return false;
    665     }
    666   }
    667 
    668   SmallVector<unsigned, 8> Args;
    669   for (unsigned i = 0, e = Call->getNumArgOperands(); i < e; ++i) {
    670     Value *V = Call->getArgOperand(i);
    671     MVT::SimpleValueType ArgTy = getSimpleType(V->getType());
    672     if (ArgTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
    673       return false;
    674 
    675     const AttributeSet &Attrs = Call->getAttributes();
    676     if (Attrs.hasAttribute(i+1, Attribute::ByVal) ||
    677         Attrs.hasAttribute(i+1, Attribute::SwiftSelf) ||
    678         Attrs.hasAttribute(i+1, Attribute::SwiftError) ||
    679         Attrs.hasAttribute(i+1, Attribute::InAlloca) ||
    680         Attrs.hasAttribute(i+1, Attribute::Nest))
    681       return false;
    682 
    683     unsigned Reg;
    684 
    685     if (Attrs.hasAttribute(i+1, Attribute::SExt))
    686       Reg = getRegForSignedValue(V);
    687     else if (Attrs.hasAttribute(i+1, Attribute::ZExt))
    688       Reg = getRegForUnsignedValue(V);
    689     else
    690       Reg = getRegForValue(V);
    691 
    692     if (Reg == 0)
    693       return false;
    694 
    695     Args.push_back(Reg);
    696   }
    697 
    698   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
    699 
    700   if (!IsVoid)
    701     MIB.addReg(ResultReg, RegState::Define);
    702 
    703   if (IsDirect)
    704     MIB.addGlobalAddress(Func);
    705   else
    706     MIB.addReg(getRegForValue(Call->getCalledValue()));
    707 
    708   for (unsigned ArgReg : Args)
    709     MIB.addReg(ArgReg);
    710 
    711   if (!IsVoid)
    712     updateValueMap(Call, ResultReg);
    713   return true;
    714 }
    715 
    716 bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
    717   const SelectInst *Select = cast<SelectInst>(I);
    718 
    719   bool Not;
    720   unsigned CondReg  = getRegForI1Value(Select->getCondition(), Not);
    721   if (CondReg == 0)
    722     return false;
    723 
    724   unsigned TrueReg  = getRegForValue(Select->getTrueValue());
    725   if (TrueReg == 0)
    726     return false;
    727 
    728   unsigned FalseReg = getRegForValue(Select->getFalseValue());
    729   if (FalseReg == 0)
    730     return false;
    731 
    732   if (Not)
    733     std::swap(TrueReg, FalseReg);
    734 
    735   unsigned Opc;
    736   const TargetRegisterClass *RC;
    737   switch (getSimpleType(Select->getType())) {
    738   case MVT::i1:
    739   case MVT::i8:
    740   case MVT::i16:
    741   case MVT::i32:
    742     Opc = WebAssembly::SELECT_I32;
    743     RC = &WebAssembly::I32RegClass;
    744     break;
    745   case MVT::i64:
    746     Opc = WebAssembly::SELECT_I64;
    747     RC = &WebAssembly::I64RegClass;
    748     break;
    749   case MVT::f32:
    750     Opc = WebAssembly::SELECT_F32;
    751     RC = &WebAssembly::F32RegClass;
    752     break;
    753   case MVT::f64:
    754     Opc = WebAssembly::SELECT_F64;
    755     RC = &WebAssembly::F64RegClass;
    756     break;
    757   default:
    758     return false;
    759   }
    760 
    761   unsigned ResultReg = createResultReg(RC);
    762   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    763     .addReg(TrueReg)
    764     .addReg(FalseReg)
    765     .addReg(CondReg);
    766 
    767   updateValueMap(Select, ResultReg);
    768   return true;
    769 }
    770 
    771 bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
    772   const TruncInst *Trunc = cast<TruncInst>(I);
    773 
    774   unsigned Reg = getRegForValue(Trunc->getOperand(0));
    775   if (Reg == 0)
    776     return false;
    777 
    778   if (Trunc->getOperand(0)->getType()->isIntegerTy(64)) {
    779     unsigned Result = createResultReg(&WebAssembly::I32RegClass);
    780     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
    781             TII.get(WebAssembly::I32_WRAP_I64), Result)
    782         .addReg(Reg);
    783     Reg = Result;
    784   }
    785 
    786   updateValueMap(Trunc, Reg);
    787   return true;
    788 }
    789 
    790 bool WebAssemblyFastISel::selectZExt(const Instruction *I) {
    791   const ZExtInst *ZExt = cast<ZExtInst>(I);
    792 
    793   const Value *Op = ZExt->getOperand(0);
    794   MVT::SimpleValueType From = getSimpleType(Op->getType());
    795   MVT::SimpleValueType To = getLegalType(getSimpleType(ZExt->getType()));
    796   unsigned Reg = zeroExtend(getRegForValue(Op), Op, From, To);
    797   if (Reg == 0)
    798     return false;
    799 
    800   updateValueMap(ZExt, Reg);
    801   return true;
    802 }
    803 
    804 bool WebAssemblyFastISel::selectSExt(const Instruction *I) {
    805   const SExtInst *SExt = cast<SExtInst>(I);
    806 
    807   const Value *Op = SExt->getOperand(0);
    808   MVT::SimpleValueType From = getSimpleType(Op->getType());
    809   MVT::SimpleValueType To = getLegalType(getSimpleType(SExt->getType()));
    810   unsigned Reg = signExtend(getRegForValue(Op), Op, From, To);
    811   if (Reg == 0)
    812     return false;
    813 
    814   updateValueMap(SExt, Reg);
    815   return true;
    816 }
    817 
    818 bool WebAssemblyFastISel::selectICmp(const Instruction *I) {
    819   const ICmpInst *ICmp = cast<ICmpInst>(I);
    820 
    821   bool I32 = getSimpleType(ICmp->getOperand(0)->getType()) != MVT::i64;
    822   unsigned Opc;
    823   bool isSigned = false;
    824   switch (ICmp->getPredicate()) {
    825   case ICmpInst::ICMP_EQ:
    826     Opc = I32 ? WebAssembly::EQ_I32 : WebAssembly::EQ_I64;
    827     break;
    828   case ICmpInst::ICMP_NE:
    829     Opc = I32 ? WebAssembly::NE_I32 : WebAssembly::NE_I64;
    830     break;
    831   case ICmpInst::ICMP_UGT:
    832     Opc = I32 ? WebAssembly::GT_U_I32 : WebAssembly::GT_U_I64;
    833     break;
    834   case ICmpInst::ICMP_UGE:
    835     Opc = I32 ? WebAssembly::GE_U_I32 : WebAssembly::GE_U_I64;
    836     break;
    837   case ICmpInst::ICMP_ULT:
    838     Opc = I32 ? WebAssembly::LT_U_I32 : WebAssembly::LT_U_I64;
    839     break;
    840   case ICmpInst::ICMP_ULE:
    841     Opc = I32 ? WebAssembly::LE_U_I32 : WebAssembly::LE_U_I64;
    842     break;
    843   case ICmpInst::ICMP_SGT:
    844     Opc = I32 ? WebAssembly::GT_S_I32 : WebAssembly::GT_S_I64;
    845     isSigned = true;
    846     break;
    847   case ICmpInst::ICMP_SGE:
    848     Opc = I32 ? WebAssembly::GE_S_I32 : WebAssembly::GE_S_I64;
    849     isSigned = true;
    850     break;
    851   case ICmpInst::ICMP_SLT:
    852     Opc = I32 ? WebAssembly::LT_S_I32 : WebAssembly::LT_S_I64;
    853     isSigned = true;
    854     break;
    855   case ICmpInst::ICMP_SLE:
    856     Opc = I32 ? WebAssembly::LE_S_I32 : WebAssembly::LE_S_I64;
    857     isSigned = true;
    858     break;
    859   default: return false;
    860   }
    861 
    862   unsigned LHS = getRegForPromotedValue(ICmp->getOperand(0), isSigned);
    863   if (LHS == 0)
    864     return false;
    865 
    866   unsigned RHS = getRegForPromotedValue(ICmp->getOperand(1), isSigned);
    867   if (RHS == 0)
    868     return false;
    869 
    870   unsigned ResultReg = createResultReg(&WebAssembly::I32RegClass);
    871   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    872       .addReg(LHS)
    873       .addReg(RHS);
    874   updateValueMap(ICmp, ResultReg);
    875   return true;
    876 }
    877 
    878 bool WebAssemblyFastISel::selectFCmp(const Instruction *I) {
    879   const FCmpInst *FCmp = cast<FCmpInst>(I);
    880 
    881   unsigned LHS = getRegForValue(FCmp->getOperand(0));
    882   if (LHS == 0)
    883     return false;
    884 
    885   unsigned RHS = getRegForValue(FCmp->getOperand(1));
    886   if (RHS == 0)
    887     return false;
    888 
    889   bool F32 = getSimpleType(FCmp->getOperand(0)->getType()) != MVT::f64;
    890   unsigned Opc;
    891   bool Not = false;
    892   switch (FCmp->getPredicate()) {
    893   case FCmpInst::FCMP_OEQ:
    894     Opc = F32 ? WebAssembly::EQ_F32 : WebAssembly::EQ_F64;
    895     break;
    896   case FCmpInst::FCMP_UNE:
    897     Opc = F32 ? WebAssembly::NE_F32 : WebAssembly::NE_F64;
    898     break;
    899   case FCmpInst::FCMP_OGT:
    900     Opc = F32 ? WebAssembly::GT_F32 : WebAssembly::GT_F64;
    901     break;
    902   case FCmpInst::FCMP_OGE:
    903     Opc = F32 ? WebAssembly::GE_F32 : WebAssembly::GE_F64;
    904     break;
    905   case FCmpInst::FCMP_OLT:
    906     Opc = F32 ? WebAssembly::LT_F32 : WebAssembly::LT_F64;
    907     break;
    908   case FCmpInst::FCMP_OLE:
    909     Opc = F32 ? WebAssembly::LE_F32 : WebAssembly::LE_F64;
    910     break;
    911   case FCmpInst::FCMP_UGT:
    912     Opc = F32 ? WebAssembly::LE_F32 : WebAssembly::LE_F64;
    913     Not = true;
    914     break;
    915   case FCmpInst::FCMP_UGE:
    916     Opc = F32 ? WebAssembly::LT_F32 : WebAssembly::LT_F64;
    917     Not = true;
    918     break;
    919   case FCmpInst::FCMP_ULT:
    920     Opc = F32 ? WebAssembly::GE_F32 : WebAssembly::GE_F64;
    921     Not = true;
    922     break;
    923   case FCmpInst::FCMP_ULE:
    924     Opc = F32 ? WebAssembly::GT_F32 : WebAssembly::GT_F64;
    925     Not = true;
    926     break;
    927   default:
    928     return false;
    929   }
    930 
    931   unsigned ResultReg = createResultReg(&WebAssembly::I32RegClass);
    932   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
    933       .addReg(LHS)
    934       .addReg(RHS);
    935 
    936   if (Not)
    937     ResultReg = notValue(ResultReg);
    938 
    939   updateValueMap(FCmp, ResultReg);
    940   return true;
    941 }
    942 
    943 bool WebAssemblyFastISel::selectBitCast(const Instruction *I) {
    944   // Target-independent code can handle this, except it doesn't set the dead
    945   // flag on the ARGUMENTS clobber, so we have to do that manually in order
    946   // to satisfy code that expects this of isBitcast() instructions.
    947   EVT VT = TLI.getValueType(DL, I->getOperand(0)->getType());
    948   EVT RetVT = TLI.getValueType(DL, I->getType());
    949   if (!VT.isSimple() || !RetVT.isSimple())
    950     return false;
    951 
    952   if (VT == RetVT) {
    953     // No-op bitcast.
    954     updateValueMap(I, getRegForValue(I->getOperand(0)));
    955     return true;
    956   }
    957 
    958   unsigned Reg = fastEmit_ISD_BITCAST_r(VT.getSimpleVT(), RetVT.getSimpleVT(),
    959                                         getRegForValue(I->getOperand(0)),
    960                                         I->getOperand(0)->hasOneUse());
    961   if (!Reg)
    962     return false;
    963   MachineBasicBlock::iterator Iter = FuncInfo.InsertPt;
    964   --Iter;
    965   assert(Iter->isBitcast());
    966   Iter->setPhysRegsDeadExcept(ArrayRef<unsigned>(), TRI);
    967   updateValueMap(I, Reg);
    968   return true;
    969 }
    970 
    971 bool WebAssemblyFastISel::selectLoad(const Instruction *I) {
    972   const LoadInst *Load = cast<LoadInst>(I);
    973   if (Load->isAtomic())
    974     return false;
    975 
    976   Address Addr;
    977   if (!computeAddress(Load->getPointerOperand(), Addr))
    978     return false;
    979 
    980   // TODO: Fold a following sign-/zero-extend into the load instruction.
    981 
    982   unsigned Opc;
    983   const TargetRegisterClass *RC;
    984   switch (getSimpleType(Load->getType())) {
    985   case MVT::i1:
    986   case MVT::i8:
    987     Opc = WebAssembly::LOAD8_U_I32;
    988     RC = &WebAssembly::I32RegClass;
    989     break;
    990   case MVT::i16:
    991     Opc = WebAssembly::LOAD16_U_I32;
    992     RC = &WebAssembly::I32RegClass;
    993     break;
    994   case MVT::i32:
    995     Opc = WebAssembly::LOAD_I32;
    996     RC = &WebAssembly::I32RegClass;
    997     break;
    998   case MVT::i64:
    999     Opc = WebAssembly::LOAD_I64;
   1000     RC = &WebAssembly::I64RegClass;
   1001     break;
   1002   case MVT::f32:
   1003     Opc = WebAssembly::LOAD_F32;
   1004     RC = &WebAssembly::F32RegClass;
   1005     break;
   1006   case MVT::f64:
   1007     Opc = WebAssembly::LOAD_F64;
   1008     RC = &WebAssembly::F64RegClass;
   1009     break;
   1010   default:
   1011     return false;
   1012   }
   1013 
   1014   materializeLoadStoreOperands(Addr);
   1015 
   1016   unsigned ResultReg = createResultReg(RC);
   1017   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
   1018                      ResultReg);
   1019 
   1020   addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Load));
   1021 
   1022   updateValueMap(Load, ResultReg);
   1023   return true;
   1024 }
   1025 
   1026 bool WebAssemblyFastISel::selectStore(const Instruction *I) {
   1027   const StoreInst *Store = cast<StoreInst>(I);
   1028   if (Store->isAtomic())
   1029     return false;
   1030 
   1031   Address Addr;
   1032   if (!computeAddress(Store->getPointerOperand(), Addr))
   1033     return false;
   1034 
   1035   unsigned Opc;
   1036   const TargetRegisterClass *RC;
   1037   bool VTIsi1 = false;
   1038   switch (getSimpleType(Store->getValueOperand()->getType())) {
   1039   case MVT::i1:
   1040     VTIsi1 = true;
   1041   case MVT::i8:
   1042     Opc = WebAssembly::STORE8_I32;
   1043     RC = &WebAssembly::I32RegClass;
   1044     break;
   1045   case MVT::i16:
   1046     Opc = WebAssembly::STORE16_I32;
   1047     RC = &WebAssembly::I32RegClass;
   1048     break;
   1049   case MVT::i32:
   1050     Opc = WebAssembly::STORE_I32;
   1051     RC = &WebAssembly::I32RegClass;
   1052     break;
   1053   case MVT::i64:
   1054     Opc = WebAssembly::STORE_I64;
   1055     RC = &WebAssembly::I64RegClass;
   1056     break;
   1057   case MVT::f32:
   1058     Opc = WebAssembly::STORE_F32;
   1059     RC = &WebAssembly::F32RegClass;
   1060     break;
   1061   case MVT::f64:
   1062     Opc = WebAssembly::STORE_F64;
   1063     RC = &WebAssembly::F64RegClass;
   1064     break;
   1065   default: return false;
   1066   }
   1067 
   1068   materializeLoadStoreOperands(Addr);
   1069 
   1070   unsigned ValueReg = getRegForValue(Store->getValueOperand());
   1071   if (VTIsi1)
   1072     ValueReg = maskI1Value(ValueReg, Store->getValueOperand());
   1073 
   1074   unsigned ResultReg = createResultReg(RC);
   1075   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
   1076                      ResultReg);
   1077 
   1078   addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Store));
   1079 
   1080   MIB.addReg(ValueReg);
   1081   return true;
   1082 }
   1083 
   1084 bool WebAssemblyFastISel::selectBr(const Instruction *I) {
   1085   const BranchInst *Br = cast<BranchInst>(I);
   1086   if (Br->isUnconditional()) {
   1087     MachineBasicBlock *MSucc = FuncInfo.MBBMap[Br->getSuccessor(0)];
   1088     fastEmitBranch(MSucc, Br->getDebugLoc());
   1089     return true;
   1090   }
   1091 
   1092   MachineBasicBlock *TBB = FuncInfo.MBBMap[Br->getSuccessor(0)];
   1093   MachineBasicBlock *FBB = FuncInfo.MBBMap[Br->getSuccessor(1)];
   1094 
   1095   bool Not;
   1096   unsigned CondReg = getRegForI1Value(Br->getCondition(), Not);
   1097 
   1098   unsigned Opc = WebAssembly::BR_IF;
   1099   if (Not)
   1100     Opc = WebAssembly::BR_UNLESS;
   1101 
   1102   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc))
   1103       .addMBB(TBB)
   1104       .addReg(CondReg);
   1105 
   1106   finishCondBranch(Br->getParent(), TBB, FBB);
   1107   return true;
   1108 }
   1109 
   1110 bool WebAssemblyFastISel::selectRet(const Instruction *I) {
   1111   if (!FuncInfo.CanLowerReturn)
   1112     return false;
   1113 
   1114   const ReturnInst *Ret = cast<ReturnInst>(I);
   1115 
   1116   if (Ret->getNumOperands() == 0) {
   1117     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
   1118             TII.get(WebAssembly::RETURN_VOID));
   1119     return true;
   1120   }
   1121 
   1122   Value *RV = Ret->getOperand(0);
   1123   unsigned Opc;
   1124   switch (getSimpleType(RV->getType())) {
   1125   case MVT::i1: case MVT::i8:
   1126   case MVT::i16: case MVT::i32:
   1127     Opc = WebAssembly::RETURN_I32;
   1128     break;
   1129   case MVT::i64:
   1130     Opc = WebAssembly::RETURN_I64;
   1131     break;
   1132   case MVT::f32: Opc = WebAssembly::RETURN_F32; break;
   1133   case MVT::f64: Opc = WebAssembly::RETURN_F64; break;
   1134   default: return false;
   1135   }
   1136 
   1137   unsigned Reg;
   1138   if (FuncInfo.Fn->getAttributes().hasAttribute(0, Attribute::SExt))
   1139     Reg = getRegForSignedValue(RV);
   1140   else if (FuncInfo.Fn->getAttributes().hasAttribute(0, Attribute::ZExt))
   1141     Reg = getRegForUnsignedValue(RV);
   1142   else
   1143     Reg = getRegForValue(RV);
   1144 
   1145   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)).addReg(Reg);
   1146   return true;
   1147 }
   1148 
   1149 bool WebAssemblyFastISel::selectUnreachable(const Instruction *I) {
   1150   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
   1151           TII.get(WebAssembly::UNREACHABLE));
   1152   return true;
   1153 }
   1154 
   1155 bool WebAssemblyFastISel::fastSelectInstruction(const Instruction *I) {
   1156   switch (I->getOpcode()) {
   1157   case Instruction::Call:
   1158     if (selectCall(I))
   1159       return true;
   1160     break;
   1161   case Instruction::Select:      return selectSelect(I);
   1162   case Instruction::Trunc:       return selectTrunc(I);
   1163   case Instruction::ZExt:        return selectZExt(I);
   1164   case Instruction::SExt:        return selectSExt(I);
   1165   case Instruction::ICmp:        return selectICmp(I);
   1166   case Instruction::FCmp:        return selectFCmp(I);
   1167   case Instruction::BitCast:     return selectBitCast(I);
   1168   case Instruction::Load:        return selectLoad(I);
   1169   case Instruction::Store:       return selectStore(I);
   1170   case Instruction::Br:          return selectBr(I);
   1171   case Instruction::Ret:         return selectRet(I);
   1172   case Instruction::Unreachable: return selectUnreachable(I);
   1173   default: break;
   1174   }
   1175 
   1176   // Fall back to target-independent instruction selection.
   1177   return selectOperator(I, I->getOpcode());
   1178 }
   1179 
   1180 FastISel *WebAssembly::createFastISel(FunctionLoweringInfo &FuncInfo,
   1181                                       const TargetLibraryInfo *LibInfo) {
   1182   return new WebAssemblyFastISel(FuncInfo, LibInfo);
   1183 }
   1184