LLVM  10.0.0svn
WebAssemblyPrepareForLiveIntervals.cpp
Go to the documentation of this file.
1 //===- WebAssemblyPrepareForLiveIntervals.cpp - Prepare for LiveIntervals -===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Fix up code to meet LiveInterval's requirements.
11 ///
12 /// Some CodeGen passes don't preserve LiveInterval's requirements, because
13 /// they run after register allocation and it isn't important. However,
14 /// WebAssembly runs LiveIntervals in a late pass. This pass transforms code
15 /// to meet LiveIntervals' requirements; primarily, it ensures that all
16 /// virtual register uses have definitions (IMPLICIT_DEF definitions if
17 /// nothing else).
18 ///
19 //===----------------------------------------------------------------------===//
20 
22 #include "WebAssembly.h"
24 #include "WebAssemblySubtarget.h"
25 #include "WebAssemblyUtilities.h"
29 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/Support/Debug.h"
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "wasm-prepare-for-live-intervals"
35 
36 namespace {
37 class WebAssemblyPrepareForLiveIntervals final : public MachineFunctionPass {
38 public:
39  static char ID; // Pass identification, replacement for typeid
40  WebAssemblyPrepareForLiveIntervals() : MachineFunctionPass(ID) {}
41 
42 private:
43  StringRef getPassName() const override {
44  return "WebAssembly Prepare For LiveIntervals";
45  }
46 
47  void getAnalysisUsage(AnalysisUsage &AU) const override {
48  AU.setPreservesCFG();
50  }
51 
52  bool runOnMachineFunction(MachineFunction &MF) override;
53 };
54 } // end anonymous namespace
55 
57 INITIALIZE_PASS(WebAssemblyPrepareForLiveIntervals, DEBUG_TYPE,
58  "Fix up code for LiveIntervals", false, false)
59 
61  return new WebAssemblyPrepareForLiveIntervals();
62 }
63 
64 // Test whether the given register has an ARGUMENT def.
65 static bool hasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) {
66  for (const auto &Def : MRI.def_instructions(Reg))
67  if (WebAssembly::isArgument(Def.getOpcode()))
68  return true;
69  return false;
70 }
71 
72 bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(
73  MachineFunction &MF) {
74  LLVM_DEBUG({
75  dbgs() << "********** Prepare For LiveIntervals **********\n"
76  << "********** Function: " << MF.getName() << '\n';
77  });
78 
79  bool Changed = false;
81  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
82  MachineBasicBlock &Entry = *MF.begin();
83 
84  assert(!mustPreserveAnalysisID(LiveIntervalsID) &&
85  "LiveIntervals shouldn't be active yet!");
86 
87  // We don't preserve SSA form.
88  MRI.leaveSSA();
89 
90  // BranchFolding and perhaps other passes don't preserve IMPLICIT_DEF
91  // instructions. LiveIntervals requires that all paths to virtual register
92  // uses provide a definition. Insert IMPLICIT_DEFs in the entry block to
93  // conservatively satisfy this.
94  //
95  // TODO: This is fairly heavy-handed; find a better approach.
96  //
97  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
98  unsigned Reg = Register::index2VirtReg(I);
99 
100  // Skip unused registers.
101  if (MRI.use_nodbg_empty(Reg))
102  continue;
103 
104  // Skip registers that have an ARGUMENT definition.
105  if (hasArgumentDef(Reg, MRI))
106  continue;
107 
108  BuildMI(Entry, Entry.begin(), DebugLoc(),
109  TII.get(WebAssembly::IMPLICIT_DEF), Reg);
110  Changed = true;
111  }
112 
113  // Move ARGUMENT_* instructions to the top of the entry block, so that their
114  // liveness reflects the fact that these really are live-in values.
115  for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE;) {
116  MachineInstr &MI = *MII++;
118  MI.removeFromParent();
119  Entry.insert(Entry.begin(), &MI);
120  }
121  }
122 
123  // Ok, we're now ready to run the LiveIntervals analysis again.
125 
126  return Changed;
127 }
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
bool isArgument(unsigned Opc)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const MachineFunctionProperties & getProperties() const
Get the function properties.
unsigned Reg
A debug info location.
Definition: DebugLoc.h:33
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:83
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
char & LiveIntervalsID
LiveIntervals - This analysis keeps track of the live ranges of virtual and physical registers...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
This file contains the declaration of the WebAssembly-specific utility functions. ...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides WebAssembly-specific target descriptions.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
INITIALIZE_PASS(WebAssemblyPrepareForLiveIntervals, DEBUG_TYPE, "Fix up code for LiveIntervals", false, false) FunctionPass *llvm
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:301
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static bool hasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
Definition: MachineInstr.h:64
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares WebAssembly-specific per-machine-function information.
MachineInstr * removeFromParent()
Unlink &#39;this&#39; from the containing basic block, and return it without deleting it. ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator_range< def_instr_iterator > def_instructions(unsigned Reg) const
FunctionPass * createWebAssemblyPrepareForLiveIntervals()
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
#define LLVM_DEBUG(X)
Definition: Debug.h:122