[mlir][LLVM] `LLVMTypeConverter`: Tighten materialization checks (#116532)
[llvm-project.git] / llvm / lib / Target / WebAssembly / WebAssemblyArgumentMove.cpp
blob8601a61626ac626e10d2cdd47ec73f8b461322b6
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file moves ARGUMENT instructions after ScheduleDAG scheduling.
11 ///
12 /// Arguments are really live-in registers, however, since we use virtual
13 /// registers and LLVM doesn't support live-in virtual registers, we're
14 /// currently making do with ARGUMENT instructions which are placed at the top
15 /// of the entry block. The trick is to get them to *stay* at the top of the
16 /// entry block.
17 ///
18 /// The ARGUMENTS physical register keeps these instructions pinned in place
19 /// during liveness-aware CodeGen passes, however one thing which does not
20 /// respect this is the ScheduleDAG scheduler. This pass is therefore run
21 /// immediately after that.
22 ///
23 /// This is all hopefully a temporary solution until we find a better solution
24 /// for describing the live-in nature of arguments.
25 ///
26 //===----------------------------------------------------------------------===//
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"
35 using namespace llvm;
37 #define DEBUG_TYPE "wasm-argument-move"
39 namespace {
40 class WebAssemblyArgumentMove final : public MachineFunctionPass {
41 public:
42 static char ID; // Pass identification, replacement for typeid
43 WebAssemblyArgumentMove() : MachineFunctionPass(ID) {}
45 StringRef getPassName() const override { return "WebAssembly Argument Move"; }
47 void getAnalysisUsage(AnalysisUsage &AU) const override {
48 AU.setPreservesCFG();
49 AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();
50 AU.addPreservedID(MachineDominatorsID);
51 MachineFunctionPass::getAnalysisUsage(AU);
54 bool runOnMachineFunction(MachineFunction &MF) override;
56 } // end anonymous namespace
58 char WebAssemblyArgumentMove::ID = 0;
59 INITIALIZE_PASS(WebAssemblyArgumentMove, DEBUG_TYPE,
60 "Move ARGUMENT instructions for WebAssembly", false, false)
62 FunctionPass *llvm::createWebAssemblyArgumentMove() {
63 return new WebAssemblyArgumentMove();
66 bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {
67 LLVM_DEBUG({
68 dbgs() << "********** Argument Move **********\n"
69 << "********** Function: " << MF.getName() << '\n';
70 });
72 bool Changed = false;
73 MachineBasicBlock &EntryMBB = MF.front();
74 MachineBasicBlock::iterator InsertPt = EntryMBB.end();
76 // Look for the first NonArg instruction.
77 for (MachineInstr &MI : EntryMBB) {
78 if (!WebAssembly::isArgument(MI.getOpcode())) {
79 InsertPt = MI;
80 break;
84 // Now move any argument instructions later in the block
85 // 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;
93 return Changed;