xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegisterBank.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
181ad6265SDimitry Andric //===- llvm/CodeGen/GlobalISel/RegisterBank.cpp - Register Bank --*- C++ -*-==//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric /// \file
981ad6265SDimitry Andric /// This file implements the RegisterBank class.
1081ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
1381ad6265SDimitry Andric #include "llvm/ADT/StringExtras.h"
1406c3fb27SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
1581ad6265SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
1681ad6265SDimitry Andric #include "llvm/Config/llvm-config.h"
1781ad6265SDimitry Andric #include "llvm/Support/Debug.h"
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric #define DEBUG_TYPE "registerbank"
2081ad6265SDimitry Andric 
2181ad6265SDimitry Andric using namespace llvm;
2281ad6265SDimitry Andric 
verify(const RegisterBankInfo & RBI,const TargetRegisterInfo & TRI) const2306c3fb27SDimitry Andric bool RegisterBank::verify(const RegisterBankInfo &RBI,
2406c3fb27SDimitry Andric                           const TargetRegisterInfo &TRI) const {
2581ad6265SDimitry Andric   for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) {
2681ad6265SDimitry Andric     const TargetRegisterClass &RC = *TRI.getRegClass(RCId);
2781ad6265SDimitry Andric 
2881ad6265SDimitry Andric     if (!covers(RC))
2981ad6265SDimitry Andric       continue;
3081ad6265SDimitry Andric     // Verify that the register bank covers all the sub classes of the
3181ad6265SDimitry Andric     // classes it covers.
3281ad6265SDimitry Andric 
3381ad6265SDimitry Andric     // Use a different (slow in that case) method than
3481ad6265SDimitry Andric     // RegisterBankInfo to find the subclasses of RC, to make sure
3581ad6265SDimitry Andric     // both agree on the covers.
3681ad6265SDimitry Andric     for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) {
3781ad6265SDimitry Andric       const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId);
3881ad6265SDimitry Andric 
3981ad6265SDimitry Andric       if (!RC.hasSubClassEq(&SubRC))
4081ad6265SDimitry Andric         continue;
4181ad6265SDimitry Andric 
4281ad6265SDimitry Andric       // Verify that the Size of the register bank is big enough to cover
4381ad6265SDimitry Andric       // all the register classes it covers.
4406c3fb27SDimitry Andric       assert(RBI.getMaximumSize(getID()) >= TRI.getRegSizeInBits(SubRC) &&
4581ad6265SDimitry Andric              "Size is not big enough for all the subclasses!");
4681ad6265SDimitry Andric       assert(covers(SubRC) && "Not all subclasses are covered");
4781ad6265SDimitry Andric     }
4881ad6265SDimitry Andric   }
4981ad6265SDimitry Andric   return true;
5081ad6265SDimitry Andric }
5181ad6265SDimitry Andric 
covers(const TargetRegisterClass & RC) const5281ad6265SDimitry Andric bool RegisterBank::covers(const TargetRegisterClass &RC) const {
53*5f757f3fSDimitry Andric   return (CoveredClasses[RC.getID() / 32] & (1U << RC.getID() % 32)) != 0;
5481ad6265SDimitry Andric }
5581ad6265SDimitry Andric 
operator ==(const RegisterBank & OtherRB) const5681ad6265SDimitry Andric bool RegisterBank::operator==(const RegisterBank &OtherRB) const {
5781ad6265SDimitry Andric   // There must be only one instance of a given register bank alive
5881ad6265SDimitry Andric   // for the whole compilation.
5981ad6265SDimitry Andric   // The RegisterBankInfo is supposed to enforce that.
6081ad6265SDimitry Andric   assert((OtherRB.getID() != getID() || &OtherRB == this) &&
6181ad6265SDimitry Andric          "ID does not uniquely identify a RegisterBank");
6281ad6265SDimitry Andric   return &OtherRB == this;
6381ad6265SDimitry Andric }
6481ad6265SDimitry Andric 
6581ad6265SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(const TargetRegisterInfo * TRI) const6681ad6265SDimitry Andric LLVM_DUMP_METHOD void RegisterBank::dump(const TargetRegisterInfo *TRI) const {
6781ad6265SDimitry Andric   print(dbgs(), /* IsForDebug */ true, TRI);
6881ad6265SDimitry Andric }
6981ad6265SDimitry Andric #endif
7081ad6265SDimitry Andric 
print(raw_ostream & OS,bool IsForDebug,const TargetRegisterInfo * TRI) const7181ad6265SDimitry Andric void RegisterBank::print(raw_ostream &OS, bool IsForDebug,
7281ad6265SDimitry Andric                          const TargetRegisterInfo *TRI) const {
7381ad6265SDimitry Andric   OS << getName();
7481ad6265SDimitry Andric   if (!IsForDebug)
7581ad6265SDimitry Andric     return;
76*5f757f3fSDimitry Andric 
77*5f757f3fSDimitry Andric   unsigned Count = 0;
78*5f757f3fSDimitry Andric   for (int i = 0, e = ((NumRegClasses + 31) / 32); i != e; ++i)
79*5f757f3fSDimitry Andric     Count += llvm::popcount(CoveredClasses[i]);
80*5f757f3fSDimitry Andric 
8106c3fb27SDimitry Andric   OS << "(ID:" << getID() << ")\n"
82*5f757f3fSDimitry Andric      << "Number of Covered register classes: " << Count << '\n';
8381ad6265SDimitry Andric   // Print all the subclasses if we can.
8481ad6265SDimitry Andric   // This register classes may not be properly initialized yet.
85*5f757f3fSDimitry Andric   if (!TRI || NumRegClasses == 0)
8681ad6265SDimitry Andric     return;
87*5f757f3fSDimitry Andric   assert(NumRegClasses == TRI->getNumRegClasses() &&
8881ad6265SDimitry Andric          "TRI does not match the initialization process?");
8981ad6265SDimitry Andric   OS << "Covered register classes:\n";
9081ad6265SDimitry Andric   ListSeparator LS;
9181ad6265SDimitry Andric   for (unsigned RCId = 0, End = TRI->getNumRegClasses(); RCId != End; ++RCId) {
9281ad6265SDimitry Andric     const TargetRegisterClass &RC = *TRI->getRegClass(RCId);
9381ad6265SDimitry Andric 
9481ad6265SDimitry Andric     if (covers(RC))
9581ad6265SDimitry Andric       OS << LS << TRI->getRegClassName(&RC);
9681ad6265SDimitry Andric   }
9781ad6265SDimitry Andric }
98