1//===- ARMConstantPoolValue.cpp - ARM constantpool value ------------------===//
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 ARM specific constantpool value class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARMConstantPoolValue.h"
14#include "llvm/ADT/FoldingSet.h"
15#include "llvm/CodeGen/MachineBasicBlock.h"
16#include "llvm/Config/llvm-config.h"
17#include "llvm/IR/Constant.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/GlobalValue.h"
20#include "llvm/IR/GlobalVariable.h"
21#include "llvm/IR/Type.h"
22#include "llvm/Support/Casting.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/raw_ostream.h"
26
27using namespace llvm;
28
29//===----------------------------------------------------------------------===//
30// ARMConstantPoolValue
31//===----------------------------------------------------------------------===//
32
33ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
34                                           ARMCP::ARMCPKind kind,
35                                           unsigned char PCAdj,
36                                           ARMCP::ARMCPModifier modifier,
37                                           bool addCurrentAddress)
38  : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind),
39    PCAdjust(PCAdj), Modifier(modifier),
40    AddCurrentAddress(addCurrentAddress) {}
41
42ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id,
43                                           ARMCP::ARMCPKind kind,
44                                           unsigned char PCAdj,
45                                           ARMCP::ARMCPModifier modifier,
46                                           bool addCurrentAddress)
47  : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
48    LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier),
49    AddCurrentAddress(addCurrentAddress) {}
50
51ARMConstantPoolValue::~ARMConstantPoolValue() = default;
52
53StringRef ARMConstantPoolValue::getModifierText() const {
54  switch (Modifier) {
55    // FIXME: Are these case sensitive? It'd be nice to lower-case all the
56    // strings if that's legal.
57  case ARMCP::no_modifier:
58    return "none";
59  case ARMCP::TLSGD:
60    return "tlsgd";
61  case ARMCP::GOT_PREL:
62    return "GOT_PREL";
63  case ARMCP::GOTTPOFF:
64    return "gottpoff";
65  case ARMCP::TPOFF:
66    return "tpoff";
67  case ARMCP::SBREL:
68    return "SBREL";
69  case ARMCP::SECREL:
70    return "secrel32";
71  }
72  llvm_unreachable("Unknown modifier!");
73}
74
75int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
76                                                    unsigned Alignment) {
77  llvm_unreachable("Shouldn't be calling this directly!");
78}
79
80void
81ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
82  ID.AddInteger(LabelId);
83  ID.AddInteger(PCAdjust);
84}
85
86bool
87ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
88  if (ACPV->Kind == Kind &&
89      ACPV->PCAdjust == PCAdjust &&
90      ACPV->Modifier == Modifier &&
91      ACPV->LabelId == LabelId &&
92      ACPV->AddCurrentAddress == AddCurrentAddress) {
93    // Two PC relative constpool entries containing the same GV address or
94    // external symbols. FIXME: What about blockaddress?
95    if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
96      return true;
97  }
98  return false;
99}
100
101#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
102LLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const {
103  errs() << "  " << *this;
104}
105#endif
106
107void ARMConstantPoolValue::print(raw_ostream &O) const {
108  if (Modifier) O << "(" << getModifierText() << ")";
109  if (PCAdjust != 0) {
110    O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
111    if (AddCurrentAddress) O << "-.";
112    O << ")";
113  }
114}
115
116//===----------------------------------------------------------------------===//
117// ARMConstantPoolConstant
118//===----------------------------------------------------------------------===//
119
120ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
121                                                 const Constant *C,
122                                                 unsigned ID,
123                                                 ARMCP::ARMCPKind Kind,
124                                                 unsigned char PCAdj,
125                                                 ARMCP::ARMCPModifier Modifier,
126                                                 bool AddCurrentAddress)
127  : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
128    CVal(C) {}
129
130ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
131                                                 unsigned ID,
132                                                 ARMCP::ARMCPKind Kind,
133                                                 unsigned char PCAdj,
134                                                 ARMCP::ARMCPModifier Modifier,
135                                                 bool AddCurrentAddress)
136  : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
137                         AddCurrentAddress),
138    CVal(C) {}
139
140ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV,
141                                                 const Constant *C)
142    : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0,
143                           ARMCP::no_modifier, false), CVal(C) {
144  GVars.insert(GV);
145}
146
147ARMConstantPoolConstant *
148ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
149  return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
150                                     ARMCP::no_modifier, false);
151}
152
153ARMConstantPoolConstant *
154ARMConstantPoolConstant::Create(const GlobalVariable *GVar,
155                                const Constant *Initializer) {
156  return new ARMConstantPoolConstant(GVar, Initializer);
157}
158
159ARMConstantPoolConstant *
160ARMConstantPoolConstant::Create(const GlobalValue *GV,
161                                ARMCP::ARMCPModifier Modifier) {
162  return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
163                                     GV, 0, ARMCP::CPValue, 0,
164                                     Modifier, false);
165}
166
167ARMConstantPoolConstant *
168ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
169                                ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
170  return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
171                                     ARMCP::no_modifier, false);
172}
173
174ARMConstantPoolConstant *
175ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
176                                ARMCP::ARMCPKind Kind, unsigned char PCAdj,
177                                ARMCP::ARMCPModifier Modifier,
178                                bool AddCurrentAddress) {
179  return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
180                                     AddCurrentAddress);
181}
182
183const GlobalValue *ARMConstantPoolConstant::getGV() const {
184  return dyn_cast_or_null<GlobalValue>(CVal);
185}
186
187const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
188  return dyn_cast_or_null<BlockAddress>(CVal);
189}
190
191int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
192                                                       unsigned Alignment) {
193  int index =
194    getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment);
195  if (index != -1) {
196    auto *CPV = static_cast<ARMConstantPoolValue*>(
197        CP->getConstants()[index].Val.MachineCPVal);
198    auto *Constant = cast<ARMConstantPoolConstant>(CPV);
199    Constant->GVars.insert(GVars.begin(), GVars.end());
200  }
201  return index;
202}
203
204bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
205  const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
206  return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
207}
208
209void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
210  ID.AddPointer(CVal);
211  for (const auto *GV : GVars)
212    ID.AddPointer(GV);
213  ARMConstantPoolValue::addSelectionDAGCSEId(ID);
214}
215
216void ARMConstantPoolConstant::print(raw_ostream &O) const {
217  O << CVal->getName();
218  ARMConstantPoolValue::print(O);
219}
220
221//===----------------------------------------------------------------------===//
222// ARMConstantPoolSymbol
223//===----------------------------------------------------------------------===//
224
225ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s,
226                                             unsigned id, unsigned char PCAdj,
227                                             ARMCP::ARMCPModifier Modifier,
228                                             bool AddCurrentAddress)
229    : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier,
230                           AddCurrentAddress),
231      S(s) {}
232
233ARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C,
234                                                     StringRef s, unsigned ID,
235                                                     unsigned char PCAdj) {
236  return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false);
237}
238
239int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
240                                                     unsigned Alignment) {
241  return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment);
242}
243
244bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) {
245  const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV);
246  return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV);
247}
248
249void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
250  ID.AddString(S);
251  ARMConstantPoolValue::addSelectionDAGCSEId(ID);
252}
253
254void ARMConstantPoolSymbol::print(raw_ostream &O) const {
255  O << S;
256  ARMConstantPoolValue::print(O);
257}
258
259//===----------------------------------------------------------------------===//
260// ARMConstantPoolMBB
261//===----------------------------------------------------------------------===//
262
263ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C,
264                                       const MachineBasicBlock *mbb,
265                                       unsigned id, unsigned char PCAdj,
266                                       ARMCP::ARMCPModifier Modifier,
267                                       bool AddCurrentAddress)
268  : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj,
269                         Modifier, AddCurrentAddress),
270    MBB(mbb) {}
271
272ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C,
273                                               const MachineBasicBlock *mbb,
274                                               unsigned ID,
275                                               unsigned char PCAdj) {
276  return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false);
277}
278
279int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP,
280                                                  unsigned Alignment) {
281  return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment);
282}
283
284bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) {
285  const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV);
286  return ACPMBB && ACPMBB->MBB == MBB &&
287    ARMConstantPoolValue::hasSameValue(ACPV);
288}
289
290void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
291  ID.AddPointer(MBB);
292  ARMConstantPoolValue::addSelectionDAGCSEId(ID);
293}
294
295void ARMConstantPoolMBB::print(raw_ostream &O) const {
296  O << printMBBReference(*MBB);
297  ARMConstantPoolValue::print(O);
298}
299