WebAssemblyArgumentMove.cpp revision 314564
1292915Sdim//===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===// 2292915Sdim// 3292915Sdim// The LLVM Compiler Infrastructure 4292915Sdim// 5292915Sdim// This file is distributed under the University of Illinois Open Source 6292915Sdim// License. See LICENSE.TXT for details. 7292915Sdim// 8292915Sdim//===----------------------------------------------------------------------===// 9292915Sdim/// 10292915Sdim/// \file 11292915Sdim/// \brief This file moves ARGUMENT instructions after ScheduleDAG scheduling. 12292915Sdim/// 13292915Sdim/// Arguments are really live-in registers, however, since we use virtual 14292915Sdim/// registers and LLVM doesn't support live-in virtual registers, we're 15292915Sdim/// currently making do with ARGUMENT instructions which are placed at the top 16292915Sdim/// of the entry block. The trick is to get them to *stay* at the top of the 17292915Sdim/// entry block. 18292915Sdim/// 19292915Sdim/// The ARGUMENTS physical register keeps these instructions pinned in place 20292915Sdim/// during liveness-aware CodeGen passes, however one thing which does not 21292915Sdim/// respect this is the ScheduleDAG scheduler. This pass is therefore run 22292915Sdim/// immediately after that. 23292915Sdim/// 24292915Sdim/// This is all hopefully a temporary solution until we find a better solution 25292915Sdim/// for describing the live-in nature of arguments. 26292915Sdim/// 27292915Sdim//===----------------------------------------------------------------------===// 28292915Sdim 29314564Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 30292915Sdim#include "WebAssembly.h" 31292915Sdim#include "WebAssemblyMachineFunctionInfo.h" 32314564Sdim#include "WebAssemblySubtarget.h" 33314564Sdim#include "WebAssemblyUtilities.h" 34292915Sdim#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 35292915Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 36292915Sdim#include "llvm/CodeGen/Passes.h" 37292915Sdim#include "llvm/Support/Debug.h" 38292915Sdim#include "llvm/Support/raw_ostream.h" 39292915Sdimusing namespace llvm; 40292915Sdim 41292915Sdim#define DEBUG_TYPE "wasm-argument-move" 42292915Sdim 43292915Sdimnamespace { 44292915Sdimclass WebAssemblyArgumentMove final : public MachineFunctionPass { 45292915Sdimpublic: 46292915Sdim static char ID; // Pass identification, replacement for typeid 47292915Sdim WebAssemblyArgumentMove() : MachineFunctionPass(ID) {} 48292915Sdim 49314564Sdim StringRef getPassName() const override { return "WebAssembly Argument Move"; } 50292915Sdim 51292915Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 52292915Sdim AU.setPreservesCFG(); 53292915Sdim AU.addPreserved<MachineBlockFrequencyInfo>(); 54292915Sdim AU.addPreservedID(MachineDominatorsID); 55292915Sdim MachineFunctionPass::getAnalysisUsage(AU); 56292915Sdim } 57292915Sdim 58292915Sdim bool runOnMachineFunction(MachineFunction &MF) override; 59292915Sdim}; 60292915Sdim} // end anonymous namespace 61292915Sdim 62292915Sdimchar WebAssemblyArgumentMove::ID = 0; 63292915SdimFunctionPass *llvm::createWebAssemblyArgumentMove() { 64292915Sdim return new WebAssemblyArgumentMove(); 65292915Sdim} 66292915Sdim 67292915Sdimbool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) { 68292915Sdim DEBUG({ 69292915Sdim dbgs() << "********** Argument Move **********\n" 70292915Sdim << "********** Function: " << MF.getName() << '\n'; 71292915Sdim }); 72292915Sdim 73292915Sdim bool Changed = false; 74292915Sdim MachineBasicBlock &EntryMBB = MF.front(); 75292915Sdim MachineBasicBlock::iterator InsertPt = EntryMBB.end(); 76292915Sdim 77292915Sdim // Look for the first NonArg instruction. 78309124Sdim for (MachineInstr &MI : EntryMBB) { 79314564Sdim if (!WebAssembly::isArgument(MI)) { 80309124Sdim InsertPt = MI; 81292915Sdim break; 82292915Sdim } 83292915Sdim } 84292915Sdim 85292915Sdim // Now move any argument instructions later in the block 86292915Sdim // to before our first NonArg instruction. 87309124Sdim for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) { 88314564Sdim if (WebAssembly::isArgument(MI)) { 89309124Sdim EntryMBB.insert(InsertPt, MI.removeFromParent()); 90292915Sdim Changed = true; 91292915Sdim } 92292915Sdim } 93292915Sdim 94292915Sdim return Changed; 95292915Sdim} 96