File: MCRegisterInfo.cpp

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,245,064 kB
  • sloc: cpp: 7,619,731; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,676; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (229 lines) | stat: -rw-r--r-- 7,666 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements MCRegisterInfo functions.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <cstdint>

using namespace llvm;

namespace {
/// MCRegAliasIterator enumerates all registers aliasing Reg.  This iterator
/// does not guarantee any ordering or that entries are unique.
class MCRegAliasIteratorImpl {
private:
  MCRegister Reg;
  const MCRegisterInfo *MCRI;

  MCRegUnitIterator RI;
  MCRegUnitRootIterator RRI;
  MCSuperRegIterator SI;

public:
  MCRegAliasIteratorImpl(MCRegister Reg, const MCRegisterInfo *MCRI)
      : Reg(Reg), MCRI(MCRI) {

    // Initialize the iterators.
    for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
      for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
        for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {
          if (Reg != *SI)
            return;
        }
      }
    }
  }

  bool isValid() const { return RI.isValid(); }

  MCRegister operator*() const {
    assert(SI.isValid() && "Cannot dereference an invalid iterator.");
    return *SI;
  }

  void advance() {
    // Assuming SI is valid.
    ++SI;
    if (SI.isValid())
      return;

    ++RRI;
    if (RRI.isValid()) {
      SI = MCSuperRegIterator(*RRI, MCRI, true);
      return;
    }

    ++RI;
    if (RI.isValid()) {
      RRI = MCRegUnitRootIterator(*RI, MCRI);
      SI = MCSuperRegIterator(*RRI, MCRI, true);
    }
  }

  MCRegAliasIteratorImpl &operator++() {
    assert(isValid() && "Cannot move off the end of the list.");
    do
      advance();
    while (isValid() && *SI == Reg);
    return *this;
  }
};
} // namespace

ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCRegister R) const {
  auto &Aliases = RegAliasesCache[R.id()];
  if (!Aliases.empty())
    return Aliases;

  for (MCRegAliasIteratorImpl It(R, this); It.isValid(); ++It)
    Aliases.push_back(*It);

  sort(Aliases);
  Aliases.erase(unique(Aliases), Aliases.end());
  assert(!llvm::is_contained(Aliases, R) &&
         "MCRegAliasIteratorImpl includes Self!");

  // Always put "self" at the end, so the iterator can choose to ignore it.
  // For registers without aliases, it also serves as a sentinel value that
  // tells us to not recompute the alias set.
  Aliases.push_back(R.id());
  Aliases.shrink_to_fit();
  return Aliases;
}

MCRegister
MCRegisterInfo::getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,
                                    const MCRegisterClass *RC) const {
  for (MCPhysReg Super : superregs(Reg))
    if (RC->contains(Super) && Reg == getSubReg(Super, SubIdx))
      return Super;
  return 0;
}

MCRegister MCRegisterInfo::getSubReg(MCRegister Reg, unsigned Idx) const {
  assert(Idx && Idx < getNumSubRegIndices() &&
         "This is not a subregister index");
  // Get a pointer to the corresponding SubRegIndices list. This list has the
  // name of each sub-register in the same order as MCSubRegIterator.
  const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
  for (MCPhysReg Sub : subregs(Reg)) {
    if (*SRI == Idx)
      return Sub;
    ++SRI;
  }
  return 0;
}

unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg,
                                        MCRegister SubReg) const {
  assert(SubReg && SubReg < getNumRegs() && "This is not a register");
  // Get a pointer to the corresponding SubRegIndices list. This list has the
  // name of each sub-register in the same order as MCSubRegIterator.
  const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
  for (MCPhysReg Sub : subregs(Reg)) {
    if (Sub == SubReg)
      return *SRI;
    ++SRI;
  }
  return 0;
}

int64_t MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
  const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
  unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;

  if (!M)
    return -1;
  DwarfLLVMRegPair Key = { RegNum, 0 };
  const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
  if (I == M+Size || I->FromReg != RegNum)
    return -1;
  // Consumers need to be able to detect -1 and -2, but at various points
  // the numbers move between unsigned and signed representations, as well as
  // between 32- and 64-bit representations. We need to convert first to int
  // before int64_t for proper sign handling.
  return int64_t(int(I->ToReg));
}

std::optional<MCRegister> MCRegisterInfo::getLLVMRegNum(uint64_t RegNum,
                                                        bool isEH) const {
  const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
  unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;

  if (!M)
    return std::nullopt;
  DwarfLLVMRegPair Key = {unsigned(RegNum), 0};
  const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
  if (I != M + Size && I->FromReg == RegNum)
    return MCRegister::from(I->ToReg);
  return std::nullopt;
}

int64_t MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const {
  // On ELF platforms, DWARF EH register numbers are the same as DWARF
  // other register numbers.  On Darwin x86, they differ and so need to be
  // mapped.  The .cfi_* directives accept integer literals as well as
  // register names and should generate exactly what the assembly code
  // asked for, so there might be DWARF/EH register numbers that don't have
  // a corresponding LLVM register number at all.  So if we can't map the
  // EH register number to an LLVM register number, assume it's just a
  // valid DWARF register number as is.
  if (std::optional<MCRegister> LRegNum = getLLVMRegNum(RegNum, true)) {
    int DwarfRegNum = getDwarfRegNum(*LRegNum, false);
    if (DwarfRegNum == -1)
      return RegNum;
    else
      return DwarfRegNum;
  }
  return RegNum;
}

int MCRegisterInfo::getSEHRegNum(MCRegister RegNum) const {
  const DenseMap<MCRegister, int>::const_iterator I = L2SEHRegs.find(RegNum);
  if (I == L2SEHRegs.end()) return (int)RegNum;
  return I->second;
}

int MCRegisterInfo::getCodeViewRegNum(MCRegister RegNum) const {
  if (L2CVRegs.empty())
    report_fatal_error("target does not implement codeview register mapping");
  const DenseMap<MCRegister, int>::const_iterator I = L2CVRegs.find(RegNum);
  if (I == L2CVRegs.end())
    report_fatal_error("unknown codeview register " + (RegNum < getNumRegs()
                                                           ? getName(RegNum)
                                                           : Twine(RegNum)));
  return I->second;
}

bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const {
  // Regunits are numerically ordered. Find a common unit.
  auto RangeA = regunits(RegA);
  MCRegUnitIterator IA = RangeA.begin(), EA = RangeA.end();
  auto RangeB = regunits(RegB);
  MCRegUnitIterator IB = RangeB.begin(), EB = RangeB.end();
  do {
    if (*IA == *IB)
      return true;
  } while (*IA < *IB ? ++IA != EA : ++IB != EB);
  return false;
}

bool MCRegisterInfo::isArtificialRegUnit(unsigned Unit) const {
  for (MCRegUnitRootIterator Root(Unit, this); Root.isValid(); ++Root)
    if (isArtificial(*Root))
      return true;
  return false;
}