diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 42 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 79 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.h | 3 |
5 files changed, 109 insertions, 48 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index fc0838459388b..bd2b1b61971a8 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -917,11 +917,10 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, if (NumBits == 0) return; // No need to emit alignment. - unsigned FillValue = 0; if (getCurrentSection()->getKind().isText()) - FillValue = MAI->getTextAlignFillValue(); - - OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0); + OutStreamer.EmitCodeAlignment(1 << NumBits); + else + OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); } /// LowerConstant - Lower the specified LLVM Constant to an MCExpr. @@ -1717,7 +1716,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { } // Print the main label for the block. - if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) { + if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { if (VerboseAsm) { // NOTE: Want this comment at start of line. O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':'; @@ -1764,6 +1763,39 @@ void AsmPrinter::printOffset(int64_t Offset) const { O << Offset; } +/// isBlockOnlyReachableByFallthough - Return true if the basic block has +/// exactly one predecessor and the control transfer mechanism between +/// the predecessor and this block is a fall-through. +bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) + const { + // If this is a landing pad, it isn't a fall through. If it has no preds, + // then nothing falls through to it. + if (MBB->isLandingPad() || MBB->pred_empty()) + return false; + + // If there isn't exactly one predecessor, it can't be a fall through. + MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; + ++PI2; + if (PI2 != MBB->pred_end()) + return false; + + // The predecessor has to be immediately before this block. + const MachineBasicBlock *Pred = *PI; + + if (!Pred->isLayoutSuccessor(MBB)) + return false; + + // If the block is completely empty, then it definitely does fall through. + if (Pred->empty()) + return true; + + // Otherwise, check the last instruction. + const MachineInstr &LastInst = Pred->back(); + return !LastInst.getDesc().isBarrier(); +} + + + GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { if (!S->usesMetadata()) return 0; diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5093dd9a9c11b..5ad1e5ea05096 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -238,7 +238,18 @@ public: LIndex = DSI; } } - setLastInsn(LastInsn); + + unsigned CurrentLastInsnIndex = 0; + if (const MachineInstr *CL = getLastInsn()) + CurrentLastInsnIndex = MIIndexMap[CL]; + unsigned FIndex = MIIndexMap[getFirstInsn()]; + + // Set LastInsn as the last instruction for this scope only if + // it follows + // 1) this scope's first instruction and + // 2) current last instruction for this scope, if any. + if (LIndex >= CurrentLastInsnIndex && LIndex >= FIndex) + setLastInsn(LastInsn); } #ifndef NDEBUG @@ -1166,7 +1177,9 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { return SPDie; SPDie = new DIE(dwarf::DW_TAG_subprogram); - addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); + // Constructors and operators for anonymous aggregates do not have names. + if (!SP.getName().empty()) + addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); StringRef LinkageName = SP.getLinkageName(); if (!LinkageName.empty()) diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index c6c59f5998568..2b08ba4ad31f0 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -638,18 +638,18 @@ void DwarfException::EmitExceptionTable() { const unsigned LandingPadSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4); bool IsSJLJ = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; - unsigned SizeSites; + unsigned CallSiteTableLength; if (IsSJLJ) - SizeSites = 0; + CallSiteTableLength = 0; else - SizeSites = CallSites.size() * + CallSiteTableLength = CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { - SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action); + CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action); if (IsSJLJ) - SizeSites += MCAsmInfo::getULEB128Size(i); + CallSiteTableLength += MCAsmInfo::getULEB128Size(i); } // Type infos. @@ -698,7 +698,20 @@ void DwarfException::EmitExceptionTable() { Asm->OutStreamer.SwitchSection(LSDASection); Asm->EmitAlignment(2, 0, 0, false); + // Emit the LSDA. O << "GCC_except_table" << SubprogramCount << ":\n"; + EmitLabel("exception", SubprogramCount); + + if (IsSJLJ) { + SmallString<16> LSDAName; + raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << + "_LSDA_" << Asm->getFunctionNumber(); + O << LSDAName.str() << ":\n"; + } + + // Emit the LSDA header. + EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); + EmitEncodingByte(TTypeEncoding, "@TType"); // The type infos need to be aligned. GCC does this by inserting padding just // before the type infos. However, this changes the size of the exception @@ -707,7 +720,7 @@ void DwarfException::EmitExceptionTable() { // So by increasing the size by inserting padding, you may increase the number // of bytes used for writing the size. If it increases, say by one byte, then // you now need to output one less byte of padding to get the type infos - // aligned. However this decreases the size of the exception table. This + // aligned. However this decreases the size of the exception table. This // changes the value you have to output for the exception table size. Due to // the variable length encoding, the number of bytes used for writing the // length may decrease. If so, you then have to increase the amount of @@ -716,41 +729,35 @@ void DwarfException::EmitExceptionTable() { // We chose another solution: don't output padding inside the table like GCC // does, instead output it before the table. unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; - unsigned TyOffset = sizeof(int8_t) + // Call site format - MCAsmInfo::getULEB128Size(SizeSites) + // Call site table length - SizeSites + SizeActions + SizeTypes; - unsigned TotalSize = sizeof(int8_t) + // LPStart format - sizeof(int8_t) + // TType format - (HaveTTData ? - MCAsmInfo::getULEB128Size(TyOffset) : 0) + // TType base offset - TyOffset; + unsigned CallSiteTableLengthSize = + MCAsmInfo::getULEB128Size(CallSiteTableLength); + unsigned TTypeBaseOffset = + sizeof(int8_t) + // Call site format + CallSiteTableLengthSize + // Call site table length size + CallSiteTableLength + // Call site table length + SizeActions + // Actions size + SizeTypes; + unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset); + unsigned TotalSize = + sizeof(int8_t) + // LPStart format + sizeof(int8_t) + // TType format + (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size + TTypeBaseOffset; // TType base offset unsigned SizeAlign = (4 - TotalSize) & 3; - for (unsigned i = 0; i != SizeAlign; ++i) { - Asm->EmitInt8(0); - EOL("Padding"); - } - - EmitLabel("exception", SubprogramCount); - - if (IsSJLJ) { - SmallString<16> LSDAName; - raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << - "_LSDA_" << Asm->getFunctionNumber(); - O << LSDAName.str() << ":\n"; + if (HaveTTData) { + // Account for any extra padding that will be added to the call site table + // length. + EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); + SizeAlign = 0; } - // Emit the header. - EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); - EmitEncodingByte(TTypeEncoding, "@TType"); - - if (HaveTTData) - EmitULEB128(TyOffset, "@TType base offset"); - // SjLj Exception handling if (IsSJLJ) { EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); - EmitULEB128(SizeSites, "Call site table length"); + + // Add extra padding if it wasn't added to the TType base offset. + EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); // Emit the landing pad site information. unsigned idx = 0; @@ -791,7 +798,9 @@ void DwarfException::EmitExceptionTable() { // Emit the landing pad call site table. EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); - EmitULEB128(SizeSites, "Call site table length"); + + // Add extra padding if it wasn't added to the TType base offset. + EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp index 1299d048e4be6..28ff0ebb93fc0 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp @@ -159,29 +159,35 @@ void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const { Value >>= 7; IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; if (IsMore) Byte |= 0x80; - Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); } while (IsMore); } /// EmitULEB128 - emit the specified signed leb128 value. -void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc) const { +void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc, + unsigned PadTo) const { if (Asm->VerboseAsm && Desc) Asm->OutStreamer.AddComment(Desc); - if (MAI->hasLEB128()) { + if (MAI->hasLEB128() && PadTo == 0) { O << "\t.uleb128\t" << Value; Asm->OutStreamer.AddBlankLine(); return; } - // If we don't have .uleb128, emit as .bytes. + // If we don't have .uleb128 or we want to emit padding, emit as .bytes. do { unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); Value >>= 7; - if (Value) Byte |= 0x80; + if (Value || PadTo != 0) Byte |= 0x80; Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); } while (Value); + + if (PadTo) { + if (PadTo > 1) + Asm->OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/); + Asm->OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/); + } } diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h index 73de398e35e56..bd715f21548ba 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h @@ -111,7 +111,8 @@ public: void EmitSLEB128(int Value, const char *Desc) const; /// EmitULEB128 - emit the specified unsigned leb128 value. - void EmitULEB128(unsigned Value, const char *Desc = 0) const; + void EmitULEB128(unsigned Value, const char *Desc = 0, + unsigned PadTo = 0) const; /// PrintLabelName - Print label name in form used by Dwarf writer. |