1 //===- WebAssemblyPrepareForLiveIntervals.cpp - Prepare for LiveIntervals -===//
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
7 //===----------------------------------------------------------------------===//
10 /// Fix up code to meet LiveInterval's requirements.
12 /// Some CodeGen passes don't preserve LiveInterval's requirements, because
13 /// they run after register allocation and it isn't important. However,
14 /// WebAssembly runs LiveIntervals in a late pass. This pass transforms code
15 /// to meet LiveIntervals' requirements; primarily, it ensures that all
16 /// virtual register uses have definitions (IMPLICIT_DEF definitions if
19 //===----------------------------------------------------------------------===//
21 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
22 #include "WebAssembly.h"
23 #include "WebAssemblyMachineFunctionInfo.h"
24 #include "WebAssemblySubtarget.h"
25 #include "WebAssemblyUtilities.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
28 #include "llvm/CodeGen/MachineRegisterInfo.h"
29 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/raw_ostream.h"
34 #define DEBUG_TYPE "wasm-prepare-for-live-intervals"
37 class WebAssemblyPrepareForLiveIntervals final
: public MachineFunctionPass
{
39 static char ID
; // Pass identification, replacement for typeid
40 WebAssemblyPrepareForLiveIntervals() : MachineFunctionPass(ID
) {}
43 StringRef
getPassName() const override
{
44 return "WebAssembly Prepare For LiveIntervals";
47 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
49 MachineFunctionPass::getAnalysisUsage(AU
);
52 bool runOnMachineFunction(MachineFunction
&MF
) override
;
54 } // end anonymous namespace
56 char WebAssemblyPrepareForLiveIntervals::ID
= 0;
57 INITIALIZE_PASS(WebAssemblyPrepareForLiveIntervals
, DEBUG_TYPE
,
58 "Fix up code for LiveIntervals", false, false)
60 FunctionPass
*llvm::createWebAssemblyPrepareForLiveIntervals() {
61 return new WebAssemblyPrepareForLiveIntervals();
64 // Test whether the given register has an ARGUMENT def.
65 static bool hasArgumentDef(unsigned Reg
, const MachineRegisterInfo
&MRI
) {
66 for (const auto &Def
: MRI
.def_instructions(Reg
))
67 if (WebAssembly::isArgument(Def
.getOpcode()))
72 bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(
73 MachineFunction
&MF
) {
75 dbgs() << "********** Prepare For LiveIntervals **********\n"
76 << "********** Function: " << MF
.getName() << '\n';
80 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
81 const auto &TII
= *MF
.getSubtarget
<WebAssemblySubtarget
>().getInstrInfo();
82 MachineBasicBlock
&Entry
= *MF
.begin();
84 assert(!mustPreserveAnalysisID(LiveIntervalsID
) &&
85 "LiveIntervals shouldn't be active yet!");
87 // We don't preserve SSA form.
90 // BranchFolding and perhaps other passes don't preserve IMPLICIT_DEF
91 // instructions. LiveIntervals requires that all paths to virtual register
92 // uses provide a definition. Insert IMPLICIT_DEFs in the entry block to
93 // conservatively satisfy this.
95 // TODO: This is fairly heavy-handed; find a better approach.
97 for (unsigned I
= 0, E
= MRI
.getNumVirtRegs(); I
< E
; ++I
) {
98 unsigned Reg
= Register::index2VirtReg(I
);
100 // Skip unused registers.
101 if (MRI
.use_nodbg_empty(Reg
))
104 // Skip registers that have an ARGUMENT definition.
105 if (hasArgumentDef(Reg
, MRI
))
108 BuildMI(Entry
, Entry
.begin(), DebugLoc(),
109 TII
.get(WebAssembly::IMPLICIT_DEF
), Reg
);
113 // Move ARGUMENT_* instructions to the top of the entry block, so that their
114 // liveness reflects the fact that these really are live-in values.
115 for (auto MII
= Entry
.begin(), MIE
= Entry
.end(); MII
!= MIE
;) {
116 MachineInstr
&MI
= *MII
++;
117 if (WebAssembly::isArgument(MI
.getOpcode())) {
118 MI
.removeFromParent();
119 Entry
.insert(Entry
.begin(), &MI
);
123 // Ok, we're now ready to run the LiveIntervals analysis again.
124 MF
.getProperties().set(MachineFunctionProperties::Property::TracksLiveness
);