================ @@ -145,9 +164,89 @@ namespace { .addImm(0); if (IsAIX) { - // The variable offset and region handle are copied in r4 and r3. The - // copies are followed by GETtlsADDR32AIX/GETtlsADDR64AIX. - if (!IsTLSTPRelMI) { + if (IsTLSLDAIXMI) { + // The relative order between the LoadOffset@toc node, and the + // .__tls_get_mod node is being tuned here. It is better to put the + // LoadOffset@toc node after the call, since the LoadOffset@toc node + // can use clobbers r4/r5. Search for the pattern of two Load@toc + // nodes, and then move the LoadOffset@toc node right before the + // node that uses the OutReg of the .__tls_get_mod node. + unsigned LDTocOp = + Is64Bit ? (IsLargeModel ? PPC::LDtocL : PPC::LDtoc) + : (IsLargeModel ? PPC::LWZtocL : PPC::LWZtoc); + if (!RegInfo.use_empty(OutReg)) { + std::set<MachineInstr *> Uses; + // Collect all instructions that use the OutReg. + for (MachineOperand &MO : RegInfo.use_operands(OutReg)) + Uses.insert(MO.getParent()); + // Find the first user (e.g.: lwax/stfdx) within the current BB. + MachineBasicBlock::iterator UseIter = MBB.begin(); + for (MachineBasicBlock::iterator IE = MBB.end(); UseIter != IE; + ++UseIter) + if (Uses.count(&*UseIter)) + break; + + // Got some work to do when UseIter pointing to valid node. Check + // the pattern and do the movement if match. + if (UseIter != MBB.end()) { + // Collect associated Load@toc nodes. Use hasOneDef to guard + // against unexpected scenarios. + std::set<MachineInstr *> LoadFromTocs; + for (MachineOperand &MO : UseIter->operands()) + if (MO.isReg() && MO.isUse()) { + if (RegInfo.hasOneDef(MO.getReg())) { + MachineInstr *Temp = + RegInfo.getOneDef(MO.getReg())->getParent(); + // For current TLSLDAIX node, get the Load@toc node for + // the InReg. Otherwise, Temp probably pointed to the + // LoadOffset@toc node that we would like to move. + if (Temp == &MI && RegInfo.hasOneDef(InReg)) + Temp = RegInfo.getOneDef(InReg)->getParent(); + if (Temp->getOpcode() == LDTocOp) + LoadFromTocs.insert(Temp); + } else { + // FIXME: analyze this scenario if there is one. + LoadFromTocs.clear(); + break; + } + } + + // Check the two Load@toc: one should be _$TLSML, and the other + // will be moved before the node that uses the OutReg of the + // .__tls_get_mod node. + if (LoadFromTocs.size() == 2) { + MachineBasicBlock::iterator TLSMLIter = MBB.end(); + MachineBasicBlock::iterator OffsetIter = MBB.end(); + // Make sure the two LoadFromTocs are within current BB, and + // one of them from the "_$TLSML" pseudo symbol, while the + // other from the variable. + for (MachineBasicBlock::iterator I = MBB.begin(), + IE = MBB.end(); + I != IE; ++I) + if (LoadFromTocs.count(&*I)) { + MachineOperand MO = I->getOperand(1); + if (MO.isGlobal() && MO.getGlobal()->hasName() && + MO.getGlobal()->getName() == "_$TLSML") + TLSMLIter = I; + else + OffsetIter = I; + } + // If both two iterators are valid, we should have identified + // the scenario, and do the movement. + if (TLSMLIter != MBB.end() && OffsetIter != MBB.end()) + OffsetIter->moveBefore(&*UseIter); + } + } + } + // The module-handle is copied in r3. The copy is followed by ---------------- amy-kwan wrote:
```suggestion // The module-handle is copied into r3. The copy is followed by ``` https://github.com/llvm/llvm-project/pull/66316 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits