//===- 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 <cstddef>
#include <string>
#include <vector>
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 <typename Derived>
int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
const std::vector<MachineConstantPoolEntry> &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<XtensaConstantPoolValue *>(
Constants[i].Val.MachineCPVal);
if (Derived *APC = dyn_cast<Derived>(CPV))
if (cast<Derived>(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 */