1 //===- WebAssemblyPrepareForLiveIntervals.cpp - Prepare for LiveIntervals -===// 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 /// Fix up code to meet LiveInterval's requirements. 11 /// 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 17 /// nothing else). 18 /// 19 //===----------------------------------------------------------------------===// 20 21 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 22 #include "Utils/WebAssemblyUtilities.h" 23 #include "WebAssembly.h" 24 #include "WebAssemblyMachineFunctionInfo.h" 25 #include "WebAssemblySubtarget.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" 32 using namespace llvm; 33 34 #define DEBUG_TYPE "wasm-prepare-for-live-intervals" 35 36 namespace { 37 class WebAssemblyPrepareForLiveIntervals final : public MachineFunctionPass { 38 public: 39 static char ID; // Pass identification, replacement for typeid 40 WebAssemblyPrepareForLiveIntervals() : MachineFunctionPass(ID) {} 41 42 private: 43 StringRef getPassName() const override { 44 return "WebAssembly Prepare For LiveIntervals"; 45 } 46 47 void getAnalysisUsage(AnalysisUsage &AU) const override { 48 AU.setPreservesCFG(); 49 MachineFunctionPass::getAnalysisUsage(AU); 50 } 51 52 bool runOnMachineFunction(MachineFunction &MF) override; 53 }; 54 } // end anonymous namespace 55 56 char WebAssemblyPrepareForLiveIntervals::ID = 0; 57 INITIALIZE_PASS(WebAssemblyPrepareForLiveIntervals, DEBUG_TYPE, 58 "Fix up code for LiveIntervals", false, false) 59 60 FunctionPass *llvm::createWebAssemblyPrepareForLiveIntervals() { 61 return new WebAssemblyPrepareForLiveIntervals(); 62 } 63 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())) 68 return true; 69 return false; 70 } 71 72 bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction( 73 MachineFunction &MF) { 74 LLVM_DEBUG({ 75 dbgs() << "********** Prepare For LiveIntervals **********\n" 76 << "********** Function: " << MF.getName() << '\n'; 77 }); 78 79 bool Changed = false; 80 MachineRegisterInfo &MRI = MF.getRegInfo(); 81 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 82 MachineBasicBlock &Entry = *MF.begin(); 83 84 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 85 "LiveIntervals shouldn't be active yet!"); 86 87 // We don't preserve SSA form. 88 MRI.leaveSSA(); 89 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. 94 // 95 // TODO: This is fairly heavy-handed; find a better approach. 96 // 97 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) { 98 unsigned Reg = Register::index2VirtReg(I); 99 100 // Skip unused registers. 101 if (MRI.use_nodbg_empty(Reg)) 102 continue; 103 104 // Skip registers that have an ARGUMENT definition. 105 if (hasArgumentDef(Reg, MRI)) 106 continue; 107 108 BuildMI(Entry, Entry.begin(), DebugLoc(), 109 TII.get(WebAssembly::IMPLICIT_DEF), Reg); 110 Changed = true; 111 } 112 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); 120 } 121 } 122 123 // Ok, we're now ready to run the LiveIntervals analysis again. 124 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); 125 126 return Changed; 127 } 128