Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 1 | //===--- WebAssemblyOptimizeLiveIntervals.cpp - LiveInterval processing ---===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame^] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | /// |
| 9 | /// \file |
Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 10 | /// Optimize LiveIntervals for use in a post-RA context. |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 11 | // |
| 12 | /// LiveIntervals normally runs before register allocation when the code is |
| 13 | /// 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] | 14 | /// 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] | 15 | /// Later, after coalescing, tail duplication, and other optimizations, it's |
| 16 | /// more common to see registers with multiple unrelated defs. This pass |
Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 17 | /// updates LiveIntervals to distribute the value numbers across separate |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 18 | /// LiveIntervals. |
| 19 | /// |
| 20 | //===----------------------------------------------------------------------===// |
| 21 | |
| 22 | #include "WebAssembly.h" |
| 23 | #include "WebAssemblySubtarget.h" |
Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/LiveIntervals.h" |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 25 | #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" |
| 26 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
| 27 | #include "llvm/CodeGen/Passes.h" |
| 28 | #include "llvm/Support/Debug.h" |
| 29 | #include "llvm/Support/raw_ostream.h" |
| 30 | using namespace llvm; |
| 31 | |
| 32 | #define DEBUG_TYPE "wasm-optimize-live-intervals" |
| 33 | |
| 34 | namespace { |
| 35 | class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass { |
Mehdi Amini | 117296c | 2016-10-01 02:56:57 +0000 | [diff] [blame] | 36 | StringRef getPassName() const override { |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 37 | return "WebAssembly Optimize Live Intervals"; |
| 38 | } |
| 39 | |
| 40 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
| 41 | AU.setPreservesCFG(); |
| 42 | AU.addRequired<LiveIntervals>(); |
| 43 | AU.addPreserved<MachineBlockFrequencyInfo>(); |
| 44 | AU.addPreserved<SlotIndexes>(); |
| 45 | AU.addPreserved<LiveIntervals>(); |
| 46 | AU.addPreservedID(LiveVariablesID); |
| 47 | AU.addPreservedID(MachineDominatorsID); |
| 48 | MachineFunctionPass::getAnalysisUsage(AU); |
| 49 | } |
| 50 | |
| 51 | bool runOnMachineFunction(MachineFunction &MF) override; |
| 52 | |
| 53 | public: |
| 54 | static char ID; // Pass identification, replacement for typeid |
| 55 | WebAssemblyOptimizeLiveIntervals() : MachineFunctionPass(ID) {} |
| 56 | }; |
| 57 | } // end anonymous namespace |
| 58 | |
| 59 | char WebAssemblyOptimizeLiveIntervals::ID = 0; |
Jacob Gravelle | 4092645 | 2018-03-30 20:36:58 +0000 | [diff] [blame] | 60 | INITIALIZE_PASS(WebAssemblyOptimizeLiveIntervals, DEBUG_TYPE, |
| 61 | "Optimize LiveIntervals for WebAssembly", false, false) |
| 62 | |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 63 | FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() { |
| 64 | return new WebAssemblyOptimizeLiveIntervals(); |
| 65 | } |
| 66 | |
Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 67 | bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction( |
| 68 | 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 | |
Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 79 | assert(MRI.tracksLiveness() && "OptimizeLiveIntervals expects liveness"); |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 80 | |
| 81 | // Split multiple-VN LiveIntervals into multiple LiveIntervals. |
Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 82 | SmallVector<LiveInterval *, 4> SplitLIs; |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 83 | for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) { |
| 84 | unsigned Reg = TargetRegisterInfo::index2VirtReg(i); |
| 85 | if (MRI.reg_nodbg_empty(Reg)) |
| 86 | continue; |
| 87 | |
| 88 | LIS.splitSeparateComponents(LIS.getInterval(Reg), SplitLIs); |
| 89 | SplitLIs.clear(); |
| 90 | } |
| 91 | |
| 92 | // In PrepareForLiveIntervals, we conservatively inserted IMPLICIT_DEF |
| 93 | // instructions to satisfy LiveIntervals' requirement that all uses be |
| 94 | // dominated by defs. Now that LiveIntervals has computed which of these |
| 95 | // defs are actually needed and which are dead, remove the dead ones. |
Heejin Ahn | f208f63 | 2018-09-05 01:27:38 +0000 | [diff] [blame] | 96 | for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE;) { |
Dan Gohman | 0cfb5f8 | 2016-05-10 04:24:02 +0000 | [diff] [blame] | 97 | MachineInstr *MI = &*MII++; |
| 98 | if (MI->isImplicitDef() && MI->getOperand(0).isDead()) { |
| 99 | LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg()); |
| 100 | LIS.removeVRegDefAt(LI, LIS.getInstructionIndex(*MI).getRegSlot()); |
| 101 | LIS.RemoveMachineInstrFromMaps(*MI); |
| 102 | MI->eraseFromParent(); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | return false; |
| 107 | } |