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 AndricModulePass *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 Andricbool 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