Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 1 | //===--- WebAssemblyOptimizeLiveIntervals.cpp - LiveInterval processing ---===// |
| 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 Optimize LiveIntervals for use in a post-RA context. |
| 12 | // |
| 13 | /// LiveIntervals normally runs before register allocation when the code is |
| 14 | /// only recently lowered out of SSA form, so it's uncommon for registers to |
| 15 | /// have multiple defs, and then they do, the defs are usually closely related. |
| 16 | /// Later, after coalescing, tail duplication, and other optimizations, it's |
| 17 | /// more common to see registers with multiple unrelated defs. This pass |
| 18 | /// updates LiveIntervalAnalysis to distribute the value numbers across separate |
| 19 | /// LiveIntervals. |
| 20 | /// |
| 21 | //===----------------------------------------------------------------------===// |
| 22 | |
| 23 | #include "WebAssembly.h" |
| 24 | #include "WebAssemblySubtarget.h" |
| 25 | #include "llvm/CodeGen/LiveIntervalAnalysis.h" |
| 26 | #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" |
| 27 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 28 | #include "llvm/CodeGen/Passes.h" |
| 29 | #include "llvm/Support/Debug.h" |
| 30 | #include "llvm/Support/raw_ostream.h" |
| 31 | using namespace llvm; |
| 32 | |
| 33 | #define DEBUG_TYPE "wasm-optimize-live-intervals" |
| 34 | |
| 35 | namespace { |
| 36 | class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass { |
Mehdi Amini | 117296c | 2016-10-01 02:56:57 +0000 | [diff] [blame] | 37 | StringRef getPassName() const override { |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 38 | return "WebAssembly Optimize Live Intervals"; |
| 39 | } |
| 40 | |
| 41 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
| 42 | AU.setPreservesCFG(); |
| 43 | AU.addRequired<LiveIntervals>(); |
| 44 | AU.addPreserved<MachineBlockFrequencyInfo>(); |
| 45 | AU.addPreserved<SlotIndexes>(); |
| 46 | AU.addPreserved<LiveIntervals>(); |
| 47 | AU.addPreservedID(LiveVariablesID); |
| 48 | AU.addPreservedID(MachineDominatorsID); |
| 49 | MachineFunctionPass::getAnalysisUsage(AU); |
| 50 | } |
| 51 | |
| 52 | bool runOnMachineFunction(MachineFunction &MF) override; |
| 53 | |
| 54 | public: |
| 55 | static char ID; // Pass identification, replacement for typeid |
| 56 | WebAssemblyOptimizeLiveIntervals() : MachineFunctionPass(ID) {} |
| 57 | }; |
| 58 | } // end anonymous namespace |
| 59 | |
| 60 | char WebAssemblyOptimizeLiveIntervals::ID = 0; |
| 61 | FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() { |
| 62 | return new WebAssemblyOptimizeLiveIntervals(); |
| 63 | } |
| 64 | |
| 65 | bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF) { |
| 66 | DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n" |
| 67 | "********** Function: " |
| 68 | << MF.getName() << '\n'); |
| 69 | |
| 70 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 71 | LiveIntervals &LIS = getAnalysis<LiveIntervals>(); |
| 72 | |
| 73 | // We don't preserve SSA form. |
| 74 | MRI.leaveSSA(); |
| 75 | |
| 76 | assert(MRI.tracksLiveness() && |
| 77 | "OptimizeLiveIntervals expects liveness"); |
| 78 | |
| 79 | // Split multiple-VN LiveIntervals into multiple LiveIntervals. |
| 80 | SmallVector<LiveInterval*, 4> SplitLIs; |
| 81 | for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { |
| 82 | unsigned Reg = TargetRegisterInfo::index2VirtReg(i); |
| 83 | if (MRI.reg_nodbg_empty(Reg)) |
| 84 | continue; |
| 85 | |
| 86 | LIS.splitSeparateComponents(LIS.getInterval(Reg), SplitLIs); |
| 87 | SplitLIs.clear(); |
| 88 | } |
| 89 | |
| 90 | // In PrepareForLiveIntervals, we conservatively inserted IMPLICIT_DEF |
| 91 | // instructions to satisfy LiveIntervals' requirement that all uses be |
| 92 | // dominated by defs. Now that LiveIntervals has computed which of these |
| 93 | // defs are actually needed and which are dead, remove the dead ones. |
| 94 | for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE; ) { |
| 95 | MachineInstr *MI = &*MII++; |
| 96 | if (MI->isImplicitDef() && MI->getOperand(0).isDead()) { |
| 97 | LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg()); |
| 98 | LIS.removeVRegDefAt(LI, LIS.getInstructionIndex(*MI).getRegSlot()); |
| 99 | LIS.RemoveMachineInstrFromMaps(*MI); |
| 100 | MI->eraseFromParent(); |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | return false; |
| 105 | } |