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( 74 MachineFunction &MF) { 75 LLVM_DEBUG({ 76 dbgs() << "********** Prepare For LiveIntervals **********\n" 77 << "********** Function: " << MF.getName() << '\n'; 78 }); 79 80 bool Changed = false; 81 MachineRegisterInfo &MRI = MF.getRegInfo(); 82 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 83 MachineBasicBlock &Entry = *MF.begin(); 84 85 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 86 "LiveIntervals shouldn't be active yet!"); 87 88 // We don't preserve SSA form. 89 MRI.leaveSSA(); 90 91 // BranchFolding and perhaps other passes don't preserve IMPLICIT_DEF 92 // instructions. LiveIntervals requires that all paths to virtual register 93 // uses provide a definition. Insert IMPLICIT_DEFs in the entry block to 94 // conservatively satisfy this. 95 // 96 // TODO: This is fairly heavy-handed; find a better approach. 97 // 98 for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { 99 unsigned Reg = TargetRegisterInfo::index2VirtReg(i); 100 101 // Skip unused registers. 102 if (MRI.use_nodbg_empty(Reg)) 103 continue; 104 105 // Skip registers that have an ARGUMENT definition. 106 if (HasArgumentDef(Reg, MRI)) 107 continue; 108 109 BuildMI(Entry, Entry.begin(), DebugLoc(), 110 TII.get(WebAssembly::IMPLICIT_DEF), Reg); 111 Changed = true; 112 } 113 114 // Move ARGUMENT_* instructions to the top of the entry block, so that their 115 // liveness reflects the fact that these really are live-in values. 116 for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE;) { 117 MachineInstr &MI = *MII++; 118 if (WebAssembly::isArgument(MI)) { 119 MI.removeFromParent(); 120 Entry.insert(Entry.begin(), &MI); 121 } 122 } 123 124 // Ok, we're now ready to run the LiveIntervals analysis again. 125 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); 126 127 return Changed; 128 } 129