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 /// \brief 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 "WebAssembly.h" 23 #include "MCTargetDesc/WebAssemblyMCTargetDesc.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 const char *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 FunctionPass *llvm::createWebAssemblyPrepareForLiveIntervals() { 58 return new WebAssemblyPrepareForLiveIntervals(); 59 } 60 61 /// Test whether the given instruction is an ARGUMENT. 62 static bool IsArgument(const MachineInstr *MI) { 63 switch (MI->getOpcode()) { 64 case WebAssembly::ARGUMENT_I32: 65 case WebAssembly::ARGUMENT_I64: 66 case WebAssembly::ARGUMENT_F32: 67 case WebAssembly::ARGUMENT_F64: 68 return true; 69 default: 70 return false; 71 } 72 } 73 74 // Test whether the given register has an ARGUMENT def. 75 static bool HasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) { 76 for (auto &Def : MRI.def_instructions(Reg)) 77 if (IsArgument(&Def)) 78 return true; 79 return false; 80 } 81 82 bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(MachineFunction &MF) { 83 DEBUG({ 84 dbgs() << "********** Prepare For LiveIntervals **********\n" 85 << "********** Function: " << MF.getName() << '\n'; 86 }); 87 88 bool Changed = false; 89 MachineRegisterInfo &MRI = MF.getRegInfo(); 90 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 91 MachineBasicBlock &Entry = *MF.begin(); 92 93 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 94 "LiveIntervals shouldn't be active yet!"); 95 96 // We don't preserve SSA form. 97 MRI.leaveSSA(); 98 99 // BranchFolding and perhaps other passes don't preserve IMPLICIT_DEF 100 // instructions. LiveIntervals requires that all paths to virtual register 101 // uses provide a definition. Insert IMPLICIT_DEFs in the entry block to 102 // conservatively satisfy this. 103 // 104 // TODO: This is fairly heavy-handed; find a better approach. 105 // 106 for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { 107 unsigned Reg = TargetRegisterInfo::index2VirtReg(i); 108 109 // Skip unused registers. 110 if (MRI.use_nodbg_empty(Reg)) 111 continue; 112 113 // Skip registers that have an ARGUMENT definition. 114 if (HasArgumentDef(Reg, MRI)) 115 continue; 116 117 BuildMI(Entry, Entry.begin(), DebugLoc(), 118 TII.get(WebAssembly::IMPLICIT_DEF), Reg); 119 Changed = true; 120 } 121 122 // Move ARGUMENT_* instructions to the top of the entry block, so that their 123 // liveness reflects the fact that these really are live-in values. 124 for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE; ) { 125 MachineInstr *MI = &*MII++; 126 if (IsArgument(MI)) { 127 MI->removeFromParent(); 128 Entry.insert(Entry.begin(), MI); 129 } 130 } 131 132 // Ok, we're now ready to run LiveIntervalAnalysis again. 133 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); 134 135 return Changed; 136 } 137