1 //===- WebAssemblyPrepareForLiveIntervals.cpp - Prepare for LiveIntervals -===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// Fix up code to meet LiveInterval's requirements. 12 /// 13 /// Some CodeGen passes don't preserve LiveInterval's requirements, because 14 /// they run after register allocation and it isn't important. However, 15 /// WebAssembly runs LiveIntervals in a late pass. This pass transforms code 16 /// to meet LiveIntervals' requirements; primarily, it ensures that all 17 /// virtual register uses have definitions (IMPLICIT_DEF definitions if 18 /// nothing else). 19 /// 20 //===----------------------------------------------------------------------===// 21 22 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 23 #include "WebAssembly.h" 24 #include "WebAssemblyMachineFunctionInfo.h" 25 #include "WebAssemblySubtarget.h" 26 #include "WebAssemblyUtilities.h" 27 #include "llvm/CodeGen/MachineFunctionPass.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineRegisterInfo.h" 30 #include "llvm/CodeGen/Passes.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/raw_ostream.h" 33 using namespace llvm; 34 35 #define DEBUG_TYPE "wasm-prepare-for-live-intervals" 36 37 namespace { 38 class WebAssemblyPrepareForLiveIntervals final : public MachineFunctionPass { 39 public: 40 static char ID; // Pass identification, replacement for typeid 41 WebAssemblyPrepareForLiveIntervals() : MachineFunctionPass(ID) {} 42 43 private: 44 StringRef getPassName() const override { 45 return "WebAssembly Prepare For LiveIntervals"; 46 } 47 48 void getAnalysisUsage(AnalysisUsage &AU) const override { 49 AU.setPreservesCFG(); 50 MachineFunctionPass::getAnalysisUsage(AU); 51 } 52 53 bool runOnMachineFunction(MachineFunction &MF) override; 54 }; 55 } // end anonymous namespace 56 57 char WebAssemblyPrepareForLiveIntervals::ID = 0; 58 INITIALIZE_PASS(WebAssemblyPrepareForLiveIntervals, DEBUG_TYPE, 59 "Fix up code for LiveIntervals", false, false) 60 61 FunctionPass *llvm::createWebAssemblyPrepareForLiveIntervals() { 62 return new WebAssemblyPrepareForLiveIntervals(); 63 } 64 65 // Test whether the given register has an ARGUMENT def. 66 static bool HasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) { 67 for (const auto &Def : MRI.def_instructions(Reg)) 68 if (WebAssembly::isArgument(Def)) 69 return true; 70 return false; 71 } 72 73 bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(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 = TargetRegisterInfo::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)) { 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