flip1995 created this revision.
flip1995 added reviewers: MaskRay, rnk, asb.
Herald added subscribers: frasercrmck, dexonsmith, luismarques, apazos, 
sameer.abuasal, s.egerton, Jim, jocewei, rupprecht, PkmX, the_o, brucehoult, 
MartinMosbeck, rogfer01, atanasyan, edward-jones, zzheng, jrtc27, gbedwell, 
niosHD, sabuasal, simoncook, johnrusso, rbar, hiraditya, mgorny, jholewinski.
Herald added a reviewer: andreadb.
Herald added a reviewer: jhenderson.
flip1995 requested review of this revision.
Herald added subscribers: llvm-commits, lldb-commits, cfe-commits, aheejin.
Herald added projects: clang, LLDB, LLVM.

Some information about the object file may be target specific. As an example,
this patch removes the hard-coded 4-byte alignment for text sections and now
uses the alignment defined by the target in the target specific
MCObjectFileInfo.

To get this to work some refactoring was involved:

1. MCObjectFileInfo and MCContext depend on each other (even during 
construction)
2. This patch removes the dependency of MCContext on MCObjectFileInfo during 
construction
3. Additionally, it untangles MCContext  and MCObjectFileInfo a bit more by 
moving elements, like the TargetTriple information from MCObjectFileInfo to 
MCContext.

The contruction of a MCContext with a MCObjectFileInfo is still a little weird:

1. Construct MCContext
2. Construct MCObjectFileInfo
3. Set MOFI for MCContext

But to untangle this futher, the circular dependency between the two would've
to be removed completely, which would be too big of a change for the thing this
patch tries to achive.

The one backend that now makes usage of this patch is RISC-V, where the text
section only has to be 2-byte aligned when the C extension is enabled. This now
produces the same alignments for RISC-V text sections as GCC does.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101462

Files:
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/tools/driver/cc1as_main.cpp
  lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
  lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
  lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCObjectFileInfo.h
  llvm/include/llvm/Support/TargetRegistry.h
  llvm/lib/CodeGen/MachineModuleInfo.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/DWARFLinker/DWARFStreamer.cpp
  llvm/lib/MC/MCAsmStreamer.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCDisassembler/Disassembler.cpp
  llvm/lib/MC/MCELFStreamer.cpp
  llvm/lib/MC/MCMachOStreamer.cpp
  llvm/lib/MC/MCObjectFileInfo.cpp
  llvm/lib/MC/MCParser/AsmParser.cpp
  llvm/lib/MC/MCParser/COFFAsmParser.cpp
  llvm/lib/MC/MCParser/DarwinAsmParser.cpp
  llvm/lib/MC/MCParser/MasmParser.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCWinCOFFStreamer.cpp
  llvm/lib/Object/ModuleSymbolTable.cpp
  llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
  llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
  llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
  llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.cpp
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.h
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
  llvm/lib/Target/TargetLoweringObjectFile.cpp
  llvm/test/MC/RISCV/align.s
  llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
  llvm/tools/llvm-dwp/llvm-dwp.cpp
  llvm/tools/llvm-exegesis/lib/Analysis.cpp
  llvm/tools/llvm-exegesis/lib/LlvmState.cpp
  llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
  llvm/tools/llvm-jitlink/llvm-jitlink.cpp
  llvm/tools/llvm-mc-assemble-fuzzer/llvm-mc-assemble-fuzzer.cpp
  llvm/tools/llvm-mc/llvm-mc.cpp
  llvm/tools/llvm-mca/llvm-mca.cpp
  llvm/tools/llvm-ml/Disassembler.cpp
  llvm/tools/llvm-ml/llvm-ml.cpp
  llvm/tools/llvm-objdump/MachODump.cpp
  llvm/tools/llvm-objdump/llvm-objdump.cpp
  llvm/tools/llvm-profgen/ProfiledBinary.cpp
  llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
  llvm/tools/sancov/sancov.cpp
  llvm/unittests/CodeGen/MachineInstrTest.cpp
  llvm/unittests/CodeGen/MachineOperandTest.cpp
  llvm/unittests/CodeGen/TestAsmPrinter.cpp
  llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
  llvm/unittests/MC/DwarfLineTables.cpp
  llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp

Index: llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
===================================================================
--- llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
+++ llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
@@ -57,6 +57,7 @@
   std::unique_ptr<MCRegisterInfo> MRI;
   std::unique_ptr<MockedUpMCAsmInfo> MUPMAI;
   std::unique_ptr<const MCInstrInfo> MII;
+  std::unique_ptr<MCSubtargetInfo> MSTI;
   std::unique_ptr<MCStreamer> Str;
   std::unique_ptr<MCAsmParser> Parser;
   std::unique_ptr<MCContext> Ctx;
@@ -86,6 +87,10 @@
     MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
     EXPECT_NE(MAI, nullptr);
 
+    std::unique_ptr<MCSubtargetInfo> MSTI;
+    MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+    EXPECT_NE(MSTI, nullptr);
+
     // Now we cast to our mocked up version of MCAsmInfo.
     MUPMAI.reset(static_cast<MockedUpMCAsmInfo *>(MAI.release()));
     // MUPMAI should "hold" MAI.
@@ -99,9 +104,9 @@
     SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
     EXPECT_EQ(Buffer, nullptr);
 
-    Ctx.reset(
-        new MCContext(MUPMAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions));
-    MOFI.InitMCObjectFileInfo(Triple, false, *Ctx, false);
+    Ctx.reset(new MCContext(Triple, MUPMAI.get(), MRI.get(), &MOFI, MSTI.get(),
+                            &SrcMgr, &MCOptions));
+    MOFI.InitMCObjectFileInfo(false, *Ctx, false);
 
     Str.reset(TheTarget->createNullStreamer(*Ctx));
 
Index: llvm/unittests/MC/DwarfLineTables.cpp
===================================================================
--- llvm/unittests/MC/DwarfLineTables.cpp
+++ llvm/unittests/MC/DwarfLineTables.cpp
@@ -21,7 +21,7 @@
 
 namespace {
 struct Context {
-  const char *Triple = "x86_64-pc-linux";
+  const char *TripleName = "x86_64-pc-linux";
   std::unique_ptr<MCRegisterInfo> MRI;
   std::unique_ptr<MCAsmInfo> MAI;
   std::unique_ptr<MCContext> Ctx;
@@ -33,14 +33,15 @@
 
     // If we didn't build x86, do not run the test.
     std::string Error;
-    const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+    const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
     if (!TheTarget)
       return;
 
-    MRI.reset(TheTarget->createMCRegInfo(Triple));
+    MRI.reset(TheTarget->createMCRegInfo(TripleName));
     MCTargetOptions MCOptions;
-    MAI.reset(TheTarget->createMCAsmInfo(*MRI, Triple, MCOptions));
-    Ctx = std::make_unique<MCContext>(MAI.get(), MRI.get(), nullptr);
+    MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
+    Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(), MRI.get(),
+                                      nullptr, nullptr);
   }
 
   operator bool() { return Ctx.get(); }
Index: llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
+++ llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
@@ -465,7 +465,7 @@
                                    inconvertibleErrorCode());
 
   TLOF = TM->getObjFileLowering();
-  MC.reset(new MCContext(MAI.get(), MRI.get(), TLOF));
+  MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), TLOF, MSTI.get()));
   TLOF->Initialize(*MC, *TM);
 
   MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC);
Index: llvm/unittests/CodeGen/TestAsmPrinter.cpp
===================================================================
--- llvm/unittests/CodeGen/TestAsmPrinter.cpp
+++ llvm/unittests/CodeGen/TestAsmPrinter.cpp
@@ -55,8 +55,9 @@
     return make_error<StringError>("no target machine for target " + TripleName,
                                    inconvertibleErrorCode());
 
-  MC.reset(new MCContext(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
-                         TM->getObjFileLowering()));
+  Triple TheTriple(TripleName);
+  MC.reset(new MCContext(TheTriple, TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
+                         TM->getObjFileLowering(), TM->getMCSubtargetInfo()));
   TM->getObjFileLowering()->Initialize(*MC, *TM);
 
   MS = new StrictMock<MockMCStreamer>(MC.get());
