1cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===// 2cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// 3cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// 5cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// 8cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// 10cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// \file 11cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// \brief This file contains the WebAssembly implementation of the 12cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// TargetInstrInfo class. 13cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// 14cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 15cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 16cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "WebAssemblyInstrInfo.h" 17cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 18cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "WebAssemblySubtarget.h" 19cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/CodeGen/MachineFrameInfo.h" 20cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h" 21cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/CodeGen/MachineMemOperand.h" 22cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/CodeGen/MachineRegisterInfo.h" 23cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarusing namespace llvm; 24cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 25cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#define DEBUG_TYPE "wasm-instr-info" 26cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 27cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#define GET_INSTRINFO_CTOR_DTOR 28cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "WebAssemblyGenInstrInfo.inc" 29cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 30cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarWebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI) 31cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar : WebAssemblyGenInstrInfo(WebAssembly::ADJCALLSTACKDOWN, 32cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar WebAssembly::ADJCALLSTACKUP), 33cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar RI(STI.getTargetTriple()) {} 34cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 35cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock::iterator I, 37cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DebugLoc DL, unsigned DestReg, 38cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned SrcReg, bool KillSrc) const { 39cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // This method is called by post-RA expansion, which expects only pregs to 40cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // exist. However we need to handle both here. 41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto &MRI = MBB.getParent()->getRegInfo(); 42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const TargetRegisterClass *RC = TargetRegisterInfo::isVirtualRegister(DestReg) ? 43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MRI.getRegClass(DestReg) : 44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(SrcReg); 45cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 46cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned CopyLocalOpcode; 47cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (RC == &WebAssembly::I32RegClass) 48cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CopyLocalOpcode = WebAssembly::COPY_LOCAL_I32; 49cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar else if (RC == &WebAssembly::I64RegClass) 50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CopyLocalOpcode = WebAssembly::COPY_LOCAL_I64; 51cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar else if (RC == &WebAssembly::F32RegClass) 52cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CopyLocalOpcode = WebAssembly::COPY_LOCAL_F32; 53cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar else if (RC == &WebAssembly::F64RegClass) 54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CopyLocalOpcode = WebAssembly::COPY_LOCAL_F64; 55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar else 56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar llvm_unreachable("Unexpected register class"); 57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 58cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BuildMI(MBB, I, DL, get(CopyLocalOpcode), DestReg) 59cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar .addReg(SrcReg, KillSrc ? RegState::Kill : 0); 60cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 61cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 62cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Branch analysis. 63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock *&TBB, 65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock *&FBB, 66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVectorImpl<MachineOperand> &Cond, 67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool /*AllowModify*/) const { 68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool HaveCond = false; 69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (MachineInstr &MI : MBB.terminators()) { 70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar switch (MI.getOpcode()) { 71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar default: 72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Unhandled instruction; bail out. 73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case WebAssembly::BR_IF: 75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (HaveCond) 76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Cond.push_back(MachineOperand::CreateImm(true)); 78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Cond.push_back(MI.getOperand(0)); 79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar TBB = MI.getOperand(1).getMBB(); 80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar HaveCond = true; 81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case WebAssembly::BR_UNLESS: 83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (HaveCond) 84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Cond.push_back(MachineOperand::CreateImm(false)); 86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Cond.push_back(MI.getOperand(0)); 87cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar TBB = MI.getOperand(1).getMBB(); 88cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar HaveCond = true; 89cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 90cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case WebAssembly::BR: 91cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!HaveCond) 92cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar TBB = MI.getOperand(0).getMBB(); 93cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar else 94cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar FBB = MI.getOperand(0).getMBB(); 95cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 96cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 97cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (MI.isBarrier()) 98cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 100cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 101cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 102cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarunsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock::instr_iterator I = MBB.instr_end(); 106cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned Count = 0; 107cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 108cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar while (I != MBB.instr_begin()) { 109cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar --I; 110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (I->isDebugValue()) 111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!I->isTerminator()) 113cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 114cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Remove the branch. 115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar I->eraseFromParent(); 116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar I = MBB.instr_end(); 117cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ++Count; 118cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 119cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return Count; 121cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarunsigned WebAssemblyInstrInfo::InsertBranch(MachineBasicBlock &MBB, 124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock *TBB, 125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineBasicBlock *FBB, 126cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ArrayRef<MachineOperand> Cond, 127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DebugLoc DL) const { 128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Cond.empty()) { 129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!TBB) 130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 0; 131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB); 133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 1; 134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar assert(Cond.size() == 2 && "Expected a flag and a successor block"); 137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 138cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Cond[0].getImm()) { 139cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BuildMI(&MBB, DL, get(WebAssembly::BR_IF)) 140cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar .addOperand(Cond[1]) 141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar .addMBB(TBB); 142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } else { 143cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BuildMI(&MBB, DL, get(WebAssembly::BR_UNLESS)) 144cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar .addOperand(Cond[1]) 145cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar .addMBB(TBB); 146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!FBB) 148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 1; 149cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB); 151cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 2; 152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 153cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool WebAssemblyInstrInfo::ReverseBranchCondition( 155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVectorImpl<MachineOperand> &Cond) const { 156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar assert(Cond.size() == 2 && "Expected a flag and a successor block"); 157cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm()); 158cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 159cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 160