Add code to the target lowering object file module to handle module flags.
authorBill Wendling <isanbard@gmail.com>
Tue, 14 Feb 2012 21:28:13 +0000 (21:28 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 14 Feb 2012 21:28:13 +0000 (21:28 +0000)
The MachO back-end needs to emit the garbage collection flags specified in the
module flags. This is a WIP, so the front-end hasn't been modified to emit these
flags just yet. Documentation and front-end switching to occur soon.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150507 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
include/llvm/Target/TargetLoweringObjectFile.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp

index 2a022657bd9e2c703be8fcbfd9f8d1392d863fc6..94b7cf4f95b46ac2aa55e3a69a2ea50efaf889d1 100644 (file)
@@ -78,6 +78,11 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
 public:
   virtual ~TargetLoweringObjectFileMachO() {}
 
+  /// emitModuleFlags - Emit the module flags that specify the garbage
+  /// collection information.
+  virtual void emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags,
+                               Mangler *Mang, const TargetMachine &TM) const;
+
   virtual const MCSection *
   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
                          Mangler *Mang, const TargetMachine &TM) const;
index 04fe2208b2841b4f01f324560bb9e2859221d422..d1151a10d2e8c13c3022b0d07c9e3b52dee2fa7c 100644 (file)
@@ -29,6 +29,7 @@ namespace llvm {
   class MCSectionMachO;
   class MCSymbol;
   class MCStreamer;
+  class NamedMDNode;
   class GlobalValue;
   class TargetMachine;
   
@@ -53,7 +54,12 @@ public:
   virtual void emitPersonalityValue(MCStreamer &Streamer,
                                     const TargetMachine &TM,
                                     const MCSymbol *Sym) const;
-  
+
+  /// emitModuleFlags - Emit the module flags that the platform cares about.
+  virtual void emitModuleFlags(MCStreamer &, NamedMDNode *, Mangler *,
+                               const TargetMachine &) const {
+  }
+
   /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
   /// decide not to emit the UsedDirective for some symbols in llvm.used.
   /// FIXME: REMOVE this (rdar://7071300)
@@ -86,9 +92,7 @@ public:
                                     const TargetMachine &TM) const {
     return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
   }
-  
-  
-  
+
   /// getExplicitSectionGlobal - Targets should implement this method to assign
   /// a section to globals with an explicit section specfied.  The
   /// implementation of this method can assume that GV->hasSection() is true.
index 241f20097edaf06f150b84094e81c29f0a59c922..80d90d668de06138bf137112dd0a6eeffbb6d737 100644 (file)
@@ -857,6 +857,10 @@ bool AsmPrinter::doFinalization(Module &M) {
     EmitVisibility(Name, V, false);
   }
 
+  // Emit module flags.
+  if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata())
+    getObjFileLowering().emitModuleFlags(OutStreamer, ModFlags, Mang, TM);
+
   // Finalize debug and EH information.
   if (DE) {
     {
index 3a71f4f126712392b7d1d710c8666e0ed067b0c7..1b62419aabd95a65e678c5939d644758abab6ee0 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
+#include "llvm/Module.h"
 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
@@ -370,6 +371,65 @@ TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const {
 //                                 MachO
 //===----------------------------------------------------------------------===//
 
+/// emitModuleFlags - Emit the module flags that specify the garbage collection
+/// information.
+void TargetLoweringObjectFileMachO::
+emitModuleFlags(MCStreamer &Streamer, NamedMDNode *ModFlags,
+                Mangler *Mang, const TargetMachine &TM) const {
+  StringRef Version("Objective-C Image Info Version");
+  StringRef SectionSpec("Objective-C Image Info Section");
+  StringRef GC("Objective-C Garbage Collection");
+  StringRef GCOnly("Objective-C GC Only");
+
+  unsigned VersionVal = 0;
+  unsigned GCFlags = 0;
+  StringRef Section;
+
+  for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) {
+    MDNode *Flag = ModFlags->getOperand(i);
+    Value *Behavior = Flag->getOperand(0);
+
+    // Ignore flags with 'Require' behavior.
+    if (cast<ConstantInt>(Behavior)->getZExtValue() == Module::Require)
+      continue;
+
+    Value *Key = Flag->getOperand(1);
+    Value *Val = Flag->getOperand(2);
+
+    StringRef KeyStr = cast<MDString>(Key)->getString();
+
+    if (KeyStr == Version)
+      VersionVal = cast<ConstantInt>(Val)->getZExtValue();
+    else if (KeyStr == GC || KeyStr == GCOnly)
+      GCFlags |= cast<ConstantInt>(Val)->getZExtValue();
+    else if (KeyStr == SectionSpec)
+      Section = cast<MDString>(Val)->getString();
+  }
+
+  // The section is mandatory. If we don't have it, then we don't have image
+  // info information.
+  if (Section.empty()) return;
+
+  uint32_t Values[2] = { VersionVal, GCFlags };
+  Module *M = ModFlags->getParent();
+  Constant *Init = ConstantDataArray::get(M->getContext(), Values);
+  GlobalVariable *GV = new GlobalVariable(*M, Init->getType(), false,
+                                          GlobalValue::InternalLinkage, Init,
+                                          "\01L_OBJC_IMAGE_INFO");
+  GV->setSection(Section);
+
+  MCSymbol *GVSym = Mang->getSymbol(GV);
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
+  const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM);
+
+  Streamer.SwitchSection(TheSection);
+  Streamer.EmitLabel(GVSym);
+
+  Streamer.EmitIntValue(VersionVal, 4);
+  Streamer.EmitIntValue(GCFlags, 4);
+  Streamer.AddBlankLine();
+}
+
 const MCSection *TargetLoweringObjectFileMachO::
 getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
                          Mangler *Mang, const TargetMachine &TM) const {