Index: llvm/unittests/CodeGen/MachineOperandTest.cpp
===================================================================
--- llvm/unittests/CodeGen/MachineOperandTest.cpp
+++ llvm/unittests/CodeGen/MachineOperandTest.cpp
@@ -318,7 +318,8 @@
 
 TEST(MachineOperandTest, PrintMCSymbol) {
   MCAsmInfo MAI;
-  MCContext Ctx(&MAI, /*MRI=*/nullptr, /*MOFI=*/nullptr);
+  Triple T = Triple("unknown-unknown-unknown");
+  MCContext Ctx(T, &MAI, /*MRI=*/nullptr, /*MOFI=*/nullptr, /*MSTI=*/nullptr);
   MCSymbol *Sym = Ctx.getOrCreateSymbol("foo");
 
   // Create a MachineOperand with a metadata and print it.
Index: llvm/unittests/CodeGen/MachineInstrTest.cpp
===================================================================
--- llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -6,8 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -33,8 +34,9 @@
 #include "MFCommon.inc"
 
 std::unique_ptr<MCContext> createMCContext(MCAsmInfo *AsmInfo) {
-  return std::make_unique<MCContext>(
-      AsmInfo, nullptr, nullptr, nullptr, nullptr, false);
+  Triple TheTriple("", "", "", "elf");
+  return std::make_unique<MCContext>(TheTriple, AsmInfo, nullptr, nullptr,
+                                     nullptr, nullptr, nullptr, false);
 }
 
 // This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
Index: llvm/tools/sancov/sancov.cpp
===================================================================
--- llvm/tools/sancov/sancov.cpp
+++ llvm/tools/sancov/sancov.cpp
@@ -727,7 +727,7 @@
   failIfEmpty(AsmInfo, "no asm info for target " + TripleName);
 
   std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
-  MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
+  MCContext Ctx(TheTriple, AsmInfo.get(), MRI.get(), MOFI.get(), STI.get());
   std::unique_ptr<MCDisassembler> DisAsm(
       TheTarget->createMCDisassembler(*STI, Ctx));
   failIfEmpty(DisAsm, "no disassembler info for target " + TripleName);
Index: llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
===================================================================
--- llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -757,7 +757,7 @@
   if (!MAI)
     ErrorAndExit("Unable to create target asm info!");
 
-  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
+  MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), nullptr, STI.get());
 
   std::unique_ptr<MCDisassembler> Disassembler(
     TheTarget->createMCDisassembler(*STI, Ctx));
Index: llvm/tools/llvm-profgen/ProfiledBinary.cpp
===================================================================
--- llvm/tools/llvm-profgen/ProfiledBinary.cpp
+++ llvm/tools/llvm-profgen/ProfiledBinary.cpp
@@ -332,9 +332,11 @@
   if (!MII)
     exitWithError("no instruction info for target " + TripleName, FileName);
 
-  MCObjectFileInfo MOFI;
-  MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
-  MOFI.InitMCObjectFileInfo(Triple(TripleName), false, Ctx);
+  MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), nullptr,
+                STI.get());
+  std::unique_ptr<MCObjectFileInfo> MOFI(
+      TheTarget->createMCObjectFileInfo(false, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
   DisAsm.reset(TheTarget->createMCDisassembler(*STI, Ctx));
   if (!DisAsm)
     exitWithError("no disassembler for target " + TripleName, FileName);
Index: llvm/tools/llvm-objdump/llvm-objdump.cpp
===================================================================
--- llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1576,10 +1576,12 @@
   if (!MII)
     reportError(Obj->getFileName(),
                 "no instruction info for target " + TripleName);
-  MCObjectFileInfo MOFI;
-  MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
+  MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), nullptr,
+                STI.get());
   // FIXME: for now initialize MCObjectFileInfo with default values
-  MOFI.InitMCObjectFileInfo(Triple(TripleName), false, Ctx);
+  std::unique_ptr<MCObjectFileInfo> MOFI(
+      TheTarget->createMCObjectFileInfo(false, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
 
   std::unique_ptr<MCDisassembler> DisAsm(
       TheTarget->createMCDisassembler(*STI, Ctx));
Index: llvm/tools/llvm-objdump/MachODump.cpp
===================================================================
--- llvm/tools/llvm-objdump/MachODump.cpp
+++ llvm/tools/llvm-objdump/MachODump.cpp
@@ -7228,7 +7228,8 @@
   std::unique_ptr<const MCSubtargetInfo> STI(
       TheTarget->createMCSubtargetInfo(TripleName, MachOMCPU, FeaturesStr));
   CHECK_TARGET_INFO_CREATION(STI);
-  MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
+  MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), nullptr,
+                STI.get());
   std::unique_ptr<MCDisassembler> DisAsm(
       TheTarget->createMCDisassembler(*STI, Ctx));
   CHECK_TARGET_INFO_CREATION(DisAsm);
@@ -7278,7 +7279,8 @@
         ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MachOMCPU,
                                            FeaturesStr));
     CHECK_THUMB_TARGET_INFO_CREATION(ThumbSTI);
-    ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
+    ThumbCtx.reset(new MCContext(Triple(ThumbTripleName), ThumbAsmInfo.get(),
+                                 ThumbMRI.get(), nullptr, ThumbSTI.get()));
     ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
     CHECK_THUMB_TARGET_INFO_CREATION(ThumbDisAsm);
     MCContext *PtrThumbCtx = ThumbCtx.get();
Index: llvm/tools/llvm-ml/llvm-ml.cpp
===================================================================
--- llvm/tools/llvm-ml/llvm-ml.cpp
+++ llvm/tools/llvm-ml/llvm-ml.cpp
@@ -275,12 +275,16 @@
 
   MAI->setPreserveAsmComments(InputArgs.hasArg(OPT_preserve_comments));
 
+  std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(
+      TripleName, /*CPU=*/"", /*Features=*/""));
+  assert(STI && "Unable to create subtarget info!");
+
   // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
   // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
-  MCObjectFileInfo MOFI;
-  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
-  MOFI.InitMCObjectFileInfo(TheTriple, /*PIC=*/false, Ctx,
-                            /*LargeCodeModel=*/true);
+  MCContext Ctx(TheTriple, MAI.get(), MRI.get(), nullptr, STI.get(), &SrcMgr);
+  std::unique_ptr<MCObjectFileInfo> MOFI(TheTarget->createMCObjectFileInfo(
+      /*PIC=*/false, Ctx, /*LargeCodeModel=*/true));
+  Ctx.setObjectFileInfo(MOFI.get());
 
   if (InputArgs.hasArg(OPT_save_temp_labels))
     Ctx.setAllowTemporaryLabels(false);
@@ -312,10 +316,6 @@
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
   assert(MCII && "Unable to create instruction info!");
 
-  std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(
-      TripleName, /*CPU=*/"", /*Features=*/""));
-  assert(STI && "Unable to create subtarget info!");
-
   MCInstPrinter *IP = nullptr;
   if (FileType == "s") {
     const bool OutputATTAsm = InputArgs.hasArg(OPT_output_att_asm);
Index: llvm/tools/llvm-ml/Disassembler.cpp
===================================================================
--- llvm/tools/llvm-ml/Disassembler.cpp
+++ llvm/tools/llvm-ml/Disassembler.cpp
@@ -123,31 +123,31 @@
   return false;
 }
 
-int Disassembler::disassemble(const Target &T, const std::string &Triple,
+int Disassembler::disassemble(const Target &T, const std::string &TripleName,
                               MCSubtargetInfo &STI, MCStreamer &Streamer,
                               MemoryBuffer &Buffer, SourceMgr &SM,
                               raw_ostream &Out) {
-  std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
+  std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(TripleName));
   if (!MRI) {
-    errs() << "error: no register info for target " << Triple << "\n";
+    errs() << "error: no register info for target " << TripleName << "\n";
     return -1;
   }
 
   MCTargetOptions MCOptions;
   std::unique_ptr<const MCAsmInfo> MAI(
-      T.createMCAsmInfo(*MRI, Triple, MCOptions));
+      T.createMCAsmInfo(*MRI, TripleName, MCOptions));
   if (!MAI) {
-    errs() << "error: no assembly info for target " << Triple << "\n";
+    errs() << "error: no assembly info for target " << TripleName << "\n";
     return -1;
   }
 
   // Set up the MCContext for creating symbols and MCExpr's.
-  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
+  MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), nullptr, &STI);
 
   std::unique_ptr<const MCDisassembler> DisAsm(
       T.createMCDisassembler(STI, Ctx));
   if (!DisAsm) {
-    errs() << "error: no disassembler for target " << Triple << "\n";
+    errs() << "error: no disassembler for target " << TripleName << "\n";
     return -1;
   }
 
