1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains helper functions to find and list registers that are
11/// tracked by the unwinding information checker.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_DWARFCFICHECKER_REGISTERS_H
16#define LLVM_DWARFCFICHECKER_REGISTERS_H
17
18#include "llvm/MC/MCRegister.h"
19#include "llvm/MC/MCRegisterInfo.h"
20
21namespace llvm {
22
23/// This analysis only keeps track and cares about super registers, not the
24/// subregisters. All reads from/writes to subregisters are considered the
25/// same operation to super registers.
26inline bool isSuperReg(const MCRegisterInfo *MCRI, MCRegister Reg) {
27 return MCRI->superregs(Reg).empty();
28}
29
30inline SmallVector<MCPhysReg> getSuperRegs(const MCRegisterInfo *MCRI) {
31 SmallVector<MCPhysReg> SuperRegs;
32 for (auto &&RegClass : MCRI->regclasses())
33 for (unsigned I = 0; I < RegClass.getNumRegs(); I++) {
34 MCRegister Reg = RegClass.getRegister(i: I);
35 if (isSuperReg(MCRI, Reg))
36 SuperRegs.push_back(Elt: Reg.id());
37 }
38
39 sort(Start: SuperRegs.begin(), End: SuperRegs.end());
40 SuperRegs.erase(CS: llvm::unique(R&: SuperRegs), CE: SuperRegs.end());
41 return SuperRegs;
42}
43
44inline SmallVector<MCPhysReg> getTrackingRegs(const MCRegisterInfo *MCRI) {
45 SmallVector<MCPhysReg> TrackingRegs;
46 for (auto Reg : getSuperRegs(MCRI))
47 if (!MCRI->isArtificial(RegNo: Reg) && !MCRI->isConstant(RegNo: Reg))
48 TrackingRegs.push_back(Elt: Reg);
49 return TrackingRegs;
50}
51
52inline MCRegister getSuperReg(const MCRegisterInfo *MCRI, MCRegister Reg) {
53 if (isSuperReg(MCRI, Reg))
54 return Reg;
55 for (auto SuperReg : MCRI->superregs(Reg))
56 if (isSuperReg(MCRI, Reg: SuperReg))
57 return SuperReg;
58
59 llvm_unreachable("Should either be a super reg, or have a super reg");
60}
61
62} // namespace llvm
63
64#endif
65