From 89c33caee358da59b7e8d1876bb117b3220aae98 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Wed, 6 Apr 2016 16:27:01 +0000 Subject: [PATCH] [RegisterBankInfo] Add a couple of helper classes for the future cost model. llvm-svn: 265553 --- .../llvm/CodeGen/GlobalISel/RegisterBankInfo.h | 98 ++++++++++++++++++++++ llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 31 +++++++ 2 files changed, 129 insertions(+) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 147bfae..31e6687 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H #define LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H +#include "llvm/ADT/APInt.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/Support/ErrorHandling.h" @@ -22,10 +23,100 @@ #include // For unique_ptr. namespace llvm { +class MachineInstr; class TargetRegisterInfo; +class raw_ostream; /// Holds all the information related to register banks. class RegisterBankInfo { +public: + /// Helper struct that represents how a value is partially mapped + /// into a register. + /// The Mask is used to represent this partial mapping. Ones represent + /// where the value lives in RegBank and the width of the Mask represents + /// the size of the whole value. + struct PartialMapping { + /// Mask where the partial value lives. + APInt Mask; + /// Register bank where the partial value lives. + const RegisterBank *RegBank; + + PartialMapping() = default; + + /// Provide a shortcut for quickly building PartialMapping. + PartialMapping(const APInt &Mask, const RegisterBank &RegBank) + : Mask(Mask), RegBank(&RegBank) {} + + /// Print this partial mapping on dbgs() stream. + void dump() const; + + /// Print this partial mapping on \p OS; + void print(raw_ostream &OS) const; + }; + + /// Helper struct that represents how a value is mapped through + /// different register banks. + struct ValueMapping { + /// How the value is broken down between the different register banks. + SmallVector BreakDown; + /// Verify that this mapping makes sense. + void verify() const; + }; + + /// Helper class that represents how the value of an instruction may be + /// mapped and what is the related cost of such mapping. + class InstructionMapping { + /// Identifier of the mapping. + /// This is used to communicate between the target and the optimizers + /// which mapping should be realized. + unsigned ID; + /// Cost of this mapping. + unsigned Cost; + /// Mapping of all the operands. + std::unique_ptr OperandsMapping; + /// Number of operands. + unsigned NumOperands; + + ValueMapping &getOperandMapping(unsigned i) { + assert(i < getNumOperands() && "Out of bound operand"); + return OperandsMapping[i]; + } + + public: + /// Constructor for the mapping of an instruction. + /// \p NumOperands should be equal to number of all the operands of + /// the related instruction. + /// The rationale is that it is more efficient for the optimizers + /// to be able to assume that the mapping of the ith operand is + /// at the index i. + InstructionMapping(unsigned ID, unsigned Cost, unsigned NumOperands) + : ID(ID), Cost(Cost), NumOperands(NumOperands) { + OperandsMapping.reset(new ValueMapping[getNumOperands()]); + } + + /// Get the cost. + unsigned getCost() const { return Cost; } + + /// Get the ID. + unsigned getID() const { return ID; } + + /// Get the number of operands. + unsigned getNumOperands() const { return NumOperands; } + + /// Get the value mapping of the ith operand. + const ValueMapping &getOperandMapping(unsigned i) const { + return const_cast(this)->getOperandMapping(i); + } + + /// Get the value mapping of the ith operand. + void setOperandMapping(unsigned i, const ValueMapping &ValMapping) { + getOperandMapping(i) = ValMapping; + } + + /// Verifiy that this mapping makes sense for \p MI. + void verify(const MachineInstr &MI) const; + }; + protected: /// Hold the set of supported register banks. std::unique_ptr RegBanks; @@ -101,6 +192,13 @@ public: void verify(const TargetRegisterInfo &TRI) const; }; + +inline raw_ostream & +operator<<(raw_ostream &OS, + const RegisterBankInfo::PartialMapping &PartMapping) { + PartMapping.print(OS); + return OS; +} } // End namespace llvm. #endif diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 3039ac9..d882779 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -11,9 +11,11 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/RegisterBank.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetRegisterInfo.h" #include // For std::max. @@ -170,3 +172,32 @@ void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId, DEBUG(dbgs() << '\n'); } while (!WorkList.empty()); } + +//------------------------------------------------------------------------------ +// Helper classes implementation. +//------------------------------------------------------------------------------ +void RegisterBankInfo::PartialMapping::dump() const { + print(dbgs()); + dbgs() << '\n'; +} + +void RegisterBankInfo::PartialMapping::print(raw_ostream &OS) const { + SmallString<128> MaskStr; + Mask.toString(MaskStr, /*Radix*/ 2, /*Signed*/ 0, /*formatAsCLiteral*/ true); + OS << "Mask(" << Mask.getBitWidth() << ") = " << MaskStr << ", RegBank = "; + if (RegBank) + OS << *RegBank; + else + OS << "nullptr"; +} + +void RegisterBankInfo::ValueMapping::verify() const { + // Check that all the partial mapping have the same bitwidth. + // Check that the union of the partial mappings covers the whole value. + // Check that each register bank is big enough to hold the partial value. +} + +void RegisterBankInfo::InstructionMapping::verify( + const MachineInstr &MI) const { + // Check that all the register operands are properly mapped. +} -- 2.7.4