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 #include <iterator>
21
22 namespace llvm {
23
24 /// This analysis only keeps track and cares about super registers, not the
25 /// subregisters. All reads from/writes to subregisters are considered the
26 /// same operation to super registers.
isSuperReg(const MCRegisterInfo * MCRI,MCPhysReg Reg)27 inline bool isSuperReg(const MCRegisterInfo *MCRI, MCPhysReg Reg) {
28 return MCRI->superregs(Reg).empty();
29 }
30
getSuperRegs(const MCRegisterInfo * MCRI)31 inline SmallVector<MCPhysReg> getSuperRegs(const MCRegisterInfo *MCRI) {
32 SmallVector<MCPhysReg> SuperRegs;
33 for (auto &&RegClass : MCRI->regclasses())
34 for (unsigned I = 0; I < RegClass.getNumRegs(); I++) {
35 MCPhysReg Reg = RegClass.getRegister(I);
36 if (isSuperReg(MCRI, Reg))
37 SuperRegs.push_back(Reg);
38 }
39
40 sort(SuperRegs.begin(), SuperRegs.end());
41 SuperRegs.erase(llvm::unique(SuperRegs), SuperRegs.end());
42 return SuperRegs;
43 }
44
getTrackingRegs(const MCRegisterInfo * MCRI)45 inline SmallVector<MCPhysReg> getTrackingRegs(const MCRegisterInfo *MCRI) {
46 SmallVector<MCPhysReg> TrackingRegs;
47 for (auto Reg : getSuperRegs(MCRI))
48 if (!MCRI->isArtificial(Reg) && !MCRI->isConstant(Reg))
49 TrackingRegs.push_back(Reg);
50 return TrackingRegs;
51 }
52
getSuperReg(const MCRegisterInfo * MCRI,MCPhysReg Reg)53 inline MCPhysReg getSuperReg(const MCRegisterInfo *MCRI, MCPhysReg Reg) {
54 if (isSuperReg(MCRI, Reg))
55 return Reg;
56 for (auto SuperReg : MCRI->superregs(Reg))
57 if (isSuperReg(MCRI, SuperReg))
58 return SuperReg;
59
60 llvm_unreachable("Should either be a super reg, or have a super reg");
61 }
62
63 } // namespace llvm
64
65 #endif
66