1 | //===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===// |
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 | // This file implements the PseudoSourceValue class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/CodeGen/PseudoSourceValue.h" |
14 | #include "llvm/CodeGen/MachineFrameInfo.h" |
15 | #include "llvm/CodeGen/PseudoSourceValueManager.h" |
16 | #include "llvm/IR/GlobalValue.h" |
17 | #include "llvm/Support/ErrorHandling.h" |
18 | #include "llvm/Support/raw_ostream.h" |
19 | #include "llvm/Target/TargetMachine.h" |
20 | |
21 | using namespace llvm; |
22 | |
23 | static const char *const PSVNames[] = { |
24 | "Stack" , "GOT" , "JumpTable" , "ConstantPool" , "FixedStack" , |
25 | "GlobalValueCallEntry" , "ExternalSymbolCallEntry" }; |
26 | |
27 | PseudoSourceValue::PseudoSourceValue(unsigned Kind, const TargetMachine &TM) |
28 | : Kind(Kind) { |
29 | AddressSpace = TM.getAddressSpaceForPseudoSourceKind(Kind); |
30 | } |
31 | |
32 | PseudoSourceValue::~PseudoSourceValue() = default; |
33 | |
34 | void PseudoSourceValue::printCustom(raw_ostream &O) const { |
35 | if (Kind < TargetCustom) |
36 | O << PSVNames[Kind]; |
37 | else |
38 | O << "TargetCustom" << Kind; |
39 | } |
40 | |
41 | bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const { |
42 | if (isStack()) |
43 | return false; |
44 | if (isGOT() || isConstantPool() || isJumpTable()) |
45 | return true; |
46 | llvm_unreachable("Unknown PseudoSourceValue!" ); |
47 | } |
48 | |
49 | bool PseudoSourceValue::isAliased(const MachineFrameInfo *) const { |
50 | if (isStack() || isGOT() || isConstantPool() || isJumpTable()) |
51 | return false; |
52 | llvm_unreachable("Unknown PseudoSourceValue!" ); |
53 | } |
54 | |
55 | bool PseudoSourceValue::mayAlias(const MachineFrameInfo *) const { |
56 | return !(isGOT() || isConstantPool() || isJumpTable()); |
57 | } |
58 | |
59 | bool FixedStackPseudoSourceValue::isConstant( |
60 | const MachineFrameInfo *MFI) const { |
61 | return MFI && MFI->isImmutableObjectIndex(ObjectIdx: FI); |
62 | } |
63 | |
64 | bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { |
65 | if (!MFI) |
66 | return true; |
67 | return MFI->isAliasedObjectIndex(ObjectIdx: FI); |
68 | } |
69 | |
70 | bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { |
71 | if (!MFI) |
72 | return true; |
73 | // Spill slots will not alias any LLVM IR value. |
74 | return !MFI->isSpillSlotObjectIndex(ObjectIdx: FI); |
75 | } |
76 | |
77 | void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const { |
78 | OS << "FixedStack" << FI; |
79 | } |
80 | |
81 | CallEntryPseudoSourceValue::CallEntryPseudoSourceValue(unsigned Kind, |
82 | const TargetMachine &TM) |
83 | : PseudoSourceValue(Kind, TM) {} |
84 | |
85 | bool CallEntryPseudoSourceValue::isConstant(const MachineFrameInfo *) const { |
86 | return false; |
87 | } |
88 | |
89 | bool CallEntryPseudoSourceValue::isAliased(const MachineFrameInfo *) const { |
90 | return false; |
91 | } |
92 | |
93 | bool CallEntryPseudoSourceValue::mayAlias(const MachineFrameInfo *) const { |
94 | return false; |
95 | } |
96 | |
97 | GlobalValuePseudoSourceValue::GlobalValuePseudoSourceValue( |
98 | const GlobalValue *GV, const TargetMachine &TM) |
99 | : CallEntryPseudoSourceValue(GlobalValueCallEntry, TM), GV(GV) {} |
100 | ExternalSymbolPseudoSourceValue::ExternalSymbolPseudoSourceValue( |
101 | const char *ES, const TargetMachine &TM) |
102 | : CallEntryPseudoSourceValue(ExternalSymbolCallEntry, TM), ES(ES) {} |
103 | |
104 | PseudoSourceValueManager::PseudoSourceValueManager(const TargetMachine &TMInfo) |
105 | : TM(TMInfo), StackPSV(PseudoSourceValue::Stack, TM), |
106 | GOTPSV(PseudoSourceValue::GOT, TM), |
107 | JumpTablePSV(PseudoSourceValue::JumpTable, TM), |
108 | ConstantPoolPSV(PseudoSourceValue::ConstantPool, TM) {} |
109 | |
110 | const PseudoSourceValue *PseudoSourceValueManager::getStack() { |
111 | return &StackPSV; |
112 | } |
113 | |
114 | const PseudoSourceValue *PseudoSourceValueManager::getGOT() { return &GOTPSV; } |
115 | |
116 | const PseudoSourceValue *PseudoSourceValueManager::getConstantPool() { |
117 | return &ConstantPoolPSV; |
118 | } |
119 | |
120 | const PseudoSourceValue *PseudoSourceValueManager::getJumpTable() { |
121 | return &JumpTablePSV; |
122 | } |
123 | |
124 | const PseudoSourceValue * |
125 | PseudoSourceValueManager::getFixedStack(int FI) { |
126 | // Frame index is often continuously positive, but can be negative. Use |
127 | // zig-zag encoding for dense index into FSValues vector. |
128 | unsigned Idx = (2 * unsigned(FI)) ^ (FI >> (sizeof(FI) * 8 - 1)); |
129 | if (FSValues.size() <= Idx) |
130 | FSValues.resize(N: Idx + 1); |
131 | std::unique_ptr<FixedStackPseudoSourceValue> &V = FSValues[Idx]; |
132 | if (!V) |
133 | V = std::make_unique<FixedStackPseudoSourceValue>(args&: FI, args: TM); |
134 | return V.get(); |
135 | } |
136 | |
137 | const PseudoSourceValue * |
138 | PseudoSourceValueManager::getGlobalValueCallEntry(const GlobalValue *GV) { |
139 | std::unique_ptr<const GlobalValuePseudoSourceValue> &E = |
140 | GlobalCallEntries[GV]; |
141 | if (!E) |
142 | E = std::make_unique<GlobalValuePseudoSourceValue>(args&: GV, args: TM); |
143 | return E.get(); |
144 | } |
145 | |
146 | const PseudoSourceValue * |
147 | PseudoSourceValueManager::getExternalSymbolCallEntry(const char *ES) { |
148 | std::unique_ptr<const ExternalSymbolPseudoSourceValue> &E = |
149 | ExternalCallEntries[ES]; |
150 | if (!E) |
151 | E = std::make_unique<ExternalSymbolPseudoSourceValue>(args&: ES, args: TM); |
152 | return E.get(); |
153 | } |
154 | |