Skip to content

[PowerPC] redesign the target flags #69695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 46 additions & 26 deletions llvm/lib/Target/PowerPC/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,79 +102,99 @@ class ModulePass;
// PPC Specific MachineOperand flags.
MO_NO_FLAG,

/// On PPC, the 12 bits are not enough for all target operand flags.
/// Treat all PPC target flags as direct flags. To define new flag that is
/// combination of other flags, add new enum entry instead of combining
/// existing flags. See example MO_GOT_TPREL_PCREL_FLAG.

/// On a symbol operand "FOO", this indicates that the reference is actually
/// to "FOO@plt". This is used for calls and jumps to external functions
/// and for PIC calls on 32-bit ELF systems.
MO_PLT = 1,
MO_PLT,

/// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to
/// the function's picbase, e.g. lo16(symbol-picbase).
MO_PIC_FLAG = 2,
MO_PIC_FLAG,

/// MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to
/// the current instruction address(pc), e.g., var@pcrel. Fixup is VK_PCREL.
MO_PCREL_FLAG = 4,
MO_PCREL_FLAG,

/// MO_GOT_FLAG - If this bit is set the symbol reference is to be computed
/// via the GOT. For example when combined with the MO_PCREL_FLAG it should
/// produce the relocation @got@pcrel. Fixup is VK_PPC_GOT_PCREL.
MO_GOT_FLAG = 8,
MO_GOT_FLAG,

// MO_PCREL_OPT_FLAG - If this bit is set the operand is part of a
// PC Relative linker optimization.
MO_PCREL_OPT_FLAG = 16,
/// MO_PCREL_OPT_FLAG - If this bit is set the operand is part of a
/// PC Relative linker optimization.
MO_PCREL_OPT_FLAG,

/// MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to
/// TLS General Dynamic model for Linux and the variable offset of TLS
/// General Dynamic model for AIX.
MO_TLSGD_FLAG = 32,
MO_TLSGD_FLAG,

/// MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to
/// the thread pointer and the symbol can be used for the TLS Initial Exec
/// and Local Exec models.
MO_TPREL_FLAG = 64,
MO_TPREL_FLAG,

/// MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to
/// TLS Local Dynamic model.
MO_TLSLD_FLAG = 128,
MO_TLSLD_FLAG,

/// MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative
/// to the region handle of TLS General Dynamic model for AIX.
MO_TLSGDM_FLAG = 256,
MO_TLSGDM_FLAG,

/// MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set
/// they should produce the relocation @got@tlsgd@pcrel.
/// Fix up is VK_PPC_GOT_TLSGD_PCREL
MO_GOT_TLSGD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSGD_FLAG,
/// MO_GOT_TLSGD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSGD_FLAG,
MO_GOT_TLSGD_PCREL_FLAG,

/// MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set
/// they should produce the relocation @got@tlsld@pcrel.
/// Fix up is VK_PPC_GOT_TLSLD_PCREL
MO_GOT_TLSLD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSLD_FLAG,
/// MO_GOT_TLSLD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSLD_FLAG,
MO_GOT_TLSLD_PCREL_FLAG,

/// MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set
/// they should produce the relocation @got@tprel@pcrel.
/// Fix up is VK_PPC_GOT_TPREL_PCREL
MO_GOT_TPREL_PCREL_FLAG = MO_GOT_FLAG | MO_TPREL_FLAG | MO_PCREL_FLAG,

/// The next are not flags but distinct values.
MO_ACCESS_MASK = 0xf00,
/// MO_GOT_TPREL_PCREL_FLAG = MO_GOT_FLAG | MO_TPREL_FLAG | MO_PCREL_FLAG,
MO_GOT_TPREL_PCREL_FLAG,

/// MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
MO_LO = 1 << 8,
MO_HA = 2 << 8,
MO_LO,
MO_HA,

MO_TPREL_LO = 4 << 8,
MO_TPREL_HA = 3 << 8,
MO_TPREL_LO,
MO_TPREL_HA,

