280 lines · c
1//===- ARMConstantPoolValue.h - ARM constantpool value ----------*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the ARM specific constantpool value class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H14#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H15 16#include "llvm/ADT/SmallPtrSet.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/ADT/iterator_range.h"19#include "llvm/CodeGen/MachineConstantPool.h"20#include "llvm/Support/Casting.h"21#include <string>22#include <vector>23 24namespace llvm {25 26class BlockAddress;27class Constant;28class GlobalValue;29class GlobalVariable;30class LLVMContext;31class MachineBasicBlock;32class raw_ostream;33class Type;34 35namespace ARMCP {36 37 enum ARMCPKind {38 CPValue,39 CPExtSymbol,40 CPBlockAddress,41 CPLSDA,42 CPMachineBasicBlock,43 CPPromotedGlobal44 };45 46 enum ARMCPModifier {47 no_modifier, /// None48 TLSGD, /// Thread Local Storage (General Dynamic Mode)49 GOT_PREL, /// Global Offset Table, PC Relative50 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset51 TPOFF, /// Thread Pointer Offset52 SECREL, /// Section Relative (Windows TLS)53 SBREL, /// Static Base Relative (RWPI)54 };55 56} // end namespace ARMCP57 58/// ARMConstantPoolValue - ARM specific constantpool value. This is used to59/// represent PC-relative displacement between the address of the load60/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).61class ARMConstantPoolValue : public MachineConstantPoolValue {62 unsigned LabelId; // Label id of the load.63 ARMCP::ARMCPKind Kind; // Kind of constant.64 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.65 // 8 for ARM, 4 for Thumb.66 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))67 bool AddCurrentAddress;68 69protected:70 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,71 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,72 bool AddCurrentAddress);73 74 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,75 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,76 bool AddCurrentAddress);77 78 template <typename Derived>79 int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {80 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();81 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {82 if (Constants[i].isMachineConstantPoolEntry() &&83 Constants[i].getAlign() >= Alignment) {84 auto *CPV =85 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);86 if (Derived *APC = dyn_cast<Derived>(CPV))87 if (cast<Derived>(this)->equals(APC))88 return i;89 }90 }91 92 return -1;93 }94 95public:96 ~ARMConstantPoolValue() override;97 98 ARMCP::ARMCPModifier getModifier() const { return Modifier; }99 StringRef getModifierText() const;100 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }101 102 bool mustAddCurrentAddress() const { return AddCurrentAddress; }103 104 unsigned getLabelId() const { return LabelId; }105 unsigned char getPCAdjustment() const { return PCAdjust; }106 107 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }108 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }109 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }110 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }111 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }112 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }113 114 int getExistingMachineCPValue(MachineConstantPool *CP,115 Align Alignment) override;116 117 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;118 119 /// hasSameValue - Return true if this ARM constpool value can share the same120 /// constantpool entry as another ARM constpool value.121 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);122 123 bool equals(const ARMConstantPoolValue *A) const {124 return this->LabelId == A->LabelId &&125 this->PCAdjust == A->PCAdjust &&126 this->Modifier == A->Modifier;127 }128 129 void print(raw_ostream &O) const override;130 void print(raw_ostream *O) const { if (O) print(*O); }131 void dump() const;132};133 134inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {135 V.print(O);136 return O;137}138 139/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,140/// Functions, and BlockAddresses.141class ARMConstantPoolConstant : public ARMConstantPoolValue {142 const Constant *CVal; // Constant being loaded.143 SmallPtrSet<const GlobalVariable*, 1> GVars;144 145 ARMConstantPoolConstant(const Constant *C,146 unsigned ID,147 ARMCP::ARMCPKind Kind,148 unsigned char PCAdj,149 ARMCP::ARMCPModifier Modifier,150 bool AddCurrentAddress);151 ARMConstantPoolConstant(Type *Ty, const Constant *C,152 unsigned ID,153 ARMCP::ARMCPKind Kind,154 unsigned char PCAdj,155 ARMCP::ARMCPModifier Modifier,156 bool AddCurrentAddress);157 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);158 159public:160 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);161 static ARMConstantPoolConstant *Create(const GlobalValue *GV,162 ARMCP::ARMCPModifier Modifier);163 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,164 const Constant *Initializer);165 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,166 ARMCP::ARMCPKind Kind,167 unsigned char PCAdj);168 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,169 ARMCP::ARMCPKind Kind,170 unsigned char PCAdj,171 ARMCP::ARMCPModifier Modifier,172 bool AddCurrentAddress);173 174 const GlobalValue *getGV() const;175 const BlockAddress *getBlockAddress() const;176 177 using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;178 179 iterator_range<promoted_iterator> promotedGlobals() { return GVars; }180 181 const Constant *getPromotedGlobalInit() const {182 return CVal;183 }184 185 int getExistingMachineCPValue(MachineConstantPool *CP,186 Align Alignment) override;187 188 /// hasSameValue - Return true if this ARM constpool value can share the same189 /// constantpool entry as another ARM constpool value.190 bool hasSameValue(ARMConstantPoolValue *ACPV) override;191 192 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;193 194 void print(raw_ostream &O) const override;195 196 static bool classof(const ARMConstantPoolValue *APV) {197 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||198 APV->isPromotedGlobal();199 }200 201 bool equals(const ARMConstantPoolConstant *A) const {202 return CVal == A->CVal && ARMConstantPoolValue::equals(A);203 }204};205 206/// ARMConstantPoolSymbol - ARM-specific constantpool values for external207/// symbols.208class ARMConstantPoolSymbol : public ARMConstantPoolValue {209 const std::string S; // ExtSymbol being loaded.210 211 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,212 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,213 bool AddCurrentAddress);214 215public:216 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,217 unsigned char PCAdj);218 219 StringRef getSymbol() const { return S; }220 221 int getExistingMachineCPValue(MachineConstantPool *CP,222 Align Alignment) override;223 224 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;225 226 /// hasSameValue - Return true if this ARM constpool value can share the same227 /// constantpool entry as another ARM constpool value.228 bool hasSameValue(ARMConstantPoolValue *ACPV) override;229 230 void print(raw_ostream &O) const override;231 232 static bool classof(const ARMConstantPoolValue *ACPV) {233 return ACPV->isExtSymbol();234 }235 236 bool equals(const ARMConstantPoolSymbol *A) const {237 return S == A->S && ARMConstantPoolValue::equals(A);238 }239};240 241/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic242/// block.243class ARMConstantPoolMBB : public ARMConstantPoolValue {244 const MachineBasicBlock *MBB; // Machine basic block.245 246 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,247 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,248 bool AddCurrentAddress);249 250public:251 static ARMConstantPoolMBB *Create(LLVMContext &C,252 const MachineBasicBlock *mbb,253 unsigned ID, unsigned char PCAdj);254 255 const MachineBasicBlock *getMBB() const { return MBB; }256 257 int getExistingMachineCPValue(MachineConstantPool *CP,258 Align Alignment) override;259 260 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;261 262 /// hasSameValue - Return true if this ARM constpool value can share the same263 /// constantpool entry as another ARM constpool value.264 bool hasSameValue(ARMConstantPoolValue *ACPV) override;265 266 void print(raw_ostream &O) const override;267 268 static bool classof(const ARMConstantPoolValue *ACPV) {269 return ACPV->isMachineBasicBlock();270 }271 272 bool equals(const ARMConstantPoolMBB *A) const {273 return MBB == A->MBB && ARMConstantPoolValue::equals(A);274 }275};276 277} // end namespace llvm278 279#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H280