97 lines · cpp
1//=- WebAssemblySetP2AlignOperands.cpp - Set alignments on loads and stores -=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file sets the p2align operands on load and store instructions.11///12//===----------------------------------------------------------------------===//13 14#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"15#include "WebAssembly.h"16#include "WebAssemblyInstrInfo.h"17#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"18#include "llvm/CodeGen/MachineMemOperand.h"19#include "llvm/CodeGen/Passes.h"20#include "llvm/Support/Debug.h"21#include "llvm/Support/raw_ostream.h"22using namespace llvm;23 24#define DEBUG_TYPE "wasm-set-p2align-operands"25 26namespace {27class WebAssemblySetP2AlignOperands final : public MachineFunctionPass {28public:29 static char ID; // Pass identification, replacement for typeid30 WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {}31 32 StringRef getPassName() const override {33 return "WebAssembly Set p2align Operands";34 }35 36 void getAnalysisUsage(AnalysisUsage &AU) const override {37 AU.setPreservesCFG();38 AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();39 AU.addPreservedID(MachineDominatorsID);40 MachineFunctionPass::getAnalysisUsage(AU);41 }42 43 bool runOnMachineFunction(MachineFunction &MF) override;44};45} // end anonymous namespace46 47char WebAssemblySetP2AlignOperands::ID = 0;48INITIALIZE_PASS(WebAssemblySetP2AlignOperands, DEBUG_TYPE,49 "Set the p2align operands for WebAssembly loads and stores",50 false, false)51 52FunctionPass *llvm::createWebAssemblySetP2AlignOperands() {53 return new WebAssemblySetP2AlignOperands();54}55 56static void rewriteP2Align(MachineInstr &MI, unsigned OperandNo) {57 assert(MI.getOperand(OperandNo).getImm() == 0 &&58 "ISel should set p2align operands to 0");59 assert(MI.hasOneMemOperand() &&60 "Load and store instructions have exactly one mem operand");61 assert((*MI.memoperands_begin())->getSize() ==62 (UINT64_C(1) << WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&63 "Default p2align value should be natural");64 assert(MI.getDesc().operands()[OperandNo].OperandType ==65 WebAssembly::OPERAND_P2ALIGN &&66 "Load and store instructions should have a p2align operand");67 uint64_t P2Align = Log2((*MI.memoperands_begin())->getAlign());68 69 // WebAssembly does not currently support supernatural alignment.70 P2Align = std::min(P2Align,71 uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));72 73 MI.getOperand(OperandNo).setImm(P2Align);74}75 76bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {77 LLVM_DEBUG({78 dbgs() << "********** Set p2align Operands **********\n"79 << "********** Function: " << MF.getName() << '\n';80 });81 82 bool Changed = false;83 84 for (auto &MBB : MF) {85 for (auto &MI : MBB) {86 int16_t P2AlignOpNum = WebAssembly::getNamedOperandIdx(87 MI.getOpcode(), WebAssembly::OpName::p2align);88 if (P2AlignOpNum != -1) {89 rewriteP2Align(MI, P2AlignOpNum);90 Changed = true;91 }92 }93 }94 95 return Changed;96}97