xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RegisterBank.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
101095a5dSDimitry Andric //===- llvm/CodeGen/GlobalISel/RegisterBank.cpp - Register Bank --*- C++ -*-==//
201095a5dSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
601095a5dSDimitry Andric //
701095a5dSDimitry Andric //===----------------------------------------------------------------------===//
801095a5dSDimitry Andric /// \file
901095a5dSDimitry Andric /// This file implements the RegisterBank class.
1001095a5dSDimitry Andric //===----------------------------------------------------------------------===//
1101095a5dSDimitry Andric 
12145449b1SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
13344a3780SDimitry Andric #include "llvm/ADT/StringExtras.h"
147fa27ce4SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
15044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
16eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
171d5ae102SDimitry Andric #include "llvm/Support/Debug.h"
1801095a5dSDimitry Andric 
1901095a5dSDimitry Andric #define DEBUG_TYPE "registerbank"
2001095a5dSDimitry Andric 
2101095a5dSDimitry Andric using namespace llvm;
2201095a5dSDimitry Andric 
verify(const RegisterBankInfo & RBI,const TargetRegisterInfo & TRI) const237fa27ce4SDimitry Andric bool RegisterBank::verify(const RegisterBankInfo &RBI,
247fa27ce4SDimitry Andric                           const TargetRegisterInfo &TRI) const {
2501095a5dSDimitry Andric   for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) {
2601095a5dSDimitry Andric     const TargetRegisterClass &RC = *TRI.getRegClass(RCId);
2701095a5dSDimitry Andric 
2801095a5dSDimitry Andric     if (!covers(RC))
2901095a5dSDimitry Andric       continue;
3001095a5dSDimitry Andric     // Verify that the register bank covers all the sub classes of the
3101095a5dSDimitry Andric     // classes it covers.
3201095a5dSDimitry Andric 
3301095a5dSDimitry Andric     // Use a different (slow in that case) method than
3401095a5dSDimitry Andric     // RegisterBankInfo to find the subclasses of RC, to make sure
3501095a5dSDimitry Andric     // both agree on the covers.
3601095a5dSDimitry Andric     for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) {
3701095a5dSDimitry Andric       const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId);
3801095a5dSDimitry Andric 
3901095a5dSDimitry Andric       if (!RC.hasSubClassEq(&SubRC))
4001095a5dSDimitry Andric         continue;
4101095a5dSDimitry Andric 
4201095a5dSDimitry Andric       // Verify that the Size of the register bank is big enough to cover
4301095a5dSDimitry Andric       // all the register classes it covers.
447fa27ce4SDimitry Andric       assert(RBI.getMaximumSize(getID()) >= TRI.getRegSizeInBits(SubRC) &&
4501095a5dSDimitry Andric              "Size is not big enough for all the subclasses!");
4601095a5dSDimitry Andric       assert(covers(SubRC) && "Not all subclasses are covered");
4701095a5dSDimitry Andric     }
4801095a5dSDimitry Andric   }
4901095a5dSDimitry Andric   return true;
5001095a5dSDimitry Andric }
5101095a5dSDimitry Andric 
covers(const TargetRegisterClass & RC) const5201095a5dSDimitry Andric bool RegisterBank::covers(const TargetRegisterClass &RC) const {
53b1c73532SDimitry Andric   return (CoveredClasses[RC.getID() / 32] & (1U << RC.getID() % 32)) != 0;
5401095a5dSDimitry Andric }
5501095a5dSDimitry Andric 
operator ==(const RegisterBank & OtherRB) const5601095a5dSDimitry Andric bool RegisterBank::operator==(const RegisterBank &OtherRB) const {
5701095a5dSDimitry Andric   // There must be only one instance of a given register bank alive
5801095a5dSDimitry Andric   // for the whole compilation.
5901095a5dSDimitry Andric   // The RegisterBankInfo is supposed to enforce that.
6001095a5dSDimitry Andric   assert((OtherRB.getID() != getID() || &OtherRB == this) &&
6101095a5dSDimitry Andric          "ID does not uniquely identify a RegisterBank");
6201095a5dSDimitry Andric   return &OtherRB == this;
6301095a5dSDimitry Andric }
6401095a5dSDimitry Andric 
6571d5a254SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(const TargetRegisterInfo * TRI) const66b915e9e0SDimitry Andric LLVM_DUMP_METHOD void RegisterBank::dump(const TargetRegisterInfo *TRI) const {
6701095a5dSDimitry Andric   print(dbgs(), /* IsForDebug */ true, TRI);
6801095a5dSDimitry Andric }
6971d5a254SDimitry Andric #endif
7001095a5dSDimitry Andric 
print(raw_ostream & OS,bool IsForDebug,const TargetRegisterInfo * TRI) const7101095a5dSDimitry Andric void RegisterBank::print(raw_ostream &OS, bool IsForDebug,
7201095a5dSDimitry Andric                          const TargetRegisterInfo *TRI) const {
7301095a5dSDimitry Andric   OS << getName();
7401095a5dSDimitry Andric   if (!IsForDebug)
7501095a5dSDimitry Andric     return;
76b1c73532SDimitry Andric 
77b1c73532SDimitry Andric   unsigned Count = 0;
78b1c73532SDimitry Andric   for (int i = 0, e = ((NumRegClasses + 31) / 32); i != e; ++i)
79b1c73532SDimitry Andric     Count += llvm::popcount(CoveredClasses[i]);
80b1c73532SDimitry Andric 
817fa27ce4SDimitry Andric   OS << "(ID:" << getID() << ")\n"
82b1c73532SDimitry Andric      << "Number of Covered register classes: " << Count << '\n';
8301095a5dSDimitry Andric   // Print all the subclasses if we can.
8401095a5dSDimitry Andric   // This register classes may not be properly initialized yet.
85b1c73532SDimitry Andric   if (!TRI || NumRegClasses == 0)
8601095a5dSDimitry Andric     return;
87b1c73532SDimitry Andric   assert(NumRegClasses == TRI->getNumRegClasses() &&
8801095a5dSDimitry Andric          "TRI does not match the initialization process?");
8901095a5dSDimitry Andric   OS << "Covered register classes:\n";
90344a3780SDimitry Andric   ListSeparator LS;
9101095a5dSDimitry Andric   for (unsigned RCId = 0, End = TRI->getNumRegClasses(); RCId != End; ++RCId) {
9201095a5dSDimitry Andric     const TargetRegisterClass &RC = *TRI->getRegClass(RCId);
9301095a5dSDimitry Andric 
94344a3780SDimitry Andric     if (covers(RC))
95344a3780SDimitry Andric       OS << LS << TRI->getRegClassName(&RC);
9601095a5dSDimitry Andric   }
9701095a5dSDimitry Andric }
98