xref: /openbsd-src/gnu/llvm/llvm/lib/Target/ARM/ARMConstantPoolValue.h (revision 097a140d792de8b2bbe59ad827d39eabf9b4280a)
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