Index: llvm/tools/llvm-mca/llvm-mca.cpp
===================================================================
--- llvm/tools/llvm-mca/llvm-mca.cpp
+++ llvm/tools/llvm-mca/llvm-mca.cpp
@@ -371,15 +371,15 @@
       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   assert(MAI && "Unable to create target asm info!");
 
-  MCObjectFileInfo MOFI;
   SourceMgr SrcMgr;
 
   // Tell SrcMgr about this buffer, which is what the parser will pick up.
   SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc());
 
-  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
-
-  MOFI.InitMCObjectFileInfo(TheTriple, /* PIC= */ false, Ctx);
+  MCContext Ctx(TheTriple, MAI.get(), MRI.get(), nullptr, STI.get(), &SrcMgr);
+  std::unique_ptr<MCObjectFileInfo> MOFI(TheTarget->createMCObjectFileInfo(
+      /* PIC= */ false, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
 
   std::unique_ptr<buffer_ostream> BOS;
 
Index: llvm/tools/llvm-mc/llvm-mc.cpp
===================================================================
--- llvm/tools/llvm-mc/llvm-mc.cpp
+++ llvm/tools/llvm-mc/llvm-mc.cpp
@@ -379,11 +379,26 @@
   }
   MAI->setPreserveAsmComments(PreserveComments);
 
+  // Package up features to be passed to target/subtarget
+  std::string FeaturesStr;
+  if (MAttrs.size()) {
+    SubtargetFeatures Features;
+    for (unsigned i = 0; i != MAttrs.size(); ++i)
+      Features.AddFeature(MAttrs[i]);
+    FeaturesStr = Features.getString();
+  }
+
+  std::unique_ptr<MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
+  assert(STI && "Unable to create subtarget info!");
+
   // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
   // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
-  MCObjectFileInfo MOFI;
-  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions);
-  MOFI.InitMCObjectFileInfo(TheTriple, PIC, Ctx, LargeCodeModel);
+  MCContext Ctx(TheTriple, MAI.get(), MRI.get(), nullptr, STI.get(), &SrcMgr,
+                &MCOptions);
+  std::unique_ptr<MCObjectFileInfo> MOFI(
+      TheTarget->createMCObjectFileInfo(PIC, Ctx, LargeCodeModel));
+  Ctx.setObjectFileInfo(MOFI.get());
 
   if (SaveTempLabels)
     Ctx.setAllowTemporaryLabels(false);
@@ -443,15 +458,6 @@
   if (GenDwarfForAssembly)
     Ctx.setGenDwarfRootFile(InputFilename, Buffer->getBuffer());
 
-  // Package up features to be passed to target/subtarget
-  std::string FeaturesStr;
-  if (MAttrs.size()) {
-    SubtargetFeatures Features;
-    for (unsigned i = 0; i != MAttrs.size(); ++i)
-      Features.AddFeature(MAttrs[i]);
-    FeaturesStr = Features.getString();
-  }
-
   sys::fs::OpenFlags Flags = (FileType == OFT_AssemblyFile)
                                  ? sys::fs::OF_TextWithCRLF
                                  : sys::fs::OF_None;
@@ -477,10 +483,6 @@
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
   assert(MCII && "Unable to create instruction info!");
 
-  std::unique_ptr<MCSubtargetInfo> STI(
-      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
-  assert(STI && "Unable to create subtarget info!");
-
   MCInstPrinter *IP = nullptr;
   if (FileType == OFT_AssemblyFile) {
     IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant,
Index: llvm/tools/llvm-mc-assemble-fuzzer/llvm-mc-assemble-fuzzer.cpp
===================================================================
--- llvm/tools/llvm-mc-assemble-fuzzer/llvm-mc-assemble-fuzzer.cpp
+++ llvm/tools/llvm-mc-assemble-fuzzer/llvm-mc-assemble-fuzzer.cpp
@@ -170,12 +170,13 @@
     abort();
   }
 
+  std::unique_ptr<MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
 
-  MCObjectFileInfo MOFI;
-  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
-
-  static const bool UsePIC = false;
-  MOFI.InitMCObjectFileInfo(TheTriple, UsePIC, Ctx);
+  MCContext Ctx(TheTriple, MAI.get(), MRI.get(), &MOFI, STI.get(), &SrcMgr);
+  std::unique_ptr<MCObjectFileInfo> MOFI(TheTarget->createMCObjectFileInfo(
+      /*UsePIC=*/false, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
 
   const unsigned OutputAsmVariant = 0;
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
@@ -191,8 +192,6 @@
   }
 
   const char *ProgName = "llvm-mc-fuzzer";
-  std::unique_ptr<MCSubtargetInfo> STI(
-      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
   std::unique_ptr<MCCodeEmitter> CE = nullptr;
   std::unique_ptr<MCAsmBackend> MAB = nullptr;
 
Index: llvm/tools/llvm-jitlink/llvm-jitlink.cpp
===================================================================
--- llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -1256,7 +1256,7 @@
                                           TripleName,
                                       inconvertibleErrorCode()));
 
-  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
+  MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), nullptr, STI.get());
 
   std::unique_ptr<MCDisassembler> Disassembler(
       TheTarget->createMCDisassembler(*STI, Ctx));
Index: llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
===================================================================
--- llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
+++ llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
@@ -130,12 +130,14 @@
 
   BenchmarkCode Result;
 
-  MCObjectFileInfo ObjectFileInfo;
   const TargetMachine &TM = State.getTargetMachine();
-  MCContext Context(TM.getMCAsmInfo(), TM.getMCRegisterInfo(), &ObjectFileInfo);
+  MCContext Context(TM.getTargetTriple(), TM.getMCAsmInfo(),
+                    TM.getMCRegisterInfo(), nullptr, TM.getMCSubtargetInfo());
+  std::unique_ptr<MCObjectFileInfo> ObjectFileInfo(
+      TM.getTarget().createMCObjectFileInfo(
+          /*PIC*/ false, Context));
+  Context.setObjectFileInfo(ObjectFileInfo.get());
   Context.initInlineSourceManager();
-  ObjectFileInfo.InitMCObjectFileInfo(TM.getTargetTriple(), /*PIC*/ false,
-                                      Context);
   BenchmarkCodeStreamer Streamer(&Context, TM.getMCRegisterInfo(), &Result);
 
   std::string Error;
Index: llvm/tools/llvm-exegesis/lib/LlvmState.cpp
===================================================================
--- llvm/tools/llvm-exegesis/lib/LlvmState.cpp
+++ llvm/tools/llvm-exegesis/lib/LlvmState.cpp
@@ -62,8 +62,10 @@
 
 bool LLVMState::canAssemble(const MCInst &Inst) const {
   MCObjectFileInfo ObjectFileInfo;
-  MCContext Context(TheTargetMachine->getMCAsmInfo(),
-                    TheTargetMachine->getMCRegisterInfo(), &ObjectFileInfo);
+  MCContext Context(TheTargetMachine->getTargetTriple(),
+                    TheTargetMachine->getMCAsmInfo(),
+                    TheTargetMachine->getMCRegisterInfo(), &ObjectFileInfo,
+                    TheTargetMachine->getMCSubtargetInfo());
   std::unique_ptr<const MCCodeEmitter> CodeEmitter(
       TheTargetMachine->getTarget().createMCCodeEmitter(
           *TheTargetMachine->getMCInstrInfo(), *TheTargetMachine->getMCRegisterInfo(),
Index: llvm/tools/llvm-exegesis/lib/Analysis.cpp
===================================================================
--- llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -176,8 +176,9 @@
       Triple(FirstPoint.LLVMTriple), 0 /*default variant*/, *AsmInfo_,
       *InstrInfo_, *RegInfo_));
 
-  Context_ = std::make_unique<MCContext>(AsmInfo_.get(), RegInfo_.get(),
-                                         &ObjectFileInfo_);
+  Context_ = std::make_unique<MCContext>(
+      Triple(FirstPoint.LLVMTriple), AsmInfo_.get(), RegInfo_.get(),
+      &ObjectFileInfo_, SubtargetInfo_.get());
   Disasm_.reset(Target.createMCDisassembler(*SubtargetInfo_, *Context_));
   assert(Disasm_ && "cannot create MCDisassembler. missing call to "
                     "InitializeXXXTargetDisassembler ?");
Index: llvm/tools/llvm-dwp/llvm-dwp.cpp
===================================================================
--- llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -875,15 +875,16 @@
   if (!MAI)
     return error("no asm info for target " + TripleName, Context);
 
-  MCObjectFileInfo MOFI;
-  MCContext MC(MAI.get(), MRI.get(), &MOFI);
-  MOFI.InitMCObjectFileInfo(*ErrOrTriple, /*PIC*/ false, MC);
-
   std::unique_ptr<MCSubtargetInfo> MSTI(
       TheTarget->createMCSubtargetInfo(TripleName, "", ""));
   if (!MSTI)
     return error("no subtarget info for target " + TripleName, Context);
 
+  MCContext MC(*ErrOrTriple, MAI.get(), MRI.get(), nullptr, MSTI.get());
+  std::unique_ptr<MCObjectFileInfo> MOFI(TheTarget->createMCObjectFileInfo(
+      /*PIC*/ false, MC));
+  MC.setObjectFileInfo(MOFI.get());
+
   MCTargetOptions Options;
   auto MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options);
   if (!MAB)
