diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericInstWrapper.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericInstWrapper.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericInstWrapper.h @@ -0,0 +1,55 @@ +//===- llvm/CodeGen/GlobalISel/GenericInstWrapper.h -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// Declares convenience wrapper classes for interpreting MachineInstr instances +/// as specific generic operations. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_GLOBALISEL_GENERICINSTWRAPPER_H +#define LLVM_CODEGEN_GLOBALISEL_GENERICINSTWRAPPER_H + +#include "llvm/CodeGen/MachineInstr.h" + +namespace llvm { + +/// A base class for all wrappers to use. This provides the opcode checking +/// logic and common utilities. +class GInstWrapper { +protected: + MachineInstr *Inst; + +public: + GInstWrapper(MachineInstr *MI, unsigned Opc) : Inst(MI) { + if (MI && MI->getOpcode() != Opc) + Inst = nullptr; + } + operator bool() { return Inst != nullptr; } + operator MachineInstr*() { return Inst; } + MachineInstr *getMI() { return Inst; } +}; + +class GLoad : public GInstWrapper { +public: + GLoad(MachineInstr *MI) : GInstWrapper(MI, TargetOpcode::G_LOAD) {} + + /// Get the definition register of the loaded value. + Register getLoadReg() const { return Inst->getOperand(0).getReg(); } + /// Get the source register of the pointer value. + Register getPointerReg() const { return Inst->getOperand(1).getReg(); } + MachineInstr::mmo_iterator memoperands_begin() { + return Inst->memoperands_begin(); + } + MachineInstr::mmo_iterator memoperands_end() { + return Inst->memoperands_end(); + } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_GENERICINSTWRAPPER_H \ No newline at end of file diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -9,6 +9,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/CodeGen/GlobalISel/GenericInstWrapper.h" #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" @@ -695,13 +696,13 @@ return false; Register SrcReg = MI.getOperand(1).getReg(); - MachineInstr *LoadDef = getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI); - if (!LoadDef || !MRI.hasOneNonDBGUse(LoadDef->getOperand(0).getReg())) + auto Load = GLoad(getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI)); + if (!Load || !MRI.hasOneNonDBGUse(Load.getLoadReg())) return false; // If the sign extend extends from a narrower width than the load's width, // then we can narrow the load width when we combine to a G_SEXTLOAD. - auto &MMO = **LoadDef->memoperands_begin(); + auto &MMO = **Load.memoperands_begin(); // Don't do this for non-simple loads. if (MMO.isAtomic() || MMO.isVolatile()) return false; @@ -717,7 +718,7 @@ // anyway for most targets. if (!isPowerOf2_32(NewSizeBits)) return false; - MatchInfo = std::make_tuple(LoadDef->getOperand(0).getReg(), NewSizeBits); + MatchInfo = std::make_tuple(Load.getLoadReg(), NewSizeBits); return true; } @@ -727,8 +728,8 @@ Register LoadReg; unsigned ScalarSizeBits; std::tie(LoadReg, ScalarSizeBits) = MatchInfo; - auto *LoadDef = MRI.getVRegDef(LoadReg); - assert(LoadDef && "Expected a load reg"); + auto Load = GLoad(MRI.getVRegDef(LoadReg)); + assert(Load && "Expected a load reg"); // If we have the following: // %ld = G_LOAD %ptr, (load 2) @@ -736,13 +737,13 @@ // ==> // %ld = G_SEXTLOAD %ptr (load 1) - auto &MMO = **LoadDef->memoperands_begin(); - Builder.setInstrAndDebugLoc(*LoadDef); + auto &MMO = **Load.memoperands_begin(); + Builder.setInstrAndDebugLoc(*Load); auto &MF = Builder.getMF(); auto PtrInfo = MMO.getPointerInfo(); auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, ScalarSizeBits / 8); Builder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, MI.getOperand(0).getReg(), - LoadDef->getOperand(1).getReg(), *NewMMO); + Load.getPointerReg(), *NewMMO); MI.eraseFromParent(); }