llvm-project/llvm/lib/Target/CSKY/CSKYConstantPoolValue.h
Zi Xuan Wu 8ddc816929 [CSKY] Lower leaf DAG node such as global symbol, frame address and jumptable, etc.
Lower global symbols such as call/external symbol.
Lower other leaf DAG node such as frame address/block address/jumptable/vastart.

Normally some leaf symbols need reside in constant pool as ABI prefers, and are addressed by
lrw or jsri instructions.

Every symbol in constant pool is lowered with one entry in target constant pool. The
entry has different type corresponding to different leaf node such as blockaddress,
jumptable, or global value.
2022-01-10 14:35:07 +08:00

222 lines
7.5 KiB
C++

//===-- CSKYConstantPoolValue.h - CSKY 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 CSKY specific constantpool value class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H
#define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstddef>
namespace llvm {
class BlockAddress;
class Constant;
class GlobalValue;
class LLVMContext;
class MachineBasicBlock;
namespace CSKYCP {
enum CSKYCPKind {
CPValue,
CPExtSymbol,
CPBlockAddress,
CPMachineBasicBlock,
CPJT
};
enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD };
} // namespace CSKYCP
/// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to
/// represent PC-relative displacement between the address of the load
/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
class CSKYConstantPoolValue : public MachineConstantPoolValue {
protected:
CSKYCP::CSKYCPKind Kind; // Kind of constant.
unsigned PCAdjust; // Extra adjustment if constantpool is pc-relative.
CSKYCP::CSKYCPModifier Modifier; // GV modifier
bool AddCurrentAddress;
unsigned LabelId = 0;
CSKYConstantPoolValue(Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress,
unsigned ID = 0);
public:
const char *getModifierText() const;
unsigned getPCAdjustment() const { return PCAdjust; }
bool mustAddCurrentAddress() const { return AddCurrentAddress; }
CSKYCP::CSKYCPModifier getModifier() const { return Modifier; }
unsigned getLabelID() const { return LabelId; }
bool isGlobalValue() const { return Kind == CSKYCP::CPValue; }
bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; }
bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; }
bool isMachineBasicBlock() const {
return Kind == CSKYCP::CPMachineBasicBlock;
}
bool isJT() const { return Kind == CSKYCP::CPJT; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
void print(raw_ostream &O) const override;
bool equals(const CSKYConstantPoolValue *A) const {
return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust &&
this->Modifier == A->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<CSKYConstantPoolValue *>(Constants[i].Val.MachineCPVal);
if (Derived *APC = dyn_cast<Derived>(CPV))
if (cast<Derived>(this)->equals(APC))
return i;
}
}
return -1;
}
};
/// CSKY-specific constant pool values for Constants,
/// Functions, and BlockAddresses.
class CSKYConstantPoolConstant : public CSKYConstantPoolValue {
const Constant *CVal; // Constant being loaded.
CSKYConstantPoolConstant(const Constant *C, CSKYCP::CSKYCPKind Kind,
unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier,
bool AddCurrentAddress, unsigned ID);
public:
static CSKYConstantPoolConstant *
Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress,
unsigned ID = 0);
const GlobalValue *getGV() const;
const BlockAddress *getBlockAddress() const;
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
void print(raw_ostream &O) const override;
bool equals(const CSKYConstantPoolConstant *A) const {
return CVal == A->CVal && CSKYConstantPoolValue::equals(A);
}
static bool classof(const CSKYConstantPoolValue *APV) {
return APV->isGlobalValue() || APV->isBlockAddress();
}
};
/// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external
/// symbols.
class CSKYConstantPoolSymbol : public CSKYConstantPoolValue {
const std::string S; // ExtSymbol being loaded.
CSKYConstantPoolSymbol(Type *Ty, const char *S, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier,
bool AddCurrentAddress);
public:
static CSKYConstantPoolSymbol *Create(Type *Ty, const char *S,
unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier);
StringRef getSymbol() const { return S; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
void print(raw_ostream &O) const override;
bool equals(const CSKYConstantPoolSymbol *A) const {
return S == A->S && CSKYConstantPoolValue::equals(A);
}
static bool classof(const CSKYConstantPoolValue *ACPV) {
return ACPV->isExtSymbol();
}
};
/// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic
/// block.
class CSKYConstantPoolMBB : public CSKYConstantPoolValue {
const MachineBasicBlock *MBB; // Machine basic block.
CSKYConstantPoolMBB(Type *Ty, const MachineBasicBlock *Mbb, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress);
public:
static CSKYConstantPoolMBB *Create(Type *Ty, const MachineBasicBlock *Mbb,
unsigned PCAdjust);
const MachineBasicBlock *getMBB() const { return MBB; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
void print(raw_ostream &O) const override;
bool equals(const CSKYConstantPoolMBB *A) const {
return MBB == A->MBB && CSKYConstantPoolValue::equals(A);
}
static bool classof(const CSKYConstantPoolValue *ACPV) {
return ACPV->isMachineBasicBlock();
}
};
/// CSKY-specific constantpool value of a jump table.
class CSKYConstantPoolJT : public CSKYConstantPoolValue {
signed JTI; // Machine basic block.
CSKYConstantPoolJT(Type *Ty, int JTIndex, unsigned PCAdj,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress);
public:
static CSKYConstantPoolJT *Create(Type *Ty, int JTI, unsigned PCAdj,
CSKYCP::CSKYCPModifier Modifier);
signed getJTI() { return JTI; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
void print(raw_ostream &O) const override;
bool equals(const CSKYConstantPoolJT *A) const {
return JTI == A->JTI && CSKYConstantPoolValue::equals(A);
}
static bool classof(const CSKYConstantPoolValue *ACPV) {
return ACPV->isJT();
}
};
} // namespace llvm
#endif