Index: llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
===================================================================
--- llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -407,7 +407,8 @@
   if (!MII)
     return make_error<UnsupportedDisassembly>("Failed to initialise MII.");
 
-  Context.reset(new MCContext(AsmInfo.get(), RegisterInfo.get(), &MOFI));
+  Context.reset(new MCContext(Triple(TripleName), AsmInfo.get(),
+                              RegisterInfo.get(), &MOFI, SubtargetInfo.get()));
 
   Disassembler.reset(
       ObjectTarget->createMCDisassembler(*SubtargetInfo, *Context));
Index: llvm/test/MC/RISCV/align.s
===================================================================
--- llvm/test/MC/RISCV/align.s
+++ llvm/test/MC/RISCV/align.s
@@ -33,13 +33,15 @@
 # Linker could satisfy alignment by removing NOPs after linker relaxation.
 
 # The first R_RISCV_ALIGN come from
-# MCELFStreamer::InitSections() emitCodeAlignment(4).
+# MCELFStreamer::InitSections() emitCodeAlignment(getTextSectionAligntment()).
 # C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
 # C-EXT-RELAX-INST:  c.nop
 test:
 	.p2align 2
-# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
-# C-EXT-RELAX-INST:  c.nop
+# If the +c extension is enable, the text section will be 2-byte aligned, so
+# one c.nop instruction is sufficient.
+# C-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0x2
+# C-EXT-RELAX-INST-NOT:  c.nop
 	bne     zero, a0, .LBB0_2
 	mv	a0, zero
 	.p2align 3
Index: llvm/lib/Target/TargetLoweringObjectFile.cpp
===================================================================
--- llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -44,7 +44,7 @@
   // `Initialize` can be called more than once.
   delete Mang;
   Mang = new Mangler();
-  InitMCObjectFileInfo(TM.getTargetTriple(), TM.isPositionIndependent(), ctx,
+  InitMCObjectFileInfo(TM.isPositionIndependent(), ctx,
                        TM.getCodeModel() == CodeModel::Large);
 
   // Reset various EH DWARF encodings.
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -15,12 +15,14 @@
 #include "RISCVELFStreamer.h"
 #include "RISCVInstPrinter.h"
 #include "RISCVMCAsmInfo.h"
+#include "RISCVMCObjectFileInfo.h"
 #include "RISCVTargetStreamer.h"
 #include "TargetInfo/RISCVTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCInstrAnalysis.h"
 #include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
@@ -62,6 +64,14 @@
   return MAI;
 }
 
+static MCObjectFileInfo *
+createRISCVMCObjectFileInfo(bool PIC, MCContext &ctx,
+                            bool LargeCodeModel = false) {
+  MCObjectFileInfo *MOFI = new RISCVMCObjectFileInfo();
+  MOFI->InitMCObjectFileInfo(PIC, ctx, LargeCodeModel);
+  return MOFI;
+}
+
 static MCSubtargetInfo *createRISCVMCSubtargetInfo(const Triple &TT,
                                                    StringRef CPU, StringRef FS) {
   if (CPU.empty())
@@ -141,6 +151,7 @@
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTargetMC() {
   for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
     TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo);
+    TargetRegistry::RegisterMCObjectFileInfo(*T, createRISCVMCObjectFileInfo);
     TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo);
     TargetRegistry::RegisterMCRegInfo(*T, createRISCVMCRegisterInfo);
     TargetRegistry::RegisterMCAsmBackend(*T, createRISCVAsmBackend);
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.h
===================================================================
--- /dev/null
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.h
@@ -0,0 +1,28 @@
+//===-- RISCVMCAsmInfo.h - RISCV Asm Info ----------------------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the RISCVMCAsmInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCOBJECTFILEINFO_H
+#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCOBJECTFILEINFO_H
+
+#include "llvm/MC/MCObjectFileInfo.h"
+
+namespace llvm {
+class Triple;
+
+class RISCVMCObjectFileInfo : public MCObjectFileInfo {
+public:
+  unsigned getTextSectionAlignment() const;
+};
+
+} // namespace llvm
+
+#endif
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.cpp
===================================================================
--- /dev/null
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCObjectFileInfo.cpp
@@ -0,0 +1,26 @@
+//===-- RISCVMCAsmInfo.cpp - RISCV Asm properties -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of the RISCVMCAsmInfo properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVMCObjectFileInfo.h"
+#include "RISCVMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
+
+using namespace llvm;
+
+unsigned RISCVMCObjectFileInfo::getTextSectionAlignment() const {
+  MCContext &Ctx = getContext();
+  const MCSubtargetInfo *STI = Ctx.getSubtargetInfo();
+  if (STI->hasFeature(RISCV::FeatureStdExtC)) {
+    return 2;
+  }
+  return 4;
+}
Index: llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
+++ llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
@@ -6,6 +6,7 @@
   RISCVMCAsmInfo.cpp
   RISCVMCCodeEmitter.cpp
   RISCVMCExpr.cpp
+  RISCVMCObjectFileInfo.cpp
   RISCVMCTargetDesc.cpp
   RISCVMatInt.cpp
   RISCVTargetStreamer.cpp
Index: llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
===================================================================
--- llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
+++ llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
@@ -94,7 +94,8 @@
     outputDwarfFileDirectives();
     OS << "\t.section";
     Section->PrintSwitchToSection(*getStreamer().getContext().getAsmInfo(),
-                                  FI->getTargetTriple(), OS, SubSection);
+                                  getStreamer().getContext().getTargetTriple(),
+                                  OS, SubSection);
     // DWARF sections are enclosed into braces - emit the open one.
     OS << "\t{\n";
     HasSections = true;
Index: llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -32,7 +32,6 @@
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstrDesc.h"
 #include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCParser/MCAsmLexer.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
@@ -6330,10 +6329,10 @@
   }
 
   enum {
-    COFF = (1 << MCObjectFileInfo::IsCOFF),
-    ELF = (1 << MCObjectFileInfo::IsELF),
-    MACHO = (1 << MCObjectFileInfo::IsMachO),
-    WASM = (1 << MCObjectFileInfo::IsWasm),
+    COFF = (1 << MCContext::IsCOFF),
+    ELF = (1 << MCContext::IsELF),
+    MACHO = (1 << MCContext::IsMachO),
+    WASM = (1 << MCContext::IsWasm),
   };
   static const struct PrefixEntry {
     const char *Spelling;
@@ -6356,20 +6355,20 @@
   }
 
   uint8_t CurrentFormat;