/// These values identify relocations on immediates folded
/// into memory operations.
MO_DTPREL_LO = 5 << 8,
MO_TLSLD_LO = 6 << 8,
MO_TOC_LO = 7 << 8,
MO_DTPREL_LO,
MO_TLSLD_LO,
MO_TOC_LO,

/// Symbol for VK_PPC_TLS fixup attached to an ADD instruction
MO_TLS,

/// MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA
Copy link
Collaborator

@bzEq bzEq Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment looks confusing, since they were previously mask ORed but now are not. Can you please provide full description?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding comments for each mask that are combination of other maks, I added a comment in the very begining about how to add a new mask.

MO_PIC_HA_FLAG,

/// MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO
MO_PIC_LO_FLAG,

/// MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG
MO_TPREL_PCREL_FLAG,

/// MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS
MO_TLS_PCREL_FLAG,

// Symbol for VK_PPC_TLS fixup attached to an ADD instruction
MO_TLS = 8 << 8
/// MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG
MO_GOT_PCREL_FLAG,
};
} // end namespace PPCII

Expand Down
31 changes: 11 additions & 20 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,25 +715,11 @@ static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
}
}

static bool hasTLSFlag(const MachineOperand &MO) {
unsigned Flags = MO.getTargetFlags();
if (Flags & PPCII::MO_TLSGD_FLAG || Flags & PPCII::MO_TPREL_FLAG ||
Flags & PPCII::MO_TLSLD_FLAG || Flags & PPCII::MO_TLSGDM_FLAG)
return true;

if (Flags == PPCII::MO_TPREL_LO || Flags == PPCII::MO_TPREL_HA ||
Flags == PPCII::MO_DTPREL_LO || Flags == PPCII::MO_TLSLD_LO ||
Flags == PPCII::MO_TLS)
return true;

return false;
}

