ARMConstantPoolValue.cpp 12 KB

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