-  switch (getContext().getObjectFileInfo()->getObjectFileType()) {
-  case MCObjectFileInfo::IsMachO:
+  switch (getContext().getObjectFileType()) {
+  case MCContext::IsMachO:
     CurrentFormat = MACHO;
     break;
-  case MCObjectFileInfo::IsELF:
+  case MCContext::IsELF:
     CurrentFormat = ELF;
     break;
-  case MCObjectFileInfo::IsCOFF:
+  case MCContext::IsCOFF:
     CurrentFormat = COFF;
     break;
-  case MCObjectFileInfo::IsWasm:
+  case MCContext::IsWasm:
     CurrentFormat = WASM;
     break;
-  case MCObjectFileInfo::IsXCOFF:
+  case MCContext::IsXCOFF:
     llvm_unreachable("unexpected object format");
     break;
   }
@@ -11001,10 +11000,9 @@
 
 /// parseDirective parses the arm specific directives
 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
-  const MCObjectFileInfo::Environment Format =
-    getContext().getObjectFileInfo()->getObjectFileType();
-  bool IsMachO = Format == MCObjectFileInfo::IsMachO;
-  bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
+  const MCContext::Environment Format = getContext().getObjectFileType();
+  bool IsMachO = Format == MCContext::IsMachO;
+  bool IsCOFF = Format == MCContext::IsCOFF;
 
   std::string IDVal = DirectiveID.getIdentifier().lower();
   if (IDVal == ".word")
@@ -11142,8 +11140,8 @@
 ///  ::= .thumbfunc symbol_name
 bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
   MCAsmParser &Parser = getParser();
-  const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
-  bool IsMachO = Format == MCObjectFileInfo::IsMachO;
+  const auto Format = getContext().getObjectFileType();
+  bool IsMachO = Format == MCContext::IsMachO;
 
   // Darwin asm has (optionally) function name after .thumb_func direction
   // ELF doesn't
Index: llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
===================================================================
--- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -5267,10 +5267,9 @@
 
 /// ParseDirective parses the arm specific directives
 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
-  const MCObjectFileInfo::Environment Format =
-    getContext().getObjectFileInfo()->getObjectFileType();
-  bool IsMachO = Format == MCObjectFileInfo::IsMachO;
-  bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
+  const MCContext::Environment Format = getContext().getObjectFileType();
+  bool IsMachO = Format == MCContext::IsMachO;
+  bool IsCOFF = Format == MCContext::IsCOFF;
 
   auto IDVal = DirectiveID.getIdentifier().lower();
   SMLoc Loc = DirectiveID.getLoc();
Index: llvm/lib/Object/ModuleSymbolTable.cpp
===================================================================
--- llvm/lib/Object/ModuleSymbolTable.cpp
+++ llvm/lib/Object/ModuleSymbolTable.cpp
@@ -99,10 +99,11 @@
   if (!MCII)
     return;
 
-  MCObjectFileInfo MOFI;
-  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
-  MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
-  MOFI.setSDKVersion(M.getSDKVersion());
+  MCContext MCCtx(TT, MAI.get(), MRI.get(), nullptr, STI.get());
+  std::unique_ptr<MCObjectFileInfo> MOFI(T->createMCObjectFileInfo(
+      /*PIC*/ false, MCCtx));
+  MOFI->setSDKVersion(M.getSDKVersion());
+  MCCtx.setObjectFileInfo(MOFI.get());
   RecordStreamer Streamer(MCCtx, M);
   T->createNullTargetStreamer(Streamer);
 
Index: llvm/lib/MC/MCWinCOFFStreamer.cpp
===================================================================
--- llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -181,8 +181,7 @@
 void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
   // SafeSEH is a feature specific to 32-bit x86.  It does not exist (and is
   // unnecessary) on all platforms which use table-based exception dispatch.
-  if (getContext().getObjectFileInfo()->getTargetTriple().getArch() !=
-      Triple::x86)
+  if (getContext().getTargetTriple().getArch() != Triple::x86)
     return;
 
   const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
@@ -266,7 +265,7 @@
                                          unsigned ByteAlignment) {
   auto *Symbol = cast<MCSymbolCOFF>(S);
 
-  const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+  const Triple &T = getContext().getTargetTriple();
   if (T.isWindowsMSVCEnvironment()) {
     if (ByteAlignment > 32)
       report_fatal_error("alignment is limited to 32-bytes");
Index: llvm/lib/MC/MCStreamer.cpp
===================================================================
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -57,10 +57,9 @@
                                      MCSection *Section,
                                      const MCExpr *Subsection,
                                      raw_ostream &OS) {
-  Section->PrintSwitchToSection(
-      *Streamer.getContext().getAsmInfo(),
-      Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
-      Subsection);
+  Section->PrintSwitchToSection(*Streamer.getContext().getAsmInfo(),
+                                Streamer.getContext().getTargetTriple(), OS,
+                                Subsection);
 }
 
 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
Index: llvm/lib/MC/MCParser/MasmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/MasmParser.cpp
+++ llvm/lib/MC/MCParser/MasmParser.cpp
@@ -1029,8 +1029,8 @@
   EndStatementAtEOFStack.push_back(true);
 
   // Initialize the platform / file format parser.
-  switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
-  case MCObjectFileInfo::IsCOFF:
+  switch (Ctx.getObjectFileType()) {
+  case MCContext::IsCOFF:
     PlatformParser.reset(createCOFFMasmParser());
     break;
   default:
Index: llvm/lib/MC/MCParser/DarwinAsmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -695,7 +695,7 @@
     return Error(Loc, toString(std::move(E)));
 
   // Issue a warning if the target is not powerpc and Section is a *coal* section.
-  Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple();
+  Triple TT = getParser().getContext().getTargetTriple();
   Triple::ArchType ArchTy = TT.getArch();
 
   if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {
@@ -1091,7 +1091,7 @@
 
 void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
                                    SMLoc Loc, Triple::OSType ExpectedOS) {
-  const Triple &Target = getContext().getObjectFileInfo()->getTargetTriple();
+  const Triple &Target = getContext().getTargetTriple();
   if (Target.getOS() != ExpectedOS)
     Warning(Loc, Twine(Directive) +
             (Arg.empty() ? Twine() : Twine(' ') + Arg) +
Index: llvm/lib/MC/MCParser/COFFAsmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -403,7 +403,7 @@
 
   SectionKind Kind = computeSectionKind(Flags);
   if (Kind.isText()) {
-    const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+    const Triple &T = getContext().getTargetTriple();
     if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
       Flags |= COFF::IMAGE_SCN_MEM_16BIT;
   }
Index: llvm/lib/MC/MCParser/AsmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/AsmParser.cpp
+++ llvm/lib/MC/MCParser/AsmParser.cpp
@@ -729,21 +729,21 @@
   Out.setStartTokLocPtr(&StartTokLoc);
 
   // Initialize the platform / file format parser.
-  switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
-  case MCObjectFileInfo::IsCOFF:
+  switch (Ctx.getObjectFileType()) {
+  case MCContext::IsCOFF:
     PlatformParser.reset(createCOFFAsmParser());
     break;
-  case MCObjectFileInfo::IsMachO:
+  case MCContext::IsMachO:
     PlatformParser.reset(createDarwinAsmParser());
     IsDarwin = true;
     break;
-  case MCObjectFileInfo::IsELF:
+  case MCContext::IsELF:
     PlatformParser.reset(createELFAsmParser());
     break;
-  case MCObjectFileInfo::IsWasm:
+  case MCContext::IsWasm:
     PlatformParser.reset(createWasmAsmParser());
     break;
-  case MCObjectFileInfo::IsXCOFF:
+  case MCContext::IsXCOFF:
     report_fatal_error(
         "Need to implement createXCOFFAsmParser for XCOFF format.");
     break;
Index: llvm/lib/MC/MCObjectFileInfo.cpp
===================================================================
--- llvm/lib/MC/MCObjectFileInfo.cpp
+++ llvm/lib/MC/MCObjectFileInfo.cpp
@@ -959,8 +959,9 @@
       /* MultiSymbolsAllowed */ true, ".dwmac", XCOFF::SSUBTYP_DWMAC);
 }
 
-void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
-                                            MCContext &ctx,
+MCObjectFileInfo::~MCObjectFileInfo() = default;
+
+void MCObjectFileInfo::InitMCObjectFileInfo(bool PIC, MCContext &ctx,
                                             bool LargeCodeModel) {
   PositionIndependent = PIC;
   Ctx = &ctx;
@@ -982,35 +983,30 @@
   DwarfAccelNamespaceSection = nullptr; // Used only by selected targets.
   DwarfAccelTypesSection = nullptr;     // Used only by selected targets.
 
-  TT = TheTriple;
+  Triple TheTriple = Ctx->getTargetTriple();
 
-  switch (TT.getObjectFormat()) {
+  switch (TheTriple.getObjectFormat()) {
   case Triple::MachO:
-    Env = IsMachO;
-    initMachOMCObjectFileInfo(TT);
+    initMachOMCObjectFileInfo(TheTriple);
     break;
   case Triple::COFF:
-    if (!TT.isOSWindows())
+    if (!TheTriple.isOSWindows())
       report_fatal_error(
           "Cannot initialize MC for non-Windows COFF object files.");
 
-    Env = IsCOFF;
-    initCOFFMCObjectFileInfo(TT);
+    initCOFFMCObjectFileInfo(TheTriple);
     break;
   case Triple::ELF:
-    Env = IsELF;
-    initELFMCObjectFileInfo(TT, LargeCodeModel);
+    initELFMCObjectFileInfo(TheTriple, LargeCodeModel);
     break;
   case Triple::Wasm:
-    Env = IsWasm;
-    initWasmMCObjectFileInfo(TT);
+    initWasmMCObjectFileInfo(TheTriple);
     break;
   case Triple::GOFF:
     report_fatal_error("Cannot initialize MC for GOFF object file format");
     break;
   case Triple::XCOFF:
-    Env = IsXCOFF;
-    initXCOFFMCObjectFileInfo(TT);
+    initXCOFFMCObjectFileInfo(TheTriple);
     break;
   case Triple::UnknownObjectFormat:
     report_fatal_error("Cannot initialize MC for unknown object file format.");
@@ -1020,7 +1016,7 @@
 
 MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
                                                    uint64_t Hash) const {
-  switch (TT.getObjectFormat()) {
+  switch (Ctx->getTargetTriple().getObjectFormat()) {
   case Triple::ELF:
     return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
                               utostr(Hash), /*IsComdat=*/true);
@@ -1041,7 +1037,7 @@
 
 MCSection *
 MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
-  if (Env != IsELF)
+  if (Ctx->getObjectFileType() != MCContext::IsELF)
     return StackSizesSection;
 
   const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
@@ -1059,7 +1055,7 @@
 
 MCSection *
 MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
-  if (Env != IsELF)
+  if (Ctx->getObjectFileType() != MCContext::IsELF)
     return nullptr;
 
   const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
@@ -1079,7 +1075,7 @@
 
 MCSection *
 MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const {
-  if (Env == IsELF) {
+  if (getContext().getObjectFileType() == MCContext::IsELF) {
     const auto *ElfSec = static_cast<const MCSectionELF *>(TextSec);
     // Create a separate section for probes that comes with a comdat function.
     if (const MCSymbol *Group = ElfSec->getGroup()) {
@@ -1095,7 +1091,7 @@
 
 MCSection *
 MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
-  if (Env == IsELF) {
+  if (getContext().getObjectFileType() == MCContext::IsELF) {
     // Create a separate comdat group for each function's descriptor in order
     // for the linker to deduplicate. The duplication, must be from different
     // tranlation unit, can come from:
@@ -1105,7 +1101,7 @@
     // Use a concatenation of the section name and the function name as the
     // group name so that descriptor-only groups won't be folded with groups of
     // code.
-    if (TT.supportsCOMDAT() && !FuncName.empty()) {
+    if (getContext().getTargetTriple().supportsCOMDAT() && !FuncName.empty()) {
       auto *S = static_cast<MCSectionELF *>(PseudoProbeDescSection);
       auto Flags = S->getFlags() | ELF::SHF_GROUP;
       return Ctx->getELFSection(S->getName(), S->getType(), Flags,
Index: llvm/lib/MC/MCMachOStreamer.cpp
===================================================================
--- llvm/lib/MC/MCMachOStreamer.cpp
+++ llvm/lib/MC/MCMachOStreamer.cpp
@@ -515,7 +515,7 @@
   MCMachOStreamer *S =
       new MCMachOStreamer(Context, std::move(MAB), std::move(OW), std::move(CE),
                           DWARFMustBeAtTheEnd, LabelSections);
-  const Triple &Target = Context.getObjectFileInfo()->getTargetTriple();
+  const Triple &Target = Context.getTargetTriple();
   S->emitVersionForTarget(Target, Context.getObjectFileInfo()->getSDKVersion());
   if (RelaxAll)
     S->getAssembler().setRelaxAll(true);
Index: llvm/lib/MC/MCELFStreamer.cpp
===================================================================
--- llvm/lib/MC/MCELFStreamer.cpp
+++ llvm/lib/MC/MCELFStreamer.cpp
@@ -90,7 +90,7 @@
 void MCELFStreamer::InitSections(bool NoExecStack) {
   MCContext &Ctx = getContext();
   SwitchSection(Ctx.getObjectFileInfo()->getTextSection());
-  emitCodeAlignment(4);
+  emitCodeAlignment(Ctx.getObjectFileInfo()->getTextSectionAlignment());
 
   if (NoExecStack)
     SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
Index: llvm/lib/MC/MCDisassembler/Disassembler.cpp
===================================================================
--- llvm/lib/MC/MCDisassembler/Disassembler.cpp
+++ llvm/lib/MC/MCDisassembler/Disassembler.cpp
@@ -74,7 +74,8 @@
     return nullptr;
 
   // Set up the MCContext for creating symbols and MCExpr's.
-  std::unique_ptr<MCContext> Ctx(new MCContext(MAI.get(), MRI.get(), nullptr));
+  std::unique_ptr<MCContext> Ctx(
+      new MCContext(Triple(TT), MAI.get(), MRI.get(), nullptr, STI.get()));
   if (!Ctx)
     return nullptr;
 
Index: llvm/lib/MC/MCContext.cpp
===================================================================
--- llvm/lib/MC/MCContext.cpp
+++ llvm/lib/MC/MCContext.cpp
@@ -62,11 +62,13 @@
   SMD.print(nullptr, errs());
 }
 
-MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
-                     const MCObjectFileInfo *mofi, const SourceMgr *mgr,
+MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
+                     const MCRegisterInfo *mri, const MCObjectFileInfo *mofi,
+                     const MCSubtargetInfo *msti, const SourceMgr *mgr,
                      MCTargetOptions const *TargetOpts, bool DoAutoReset)
-    : SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler),
-      MAI(mai), MRI(mri), MOFI(mofi), Symbols(Allocator), UsedNames(Allocator),
+    : TT(TheTriple), SrcMgr(mgr), InlineSrcMgr(nullptr),
+      DiagHandler(defaultDiagHandler), MAI(mai), MRI(mri), MOFI(mofi),
+      MSTI(msti), Symbols(Allocator), UsedNames(Allocator),
       InlineAsmUsedLabelNames(Allocator),
       CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
       AutoReset(DoAutoReset), TargetOptions(TargetOpts) {
@@ -75,6 +77,34 @@
   if (SrcMgr && SrcMgr->getNumBuffers())
     MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())
                                    ->getBufferIdentifier());
+
+  switch (TheTriple.getObjectFormat()) {
+  case Triple::MachO:
+    Env = IsMachO;
+    break;
+  case Triple::COFF:
+    if (!TheTriple.isOSWindows())
+      report_fatal_error(
+          "Cannot initialize MC for non-Windows COFF object files.");
+
+    Env = IsCOFF;
+    break;
+  case Triple::ELF:
+    Env = IsELF;
+    break;
+  case Triple::Wasm:
+    Env = IsWasm;
+    break;
+  case Triple::XCOFF:
+    Env = IsXCOFF;
+    break;
+  case Triple::GOFF:
+    report_fatal_error("Cannot initialize MC for GOFF object file format");
+    break;
+  case Triple::UnknownObjectFormat:
+    report_fatal_error("Cannot initialize MC for unknown object file format.");
+    break;
+  }
 }
 
 MCContext::~MCContext() {
@@ -195,19 +225,18 @@
                 "MCSymbol classes must be trivially destructible");
   static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(),
                 "MCSymbol classes must be trivially destructible");
-  if (MOFI) {
-    switch (MOFI->getObjectFileType()) {
-    case MCObjectFileInfo::IsCOFF:
-      return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
-    case MCObjectFileInfo::IsELF:
-      return new (Name, *this) MCSymbolELF(Name, IsTemporary);
-    case MCObjectFileInfo::IsMachO:
-      return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
-    case MCObjectFileInfo::IsWasm:
-      return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
-    case MCObjectFileInfo::IsXCOFF:
-      return createXCOFFSymbolImpl(Name, IsTemporary);
-    }
+
+  switch (getObjectFileType()) {
+  case MCContext::IsCOFF:
+    return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
+  case MCContext::IsELF:
+    return new (Name, *this) MCSymbolELF(Name, IsTemporary);
+  case MCContext::IsMachO:
+    return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
+  case MCContext::IsWasm:
+    return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
+  case MCContext::IsXCOFF:
+    return createXCOFFSymbolImpl(Name, IsTemporary);
   }
   return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
                                     IsTemporary);
Index: llvm/lib/MC/MCAsmStreamer.cpp
===================================================================
--- llvm/lib/MC/MCAsmStreamer.cpp
+++ llvm/lib/MC/MCAsmStreamer.cpp
@@ -484,9 +484,8 @@
   if (MCTargetStreamer *TS = getTargetStreamer()) {
     TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
   } else {
-    Section->PrintSwitchToSection(
-        *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
-        Subsection);
+    Section->PrintSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
+                                  Subsection);
   }
 }
 
Index: llvm/lib/DWARFLinker/DWARFStreamer.cpp
===================================================================
--- llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -50,14 +50,14 @@
   if (!MAI)
     return error("no asm info for target " + TripleName, Context), false;
 
-  MOFI.reset(new MCObjectFileInfo);
-  MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get()));
-  MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, *MC);
-
   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
   if (!MSTI)
     return error("no subtarget info for target " + TripleName, Context), false;
 
+  MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), nullptr, MSTI.get()));
+  MOFI.reset(TheTarget->createMCObjectFileInfo(/*PIC*/ false, *MC));
+  MC->setObjectFileInfo(MOFI.get());
+
   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
   if (!MAB)
     return error("no asm backend for target " + TripleName, Context), false;
@@ -212,7 +212,7 @@
   Asm.emitInt32(11 + Die.getSize() - 4);
   Asm.emitInt16(2);
   Asm.emitInt32(0);
-  Asm.emitInt8(MOFI->getTargetTriple().isArch64Bit() ? 8 : 4);
+  Asm.emitInt8(MC->getTargetTriple().isArch64Bit() ? 8 : 4);
   DebugInfoSectionSize += 11;
   emitDIE(Die);
 }
Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1625,7 +1625,7 @@
       // Append "$symbol" to the section name *before* IR-level mangling is
       // applied when targetting mingw. This is what GCC does, and the ld.bfd
       // COFF linker will not properly handle comdats otherwise.
-      if (getTargetTriple().isWindowsGNUEnvironment())
+      if (getContext().getTargetTriple().isWindowsGNUEnvironment())
         raw_svector_ostream(Name) << '$' << ComdatGV->getName();
 
       return getContext().getCOFFSection(Name, Characteristics, Kind,
@@ -1742,7 +1742,8 @@
   std::string Flags;
   for (const GlobalValue &GV : M.global_values()) {
     raw_string_ostream OS(Flags);
-    emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
+    emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(),
+                                 getMangler());
     OS.flush();
     if (!Flags.empty()) {
       Streamer.SwitchSection(getDrectveSection());
@@ -1766,7 +1767,8 @@
           continue;
 
         raw_string_ostream OS(Flags);
-        emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+        emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(),
+                                   getMangler());
         OS.flush();
 
         if (!Flags.empty()) {
@@ -1845,16 +1847,16 @@
 
 MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
-  return getCOFFStaticStructorSection(getContext(), getTargetTriple(), true,
-                                      Priority, KeySym,
-                                      cast<MCSectionCOFF>(StaticCtorSection));
+  return getCOFFStaticStructorSection(
+      getContext(), getContext().getTargetTriple(), true, Priority, KeySym,
+      cast<MCSectionCOFF>(StaticCtorSection));
 }
 
 MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
-  return getCOFFStaticStructorSection(getContext(), getTargetTriple(), false,
-                                      Priority, KeySym,
-                                      cast<MCSectionCOFF>(StaticDtorSection));
+  return getCOFFStaticStructorSection(
+      getContext(), getContext().getTargetTriple(), false, Priority, KeySym,
+      cast<MCSectionCOFF>(StaticDtorSection));
 }
 
 const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
Index: llvm/lib/CodeGen/MachineModuleInfo.cpp
===================================================================
--- llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -217,8 +217,9 @@
 
 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
     : TM(std::move(MMI.TM)),
-      Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(),
-              MMI.TM.getObjFileLowering(), nullptr, nullptr, false),
+      Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(),
+              MMI.TM.getMCRegisterInfo(), MMI.TM.getObjFileLowering(),
+              MMI.TM.getMCSubtargetInfo(), nullptr, nullptr, false),
       MachineFunctions(std::move(MMI.MachineFunctions)) {
   ObjFileMMI = MMI.ObjFileMMI;
   CurCallSite = MMI.CurCallSite;
@@ -232,15 +233,17 @@
 }
 
 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
