1 //===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===// 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 contains the WebAssembly implementation of the 12 /// TargetInstrInfo class. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "WebAssemblyInstrInfo.h" 17 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 18 #include "WebAssemblySubtarget.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineMemOperand.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 using namespace llvm; 24 25 #define DEBUG_TYPE "wasm-instr-info" 26 27 #define GET_INSTRINFO_CTOR_DTOR 28 #include "WebAssemblyGenInstrInfo.inc" 29 30 WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI) 31 : RI(STI.getTargetTriple()) {} 32 33 void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 34 MachineBasicBlock::iterator I, 35 DebugLoc DL, unsigned DestReg, 36 unsigned SrcReg, bool KillSrc) const { 37 const TargetRegisterClass *RC = 38 MBB.getParent()->getRegInfo().getRegClass(SrcReg); 39 40 unsigned SetLocalOpcode; 41 if (RC == &WebAssembly::I32RegClass) 42 SetLocalOpcode = WebAssembly::SET_LOCAL_I32; 43 else if (RC == &WebAssembly::I64RegClass) 44 SetLocalOpcode = WebAssembly::SET_LOCAL_I64; 45 else if (RC == &WebAssembly::F32RegClass) 46 SetLocalOpcode = WebAssembly::SET_LOCAL_F32; 47 else if (RC == &WebAssembly::F64RegClass) 48 SetLocalOpcode = WebAssembly::SET_LOCAL_F64; 49 else 50 llvm_unreachable("Unexpected register class"); 51 52 BuildMI(MBB, I, DL, get(SetLocalOpcode), DestReg) 53 .addReg(SrcReg, KillSrc ? RegState::Kill : 0); 54 } 55 56 // Branch analysis. 57 bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 58 MachineBasicBlock *&TBB, 59 MachineBasicBlock *&FBB, 60 SmallVectorImpl<MachineOperand> &Cond, 61 bool AllowModify) const { 62 bool HaveCond = false; 63 for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>( 64 MBB.getFirstInstrTerminator(), MBB.instr_end())) { 65 switch (MI.getOpcode()) { 66 default: 67 // Unhandled instruction; bail out. 68 return true; 69 case WebAssembly::BR_IF: 70 if (HaveCond) 71 return true; 72 Cond.push_back(MI.getOperand(0)); 73 TBB = MI.getOperand(1).getMBB(); 74 HaveCond = true; 75 break; 76 case WebAssembly::BR: 77 if (!HaveCond) 78 TBB = MI.getOperand(0).getMBB(); 79 else 80 FBB = MI.getOperand(0).getMBB(); 81 break; 82 } 83 if (MI.isBarrier()) 84 break; 85 } 86 87 return false; 88 } 89 90 unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 91 MachineBasicBlock::instr_iterator I = MBB.instr_end(); 92 unsigned Count = 0; 93 94 while (I != MBB.instr_begin()) { 95 --I; 96 if (I->isDebugValue()) 97 continue; 98 if (!I->isTerminator()) 99 break; 100 // Remove the branch. 101 I->eraseFromParent(); 102 I = MBB.instr_end(); 103 ++Count; 104 } 105 106 return Count; 107 } 108 109 unsigned WebAssemblyInstrInfo::InsertBranch( 110 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 111 ArrayRef<MachineOperand> Cond, DebugLoc DL) const { 112 assert(Cond.size() <= 1); 113 114 if (Cond.empty()) { 115 if (!TBB) 116 return 0; 117 118 BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB); 119 return 1; 120 } 121 122 BuildMI(&MBB, DL, get(WebAssembly::BR_IF)) 123 .addOperand(Cond[0]) 124 .addMBB(TBB); 125 if (!FBB) 126 return 1; 127 128 BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB); 129 return 2; 130 } 131 132 bool WebAssemblyInstrInfo::ReverseBranchCondition( 133 SmallVectorImpl<MachineOperand> &Cond) const { 134 assert(Cond.size() == 1); 135 136 // TODO: Add branch reversal here... And re-enable MachineBlockPlacementID 137 // when we do. 138 139 return true; 140 } 141