/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/BPF/BPFRegisterInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- BPFRegisterInfo.cpp - BPF Register Information ----------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the BPF implementation of the TargetRegisterInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "BPFRegisterInfo.h" |
15 | | #include "BPF.h" |
16 | | #include "BPFSubtarget.h" |
17 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
18 | | #include "llvm/CodeGen/MachineFunction.h" |
19 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
20 | | #include "llvm/CodeGen/RegisterScavenging.h" |
21 | | #include "llvm/IR/DiagnosticInfo.h" |
22 | | #include "llvm/Support/ErrorHandling.h" |
23 | | #include "llvm/Target/TargetFrameLowering.h" |
24 | | #include "llvm/Target/TargetInstrInfo.h" |
25 | | |
26 | | #define GET_REGINFO_TARGET_DESC |
27 | | #include "BPFGenRegisterInfo.inc" |
28 | | using namespace llvm; |
29 | | |
30 | | BPFRegisterInfo::BPFRegisterInfo() |
31 | 51 | : BPFGenRegisterInfo(BPF::R0) {} |
32 | | |
33 | | const MCPhysReg * |
34 | 1.06k | BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { |
35 | 1.06k | return CSR_SaveList; |
36 | 1.06k | } |
37 | | |
38 | 294 | BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const { |
39 | 294 | BitVector Reserved(getNumRegs()); |
40 | 294 | Reserved.set(BPF::R10); // R10 is read only frame pointer |
41 | 294 | Reserved.set(BPF::R11); // R11 is pseudo stack pointer |
42 | 294 | return Reserved; |
43 | 294 | } |
44 | | |
45 | | static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) |
46 | 121 | { |
47 | 121 | if (Offset <= -512121 ) { |
48 | 1 | auto F = MF.getFunction(); |
49 | 1 | DiagnosticInfoUnsupported DiagStackSize(*F, |
50 | 1 | "Looks like the BPF stack limit of 512 bytes is exceeded. " |
51 | 1 | "Please move large on stack variables into BPF per-cpu array map.\n", |
52 | 1 | DL); |
53 | 1 | F->getContext().diagnose(DiagStackSize); |
54 | 1 | } |
55 | 121 | } |
56 | | |
57 | | void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, |
58 | | int SPAdj, unsigned FIOperandNum, |
59 | 121 | RegScavenger *RS) const { |
60 | 121 | assert(SPAdj == 0 && "Unexpected"); |
61 | 121 | |
62 | 121 | unsigned i = 0; |
63 | 121 | MachineInstr &MI = *II; |
64 | 121 | MachineBasicBlock &MBB = *MI.getParent(); |
65 | 121 | MachineFunction &MF = *MBB.getParent(); |
66 | 121 | DebugLoc DL = MI.getDebugLoc(); |
67 | 121 | |
68 | 121 | if (!DL) |
69 | 121 | /* try harder to get some debug loc */ |
70 | 121 | for (auto &I : MBB) |
71 | 2.14k | if (2.14k I.getDebugLoc()2.14k ) { |
72 | 2 | DL = I.getDebugLoc(); |
73 | 2 | break; |
74 | 2 | } |
75 | 121 | |
76 | 250 | while (!MI.getOperand(i).isFI()250 ) { |
77 | 129 | ++i; |
78 | 129 | assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); |
79 | 129 | } |
80 | 121 | |
81 | 121 | unsigned FrameReg = getFrameRegister(MF); |
82 | 121 | int FrameIndex = MI.getOperand(i).getIndex(); |
83 | 121 | const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); |
84 | 121 | |
85 | 121 | if (MI.getOpcode() == BPF::MOV_rr121 ) { |
86 | 13 | int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); |
87 | 13 | |
88 | 13 | WarnSize(Offset, MF, DL); |
89 | 13 | MI.getOperand(i).ChangeToRegister(FrameReg, false); |
90 | 13 | unsigned reg = MI.getOperand(i - 1).getReg(); |
91 | 13 | BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg) |
92 | 13 | .addReg(reg) |
93 | 13 | .addImm(Offset); |
94 | 13 | return; |
95 | 13 | } |
96 | 108 | |
97 | 108 | int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + |
98 | 108 | MI.getOperand(i + 1).getImm(); |
99 | 108 | |
100 | 108 | if (!isInt<32>(Offset)) |
101 | 0 | llvm_unreachable("bug in frame offset"); |
102 | 108 | |
103 | 108 | WarnSize(Offset, MF, DL); |
104 | 108 | |
105 | 108 | if (MI.getOpcode() == BPF::FI_ri108 ) { |
106 | 1 | // architecture does not really support FI_ri, replace it with |
107 | 1 | // MOV_rr <target_reg>, frame_reg |
108 | 1 | // ADD_ri <target_reg>, imm |
109 | 1 | unsigned reg = MI.getOperand(i - 1).getReg(); |
110 | 1 | |
111 | 1 | BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg) |
112 | 1 | .addReg(FrameReg); |
113 | 1 | BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg) |
114 | 1 | .addReg(reg) |
115 | 1 | .addImm(Offset); |
116 | 1 | |
117 | 1 | // Remove FI_ri instruction |
118 | 1 | MI.eraseFromParent(); |
119 | 108 | } else { |
120 | 107 | MI.getOperand(i).ChangeToRegister(FrameReg, false); |
121 | 107 | MI.getOperand(i + 1).ChangeToImmediate(Offset); |
122 | 107 | } |
123 | 121 | } |
124 | | |
125 | 131 | unsigned BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const { |
126 | 131 | return BPF::R10; |
127 | 131 | } |