-    : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
-                       TM->getObjFileLowering(), nullptr, nullptr, false) {
+    : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
+                       TM->getMCRegisterInfo(), TM->getObjFileLowering(),
+                       TM->getMCSubtargetInfo(), nullptr, nullptr, false) {
   initialize();
 }
 
 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
                                      MCContext *ExtContext)
-    : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
-                       TM->getObjFileLowering(), nullptr, nullptr, false),
+    : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
+                       TM->getMCRegisterInfo(), TM->getObjFileLowering(),
+                       TM->getMCSubtargetInfo(), nullptr, nullptr, false),
       ExternalContext(ExtContext) {
   initialize();
 }
Index: llvm/include/llvm/Support/TargetRegistry.h
===================================================================
--- llvm/include/llvm/Support/TargetRegistry.h
+++ llvm/include/llvm/Support/TargetRegistry.h
@@ -23,6 +23,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
@@ -130,6 +131,9 @@
   using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI,
                                            const Triple &TT,
                                            const MCTargetOptions &Options);
+  using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(bool PIC,
+                                                         MCContext &ctx,
+                                                         bool LargeCodeModel);
   using MCInstrInfoCtorFnTy = MCInstrInfo *(*)();
   using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info);
   using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT);
@@ -227,6 +231,10 @@
   /// registered.
   MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
 
