1344a3780SDimitry Andric //===-- WebAssemblyMCLowerPrePass.cpp - Prepare for MC lower --------------===// 2344a3780SDimitry Andric // 3344a3780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4344a3780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5344a3780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6344a3780SDimitry Andric // 7344a3780SDimitry Andric //===----------------------------------------------------------------------===// 8344a3780SDimitry Andric /// 9344a3780SDimitry Andric /// \file 10344a3780SDimitry Andric /// Some information in MC lowering / asm printing gets generated as 11344a3780SDimitry Andric /// instructions get emitted, but may be necessary at the start, such as for 12344a3780SDimitry Andric /// .globaltype declarations. This pass collects this information. 13344a3780SDimitry Andric /// 14344a3780SDimitry Andric //===----------------------------------------------------------------------===// 15344a3780SDimitry Andric 16344a3780SDimitry Andric #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 17344a3780SDimitry Andric #include "WebAssembly.h" 18344a3780SDimitry Andric #include "WebAssemblyMachineFunctionInfo.h" 19344a3780SDimitry Andric #include "WebAssemblySubtarget.h" 20b1c73532SDimitry Andric #include "WebAssemblyUtilities.h" 21344a3780SDimitry Andric #include "llvm/ADT/SCCIterator.h" 22344a3780SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 23344a3780SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 24344a3780SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 25344a3780SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h" 26344a3780SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 27344a3780SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 28344a3780SDimitry Andric #include "llvm/CodeGen/Passes.h" 29ac9a064cSDimitry Andric #include "llvm/IR/Module.h" 30344a3780SDimitry Andric #include "llvm/Support/Debug.h" 31344a3780SDimitry Andric #include "llvm/Support/raw_ostream.h" 32344a3780SDimitry Andric using namespace llvm; 33344a3780SDimitry Andric 34344a3780SDimitry Andric #define DEBUG_TYPE "wasm-mclower-prepass" 35344a3780SDimitry Andric 36344a3780SDimitry Andric namespace { 37c0981da4SDimitry Andric class WebAssemblyMCLowerPrePass final : public ModulePass { getPassName() const38344a3780SDimitry Andric StringRef getPassName() const override { 39344a3780SDimitry Andric return "WebAssembly MC Lower Pre Pass"; 40344a3780SDimitry Andric } 41344a3780SDimitry Andric getAnalysisUsage(AnalysisUsage & AU) const42344a3780SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 43344a3780SDimitry Andric AU.setPreservesCFG(); 44c0981da4SDimitry Andric ModulePass::getAnalysisUsage(AU); 45344a3780SDimitry Andric } 46344a3780SDimitry Andric 47c0981da4SDimitry Andric bool runOnModule(Module &M) override; 48344a3780SDimitry Andric 49344a3780SDimitry Andric public: 50344a3780SDimitry Andric static char ID; // Pass identification, replacement for typeid WebAssemblyMCLowerPrePass()51c0981da4SDimitry Andric WebAssemblyMCLowerPrePass() : ModulePass(ID) {} 52344a3780SDimitry Andric }; 53344a3780SDimitry Andric } // end anonymous namespace 54344a3780SDimitry Andric 55344a3780SDimitry Andric char WebAssemblyMCLowerPrePass::ID = 0; 56344a3780SDimitry Andric INITIALIZE_PASS( 57344a3780SDimitry Andric WebAssemblyMCLowerPrePass, DEBUG_TYPE, 58344a3780SDimitry Andric "Collects information ahead of time for MC lowering", 59344a3780SDimitry Andric false, false) 60344a3780SDimitry Andric createWebAssemblyMCLowerPrePass()61c0981da4SDimitry AndricModulePass *llvm::createWebAssemblyMCLowerPrePass() { 62344a3780SDimitry Andric return new WebAssemblyMCLowerPrePass(); 63344a3780SDimitry Andric } 64344a3780SDimitry Andric 65c0981da4SDimitry Andric // NOTE: this is a ModulePass since we need to enforce that this code has run 66c0981da4SDimitry Andric // for all functions before AsmPrinter. If this way of doing things is ever 67c0981da4SDimitry Andric // suboptimal, we could opt to make it a MachineFunctionPass and instead use 68c0981da4SDimitry Andric // something like createBarrierNoopPass() to enforce ordering. 69145449b1SDimitry Andric // 70145449b1SDimitry Andric // The information stored here is essential for emitExternalDecls in the Wasm 71145449b1SDimitry Andric // AsmPrinter runOnModule(Module & M)72c0981da4SDimitry Andricbool WebAssemblyMCLowerPrePass::runOnModule(Module &M) { 73c0981da4SDimitry Andric auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>(); 74c0981da4SDimitry Andric if (!MMIWP) 75c0981da4SDimitry Andric return true; 76344a3780SDimitry Andric 77c0981da4SDimitry Andric MachineModuleInfo &MMI = MMIWP->getMMI(); 78344a3780SDimitry Andric MachineModuleInfoWasm &MMIW = MMI.getObjFileInfo<MachineModuleInfoWasm>(); 79344a3780SDimitry Andric 80c0981da4SDimitry Andric for (Function &F : M) { 81c0981da4SDimitry Andric MachineFunction *MF = MMI.getMachineFunction(F); 82c0981da4SDimitry Andric if (!MF) 83c0981da4SDimitry Andric continue; 84c0981da4SDimitry Andric 85c0981da4SDimitry Andric LLVM_DEBUG(dbgs() << "********** MC Lower Pre Pass **********\n" 86c0981da4SDimitry Andric "********** Function: " 87c0981da4SDimitry Andric << MF->getName() << '\n'); 88c0981da4SDimitry Andric 89c0981da4SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 90344a3780SDimitry Andric for (auto &MI : MBB) { 91344a3780SDimitry Andric // FIXME: what should all be filtered out beyond these? 92344a3780SDimitry Andric if (MI.isDebugInstr() || MI.isInlineAsm()) 93344a3780SDimitry Andric continue; 94344a3780SDimitry Andric for (MachineOperand &MO : MI.uses()) { 95344a3780SDimitry Andric if (MO.isSymbol()) { 96344a3780SDimitry Andric MMIW.MachineSymbolsUsed.insert(MO.getSymbolName()); 97344a3780SDimitry Andric } 98344a3780SDimitry Andric } 99344a3780SDimitry Andric } 100344a3780SDimitry Andric } 101c0981da4SDimitry Andric } 102344a3780SDimitry Andric return true; 103344a3780SDimitry Andric } 104