1*9880d681SAndroid Build Coastguard Worker //===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker /// 10*9880d681SAndroid Build Coastguard Worker /// \file 11*9880d681SAndroid Build Coastguard Worker /// \brief This file moves ARGUMENT instructions after ScheduleDAG scheduling. 12*9880d681SAndroid Build Coastguard Worker /// 13*9880d681SAndroid Build Coastguard Worker /// Arguments are really live-in registers, however, since we use virtual 14*9880d681SAndroid Build Coastguard Worker /// registers and LLVM doesn't support live-in virtual registers, we're 15*9880d681SAndroid Build Coastguard Worker /// currently making do with ARGUMENT instructions which are placed at the top 16*9880d681SAndroid Build Coastguard Worker /// of the entry block. The trick is to get them to *stay* at the top of the 17*9880d681SAndroid Build Coastguard Worker /// entry block. 18*9880d681SAndroid Build Coastguard Worker /// 19*9880d681SAndroid Build Coastguard Worker /// The ARGUMENTS physical register keeps these instructions pinned in place 20*9880d681SAndroid Build Coastguard Worker /// during liveness-aware CodeGen passes, however one thing which does not 21*9880d681SAndroid Build Coastguard Worker /// respect this is the ScheduleDAG scheduler. This pass is therefore run 22*9880d681SAndroid Build Coastguard Worker /// immediately after that. 23*9880d681SAndroid Build Coastguard Worker /// 24*9880d681SAndroid Build Coastguard Worker /// This is all hopefully a temporary solution until we find a better solution 25*9880d681SAndroid Build Coastguard Worker /// for describing the live-in nature of arguments. 26*9880d681SAndroid Build Coastguard Worker /// 27*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker #include "WebAssembly.h" 30*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 31*9880d681SAndroid Build Coastguard Worker #include "WebAssemblyMachineFunctionInfo.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h" 34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h" 35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h" 36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 37*9880d681SAndroid Build Coastguard Worker using namespace llvm; 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "wasm-argument-move" 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker namespace { 42*9880d681SAndroid Build Coastguard Worker class WebAssemblyArgumentMove final : public MachineFunctionPass { 43*9880d681SAndroid Build Coastguard Worker public: 44*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification, replacement for typeid WebAssemblyArgumentMove()45*9880d681SAndroid Build Coastguard Worker WebAssemblyArgumentMove() : MachineFunctionPass(ID) {} 46*9880d681SAndroid Build Coastguard Worker getPassName() const47*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override { 48*9880d681SAndroid Build Coastguard Worker return "WebAssembly Argument Move"; 49*9880d681SAndroid Build Coastguard Worker } 50*9880d681SAndroid Build Coastguard Worker getAnalysisUsage(AnalysisUsage & AU) const51*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 52*9880d681SAndroid Build Coastguard Worker AU.setPreservesCFG(); 53*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineBlockFrequencyInfo>(); 54*9880d681SAndroid Build Coastguard Worker AU.addPreservedID(MachineDominatorsID); 55*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU); 56*9880d681SAndroid Build Coastguard Worker } 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override; 59*9880d681SAndroid Build Coastguard Worker }; 60*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker char WebAssemblyArgumentMove::ID = 0; createWebAssemblyArgumentMove()63*9880d681SAndroid Build Coastguard WorkerFunctionPass *llvm::createWebAssemblyArgumentMove() { 64*9880d681SAndroid Build Coastguard Worker return new WebAssemblyArgumentMove(); 65*9880d681SAndroid Build Coastguard Worker } 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker /// Test whether the given instruction is an ARGUMENT. IsArgument(const MachineInstr & MI)68*9880d681SAndroid Build Coastguard Workerstatic bool IsArgument(const MachineInstr &MI) { 69*9880d681SAndroid Build Coastguard Worker switch (MI.getOpcode()) { 70*9880d681SAndroid Build Coastguard Worker case WebAssembly::ARGUMENT_I32: 71*9880d681SAndroid Build Coastguard Worker case WebAssembly::ARGUMENT_I64: 72*9880d681SAndroid Build Coastguard Worker case WebAssembly::ARGUMENT_F32: 73*9880d681SAndroid Build Coastguard Worker case WebAssembly::ARGUMENT_F64: 74*9880d681SAndroid Build Coastguard Worker return true; 75*9880d681SAndroid Build Coastguard Worker default: 76*9880d681SAndroid Build Coastguard Worker return false; 77*9880d681SAndroid Build Coastguard Worker } 78*9880d681SAndroid Build Coastguard Worker } 79*9880d681SAndroid Build Coastguard Worker runOnMachineFunction(MachineFunction & MF)80*9880d681SAndroid Build Coastguard Workerbool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) { 81*9880d681SAndroid Build Coastguard Worker DEBUG({ 82*9880d681SAndroid Build Coastguard Worker dbgs() << "********** Argument Move **********\n" 83*9880d681SAndroid Build Coastguard Worker << "********** Function: " << MF.getName() << '\n'; 84*9880d681SAndroid Build Coastguard Worker }); 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker bool Changed = false; 87*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &EntryMBB = MF.front(); 88*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPt = EntryMBB.end(); 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker // Look for the first NonArg instruction. 91*9880d681SAndroid Build Coastguard Worker for (MachineInstr &MI : EntryMBB) { 92*9880d681SAndroid Build Coastguard Worker if (!IsArgument(MI)) { 93*9880d681SAndroid Build Coastguard Worker InsertPt = MI; 94*9880d681SAndroid Build Coastguard Worker break; 95*9880d681SAndroid Build Coastguard Worker } 96*9880d681SAndroid Build Coastguard Worker } 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker // Now move any argument instructions later in the block 99*9880d681SAndroid Build Coastguard Worker // to before our first NonArg instruction. 100*9880d681SAndroid Build Coastguard Worker for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) { 101*9880d681SAndroid Build Coastguard Worker if (IsArgument(MI)) { 102*9880d681SAndroid Build Coastguard Worker EntryMBB.insert(InsertPt, MI.removeFromParent()); 103*9880d681SAndroid Build Coastguard Worker Changed = true; 104*9880d681SAndroid Build Coastguard Worker } 105*9880d681SAndroid Build Coastguard Worker } 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker return Changed; 108*9880d681SAndroid Build Coastguard Worker } 109