summaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
commit829000e035f46f2a227a5466e4e427a2f3cc00a9 (patch)
treebe5a687969f682edded4aa6f13594ffd9aa9030e /lib/CodeGen/AsmPrinter
parent1e7804dbd25b8dbf534c850355d70ad215206f4b (diff)
Notes
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp328
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp178
2 files changed, 271 insertions, 235 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 6b24e24d3716..876f628336fa 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -807,124 +807,145 @@ void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const {
// Print out the specified constant, without a storage class. Only the
// constants valid in constant expressions can occur here.
void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
- if (CV->isNullValue() || isa<UndefValue>(CV))
+ if (CV->isNullValue() || isa<UndefValue>(CV)) {
O << '0';
- else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ return;
+ }
+
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
O << CI->getZExtValue();
- } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
+ return;
+ }
+
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
// This is a constant address for a global variable or function. Use the
// name of the variable or function as the address value.
O << Mang->getMangledName(GV);
- } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+ return;
+ }
+
+ if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
+ GetBlockAddressSymbol(BA)->print(O, MAI);
+ return;
+ }
+
+ const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
+ if (CE == 0) {
+ llvm_unreachable("Unknown constant value!");
+ O << '0';
+ return;
+ }
+
+ switch (CE->getOpcode()) {
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ default:
+ llvm_unreachable("FIXME: Don't support this constant cast expr");
+ case Instruction::GetElementPtr: {
+ // generate a symbolic expression for the byte address
const TargetData *TD = TM.getTargetData();
- unsigned Opcode = CE->getOpcode();
- switch (Opcode) {
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- llvm_unreachable("FIXME: Don't support this constant cast expr");
- case Instruction::GetElementPtr: {
- // generate a symbolic expression for the byte address
- const Constant *ptrVal = CE->getOperand(0);
- SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
- if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
- idxVec.size())) {
- // Truncate/sext the offset to the pointer size.
- if (TD->getPointerSizeInBits() != 64) {
- int SExtAmount = 64-TD->getPointerSizeInBits();
- Offset = (Offset << SExtAmount) >> SExtAmount;
- }
-
- if (Offset)
- O << '(';
- EmitConstantValueOnly(ptrVal);
- if (Offset > 0)
- O << ") + " << Offset;
- else if (Offset < 0)
- O << ") - " << -Offset;
- } else {
- EmitConstantValueOnly(ptrVal);
- }
- break;
+ const Constant *ptrVal = CE->getOperand(0);
+ SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
+ int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
+ idxVec.size());
+ if (Offset == 0)
+ return EmitConstantValueOnly(ptrVal);
+
+ // Truncate/sext the offset to the pointer size.
+ if (TD->getPointerSizeInBits() != 64) {
+ int SExtAmount = 64-TD->getPointerSizeInBits();
+ Offset = (Offset << SExtAmount) >> SExtAmount;
}
- case Instruction::BitCast:
- return EmitConstantValueOnly(CE->getOperand(0));
-
- case Instruction::IntToPtr: {
- // Handle casts to pointers by changing them into casts to the appropriate
- // integer type. This promotes constant folding and simplifies this code.
- Constant *Op = CE->getOperand(0);
- Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
- false/*ZExt*/);
+
+ if (Offset)
+ O << '(';
+ EmitConstantValueOnly(ptrVal);
+ if (Offset > 0)
+ O << ") + " << Offset;
+ else
+ O << ") - " << -Offset;
+ return;
+ }
+ case Instruction::BitCast:
+ return EmitConstantValueOnly(CE->getOperand(0));
+
+ case Instruction::IntToPtr: {
+ // Handle casts to pointers by changing them into casts to the appropriate
+ // integer type. This promotes constant folding and simplifies this code.
+ const TargetData *TD = TM.getTargetData();
+ Constant *Op = CE->getOperand(0);
+ Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
+ false/*ZExt*/);
+ return EmitConstantValueOnly(Op);
+ }
+
+ case Instruction::PtrToInt: {
+ // Support only foldable casts to/from pointers that can be eliminated by
+ // changing the pointer to the appropriately sized integer type.
+ Constant *Op = CE->getOperand(0);
+ const Type *Ty = CE->getType();
+ const TargetData *TD = TM.getTargetData();
+
+ // We can emit the pointer value into this slot if the slot is an
+ // integer slot greater or equal to the size of the pointer.
+ if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
return EmitConstantValueOnly(Op);
- }
-
+
+ O << "((";
+ EmitConstantValueOnly(Op);
+ APInt ptrMask =
+ APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType()));
+
+ SmallString<40> S;
+ ptrMask.toStringUnsigned(S);
+ O << ") & " << S.str() << ')';
+ return;
+ }
- case Instruction::PtrToInt: {
- // Support only foldable casts to/from pointers that can be eliminated by
- // changing the pointer to the appropriately sized integer type.
- Constant *Op = CE->getOperand(0);
- const Type *Ty = CE->getType();
-
- // We can emit the pointer value into this slot if the slot is an
- // integer slot greater or equal to the size of the pointer.
- if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
- return EmitConstantValueOnly(Op);
-
- O << "((";
- EmitConstantValueOnly(Op);
- APInt ptrMask =
- APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType()));
+ case Instruction::Trunc:
+ // We emit the value and depend on the assembler to truncate the generated
+ // expression properly. This is important for differences between
+ // blockaddress labels. Since the two labels are in the same function, it
+ // is reasonable to treat their delta as a 32-bit value.
+ return EmitConstantValueOnly(CE->getOperand(0));
- SmallString<40> S;
- ptrMask.toStringUnsigned(S);
- O << ") & " << S.str() << ')';
- break;
- }
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ O << '(';
+ EmitConstantValueOnly(CE->getOperand(0));
+ O << ')';
+ switch (CE->getOpcode()) {
case Instruction::Add:
+ O << " + ";
+ break;
case Instruction::Sub:
+ O << " - ";
+ break;
case Instruction::And:
+ O << " & ";
+ break;
case Instruction::Or:
+ O << " | ";
+ break;
case Instruction::Xor:
- O << '(';
- EmitConstantValueOnly(CE->getOperand(0));
- O << ')';
- switch (Opcode) {
- case Instruction::Add:
- O << " + ";
- break;
- case Instruction::Sub:
- O << " - ";
- break;
- case Instruction::And:
- O << " & ";
- break;
- case Instruction::Or:
- O << " | ";
- break;
- case Instruction::Xor:
- O << " ^ ";
- break;
- default:
- break;
- }
- O << '(';
- EmitConstantValueOnly(CE->getOperand(1));
- O << ')';
- break;
+ O << " ^ ";
+ break;
default:
- llvm_unreachable("Unsupported operator!");
+ break;
}
- } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
- GetBlockAddressSymbol(BA)->print(O, MAI);
- } else {
- llvm_unreachable("Unknown constant value!");
+ O << '(';
+ EmitConstantValueOnly(CE->getOperand(1));
+ O << ')';
+ break;
}
}
@@ -1225,8 +1246,7 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
unsigned AddrSpace) {
const TargetData *TD = TM.getTargetData();
unsigned BitWidth = CI->getBitWidth();
- assert(isPowerOf2_32(BitWidth) &&
- "Non-power-of-2-sized integers not handled!");
+ assert((BitWidth & 63) == 0 && "only support multiples of 64-bits");
// We don't expect assemblers to support integer data directives
// for more than 64 bits, so we emit the data in at most 64-bit
@@ -1239,39 +1259,34 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
else
Val = RawData[i];
- if (MAI->getData64bitsDirective(AddrSpace))
+ if (MAI->getData64bitsDirective(AddrSpace)) {
O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n';
- else if (TD->isBigEndian()) {
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant half of i64 " << Val;
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant half of i64 " << Val;
- }
- O << '\n';
- } else {
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant half of i64 " << Val;
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant half of i64 " << Val;
- }
- O << '\n';
+ continue;
}
+
+ // Emit two 32-bit chunks, order depends on endianness.
+ unsigned FirstChunk = unsigned(Val), SecondChunk = unsigned(Val >> 32);
+ const char *FirstName = " least", *SecondName = " most";
+ if (TD->isBigEndian()) {
+ std::swap(FirstChunk, SecondChunk);
+ std::swap(FirstName, SecondName);
+ }
+
+ O << MAI->getData32bitsDirective(AddrSpace) << FirstChunk;
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString()
+ << FirstName << " significant half of i64 " << Val;
+ }
+ O << '\n';
+
+ O << MAI->getData32bitsDirective(AddrSpace) << SecondChunk;
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString()
+ << SecondName << " significant half of i64 " << Val;
+ }
+ O << '\n';
}
}
@@ -1284,22 +1299,39 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
if (CV->isNullValue() || isa<UndefValue>(CV)) {
EmitZeros(Size, AddrSpace);
return;
- } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
+ }
+
+ if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
EmitGlobalConstantArray(CVA , AddrSpace);
return;
- } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
+ }
+
+ if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
EmitGlobalConstantStruct(CVS, AddrSpace);
return;
- } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+ }
+
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
EmitGlobalConstantFP(CFP, AddrSpace);
return;
- } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ }
+
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ // If we can directly emit an 8-byte constant, do it.
+ if (Size == 8)
+ if (const char *Data64Dir = MAI->getData64bitsDirective(AddrSpace)) {
+ O << Data64Dir << CI->getZExtValue() << '\n';
+ return;
+ }
+
// Small integers are handled below; large integers are handled here.
if (Size > 4) {
EmitGlobalConstantLargeInt(CI, AddrSpace);
return;
}
- } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
+ }
+
+ if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
EmitGlobalConstantVector(CP);
return;
}
@@ -1617,7 +1649,7 @@ void AsmPrinter::printLabel(unsigned Id) const {
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
/// instruction, using the specified assembler variant. Targets should
-/// overried this to format as appropriate.
+/// override this to format as appropriate.
bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode) {
// Target doesn't support this yet!
@@ -1645,15 +1677,17 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
// This code must use the function name itself, and not the function number,
// since it must be possible to generate the label name from within other
// functions.
- std::string FuncName = Mang->getMangledName(F);
+ SmallString<60> FnName;
+ Mang->getNameWithPrefix(FnName, F, false);
- SmallString<60> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA"
- << FuncName.size() << '_' << FuncName << '_'
- << Mang->makeNameProper(BB->getName())
- << Suffix;
+ // FIXME: THIS IS BROKEN IF THE LLVM BASIC BLOCK DOESN'T HAVE A NAME!
+ SmallString<60> NameResult;
+ Mang->getNameWithPrefix(NameResult,
+ StringRef("BA") + Twine((unsigned)FnName.size()) +
+ "_" + FnName.str() + "_" + BB->getName() + Suffix,
+ Mangler::Private);
- return OutContext.GetOrCreateSymbol(Name.str());
+ return OutContext.GetOrCreateSymbol(NameResult.str());
}
MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 8a3ceb631d03..15f37aec148a 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -212,19 +212,30 @@ public:
///
void addVariable(DbgVariable *V) { Variables.push_back(V); }
- void fixInstructionMarkers() {
+ void fixInstructionMarkers(DenseMap<const MachineInstr *,
+ unsigned> &MIIndexMap) {
assert (getFirstInsn() && "First instruction is missing!");
- if (getLastInsn())
- return;
-
- // If a scope does not have an instruction to mark an end then use
- // the end of last child scope.
+
+ // Use the end of last child scope as end of this scope.
SmallVector<DbgScope *, 4> &Scopes = getScopes();
- assert (!Scopes.empty() && "Inner most scope does not have last insn!");
- DbgScope *L = Scopes.back();
- if (!L->getLastInsn())
- L->fixInstructionMarkers();
- setLastInsn(L->getLastInsn());
+ const MachineInstr *LastInsn = getFirstInsn();
+ unsigned LIndex = 0;
+ if (Scopes.empty()) {
+ assert (getLastInsn() && "Inner most scope does not have last insn!");
+ return;
+ }
+ for (SmallVector<DbgScope *, 4>::iterator SI = Scopes.begin(),
+ SE = Scopes.end(); SI != SE; ++SI) {
+ DbgScope *DS = *SI;
+ DS->fixInstructionMarkers(MIIndexMap);
+ const MachineInstr *DSLastInsn = DS->getLastInsn();
+ unsigned DSI = MIIndexMap[DSLastInsn];
+ if (DSI > LIndex) {
+ LastInsn = DSLastInsn;
+ LIndex = DSI;
+ }
+ }
+ setLastInsn(LastInsn);
}
#ifndef NDEBUG
@@ -1021,6 +1032,16 @@ DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) {
return Enumerator;
}
+/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
+/// printer to not emit usual symbol prefix before the symbol name is used then
+/// return linkage name after skipping this special LLVM prefix.
+static StringRef getRealLinkageName(StringRef LinkageName) {
+ char One = '\1';
+ if (LinkageName.startswith(StringRef(&One, 1)))
+ return LinkageName.substr(1);
+ return LinkageName;
+}
+
/// createGlobalVariableDIE - Create new DIE using GV.
DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
// If the global variable was optmized out then no need to create debug info
@@ -1033,16 +1054,10 @@ DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
GV.getDisplayName());
StringRef LinkageName = GV.getLinkageName();
- if (!LinkageName.empty()) {
- // Skip special LLVM prefix that is used to inform the asm printer to not
- // emit usual symbol prefix before the symbol name. This happens for
- // Objective-C symbol names and symbol whose name is replaced using GCC's
- // __asm__ attribute.
- if (LinkageName[0] == 1)
- LinkageName = LinkageName.substr(1);
+ if (!LinkageName.empty())
addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
- LinkageName);
- }
+ getRealLinkageName(LinkageName));
+
addType(GVDie, GV.getType());
if (!GV.isLocalToUnit())
addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
@@ -1074,10 +1089,9 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
uint64_t Offset = DT.getOffsetInBits();
- uint64_t FieldOffset = Offset;
uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
- FieldOffset = (HiMark - FieldSize);
+ uint64_t FieldOffset = (HiMark - FieldSize);
Offset -= FieldOffset;
// Maybe we need to work from the other end.
@@ -1119,16 +1133,10 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
StringRef LinkageName = SP.getLinkageName();
- if (!LinkageName.empty()) {
- // Skip special LLVM prefix that is used to inform the asm printer to not
- // emit usual symbol prefix before the symbol name. This happens for
- // Objective-C symbol names and symbol whose name is replaced using GCC's
- // __asm__ attribute.
- if (LinkageName[0] == 1)
- LinkageName = LinkageName.substr(1);
+ if (!LinkageName.empty())
addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
- LinkageName);
- }
+ getRealLinkageName(LinkageName));
+
addSourceLine(SPDie, &SP);
// Add prototyped tag, if C or ObjC.
@@ -1382,7 +1390,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
I->second.push_back(std::make_pair(StartID, ScopeDIE));
StringPool.insert(InlinedSP.getName());
- StringPool.insert(InlinedSP.getLinkageName());
+ StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName()));
+
DILocation DL(Scope->getInlinedAt());
addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID());
addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
@@ -1644,8 +1653,11 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
ModuleCU->insertDIE(N, VariableDie);
// Add to context owner.
- if (DI_GV.isDefinition()
- && !DI_GV.getContext().isCompileUnit()) {
+ DIDescriptor GVContext = DI_GV.getContext();
+ // Do not create specification DIE if context is either compile unit
+ // or a subprogram.
+ if (DI_GV.isDefinition() && !GVContext.isCompileUnit()
+ && !GVContext.isSubprogram()) {
// Create specification DIE.
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
@@ -1663,7 +1675,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
Asm->Mang->getMangledName(DI_GV.getGlobal()));
addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
}
- addToContextOwner(VariableDie, DI_GV.getContext());
+ addToContextOwner(VariableDie, GVContext);
// Expose as global. FIXME - need to check external flag.
ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
@@ -1804,7 +1816,8 @@ void DwarfDebug::endModule() {
DIE *NDie = ModuleCU->getDIE(N);
if (!NDie) continue;
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
- addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
+ // FIXME - This is not the correct approach.
+ // addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
}
// Standard sections final addresses.
@@ -1976,12 +1989,15 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
if (!DbgScopeMap.empty())
return false;
+ DenseMap<const MachineInstr *, unsigned> MIIndexMap;
+ unsigned MIIndex = 0;
// Scan each instruction and create scopes. First build working set of scopes.
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
+ MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DebugLocTuple DLT = MF->getDebugLocTuple(DL);
@@ -2014,16 +2030,10 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
}
}
- // If a scope's last instruction is not set then use its child scope's
- // last instruction as this scope's last instrunction.
- for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
- DE = DbgScopeMap.end(); DI != DE; ++DI) {
- if (DI->second->isAbstractScope())
- continue;
- assert (DI->second->getFirstInsn() && "Invalid first instruction!");
- DI->second->fixInstructionMarkers();
- assert (DI->second->getLastInsn() && "Invalid last instruction!");
- }
+ if (!CurrentFnDbgScope)
+ return false;
+
+ CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap);
// Each scope has first instruction and last instruction to mark beginning
// and end of a scope respectively. Create an inverse map that list scopes
@@ -2105,38 +2115,41 @@ void DwarfDebug::endFunction(MachineFunction *MF) {
if (DbgScopeMap.empty())
return;
- // Define end label for subprogram.
- EmitLabel("func_end", SubprogramCount);
-
- // Get function line info.
- if (!Lines.empty()) {
- // Get section line info.
- unsigned ID = SectionMap.insert(Asm->getCurrentSection());
- if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
- std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
- // Append the function info to section info.
- SectionLineInfos.insert(SectionLineInfos.end(),
- Lines.begin(), Lines.end());
+ if (CurrentFnDbgScope) {
+ // Define end label for subprogram.
+ EmitLabel("func_end", SubprogramCount);
+
+ // Get function line info.
+ if (!Lines.empty()) {
+ // Get section line info.
+ unsigned ID = SectionMap.insert(Asm->getCurrentSection());
+ if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
+ std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
+ // Append the function info to section info.
+ SectionLineInfos.insert(SectionLineInfos.end(),
+ Lines.begin(), Lines.end());
+ }
+
+ // Construct abstract scopes.
+ for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
+ AE = AbstractScopesList.end(); AI != AE; ++AI)
+ constructScopeDIE(*AI);
+
+ constructScopeDIE(CurrentFnDbgScope);
+
+ DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
+ MMI->getFrameMoves()));
}
- // Construct abstract scopes.
- for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
- AE = AbstractScopesList.end(); AI != AE; ++AI)
- constructScopeDIE(*AI);
-
- constructScopeDIE(CurrentFnDbgScope);
-
- DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
- MMI->getFrameMoves()));
-
// Clear debug info
- CurrentFnDbgScope = NULL;
- DbgScopeMap.clear();
- DbgScopeBeginMap.clear();
- DbgScopeEndMap.clear();
- ConcreteScopes.clear();
- AbstractScopesList.clear();
-
+ if (CurrentFnDbgScope) {
+ CurrentFnDbgScope = NULL;
+ DbgScopeMap.clear();
+ DbgScopeBeginMap.clear();
+ DbgScopeEndMap.clear();
+ ConcreteScopes.clear();
+ AbstractScopesList.clear();
+ }
Lines.clear();
if (TimePassesIsEnabled)
@@ -2908,8 +2921,6 @@ void DwarfDebug::emitDebugInlineInfo() {
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
-// for (ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
- // I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
MDNode *Node = *I;
ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
= InlineInfo.find(Node);
@@ -2920,20 +2931,11 @@ void DwarfDebug::emitDebugInlineInfo() {
if (LName.empty())
Asm->EmitString(Name);
- else {
- // Skip special LLVM prefix that is used to inform the asm printer to not
- // emit usual symbol prefix before the symbol name. This happens for
- // Objective-C symbol names and symbol whose name is replaced using GCC's
- // __asm__ attribute.
- if (LName[0] == 1)
- LName = LName.substr(1);
-// Asm->EmitString(LName);
+ else
EmitSectionOffset("string", "section_str",
- StringPool.idFor(LName), false, true);
+ StringPool.idFor(getRealLinkageName(LName)), false, true);
- }
Asm->EOL("MIPS linkage name");
-// Asm->EmitString(Name);
EmitSectionOffset("string", "section_str",
StringPool.idFor(Name), false, true);
Asm->EOL("Function name");