Add code to the target lowering object file module to handle module flags.

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
This commit is contained in:
Bill Wendling 2012-02-14 21:28:13 +00:00
parent 03698deb25
commit b464d3ff72
4 changed files with 77 additions and 4 deletions

View 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;

View 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.

View 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) {
{

View 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 {