diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/Android.mk | 31 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 43 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DIE.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 232 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.cpp | 77 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp | 1 |
9 files changed, 265 insertions, 154 deletions
diff --git a/lib/CodeGen/AsmPrinter/Android.mk b/lib/CodeGen/AsmPrinter/Android.mk new file mode 100644 index 0000000..62601f0 --- /dev/null +++ b/lib/CodeGen/AsmPrinter/Android.mk @@ -0,0 +1,31 @@ +LOCAL_PATH := $(call my-dir) + +codegen_asmprinter_SRC_FILES := \ + AsmPrinter.cpp \ + DIE.cpp \ + DwarfDebug.cpp \ + DwarfException.cpp \ + DwarfLabel.cpp \ + DwarfPrinter.cpp \ + DwarfWriter.cpp \ + OcamlGCPrinter.cpp + +# For the host +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(codegen_asmprinter_SRC_FILES) +LOCAL_MODULE:= libLLVMAsmPrinter + +include $(LLVM_HOST_BUILD_MK) +include $(BUILD_HOST_STATIC_LIBRARY) + +# For the device +# ===================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(codegen_asmprinter_SRC_FILES) +LOCAL_MODULE:= libLLVMAsmPrinter + +include $(LLVM_DEVICE_BUILD_MK) +include $(BUILD_STATIC_LIBRARY) diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index fc08384..bbeb026 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -50,6 +50,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" #include <cerrno> +#include <ctype.h> using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); @@ -917,11 +918,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 +1717,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 +1764,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/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 349e0ac..63360c0 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -313,6 +313,7 @@ void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const { D->EmitSectionOffset(Label.getTag(), Section.getTag(), Label.getNumber(), Section.getNumber(), IsSmall, IsEH, UseSet); + D->getAsm()->O << '\n'; // FIXME: Necesssary? } /// SizeOf - Determine size of delta value in bytes. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5093dd9..5ad1e5e 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 b6801dc..2b08ba4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -50,26 +50,6 @@ DwarfException::~DwarfException() { delete ExceptionTimer; } -/// SizeOfEncodedValue - Return the size of the encoding in bytes. -unsigned DwarfException::SizeOfEncodedValue(unsigned Encoding) { - if (Encoding == dwarf::DW_EH_PE_omit) - return 0; - - switch (Encoding & 0x07) { - case dwarf::DW_EH_PE_absptr: - return TD->getPointerSize(); - case dwarf::DW_EH_PE_udata2: - return 2; - case dwarf::DW_EH_PE_udata4: - return 4; - case dwarf::DW_EH_PE_udata8: - return 8; - } - - assert(0 && "Invalid encoded value."); - return 0; -} - /// CreateLabelDiff - Emit a label and subtract it from the expression we /// already have. This is equivalent to emitting "foo - .", but we have to emit /// the label for "." directly. @@ -100,7 +80,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { TD->getPointerSize() : -TD->getPointerSize(); const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - + // Begin eh frame section. Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); @@ -128,30 +108,16 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // The personality presence indicates that language specific information will // show up in the eh frame. Find out how we are supposed to lower the // personality function reference: - const MCExpr *PersonalityRef = 0; - bool IsPersonalityIndirect = false, IsPersonalityPCRel = false; - if (PersonalityFn) { - // FIXME: HANDLE STATIC CODEGEN MODEL HERE. - - // In non-static mode, ask the object file how to represent this reference. - PersonalityRef = - TLOF.getSymbolForDwarfGlobalReference(PersonalityFn, Asm->Mang, - Asm->MMI, - IsPersonalityIndirect, - IsPersonalityPCRel); - } - - unsigned PerEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - if (IsPersonalityIndirect) - PerEncoding |= dwarf::DW_EH_PE_indirect; - unsigned LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - unsigned FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + + unsigned LSDAEncoding = TLOF.getLSDAEncoding(); + unsigned FDEEncoding = TLOF.getFDEEncoding(); + unsigned PerEncoding = TLOF.getPersonalityEncoding(); char Augmentation[6] = { 0 }; unsigned AugmentationSize = 0; char *APtr = Augmentation + 1; - if (PersonalityRef) { + if (PersonalityFn) { // There is a personality function. *APtr++ = 'P'; AugmentationSize += 1 + SizeOfEncodedValue(PerEncoding); @@ -181,20 +147,19 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); EOL("CIE Return Address Column"); - EmitULEB128(AugmentationSize, "Augmentation Size"); - EmitEncodingByte(PerEncoding, "Personality"); - - // If there is a personality, we need to indicate the function's location. - if (PersonalityRef) { - if (!IsPersonalityPCRel) - PersonalityRef = CreateLabelDiff(PersonalityRef, "personalityref_addr", - Index); + if (Augmentation[0]) { + EmitULEB128(AugmentationSize, "Augmentation Size"); - O << MAI->getData32bitsDirective() << *PersonalityRef; - EOL("Personality"); - - EmitEncodingByte(LSDAEncoding, "LSDA"); - EmitEncodingByte(FDEEncoding, "FDE"); + // If there is a personality, we need to indicate the function's location. + if (PersonalityFn) { + EmitEncodingByte(PerEncoding, "Personality"); + EmitReference(PersonalityFn, PerEncoding); + EOL("Personality"); + } + if (UsesLSDA[Index]) + EmitEncodingByte(LSDAEncoding, "LSDA"); + if (FDEEncoding != dwarf::DW_EH_PE_absptr) + EmitEncodingByte(FDEEncoding, "FDE"); } // Indicate locations of general callee saved registers in frame. @@ -216,8 +181,12 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { "Should not emit 'available externally' functions at all"); const Function *TheFunc = EHFrameInfo.function; + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); + unsigned LSDAEncoding = TLOF.getLSDAEncoding(); + unsigned FDEEncoding = TLOF.getFDEEncoding(); + + Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); // Externally visible entry into the functions eh frame info. If the // corresponding function is static, this should not be externally visible. @@ -255,7 +224,8 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { // EH frame header. EmitDifference("eh_frame_end", EHFrameInfo.Number, - "eh_frame_begin", EHFrameInfo.Number, true); + "eh_frame_begin", EHFrameInfo.Number, + true); EOL("Length of Frame Information Entry"); EmitLabel("eh_frame_begin", EHFrameInfo.Number); @@ -266,33 +236,23 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { EOL("FDE CIE offset"); - EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); + EmitReference("eh_func_begin", EHFrameInfo.Number, FDEEncoding); EOL("FDE initial location"); EmitDifference("eh_func_end", EHFrameInfo.Number, - "eh_func_begin", EHFrameInfo.Number, true); + "eh_func_begin", EHFrameInfo.Number, + SizeOfEncodedValue(FDEEncoding) == 4); EOL("FDE address range"); // If there is a personality and landing pads then point to the language // specific data area in the exception table. if (MMI->getPersonalities()[0] != NULL) { + unsigned Size = SizeOfEncodedValue(LSDAEncoding); - if (Asm->TM.getLSDAEncoding() != DwarfLSDAEncoding::EightByte) { - EmitULEB128(4, "Augmentation size"); - - if (EHFrameInfo.hasLandingPads) - EmitReference("exception", EHFrameInfo.Number, true, true); - else - Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); - } else { - EmitULEB128(TD->getPointerSize(), "Augmentation size"); - - if (EHFrameInfo.hasLandingPads) { - EmitReference("exception", EHFrameInfo.Number, true, false); - } else { - Asm->OutStreamer.EmitIntValue(0, TD->getPointerSize(), - 0/*addrspace*/); - } - } + EmitULEB128(Size, "Augmentation size"); + if (EHFrameInfo.hasLandingPads) + EmitReference("exception", EHFrameInfo.Number, LSDAEncoding); + else + Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/); EOL("Language Specific Data Area"); } else { @@ -407,20 +367,22 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, if (NumShared < TypeIds.size()) { unsigned SizeAction = 0; - ActionEntry *PrevAction = 0; + unsigned PrevAction = (unsigned)-1; if (NumShared) { const unsigned SizePrevIds = PrevLPI->TypeIds.size(); assert(Actions.size()); - PrevAction = &Actions.back(); - SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) + - MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); + PrevAction = Actions.size() - 1; + SizeAction = + MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) + + MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); for (unsigned j = NumShared; j != SizePrevIds; ++j) { + assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); SizeAction -= - MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); - SizeAction += -PrevAction->NextAction; - PrevAction = PrevAction->Previous; + MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); + SizeAction += -Actions[PrevAction].NextAction; + PrevAction = Actions[PrevAction].Previous; } } @@ -437,7 +399,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; Actions.push_back(Action); - PrevAction = &Actions.back(); + PrevAction = Actions.size() - 1; } // Record the first action of the landing pad site. @@ -447,7 +409,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, // Information used when created the call-site table. The action record // field of the call site record is the offset of the first associated // action record, relative to the start of the actions table. This value is - // biased by 1 (1 in dicating the start of the actions table), and 0 + // biased by 1 (1 indicating the start of the actions table), and 0 // indicates that there are no actions. FirstActions.push_back(FirstAction); @@ -648,8 +610,7 @@ void DwarfException::EmitExceptionTable() { // landing pad site. SmallVector<ActionEntry, 32> Actions; SmallVector<unsigned, 64> FirstActions; - unsigned SizeActions = ComputeActionsTable(LandingPads, Actions, - FirstActions); + unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions); // Invokes and nounwind calls have entries in PadMap (due to being bracketed // by try-range labels when lowered). Ordinary calls do not, so appropriate @@ -677,29 +638,29 @@ 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. const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); - unsigned TTypeFormat; + unsigned TTypeEncoding; unsigned TypeFormatSize; if (!HaveTTData) { // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say // that we're omitting that bit. - TTypeFormat = dwarf::DW_EH_PE_omit; + TTypeEncoding = dwarf::DW_EH_PE_omit; TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr); } else { // Okay, we have actual filters or typeinfos to emit. As such, we need to @@ -729,21 +690,28 @@ void DwarfException::EmitExceptionTable() { // somewhere. This predicate should be moved to a shared location that is // in target-independent code. // - if (LSDASection->getKind().isWriteable() || - Asm->TM.getRelocationModel() == Reloc::Static) - TTypeFormat = dwarf::DW_EH_PE_absptr; - else - TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4; - - TypeFormatSize = SizeOfEncodedValue(TTypeFormat); + TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); + TypeFormatSize = SizeOfEncodedValue(TTypeEncoding); } // Begin the exception table. 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 @@ -752,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 @@ -761,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(TTypeFormat, "@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; @@ -836,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) { @@ -906,23 +870,23 @@ void DwarfException::EmitExceptionTable() { } // Emit the Catch TypeInfos. - if (TypeInfos.size() != 0) EOL("-- Catch TypeInfos --"); + if (!TypeInfos.empty()) EOL("-- Catch TypeInfos --"); for (std::vector<GlobalVariable *>::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { const GlobalVariable *GV = *I; - PrintRelDirective(); if (GV) { - O << *Asm->GetGlobalValueSymbol(GV); + EmitReference(GV, TTypeEncoding); EOL("TypeInfo"); } else { + PrintRelDirective(TTypeEncoding); O << "0x0"; EOL(""); } } // Emit the Exception Specifications. - if (FilterIds.size() != 0) EOL("-- Filter IDs --"); + if (!FilterIds.empty()) EOL("-- Filter IDs --"); for (std::vector<unsigned>::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { unsigned TypeID = *I; diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h index 06033a1..3db1a00 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/lib/CodeGen/AsmPrinter/DwarfException.h @@ -76,9 +76,6 @@ class DwarfException : public DwarfPrinter { /// ExceptionTimer - Timer for the Dwarf exception writer. Timer *ExceptionTimer; - /// SizeOfEncodedValue - Return the size of the encoding in bytes. - unsigned SizeOfEncodedValue(unsigned Encoding); - /// EmitCIE - Emit a Common Information Entry (CIE). This holds information /// that is shared among many Frame Description Entries. There is at least /// one CIE in every non-empty .debug_frame section. @@ -135,7 +132,7 @@ class DwarfException : public DwarfPrinter { struct ActionEntry { int ValueForTypeID; // The value to write - may not be equal to the type id. int NextAction; - struct ActionEntry *Previous; + unsigned Previous; }; /// CallSiteEntry - Structure describing an entry in the call-site table. diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp index 415390b..28ff0eb 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // Emit general DWARF directives. -// +// //===----------------------------------------------------------------------===// #include "DwarfPrinter.h" @@ -18,13 +18,17 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/ADT/SmallString.h" using namespace llvm; DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, @@ -33,6 +37,26 @@ DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL), SubprogramCount(0), Flavor(flavor), SetCounter(1) {} +/// SizeOfEncodedValue - Return the size of the encoding in bytes. +unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const { + if (Encoding == dwarf::DW_EH_PE_omit) + return 0; + + switch (Encoding & 0x07) { + case dwarf::DW_EH_PE_absptr: + return TD->getPointerSize(); + case dwarf::DW_EH_PE_udata2: + return 2; + case dwarf::DW_EH_PE_udata4: + return 4; + case dwarf::DW_EH_PE_udata8: + return 8; + } + + assert(0 && "Invalid encoded value."); + return 0; +} + void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const { if (isInSection && MAI->getDwarfSectionOffsetDirective()) O << MAI->getDwarfSectionOffsetDirective(); @@ -42,6 +66,14 @@ void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const { O << MAI->getData64bitsDirective(); } +void DwarfPrinter::PrintRelDirective(unsigned Encoding) const { + unsigned Size = SizeOfEncodedValue(Encoding); + assert((Size == 4 || Size == 8) && "Do not support other types or rels!"); + + O << (Size == 4 ? + MAI->getData32bitsDirective() : MAI->getData64bitsDirective()); +} + /// EOL - Print a newline character to asm stream. If a comment is present /// then it will be printed first. Comments should not contain '\n'. void DwarfPrinter::EOL(const Twine &Comment) const { @@ -127,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*/); + } } @@ -195,6 +233,31 @@ void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative, if (IsPCRelative) O << "-" << MAI->getPCSymbol(); } +void DwarfPrinter::EmitReference(const char *Tag, unsigned Number, + unsigned Encoding) const { + SmallString<64> Name; + raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() + << Tag << Number; + + MCSymbol *Sym = Asm->OutContext.GetOrCreateSymbol(Name.str()); + EmitReference(Sym, Encoding); +} + +void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const { + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + + PrintRelDirective(Encoding); + O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);; +} + +void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const { + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + + PrintRelDirective(Encoding); + O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, + Asm->MMI, Encoding);; +} + /// EmitDifference - Emit the difference between two labels. If this assembler /// supports .set, we emit a .set of a temporary and then use it in the .word. void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi, @@ -248,7 +311,6 @@ void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section, PrintRelDirective(IsSmall); PrintLabelName("set", SetCounter, Flavor); ++SetCounter; - O << "\n"; } else { PrintRelDirective(IsSmall, true); PrintLabelName(Label, LabelNumber); @@ -257,7 +319,6 @@ void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section, O << "-"; PrintLabelName(Section, SectionNumber); } - O << "\n"; } } diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h index 69d9c27..bd715f2 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h @@ -28,6 +28,7 @@ class Module; class MCAsmInfo; class TargetData; class TargetRegisterInfo; +class GlobalValue; class MCSymbol; class Twine; @@ -85,6 +86,10 @@ public: const MCAsmInfo *getMCAsmInfo() const { return MAI; } const TargetData *getTargetData() const { return TD; } + /// SizeOfEncodedValue - Return the size of the encoding in bytes. + unsigned SizeOfEncodedValue(unsigned Encoding) const; + + void PrintRelDirective(unsigned Encoding) const; void PrintRelDirective(bool Force32Bit = false, bool isInSection = false) const; @@ -106,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. @@ -140,6 +146,10 @@ public: void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false, bool Force32Bit = false) const; + void EmitReference(const char *Tag, unsigned Number, unsigned Encoding) const; + void EmitReference(const MCSymbol *Sym, unsigned Encoding) const; + void EmitReference(const GlobalValue *GV, unsigned Encoding) const; + /// EmitDifference - Emit the difference between two labels. void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo, bool IsSmall = false) { diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 3531ed6..a9502fd 100644 --- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -22,6 +22,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" +#include <ctype.h> using namespace llvm; namespace { |