//===- XtensaConstantPoolValue.h - Xtensa constantpool value ----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the Xtensa specific constantpool value class. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H #define LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include #include #include namespace llvm { class BlockAddress; class Constant; class GlobalValue; class LLVMContext; class MachineBasicBlock; namespace XtensaCP { enum XtensaCPKind { CPExtSymbol, CPBlockAddress, CPMachineBasicBlock, CPJumpTable }; enum XtensaCPModifier { no_modifier, // None TPOFF // Thread Pointer Offset }; } // namespace XtensaCP /// XtensaConstantPoolValue - Xtensa specific constantpool value. This is used /// to represent PC-relative displacement between the address of the load /// instruction and the constant being loaded. class XtensaConstantPoolValue : public MachineConstantPoolValue { unsigned LabelId; // Label id of the load. XtensaCP::XtensaCPKind Kind; // Kind of constant. XtensaCP::XtensaCPModifier Modifier; // Symbol name modifier //(for example Global Variable name) protected: XtensaConstantPoolValue( Type *Ty, unsigned ID, XtensaCP::XtensaCPKind Kind, XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); XtensaConstantPoolValue( LLVMContext &C, unsigned id, XtensaCP::XtensaCPKind Kind, XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); template int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { const std::vector &Constants = CP->getConstants(); for (unsigned i = 0, e = Constants.size(); i != e; ++i) { if (Constants[i].isMachineConstantPoolEntry() && (Constants[i].getAlign() >= Alignment)) { auto *CPV = static_cast( Constants[i].Val.MachineCPVal); if (Derived *APC = dyn_cast(CPV)) if (cast(this)->equals(APC)) return i; } } return -1; } public: ~XtensaConstantPoolValue() override; XtensaCP::XtensaCPModifier getModifier() const { return Modifier; } bool hasModifier() const { return Modifier != XtensaCP::no_modifier; } StringRef getModifierText() const; unsigned getLabelId() const { return LabelId; } void setLabelId(unsigned ID) { LabelId = ID; } bool isExtSymbol() const { return Kind == XtensaCP::CPExtSymbol; } bool isBlockAddress() const { return Kind == XtensaCP::CPBlockAddress; } bool isMachineBasicBlock() const { return Kind == XtensaCP::CPMachineBasicBlock; } bool isJumpTable() const { return Kind == XtensaCP::CPJumpTable; } int getExistingMachineCPValue(MachineConstantPool *CP, Align Alignment) override; void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; /// hasSameValue - Return true if this Xtensa constpool value can share the /// same constantpool entry as another Xtensa constpool value. virtual bool hasSameValue(XtensaConstantPoolValue *ACPV); bool equals(const XtensaConstantPoolValue *A) const { return this->LabelId == A->LabelId && this->Modifier == A->Modifier; } void print(raw_ostream &O) const override; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void dump() const; #endif }; inline raw_ostream &operator<<(raw_ostream &O, const XtensaConstantPoolValue &V) { V.print(O); return O; } /// XtensaConstantPoolConstant - Xtensa-specific constant pool values for /// Constants (for example BlockAddresses). class XtensaConstantPoolConstant : public XtensaConstantPoolValue { const Constant *CVal; // Constant being loaded. XtensaConstantPoolConstant(const Constant *C, unsigned ID, XtensaCP::XtensaCPKind Kind); public: static XtensaConstantPoolConstant *Create(const Constant *C, unsigned ID, XtensaCP::XtensaCPKind Kind); const BlockAddress *getBlockAddress() const; int getExistingMachineCPValue(MachineConstantPool *CP, Align Alignment) override; /// hasSameValue - Return true if this Xtensa constpool value can share the /// same constantpool entry as another Xtensa constpool value. bool hasSameValue(XtensaConstantPoolValue *ACPV) override; void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; void print(raw_ostream &O) const override; static bool classof(const XtensaConstantPoolValue *APV) { return APV->isBlockAddress(); } bool equals(const XtensaConstantPoolConstant *A) const { return CVal == A->CVal && XtensaConstantPoolValue::equals(A); } }; /// XtensaConstantPoolSymbol - Xtensa-specific constantpool values for external /// symbols. class XtensaConstantPoolSymbol : public XtensaConstantPoolValue { const std::string S; // ExtSymbol being loaded. bool PrivateLinkage; XtensaConstantPoolSymbol( LLVMContext &C, const char *S, unsigned Id, bool PrivLinkage, XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); public: static XtensaConstantPoolSymbol * Create(LLVMContext &C, const char *S, unsigned ID, bool PrivLinkage, XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); const char *getSymbol() const { return S.c_str(); } int getExistingMachineCPValue(MachineConstantPool *CP, Align Alignment) override; void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; /// hasSameValue - Return true if this Xtensa constpool value can share the /// same constantpool entry as another Xtensa constpool value. bool hasSameValue(XtensaConstantPoolValue *ACPV) override; bool isPrivateLinkage() { return PrivateLinkage; } void print(raw_ostream &O) const override; static bool classof(const XtensaConstantPoolValue *ACPV) { return ACPV->isExtSymbol(); } bool equals(const XtensaConstantPoolSymbol *A) const { return S == A->S && XtensaConstantPoolValue::equals(A); } }; /// XtensaConstantPoolMBB - Xtensa-specific constantpool value of a machine /// basic block. class XtensaConstantPoolMBB : public XtensaConstantPoolValue { const MachineBasicBlock *MBB; // Machine basic block. XtensaConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *M, unsigned ID); public: static XtensaConstantPoolMBB *Create(LLVMContext &C, const MachineBasicBlock *M, unsigned ID); const MachineBasicBlock *getMBB() const { return MBB; } int getExistingMachineCPValue(MachineConstantPool *CP, Align Alignment) override; void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; /// hasSameValue - Return true if this Xtensa constpool value can share the /// same constantpool entry as another Xtensa constpool value. bool hasSameValue(XtensaConstantPoolValue *ACPV) override; void print(raw_ostream &O) const override; static bool classof(const XtensaConstantPoolValue *ACPV) { return ACPV->isMachineBasicBlock(); } bool equals(const XtensaConstantPoolMBB *A) const { return MBB == A->MBB && XtensaConstantPoolValue::equals(A); } }; /// XtensaConstantPoolJumpTable - Xtensa-specific constantpool values for Jump /// Table symbols. class XtensaConstantPoolJumpTable : public XtensaConstantPoolValue { unsigned Idx; // Jump Table Index. XtensaConstantPoolJumpTable(LLVMContext &C, unsigned Idx); public: static XtensaConstantPoolJumpTable *Create(LLVMContext &C, unsigned Idx); unsigned getIndex() const { return Idx; } int getExistingMachineCPValue(MachineConstantPool *CP, Align Alignment) override; void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; /// hasSameValue - Return true if this Xtensa constpool value can share the /// same constantpool entry as another Xtensa constpool value. bool hasSameValue(XtensaConstantPoolValue *ACPV) override; void print(raw_ostream &O) const override; static bool classof(const XtensaConstantPoolValue *ACPV) { return ACPV->isJumpTable(); } bool equals(const XtensaConstantPoolJumpTable *A) const { return Idx == A->Idx && XtensaConstantPoolValue::equals(A); } }; } // namespace llvm #endif /* LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H */