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 |
Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 11 | /// Optimize LiveIntervals for use in a post-RA context. |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 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 |
Dan Gohman | fd2f7ae | 2018-06-26 03:03:41 +0000 | [diff] [blame^] | 15 | /// have multiple defs, and when they do, the defs are usually closely related. |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 16 | /// Later, after coalescing, tail duplication, and other optimizations, it's |
| 17 | /// more common to see registers with multiple unrelated defs. This pass |
Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 18 | /// updates LiveIntervals to distribute the value numbers across separate |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 19 | /// LiveIntervals. |
| 20 | /// |
| 21 | //===----------------------------------------------------------------------===// |
| 22 | |
| 23 | #include "WebAssembly.h" |
| 24 | #include "WebAssemblySubtarget.h" |
Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 25 | #include "llvm/CodeGen/LiveIntervals.h" |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 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; |
Jacob Gravelle | 4092645 | 2018-03-30 20:36:58 +0000 | [diff] [blame] | 61 | INITIALIZE_PASS(WebAssemblyOptimizeLiveIntervals, DEBUG_TYPE, |
| 62 | "Optimize LiveIntervals for WebAssembly", false, false) |
| 63 | |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 64 | FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() { |
| 65 | return new WebAssemblyOptimizeLiveIntervals(); |
| 66 | } |
| 67 | |
| 68 | bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF) { |
Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 69 | LLVM_DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n" |
| 70 | "********** Function: " |
| 71 | << MF.getName() << '\n'); |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 72 | |
| 73 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
| 74 | LiveIntervals &LIS = getAnalysis<LiveIntervals>(); |
| 75 | |
| 76 | // We don't preserve SSA form. |
| 77 | MRI.leaveSSA(); |
| 78 | |
| 79 | assert(MRI.tracksLiveness() && |
| 80 | "OptimizeLiveIntervals expects liveness"); |
| 81 | |
| 82 | // Split multiple-VN LiveIntervals into multiple LiveIntervals. |
| 83 | SmallVector<LiveInterval*, 4> SplitLIs; |
| 84 | for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { |
| 85 | unsigned Reg = TargetRegisterInfo::index2VirtReg(i); |
| 86 | if (MRI.reg_nodbg_empty(Reg)) |
| 87 | continue; |
| 88 | |
| 89 | LIS.splitSeparateComponents(LIS.getInterval(Reg), SplitLIs); |
| 90 | SplitLIs.clear(); |
| 91 | } |
| 92 | |
| 93 | // In PrepareForLiveIntervals, we conservatively inserted IMPLICIT_DEF |
| 94 | // instructions to satisfy LiveIntervals' requirement that all uses be |
| 95 | // dominated by defs. Now that LiveIntervals has computed which of these |
| 96 | // defs are actually needed and which are dead, remove the dead ones. |
| 97 | for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE; ) { |
| 98 | MachineInstr *MI = &*MII++; |
| 99 | if (MI->isImplicitDef() && MI->getOperand(0).isDead()) { |
| 100 | LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg()); |
| 101 | LIS.removeVRegDefAt(LI, LIS.getInstructionIndex(*MI).getRegSlot()); |
| 102 | LIS.RemoveMachineInstrFromMaps(*MI); |
| 103 | MI->eraseFromParent(); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | return false; |
| 108 | } |