12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- //===-- WebAssemblyArgumentMove.cpp - Argument instruction moving ---------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// This file moves ARGUMENT instructions after ScheduleDAG scheduling.
- ///
- /// Arguments are really live-in registers, however, since we use virtual
- /// registers and LLVM doesn't support live-in virtual registers, we're
- /// currently making do with ARGUMENT instructions which are placed at the top
- /// of the entry block. The trick is to get them to *stay* at the top of the
- /// entry block.
- ///
- /// The ARGUMENTS physical register keeps these instructions pinned in place
- /// during liveness-aware CodeGen passes, however one thing which does not
- /// respect this is the ScheduleDAG scheduler. This pass is therefore run
- /// immediately after that.
- ///
- /// This is all hopefully a temporary solution until we find a better solution
- /// for describing the live-in nature of arguments.
- ///
- //===----------------------------------------------------------------------===//
- #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
- #include "Utils/WebAssemblyUtilities.h"
- #include "WebAssembly.h"
- #include "WebAssemblyMachineFunctionInfo.h"
- #include "WebAssemblySubtarget.h"
- #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
- #include "llvm/CodeGen/MachineRegisterInfo.h"
- #include "llvm/CodeGen/Passes.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace llvm;
- #define DEBUG_TYPE "wasm-argument-move"
- namespace {
- class WebAssemblyArgumentMove final : public MachineFunctionPass {
- public:
- static char ID; // Pass identification, replacement for typeid
- WebAssemblyArgumentMove() : MachineFunctionPass(ID) {}
- StringRef getPassName() const override { return "WebAssembly Argument Move"; }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- AU.addPreserved<MachineBlockFrequencyInfo>();
- AU.addPreservedID(MachineDominatorsID);
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- bool runOnMachineFunction(MachineFunction &MF) override;
- };
- } // end anonymous namespace
- char WebAssemblyArgumentMove::ID = 0;
- INITIALIZE_PASS(WebAssemblyArgumentMove, DEBUG_TYPE,
- "Move ARGUMENT instructions for WebAssembly", false, false)
- FunctionPass *llvm::createWebAssemblyArgumentMove() {
- return new WebAssemblyArgumentMove();
- }
- bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {
- LLVM_DEBUG({
- dbgs() << "********** Argument Move **********\n"
- << "********** Function: " << MF.getName() << '\n';
- });
- bool Changed = false;
- MachineBasicBlock &EntryMBB = MF.front();
- MachineBasicBlock::iterator InsertPt = EntryMBB.end();
- // Look for the first NonArg instruction.
- for (MachineInstr &MI : EntryMBB) {
- if (!WebAssembly::isArgument(MI.getOpcode())) {
- InsertPt = MI;
- break;
- }
- }
- // Now move any argument instructions later in the block
- // to before our first NonArg instruction.
- for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) {
- if (WebAssembly::isArgument(MI.getOpcode())) {
- EntryMBB.insert(InsertPt, MI.removeFromParent());
- Changed = true;
- }
- }
- return Changed;
- }
|