+  /// MCObjectFileInfoCtorFn - Constructor function for this target's
+  /// MCObjectFileInfo, if registered.
+  MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn;
+
   /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
   /// if registered.
   MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
@@ -350,6 +358,19 @@
     return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options);
   }
 
+  /// createMCObjectFileInfo - Create a MCObjectFileInfo implementation for the
+  /// specified target triple.
+  ///
+  MCObjectFileInfo *createMCObjectFileInfo(bool PIC, MCContext &ctx,
+                                           bool LargeCodeModel = false) const {
+    if (!MCObjectFileInfoCtorFn) {
+      MCObjectFileInfo *MOFI = new MCObjectFileInfo();
+      MOFI->InitMCObjectFileInfo(PIC, ctx, LargeCodeModel);
+      return MOFI;
+    }
+    return MCObjectFileInfoCtorFn(PIC, ctx, LargeCodeModel);
+  }
+
   /// createMCInstrInfo - Create a MCInstrInfo implementation.
   ///
   MCInstrInfo *createMCInstrInfo() const {
@@ -724,6 +745,20 @@
     T.MCAsmInfoCtorFn = Fn;
   }
 
+  /// RegisterMCObjectFileInfo - Register a MCObjectFileInfo implementation for
+  /// the given target.
+  ///
+  /// Clients are responsible for ensuring that registration doesn't occur
+  /// while another thread is attempting to access the registry. Typically
+  /// this is done by initializing all targets at program startup.
+  ///
+  /// @param T - The target being registered.
+  /// @param Fn - A function to construct a MCObjectFileInfo for the target.
+  static void RegisterMCObjectFileInfo(Target &T,
+                                       Target::MCObjectFileInfoCtorFnTy Fn) {
+    T.MCObjectFileInfoCtorFn = Fn;
+  }
+
   /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
   /// given target.
   ///
@@ -991,6 +1026,40 @@
   }
 };
 
+/// RegisterMCObjectFileInfo - Helper template for registering a target object
+/// file info implementation.  This invokes the static "Create" method on the
+/// class to actually do the construction.  Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+///   extern Target TheFooTarget;
+///   RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget);
+/// }
+template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo {
+  RegisterMCObjectFileInfo(Target &T) {
+    TargetRegistry::RegisterMCObjectFileInfo(T, &Allocator);
+  }
+
+private:
+  static MCObjectFileInfo *Allocator(bool PIC, MCContext &ctx,
+                                     bool LargeCodeModel = false) {
+    return new MCObjectFileInfoImpl(PIC, ctx, LargeCodeModel);
+  }
+};
+
+/// RegisterMCObjectFileInfo - Helper template for registering a target object
+/// file info implementation.  This invokes the specified function to do the
+/// construction.  Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+///   extern Target TheFooTarget;
+///   RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCObjectFileInfoFn {
+  RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) {
+    TargetRegistry::RegisterMCObjectFileInfo(T, Fn);
+  }
+};
+
 /// RegisterMCInstrInfo - Helper template for registering a target instruction
 /// info implementation.  This invokes the static "Create" method on the class
 /// to actually do the construction.  Usage:
Index: llvm/include/llvm/MC/MCObjectFileInfo.h
===================================================================
--- llvm/include/llvm/MC/MCObjectFileInfo.h
+++ llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -227,8 +227,9 @@
   MCSection *TOCBaseSection = nullptr;
 
 public:
-  void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
+  void InitMCObjectFileInfo(bool PIC, MCContext &ctx,
                             bool LargeCodeModel = false);
