diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 69 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 32 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 11 |
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(); |