WebAssemblyPrepareForLiveIntervals.cpp revision 314564
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 "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" 33using namespace llvm; 34 35#define DEBUG_TYPE "wasm-prepare-for-live-intervals" 36 37namespace { 38class WebAssemblyPrepareForLiveIntervals final : public MachineFunctionPass { 39public: 40 static char ID; // Pass identification, replacement for typeid 41 WebAssemblyPrepareForLiveIntervals() : MachineFunctionPass(ID) {} 42 43private: 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 57char WebAssemblyPrepareForLiveIntervals::ID = 0; 58FunctionPass *llvm::createWebAssemblyPrepareForLiveIntervals() { 59 return new WebAssemblyPrepareForLiveIntervals(); 60} 61 62// Test whether the given register has an ARGUMENT def. 63static bool HasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) { 64 for (const auto &Def : MRI.def_instructions(Reg)) 65 if (WebAssembly::isArgument(Def)) 66 return true; 67 return false; 68} 69 70bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(MachineFunction &MF) { 71 DEBUG({ 72 dbgs() << "********** Prepare For LiveIntervals **********\n" 73 << "********** Function: " << MF.getName() << '\n'; 74 }); 75 76 bool Changed = false; 77 MachineRegisterInfo &MRI = MF.getRegInfo(); 78 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 79 MachineBasicBlock &Entry = *MF.begin(); 80 81 assert(!mustPreserveAnalysisID(LiveIntervalsID) && 82 "LiveIntervals shouldn't be active yet!"); 83 84 // We don't preserve SSA form. 85 MRI.leaveSSA(); 86 87 // BranchFolding and perhaps other passes don't preserve IMPLICIT_DEF 88 // instructions. LiveIntervals requires that all paths to virtual register 89 // uses provide a definition. Insert IMPLICIT_DEFs in the entry block to 90 // conservatively satisfy this. 91 // 92 // TODO: This is fairly heavy-handed; find a better approach. 93 // 94 for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { 95 unsigned Reg = TargetRegisterInfo::index2VirtReg(i); 96 97 // Skip unused registers. 98 if (MRI.use_nodbg_empty(Reg)) 99 continue; 100 101 // Skip registers that have an ARGUMENT definition. 102 if (HasArgumentDef(Reg, MRI)) 103 continue; 104 105 BuildMI(Entry, Entry.begin(), DebugLoc(), 106 TII.get(WebAssembly::IMPLICIT_DEF), Reg); 107 Changed = true; 108 } 109 110 // Move ARGUMENT_* instructions to the top of the entry block, so that their 111 // liveness reflects the fact that these really are live-in values. 112 for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE; ) { 113 MachineInstr &MI = *MII++; 114 if (WebAssembly::isArgument(MI)) { 115 MI.removeFromParent(); 116 Entry.insert(Entry.begin(), &MI); 117 } 118 } 119 120 // Ok, we're now ready to run LiveIntervalAnalysis again. 121 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); 122 123 return Changed; 124} 125