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