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 BuildMI(MBB, I, DL, get(WebAssembly::COPY), DestReg) 38 .addReg(SrcReg, KillSrc ? RegState::Kill : 0); 39 } 40 41 // Branch analysis. 42 bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 43 MachineBasicBlock *&TBB, 44 MachineBasicBlock *&FBB, 45 SmallVectorImpl<MachineOperand> &Cond, 46 bool AllowModify) const { 47 bool HaveCond = false; 48 for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>( 49 MBB.getFirstInstrTerminator(), MBB.instr_end())) { 50 switch (MI.getOpcode()) { 51 default: 52 // Unhandled instruction; bail out. 53 return true; 54 case WebAssembly::BRIF: 55 if (HaveCond) 56 return true; 57 Cond.push_back(MI.getOperand(1)); 58 TBB = MI.getOperand(0).getMBB(); 59 HaveCond = true; 60 break; 61 case WebAssembly::BR: 62 if (!HaveCond) 63 TBB = MI.getOperand(0).getMBB(); 64 else 65 FBB = MI.getOperand(0).getMBB(); 66 break; 67 } 68 if (MI.isBarrier()) 69 break; 70 } 71 72 return false; 73 } 74 75 unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 76 MachineBasicBlock::instr_iterator I = MBB.instr_end(); 77 unsigned Count = 0; 78 79 while (I != MBB.instr_begin()) { 80 --I; 81 if (I->isDebugValue()) 82 continue; 83 if (!I->isTerminator()) 84 break; 85 // Remove the branch. 86 I->eraseFromParent(); 87 I = MBB.instr_end(); 88 ++Count; 89 } 90 91 return Count; 92 } 93 94 unsigned WebAssemblyInstrInfo::InsertBranch( 95 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 96 ArrayRef<MachineOperand> Cond, DebugLoc DL) const { 97 assert(Cond.size() <= 1); 98 99 if (Cond.empty()) { 100 if (!TBB) 101 return 0; 102 103 BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB); 104 return 1; 105 } 106 107 BuildMI(&MBB, DL, get(WebAssembly::BRIF)) 108 .addMBB(TBB) 109 .addOperand(Cond[0]); 110 if (!FBB) 111 return 1; 112 113 BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB); 114 return 2; 115 } 116 117 bool WebAssemblyInstrInfo::ReverseBranchCondition( 118 SmallVectorImpl<MachineOperand> &Cond) const { 119 assert(Cond.size() == 1); 120 121 // TODO: Add branch reversal here... And re-enable MachineBlockPlacementID 122 // when we do. 123 124 return true; 125 } 126