diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h @@ -0,0 +1,102 @@ +//===- llvm/CodeGen/GlobalISel/GenericMachineInstrs.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_GENERICMACHINEINSTRS_H +#define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H + +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/Support/Casting.h" + +namespace llvm { + +/// A base class for all GenericMachineInstrs. +class GenericMachineInstr : public MachineInstr { +public: + GenericMachineInstr() = delete; + + /// Access the Idx'th operand as a register and return it. + Register getReg(unsigned Idx) { return getOperand(Idx).getReg(); } + + static bool classof(const MachineInstr *MI) { + return isPreISelGenericOpcode(MI->getOpcode()); + } +}; + +class GLoadStore : public GenericMachineInstr { +public: + /// Get the source register of the pointer value. + Register getPointerReg() const { return getOperand(1).getReg(); } + + static bool classof(const MachineInstr *MI) { + switch (MI->getOpcode()) { + case TargetOpcode::G_LOAD: + case TargetOpcode::G_STORE: + case TargetOpcode::G_ZEXTLOAD: + case TargetOpcode::G_SEXTLOAD: + return true; + default: + return false; + } + } +}; + +class GAnyLoad : public GLoadStore { +public: + /// Get the definition register of the loaded value. + Register getDstReg() const { return getOperand(0).getReg(); } + + static bool classof(const MachineInstr *MI) { + switch (MI->getOpcode()) { + case TargetOpcode::G_LOAD: + case TargetOpcode::G_ZEXTLOAD: + case TargetOpcode::G_SEXTLOAD: + return true; + default: + return false; + } + } +}; + +class GLoad : public GAnyLoad { +public: + static bool classof(const MachineInstr *MI) { + return MI->getOpcode() == TargetOpcode::G_LOAD; + } +}; +class GSExtLoad : public GAnyLoad { +public: + static bool classof(const MachineInstr *MI) { + return MI->getOpcode() == TargetOpcode::G_SEXTLOAD; + } +}; +class GZExtLoad : public GAnyLoad { +public: + static bool classof(const MachineInstr *MI) { + return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD; + } +}; + +class GStore : public GLoadStore { +public: + /// Get the stored value register. + Register getStoredReg() const { return getOperand(0).getReg(); } + + static bool classof(const MachineInstr *MI) { + return MI->getOpcode() == TargetOpcode::G_STORE; + } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H \ No newline at end of file diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h" @@ -2757,12 +2758,13 @@ } LegalizerHelper::LegalizeResult -LegalizerHelper::lowerLoad(MachineInstr &MI) { +LegalizerHelper::lowerLoad(MachineInstr &LoadMI) { // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT - Register DstReg = MI.getOperand(0).getReg(); - Register PtrReg = MI.getOperand(1).getReg(); + auto *MI = cast(&LoadMI); + Register DstReg = MI->getDstReg(); + Register PtrReg = MI->getPointerReg(); LLT DstTy = MRI.getType(DstReg); - MachineMemOperand &MMO = **MI.memoperands_begin(); + MachineMemOperand &MMO = **MI->memoperands_begin(); LLT MemTy = MMO.getMemoryType(); MachineFunction &MF = MIRBuilder.getMF(); if (MemTy.isVector()) @@ -2788,11 +2790,10 @@ LoadReg = MRI.createGenericVirtualRegister(WideMemTy); } - if (MI.getOpcode() == TargetOpcode::G_SEXTLOAD) { + if (isa(MI)) { auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO); MIRBuilder.buildSExtInReg(LoadReg, NewLoad, MemSizeInBits); - } else if (MI.getOpcode() == TargetOpcode::G_ZEXTLOAD || - WideMemTy == DstTy) { + } else if (isa(MI) || WideMemTy == DstTy) { auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO); // The extra bits are guaranteed to be zero, since we stored them that // way. A zext load from Wide thus automatically gives zext from MemVT. @@ -2804,14 +2805,14 @@ if (DstTy != LoadTy) MIRBuilder.buildTrunc(DstReg, LoadReg); - MI.eraseFromParent(); + MI->eraseFromParent(); return Legalized; } if (DstTy.getSizeInBits() != MMO.getSizeInBits()) return UnableToLegalize; - if (MI.getOpcode() == TargetOpcode::G_LOAD) { + if (isa(MI)) { // This load needs splitting into power of 2 sized loads. if (DstTy.isVector()) return UnableToLegalize; @@ -2857,7 +2858,7 @@ auto Shift = MIRBuilder.buildShl(AnyExtTy, SmallLoad, ShiftAmt); auto Or = MIRBuilder.buildOr(AnyExtTy, Shift, LargeLoad); MIRBuilder.buildTrunc(DstReg, {Or}); - MI.eraseFromParent(); + MI->eraseFromParent(); return Legalized; } @@ -7089,13 +7090,14 @@ // %v1 = G_ASHR %a, scalar_size-1 // %v2 = G_ADD %a, %v1 // %res = G_XOR %v2, %v1 - LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); + auto *GMI = cast(&MI); + LLT DstTy = MRI.getType(GMI->getReg(0)); Register OpReg = MI.getOperand(1).getReg(); auto ShiftAmt = MIRBuilder.buildConstant(DstTy, DstTy.getScalarSizeInBits() - 1); auto Shift = MIRBuilder.buildAShr(DstTy, OpReg, ShiftAmt); auto Add = MIRBuilder.buildAdd(DstTy, OpReg, Shift); - MIRBuilder.buildXor(MI.getOperand(0).getReg(), Add, Shift); + MIRBuilder.buildXor(GMI->getReg(0), Add, Shift); MI.eraseFromParent(); return Legalized; }