xref: /freebsd/contrib/llvm-project/llvm/lib/DWARFCFIChecker/Registers.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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