109467b48Spatrick //===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file implements the ARM specific constantpool value class. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 1409467b48Spatrick #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 1509467b48Spatrick 1609467b48Spatrick #include "llvm/ADT/SmallPtrSet.h" 1709467b48Spatrick #include "llvm/ADT/StringRef.h" 1809467b48Spatrick #include "llvm/ADT/iterator_range.h" 1909467b48Spatrick #include "llvm/CodeGen/MachineConstantPool.h" 2009467b48Spatrick #include "llvm/Support/Casting.h" 2109467b48Spatrick #include <string> 2209467b48Spatrick #include <vector> 2309467b48Spatrick 2409467b48Spatrick namespace llvm { 2509467b48Spatrick 2609467b48Spatrick class BlockAddress; 2709467b48Spatrick class Constant; 2809467b48Spatrick class GlobalValue; 2909467b48Spatrick class GlobalVariable; 3009467b48Spatrick class LLVMContext; 3109467b48Spatrick class MachineBasicBlock; 3209467b48Spatrick class raw_ostream; 3309467b48Spatrick class Type; 3409467b48Spatrick 3509467b48Spatrick namespace ARMCP { 3609467b48Spatrick 3709467b48Spatrick enum ARMCPKind { 3809467b48Spatrick CPValue, 3909467b48Spatrick CPExtSymbol, 4009467b48Spatrick CPBlockAddress, 4109467b48Spatrick CPLSDA, 4209467b48Spatrick CPMachineBasicBlock, 4309467b48Spatrick CPPromotedGlobal 4409467b48Spatrick }; 4509467b48Spatrick 4609467b48Spatrick enum ARMCPModifier { 4709467b48Spatrick no_modifier, /// None 4809467b48Spatrick TLSGD, /// Thread Local Storage (General Dynamic Mode) 4909467b48Spatrick GOT_PREL, /// Global Offset Table, PC Relative 5009467b48Spatrick GOTTPOFF, /// Global Offset Table, Thread Pointer Offset 5109467b48Spatrick TPOFF, /// Thread Pointer Offset 5209467b48Spatrick SECREL, /// Section Relative (Windows TLS) 5309467b48Spatrick SBREL, /// Static Base Relative (RWPI) 5409467b48Spatrick }; 5509467b48Spatrick 5609467b48Spatrick } // end namespace ARMCP 5709467b48Spatrick 5809467b48Spatrick /// ARMConstantPoolValue - ARM specific constantpool value. This is used to 5909467b48Spatrick /// represent PC-relative displacement between the address of the load 6009467b48Spatrick /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 6109467b48Spatrick class ARMConstantPoolValue : public MachineConstantPoolValue { 6209467b48Spatrick unsigned LabelId; // Label id of the load. 6309467b48Spatrick ARMCP::ARMCPKind Kind; // Kind of constant. 6409467b48Spatrick unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 6509467b48Spatrick // 8 for ARM, 4 for Thumb. 6609467b48Spatrick ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 6709467b48Spatrick bool AddCurrentAddress; 6809467b48Spatrick 6909467b48Spatrick protected: 7009467b48Spatrick ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 7109467b48Spatrick unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 7209467b48Spatrick bool AddCurrentAddress); 7309467b48Spatrick 7409467b48Spatrick ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 7509467b48Spatrick unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 7609467b48Spatrick bool AddCurrentAddress); 7709467b48Spatrick 7809467b48Spatrick template <typename Derived> getExistingMachineCPValueImpl(MachineConstantPool * CP,Align Alignment)79*097a140dSpatrick int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { 8009467b48Spatrick const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 8109467b48Spatrick for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 8209467b48Spatrick if (Constants[i].isMachineConstantPoolEntry() && 83*097a140dSpatrick Constants[i].getAlign() >= Alignment) { 8409467b48Spatrick auto *CPV = 8509467b48Spatrick static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal); 8609467b48Spatrick if (Derived *APC = dyn_cast<Derived>(CPV)) 8709467b48Spatrick if (cast<Derived>(this)->equals(APC)) 8809467b48Spatrick return i; 8909467b48Spatrick } 9009467b48Spatrick } 9109467b48Spatrick 9209467b48Spatrick return -1; 9309467b48Spatrick } 9409467b48Spatrick 9509467b48Spatrick public: 9609467b48Spatrick ~ARMConstantPoolValue() override; 9709467b48Spatrick getModifier()9809467b48Spatrick ARMCP::ARMCPModifier getModifier() const { return Modifier; } 9909467b48Spatrick StringRef getModifierText() const; hasModifier()10009467b48Spatrick bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 10109467b48Spatrick mustAddCurrentAddress()10209467b48Spatrick bool mustAddCurrentAddress() const { return AddCurrentAddress; } 10309467b48Spatrick getLabelId()10409467b48Spatrick unsigned getLabelId() const { return LabelId; } getPCAdjustment()10509467b48Spatrick unsigned char getPCAdjustment() const { return PCAdjust; } 10609467b48Spatrick isGlobalValue()10709467b48Spatrick bool isGlobalValue() const { return Kind == ARMCP::CPValue; } isExtSymbol()10809467b48Spatrick bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } isBlockAddress()10909467b48Spatrick bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } isLSDA()11009467b48Spatrick bool isLSDA() const { return Kind == ARMCP::CPLSDA; } isMachineBasicBlock()11109467b48Spatrick bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } isPromotedGlobal()11209467b48Spatrick bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; } 11309467b48Spatrick 11409467b48Spatrick int getExistingMachineCPValue(MachineConstantPool *CP, 115*097a140dSpatrick Align Alignment) override; 11609467b48Spatrick 11709467b48Spatrick void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 11809467b48Spatrick 11909467b48Spatrick /// hasSameValue - Return true if this ARM constpool value can share the same 12009467b48Spatrick /// constantpool entry as another ARM constpool value. 12109467b48Spatrick virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 12209467b48Spatrick equals(const ARMConstantPoolValue * A)12309467b48Spatrick bool equals(const ARMConstantPoolValue *A) const { 12409467b48Spatrick return this->LabelId == A->LabelId && 12509467b48Spatrick this->PCAdjust == A->PCAdjust && 12609467b48Spatrick this->Modifier == A->Modifier; 12709467b48Spatrick } 12809467b48Spatrick 12909467b48Spatrick void print(raw_ostream &O) const override; print(raw_ostream * O)13009467b48Spatrick void print(raw_ostream *O) const { if (O) print(*O); } 13109467b48Spatrick void dump() const; 13209467b48Spatrick }; 13309467b48Spatrick 13409467b48Spatrick inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 13509467b48Spatrick V.print(O); 13609467b48Spatrick return O; 13709467b48Spatrick } 13809467b48Spatrick 13909467b48Spatrick /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, 14009467b48Spatrick /// Functions, and BlockAddresses. 14109467b48Spatrick class ARMConstantPoolConstant : public ARMConstantPoolValue { 14209467b48Spatrick const Constant *CVal; // Constant being loaded. 14309467b48Spatrick SmallPtrSet<const GlobalVariable*, 1> GVars; 14409467b48Spatrick 14509467b48Spatrick ARMConstantPoolConstant(const Constant *C, 14609467b48Spatrick unsigned ID, 14709467b48Spatrick ARMCP::ARMCPKind Kind, 14809467b48Spatrick unsigned char PCAdj, 14909467b48Spatrick ARMCP::ARMCPModifier Modifier, 15009467b48Spatrick bool AddCurrentAddress); 15109467b48Spatrick ARMConstantPoolConstant(Type *Ty, const Constant *C, 15209467b48Spatrick unsigned ID, 15309467b48Spatrick ARMCP::ARMCPKind Kind, 15409467b48Spatrick unsigned char PCAdj, 15509467b48Spatrick ARMCP::ARMCPModifier Modifier, 15609467b48Spatrick bool AddCurrentAddress); 15709467b48Spatrick ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init); 15809467b48Spatrick 15909467b48Spatrick public: 16009467b48Spatrick static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 16109467b48Spatrick static ARMConstantPoolConstant *Create(const GlobalValue *GV, 16209467b48Spatrick ARMCP::ARMCPModifier Modifier); 16309467b48Spatrick static ARMConstantPoolConstant *Create(const GlobalVariable *GV, 16409467b48Spatrick const Constant *Initializer); 16509467b48Spatrick static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 16609467b48Spatrick ARMCP::ARMCPKind Kind, 16709467b48Spatrick unsigned char PCAdj); 16809467b48Spatrick static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 16909467b48Spatrick ARMCP::ARMCPKind Kind, 17009467b48Spatrick unsigned char PCAdj, 17109467b48Spatrick ARMCP::ARMCPModifier Modifier, 17209467b48Spatrick bool AddCurrentAddress); 17309467b48Spatrick 17409467b48Spatrick const GlobalValue *getGV() const; 17509467b48Spatrick const BlockAddress *getBlockAddress() const; 17609467b48Spatrick 17709467b48Spatrick using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator; 17809467b48Spatrick promotedGlobals()17909467b48Spatrick iterator_range<promoted_iterator> promotedGlobals() { 18009467b48Spatrick return iterator_range<promoted_iterator>(GVars.begin(), GVars.end()); 18109467b48Spatrick } 18209467b48Spatrick getPromotedGlobalInit()18309467b48Spatrick const Constant *getPromotedGlobalInit() const { 18409467b48Spatrick return CVal; 18509467b48Spatrick } 18609467b48Spatrick 18709467b48Spatrick int getExistingMachineCPValue(MachineConstantPool *CP, 188*097a140dSpatrick Align Alignment) override; 18909467b48Spatrick 19009467b48Spatrick /// hasSameValue - Return true if this ARM constpool value can share the same 19109467b48Spatrick /// constantpool entry as another ARM constpool value. 19209467b48Spatrick bool hasSameValue(ARMConstantPoolValue *ACPV) override; 19309467b48Spatrick 19409467b48Spatrick void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 19509467b48Spatrick 19609467b48Spatrick void print(raw_ostream &O) const override; 19709467b48Spatrick classof(const ARMConstantPoolValue * APV)19809467b48Spatrick static bool classof(const ARMConstantPoolValue *APV) { 19909467b48Spatrick return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() || 20009467b48Spatrick APV->isPromotedGlobal(); 20109467b48Spatrick } 20209467b48Spatrick equals(const ARMConstantPoolConstant * A)20309467b48Spatrick bool equals(const ARMConstantPoolConstant *A) const { 20409467b48Spatrick return CVal == A->CVal && ARMConstantPoolValue::equals(A); 20509467b48Spatrick } 20609467b48Spatrick }; 20709467b48Spatrick 20809467b48Spatrick /// ARMConstantPoolSymbol - ARM-specific constantpool values for external 20909467b48Spatrick /// symbols. 21009467b48Spatrick class ARMConstantPoolSymbol : public ARMConstantPoolValue { 21109467b48Spatrick const std::string S; // ExtSymbol being loaded. 21209467b48Spatrick 21309467b48Spatrick ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id, 21409467b48Spatrick unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 21509467b48Spatrick bool AddCurrentAddress); 21609467b48Spatrick 21709467b48Spatrick public: 21809467b48Spatrick static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID, 21909467b48Spatrick unsigned char PCAdj); 22009467b48Spatrick getSymbol()22109467b48Spatrick StringRef getSymbol() const { return S; } 22209467b48Spatrick 22309467b48Spatrick int getExistingMachineCPValue(MachineConstantPool *CP, 224*097a140dSpatrick Align Alignment) override; 22509467b48Spatrick 22609467b48Spatrick void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 22709467b48Spatrick 22809467b48Spatrick /// hasSameValue - Return true if this ARM constpool value can share the same 22909467b48Spatrick /// constantpool entry as another ARM constpool value. 23009467b48Spatrick bool hasSameValue(ARMConstantPoolValue *ACPV) override; 23109467b48Spatrick 23209467b48Spatrick void print(raw_ostream &O) const override; 23309467b48Spatrick classof(const ARMConstantPoolValue * ACPV)23409467b48Spatrick static bool classof(const ARMConstantPoolValue *ACPV) { 23509467b48Spatrick return ACPV->isExtSymbol(); 23609467b48Spatrick } 23709467b48Spatrick equals(const ARMConstantPoolSymbol * A)23809467b48Spatrick bool equals(const ARMConstantPoolSymbol *A) const { 23909467b48Spatrick return S == A->S && ARMConstantPoolValue::equals(A); 24009467b48Spatrick } 24109467b48Spatrick }; 24209467b48Spatrick 24309467b48Spatrick /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 24409467b48Spatrick /// block. 24509467b48Spatrick class ARMConstantPoolMBB : public ARMConstantPoolValue { 24609467b48Spatrick const MachineBasicBlock *MBB; // Machine basic block. 24709467b48Spatrick 24809467b48Spatrick ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 24909467b48Spatrick unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 25009467b48Spatrick bool AddCurrentAddress); 25109467b48Spatrick 25209467b48Spatrick public: 25309467b48Spatrick static ARMConstantPoolMBB *Create(LLVMContext &C, 25409467b48Spatrick const MachineBasicBlock *mbb, 25509467b48Spatrick unsigned ID, unsigned char PCAdj); 25609467b48Spatrick getMBB()25709467b48Spatrick const MachineBasicBlock *getMBB() const { return MBB; } 25809467b48Spatrick 25909467b48Spatrick int getExistingMachineCPValue(MachineConstantPool *CP, 260*097a140dSpatrick Align Alignment) override; 26109467b48Spatrick 26209467b48Spatrick void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 26309467b48Spatrick 26409467b48Spatrick /// hasSameValue - Return true if this ARM constpool value can share the same 26509467b48Spatrick /// constantpool entry as another ARM constpool value. 26609467b48Spatrick bool hasSameValue(ARMConstantPoolValue *ACPV) override; 26709467b48Spatrick 26809467b48Spatrick void print(raw_ostream &O) const override; 26909467b48Spatrick classof(const ARMConstantPoolValue * ACPV)27009467b48Spatrick static bool classof(const ARMConstantPoolValue *ACPV) { 27109467b48Spatrick return ACPV->isMachineBasicBlock(); 27209467b48Spatrick } 27309467b48Spatrick equals(const ARMConstantPoolMBB * A)27409467b48Spatrick bool equals(const ARMConstantPoolMBB *A) const { 27509467b48Spatrick return MBB == A->MBB && ARMConstantPoolValue::equals(A); 27609467b48Spatrick } 27709467b48Spatrick }; 27809467b48Spatrick 27909467b48Spatrick } // end namespace llvm 28009467b48Spatrick 28109467b48Spatrick #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 282