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 115f8f34e4SAdrian Prantl /// 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" 334fc4e42dSDan 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; 6340926451SJacob Gravelle INITIALIZE_PASS(WebAssemblyArgumentMove, DEBUG_TYPE, 6440926451SJacob Gravelle "Move ARGUMENT instructions for WebAssembly", false, false) 6540926451SJacob Gravelle 661cf96c0cSDan Gohman FunctionPass *llvm::createWebAssemblyArgumentMove() { 671cf96c0cSDan Gohman return new WebAssemblyArgumentMove(); 681cf96c0cSDan Gohman } 691cf96c0cSDan Gohman 701cf96c0cSDan Gohman bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) { 71*d34e60caSNicola Zaghen LLVM_DEBUG({ 721cf96c0cSDan Gohman dbgs() << "********** Argument Move **********\n" 731cf96c0cSDan Gohman << "********** Function: " << MF.getName() << '\n'; 741cf96c0cSDan Gohman }); 751cf96c0cSDan Gohman 761cf96c0cSDan Gohman bool Changed = false; 771cf96c0cSDan Gohman MachineBasicBlock &EntryMBB = MF.front(); 781cf96c0cSDan Gohman MachineBasicBlock::iterator InsertPt = EntryMBB.end(); 791cf96c0cSDan Gohman 801cf96c0cSDan Gohman // Look for the first NonArg instruction. 81500d0469SDuncan P. N. Exon Smith for (MachineInstr &MI : EntryMBB) { 824fc4e42dSDan Gohman if (!WebAssembly::isArgument(MI)) { 83500d0469SDuncan P. N. Exon Smith InsertPt = MI; 841cf96c0cSDan Gohman break; 851cf96c0cSDan Gohman } 861cf96c0cSDan Gohman } 871cf96c0cSDan Gohman 881cf96c0cSDan Gohman // Now move any argument instructions later in the block 891cf96c0cSDan Gohman // to before our first NonArg instruction. 90500d0469SDuncan P. N. Exon Smith for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) { 914fc4e42dSDan Gohman if (WebAssembly::isArgument(MI)) { 92500d0469SDuncan P. N. Exon Smith EntryMBB.insert(InsertPt, MI.removeFromParent()); 931cf96c0cSDan Gohman Changed = true; 941cf96c0cSDan Gohman } 951cf96c0cSDan Gohman } 961cf96c0cSDan Gohman 971cf96c0cSDan Gohman return Changed; 981cf96c0cSDan Gohman } 99