-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[AIX] Support per global code model. #79202
Conversation
return ModuleModel; | ||
|
||
std::optional<CodeModel::Model> MaybeCodeModel = | ||
dyn_cast<GlobalVariable>(GV)->getCodeModel(); |
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.
dyn_cast maybe return a nullptr, do we need to check dyn_cast(GV) not nullptr here ?
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 have an early return on !isa<GlobalVariable>(GV))
so we know dyn_cast must not fail - and because of that I should be using cast<> instead. I'll update it.
return; | ||
|
||
const GlobalVariable *GVar = cast<GlobalVariable>(GV); | ||
std::optional<CodeModel::Model> MaybeCM = GVar->getCodeModel(); |
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: do not need to introduce a new variable GVar, since it only be used once
case MachineOperand::MO_GlobalAddress: { | ||
const GlobalValue *GV = MO.getGlobal(); | ||
MCSymbol *Sym = AP.getSymbol(GV); | ||
checkPerGlobalCodeModel(GV, Sym); |
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 a good place to checkPerGlobalCodeModel in the getMCSymbolForTOCPseudoMO , This means that an MCSymbolXCOFF may end up setting PerSymbolCodeModel
several times, depending on how many times the GV is used as an operand
how about to do it in
bool PPCAIXAsmPrinter::doInitiation() {
.....
for (const auto &G : M.globals()) {
..
MCSymbol *Sym = getSymbol(&G);
checkPerGlobalCodeModel(%G, Sym)
}
return; | ||
|
||
static std::optional<CodeModel::Model> | ||
hasPerGlobalCodeModel(const GlobalValue *GV) { |
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 , the functionality looks like to get the CodeModel::Model , change the function name to getPerGlobalCodeModel
; CHECK-SMALL32: lwz [[SCRATCH:[0-9]+]], L..C[[TL_F:[0-9]+]](2) | ||
; CHECK-LARGE64: ld [[SCRATCH:[0-9]+]], L..C[[TL_F]]@l([[HI]]) | ||
; CHECK-SMALL64: ld [[SCRATCH:[0-9]+]], L..C[[TL_F:[0-9]+]](2) | ||
; CHECK: lwz 3, 0([[SCRATCH]]) |
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.
since the only different of 32bit and 64 bit is lwz
and ld
for example:
CHECK-LARGE32: lwz [[SCRATCH:[0-9]+]], L..C[[TL_F]]@l([[HI]])
CHECK-LARGE64: ld [[SCRATCH:[0-9]+]], L..C[[TL_F]]@l([[HI]])
I will change like as following to make the test case simple.
RUN: %s | FileCheck --check-prefixes=CHECK,CHECK32,CHECK-LARGE,CHECK-LARGE32
to
RUN: %s | FileCheck -DINSTR=lwz
--check-prefixes=CHECK,CHECK32,CHECK-LARGE
CHECK-LARGE: [[INSTR]]
[[SCRATCH:[0-9]+]], L..C[[TL_F]]@l([[HI]]
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 like the suggestion in that it simplifies the number of check prefixes we have, but then it also buries some of the details behind the macro. I was looking at the difference in the toc peephole patch (since the testing there seems to have gone from using the macro to now using it) and personally prefer having the extra check but easier to read output - mainly because we are already impacting the readability by having to have match variables for the labels in the TOC. If you feel really strongly let me know and I will change it over to your suggestion.
} | ||
; CHECK: addis [[HI:[0-9]+]], L..C[[TL_D]]@u(2) | ||
; CHECK32: lwz 3, L..C[[TL_D]]@l([[HI]]) | ||
; CHECK64: ld 3, L..C[[TL_D]]@l([[HI]]) |
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.
ditto, we can use -DINSTR=lwz or -DINSTR=ld
; CHECK-LARGE32: lwz [[SCRATCH:[0-9]+]], L..C[[TL_E]]@l([[HI]]) | ||
; CHECK-SMALL32: lwz [[SCRATCH:[0-9]+]], L..C[[TL_E:[0-9]+]](2) | ||
; CHECK-LARGE64: ld [[SCRATCH:[0-9]+]], L..C[[TL_E]]@l([[HI]]) | ||
; CHECK-SMALL64: ld [[SCRATCH:[0-9]+]], L..C[[TL_E:[0-9]+]](2) |
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.
ditto as below comment.
const TargetMachine &TM) { | ||
const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(Sym); | ||
// Use large code model toc entries for ehinfo symbols as they are | ||
// never refrenced directly. The runtime loads their TOC entries |
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: refrenced -> referenced
const TargetMachine &TM) { | ||
const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(Sym); | ||
// Use large code model toc entries for ehinfo symbols as they are | ||
// never refrenced directly. The runtime loads their TOC entries |
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: their TOC entries address -> their TOC entry addresses
const TargetMachine &TM, | ||
const MachineOperand &MO) { | ||
CodeModel::Model ModuleModel = TM.getCodeModel(); | ||
// Per global code model is only support on 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.
nit: only support -> only supported
@@ -176,6 +176,15 @@ bool PPCSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const { | |||
// Large code model always uses the TOC even for local symbols. | |||
if (TM.getCodeModel() == CodeModel::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.
What happens if the TM.getCodeModel is large, but the specific GV is set to small?
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.
This was a really good question. I think originally I added this because it was triggering an assertion in the PPCAsmPrinter when we would emit the large code model nodes when the module code model was small. In reality both small and large code model use an indirect. That is true for both XCOFF and ELF - ELF has medium code model where we accessing things toc-relative instead of got indirect. I changed the AIX code to check for the toc-data attribute, since that is the only time a symbol would not be indirected on AIX.
The existing code is slightly wrong in that we should be returning true for both small and large code model, but because of where (and how) this function is used that change will be untestable. We can update it in a separate NFC patch to make it correct at least, and when we add support for per global code model for ELF then it would be come testable.
3dbf6c9
to
9e5eb9a
Compare
rebased and force pushed as there were conflicting changes that had landed since this PR was first posted. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
@@ -186,9 +186,18 @@ bool PPCSubtarget::enableSubRegLiveness() const { | |||
} | |||
|
|||
bool PPCSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const { | |||
if (isAIXABI() && isa<GlobalVariable>(GV)) { | |||
// On AIX the only symbols that aren't indirect are toc-data. | |||
if (cast<GlobalVariable>(GV)->hasAttribute("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: According to https://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates, we should try not to use isa<>
followed by <cast>
?
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.
updated to use dyn_cast
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.
At first glance, the code diff is larger than what I thought. I original thought we just need a small change to fix the code generation for per global code model in ISEL-DAG phase.
But seems to keep the optimization of keeping large code model symbols with TE
SMC, most of the code changes are for recording code model for a XCOFF symbol because there is no direct mapping between MCSymbolXCOFF
and GlobalVariable
. I cannot find a better way to avoid these codes either...
case MachineOperand::MO_GlobalAddress: | ||
return AP.getSymbol(MO.getGlobal()); | ||
case MachineOperand::MO_GlobalAddress: { | ||
const GlobalValue *GV = MO.getGlobal(); |
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.
This seems unnecessary?
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 put other two small comment. I do not have further comment on the patch, please address zhengchen's comment and wait for zhengchen happy with the PR.
return CM; | ||
} | ||
|
||
return ModuleModel; |
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 : we can change the code from line 574 ~591 to (I do not have strong suggestion on the change, feel free to keep your code if you want)
if (auto *GValue = dyn_cast<GlobalAddressSDNode>(Node->getOperand(0)){
if(auto *GVar = dyn_cast<GlobalVariable>(GV)){
std::optional<CodeModel::Model> MaybeCodeModel =GV->getCodeModel();
if (MaybeCodeModel) {
CodeModel::Model CM = *MaybeCodeModel;
assert((CM == CodeModel::Small || CM == CodeModel::Large) &&
"invalid code model for AIX");
return CM;
}
}
}
return ModuleModel;
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 too. Thanks for making the improvement.
3fd3217
to
701e485
Compare
Exploit the per global code model attribute on AIX. On AIX we need to update both the code sequence used to access the global (either 1 or 2 instructions for small and large code model respectively) and the storage mapping class that we emit the toc entry.
- convert assert to early return. - change dyn_cast<> following an isa<> to a cast<> - remove a null check after a cast<>
- Change setting per global code model on MCSymbol to the ASMPrinters initialization so it happens once. - Add some globals without explicit code models to the lit test.
- Fixed some spelling mistakes in comments. - renamed function that retreives the per global code model. - updated the AIX specific code in isGVIndirectSymbol.
Co-authored-by: Amy Kwan <akwan0907@gmail.com>
Co-authored-by: Amy Kwan <akwan0907@gmail.com>
- use dyn_cast instad of isa + cast - remove erroneously added newline in otherwise untouched code.
- Added support for looking through aliases to the aliasees objects code model, along with lit testing. - Split the shared code of 'getCodeModel' into PPCSubtarget and have PPCISelDAGToDAG and PPCAsmPrinter use that. - Undo unintended change to 'getMCSymbolForTOCPsudoMO' that was left when addressing earlier comments.
701e485
to
a77ce54
Compare
Exploit the per global code model attribute on AIX. On AIX we need to update both the code sequence used to access the global (either 1 or 2 instructions for small and large code model respectively) and the storage mapping class that we emit the toc entry.