static PPCAsmPrinter::TOCEntryType
getTOCEntryTypeForMO(const MachineOperand &MO) {
// Use the target flags to determine if this MO is Thread Local.
// If we don't do this it comes out as Global.
if (hasTLSFlag(MO))
if (PPCInstrInfo::hasTLSFlag(MO.getTargetFlags()))
return PPCAsmPrinter::TOCType_ThreadLocal;

switch (MO.getType()) {
Expand Down Expand Up @@ -830,7 +816,10 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
// For TLS initial-exec and local-exec accesses on AIX, we have one TOC
// entry for the symbol (with the variable offset), which is differentiated
// by MO_TPREL_FLAG.
if (MO.getTargetFlags() & PPCII::MO_TPREL_FLAG) {
unsigned Flag = MO.getTargetFlags();
if (Flag == PPCII::MO_TPREL_FLAG ||
Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
Flag == PPCII::MO_TPREL_PCREL_FLAG) {
assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n");
TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());
if (Model == TLSModel::LocalExec)
Expand All @@ -842,9 +831,9 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
// For GD TLS access on AIX, we have two TOC entries for the symbol (one for
// the variable offset and the other for the region handle). They are
// differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
if (MO.getTargetFlags() & PPCII::MO_TLSGDM_FLAG)
if (Flag == PPCII::MO_TLSGDM_FLAG)
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
if (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG)
if (Flag == PPCII::MO_TLSGD_FLAG || Flag == PPCII::MO_GOT_TLSGD_PCREL_FLAG)
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
return MCSymbolRefExpr::VariantKind::VK_None;
};
Expand Down Expand Up @@ -1538,8 +1527,10 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
// The faster non-TOC-based local-exec sequence is represented by `addi`
// with an immediate operand having the MO_TPREL_FLAG. Such an instruction
// does not otherwise arise.
const MachineOperand &MO = MI->getOperand(2);
if ((MO.getTargetFlags() & PPCII::MO_TPREL_FLAG) != 0) {
unsigned Flag = MI->getOperand(2).getTargetFlags();
if (Flag == PPCII::MO_TPREL_FLAG ||
Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
Flag == PPCII::MO_TPREL_PCREL_FLAG) {
assert(
Subtarget->hasAIXSmallLocalExecTLS() &&
"addi with thread-pointer only expected with local-exec small TLS");
Expand Down
16 changes: 7 additions & 9 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2971,7 +2971,7 @@ bool PPCTargetLowering::SelectAddressRegRegOnly(SDValue N, SDValue &Base,

template <typename Ty> static bool isValidPCRelNode(SDValue N) {
Ty *PCRelCand = dyn_cast<Ty>(N);
return PCRelCand && (PCRelCand->getTargetFlags() & PPCII::MO_PCREL_FLAG);
return PCRelCand && (PPCInstrInfo::hasPCRelFlag(PCRelCand->getTargetFlags()));
}

/// Returns true if this address is a PC Relative address.
Expand Down Expand Up @@ -3132,8 +3132,8 @@ static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget,

// Don't use the pic base if not in PIC relocation model.
if (IsPIC) {
HiOpFlags |= PPCII::MO_PIC_FLAG;
LoOpFlags |= PPCII::MO_PIC_FLAG;
HiOpFlags = PPCII::MO_PIC_HA_FLAG;
LoOpFlags = PPCII::MO_PIC_LO_FLAG;
}
}

Expand Down Expand Up @@ -3452,8 +3452,8 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressLinux(SDValue Op,
if (Model == TLSModel::LocalExec) {
if (Subtarget.isUsingPCRelativeCalls()) {
SDValue TLSReg = DAG.getRegister(PPC::X13, MVT::i64);
SDValue TGA = DAG.getTargetGlobalAddress(
GV, dl, PtrVT, 0, (PPCII::MO_PCREL_FLAG | PPCII::MO_TPREL_FLAG));
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
PPCII::MO_TPREL_PCREL_FLAG);
SDValue MatAddr =
DAG.getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
Expand All @@ -3475,8 +3475,7 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressLinux(SDValue Op,
SDValue TGA = DAG.getTargetGlobalAddress(
GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_GOT_TPREL_PCREL_FLAG : 0);
SDValue TGATLS = DAG.getTargetGlobalAddress(
GV, dl, PtrVT, 0,
IsPCRel ? (PPCII::MO_TLS | PPCII::MO_PCREL_FLAG) : PPCII::MO_TLS);
GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_TLS_PCREL_FLAG : PPCII::MO_TLS);
SDValue TPOffset;
if (IsPCRel) {
SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
Expand Down Expand Up @@ -3572,8 +3571,7 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
EVT Ty = getPointerTy(DAG.getDataLayout());
if (isAccessedAsGotIndirect(Op)) {
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty, GSDN->getOffset(),
PPCII::MO_PCREL_FLAG |
PPCII::MO_GOT_FLAG);
PPCII::MO_GOT_PCREL_FLAG);
SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
SDValue Load = DAG.getLoad(MVT::i64, DL, DAG.getEntryNode(), MatPCRel,
MachinePointerInfo());
Expand Down
37 changes: 18 additions & 19 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2973,27 +2973,12 @@ unsigned PPCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {

std::pair<unsigned, unsigned>
PPCInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
const unsigned Mask = PPCII::MO_ACCESS_MASK;
return std::make_pair(TF & Mask, TF & ~Mask);
// PPC always uses a direct mask.
return std::make_pair(TF, 0u);
}

ArrayRef<std::pair<unsigned, const char *>>
PPCInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
using namespace PPCII;
static const std::pair<unsigned, const char *> TargetFlags[] = {
{MO_LO, "ppc-lo"},
{MO_HA, "ppc-ha"},
{MO_TPREL_LO, "ppc-tprel-lo"},
{MO_TPREL_HA, "ppc-tprel-ha"},
{MO_DTPREL_LO, "ppc-dtprel-lo"},
{MO_TLSLD_LO, "ppc-tlsld-lo"},
{MO_TOC_LO, "ppc-toc-lo"},
{MO_TLS, "ppc-tls"}};
return ArrayRef(TargetFlags);
}

ArrayRef<std::pair<unsigned, const char *>>
PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
using namespace PPCII;
static const std::pair<unsigned, const char *> TargetFlags[] = {
{MO_PLT, "ppc-plt"},
Expand All @@ -3002,12 +2987,26 @@ PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
{MO_GOT_FLAG, "ppc-got"},
{MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
{MO_TLSGD_FLAG, "ppc-tlsgd"},
{MO_TLSLD_FLAG, "ppc-tlsld"},
{MO_TPREL_FLAG, "ppc-tprel"},
{MO_TLSLD_FLAG, "ppc-tlsld"},
{MO_TLSGDM_FLAG, "ppc-tlsgdm"},
{MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
{MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
{MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};
{MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"},
{MO_LO, "ppc-lo"},
{MO_HA, "ppc-ha"},
{MO_TPREL_LO, "ppc-tprel-lo"},
{MO_TPREL_HA, "ppc-tprel-ha"},
{MO_DTPREL_LO, "ppc-dtprel-lo"},
{MO_TLSLD_LO, "ppc-tlsld-lo"},
{MO_TOC_LO, "ppc-toc-lo"},
{MO_TLS, "ppc-tls"},
{MO_PIC_HA_FLAG, "ppc-ha-pic"},
{MO_PIC_LO_FLAG, "ppc-lo-pic"},
{MO_TPREL_PCREL_FLAG, "ppc-tprel-pcrel"},
{MO_TLS_PCREL_FLAG, "ppc-tls-pcrel"},
{MO_GOT_PCREL_FLAG, "ppc-got-pcrel"},
};
return ArrayRef(TargetFlags);
}

Expand Down
30 changes: 27 additions & 3 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVM_LIB_TARGET_POWERPC_PPCINSTRINFO_H

#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "PPC.h"
#include "PPCRegisterInfo.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
Expand Down Expand Up @@ -283,6 +284,32 @@ class PPCInstrInfo : public PPCGenInstrInfo {
return false;
}

static bool hasPCRelFlag(unsigned TF) {
return TF == PPCII::MO_PCREL_FLAG || TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
TF == PPCII::MO_TPREL_PCREL_FLAG || TF == PPCII::MO_TLS_PCREL_FLAG ||
TF == PPCII::MO_GOT_PCREL_FLAG;
}

static bool hasGOTFlag(unsigned TF) {
return TF == PPCII::MO_GOT_FLAG || TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
TF == PPCII::MO_GOT_PCREL_FLAG;
}

static bool hasTLSFlag(unsigned TF) {
return TF == PPCII::MO_TLSGD_FLAG || TF == PPCII::MO_TPREL_FLAG ||
TF == PPCII::MO_TLSLD_FLAG || TF == PPCII::MO_TLSGDM_FLAG ||
TF == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TLSLD_PCREL_FLAG ||
TF == PPCII::MO_GOT_TPREL_PCREL_FLAG || TF == PPCII::MO_TPREL_LO ||
TF == PPCII::MO_TPREL_HA || TF == PPCII::MO_DTPREL_LO ||
TF == PPCII::MO_TLSLD_LO || TF == PPCII::MO_TLS ||
TF == PPCII::MO_TPREL_PCREL_FLAG || TF == PPCII::MO_TLS_PCREL_FLAG;
}

ScheduleHazardRecognizer *
CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
const ScheduleDAG *DAG) const override;
Expand Down Expand Up @@ -555,9 +582,6 @@ class PPCInstrInfo : public PPCGenInstrInfo {
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;

ArrayRef<std::pair<unsigned, const char *>>
getSerializableBitmaskMachineOperandTargetFlags() const override;

// Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction.
bool expandVSXMemPseudo(MachineInstr &MI) const;

Expand Down
Loading