-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[PowerPC][AIX] 64-bit large code-model support for toc-data #90619
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
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-powerpc Author: Zaara Syeda (syzaara) ChangesThis patch adds support for toc-data for 64-bit large code-model. The sequence ADDIStocHA8/ADDItocL8 is used to access the data directly from the TOC. Full diff: https://github.com/llvm/llvm-project/pull/90619.diff 5 Files Affected:
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 51b79dc2b04b4e..14dc4d1249a888 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -1148,21 +1148,21 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
- // If the symbol isn't toc-data then use the TOC on AIX.
+ // If the symbol does not have the toc-data attribute, then we create the
+ // TOC entry on AIX. If the toc-data attribute is used, the TOC entry
+ // contains the data rather than the address of the MOSymbol.
// Map the global address operand to be a reference to the TOC entry we
// will synthesize later. 'TOCEntry' is a label used to reference the
// storage allocated in the TOC which contains the address of 'MOSymbol'.
- // If the toc-data attribute is used, the TOC entry contains the data
- // rather than the address of the MOSymbol.
if ( {
if (!MO.isGlobal())
return false;
- const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal());
- if (!GV)
- return false;
+ if (const GlobalVariable *GV =
+ dyn_cast<GlobalVariable>(MO.getGlobal()))
+ return GV->hasAttribute("toc-data");
- return GV->hasAttribute("toc-data");
+ return false;
}(MO)) {
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
}
@@ -1292,8 +1292,9 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
unsigned Op = MI->getOpcode();
- // Change the opcode to load address for tocdata
- TmpInst.setOpcode(Op == PPC::ADDItocL8 ? PPC::ADDI8 : PPC::LA);
+ // Change the opcode to load address for toc data.
+ unsigned NewOp64 = IsAIX ? PPC::LA8 : PPC::ADDI8;
+ TmpInst.setOpcode(Op == PPC::ADDItocL8 ? NewOp64 : PPC::LA);
const MachineOperand &MO = MI->getOperand(2);
assert((Op == PPC::ADDItocL8)
@@ -1307,8 +1308,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
const MCExpr *Exp = MCSymbolRefExpr::create(
MOSymbol,
- Op == PPC::ADDItocL8 ? MCSymbolRefExpr::VK_PPC_TOC_LO
- : MCSymbolRefExpr::VK_PPC_L,
+ IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO,
OutContext);
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 2f647daa4bcb57..c9b3cb58ca5831 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -6141,24 +6141,23 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
assert((isPPC64 || (isAIXABI && !isPPC64)) && "We are dealing with 64-bit"
" ELF/AIX or 32-bit AIX in the following.");
- // Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode
- // or 64-bit medium (ELF-only) or large (ELF and AIX) code model code non
- // toc-data symbols.
+ // Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode,
+ // 64-bit medium (ELF-only), or large (ELF and AIX) code model code that
+ // does not contain TOC data symbols.
// We generate two instructions as described below. The first source
- // operand is a symbol reference. If it must be toc-referenced according to
- // Subtarget, we generate:
+ // operand is a symbol reference. If it must be referenced via the TOC
+ // according to Subtarget, we generate:
// [32-bit AIX]
// LWZtocL(@sym, ADDIStocHA(%r2, @sym))
// [64-bit ELF/AIX]
// LDtocL(@sym, ADDIStocHA8(%x2, @sym))
// Otherwise we generate:
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
-
- // For large code model toc-data symbols we generate:
+ // For large code model with TOC data symbols we generate:
// [32-bit AIX]
// ADDItocL(ADDIStocHA(%x2, @sym), @sym)
// [64-bit AIX]
- // Currently not supported.
+ // ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
SDValue GA = N->getOperand(0);
SDValue TOCbase = N->getOperand(1);
@@ -6167,16 +6166,12 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
SDNode *Tmp = CurDAG->getMachineNode(
isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
- // On AIX if the symbol has the toc-data attribute it will be defined
- // in the TOC entry, so we use an ADDItocL similar to the medium code
- // model ELF abi.
+ // On AIX, if the symbol has the toc-data attribute it will be defined
+ // in the TOC entry, so we use an ADDItocL/ADDItocL8.
if (isAIXABI && hasTocDataAttr(GA)) {
- if (isPPC64)
- report_fatal_error(
- "64-bit large code model toc-data not yet supported");
-
- ReplaceNode(N, CurDAG->getMachineNode(PPC::ADDItocL, dl, VT,
- SDValue(Tmp, 0), GA));
+ ReplaceNode(
+ N, CurDAG->getMachineNode(isPPC64 ? PPC::ADDItocL8 : PPC::ADDItocL,
+ dl, VT, SDValue(Tmp, 0), GA));
return;
}
@@ -7780,6 +7775,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
Flags = PPCII::MO_TLSLD_LO;
break;
case PPC::ADDItocL8:
+ // Skip the following peephole optimizations for ADDItocL8 on AIX which
+ // is used for toc-data access.
+ if (Subtarget->isAIXABI())
+ continue;
Flags = PPCII::MO_TOC_LO;
break;
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 9e56de732c587e..85bbfabf5d3c91 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -4438,6 +4438,12 @@ bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
if (Opc != PPC::ADDItocL8 && Opc != PPC::ADDI && Opc != PPC::ADDI8)
return false;
+ // Skip the optimization of transformTo[NewImm|Imm]FormFedByAdd for ADDItocL8
+ // on AIX which is used for toc-data access. TODO: Follow up to see if it can
+ // apply for AIX toc-data as well.
+ if (Opc == PPC::ADDItocL8 && Subtarget.isAIX())
+ return false;
+
assert(DefMI.getNumOperands() >= 3 &&
"Add inst must have at least three operands");
RegMO = &DefMI.getOperand(1);
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 7929a781dbda84..e3d6d2f094f2e7 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3346,7 +3346,7 @@ def ADDIStocHA : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentr
"#ADDIStocHA",
[(set i32:$rD,
(PPCtoc_entry i32:$reg, tglobaladdr:$disp))]>;
-// TOC Data Transform AIX
+// TOC Data Transform on AIX
def ADDItoc : PPCEmitTimePseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
"#ADDItoc",
[(set i32:$rD,
diff --git a/llvm/test/CodeGen/PowerPC/toc-data.ll b/llvm/test/CodeGen/PowerPC/toc-data.ll
index 7f7afe76cfcdeb..1a10780954529f 100644
--- a/llvm/test/CodeGen/PowerPC/toc-data.ll
+++ b/llvm/test/CodeGen/PowerPC/toc-data.ll
@@ -16,6 +16,10 @@
; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32LARGE
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32LARGE
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \
+; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64LARGE
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64LARGE
+
; Global variables i and f have the toc-data attribute.
; In the following functions, those writing to or reading from
; variables i and f should use the toc-data access pattern.
@@ -63,6 +67,17 @@ define dso_local void @write_int(i32 signext %in) {
; TEST32LARGE-NEXT: la 4, i[TD]@l(4)
; TEST32LARGE-NEXT: stw 3, 0(4)
+
+; CHECK64LARGE: name: write_int
+; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i
+; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @i
+; CHECK64LARGE-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i)
+
+; TEST64LARGE: .write_int:
+; TEST64LARGE: addis 4, i[TD]@u(2)
+; TEST64LARGE-NEXT: la 4, i[TD]@l(4)
+; TEST64LARGE-NEXT: stw 3, 0(4)
+
define dso_local i64 @read_ll() {
entry:
%0 = load i64, ptr @ll, align 8
@@ -98,6 +113,15 @@ define dso_local i64 @read_ll() {
; TEST32LARGE-NEXT: lwz 3, 0(4)
; TEST32LARGE-NEXT: lwz 4, 4(4)
+; CHECK64LARGE: name: read_ll
+; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @ll
+; CHECK64LARGE: LDtocL @ll, killed %[[SCRATCH1]] :: (load (s64) from got)
+
+; TEST64LARGE: .read_ll:
+; TEST64LARGE: addis 3, L..C0@u(2)
+; TEST64LARGE-NEXT: ld 3, L..C0@l(3)
+; TEST64LARGE-NEXT: ld 3, 0(3)
+
define dso_local float @read_float() {
entry:
%0 = load float, ptr @f, align 4
@@ -134,6 +158,18 @@ define dso_local float @read_float() {
; TEST32LARGE-NEXT: la 3, f[TD]@l(3)
; TEST32LARGE-NEXT: lfs 1, 0(3)
+
+; CHECK64LARGE: name: read_float
+; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @f
+; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @f
+; CHECK64LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f)
+
+
+; TEST64LARGE: .read_float:
+; TEST64LARGE: addis 3, f[TD]@u(2)
+; TEST64LARGE-NEXT: la 3, f[TD]@l(3)
+; TEST64LARGE-NEXT: lfs 1, 0(3)
+
define dso_local void @write_double(double %in) {
entry:
store double %in, ptr @d, align 8
@@ -167,6 +203,15 @@ define dso_local void @write_double(double %in) {
; TEST32LARGE-NEXT: lwz 3, L..C1@l(3)
; TEST32LARGE-NEXT: stfd 1, 0(3)
+; CHECK64LARGE: name: write_double
+; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @d
+; CHECK64LARGE: LDtocL @d, killed %[[SCRATCH1]] :: (load (s64) from got)
+
+; TEST64LARGE: .write_double:
+; TEST64LARGE: addis 3, L..C1@u(2)
+; TEST64LARGE-NEXT: ld 3, L..C1@l(3)
+; TEST64LARGE-NEXT: stfd 1, 0(3)
+
define dso_local nonnull ptr @addr() {
entry:
ret ptr @i
@@ -237,4 +282,26 @@ define dso_local nonnull ptr @addr() {
; TEST32LARGE-NEXT: .globl f[TD]
; TEST32LARGE-NOT: .tc f[TE],f[RW]
+; CHECK64LARGE: name: addr
+; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i
+; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc = ADDItocL8 killed %[[SCRATCH1]], @i
+; CHECK64LARGE-NEXT: $x3 = COPY %[[SCRATCH2]]
+
+; TEST64LARGE: .addr:
+; TEST64LARGE: addis 3, i[TD]@u(2)
+; TEST64LARGE: la 3, i[TD]@l(3)
+
+; TEST64LARGE: .toc
+; TEST64LARGE: .tc ll[TE],ll[RW]
+; TEST64LARGE-NOT: .csect ll[TD]
+; TEST64LARGE: .tc d[TE],d[RW]
+; TEST64LARGE-NOT: .csect d[TD],2
+; TEST64LARGE: .csect i[TD],2
+; TEST64LARGE-NEXT: .globl i[TD]
+; TEST64LARGE-NEXT: .align 2
+; TEST64LARGE-NOT: .tc i[TE],i[RW]
+; TEST64LARGE: .csect f[TD],2
+; TEST64LARGE-NEXT: .globl f[TD]
+; TEST64LARGE-NOT: .tc f[TE],f[RW]
+
attributes #0 = { "toc-data" }
|
It looks this patch is for AIX only? suggest that add AIX in the title and description. |
|
||
return GV->hasAttribute("toc-data"); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the change is NFC ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only ADDIStocHA8/ADDItocL8 are related to 64bit in the patch, I do not think it is a good idea to have a NFC code of ADDIStocHA which is not related to the functionality of the patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can change this in a follow-up NFC patch.
@@ -7780,6 +7775,10 @@ void PPCDAGToDAGISel::PeepholePPC64() { | |||
Flags = PPCII::MO_TLSLD_LO; | |||
break; | |||
case PPC::ADDItocL8: | |||
// Skip the following peephole optimizations for ADDItocL8 on AIX which | |||
// is used for toc-data access. | |||
if (Subtarget->isAIXABI()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curiously , why skip the peephole for the ADDItocL8 in AIX?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a follow on patch for adding this peephole optimization: #76488 since earlier patches related to this were reverted as the code needed some refactoring.
See: https://reviews.llvm.org/D101470 and https://reviews.llvm.org/D155957
// If the symbol isn't toc-data then use the TOC on AIX. | ||
// If the symbol does not have the toc-data attribute, then we create the | ||
// TOC entry on AIX. If the toc-data attribute is used, the TOC entry | ||
// contains the data rather than the address of the MOSymbol. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure whether it is reasonable to change the order the comment.
I am prefer to keep the original order
// Map the global address operand to be a reference to the TOC entry we
// will synthesize later. 'TOCEntry' is a label used to reference the
// storage allocated in the TOC which contains the address of 'MOSymbol'.
// If the symbol does not have the toc-data attribute, then we create the
// TOC entry on AIX. If the toc-data attribute is used, the TOC entry
// contains the data rather than the address of the MOSymbol.
but feel free to keep your comment if you think it is reasonable,
if (TOCDataGloballyinEffect && | ||
(Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("large") || | ||
Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("medium"))) { | ||
D.Diag(clang::diag::warn_drv_unsupported_tocdata); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do the patch also support "medium" ? but in the description of the patch , it is "64-bit large code-model" , and do you want to add medium test case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AIX does not have medium model. when specifying it, it will be mapped to large.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, according to https://reviews.llvm.org/D106371, medium will be large.
// or 64-bit medium (ELF-only) or large (ELF and AIX) code model code non | ||
// toc-data symbols. | ||
// Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode, | ||
// 64-bit medium (ELF-only), or large (ELF and AIX) code model code that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from the comment , Transforms the ISD::TOC_ENTRY only happened in 32-bit AIX large code model mode
and large (ELF and AIX)
, 64-bit medium (ELF-only)
and the patch is for AIX, but we remove the warning of the support of the AIX medium in the AIX.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question about the comment. We say we are transforming for:
- 32-bit large AIX
- 64-bit medium ELF
- large (ELF and AIX)
And then the comment below says:
We generate two instructions as described below. The first source
// operand is a symbol reference. If it must be referenced via the TOC
// according to Subtarget, we generate:
// [32-bit AIX]
// LWZtocL(@sym, ADDIStocHA(%r2, @sym))
// [64-bit ELF/AIX]
// LDtocL(@sym, ADDIStocHA8(%x2, @sym))
// Otherwise we generate:
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
The first two LWZtocL(@sym, ADDIStocHA(%r2, @sym))
and LDtocL(@sym, ADDIStocHA8(%x2, @sym))
should take care of large ELF and AIX, and then ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
handles the 64-bit ELF.
The rest of the comment below it is toc-data related. Is it necessary to still say the for 32-bit AIX large code model mode
part if this is almost encapsulated in the large (ELF and AIX)
part? Or am I misunderstanding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM just some nits. I don't think it needs another review for them from my side.
Please commit when @diggerlin is also happy.
Thanks very much for adding this support.
clang/test/Driver/tocdata-cc1.c
Outdated
@@ -1,16 +1,13 @@ | |||
// RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mcmodel=medium -mtocdata %s 2>&1 \ | |||
// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s | |||
// RUN: | FileCheck -check-prefix=CHECK-TOC %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since all the check prefix are "TOC", maybe we can use the default one, i.e., without setting -check-prefix?
@@ -1292,8 +1291,9 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { | |||
|
|||
unsigned Op = MI->getOpcode(); | |||
|
|||
// Change the opcode to load address for tocdata | |||
TmpInst.setOpcode(Op == PPC::ADDItocL8 ? PPC::ADDI8 : PPC::LA); | |||
// Change the opcode to load address for toc data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe we can also add a comment here saying that for ADDItocL
, it is only used for 32-bit toc data on AIX, so always using LA?
SDValue(Tmp, 0), GA)); | ||
ReplaceNode( | ||
N, CurDAG->getMachineNode(isPPC64 ? PPC::ADDItocL8 : PPC::ADDItocL, | ||
dl, VT, SDValue(Tmp, 0), GA)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I suggest to add an assert like assert(isPPC64 && ...)
before line 6188 which assumes 32-bit linux/aix are already handled, so it uses ADDItocL8
directly.
if (TOCDataGloballyinEffect && | ||
(Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("large") || | ||
Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("medium"))) { | ||
D.Diag(clang::diag::warn_drv_unsupported_tocdata); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AIX does not have medium model. when specifying it, it will be mapped to large.
This patch adds support for toc-data for 64-bit large code-model. The sequence ADDIStocHA8/ADDItocL8 is used to access the data directly from the TOC. When emitting the instruction ADDIStocHA8, we check if the symbol has toc-data attribute before creating a toc entry for it. When emitting the instruction ADDItocL8, we use the LA8 instruction to load the address.
// Change the opcode to load address for tocdata | ||
TmpInst.setOpcode(Op == PPC::ADDItocL8 ? PPC::ADDI8 : PPC::LA); | ||
// Change the opcode to load address for toc data. | ||
unsigned NewOp64 = IsAIX ? PPC::LA8 : PPC::ADDI8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: Roll selecting the new opcode into a single statement rather then selecting what the opcode would be for 64-bit, then deciding too use LA or the 64-bit opcode in 2 different statements?
// operand is a symbol reference. If it must be toc-referenced according to | ||
// Subtarget, we generate: | ||
// operand is a symbol reference. If it must be referenced via the TOC | ||
// according to Subtarget, we generate: | ||
// [32-bit AIX] | ||
// LWZtocL(@sym, ADDIStocHA(%r2, @sym)) | ||
// [64-bit ELF/AIX] | ||
// LDtocL(@sym, ADDIStocHA8(%x2, @sym)) | ||
// Otherwise we generate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Otherwise we generate: | |
// Otherwise for medium code model ELF we generate: |
// [32-bit AIX] | ||
// LWZtocL(@sym, ADDIStocHA(%r2, @sym)) | ||
// [64-bit ELF/AIX] | ||
// LDtocL(@sym, ADDIStocHA8(%x2, @sym)) | ||
// Otherwise we generate: | ||
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym) | ||
|
||
// For large code model toc-data symbols we generate: | ||
// For large code model with TOC data symbols we generate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// For large code model with TOC data symbols we generate: | |
// And finally for AIX with toc-data we generate: |
if (TOCDataGloballyinEffect && | ||
(Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("large") || | ||
Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("medium"))) { | ||
D.Diag(clang::diag::warn_drv_unsupported_tocdata); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, according to https://reviews.llvm.org/D106371, medium will be large.
@@ -1292,8 +1291,9 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { | |||
|
|||
unsigned Op = MI->getOpcode(); | |||
|
|||
// Change the opcode to load address for tocdata | |||
TmpInst.setOpcode(Op == PPC::ADDItocL8 ? PPC::ADDI8 : PPC::LA); | |||
// Change the opcode to load address for toc data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another nit: maybe toc-data
instead of toc data
for consistency with other comments.
// or 64-bit medium (ELF-only) or large (ELF and AIX) code model code non | ||
// toc-data symbols. | ||
// Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode, | ||
// 64-bit medium (ELF-only), or large (ELF and AIX) code model code that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question about the comment. We say we are transforming for:
- 32-bit large AIX
- 64-bit medium ELF
- large (ELF and AIX)
And then the comment below says:
We generate two instructions as described below. The first source
// operand is a symbol reference. If it must be referenced via the TOC
// according to Subtarget, we generate:
// [32-bit AIX]
// LWZtocL(@sym, ADDIStocHA(%r2, @sym))
// [64-bit ELF/AIX]
// LDtocL(@sym, ADDIStocHA8(%x2, @sym))
// Otherwise we generate:
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
The first two LWZtocL(@sym, ADDIStocHA(%r2, @sym))
and LDtocL(@sym, ADDIStocHA8(%x2, @sym))
should take care of large ELF and AIX, and then ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
handles the 64-bit ELF.
The rest of the comment below it is toc-data related. Is it necessary to still say the for 32-bit AIX large code model mode
part if this is almost encapsulated in the large (ELF and AIX)
part? Or am I misunderstanding?
0decd75
to
45550b5
Compare
@@ -6143,23 +6143,23 @@ void PPCDAGToDAGISel::Select(SDNode *N) { | |||
" ELF/AIX or 32-bit AIX in the following."); | |||
|
|||
// Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode, | |||
// or 64-bit medium (ELF-only), or large (ELF and AIX) code model code that | |||
// does not conain TOC data symbols. | |||
// 64-bit medium (ELF-only), or large (ELF and AIX) code model code that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this offline. I was just misunderstanding the comment and read it wrong so the above can be disregarded. I think adding the 64-bit
before large would be helpful, though.
// 64-bit medium (ELF-only), or large (ELF and AIX) code model code that | |
// 64-bit medium (ELF-only), or 64-bit large (ELF and AIX) code model code that |
This patch adds support for toc-data for 64-bit large code-model on AIX. The sequence ADDIStocHA8/ADDItocL8 is used to access the data directly from the TOC.
When emitting the instruction ADDIStocHA8, we check if the symbol has toc-data attribute before creating a toc entry for it. When emitting the instruction ADDItocL8, we use the LA8 instruction to load the address.