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 2306c3fb27SDimitry 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 5281ad6265SDimitry 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 5681ad6265SDimitry 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) 6681ad6265SDimitry 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 7181ad6265SDimitry 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