+  virtual ~MCObjectFileInfo();
   MCContext &getContext() const { return *Ctx; }
 
   bool getSupportsWeakOmittedEHFrame() const {
@@ -251,6 +252,7 @@
     return CompactUnwindDwarfEHFrameOnly;
   }
 
+  virtual unsigned getTextSectionAlignment() const { return 4; }
   MCSection *getTextSection() const { return TextSection; }
   MCSection *getDataSection() const { return DataSection; }
   MCSection *getBSSSection() const { return BSSSection; }
@@ -416,16 +418,11 @@
 
   MCSection *getEHFrameSection() const { return EHFrameSection; }
 
-  enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
-  Environment getObjectFileType() const { return Env; }
-
   bool isPositionIndependent() const { return PositionIndependent; }
 
 private:
-  Environment Env;
   bool PositionIndependent = false;
   MCContext *Ctx = nullptr;
-  Triple TT;
   VersionTuple SDKVersion;
 
   void initMachOMCObjectFileInfo(const Triple &T);
@@ -436,8 +433,6 @@
   MCSection *getDwarfComdatSection(const char *Name, uint64_t Hash) const;
 
 public:
-  const Triple &getTargetTriple() const { return TT; }
-
   void setSDKVersion(const VersionTuple &TheSDKVersion) {
     SDKVersion = TheSDKVersion;
   }
Index: llvm/include/llvm/MC/MCContext.h
===================================================================
--- llvm/include/llvm/MC/MCContext.h
+++ llvm/include/llvm/MC/MCContext.h
@@ -74,8 +74,14 @@
     using DiagHandlerTy =
         std::function<void(const SMDiagnostic &, bool, const SourceMgr &,
                            std::vector<const MDNode *> &)>;
+    enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
 
   private:
+    Environment Env;
+
+    /// The triple for this object.
+    Triple TT;
+
     /// The SourceMgr for this object, if any.
     const SourceMgr *SrcMgr;
 
@@ -94,6 +100,9 @@
     /// The MCObjectFileInfo for this target.
     const MCObjectFileInfo *MOFI;
 
+    /// The MCSubtargetInfo for this target.
+    const MCSubtargetInfo *MSTI;
+
     std::unique_ptr<CodeViewContext> CVContext;
 
     /// Allocator object used for creating machine code objects.
@@ -383,8 +392,9 @@
     DenseSet<StringRef> ELFSeenGenericMergeableSections;
 
   public:
-    explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
-                       const MCObjectFileInfo *MOFI,
+    explicit MCContext(const Triple &TheTriple, const MCAsmInfo *MAI,
+                       const MCRegisterInfo *MRI, const MCObjectFileInfo *MOFI,
+                       const MCSubtargetInfo *MSTI,
                        const SourceMgr *Mgr = nullptr,
                        MCTargetOptions const *TargetOpts = nullptr,
                        bool DoAutoReset = true);
@@ -392,6 +402,9 @@
     MCContext &operator=(const MCContext &) = delete;
     ~MCContext();
 
+    Environment getObjectFileType() const { return Env; }
+
+    const Triple &getTargetTriple() const { return TT; }
     const SourceMgr *getSourceManager() const { return SrcMgr; }
 
     void initInlineSourceManager();
@@ -403,12 +416,16 @@
       this->DiagHandler = DiagHandler;
     }
 
+    void setObjectFileInfo(const MCObjectFileInfo *Mofi) { MOFI = Mofi; }
+
     const MCAsmInfo *getAsmInfo() const { return MAI; }
 
     const MCRegisterInfo *getRegisterInfo() const { return MRI; }
 
     const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
 
+    const MCSubtargetInfo *getSubtargetInfo() const { return MSTI; }
+
     CodeViewContext &getCVContext();
 
     void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
Index: lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
===================================================================
--- lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -163,8 +163,9 @@
       target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
   assert(m_asm_info.get() && m_subtype_info.get());
 
-  m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
-                                                m_reg_info.get(), nullptr);
+  m_context = std::make_unique<llvm::MCContext>(triple, m_asm_info.get(),
+                                                m_reg_info.get(), nullptr,
+                                                m_subtype_info.get());
   assert(m_context.get());
 
   m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
Index: lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
===================================================================
--- lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -159,8 +159,9 @@
       target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
   assert(m_asm_info.get() && m_subtype_info.get());
 
-  m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
-                                                m_reg_info.get(), nullptr);
+  m_context = std::make_unique<llvm::MCContext>(triple, m_asm_info.get(),
+                                                m_reg_info.get(), nullptr,
+                                                m_subtype_info.get());
   assert(m_context.get());
 
   m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
Index: lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
===================================================================
--- lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -905,7 +905,8 @@
     return Instance();
 
   std::unique_ptr<llvm::MCContext> context_up(
-      new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr));
+      new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
+                          reg_info_up.get(), nullptr, subtarget_info_up.get()));
   if (!context_up)
     return Instance();
 
Index: clang/tools/driver/cc1as_main.cpp
===================================================================
--- clang/tools/driver/cc1as_main.cpp
+++ clang/tools/driver/cc1as_main.cpp
@@ -383,11 +383,15 @@
   if (!Opts.SplitDwarfOutput.empty())
     DwoOS = getOutputStream(Opts.SplitDwarfOutput, Diags, IsBinary);
 
-  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
-  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
-  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+  // Build up the feature string from the target feature list.
+  std::string FS = llvm::join(Opts.Features, ",");
 
-  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr, &MCOptions);
+  std::unique_ptr<MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
+  assert(STI && "Unable to create subtarget info!");
+
+  MCContext Ctx(Triple(Opts.Triple), MAI.get(), MRI.get(), nullptr, STI.get(),
+                &SrcMgr, &MCOptions);
 
   bool PIC = false;
   if (Opts.RelocationModel == "static") {
@@ -400,7 +404,12 @@
     PIC = false;
   }
 
-  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx);
+  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
+  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
+  std::unique_ptr<MCObjectFileInfo> MOFI(
+      TheTarget->createMCObjectFileInfo(PIC, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
+
   if (Opts.SaveTemporaryLabels)
     Ctx.setAllowTemporaryLabels(false);
   if (Opts.GenDwarfForAssembly)
@@ -428,18 +437,11 @@
     Ctx.setGenDwarfRootFile(Opts.InputFile,
                             SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer());
 
-  // Build up the feature string from the target feature list.
-  std::string FS = llvm::join(Opts.Features, ",");
-
   std::unique_ptr<MCStreamer> Str;
 
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
   assert(MCII && "Unable to create instruction info!");
 
-  std::unique_ptr<MCSubtargetInfo> STI(
-      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
-  assert(STI && "Unable to create subtarget info!");
-
   raw_pwrite_stream *Out = FDOS.get();
   std::unique_ptr<buffer_ostream> BOS;
 
@@ -493,8 +495,7 @@
 
   // When -fembed-bitcode is passed to clang_as, a 1-byte marker
   // is emitted in __LLVM,__asm section if the object file is MachO format.
-  if (Opts.EmbedBitcode && Ctx.getObjectFileInfo()->getObjectFileType() ==
-                               MCObjectFileInfo::IsMachO) {
+  if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) {
     MCSection *AsmLabel = Ctx.getMachOSection(
         "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly());
     Str.get()->SwitchSection(AsmLabel);
Index: clang/lib/Parse/ParseStmtAsm.cpp
===================================================================
--- clang/lib/Parse/ParseStmtAsm.cpp
+++ clang/lib/Parse/ParseStmtAsm.cpp
@@ -577,19 +577,24 @@
       TheTarget->createMCAsmInfo(*MRI, TT, MCOptions));
   // Get the instruction descriptor.
   std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
-  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
   std::unique_ptr<llvm::MCSubtargetInfo> STI(
       TheTarget->createMCSubtargetInfo(TT, TO.CPU, FeaturesStr));
   // Target MCTargetDesc may not be linked in clang-based tools.
+
+  llvm::SourceMgr TempSrcMgr;
+  llvm::MCContext Ctx(TheTriple, MAI.get(), MRI.get(), nullptr, STI.get(),
+                      &TempSrcMgr);
+  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(
+      TheTarget->createMCObjectFileInfo(
+          /*PIC*/ false, Ctx));
+  Ctx.setObjectFileInfo(MOFI.get());
+
   if (!MAI || !MII || !MOFI || !STI) {
     Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
         << "target MC unavailable";
     return EmptyStmt();
   }
 
-  llvm::SourceMgr TempSrcMgr;
-  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
-  MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, Ctx);
   std::unique_ptr<llvm::MemoryBuffer> Buffer =
       llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to