1bb372243SDan Gohman //=- WebAssemblySetP2AlignOperands.cpp - Set alignments on loads and stores -=// 2bb372243SDan Gohman // 3bb372243SDan Gohman // The LLVM Compiler Infrastructure 4bb372243SDan Gohman // 5bb372243SDan Gohman // This file is distributed under the University of Illinois Open Source 6bb372243SDan Gohman // License. See LICENSE.TXT for details. 7bb372243SDan Gohman // 8bb372243SDan Gohman //===----------------------------------------------------------------------===// 9bb372243SDan Gohman /// 10bb372243SDan Gohman /// \file 11bb372243SDan Gohman /// \brief This file sets the p2align operands on load and store instructions. 12bb372243SDan Gohman /// 13bb372243SDan Gohman //===----------------------------------------------------------------------===// 14bb372243SDan Gohman 15bb372243SDan Gohman #include "WebAssembly.h" 16bb372243SDan Gohman #include "MCTargetDesc/WebAssemblyMCTargetDesc.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 33*117296c0SMehdi 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; 49bb372243SDan Gohman FunctionPass *llvm::createWebAssemblySetP2AlignOperands() { 50bb372243SDan Gohman return new WebAssemblySetP2AlignOperands(); 51bb372243SDan Gohman } 52bb372243SDan Gohman 53bb372243SDan Gohman bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) { 54bb372243SDan Gohman DEBUG({ 55bb372243SDan Gohman dbgs() << "********** Set p2align Operands **********\n" 56bb372243SDan Gohman << "********** Function: " << MF.getName() << '\n'; 57bb372243SDan Gohman }); 58bb372243SDan Gohman 59bb372243SDan Gohman bool Changed = false; 60bb372243SDan Gohman 61bb372243SDan Gohman for (auto &MBB : MF) { 62bb372243SDan Gohman for (auto &MI : MBB) { 63bb372243SDan Gohman switch (MI.getOpcode()) { 64bb372243SDan Gohman case WebAssembly::LOAD_I32: 65bb372243SDan Gohman case WebAssembly::LOAD_I64: 66bb372243SDan Gohman case WebAssembly::LOAD_F32: 67bb372243SDan Gohman case WebAssembly::LOAD_F64: 68bb372243SDan Gohman case WebAssembly::LOAD8_S_I32: 69bb372243SDan Gohman case WebAssembly::LOAD8_U_I32: 70bb372243SDan Gohman case WebAssembly::LOAD16_S_I32: 71bb372243SDan Gohman case WebAssembly::LOAD16_U_I32: 72bb372243SDan Gohman case WebAssembly::LOAD8_S_I64: 73bb372243SDan Gohman case WebAssembly::LOAD8_U_I64: 74bb372243SDan Gohman case WebAssembly::LOAD16_S_I64: 75bb372243SDan Gohman case WebAssembly::LOAD16_U_I64: 76bb372243SDan Gohman case WebAssembly::LOAD32_S_I64: 77bb372243SDan Gohman case WebAssembly::LOAD32_U_I64: 78bb372243SDan Gohman case WebAssembly::STORE_I32: 79bb372243SDan Gohman case WebAssembly::STORE_I64: 80bb372243SDan Gohman case WebAssembly::STORE_F32: 81bb372243SDan Gohman case WebAssembly::STORE_F64: 82bb372243SDan Gohman case WebAssembly::STORE8_I32: 83bb372243SDan Gohman case WebAssembly::STORE16_I32: 84bb372243SDan Gohman case WebAssembly::STORE8_I64: 85bb372243SDan Gohman case WebAssembly::STORE16_I64: 8604e7fb77SDan Gohman case WebAssembly::STORE32_I64: { 87bb372243SDan Gohman assert(MI.getOperand(3).getImm() == 0 && 88bb372243SDan Gohman "ISel should set p2align operands to 0"); 89bb372243SDan Gohman assert(MI.hasOneMemOperand() && 90bb372243SDan Gohman "Load and store instructions have exactly one mem operand"); 91bb372243SDan Gohman assert((*MI.memoperands_begin())->getSize() == 92bb372243SDan Gohman (UINT64_C(1) 93bb372243SDan Gohman << WebAssembly::GetDefaultP2Align(MI.getOpcode())) && 94bb372243SDan Gohman "Default p2align value should be natural"); 95bb372243SDan Gohman assert(MI.getDesc().OpInfo[3].OperandType == 96bb372243SDan Gohman WebAssembly::OPERAND_P2ALIGN && 97bb372243SDan Gohman "Load and store instructions should have a p2align operand"); 9804e7fb77SDan Gohman uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment()); 9904e7fb77SDan Gohman 10004e7fb77SDan Gohman // WebAssembly does not currently support supernatural alignment. 10104e7fb77SDan Gohman P2Align = std::min( 10204e7fb77SDan Gohman P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode()))); 10304e7fb77SDan Gohman 10404e7fb77SDan Gohman MI.getOperand(3).setImm(P2Align); 105bb372243SDan Gohman break; 10604e7fb77SDan Gohman } 107bb372243SDan Gohman default: 108bb372243SDan Gohman break; 109bb372243SDan Gohman } 110bb372243SDan Gohman } 111bb372243SDan Gohman } 112bb372243SDan Gohman 113bb372243SDan Gohman return Changed; 114bb372243SDan Gohman } 115