[llvm] [AIX][TLS] Optimize the -maix-small-local-exec-tls local-exec access sequence for non-zero offsets (PR #71485)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 08:44:15 PST 2023


================
@@ -1556,6 +1629,69 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
   EmitToStreamer(*OutStreamer, TmpInst);
 }
 
+// For non-TOC-based local-exec variables that have a non-zero offset,
+// we need to create a new MCExpr that adds the non-zero offset to the address
+// of the local-exec variable that will be used in either an addi, load or
+// store. However, the final displacement for these instructions must be
+// between [-32768, 32768), so if the TLS address + it's non-zero offset is
+// greater than 32KB, a new MCExpr is produced to accommodate this situation.
+const MCExpr *PPCAsmPrinter::getAdjustedLocalExecExpr(const MachineOperand &MO,
+                                                      int64_t Offset) {
+  assert(MO.isGlobal() && "Only expecting a global MachineOperand here!");
+  const GlobalValue *GValue = MO.getGlobal();
+  TLSModel::Model Model = TM.getTLSModel(GValue);
+  assert(Model == TLSModel::LocalExec &&
+         "Only local-exec accesses are handled!");
+  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_PPC_AIX_TLSLE;
+
+  const MCExpr *Expr =
+      MCSymbolRefExpr::create(getSymbol(GValue), RefKind, OutContext);
+
+  bool IsGlobalADeclaration = GValue->isDeclarationForLinker();
+  // Find the GlobalVariable that corresponds to the particular TLS variable
+  // in the TLS variable to address mapping. All TLS variables should exist
+  // within this map, with the exception of TLS variables marked as extern.
+  const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.find(GValue);
+  if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.end())
+    assert(IsGlobalADeclaration &&
+           "Only expecting to find extern TLS variables not present in the TLS "
+           "variables to address map!");
+
+  unsigned TLSVarAddress = TLSVarsMapEntryIter->second;
+  ptrdiff_t FinalAddress = (TLSVarAddress + Offset);
+  // If the address of the TLS variable + the offset is less than 32KB,
+  // or if the TLS variable is extern, we simply produce an MCExpr to add the
+  // non-zero offset to the TLS variable address.
+  // For when TLS variables are extern, this is safe to do because we can
+  // assume that the address of extern TLS variables are zero.
+  if ((FinalAddress < 32768) || IsGlobalADeclaration)
+    Expr = MCBinaryExpr::createAdd(
+        Expr, MCConstantExpr::create(Offset, OutContext), OutContext);
+  else {
+    // Handle the written offset for cases where:
+    //   address of the TLS variable + the offset is greater than 32KB.
+
+    // Get the address in the range of 0 to 64KB.
----------------
stephenpeckham wrote:

I think you can simplify this.The amount you have to subtract is ((FinalAddress + 32768 ) & ~0xFFFF)

https://github.com/llvm/llvm-project/pull/71485


More information about the llvm-commits mailing list