1*bb372243SDan Gohman //=- WebAssemblySetP2AlignOperands.cpp - Set alignments on loads and stores -=// 2*bb372243SDan Gohman // 3*bb372243SDan Gohman // The LLVM Compiler Infrastructure 4*bb372243SDan Gohman // 5*bb372243SDan Gohman // This file is distributed under the University of Illinois Open Source 6*bb372243SDan Gohman // License. See LICENSE.TXT for details. 7*bb372243SDan Gohman // 8*bb372243SDan Gohman //===----------------------------------------------------------------------===// 9*bb372243SDan Gohman /// 10*bb372243SDan Gohman /// \file 11*bb372243SDan Gohman /// \brief This file sets the p2align operands on load and store instructions. 12*bb372243SDan Gohman /// 13*bb372243SDan Gohman //===----------------------------------------------------------------------===// 14*bb372243SDan Gohman 15*bb372243SDan Gohman #include "WebAssembly.h" 16*bb372243SDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 17*bb372243SDan Gohman #include "WebAssemblyMachineFunctionInfo.h" 18*bb372243SDan Gohman #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 19*bb372243SDan Gohman #include "llvm/CodeGen/MachineMemOperand.h" 20*bb372243SDan Gohman #include "llvm/CodeGen/Passes.h" 21*bb372243SDan Gohman #include "llvm/Support/Debug.h" 22*bb372243SDan Gohman #include "llvm/Support/raw_ostream.h" 23*bb372243SDan Gohman using namespace llvm; 24*bb372243SDan Gohman 25*bb372243SDan Gohman #define DEBUG_TYPE "wasm-set-p2align-operands" 26*bb372243SDan Gohman 27*bb372243SDan Gohman namespace { 28*bb372243SDan Gohman class WebAssemblySetP2AlignOperands final : public MachineFunctionPass { 29*bb372243SDan Gohman public: 30*bb372243SDan Gohman static char ID; // Pass identification, replacement for typeid 31*bb372243SDan Gohman WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {} 32*bb372243SDan Gohman 33*bb372243SDan Gohman const char *getPassName() const override { 34*bb372243SDan Gohman return "WebAssembly Set p2align Operands"; 35*bb372243SDan Gohman } 36*bb372243SDan Gohman 37*bb372243SDan Gohman void getAnalysisUsage(AnalysisUsage &AU) const override { 38*bb372243SDan Gohman AU.setPreservesCFG(); 39*bb372243SDan Gohman AU.addPreserved<MachineBlockFrequencyInfo>(); 40*bb372243SDan Gohman AU.addPreservedID(MachineDominatorsID); 41*bb372243SDan Gohman MachineFunctionPass::getAnalysisUsage(AU); 42*bb372243SDan Gohman } 43*bb372243SDan Gohman 44*bb372243SDan Gohman bool runOnMachineFunction(MachineFunction &MF) override; 45*bb372243SDan Gohman }; 46*bb372243SDan Gohman } // end anonymous namespace 47*bb372243SDan Gohman 48*bb372243SDan Gohman char WebAssemblySetP2AlignOperands::ID = 0; 49*bb372243SDan Gohman FunctionPass *llvm::createWebAssemblySetP2AlignOperands() { 50*bb372243SDan Gohman return new WebAssemblySetP2AlignOperands(); 51*bb372243SDan Gohman } 52*bb372243SDan Gohman 53*bb372243SDan Gohman bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) { 54*bb372243SDan Gohman DEBUG({ 55*bb372243SDan Gohman dbgs() << "********** Set p2align Operands **********\n" 56*bb372243SDan Gohman << "********** Function: " << MF.getName() << '\n'; 57*bb372243SDan Gohman }); 58*bb372243SDan Gohman 59*bb372243SDan Gohman bool Changed = false; 60*bb372243SDan Gohman 61*bb372243SDan Gohman for (auto &MBB : MF) { 62*bb372243SDan Gohman for (auto &MI : MBB) { 63*bb372243SDan Gohman switch (MI.getOpcode()) { 64*bb372243SDan Gohman case WebAssembly::LOAD_I32: 65*bb372243SDan Gohman case WebAssembly::LOAD_I64: 66*bb372243SDan Gohman case WebAssembly::LOAD_F32: 67*bb372243SDan Gohman case WebAssembly::LOAD_F64: 68*bb372243SDan Gohman case WebAssembly::LOAD8_S_I32: 69*bb372243SDan Gohman case WebAssembly::LOAD8_U_I32: 70*bb372243SDan Gohman case WebAssembly::LOAD16_S_I32: 71*bb372243SDan Gohman case WebAssembly::LOAD16_U_I32: 72*bb372243SDan Gohman case WebAssembly::LOAD8_S_I64: 73*bb372243SDan Gohman case WebAssembly::LOAD8_U_I64: 74*bb372243SDan Gohman case WebAssembly::LOAD16_S_I64: 75*bb372243SDan Gohman case WebAssembly::LOAD16_U_I64: 76*bb372243SDan Gohman case WebAssembly::LOAD32_S_I64: 77*bb372243SDan Gohman case WebAssembly::LOAD32_U_I64: 78*bb372243SDan Gohman case WebAssembly::STORE_I32: 79*bb372243SDan Gohman case WebAssembly::STORE_I64: 80*bb372243SDan Gohman case WebAssembly::STORE_F32: 81*bb372243SDan Gohman case WebAssembly::STORE_F64: 82*bb372243SDan Gohman case WebAssembly::STORE8_I32: 83*bb372243SDan Gohman case WebAssembly::STORE16_I32: 84*bb372243SDan Gohman case WebAssembly::STORE8_I64: 85*bb372243SDan Gohman case WebAssembly::STORE16_I64: 86*bb372243SDan Gohman case WebAssembly::STORE32_I64: 87*bb372243SDan Gohman assert(MI.getOperand(3).getImm() == 0 && 88*bb372243SDan Gohman "ISel should set p2align operands to 0"); 89*bb372243SDan Gohman assert(MI.hasOneMemOperand() && 90*bb372243SDan Gohman "Load and store instructions have exactly one mem operand"); 91*bb372243SDan Gohman assert((*MI.memoperands_begin())->getSize() == 92*bb372243SDan Gohman (UINT64_C(1) 93*bb372243SDan Gohman << WebAssembly::GetDefaultP2Align(MI.getOpcode())) && 94*bb372243SDan Gohman "Default p2align value should be natural"); 95*bb372243SDan Gohman assert(MI.getDesc().OpInfo[3].OperandType == 96*bb372243SDan Gohman WebAssembly::OPERAND_P2ALIGN && 97*bb372243SDan Gohman "Load and store instructions should have a p2align operand"); 98*bb372243SDan Gohman MI.getOperand(3).setImm( 99*bb372243SDan Gohman Log2_64((*MI.memoperands_begin())->getAlignment())); 100*bb372243SDan Gohman break; 101*bb372243SDan Gohman default: 102*bb372243SDan Gohman break; 103*bb372243SDan Gohman } 104*bb372243SDan Gohman } 105*bb372243SDan Gohman } 106*bb372243SDan Gohman 107*bb372243SDan Gohman return Changed; 108*bb372243SDan Gohman } 109