1bb372243SDan Gohman //=- WebAssemblySetP2AlignOperands.cpp - Set alignments on loads and stores -=// 2bb372243SDan Gohman // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bb372243SDan Gohman // 7bb372243SDan Gohman //===----------------------------------------------------------------------===// 8bb372243SDan Gohman /// 9bb372243SDan Gohman /// \file 105f8f34e4SAdrian Prantl /// This file sets the p2align operands on load and store instructions. 11bb372243SDan Gohman /// 12bb372243SDan Gohman //===----------------------------------------------------------------------===// 13bb372243SDan Gohman 14bb372243SDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 156bda14b3SChandler Carruth #include "WebAssembly.h" 16*972d7d51SThomas Lively #include "WebAssemblyInstrInfo.h" 17bb372243SDan Gohman #include "WebAssemblyMachineFunctionInfo.h" 18bb372243SDan Gohman #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 19bb372243SDan Gohman #include "llvm/CodeGen/MachineMemOperand.h" 20bb372243SDan Gohman #include "llvm/CodeGen/Passes.h" 21bb372243SDan Gohman #include "llvm/Support/Debug.h" 22bb372243SDan Gohman #include "llvm/Support/raw_ostream.h" 23bb372243SDan Gohman using namespace llvm; 24bb372243SDan Gohman 25bb372243SDan Gohman #define DEBUG_TYPE "wasm-set-p2align-operands" 26bb372243SDan Gohman 27bb372243SDan Gohman namespace { 28bb372243SDan Gohman class WebAssemblySetP2AlignOperands final : public MachineFunctionPass { 29bb372243SDan Gohman public: 30bb372243SDan Gohman static char ID; // Pass identification, replacement for typeid 31bb372243SDan Gohman WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {} 32bb372243SDan Gohman 33117296c0SMehdi Amini StringRef getPassName() const override { 34bb372243SDan Gohman return "WebAssembly Set p2align Operands"; 35bb372243SDan Gohman } 36bb372243SDan Gohman 37bb372243SDan Gohman void getAnalysisUsage(AnalysisUsage &AU) const override { 38bb372243SDan Gohman AU.setPreservesCFG(); 39bb372243SDan Gohman AU.addPreserved<MachineBlockFrequencyInfo>(); 40bb372243SDan Gohman AU.addPreservedID(MachineDominatorsID); 41bb372243SDan Gohman MachineFunctionPass::getAnalysisUsage(AU); 42bb372243SDan Gohman } 43bb372243SDan Gohman 44bb372243SDan Gohman bool runOnMachineFunction(MachineFunction &MF) override; 45bb372243SDan Gohman }; 46bb372243SDan Gohman } // end anonymous namespace 47bb372243SDan Gohman 48bb372243SDan Gohman char WebAssemblySetP2AlignOperands::ID = 0; 4940926451SJacob Gravelle INITIALIZE_PASS(WebAssemblySetP2AlignOperands, DEBUG_TYPE, 5040926451SJacob Gravelle "Set the p2align operands for WebAssembly loads and stores", 5140926451SJacob Gravelle false, false) 5240926451SJacob Gravelle 53bb372243SDan Gohman FunctionPass *llvm::createWebAssemblySetP2AlignOperands() { 54bb372243SDan Gohman return new WebAssemblySetP2AlignOperands(); 55bb372243SDan Gohman } 56bb372243SDan Gohman 5718c56a07SHeejin Ahn static void rewriteP2Align(MachineInstr &MI, unsigned OperandNo) { 587f1bdb2eSDan Gohman assert(MI.getOperand(OperandNo).getImm() == 0 && 597f1bdb2eSDan Gohman "ISel should set p2align operands to 0"); 607f1bdb2eSDan Gohman assert(MI.hasOneMemOperand() && 617f1bdb2eSDan Gohman "Load and store instructions have exactly one mem operand"); 627f1bdb2eSDan Gohman assert((*MI.memoperands_begin())->getSize() == 63f208f631SHeejin Ahn (UINT64_C(1) << WebAssembly::GetDefaultP2Align(MI.getOpcode())) && 647f1bdb2eSDan Gohman "Default p2align value should be natural"); 657f1bdb2eSDan Gohman assert(MI.getDesc().OpInfo[OperandNo].OperandType == 667f1bdb2eSDan Gohman WebAssembly::OPERAND_P2ALIGN && 677f1bdb2eSDan Gohman "Load and store instructions should have a p2align operand"); 687f1bdb2eSDan Gohman uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment()); 697f1bdb2eSDan Gohman 707f1bdb2eSDan Gohman // WebAssembly does not currently support supernatural alignment. 71f208f631SHeejin Ahn P2Align = std::min(P2Align, 72f208f631SHeejin Ahn uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode()))); 737f1bdb2eSDan Gohman 747f1bdb2eSDan Gohman MI.getOperand(OperandNo).setImm(P2Align); 757f1bdb2eSDan Gohman } 767f1bdb2eSDan Gohman 77bb372243SDan Gohman bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) { 78d34e60caSNicola Zaghen LLVM_DEBUG({ 79bb372243SDan Gohman dbgs() << "********** Set p2align Operands **********\n" 80bb372243SDan Gohman << "********** Function: " << MF.getName() << '\n'; 81bb372243SDan Gohman }); 82bb372243SDan Gohman 83bb372243SDan Gohman bool Changed = false; 84bb372243SDan Gohman 85bb372243SDan Gohman for (auto &MBB : MF) { 86bb372243SDan Gohman for (auto &MI : MBB) { 87*972d7d51SThomas Lively int16_t P2AlignOpNum = WebAssembly::getNamedOperandIdx( 88*972d7d51SThomas Lively MI.getOpcode(), WebAssembly::OpName::p2align); 89*972d7d51SThomas Lively if (P2AlignOpNum != -1) { 90*972d7d51SThomas Lively rewriteP2Align(MI, P2AlignOpNum); 91*972d7d51SThomas Lively Changed = true; 92bb372243SDan Gohman } 93bb372243SDan Gohman } 94bb372243SDan Gohman } 95bb372243SDan Gohman 96bb372243SDan Gohman return Changed; 97bb372243SDan Gohman } 98