xref: /freebsd/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMCLowerPrePass.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric //===-- WebAssemblyMCLowerPrePass.cpp - Prepare for MC lower --------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric ///
9fe6060f1SDimitry Andric /// \file
10fe6060f1SDimitry Andric /// Some information in MC lowering / asm printing gets generated as
11fe6060f1SDimitry Andric /// instructions get emitted, but may be necessary at the start, such as for
12fe6060f1SDimitry Andric /// .globaltype declarations. This pass collects this information.
13fe6060f1SDimitry Andric ///
14fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
15fe6060f1SDimitry Andric 
16fe6060f1SDimitry Andric #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
17fe6060f1SDimitry Andric #include "WebAssembly.h"
18fe6060f1SDimitry Andric #include "WebAssemblyMachineFunctionInfo.h"
19fe6060f1SDimitry Andric #include "WebAssemblySubtarget.h"
205f757f3fSDimitry Andric #include "WebAssemblyUtilities.h"
21fe6060f1SDimitry Andric #include "llvm/ADT/SCCIterator.h"
22fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
23fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
24fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
25fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
26fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h"
27fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
28fe6060f1SDimitry Andric #include "llvm/CodeGen/Passes.h"
29*0fca6ea1SDimitry Andric #include "llvm/IR/Module.h"
30fe6060f1SDimitry Andric #include "llvm/Support/Debug.h"
31fe6060f1SDimitry Andric #include "llvm/Support/raw_ostream.h"
32fe6060f1SDimitry Andric using namespace llvm;
33fe6060f1SDimitry Andric 
34fe6060f1SDimitry Andric #define DEBUG_TYPE "wasm-mclower-prepass"
35fe6060f1SDimitry Andric 
36fe6060f1SDimitry Andric namespace {
37349cc55cSDimitry Andric class WebAssemblyMCLowerPrePass final : public ModulePass {
getPassName() const38fe6060f1SDimitry Andric   StringRef getPassName() const override {
39fe6060f1SDimitry Andric     return "WebAssembly MC Lower Pre Pass";
40fe6060f1SDimitry Andric   }
41fe6060f1SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const42fe6060f1SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
43fe6060f1SDimitry Andric     AU.setPreservesCFG();
44349cc55cSDimitry Andric     ModulePass::getAnalysisUsage(AU);
45fe6060f1SDimitry Andric   }
46fe6060f1SDimitry Andric 
47349cc55cSDimitry Andric   bool runOnModule(Module &M) override;
48fe6060f1SDimitry Andric 
49fe6060f1SDimitry Andric public:
50fe6060f1SDimitry Andric   static char ID; // Pass identification, replacement for typeid
WebAssemblyMCLowerPrePass()51349cc55cSDimitry Andric   WebAssemblyMCLowerPrePass() : ModulePass(ID) {}
52fe6060f1SDimitry Andric };
53fe6060f1SDimitry Andric } // end anonymous namespace
54fe6060f1SDimitry Andric 
55fe6060f1SDimitry Andric char WebAssemblyMCLowerPrePass::ID = 0;
56fe6060f1SDimitry Andric INITIALIZE_PASS(
57fe6060f1SDimitry Andric     WebAssemblyMCLowerPrePass, DEBUG_TYPE,
58fe6060f1SDimitry Andric     "Collects information ahead of time for MC lowering",
59fe6060f1SDimitry Andric     false, false)
60fe6060f1SDimitry Andric 
createWebAssemblyMCLowerPrePass()61349cc55cSDimitry Andric ModulePass *llvm::createWebAssemblyMCLowerPrePass() {
62fe6060f1SDimitry Andric   return new WebAssemblyMCLowerPrePass();
63fe6060f1SDimitry Andric }
64fe6060f1SDimitry Andric 
65349cc55cSDimitry Andric // NOTE: this is a ModulePass since we need to enforce that this code has run
66349cc55cSDimitry Andric // for all functions before AsmPrinter. If this way of doing things is ever
67349cc55cSDimitry Andric // suboptimal, we could opt to make it a MachineFunctionPass and instead use
68349cc55cSDimitry Andric // something like createBarrierNoopPass() to enforce ordering.
6981ad6265SDimitry Andric //
7081ad6265SDimitry Andric // The information stored here is essential for emitExternalDecls in the Wasm
7181ad6265SDimitry Andric // AsmPrinter
runOnModule(Module & M)72349cc55cSDimitry Andric bool WebAssemblyMCLowerPrePass::runOnModule(Module &M) {
73349cc55cSDimitry Andric   auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
74349cc55cSDimitry Andric   if (!MMIWP)
75349cc55cSDimitry Andric     return true;
76fe6060f1SDimitry Andric 
77349cc55cSDimitry Andric   MachineModuleInfo &MMI = MMIWP->getMMI();
78fe6060f1SDimitry Andric   MachineModuleInfoWasm &MMIW = MMI.getObjFileInfo<MachineModuleInfoWasm>();
79fe6060f1SDimitry Andric 
80349cc55cSDimitry Andric   for (Function &F : M) {
81349cc55cSDimitry Andric     MachineFunction *MF = MMI.getMachineFunction(F);
82349cc55cSDimitry Andric     if (!MF)
83349cc55cSDimitry Andric       continue;
84349cc55cSDimitry Andric 
85349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "********** MC Lower Pre Pass **********\n"
86349cc55cSDimitry Andric                          "********** Function: "
87349cc55cSDimitry Andric                       << MF->getName() << '\n');
88349cc55cSDimitry Andric 
89349cc55cSDimitry Andric     for (MachineBasicBlock &MBB : *MF) {
90fe6060f1SDimitry Andric       for (auto &MI : MBB) {
91fe6060f1SDimitry Andric         // FIXME: what should all be filtered out beyond these?
92fe6060f1SDimitry Andric         if (MI.isDebugInstr() || MI.isInlineAsm())
93fe6060f1SDimitry Andric           continue;
94fe6060f1SDimitry Andric         for (MachineOperand &MO : MI.uses()) {
95fe6060f1SDimitry Andric           if (MO.isSymbol()) {
96fe6060f1SDimitry Andric             MMIW.MachineSymbolsUsed.insert(MO.getSymbolName());
97fe6060f1SDimitry Andric           }
98fe6060f1SDimitry Andric         }
99fe6060f1SDimitry Andric       }
100fe6060f1SDimitry Andric     }
101349cc55cSDimitry Andric   }
102fe6060f1SDimitry Andric   return true;
103fe6060f1SDimitry Andric }
104