10cfb5f85SDan Gohman //===--- WebAssemblyOptimizeLiveIntervals.cpp - LiveInterval processing ---===//
20cfb5f85SDan Gohman //
30cfb5f85SDan Gohman //                     The LLVM Compiler Infrastructure
40cfb5f85SDan Gohman //
50cfb5f85SDan Gohman // This file is distributed under the University of Illinois Open Source
60cfb5f85SDan Gohman // License. See LICENSE.TXT for details.
70cfb5f85SDan Gohman //
80cfb5f85SDan Gohman //===----------------------------------------------------------------------===//
90cfb5f85SDan Gohman ///
100cfb5f85SDan Gohman /// \file
115f8f34e4SAdrian Prantl /// Optimize LiveIntervals for use in a post-RA context.
120cfb5f85SDan Gohman //
130cfb5f85SDan Gohman /// LiveIntervals normally runs before register allocation when the code is
140cfb5f85SDan Gohman /// only recently lowered out of SSA form, so it's uncommon for registers to
15*fd2f7aebSDan Gohman /// have multiple defs, and when they do, the defs are usually closely related.
160cfb5f85SDan Gohman /// Later, after coalescing, tail duplication, and other optimizations, it's
170cfb5f85SDan Gohman /// more common to see registers with multiple unrelated defs. This pass
18f842297dSMatthias Braun /// updates LiveIntervals to distribute the value numbers across separate
190cfb5f85SDan Gohman /// LiveIntervals.
200cfb5f85SDan Gohman ///
210cfb5f85SDan Gohman //===----------------------------------------------------------------------===//
220cfb5f85SDan Gohman 
230cfb5f85SDan Gohman #include "WebAssembly.h"
240cfb5f85SDan Gohman #include "WebAssemblySubtarget.h"
25f842297dSMatthias Braun #include "llvm/CodeGen/LiveIntervals.h"
260cfb5f85SDan Gohman #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
270cfb5f85SDan Gohman #include "llvm/CodeGen/MachineRegisterInfo.h"
280cfb5f85SDan Gohman #include "llvm/CodeGen/Passes.h"
290cfb5f85SDan Gohman #include "llvm/Support/Debug.h"
300cfb5f85SDan Gohman #include "llvm/Support/raw_ostream.h"
310cfb5f85SDan Gohman using namespace llvm;
320cfb5f85SDan Gohman 
330cfb5f85SDan Gohman #define DEBUG_TYPE "wasm-optimize-live-intervals"
340cfb5f85SDan Gohman 
350cfb5f85SDan Gohman namespace {
360cfb5f85SDan Gohman class WebAssemblyOptimizeLiveIntervals final : public MachineFunctionPass {
37117296c0SMehdi Amini   StringRef getPassName() const override {
380cfb5f85SDan Gohman     return "WebAssembly Optimize Live Intervals";
390cfb5f85SDan Gohman   }
400cfb5f85SDan Gohman 
410cfb5f85SDan Gohman   void getAnalysisUsage(AnalysisUsage &AU) const override {
420cfb5f85SDan Gohman     AU.setPreservesCFG();
430cfb5f85SDan Gohman     AU.addRequired<LiveIntervals>();
440cfb5f85SDan Gohman     AU.addPreserved<MachineBlockFrequencyInfo>();
450cfb5f85SDan Gohman     AU.addPreserved<SlotIndexes>();
460cfb5f85SDan Gohman     AU.addPreserved<LiveIntervals>();
470cfb5f85SDan Gohman     AU.addPreservedID(LiveVariablesID);
480cfb5f85SDan Gohman     AU.addPreservedID(MachineDominatorsID);
490cfb5f85SDan Gohman     MachineFunctionPass::getAnalysisUsage(AU);
500cfb5f85SDan Gohman   }
510cfb5f85SDan Gohman 
520cfb5f85SDan Gohman   bool runOnMachineFunction(MachineFunction &MF) override;
530cfb5f85SDan Gohman 
540cfb5f85SDan Gohman public:
550cfb5f85SDan Gohman   static char ID; // Pass identification, replacement for typeid
560cfb5f85SDan Gohman   WebAssemblyOptimizeLiveIntervals() : MachineFunctionPass(ID) {}
570cfb5f85SDan Gohman };
580cfb5f85SDan Gohman } // end anonymous namespace
590cfb5f85SDan Gohman 
600cfb5f85SDan Gohman char WebAssemblyOptimizeLiveIntervals::ID = 0;
6140926451SJacob Gravelle INITIALIZE_PASS(WebAssemblyOptimizeLiveIntervals, DEBUG_TYPE,
6240926451SJacob Gravelle                 "Optimize LiveIntervals for WebAssembly", false, false)
6340926451SJacob Gravelle 
640cfb5f85SDan Gohman FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() {
650cfb5f85SDan Gohman   return new WebAssemblyOptimizeLiveIntervals();
660cfb5f85SDan Gohman }
670cfb5f85SDan Gohman 
680cfb5f85SDan Gohman bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
69d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n"
700cfb5f85SDan Gohman                        "********** Function: "
710cfb5f85SDan Gohman                     << MF.getName() << '\n');
720cfb5f85SDan Gohman 
730cfb5f85SDan Gohman   MachineRegisterInfo &MRI = MF.getRegInfo();
740cfb5f85SDan Gohman   LiveIntervals &LIS = getAnalysis<LiveIntervals>();
750cfb5f85SDan Gohman 
760cfb5f85SDan Gohman   // We don't preserve SSA form.
770cfb5f85SDan Gohman   MRI.leaveSSA();
780cfb5f85SDan Gohman 
790cfb5f85SDan Gohman   assert(MRI.tracksLiveness() &&
800cfb5f85SDan Gohman          "OptimizeLiveIntervals expects liveness");
810cfb5f85SDan Gohman 
820cfb5f85SDan Gohman   // Split multiple-VN LiveIntervals into multiple LiveIntervals.
830cfb5f85SDan Gohman   SmallVector<LiveInterval*, 4> SplitLIs;
840cfb5f85SDan Gohman   for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) {
850cfb5f85SDan Gohman     unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
860cfb5f85SDan Gohman     if (MRI.reg_nodbg_empty(Reg))
870cfb5f85SDan Gohman       continue;
880cfb5f85SDan Gohman 
890cfb5f85SDan Gohman     LIS.splitSeparateComponents(LIS.getInterval(Reg), SplitLIs);
900cfb5f85SDan Gohman     SplitLIs.clear();
910cfb5f85SDan Gohman   }
920cfb5f85SDan Gohman 
930cfb5f85SDan Gohman   // In PrepareForLiveIntervals, we conservatively inserted IMPLICIT_DEF
940cfb5f85SDan Gohman   // instructions to satisfy LiveIntervals' requirement that all uses be
950cfb5f85SDan Gohman   // dominated by defs. Now that LiveIntervals has computed which of these
960cfb5f85SDan Gohman   // defs are actually needed and which are dead, remove the dead ones.
970cfb5f85SDan Gohman   for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE; ) {
980cfb5f85SDan Gohman     MachineInstr *MI = &*MII++;
990cfb5f85SDan Gohman     if (MI->isImplicitDef() && MI->getOperand(0).isDead()) {
1000cfb5f85SDan Gohman       LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg());
1010cfb5f85SDan Gohman       LIS.removeVRegDefAt(LI, LIS.getInstructionIndex(*MI).getRegSlot());
1020cfb5f85SDan Gohman       LIS.RemoveMachineInstrFromMaps(*MI);
1030cfb5f85SDan Gohman       MI->eraseFromParent();
1040cfb5f85SDan Gohman     }
1050cfb5f85SDan Gohman   }
1060cfb5f85SDan Gohman 
1070cfb5f85SDan Gohman   return false;
1080cfb5f85SDan Gohman }
109