Path: blob/main/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyArgumentMove.cpp
35266 views
//===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file moves ARGUMENT instructions after ScheduleDAG scheduling.10///11/// Arguments are really live-in registers, however, since we use virtual12/// registers and LLVM doesn't support live-in virtual registers, we're13/// currently making do with ARGUMENT instructions which are placed at the top14/// of the entry block. The trick is to get them to *stay* at the top of the15/// entry block.16///17/// The ARGUMENTS physical register keeps these instructions pinned in place18/// during liveness-aware CodeGen passes, however one thing which does not19/// respect this is the ScheduleDAG scheduler. This pass is therefore run20/// immediately after that.21///22/// This is all hopefully a temporary solution until we find a better solution23/// for describing the live-in nature of arguments.24///25//===----------------------------------------------------------------------===//2627#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"28#include "WebAssembly.h"29#include "WebAssemblyMachineFunctionInfo.h"30#include "WebAssemblySubtarget.h"31#include "WebAssemblyUtilities.h"32#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"33#include "llvm/CodeGen/MachineRegisterInfo.h"34#include "llvm/CodeGen/Passes.h"35#include "llvm/Support/Debug.h"36#include "llvm/Support/raw_ostream.h"37using namespace llvm;3839#define DEBUG_TYPE "wasm-argument-move"4041namespace {42class WebAssemblyArgumentMove final : public MachineFunctionPass {43public:44static char ID; // Pass identification, replacement for typeid45WebAssemblyArgumentMove() : MachineFunctionPass(ID) {}4647StringRef getPassName() const override { return "WebAssembly Argument Move"; }4849void getAnalysisUsage(AnalysisUsage &AU) const override {50AU.setPreservesCFG();51AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();52AU.addPreservedID(MachineDominatorsID);53MachineFunctionPass::getAnalysisUsage(AU);54}5556bool runOnMachineFunction(MachineFunction &MF) override;57};58} // end anonymous namespace5960char WebAssemblyArgumentMove::ID = 0;61INITIALIZE_PASS(WebAssemblyArgumentMove, DEBUG_TYPE,62"Move ARGUMENT instructions for WebAssembly", false, false)6364FunctionPass *llvm::createWebAssemblyArgumentMove() {65return new WebAssemblyArgumentMove();66}6768bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {69LLVM_DEBUG({70dbgs() << "********** Argument Move **********\n"71<< "********** Function: " << MF.getName() << '\n';72});7374bool Changed = false;75MachineBasicBlock &EntryMBB = MF.front();76MachineBasicBlock::iterator InsertPt = EntryMBB.end();7778// Look for the first NonArg instruction.79for (MachineInstr &MI : EntryMBB) {80if (!WebAssembly::isArgument(MI.getOpcode())) {81InsertPt = MI;82break;83}84}8586// Now move any argument instructions later in the block87// to before our first NonArg instruction.88for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) {89if (WebAssembly::isArgument(MI.getOpcode())) {90EntryMBB.insert(InsertPt, MI.removeFromParent());91Changed = true;92}93}9495return Changed;96}979899