Path: blob/main/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonGenMemAbsolute.cpp
35268 views
//===--- HexagonGenMemAbsolute.cpp - Generate Load/Store Set Absolute ---===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78// This pass traverses through all the basic blocks in a function and converts9// an indexed load/store with offset "0" to a absolute-set load/store10// instruction as long as the use of the register in the new instruction11// dominates the rest of the uses and there are more than 2 uses.1213#include "HexagonTargetMachine.h"14#include "llvm/ADT/Statistic.h"15#include "llvm/CodeGen/MachineDominators.h"16#include "llvm/CodeGen/MachineFunctionPass.h"17#include "llvm/CodeGen/MachineInstrBuilder.h"18#include "llvm/CodeGen/MachineRegisterInfo.h"19#include "llvm/CodeGen/Passes.h"20#include "llvm/CodeGen/TargetInstrInfo.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/raw_ostream.h"23#include "llvm/Target/TargetMachine.h"2425#define DEBUG_TYPE "hexagon-abs"2627using namespace llvm;2829STATISTIC(HexagonNumLoadAbsConversions,30"Number of Load instructions converted to absolute-set form");31STATISTIC(HexagonNumStoreAbsConversions,32"Number of Store instructions converted to absolute-set form");3334namespace llvm {35FunctionPass *createHexagonGenMemAbsolute();36void initializeHexagonGenMemAbsolutePass(PassRegistry &Registry);37} // namespace llvm3839namespace {4041class HexagonGenMemAbsolute : public MachineFunctionPass {42const HexagonInstrInfo *TII;43MachineRegisterInfo *MRI;44const TargetRegisterInfo *TRI;4546public:47static char ID;48HexagonGenMemAbsolute() : MachineFunctionPass(ID), TII(0), MRI(0), TRI(0) {49initializeHexagonGenMemAbsolutePass(*PassRegistry::getPassRegistry());50}5152StringRef getPassName() const override {53return "Hexagon Generate Load/Store Set Absolute Address Instruction";54}5556void getAnalysisUsage(AnalysisUsage &AU) const override {57MachineFunctionPass::getAnalysisUsage(AU);58AU.addRequired<MachineDominatorTreeWrapperPass>();59AU.addPreserved<MachineDominatorTreeWrapperPass>();60}6162bool runOnMachineFunction(MachineFunction &Fn) override;6364private:65static bool isValidIndexedLoad(int &Opcode, int &NewOpcode);66static bool isValidIndexedStore(int &Opcode, int &NewOpcode);67};68} // namespace6970char HexagonGenMemAbsolute::ID = 0;7172INITIALIZE_PASS(HexagonGenMemAbsolute, "hexagon-gen-load-absolute",73"Hexagon Generate Load/Store Set Absolute Address Instruction",74false, false)7576bool HexagonGenMemAbsolute::runOnMachineFunction(MachineFunction &Fn) {77if (skipFunction(Fn.getFunction()))78return false;7980TII = Fn.getSubtarget<HexagonSubtarget>().getInstrInfo();81MRI = &Fn.getRegInfo();82TRI = Fn.getRegInfo().getTargetRegisterInfo();8384MachineDominatorTree &MDT =85getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();8687// Loop over all of the basic blocks88for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();89MBBb != MBBe; ++MBBb) {90MachineBasicBlock *MBB = &*MBBb;91// Traverse the basic block92for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();93++MII) {94MachineInstr *MI = &*MII;95int Opc = MI->getOpcode();96if (Opc != Hexagon::CONST32 && Opc != Hexagon::A2_tfrsi)97continue;9899const MachineOperand &MO = MI->getOperand(0);100if (!MO.isReg() || !MO.isDef())101continue;102103unsigned DstReg = MO.getReg();104if (MRI->use_nodbg_empty(DstReg))105continue;106107typedef MachineRegisterInfo::use_nodbg_iterator use_iterator;108use_iterator NextUseMI = MRI->use_nodbg_begin(DstReg);109110MachineInstr *NextMI = NextUseMI->getParent();111int NextOpc = NextMI->getOpcode();112int NewOpc;113bool IsLoad = isValidIndexedLoad(NextOpc, NewOpc);114115if (!IsLoad && !isValidIndexedStore(NextOpc, NewOpc))116continue;117118// Base and Offset positions for load and store instructions119// Load R(dest), R(base), Imm -> R(dest) = mem(R(base) + Imm)120// Store R(base), Imm, R (src) -> mem(R(base) + Imm) = R(src)121unsigned BaseRegPos, ImmPos, RegPos;122if (!TII->getBaseAndOffsetPosition(*NextMI, BaseRegPos, ImmPos))123continue;124RegPos = IsLoad ? 0 : 2;125126bool IsGlobal = MI->getOperand(1).isGlobal();127if (!MI->getOperand(1).isImm() && !IsGlobal)128continue;129130const MachineOperand *BaseOp = nullptr;131int64_t Offset;132bool Scalable;133TII->getMemOperandWithOffset(*NextMI, BaseOp, Offset, Scalable, TRI);134135// Ensure BaseOp is non-null and register type.136if (!BaseOp || !BaseOp->isReg())137continue;138139if (Scalable)140continue;141142unsigned BaseReg = BaseOp->getReg();143if ((DstReg != BaseReg) || (Offset != 0))144continue;145146const MachineOperand &MO0 = NextMI->getOperand(RegPos);147148if (!MO0.isReg())149continue;150151unsigned LoadStoreReg = MO0.getReg();152153// Store: Bail out if the src and base are same (def and use on same154// register).155if (LoadStoreReg == BaseReg)156continue;157158// Insert the absolute-set instruction "I" only if the use of the159// BaseReg in "I" dominates the rest of the uses of BaseReg and if160// there are more than 2 uses of this BaseReg.161bool Dominates = true;162unsigned Counter = 0;163for (use_iterator I = NextUseMI, E = MRI->use_nodbg_end(); I != E; ++I) {164Counter++;165if (!MDT.dominates(NextMI, I->getParent()))166Dominates = false;167}168169if ((!Dominates) || (Counter < 3))170continue;171172// If we reach here, we have met all the conditions required for the173// replacement of the absolute instruction.174LLVM_DEBUG({175dbgs() << "Found a pair of instructions for absolute-set "176<< (IsLoad ? "load" : "store") << "\n";177dbgs() << *MI;178dbgs() << *NextMI;179});180MachineBasicBlock *ParentBlock = NextMI->getParent();181MachineInstrBuilder MIB;182if (IsLoad) { // Insert absolute-set load instruction183++HexagonNumLoadAbsConversions;184MIB = BuildMI(*ParentBlock, NextMI, NextMI->getDebugLoc(),185TII->get(NewOpc), LoadStoreReg)186.addReg(DstReg, RegState::Define);187} else { // Insert absolute-set store instruction188++HexagonNumStoreAbsConversions;189MIB = BuildMI(*ParentBlock, NextMI, NextMI->getDebugLoc(),190TII->get(NewOpc), DstReg);191}192193MachineOperand ImmOperand = MI->getOperand(1);194if (IsGlobal)195MIB.addGlobalAddress(ImmOperand.getGlobal(), ImmOperand.getOffset(),196ImmOperand.getTargetFlags());197else198MIB.addImm(ImmOperand.getImm());199200if (IsLoad)201MIB->getOperand(0).setSubReg(MO0.getSubReg());202else203MIB.addReg(LoadStoreReg, 0, MO0.getSubReg());204205LLVM_DEBUG(dbgs() << "Replaced with " << *MIB << "\n");206// Erase the instructions that got replaced.207MII = MBB->erase(MI);208--MII;209NextMI->getParent()->erase(NextMI);210}211}212213return true;214}215216bool HexagonGenMemAbsolute::isValidIndexedLoad(int &Opc, int &NewOpc) {217218bool Result = true;219switch (Opc) {220case Hexagon::L2_loadrb_io:221NewOpc = Hexagon::L4_loadrb_ap;222break;223case Hexagon::L2_loadrh_io:224NewOpc = Hexagon::L4_loadrh_ap;225break;226case Hexagon::L2_loadri_io:227NewOpc = Hexagon::L4_loadri_ap;228break;229case Hexagon::L2_loadrd_io:230NewOpc = Hexagon::L4_loadrd_ap;231break;232case Hexagon::L2_loadruh_io:233NewOpc = Hexagon::L4_loadruh_ap;234break;235case Hexagon::L2_loadrub_io:236NewOpc = Hexagon::L4_loadrub_ap;237break;238default:239Result = false;240}241242return Result;243}244245bool HexagonGenMemAbsolute::isValidIndexedStore(int &Opc, int &NewOpc) {246247bool Result = true;248switch (Opc) {249case Hexagon::S2_storerd_io:250NewOpc = Hexagon::S4_storerd_ap;251break;252case Hexagon::S2_storeri_io:253NewOpc = Hexagon::S4_storeri_ap;254break;255case Hexagon::S2_storerh_io:256NewOpc = Hexagon::S4_storerh_ap;257break;258case Hexagon::S2_storerb_io:259NewOpc = Hexagon::S4_storerb_ap;260break;261default:262Result = false;263}264265return Result;266}267268//===----------------------------------------------------------------------===//269// Public Constructor Functions270//===----------------------------------------------------------------------===//271272FunctionPass *llvm::createHexagonGenMemAbsolute() {273return new HexagonGenMemAbsolute();274}275276277