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" 20*5f757f3fSDimitry 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" 29fe6060f1SDimitry Andric #include "llvm/Support/Debug.h" 30fe6060f1SDimitry Andric #include "llvm/Support/raw_ostream.h" 31fe6060f1SDimitry Andric using namespace llvm; 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric #define DEBUG_TYPE "wasm-mclower-prepass" 34fe6060f1SDimitry Andric 35fe6060f1SDimitry Andric namespace { 36349cc55cSDimitry Andric class WebAssemblyMCLowerPrePass final : public ModulePass { 37fe6060f1SDimitry Andric StringRef getPassName() const override { 38fe6060f1SDimitry Andric return "WebAssembly MC Lower Pre Pass"; 39fe6060f1SDimitry Andric } 40fe6060f1SDimitry Andric 41fe6060f1SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 42fe6060f1SDimitry Andric AU.setPreservesCFG(); 43349cc55cSDimitry Andric ModulePass::getAnalysisUsage(AU); 44fe6060f1SDimitry Andric } 45fe6060f1SDimitry Andric 46349cc55cSDimitry Andric bool runOnModule(Module &M) override; 47fe6060f1SDimitry Andric 48fe6060f1SDimitry Andric public: 49fe6060f1SDimitry Andric static char ID; // Pass identification, replacement for typeid 50349cc55cSDimitry Andric WebAssemblyMCLowerPrePass() : ModulePass(ID) {} 51fe6060f1SDimitry Andric }; 52fe6060f1SDimitry Andric } // end anonymous namespace 53fe6060f1SDimitry Andric 54fe6060f1SDimitry Andric char WebAssemblyMCLowerPrePass::ID = 0; 55fe6060f1SDimitry Andric INITIALIZE_PASS( 56fe6060f1SDimitry Andric WebAssemblyMCLowerPrePass, DEBUG_TYPE, 57fe6060f1SDimitry Andric "Collects information ahead of time for MC lowering", 58fe6060f1SDimitry Andric false, false) 59fe6060f1SDimitry Andric 60349cc55cSDimitry Andric ModulePass *llvm::createWebAssemblyMCLowerPrePass() { 61fe6060f1SDimitry Andric return new WebAssemblyMCLowerPrePass(); 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric 64349cc55cSDimitry Andric // NOTE: this is a ModulePass since we need to enforce that this code has run 65349cc55cSDimitry Andric // for all functions before AsmPrinter. If this way of doing things is ever 66349cc55cSDimitry Andric // suboptimal, we could opt to make it a MachineFunctionPass and instead use 67349cc55cSDimitry Andric // something like createBarrierNoopPass() to enforce ordering. 6881ad6265SDimitry Andric // 6981ad6265SDimitry Andric // The information stored here is essential for emitExternalDecls in the Wasm 7081ad6265SDimitry Andric // AsmPrinter 71349cc55cSDimitry Andric bool WebAssemblyMCLowerPrePass::runOnModule(Module &M) { 72349cc55cSDimitry Andric auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>(); 73349cc55cSDimitry Andric if (!MMIWP) 74349cc55cSDimitry Andric return true; 75fe6060f1SDimitry Andric 76349cc55cSDimitry Andric MachineModuleInfo &MMI = MMIWP->getMMI(); 77fe6060f1SDimitry Andric MachineModuleInfoWasm &MMIW = MMI.getObjFileInfo<MachineModuleInfoWasm>(); 78fe6060f1SDimitry Andric 79349cc55cSDimitry Andric for (Function &F : M) { 80349cc55cSDimitry Andric MachineFunction *MF = MMI.getMachineFunction(F); 81349cc55cSDimitry Andric if (!MF) 82349cc55cSDimitry Andric continue; 83349cc55cSDimitry Andric 84349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "********** MC Lower Pre Pass **********\n" 85349cc55cSDimitry Andric "********** Function: " 86349cc55cSDimitry Andric << MF->getName() << '\n'); 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric for (MachineBasicBlock &MBB : *MF) { 89fe6060f1SDimitry Andric for (auto &MI : MBB) { 90fe6060f1SDimitry Andric // FIXME: what should all be filtered out beyond these? 91fe6060f1SDimitry Andric if (MI.isDebugInstr() || MI.isInlineAsm()) 92fe6060f1SDimitry Andric continue; 93fe6060f1SDimitry Andric for (MachineOperand &MO : MI.uses()) { 94fe6060f1SDimitry Andric if (MO.isSymbol()) { 95fe6060f1SDimitry Andric MMIW.MachineSymbolsUsed.insert(MO.getSymbolName()); 96fe6060f1SDimitry Andric } 97fe6060f1SDimitry Andric } 98fe6060f1SDimitry Andric } 99fe6060f1SDimitry Andric } 100349cc55cSDimitry Andric } 101fe6060f1SDimitry Andric return true; 102fe6060f1SDimitry Andric } 103