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"
16972d7d51SThomas 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
WebAssemblySetP2AlignOperands()31bb372243SDan Gohman WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {}
32bb372243SDan Gohman
getPassName() const33117296c0SMehdi Amini StringRef getPassName() const override {
34bb372243SDan Gohman return "WebAssembly Set p2align Operands";
35bb372243SDan Gohman }
36bb372243SDan Gohman
getAnalysisUsage(AnalysisUsage & AU) const37bb372243SDan 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
createWebAssemblySetP2AlignOperands()53bb372243SDan Gohman FunctionPass *llvm::createWebAssemblySetP2AlignOperands() {
54bb372243SDan Gohman return new WebAssemblySetP2AlignOperands();
55bb372243SDan Gohman }
56bb372243SDan Gohman
rewriteP2Align(MachineInstr & MI,unsigned OperandNo)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");
68*74eac903SGuillaume Chatelet uint64_t P2Align = Log2((*MI.memoperands_begin())->getAlign());
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
runOnMachineFunction(MachineFunction & MF)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) {
87972d7d51SThomas Lively int16_t P2AlignOpNum = WebAssembly::getNamedOperandIdx(
88972d7d51SThomas Lively MI.getOpcode(), WebAssembly::OpName::p2align);
89972d7d51SThomas Lively if (P2AlignOpNum != -1) {
90972d7d51SThomas Lively rewriteP2Align(MI, P2AlignOpNum);
91972d7d51SThomas Lively Changed = true;
92bb372243SDan Gohman }
93bb372243SDan Gohman }
94bb372243SDan Gohman }
95bb372243SDan Gohman
96bb372243SDan Gohman return Changed;
97bb372243SDan Gohman }
98