From b993023ac9ebc7225a01f1e2e02a6f9a5fc02b7b Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Thu, 22 Dec 2016 21:56:19 +0000 Subject: [PATCH] [GlobalISel] Refactor the logic to constraint registers. Move the logic to constraint register from InstructionSelector to a utility function. It will be required by other passes in the GlobalISel pipeline. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290374 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/GlobalISel/Utils.h | 43 ++++++++++++++++++++++++ lib/CodeGen/GlobalISel/CMakeLists.txt | 1 + lib/CodeGen/GlobalISel/InstructionSelector.cpp | 19 ++++------- lib/CodeGen/GlobalISel/Utils.cpp | 45 ++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 include/llvm/CodeGen/GlobalISel/Utils.h create mode 100644 lib/CodeGen/GlobalISel/Utils.cpp diff --git a/include/llvm/CodeGen/GlobalISel/Utils.h b/include/llvm/CodeGen/GlobalISel/Utils.h new file mode 100644 index 00000000000..f5d5f5cdf0c --- /dev/null +++ b/include/llvm/CodeGen/GlobalISel/Utils.h @@ -0,0 +1,43 @@ +//==-- llvm/CodeGen/GlobalISel/Utils.h ---------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file This file declares the API of helper functions used throughout the +/// GlobalISel pipeline. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_GLOBALISEL_UTILS_H +#define LLVM_CODEGEN_GLOBALISEL_UTILS_H + +namespace llvm { + +class MachineFunction; +class MachineInstr; +class MachineRegisterInfo; +class MCInstrDesc; +class RegisterBankInfo; +class TargetInstrInfo; +class TargetRegisterInfo; + +/// Try to constrain Reg so that it is usable by argument OpIdx of the +/// provided MCInstrDesc \p II. If this fails, create a new virtual +/// register in the correct class and insert a COPY before \p InsertPt. +/// The debug location of \p InsertPt is used for the new copy. +/// +/// \return The virtual register constrained to the right register class. +unsigned constrainOperandRegClass(const MachineFunction &MF, + const TargetRegisterInfo &TRI, + MachineRegisterInfo &MRI, + const TargetInstrInfo &TII, + const RegisterBankInfo &RBI, + MachineInstr &InsertPt, const MCInstrDesc &II, + unsigned Reg, unsigned OpIdx); + +} // End namespace llvm. +#endif diff --git a/lib/CodeGen/GlobalISel/CMakeLists.txt b/lib/CodeGen/GlobalISel/CMakeLists.txt index e1648fce09e..76ab5d36047 100644 --- a/lib/CodeGen/GlobalISel/CMakeLists.txt +++ b/lib/CodeGen/GlobalISel/CMakeLists.txt @@ -11,6 +11,7 @@ set(GLOBAL_ISEL_FILES RegBankSelect.cpp RegisterBank.cpp RegisterBankInfo.cpp + Utils.cpp ) # Add GlobalISel files to the dependencies if the user wants to build it. diff --git a/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/lib/CodeGen/GlobalISel/InstructionSelector.cpp index 3b2177c72c4..5c34da0dc55 100644 --- a/lib/CodeGen/GlobalISel/InstructionSelector.cpp +++ b/lib/CodeGen/GlobalISel/InstructionSelector.cpp @@ -12,6 +12,7 @@ #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -39,27 +40,21 @@ bool InstructionSelector::constrainSelectedInstRegOperands( DEBUG(dbgs() << "Converting operand: " << MO << '\n'); assert(MO.isReg() && "Unsupported non-reg operand"); + unsigned Reg = MO.getReg(); // Physical registers don't need to be constrained. - if (TRI.isPhysicalRegister(MO.getReg())) + if (TRI.isPhysicalRegister(Reg)) continue; // Register operands with a value of 0 (e.g. predicate operands) don't need // to be constrained. - if (MO.getReg() == 0) + if (Reg == 0) continue; - const TargetRegisterClass *RC = TII.getRegClass(I.getDesc(), OpI, &TRI, MF); - assert(RC && "Selected inst should have regclass operand"); - // If the operand is a vreg, we should constrain its regclass, and only // insert COPYs if that's impossible. - // If the operand is a physreg, we only insert COPYs if the register class - // doesn't contain the register. - if (RBI.constrainGenericRegister(MO.getReg(), *RC, MRI)) - continue; - - DEBUG(dbgs() << "Constraining with COPYs isn't implemented yet"); - return false; + // constrainOperandRegClass does that for us. + MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), + Reg, OpI)); } return true; } diff --git a/lib/CodeGen/GlobalISel/Utils.cpp b/lib/CodeGen/GlobalISel/Utils.cpp new file mode 100644 index 00000000000..e50091833c2 --- /dev/null +++ b/lib/CodeGen/GlobalISel/Utils.cpp @@ -0,0 +1,45 @@ +//===- llvm/CodeGen/GlobalISel/Utils.cpp -------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file This file implements the utility functions used by the GlobalISel +/// pipeline. +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/GlobalISel/Utils.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" + +#define DEBUG_TYPE "globalisel-utils" + +using namespace llvm; + +unsigned llvm::constrainOperandRegClass( + const MachineFunction &MF, const TargetRegisterInfo &TRI, + MachineRegisterInfo &MRI, const TargetInstrInfo &TII, + const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, + unsigned Reg, unsigned OpIdx) { + // Assume physical registers are properly constrained. + assert(TargetRegisterInfo::isVirtualRegister(Reg) && + "PhysReg not implemented"); + + const TargetRegisterClass *RegClass = TII.getRegClass(II, OpIdx, &TRI, MF); + + if (!RBI.constrainGenericRegister(Reg, *RegClass, MRI)) { + unsigned NewReg = MRI.createVirtualRegister(RegClass); + BuildMI(*InsertPt.getParent(), InsertPt, InsertPt.getDebugLoc(), + TII.get(TargetOpcode::COPY), NewReg) + .addReg(Reg); + return NewReg; + } + + return Reg; +} -- 2.11.0