11cf96c0cSDan Gohman //===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===// 21cf96c0cSDan Gohman // 31cf96c0cSDan Gohman // The LLVM Compiler Infrastructure 41cf96c0cSDan Gohman // 51cf96c0cSDan Gohman // This file is distributed under the University of Illinois Open Source 61cf96c0cSDan Gohman // License. See LICENSE.TXT for details. 71cf96c0cSDan Gohman // 81cf96c0cSDan Gohman //===----------------------------------------------------------------------===// 91cf96c0cSDan Gohman /// 101cf96c0cSDan Gohman /// \file 111cf96c0cSDan Gohman /// \brief This file moves ARGUMENT instructions after ScheduleDAG scheduling. 121cf96c0cSDan Gohman /// 131cf96c0cSDan Gohman /// Arguments are really live-in registers, however, since we use virtual 141cf96c0cSDan Gohman /// registers and LLVM doesn't support live-in virtual registers, we're 151cf96c0cSDan Gohman /// currently making do with ARGUMENT instructions which are placed at the top 161cf96c0cSDan Gohman /// of the entry block. The trick is to get them to *stay* at the top of the 171cf96c0cSDan Gohman /// entry block. 181cf96c0cSDan Gohman /// 191cf96c0cSDan Gohman /// The ARGUMENTS physical register keeps these instructions pinned in place 201cf96c0cSDan Gohman /// during liveness-aware CodeGen passes, however one thing which does not 211cf96c0cSDan Gohman /// respect this is the ScheduleDAG scheduler. This pass is therefore run 221cf96c0cSDan Gohman /// immediately after that. 231cf96c0cSDan Gohman /// 241cf96c0cSDan Gohman /// This is all hopefully a temporary solution until we find a better solution 251cf96c0cSDan Gohman /// for describing the live-in nature of arguments. 261cf96c0cSDan Gohman /// 271cf96c0cSDan Gohman //===----------------------------------------------------------------------===// 281cf96c0cSDan Gohman 291cf96c0cSDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 3039bf39f3SDerek Schuff #include "WebAssembly.h" 311cf96c0cSDan Gohman #include "WebAssemblyMachineFunctionInfo.h" 3239bf39f3SDerek Schuff #include "WebAssemblySubtarget.h" 33*4fc4e42dSDan Gohman #include "WebAssemblyUtilities.h" 341cf96c0cSDan Gohman #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 351cf96c0cSDan Gohman #include "llvm/CodeGen/MachineRegisterInfo.h" 361cf96c0cSDan Gohman #include "llvm/CodeGen/Passes.h" 371cf96c0cSDan Gohman #include "llvm/Support/Debug.h" 381cf96c0cSDan Gohman #include "llvm/Support/raw_ostream.h" 391cf96c0cSDan Gohman using namespace llvm; 401cf96c0cSDan Gohman 411cf96c0cSDan Gohman #define DEBUG_TYPE "wasm-argument-move" 421cf96c0cSDan Gohman 431cf96c0cSDan Gohman namespace { 441cf96c0cSDan Gohman class WebAssemblyArgumentMove final : public MachineFunctionPass { 451cf96c0cSDan Gohman public: 461cf96c0cSDan Gohman static char ID; // Pass identification, replacement for typeid 471cf96c0cSDan Gohman WebAssemblyArgumentMove() : MachineFunctionPass(ID) {} 481cf96c0cSDan Gohman 49117296c0SMehdi Amini StringRef getPassName() const override { return "WebAssembly Argument Move"; } 501cf96c0cSDan Gohman 511cf96c0cSDan Gohman void getAnalysisUsage(AnalysisUsage &AU) const override { 521cf96c0cSDan Gohman AU.setPreservesCFG(); 531cf96c0cSDan Gohman AU.addPreserved<MachineBlockFrequencyInfo>(); 541cf96c0cSDan Gohman AU.addPreservedID(MachineDominatorsID); 551cf96c0cSDan Gohman MachineFunctionPass::getAnalysisUsage(AU); 561cf96c0cSDan Gohman } 571cf96c0cSDan Gohman 581cf96c0cSDan Gohman bool runOnMachineFunction(MachineFunction &MF) override; 591cf96c0cSDan Gohman }; 601cf96c0cSDan Gohman } // end anonymous namespace 611cf96c0cSDan Gohman 621cf96c0cSDan Gohman char WebAssemblyArgumentMove::ID = 0; 631cf96c0cSDan Gohman FunctionPass *llvm::createWebAssemblyArgumentMove() { 641cf96c0cSDan Gohman return new WebAssemblyArgumentMove(); 651cf96c0cSDan Gohman } 661cf96c0cSDan Gohman 671cf96c0cSDan Gohman bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) { 681cf96c0cSDan Gohman DEBUG({ 691cf96c0cSDan Gohman dbgs() << "********** Argument Move **********\n" 701cf96c0cSDan Gohman << "********** Function: " << MF.getName() << '\n'; 711cf96c0cSDan Gohman }); 721cf96c0cSDan Gohman 731cf96c0cSDan Gohman bool Changed = false; 741cf96c0cSDan Gohman MachineBasicBlock &EntryMBB = MF.front(); 751cf96c0cSDan Gohman MachineBasicBlock::iterator InsertPt = EntryMBB.end(); 761cf96c0cSDan Gohman 771cf96c0cSDan Gohman // Look for the first NonArg instruction. 78500d0469SDuncan P. N. Exon Smith for (MachineInstr &MI : EntryMBB) { 79*4fc4e42dSDan Gohman if (!WebAssembly::isArgument(MI)) { 80500d0469SDuncan P. N. Exon Smith InsertPt = MI; 811cf96c0cSDan Gohman break; 821cf96c0cSDan Gohman } 831cf96c0cSDan Gohman } 841cf96c0cSDan Gohman 851cf96c0cSDan Gohman // Now move any argument instructions later in the block 861cf96c0cSDan Gohman // to before our first NonArg instruction. 87500d0469SDuncan P. N. Exon Smith for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) { 88*4fc4e42dSDan Gohman if (WebAssembly::isArgument(MI)) { 89500d0469SDuncan P. N. Exon Smith EntryMBB.insert(InsertPt, MI.removeFromParent()); 901cf96c0cSDan Gohman Changed = true; 911cf96c0cSDan Gohman } 921cf96c0cSDan Gohman } 931cf96c0cSDan Gohman 941cf96c0cSDan Gohman return Changed; 951cf96c0cSDan Gohman } 96