1c62eefb8SMircea Trofin //===- llvm/CodeGen/GlobalISel/RegisterBank.cpp - Register Bank --*- C++ -*-==//
2c62eefb8SMircea Trofin //
3c62eefb8SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c62eefb8SMircea Trofin // See https://llvm.org/LICENSE.txt for license information.
5c62eefb8SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c62eefb8SMircea Trofin //
7c62eefb8SMircea Trofin //===----------------------------------------------------------------------===//
8c62eefb8SMircea Trofin /// \file
9c62eefb8SMircea Trofin /// This file implements the RegisterBank class.
10c62eefb8SMircea Trofin //===----------------------------------------------------------------------===//
11c62eefb8SMircea Trofin
12cb216076SMircea Trofin #include "llvm/CodeGen/RegisterBank.h"
13c62eefb8SMircea Trofin #include "llvm/ADT/StringExtras.h"
14aa7eace8SNitin John Raj #include "llvm/CodeGen/RegisterBankInfo.h"
15c62eefb8SMircea Trofin #include "llvm/CodeGen/TargetRegisterInfo.h"
16c62eefb8SMircea Trofin #include "llvm/Config/llvm-config.h"
17c62eefb8SMircea Trofin #include "llvm/Support/Debug.h"
18c62eefb8SMircea Trofin
19c62eefb8SMircea Trofin #define DEBUG_TYPE "registerbank"
20c62eefb8SMircea Trofin
21c62eefb8SMircea Trofin using namespace llvm;
22c62eefb8SMircea Trofin
verify(const RegisterBankInfo & RBI,const TargetRegisterInfo & TRI) const23aa7eace8SNitin John Raj bool RegisterBank::verify(const RegisterBankInfo &RBI,
24aa7eace8SNitin John Raj const TargetRegisterInfo &TRI) const {
25c62eefb8SMircea Trofin for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) {
26c62eefb8SMircea Trofin const TargetRegisterClass &RC = *TRI.getRegClass(RCId);
27c62eefb8SMircea Trofin
28c62eefb8SMircea Trofin if (!covers(RC))
29c62eefb8SMircea Trofin continue;
30c62eefb8SMircea Trofin // Verify that the register bank covers all the sub classes of the
31c62eefb8SMircea Trofin // classes it covers.
32c62eefb8SMircea Trofin
33c62eefb8SMircea Trofin // Use a different (slow in that case) method than
34c62eefb8SMircea Trofin // RegisterBankInfo to find the subclasses of RC, to make sure
35c62eefb8SMircea Trofin // both agree on the covers.
36c62eefb8SMircea Trofin for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) {
37c62eefb8SMircea Trofin const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId);
38c62eefb8SMircea Trofin
39c62eefb8SMircea Trofin if (!RC.hasSubClassEq(&SubRC))
40c62eefb8SMircea Trofin continue;
41c62eefb8SMircea Trofin
42c62eefb8SMircea Trofin // Verify that the Size of the register bank is big enough to cover
43c62eefb8SMircea Trofin // all the register classes it covers.
44aa7eace8SNitin John Raj assert(RBI.getMaximumSize(getID()) >= TRI.getRegSizeInBits(SubRC) &&
45c62eefb8SMircea Trofin "Size is not big enough for all the subclasses!");
46c62eefb8SMircea Trofin assert(covers(SubRC) && "Not all subclasses are covered");
47c62eefb8SMircea Trofin }
48c62eefb8SMircea Trofin }
49c62eefb8SMircea Trofin return true;
50c62eefb8SMircea Trofin }
51c62eefb8SMircea Trofin
covers(const TargetRegisterClass & RC) const52c62eefb8SMircea Trofin bool RegisterBank::covers(const TargetRegisterClass &RC) const {
53*46732e2aSCraig Topper return (CoveredClasses[RC.getID() / 32] & (1U << RC.getID() % 32)) != 0;
54c62eefb8SMircea Trofin }
55c62eefb8SMircea Trofin
operator ==(const RegisterBank & OtherRB) const56c62eefb8SMircea Trofin bool RegisterBank::operator==(const RegisterBank &OtherRB) const {
57c62eefb8SMircea Trofin // There must be only one instance of a given register bank alive
58c62eefb8SMircea Trofin // for the whole compilation.
59c62eefb8SMircea Trofin // The RegisterBankInfo is supposed to enforce that.
60c62eefb8SMircea Trofin assert((OtherRB.getID() != getID() || &OtherRB == this) &&
61c62eefb8SMircea Trofin "ID does not uniquely identify a RegisterBank");
62c62eefb8SMircea Trofin return &OtherRB == this;
63c62eefb8SMircea Trofin }
64c62eefb8SMircea Trofin
65c62eefb8SMircea Trofin #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(const TargetRegisterInfo * TRI) const66c62eefb8SMircea Trofin LLVM_DUMP_METHOD void RegisterBank::dump(const TargetRegisterInfo *TRI) const {
67c62eefb8SMircea Trofin print(dbgs(), /* IsForDebug */ true, TRI);
68c62eefb8SMircea Trofin }
69c62eefb8SMircea Trofin #endif
70c62eefb8SMircea Trofin
print(raw_ostream & OS,bool IsForDebug,const TargetRegisterInfo * TRI) const71c62eefb8SMircea Trofin void RegisterBank::print(raw_ostream &OS, bool IsForDebug,
72c62eefb8SMircea Trofin const TargetRegisterInfo *TRI) const {
73c62eefb8SMircea Trofin OS << getName();
74c62eefb8SMircea Trofin if (!IsForDebug)
75c62eefb8SMircea Trofin return;
76*46732e2aSCraig Topper
77*46732e2aSCraig Topper unsigned Count = 0;
78*46732e2aSCraig Topper for (int i = 0, e = ((NumRegClasses + 31) / 32); i != e; ++i)
79*46732e2aSCraig Topper Count += llvm::popcount(CoveredClasses[i]);
80*46732e2aSCraig Topper
81aa7eace8SNitin John Raj OS << "(ID:" << getID() << ")\n"
82*46732e2aSCraig Topper << "Number of Covered register classes: " << Count << '\n';
83c62eefb8SMircea Trofin // Print all the subclasses if we can.
84c62eefb8SMircea Trofin // This register classes may not be properly initialized yet.
85*46732e2aSCraig Topper if (!TRI || NumRegClasses == 0)
86c62eefb8SMircea Trofin return;
87*46732e2aSCraig Topper assert(NumRegClasses == TRI->getNumRegClasses() &&
88c62eefb8SMircea Trofin "TRI does not match the initialization process?");
89c62eefb8SMircea Trofin OS << "Covered register classes:\n";
90c62eefb8SMircea Trofin ListSeparator LS;
91c62eefb8SMircea Trofin for (unsigned RCId = 0, End = TRI->getNumRegClasses(); RCId != End; ++RCId) {
92c62eefb8SMircea Trofin const TargetRegisterClass &RC = *TRI->getRegClass(RCId);
93c62eefb8SMircea Trofin
94c62eefb8SMircea Trofin if (covers(RC))
95c62eefb8SMircea Trofin OS << LS << TRI->getRegClassName(&RC);
96c62eefb8SMircea Trofin }
97c62eefb8SMircea Trofin }
98