[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-10 Thread Jake Egan via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbbd0d123d3aa: Implement -frecord-command-line for XCOFF 
(authored by Jake-Egan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x003a,
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a004028, 0x23296f70, 0x7420736f, 0x6d657468, 0x696e6720
+; ASM: .info , 0x656c7365, 0x20313233, 0x0a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else 123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include 
 #include 
 
 using namespace llvm;
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,70 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char InfoDirective[] = 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-06 Thread Scott Linder via Phabricator via cfe-commits
scott.linder accepted this revision.
scott.linder added a comment.
This revision is now accepted and ready to land.

Thank you for the patch and the changes! This LGTM, and AFAICT all of the 
comments have been addressed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan added inline comments.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:981
+
+  // Metadata needs to be padded out to an even word size.
+  size_t MetadataSize = Metadata.size();

scott.linder wrote:
> stephenpeckham wrote:
> > There's no requirement to pad the .info section. When you generate assembly 
> > language, the .info pseudo-op can only generate words of data, so the if 
> > the data length is not 0(mod 4), the last word will have to be padded with 
> > low-order 0s.  This means that the length of the .info section will be a 
> > multiple of 4. The length, on the other hand, should be exact. At link 
> > time, only "length" bytes will be copied to the output file.
> > 
> > If you emit object code directly, you will not need to emit any padding 
> > bytes.
> Does the comment still need updating then? It could capture the fact that the 
> "lowest common denominator" is the assembly syntax as it works in terms of 
> words, and so may requiring padding in the final word. We can be clear that 
> we apply the same restriction to the object case judiciously, as it make the 
> output identical and avoids more code paths. We could also note that the 
> linker can use the length to optimize the final linked binary.
> 
> These all clear things up to a fresh reader, so I think they are worthwhile 
> things to include in comments.
I updated the comment. Please let me know if it's sufficient 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 537572.
Jake-Egan added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x003a,
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a004028, 0x23296f70, 0x7420736f, 0x6d657468, 0x696e6720
+; ASM: .info , 0x656c7365, 0x20313233, 0x0a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else 123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include 
 #include 
 
 using namespace llvm;
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,70 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char InfoDirective[] = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info pseudo-op and 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Scott Linder via Phabricator via cfe-commits
scott.linder added inline comments.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:993
+  // Metadata needs to be padded out to an even word size.
+  uint32_t PaddedSize = alignTo(std::max((int)MetadataSize, 1), 4);
+  uint32_t PaddingSize = PaddedSize - MetadataSize;

With the `MetadataSize == 0` case handled the `std::max` should be redundant 
now, right?

Also the literal `4` can be `WordSize`



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:1018
+  for (; Index + WordSize <= MetadataSize; Index += WordSize)
+PrintWord((const uint8_t *)Metadata.data() + Index);
+

Nit: for pointer casts I would prefer an explicit `reinterpret_cast`



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:981
+
+  // Metadata needs to be padded out to an even word size.
+  size_t MetadataSize = Metadata.size();

stephenpeckham wrote:
> There's no requirement to pad the .info section. When you generate assembly 
> language, the .info pseudo-op can only generate words of data, so the if the 
> data length is not 0(mod 4), the last word will have to be padded with 
> low-order 0s.  This means that the length of the .info section will be a 
> multiple of 4. The length, on the other hand, should be exact. At link time, 
> only "length" bytes will be copied to the output file.
> 
> If you emit object code directly, you will not need to emit any padding bytes.
Does the comment still need updating then? It could capture the fact that the 
"lowest common denominator" is the assembly syntax as it works in terms of 
words, and so may requiring padding in the final word. We can be clear that we 
apply the same restriction to the object case judiciously, as it make the 
output identical and avoids more code paths. We could also note that the linker 
can use the length to optimize the final linked binary.

These all clear things up to a fresh reader, so I think they are worthwhile 
things to include in comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added inline comments.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:972
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:2974
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }

hubert.reinterpretcast wrote:
> stephenpeckham wrote:
> > I would use a newline here.  The AIX **what **command looks for @(#) and 
> > echos subsequent bytes until it sees a double quote, a backslash, a > 
> > symbol, newline, or null byte.  The @(#) is not echoed, nor is the 
> > terminating character.  The **what **command prints a newline after it 
> > finds a terminating character.  This means that if the command line 
> > contains any of the special characters, the line will be truncated.
> > 
> > Exception:  If the @(#) is followed by "opt " or " opt ", the terminating 
> > characters are only a newline or null byte. This allows any of the other 
> > special characters to be part of the command line. It doesn't really matter 
> > if you use a newline or a null byte, but the legacy XL compiler uses a 
> > newline. The "opt" keyword should appear if the command line can contain a 
> > double quote, a > or a backslash.
> > 
> > The legacy compiler also uses other keywords besides "opt", including 
> > "version" and "cfg".  The **what** command doesn't do anything special with 
> > these keywords.
> As mentioned offline, newline on its own has potential of ambiguity because 
> it can appear in command line options (null bytes cannot). If there is a 
> preference for newline to be present, then having a null byte after could 
> help.
> 
> Note that `@(#)opt ` can appear on the command line too. Using `what` will 
> have limitations (but we should leave the possibility open for other 
> tools/methods to work).
> 
Thanks; I confirm that my comment has been addressed. I have no further 
comments at this time. Feel free to commit if another reviewer approves the 
patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-05 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 537377.
Jake-Egan added a comment.

Rerun CI


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x003a,
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a004028, 0x23296f70, 0x7420736f, 0x6d657468, 0x696e6720
+; ASM: .info , 0x656c7365, 0x20313233, 0x0a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else 123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include 
 #include 
 
 using namespace llvm;
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,66 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info pseudo-op and C_INFO 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-04 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 537160.
Jake-Egan added a comment.

Fix formatting


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x003a,
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a004028, 0x23296f70, 0x7420736f, 0x6d657468, 0x696e6720
+; ASM: .info , 0x656c7365, 0x20313233, 0x0a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else 123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include 
 #include 
 
 using namespace llvm;
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,66 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info pseudo-op and C_INFO symbol name.
+  OS << InfoDirective;
+ 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-04 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 537156.
Jake-Egan edited the summary of this revision.
Jake-Egan added a comment.

Updated to use both a newline and null byte to separate command lines.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x003a,
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a004028, 0x23296f70, 0x7420736f, 0x6d657468, 0x696e6720
+; ASM: .info , 0x656c7365, 0x20313233, 0x0a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else 123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -37,6 +37,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include 
+#include 
 
 using namespace llvm;
 
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,65 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2338
   // Emit bytes for llvm.commandline metadata.
-  emitModuleCommandLines(M);
+  // The command line metadata waas emitted earlier on XCOFF.
+  if (!TM.getTargetTriple().isOSBinFormatXCOFF())

Minor nit: Typo.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:2974
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }

stephenpeckham wrote:
> I would use a newline here.  The AIX **what **command looks for @(#) and 
> echos subsequent bytes until it sees a double quote, a backslash, a > symbol, 
> newline, or null byte.  The @(#) is not echoed, nor is the terminating 
> character.  The **what **command prints a newline after it finds a 
> terminating character.  This means that if the command line contains any of 
> the special characters, the line will be truncated.
> 
> Exception:  If the @(#) is followed by "opt " or " opt ", the terminating 
> characters are only a newline or null byte. This allows any of the other 
> special characters to be part of the command line. It doesn't really matter 
> if you use a newline or a null byte, but the legacy XL compiler uses a 
> newline. The "opt" keyword should appear if the command line can contain a 
> double quote, a > or a backslash.
> 
> The legacy compiler also uses other keywords besides "opt", including 
> "version" and "cfg".  The **what** command doesn't do anything special with 
> these keywords.
As mentioned offline, newline on its own has potential of ambiguity because it 
can appear in command line options (null bytes cannot). If there is a 
preference for newline to be present, then having a null byte after could help.

Note that `@(#)opt ` can appear on the command line too. Using `what` will have 
limitations (but we should leave the possibility open for other tools/methods 
to work).



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 536920.
Jake-Egan edited the summary of this revision.
Jake-Egan added a comment.

Thanks for the review @stephenpeckham, I updated the patch with the requested 
changes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x0037, 
+; ASM: .info , 0x40282329, 0x6f707420, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x0a402823, 0x296f7074, 0x20736f6d, 0x65746869, 0x6e672065
+; ASM: .info , 0x6c736531, 0x32330a00
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,25 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)opt " << MDS->getString() << "\n";
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -37,6 +37,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include 
+#include 
 
 using namespace llvm;
 
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,65 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Stephen Peckham via Phabricator via cfe-commits
stephenpeckham added inline comments.



Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2338
   // Emit bytes for llvm.commandline metadata.
-  emitModuleCommandLines(M);
+  if (!TM.getTargetTriple().isOSBinFormatXCOFF())
+emitModuleCommandLines(M);

I would add a comment explaining that for XCOFF, the command line metadata was 
emitted earlier.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:981
+
+  // Metadata needs to be padded out to an even word size.
+  size_t MetadataSize = Metadata.size();

There's no requirement to pad the .info section. When you generate assembly 
language, the .info pseudo-op can only generate words of data, so the if the 
data length is not 0(mod 4), the last word will have to be padded with 
low-order 0s.  This means that the length of the .info section will be a 
multiple of 4. The length, on the other hand, should be exact. At link time, 
only "length" bytes will be copied to the output file.

If you emit object code directly, you will not need to emit any padding bytes.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:987
+  // If there's no metadata, the length is 0.
+  if (MetadataSize == 0) {
+OS << format_hex(uint32_t(0), 10) << ",";

Can this be moved up right after the computation of MetadataSize?  Can't you 
just emit "0,"?  Why call format_hex()? It seems odd to have a literal comma 
here instead of using Separator.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:994
+  // Emit length of the metadata with padding.
+  OS << format_hex(PaddedSize, 10) << ",";
+

You should use MetadataSize  and Separator here.  In fact, you could emit the 
length before checking for 0, expecially because a length of 0 is a rare case 
(and impossible for this patch).



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:2974
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }

I would use a newline here.  The AIX **what **command looks for @(#) and echos 
subsequent bytes until it sees a double quote, a backslash, a > symbol, 
newline, or null byte.  The @(#) is not echoed, nor is the terminating 
character.  The **what **command prints a newline after it finds a terminating 
character.  This means that if the command line contains any of the special 
characters, the line will be truncated.

Exception:  If the @(#) is followed by "opt " or " opt ", the terminating 
characters are only a newline or null byte. This allows any of the other 
special characters to be part of the command line. It doesn't really matter if 
you use a newline or a null byte, but the legacy XL compiler uses a newline. 
The "opt" keyword should appear if the command line can contain a double quote, 
a > or a backslash.

The legacy compiler also uses other keywords besides "opt", including "version" 
and "cfg".  The **what** command doesn't do anything special with these 
keywords.



Comment at: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll:16
+
+; ASM: .info ".GCC.command.line", 0x0030,
+; ASM: .info , 0x40282329, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d, 
0x6c696e65

0x002e:  The actual length should be emitted.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 536890.
Jake-Egan added a comment.

Fix formatting


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x0030,
+; ASM: .info , 0x40282329, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d, 0x6c696e65
+; ASM: .info , 0x00402823, 0x29736f6d, 0x65746869, 0x6e672065, 0x6c736531, 0x3233
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include 
 #include 
 
 using namespace llvm;
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,66 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info pseudo-op and C_INFO symbol name.
+  OS << InfoDirective;
+  PrintQuotedString(Name, OS);
+  OS << Separator;
+
+  // 

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan marked an inline comment as done.
Jake-Egan added inline comments.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:986
+
+  // If there's no metadata, the length is 0.
+  if (MetadataSize == 0) {

Handled the 0 length case here.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan marked 6 inline comments as done.
Jake-Egan added inline comments.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:1022
+  if (PaddingSize) {
+assert(PaddedSize - Index == WordSize);
+std::array LastWord = {0};

I changed the assert that you requested because it would always fail:

```
assert(Length - Index == MetadataPaddingSize);
```




Comment at: llvm/lib/MC/MCAsmStreamer.cpp:980
+  size_t MetadataSize = Metadata.size();
+  uint32_t MetadataPaddingSize = 3 - (MetadataSize - 1) % 4;
+

scott.linder wrote:
> scott.linder wrote:
> > I couldn't quickly find a reference for the alignment requirement, but it 
> > seems like there is an additional requirement that the length must also be 
> > non-zero, not just even?
> > 
> > If so, can you update the comment?
> > 
> > I would also rather explicitly use `alignTo` and `max` to express this (see 
> > suggestion), but if we don't expect the optimizer to clean it up I'm fine 
> > with the more terse version.
> Can you factor this out at function scope? It gets repeated below
The length can be zero. See second paragraph of the comment section: 
https://www.ibm.com/docs/en/aix/7.2?topic=formats-xcoff-object-file-format#XCOFF__a1pyfk2b4joyc__title__1


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-07-03 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan updated this revision to Diff 536795.
Jake-Egan added a comment.

Thanks for the review @scott.linder. I applied the changes you requested with 
some differences.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x0030,
+; ASM: .info , 0x40282329, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d, 0x6c696e65
+; ASM: .info , 0x00402823, 0x29736f6d, 0x65746869, 0x6e672065, 0x6c736531, 0x3233
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -290,6 +290,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2954,6 +2956,26 @@
   return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
 }
 
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1208,6 +1208,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -37,6 +37,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include 
+#include 
 
 using namespace llvm;
 
@@ -200,6 +201,7 @@
 const MCSymbol *Trap,
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
 
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -966,6 +968,65 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+  const char *Separator = ", ";
+  constexpr int WordSize = sizeof(uint32_t);
+
+  // Start by emitting the .info pseudo-op and C_INFO symbol name.
+  OS << InfoDirective;
+  

[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-06-28 Thread Scott Linder via Phabricator via cfe-commits
scott.linder added a comment.

Sorry for the delay in review, I am not too familiar with XCOFF so I was hoping 
someone else would take a look first.

If my understanding of the COFF docs I could find is correct then this LGTM 
save for some nits/suggestions




Comment at: llvm/lib/MC/MCAsmStreamer.cpp:970-1037
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+
+  // Start by emitting the .info pseudo-op and C_INFO symbol name
+  OS << InfoDirective;
+  PrintQuotedString(Name, OS);
+  OS << ", ";

I sketched out some of the suggestions I had, although the bigger changes are 
just because the extra `.info` for the padded byte bugged me. If you aren't 
concerned with it I'm also happy with what you have



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:980
+  size_t MetadataSize = Metadata.size();
+  uint32_t MetadataPaddingSize = 3 - (MetadataSize - 1) % 4;
+

I couldn't quickly find a reference for the alignment requirement, but it seems 
like there is an additional requirement that the length must also be non-zero, 
not just even?

If so, can you update the comment?

I would also rather explicitly use `alignTo` and `max` to express this (see 
suggestion), but if we don't expect the optimizer to clean it up I'm fine with 
the more terse version.



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:980
+  size_t MetadataSize = Metadata.size();
+  uint32_t MetadataPaddingSize = 3 - (MetadataSize - 1) % 4;
+

scott.linder wrote:
> I couldn't quickly find a reference for the alignment requirement, but it 
> seems like there is an additional requirement that the length must also be 
> non-zero, not just even?
> 
> If so, can you update the comment?
> 
> I would also rather explicitly use `alignTo` and `max` to express this (see 
> suggestion), but if we don't expect the optimizer to clean it up I'm fine 
> with the more terse version.
Can you factor this out at function scope? It gets repeated below



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:984
+  uint32_t Length = MetadataSize + MetadataPaddingSize;
+  OS << format_hex(uint32_t(Length), 10) << ",";
+  EmitEOL();

Redundant cast



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:988
+  // Return the remaining bytes padded with 0s.
+  auto GetLastWord = [](const uint8_t *Data,
+uint32_t PaddingBytes) -> uint32_t {

It seems odd to use a lambda when this is only used once. Why not just compute 
the last word directly?



Comment at: llvm/lib/MC/MCAsmStreamer.cpp:1033
+MetadataPaddingSize);
+OS << InfoDirective << ", ";
+OS << format_hex(LastWord, 10);

Can you factor this out as `Separator` at function scope?



Comment at: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll:21
+; Trailing padding:
+; ASM: .info , 0x3233
+

Having the padded byte force a new `.info` directive doesn't seem ideal. I 
suggested something to avoid it, but I suppose it also doesn't really harm 
anything.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153600/new/

https://reviews.llvm.org/D153600

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153600: Implement -frecord-command-line for XCOFF

2023-06-22 Thread Jake Egan via Phabricator via cfe-commits
Jake-Egan created this revision.
Herald added subscribers: kbarton, hiraditya, nemanjai.
Herald added a project: All.
Jake-Egan requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, MaskRay.
Herald added projects: clang, LLVM.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153600

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/MC/MCStreamer.h
  llvm/include/llvm/MC/MCXCOFFStreamer.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll

Index: llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-command-line-metadata.ll
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefix=ASM %s
+
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj  < %s 2>&1 | \
+; RUN: FileCheck --check-prefix=OBJ %s
+
+; Verify that llvm.commandline metadata is emitted to .info sections and that the
+; metadata is padded if necessary.
+
+; OBJ: LLVM ERROR: emitXCOFFCInfoSym is not implemented yet on object generation path
+
+; ASM: .info ".GCC.command.line", 0x0030,
+; ASM: .info , 0x40282329, 0x636c616e, 0x67202d63, 0x6f6d6d61, 0x6e64202d
+; ASM: .info , 0x6c696e65, 0x00402823, 0x29736f6d, 0x65746869, 0x6e672065
+; ASM: .info , 0x6c736531
+; Trailing padding:
+; ASM: .info , 0x3233
+
+!llvm.commandline = !{!0, !1}
+!0 = !{!"clang -command -line"}
+!1 = !{!"something else123"}
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -289,6 +289,8 @@
   bool doFinalization(Module ) override;
 
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+  void emitModuleCommandLines(Module ) override;
 };
 
 } // end anonymous namespace
@@ -2964,3 +2966,23 @@
   TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
  createPPCAsmPrinterPass);
 }
+
+void PPCAIXAsmPrinter::emitModuleCommandLines(Module ) {
+  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
+  if (!NMD || !NMD->getNumOperands())
+return;
+
+  std::string S;
+  raw_string_ostream RSOS(S);
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+const MDNode *N = NMD->getOperand(i);
+assert(N->getNumOperands() == 1 &&
+   "llvm.commandline metadata entry can have only one operand");
+const MDString *MDS = cast(N->getOperand(0));
+// Add "@(#)" to support retrieving the command line information with the
+// AIX "what" command
+RSOS << "@(#)" << MDS->getString();
+RSOS.write('\0');
+  }
+  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
+}
Index: llvm/lib/MC/MCStreamer.cpp
===
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1204,6 +1204,11 @@
  "XCOFF targets");
 }
 
+void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  llvm_unreachable("emitXCOFFCInfoSym is only supported on"
+   "XCOFF targets");
+}
+
 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
 StringRef Name, bool KeepOriginalSym) {}
Index: llvm/lib/MC/MCAsmStreamer.cpp
===
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -201,6 +201,8 @@
 unsigned Lang, unsigned Reason,
 unsigned FunctionSize, bool hasDebug) override;
 
+  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
+
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
 Align ByteAlignment) override;
@@ -965,6 +967,75 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+  const char *InfoDirective = "\t.info ";
+
+  // Start by emitting the .info pseudo-op and C_INFO symbol name
+  OS << InfoDirective;
+  PrintQuotedString(Name, OS);
+  OS << ", ";
+
+  // Metadata needs to be padded out to an even word size.
+  size_t MetadataSize = Metadata.size();
+  uint32_t MetadataPaddingSize = 3 - (MetadataSize - 1) % 4;
+
+  //