brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 8601a61 Raw
95 lines · cpp
1//===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file moves ARGUMENT instructions after ScheduleDAG scheduling.11///12/// Arguments are really live-in registers, however, since we use virtual13/// registers and LLVM doesn't support live-in virtual registers, we're14/// currently making do with ARGUMENT instructions which are placed at the top15/// of the entry block. The trick is to get them to *stay* at the top of the16/// entry block.17///18/// The ARGUMENTS physical register keeps these instructions pinned in place19/// during liveness-aware CodeGen passes, however one thing which does not20/// respect this is the ScheduleDAG scheduler. This pass is therefore run21/// immediately after that.22///23/// This is all hopefully a temporary solution until we find a better solution24/// for describing the live-in nature of arguments.25///26//===----------------------------------------------------------------------===//27 28#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"29#include "WebAssembly.h"30#include "WebAssemblyUtilities.h"31#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"32#include "llvm/CodeGen/Passes.h"33#include "llvm/Support/Debug.h"34#include "llvm/Support/raw_ostream.h"35using namespace llvm;36 37#define DEBUG_TYPE "wasm-argument-move"38 39namespace {40class WebAssemblyArgumentMove final : public MachineFunctionPass {41public:42  static char ID; // Pass identification, replacement for typeid43  WebAssemblyArgumentMove() : MachineFunctionPass(ID) {}44 45  StringRef getPassName() const override { return "WebAssembly Argument Move"; }46 47  void getAnalysisUsage(AnalysisUsage &AU) const override {48    AU.setPreservesCFG();49    AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();50    AU.addPreservedID(MachineDominatorsID);51    MachineFunctionPass::getAnalysisUsage(AU);52  }53 54  bool runOnMachineFunction(MachineFunction &MF) override;55};56} // end anonymous namespace57 58char WebAssemblyArgumentMove::ID = 0;59INITIALIZE_PASS(WebAssemblyArgumentMove, DEBUG_TYPE,60                "Move ARGUMENT instructions for WebAssembly", false, false)61 62FunctionPass *llvm::createWebAssemblyArgumentMove() {63  return new WebAssemblyArgumentMove();64}65 66bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {67  LLVM_DEBUG({68    dbgs() << "********** Argument Move **********\n"69           << "********** Function: " << MF.getName() << '\n';70  });71 72  bool Changed = false;73  MachineBasicBlock &EntryMBB = MF.front();74  MachineBasicBlock::iterator InsertPt = EntryMBB.end();75 76  // Look for the first NonArg instruction.77  for (MachineInstr &MI : EntryMBB) {78    if (!WebAssembly::isArgument(MI.getOpcode())) {79      InsertPt = MI;80      break;81    }82  }83 84  // Now move any argument instructions later in the block85  // to before our first NonArg instruction.86  for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) {87    if (WebAssembly::isArgument(MI.getOpcode())) {88      EntryMBB.insert(InsertPt, MI.removeFromParent());89      Changed = true;90    }91  }92 93  return Changed;94}95