aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp69
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp32
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h11
3 files changed, 103 insertions, 9 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 9453a80061..d506d7e507 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -156,6 +156,11 @@ bool AsmPrinter::doInitialization(Module &M) {
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
MMI->AnalyzeModule(M);
+ // @LOCALMOD-BEGIN
+ IsPlainObject =
+ (MMI->getModule()->getOutputFormat() == Module::ObjectOutputFormat);
+ // @LOCALMOD-END
+
// Initialize TargetLoweringObjectFile.
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
@@ -272,6 +277,17 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
MCSymbol *GVSym = Mang->getSymbol(GV);
EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());
+ // @LOCALMOD-BEGIN
+ // For .pexe and .pso files, emit ELF type STT_OBJECT or STT_TLS instead
+ // of NOTYPE for undefined symbols.
+ // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2527
+ if (!GV->hasInitializer() && !IsPlainObject) {
+ OutStreamer.EmitSymbolAttribute(GVSym,
+ GV->isThreadLocal() ? MCSA_ELF_TypeTLS
+ : MCSA_ELF_TypeObject);
+ }
+ // @LOCALMOD-END
+
if (!GV->hasInitializer()) // External globals require no extra code.
return;
@@ -681,9 +697,14 @@ void AsmPrinter::EmitFunctionBody() {
break;
case TargetOpcode::EH_LABEL:
- case TargetOpcode::GC_LABEL:
+ case TargetOpcode::GC_LABEL: {
+ // @LOCALMOD-START
+ unsigned LabelAlign = GetTargetLabelAlign(II);
+ if (LabelAlign) EmitAlignment(LabelAlign);
+ // @LOCALMOD-END
OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
break;
+ }
case TargetOpcode::INLINEASM:
EmitInlineAsm(II);
break;
@@ -699,6 +720,20 @@ void AsmPrinter::EmitFunctionBody() {
case TargetOpcode::KILL:
if (isVerbose()) emitKill(II, *this);
break;
+ // @LOCALMOD-BEGIN
+ case TargetOpcode::BUNDLE_ALIGN_START:
+ OutStreamer.EmitBundleAlignStart();
+ break;
+ case TargetOpcode::BUNDLE_ALIGN_END:
+ OutStreamer.EmitBundleAlignEnd();
+ break;
+ case TargetOpcode::BUNDLE_LOCK:
+ OutStreamer.EmitBundleLock();
+ break;
+ case TargetOpcode::BUNDLE_UNLOCK:
+ OutStreamer.EmitBundleUnlock();
+ break;
+ // @LOCALMOD-END
default:
if (!TM.hasMCUseLoc())
MCLineEntry::Make(&OutStreamer, getCurrentSection());
@@ -848,6 +883,16 @@ bool AsmPrinter::doFinalization(Module &M) {
const Function &F = *I;
if (!F.isDeclaration())
continue;
+
+ // @LOCALMOD-BEGIN
+ // For .pexe and .pso files, emit STT_FUNC for function declarations.
+ // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2527
+ if (!IsPlainObject) {
+ OutStreamer.EmitSymbolAttribute(Mang->getSymbol(&F),
+ MCSA_ELF_TypeFunction);
+ }
+ // @LOCALMOD-END
+
GlobalValue::VisibilityTypes V = F.getVisibility();
if (V == GlobalValue::DefaultVisibility)
continue;
@@ -1065,12 +1110,25 @@ void AsmPrinter::EmitJumpTableInfo() {
if (// In PIC mode, we need to emit the jump table to the same section as the
// function body itself, otherwise the label differences won't make sense.
// FIXME: Need a better predicate for this: what about custom entries?
- MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
+ (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
// We should also do if the section name is NULL or function is declared
// in discardable section
// FIXME: this isn't the right predicate, should be based on the MCSection
// for the function.
- F->isWeakForLinker()) {
+ // @LOCALMOD-START
+ // the original code is a hack
+ // jumptables usually end up in .rodata
+ // but for functions with weak linkage there is a chance that the are
+ // not needed. So in order to be discard the function AND the jumptable
+ // they keep them both in .text. This fix only works if we never discard
+ // weak functions. This is guaranteed because the bitcode linker already
+ // throws out unused ones.
+ // TODO: Investigate the other case of concern -- PIC code.
+ // Concern is about jumptables being in a different section: can the
+ // rodata and text be too far apart for a RIP-relative offset?
+ F->isWeakForLinker())
+ && !UseReadOnlyJumpTables()) {
+ // @LOCALMOD-END
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
} else {
// Otherwise, drop it in the readonly section.
@@ -1097,7 +1155,7 @@ void AsmPrinter::EmitJumpTableInfo() {
// .set directive for each unique entry. This reduces the number of
// relocations the assembler will generate for the jump table.
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
- MAI->hasSetDirective()) {
+ MAI->hasSetDirective() && !UseReadOnlyJumpTables()) { // @LOCALMOD
SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;
const TargetLowering *TLI = TM.getTargetLowering();
const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);
@@ -1180,7 +1238,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
// If we have emitted set directives for the jump table entries, print
// them rather than the entries themselves. If we're emitting PIC, then
// emit the table entries as differences between two text section labels.
- if (MAI->hasSetDirective()) {
+ if (MAI->hasSetDirective() && !UseReadOnlyJumpTables()) { // @LOCALMOD
// If we used .set, reference the .set's symbol.
Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()),
OutContext);
@@ -1200,7 +1258,6 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
}
-
/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
/// special global used by LLVM. If so, emit it and return true, otherwise
/// do nothing and return false.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 52b10d7ca6..ee8a6f36e7 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -567,7 +567,8 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
/// maps as well.
unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,
- StringRef DirName) {
+ StringRef DirName,
+ StringRef Extra) { // @LOCALMOD
// If FE did not provide a file name, then assume stdin.
if (FileName.empty())
return GetOrCreateSourceID("<stdin>", StringRef());
@@ -583,6 +584,9 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,
NamePair += DirName;
NamePair += '\0'; // Zero bytes are not allowed in paths.
NamePair += FileName;
+ // @LOCALMOD
+ NamePair += '\0'; // Zero bytes are not allowed in paths.
+ NamePair += Extra;
StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(NamePair, SrcId);
if (Ent.getValue() != SrcId)
@@ -594,13 +598,37 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,
return SrcId;
}
+// @LOCALMOD-BEGIN
+// A special version of GetOrCreateSourceID for CompileUnits.
+// It is possible that with bitcode linking, we end up with distinct
+// compile units based on the same source file.
+// E.g., compile foo.c with -DMACRO1 to foo1.bc, then compile
+// foo.c again with -DMACRO2 to foo2.bc and link.
+// We use additional information to form a unique ID in that case.
+unsigned DwarfDebug::GetOrCreateCompileUnitID(StringRef Filename,
+ StringRef Dirname,
+ const MDNode *N) {
+ std::string DIUnitStr;
+ raw_string_ostream ostr(DIUnitStr);
+
+ // Using information from the compile unit (N)'s getEnumTypes(),
+ // getRetainedTypes(), getSubprograms(), getGlobalVariables()
+ // could be pretty expensive.
+ // Cheat and use the MDNode's address as an additional identifying factor.
+ // constructCompileUnit() is only called once per compile unit.
+ ostr << static_cast<const void*>(N);
+ return GetOrCreateSourceID(Filename, Dirname, ostr.str());
+}
+// @LOCALMOD-END
+
/// constructCompileUnit - Create new CompileUnit for the given
/// metadata node with tag DW_TAG_compile_unit.
CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
DICompileUnit DIUnit(N);
StringRef FN = DIUnit.getFilename();
CompilationDir = DIUnit.getDirectory();
- unsigned ID = GetOrCreateSourceID(FN, CompilationDir);
+ // @LOCALMOD
+ unsigned ID = GetOrCreateCompileUnitID(FN, CompilationDir, N);
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
CompileUnit *NewCU = new CompileUnit(ID, DIUnit.getLanguage(), Die,
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 20e232dfc8..5508674bc9 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -524,7 +524,16 @@ public:
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map.
- unsigned GetOrCreateSourceID(StringRef DirName, StringRef FullName);
+ unsigned GetOrCreateSourceID(StringRef DirName, StringRef FullName,
+ StringRef Extra = ""); // @LOCALMOD for Extra
+
+ // @LOCALMOD-BEGIN - Create an ID for CompileUnits, taking extra care
+ // in the case that we have multiple compile units coming from the
+ // same source file and directory.
+ unsigned GetOrCreateCompileUnitID(StringRef FileName, StringRef DirName,
+ const MDNode *N);
+ // @LOCALMOD-END
+
/// getStringPool - returns the entry into the start of the pool.
MCSymbol *getStringPool();