diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter')
7 files changed, 317 insertions, 205 deletions
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 161afba..7f314ee 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -575,6 +575,8 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { } } else if (MI->getOperand(0).isImm()) { OS << MI->getOperand(0).getImm(); + } else if (MI->getOperand(0).isCImm()) { + MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); } else { assert(MI->getOperand(0).isReg() && "Unknown operand type"); if (MI->getOperand(0).getReg() == 0) { @@ -1211,9 +1213,9 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { /// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each /// global in the specified llvm.used list for which emitUsedDirectiveFor /// is true, as being used with this directive. -void AsmPrinter::EmitLLVMUsedList(Constant *List) { +void AsmPrinter::EmitLLVMUsedList(const Constant *List) { // Should be an array of 'i8*'. - ConstantArray *InitList = dyn_cast<ConstantArray>(List); + const ConstantArray *InitList = dyn_cast<ConstantArray>(List); if (InitList == 0) return; for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { @@ -1226,11 +1228,11 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) { /// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the /// function pointers, ignoring the init priority. -void AsmPrinter::EmitXXStructorList(Constant *List) { +void AsmPrinter::EmitXXStructorList(const Constant *List) { // Should be an array of '{ int, void ()* }' structs. The first value is the // init priority, which we ignore. if (!isa<ConstantArray>(List)) return; - ConstantArray *InitList = cast<ConstantArray>(List); + const ConstantArray *InitList = cast<ConstantArray>(List); for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. @@ -1516,6 +1518,13 @@ static void EmitGlobalConstantVector(const ConstantVector *CV, unsigned AddrSpace, AsmPrinter &AP) { for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) EmitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP); + + const TargetData &TD = *AP.TM.getTargetData(); + unsigned Size = TD.getTypeAllocSize(CV->getType()); + unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) * + CV->getType()->getNumElements(); + if (unsigned Padding = Size - EmittedSize) + AP.OutStreamer.EmitZeros(Padding, AddrSpace); } static void EmitGlobalConstantStruct(const ConstantStruct *CS, @@ -1925,7 +1934,7 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { return false; // The predecessor has to be immediately before this block. - const MachineBasicBlock *Pred = *PI; + MachineBasicBlock *Pred = *PI; if (!Pred->isLayoutSuccessor(MBB)) return false; @@ -1934,9 +1943,28 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { if (Pred->empty()) return true; - // Otherwise, check the last instruction. - const MachineInstr &LastInst = Pred->back(); - return !LastInst.getDesc().isBarrier(); + // Check the terminators in the previous blocks + for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(), + IE = Pred->end(); II != IE; ++II) { + MachineInstr &MI = *II; + + // If it is not a simple branch, we are in a table somewhere. + if (!MI.getDesc().isBranch() || MI.getDesc().isIndirectBranch()) + return false; + + // If we are the operands of one of the branches, this is not + // a fall through. + for (MachineInstr::mop_iterator OI = MI.operands_begin(), + OE = MI.operands_end(); OI != OE; ++OI) { + const MachineOperand& OP = *OI; + if (OP.isJTI()) + return false; + if (OP.isMBB() && OP.getMBB() == MBB) + return false; + } + } + + return true; } diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index c6166e2..5ac455e 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetAsmParser.h" #include "llvm/Target/TargetMachine.h" @@ -111,7 +112,16 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const { OwningPtr<MCAsmParser> Parser(createMCAsmParser(TM.getTarget(), SrcMgr, OutContext, OutStreamer, *MAI)); - OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(*Parser, TM)); + + // FIXME: It would be nice if we can avoid createing a new instance of + // MCSubtargetInfo here given TargetSubtargetInfo is available. However, + // we have to watch out for asm directives which can change subtarget + // state. e.g. .code 16, .code 32. + OwningPtr<MCSubtargetInfo> + STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(), + TM.getTargetCPU(), + TM.getTargetFeatureString())); + OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(*STI, *Parser)); if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index bff1a35..1fe035e 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -491,7 +491,7 @@ bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) { } /// addConstantValue - Add constant value entry in variable DIE. -bool CompileUnit::addConstantValue(DIE *Die, ConstantInt *CI, +bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned) { unsigned CIBitWidth = CI->getBitWidth(); if (CIBitWidth <= 64) { diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 60a9b28..213c7fc 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -181,7 +181,7 @@ public: /// addConstantValue - Add constant value entry in variable DIE. bool addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty); - bool addConstantValue(DIE *Die, ConstantInt *CI, bool Unsigned); + bool addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned); /// addConstantFPValue - Add constant value entry in variable DIE. bool addConstantFPValue(DIE *Die, const MachineOperand &MO); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 8845bfa..125e1e8 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -229,6 +229,7 @@ public: void DbgScope::dump() const { raw_ostream &err = dbgs(); err.indent(IndentLevel); + err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; const MDNode *N = Desc; N->dump(); if (AbstractScope) @@ -618,6 +619,21 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { return ScopeDIE; } +/// isUnsignedDIType - Return true if type encoding is unsigned. +static bool isUnsignedDIType(DIType Ty) { + DIDerivedType DTy(Ty); + if (DTy.Verify()) + return isUnsignedDIType(DTy.getTypeDerivedFrom()); + + DIBasicType BTy(Ty); + if (BTy.Verify()) { + unsigned Encoding = BTy.getEncoding(); + if (Encoding == dwarf::DW_ATE_unsigned || + Encoding == dwarf::DW_ATE_unsigned_char) + return true; + } + return false; +} /// constructVariableDIE - Construct a DIE for the given DbgVariable. DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { @@ -718,6 +734,11 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { else if (DVInsn->getOperand(0).isFPImm()) updated = VariableCU->addConstantFPValue(VariableDie, DVInsn->getOperand(0)); + else if (DVInsn->getOperand(0).isCImm()) + updated = + VariableCU->addConstantValue(VariableDie, + DVInsn->getOperand(0).getCImm(), + isUnsignedDIType(DV->getType())); } else { VariableCU->addVariableAddress(DV, VariableDie, Asm->getDebugValueLocation(DVInsn)); @@ -913,22 +934,6 @@ CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const { return I->second; } -/// isUnsignedDIType - Return true if type encoding is unsigned. -static bool isUnsignedDIType(DIType Ty) { - DIDerivedType DTy(Ty); - if (DTy.Verify()) - return isUnsignedDIType(DTy.getTypeDerivedFrom()); - - DIBasicType BTy(Ty); - if (BTy.Verify()) { - unsigned Encoding = BTy.getEncoding(); - if (Encoding == dwarf::DW_ATE_unsigned || - Encoding == dwarf::DW_ATE_unsigned_char) - return true; - } - return false; -} - // Return const exprssion if value is a GEP to access merged global // constant. e.g. // i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) @@ -1017,7 +1022,7 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) { } else { TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); } - } else if (ConstantInt *CI = + } else if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(GV.getConstant())) TheCU->addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy)); else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { @@ -1310,7 +1315,6 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, void DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF, SmallPtrSet<const MDNode *, 16> &Processed) { - const LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), VE = VMap.end(); VI != VE; ++VI) { @@ -1320,11 +1324,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF, DIVariable DV(Var); const std::pair<unsigned, DebugLoc> &VP = VI->second; - DbgScope *Scope = 0; - if (const MDNode *IA = VP.second.getInlinedAt(Ctx)) - Scope = ConcreteScopes.lookup(IA); - if (Scope == 0) - Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx)); + DbgScope *Scope = findDbgScope(VP.second); // If variable scope is not found then skip this variable. if (Scope == 0) @@ -1351,6 +1351,34 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) { MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0; } +/// getDebugLocEntry - Get .debug_loc entry for the instraction range starting +/// at MI. +static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, + const MCSymbol *FLabel, + const MCSymbol *SLabel, + const MachineInstr *MI) { + const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata(); + + if (MI->getNumOperands() != 3) { + MachineLocation MLoc = Asm->getDebugValueLocation(MI); + return DotDebugLocEntry(FLabel, SLabel, MLoc, Var); + } + if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) { + MachineLocation MLoc; + MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); + return DotDebugLocEntry(FLabel, SLabel, MLoc, Var); + } + if (MI->getOperand(0).isImm()) + return DotDebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm()); + if (MI->getOperand(0).isFPImm()) + return DotDebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm()); + if (MI->getOperand(0).isCImm()) + return DotDebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm()); + + assert (0 && "Unexpected 3 operand DBG_VALUE instruction!"); + return DotDebugLocEntry(); +} + /// collectVariableInfo - Populate DbgScope entries with variables' info. void DwarfDebug::collectVariableInfo(const MachineFunction *MF, @@ -1379,7 +1407,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, DISubprogram(DV.getContext()).describes(MF->getFunction())) Scope = CurrentFnDbgScope; else - Scope = findDbgScope(MInsn); + Scope = findDbgScope(MInsn->getDebugLoc()); // If variable scope is not found then skip this variable. if (!Scope) continue; @@ -1424,6 +1452,8 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, SLabel = FunctionEndSym; else { const MachineInstr *End = HI[1]; + DEBUG(dbgs() << "DotDebugLoc Pair:\n" + << "\t" << *Begin << "\t" << *End << "\n"); if (End->isDebugValue()) SLabel = getLabelBeforeInsn(End); else { @@ -1435,25 +1465,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, } // The value is valid until the next DBG_VALUE or clobber. - MachineLocation MLoc; - if (Begin->getNumOperands() == 3) { - if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm()) { - MLoc.set(Begin->getOperand(0).getReg(), - Begin->getOperand(1).getImm()); - DotDebugLocEntries. - push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var)); - } - // FIXME: Handle isFPImm also. - else if (Begin->getOperand(0).isImm()) { - DotDebugLocEntries. - push_back(DotDebugLocEntry(FLabel, SLabel, - Begin->getOperand(0).getImm())); - } - } else { - MLoc = Asm->getDebugValueLocation(Begin); - DotDebugLocEntries. - push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var)); - } + DotDebugLocEntries.push_back(getDebugLocEntry(Asm, FLabel, SLabel, Begin)); } DotDebugLocEntries.push_back(DotDebugLocEntry()); } @@ -1550,8 +1562,12 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) { } /// getOrCreateDbgScope - Create DbgScope for the scope. -DbgScope *DwarfDebug::getOrCreateDbgScope(const MDNode *Scope, - const MDNode *InlinedAt) { +DbgScope *DwarfDebug::getOrCreateDbgScope(DebugLoc DL) { + LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); + MDNode *Scope = NULL; + MDNode *InlinedAt = NULL; + DL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx); + if (!InlinedAt) { DbgScope *WScope = DbgScopeMap.lookup(Scope); if (WScope) @@ -1560,22 +1576,12 @@ DbgScope *DwarfDebug::getOrCreateDbgScope(const MDNode *Scope, DbgScopeMap.insert(std::make_pair(Scope, WScope)); if (DIDescriptor(Scope).isLexicalBlock()) { DbgScope *Parent = - getOrCreateDbgScope(DILexicalBlock(Scope).getContext(), NULL); + getOrCreateDbgScope(DebugLoc::getFromDILexicalBlock(Scope)); WScope->setParent(Parent); Parent->addScope(WScope); - } - - if (!WScope->getParent()) { - StringRef SPName = DISubprogram(Scope).getLinkageName(); - // We used to check only for a linkage name, but that fails - // since we began omitting the linkage name for private - // functions. The new way is to check for the name in metadata, - // but that's not supported in old .ll test cases. Ergo, we - // check both. - if (SPName == Asm->MF->getFunction()->getName() || - DISubprogram(Scope).getFunction() == Asm->MF->getFunction()) - CurrentFnDbgScope = WScope; - } + } else if (DIDescriptor(Scope).isSubprogram() + && DISubprogram(Scope).describes(Asm->MF->getFunction())) + CurrentFnDbgScope = WScope; return WScope; } @@ -1587,37 +1593,14 @@ DbgScope *DwarfDebug::getOrCreateDbgScope(const MDNode *Scope, WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt); DbgScopeMap.insert(std::make_pair(InlinedAt, WScope)); - DILocation DL(InlinedAt); + InlinedDbgScopeMap[DebugLoc::getFromDILocation(InlinedAt)] = WScope; DbgScope *Parent = - getOrCreateDbgScope(DL.getScope(), DL.getOrigLocation()); + getOrCreateDbgScope(DebugLoc::getFromDILocation(InlinedAt)); WScope->setParent(Parent); Parent->addScope(WScope); - - ConcreteScopes[InlinedAt] = WScope; - return WScope; } -/// hasValidLocation - Return true if debug location entry attached with -/// machine instruction encodes valid location info. -static bool hasValidLocation(LLVMContext &Ctx, - const MachineInstr *MInsn, - const MDNode *&Scope, const MDNode *&InlinedAt) { - DebugLoc DL = MInsn->getDebugLoc(); - if (DL.isUnknown()) return false; - - const MDNode *S = DL.getScope(Ctx); - - // There is no need to create another DIE for compile unit. For all - // other scopes, create one DbgScope now. This will be translated - // into a scope DIE at the end. - if (DIScope(S).isCompileUnit()) return false; - - Scope = S; - InlinedAt = DL.getInlinedAt(Ctx); - return true; -} - /// calculateDominanceGraph - Calculate dominance graph for DbgScope /// hierarchy. static void calculateDominanceGraph(DbgScope *Scope) { @@ -1648,21 +1631,24 @@ static void calculateDominanceGraph(DbgScope *Scope) { /// printDbgScopeInfo - Print DbgScope info for each machine instruction. static -void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF, +void printDbgScopeInfo(const MachineFunction *MF, DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap) { #ifndef NDEBUG + LLVMContext &Ctx = MF->getFunction()->getContext(); unsigned PrevDFSIn = 0; 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; - const MDNode *Scope = NULL; - const MDNode *InlinedAt = NULL; + MDNode *Scope = NULL; + MDNode *InlinedAt = NULL; // Check if instruction has valid location information. - if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) { + DebugLoc MIDL = MInsn->getDebugLoc(); + if (!MIDL.isUnknown()) { + MIDL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx); dbgs() << " [ "; if (InlinedAt) dbgs() << "*"; @@ -1692,11 +1678,9 @@ bool DwarfDebug::extractScopeInformation() { return false; // Scan each instruction and create scopes. First build working set of scopes. - LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); SmallVector<DbgRange, 4> MIRanges; DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap; - const MDNode *PrevScope = NULL; - const MDNode *PrevInlinedAt = NULL; + DebugLoc PrevDL; const MachineInstr *RangeBeginMI = NULL; const MachineInstr *PrevMI = NULL; for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); @@ -1704,17 +1688,16 @@ bool DwarfDebug::extractScopeInformation() { for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; - const MDNode *Scope = NULL; - const MDNode *InlinedAt = NULL; // Check if instruction has valid location information. - if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) { + const DebugLoc MIDL = MInsn->getDebugLoc(); + if (MIDL.isUnknown()) { PrevMI = MInsn; continue; } // If scope has not changed then skip this instruction. - if (Scope == PrevScope && PrevInlinedAt == InlinedAt) { + if (MIDL == PrevDL) { PrevMI = MInsn; continue; } @@ -1727,9 +1710,13 @@ bool DwarfDebug::extractScopeInformation() { // If we have alread seen a beginning of a instruction range and // current instruction scope does not match scope of first instruction // in this range then create a new instruction range. + DEBUG(dbgs() << "Creating new instruction range :\n"); + DEBUG(dbgs() << "Begin Range at " << *RangeBeginMI); + DEBUG(dbgs() << "End Range at " << *PrevMI); + DEBUG(dbgs() << "Next Range starting at " << *MInsn); + DEBUG(dbgs() << "------------------------\n"); DbgRange R(RangeBeginMI, PrevMI); - MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, - PrevInlinedAt); + MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL); MIRanges.push_back(R); } @@ -1738,16 +1725,15 @@ bool DwarfDebug::extractScopeInformation() { // Reset previous markers. PrevMI = MInsn; - PrevScope = Scope; - PrevInlinedAt = InlinedAt; + PrevDL = MIDL; } } // Create last instruction range. - if (RangeBeginMI && PrevMI && PrevScope) { + if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { DbgRange R(RangeBeginMI, PrevMI); MIRanges.push_back(R); - MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt); + MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL); } if (!CurrentFnDbgScope) @@ -1755,7 +1741,7 @@ bool DwarfDebug::extractScopeInformation() { calculateDominanceGraph(CurrentFnDbgScope); if (PrintDbgScope) - printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap); + printDbgScopeInfo(Asm->MF, MI2ScopeMap); // Find ranges of instructions covered by each DbgScope; DbgScope *PrevDbgScope = NULL; @@ -1842,8 +1828,6 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned"); - /// ProcessedArgs - Collection of arguments already processed. - SmallPtrSet<const MDNode *, 8> ProcessedArgs; const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); /// LiveUserVar - Map physreg numbers to the MDNode they contain. std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs()); @@ -1883,8 +1867,12 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { if (Prev->isDebugValue()) { // Coalesce identical entries at the end of History. if (History.size() >= 2 && - Prev->isIdenticalTo(History[History.size() - 2])) + Prev->isIdenticalTo(History[History.size() - 2])) { + DEBUG(dbgs() << "Coalesce identical DBG_VALUE entries:\n" + << "\t" << *Prev + << "\t" << *History[History.size() - 2] << "\n"); History.pop_back(); + } // Terminate old register assignments that don't reach MI; MachineFunction::const_iterator PrevMBB = Prev->getParent(); @@ -1894,9 +1882,12 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // its basic block. MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr(); - if (LastMI == PrevMBB->end()) + if (LastMI == PrevMBB->end()) { // Drop DBG_VALUE for empty range. + DEBUG(dbgs() << "Drop DBG_VALUE for empty range:\n" + << "\t" << *Prev << "\n"); History.pop_back(); + } else { // Terminate after LastMI. History.push_back(LastMI); @@ -2053,10 +2044,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DbgVariableToFrameIndexMap.clear(); VarToAbstractVarMap.clear(); DbgVariableToDbgInstMap.clear(); + InlinedDbgScopeMap.clear(); DeleteContainerSeconds(DbgScopeMap); UserVariables.clear(); DbgValues.clear(); - ConcreteScopes.clear(); DeleteContainerSeconds(AbstractScopes); AbstractScopesList.clear(); AbstractVariables.clear(); @@ -2083,22 +2074,17 @@ bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) { return true; } -/// findDbgScope - Find DbgScope for the debug loc attached with an -/// instruction. -DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) { - DbgScope *Scope = NULL; - LLVMContext &Ctx = - MInsn->getParent()->getParent()->getFunction()->getContext(); - DebugLoc DL = MInsn->getDebugLoc(); - +/// findDbgScope - Find DbgScope for the debug loc. +DbgScope *DwarfDebug::findDbgScope(DebugLoc DL) { if (DL.isUnknown()) - return Scope; + return NULL; - if (const MDNode *IA = DL.getInlinedAt(Ctx)) - Scope = ConcreteScopes.lookup(IA); - if (Scope == 0) + DbgScope *Scope = NULL; + LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); + if (MDNode *IA = DL.getInlinedAt(Ctx)) + Scope = InlinedDbgScopeMap.lookup(DebugLoc::getFromDILocation(IA)); + else Scope = DbgScopeMap.lookup(DL.getScope(Ctx)); - return Scope; } @@ -2597,56 +2583,61 @@ void DwarfDebug::emitDebugLoc() { MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol(); Asm->EmitLabelDifference(end, begin, 2); Asm->OutStreamer.EmitLabel(begin); - if (Entry.isConstant()) { + if (Entry.isInt()) { DIBasicType BTy(DV.getType()); if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { Asm->OutStreamer.AddComment("DW_OP_consts"); Asm->EmitInt8(dwarf::DW_OP_consts); - Asm->EmitSLEB128(Entry.getConstant()); + Asm->EmitSLEB128(Entry.getInt()); } else { Asm->OutStreamer.AddComment("DW_OP_constu"); Asm->EmitInt8(dwarf::DW_OP_constu); - Asm->EmitULEB128(Entry.getConstant()); + Asm->EmitULEB128(Entry.getInt()); } - } else if (DV.hasComplexAddress()) { - unsigned N = DV.getNumAddrElements(); - unsigned i = 0; - if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { - if (Entry.Loc.getOffset()) { - i = 2; - Asm->EmitDwarfRegOp(Entry.Loc); - Asm->OutStreamer.AddComment("DW_OP_deref"); - Asm->EmitInt8(dwarf::DW_OP_deref); - Asm->OutStreamer.AddComment("DW_OP_plus_uconst"); - Asm->EmitInt8(dwarf::DW_OP_plus_uconst); - Asm->EmitSLEB128(DV.getAddrElement(1)); + } else if (Entry.isLocation()) { + if (!DV.hasComplexAddress()) + // Regular entry. + Asm->EmitDwarfRegOp(Entry.Loc); + else { + // Complex address entry. + unsigned N = DV.getNumAddrElements(); + unsigned i = 0; + if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { + if (Entry.Loc.getOffset()) { + i = 2; + Asm->EmitDwarfRegOp(Entry.Loc); + Asm->OutStreamer.AddComment("DW_OP_deref"); + Asm->EmitInt8(dwarf::DW_OP_deref); + Asm->OutStreamer.AddComment("DW_OP_plus_uconst"); + Asm->EmitInt8(dwarf::DW_OP_plus_uconst); + Asm->EmitSLEB128(DV.getAddrElement(1)); + } else { + // If first address element is OpPlus then emit + // DW_OP_breg + Offset instead of DW_OP_reg + Offset. + MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1)); + Asm->EmitDwarfRegOp(Loc); + i = 2; + } } else { - // If first address element is OpPlus then emit - // DW_OP_breg + Offset instead of DW_OP_reg + Offset. - MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1)); - Asm->EmitDwarfRegOp(Loc); - i = 2; + Asm->EmitDwarfRegOp(Entry.Loc); + } + + // Emit remaining complex address elements. + for (; i < N; ++i) { + uint64_t Element = DV.getAddrElement(i); + if (Element == DIBuilder::OpPlus) { + Asm->EmitInt8(dwarf::DW_OP_plus_uconst); + Asm->EmitULEB128(DV.getAddrElement(++i)); + } else if (Element == DIBuilder::OpDeref) + Asm->EmitInt8(dwarf::DW_OP_deref); + else llvm_unreachable("unknown Opcode found in complex address"); } - } else { - Asm->EmitDwarfRegOp(Entry.Loc); - } - - // Emit remaining complex address elements. - for (; i < N; ++i) { - uint64_t Element = DV.getAddrElement(i); - if (Element == DIBuilder::OpPlus) { - Asm->EmitInt8(dwarf::DW_OP_plus_uconst); - Asm->EmitULEB128(DV.getAddrElement(++i)); - } else if (Element == DIBuilder::OpDeref) - Asm->EmitInt8(dwarf::DW_OP_deref); - else llvm_unreachable("unknown Opcode found in complex address"); } - } else { - // Regular entry. - Asm->EmitDwarfRegOp(Entry.Loc); } + // else ... ignore constant fp. There is not any good way to + // to represent them here in dwarf. Asm->OutStreamer.EmitLabel(end); } } diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index abda2e6..b245006 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -69,17 +69,35 @@ typedef struct DotDebugLocEntry { const MDNode *Variable; bool Merged; bool Constant; - int64_t iConstant; + enum EntryType { + E_Location, + E_Integer, + E_ConstantFP, + E_ConstantInt + }; + enum EntryType EntryKind; + + union { + int64_t Int; + const ConstantFP *CFP; + const ConstantInt *CIP; + } Constants; DotDebugLocEntry() : Begin(0), End(0), Variable(0), Merged(false), - Constant(false), iConstant(0) {} + Constant(false) { Constants.Int = 0;} DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L, const MDNode *V) : Begin(B), End(E), Loc(L), Variable(V), Merged(false), - Constant(false), iConstant(0) {} + Constant(false) { Constants.Int = 0; EntryKind = E_Location; } DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i) : Begin(B), End(E), Variable(0), Merged(false), - Constant(true), iConstant(i) {} + Constant(true) { Constants.Int = i; EntryKind = E_Integer; } + DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr) + : Begin(B), End(E), Variable(0), Merged(false), + Constant(true) { Constants.CFP = FPtr; EntryKind = E_ConstantFP; } + DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantInt *IPtr) + : Begin(B), End(E), Variable(0), Merged(false), + Constant(true) { Constants.CIP = IPtr; EntryKind = E_ConstantInt; } /// Empty entries are also used as a trigger to emit temp label. Such /// labels are referenced is used to find debug_loc offset for a given DIE. @@ -91,8 +109,13 @@ typedef struct DotDebugLocEntry { Next->Begin = Begin; Merged = true; } - bool isConstant() { return Constant; } - int64_t getConstant() { return iConstant; } + bool isLocation() const { return EntryKind == E_Location; } + bool isInt() const { return EntryKind == E_Integer; } + bool isConstantFP() const { return EntryKind == E_ConstantFP; } + bool isConstantInt() const { return EntryKind == E_ConstantInt; } + int64_t getInt() { return Constants.Int; } + const ConstantFP *getConstantFP() { return Constants.CFP; } + const ConstantInt *getConstantInt() { return Constants.CIP; } } DotDebugLocEntry; //===----------------------------------------------------------------------===// @@ -178,12 +201,10 @@ class DwarfDebug { /// DbgScopeMap - Tracks the scopes in the current function. Owns the /// contained DbgScope*s. - /// DenseMap<const MDNode *, DbgScope *> DbgScopeMap; - /// ConcreteScopes - Tracks the concrete scopees in the current function. - /// These scopes are also included in DbgScopeMap. - DenseMap<const MDNode *, DbgScope *> ConcreteScopes; + /// InlinedDbgScopeMap - Tracks inlined function scopes in current function. + DenseMap<DebugLoc, DbgScope *> InlinedDbgScopeMap; /// AbstractScopes - Tracks the abstract scopes a module. These scopes are /// not included DbgScopeMap. AbstractScopes owns its DbgScope*s. @@ -296,7 +317,7 @@ private: void assignAbbrevNumber(DIEAbbrev &Abbrev); /// getOrCreateDbgScope - Create DbgScope for the scope. - DbgScope *getOrCreateDbgScope(const MDNode *Scope, const MDNode *InlinedAt); + DbgScope *getOrCreateDbgScope(DebugLoc DL); DbgScope *getOrCreateAbstractScope(const MDNode *N); @@ -427,9 +448,8 @@ private: /// is found. Update FI to hold value of the index. bool findVariableFrameIndex(const DbgVariable *V, int *FI); - /// findDbgScope - Find DbgScope for the debug loc attached with an - /// instruction. - DbgScope *findDbgScope(const MachineInstr *MI); + /// findDbgScope - Find DbgScope for the debug loc. + DbgScope *findDbgScope(DebugLoc DL); /// identifyScopeMarkers() - Indentify instructions that are marking /// beginning of or end of a scope. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp index 967a278..1f992fa 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -512,6 +512,8 @@ void DwarfException::EmitExceptionTable() { SizeAlign = 0; } + bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); + // SjLj Exception handling if (IsSJLJ) { Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); @@ -525,14 +527,30 @@ void DwarfException::EmitExceptionTable() { I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { const CallSiteEntry &S = *I; + if (VerboseAsm) { + // Emit comments that decode the call site. + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + + llvm::utostr(idx) + " <<"); + Asm->OutStreamer.AddComment(Twine(" On exception at call site ") + + llvm::utostr(idx)); + + if (S.Action == 0) + Asm->OutStreamer.AddComment(" Action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" Action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + + Asm->OutStreamer.AddBlankLine(); + } + // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->EmitULEB128(idx, "Landing pad"); + Asm->EmitULEB128(idx); // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128(S.Action, "Action"); + Asm->EmitULEB128(S.Action); } } else { // DWARF Exception handling @@ -562,6 +580,7 @@ void DwarfException::EmitExceptionTable() { // Add extra padding if it wasn't added to the TType base offset. Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); + unsigned Entry = 0; for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { const CallSiteEntry &S = *I; @@ -576,19 +595,38 @@ void DwarfException::EmitExceptionTable() { if (EndLabel == 0) EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); + if (VerboseAsm) { + // Emit comments that decode the call site. + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + + llvm::utostr(++Entry) + " <<"); + Asm->OutStreamer.AddComment(Twine(" Call between ") + + BeginLabel->getName() + " and " + + EndLabel->getName()); + + if (!S.PadLabel) { + Asm->OutStreamer.AddComment(" has no landing pad"); + } else { + Asm->OutStreamer.AddComment(Twine(" jumps to ") + + S.PadLabel->getName()); + + if (S.Action == 0) + Asm->OutStreamer.AddComment(" On action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" On action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + } + + Asm->OutStreamer.AddBlankLine(); + } + // Offset of the call site relative to the previous call site, counted in // number of 16-byte bundles. The first call site is counted relative to // the start of the procedure fragment. - Asm->OutStreamer.AddComment("Region start"); Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); - - Asm->OutStreamer.AddComment("Region length"); Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->OutStreamer.AddComment("Landing pad"); if (!S.PadLabel) Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); else @@ -597,45 +635,63 @@ void DwarfException::EmitExceptionTable() { // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128(S.Action, "Action"); + Asm->EmitULEB128(S.Action); } } // Emit the Action Table. - if (Actions.size() != 0) { - Asm->OutStreamer.AddComment("-- Action Record Table --"); - Asm->OutStreamer.AddBlankLine(); - } - + int Entry = 0; for (SmallVectorImpl<ActionEntry>::const_iterator I = Actions.begin(), E = Actions.end(); I != E; ++I) { const ActionEntry &Action = *I; - Asm->OutStreamer.AddComment("Action Record"); - Asm->OutStreamer.AddBlankLine(); + + if (VerboseAsm) { + // Emit comments that decode the action table. + Asm->OutStreamer.AddComment(Twine(">> Action Record ") + + llvm::utostr(++Entry) + " <<"); + if (Action.ValueForTypeID >= 0) + Asm->OutStreamer.AddComment(Twine(" Catch TypeInfo ") + + llvm::itostr(Action.ValueForTypeID)); + else + Asm->OutStreamer.AddComment(Twine(" Filter TypeInfo ") + + llvm::itostr(Action.ValueForTypeID)); + + if (Action.NextAction == 0) { + Asm->OutStreamer.AddComment(" No further actions"); + } else { + unsigned NextAction = Entry + (Action.NextAction + 1) / 2; + Asm->OutStreamer.AddComment(Twine(" Continue to action ") + + llvm::utostr(NextAction)); + } + + Asm->OutStreamer.AddBlankLine(); + } // Type Filter // // Used by the runtime to match the type of the thrown exception to the // type of the catch clauses or the types in the exception specification. - Asm->EmitSLEB128(Action.ValueForTypeID, " TypeInfo index"); + Asm->EmitSLEB128(Action.ValueForTypeID); // Action Record // // Self-relative signed displacement in bytes of the next action record, // or 0 if there is no next action record. - Asm->EmitSLEB128(Action.NextAction, " Next action"); + Asm->EmitSLEB128(Action.NextAction); } // Emit the Catch TypeInfos. - if (!TypeInfos.empty()) { - Asm->OutStreamer.AddComment("-- Catch TypeInfos --"); + if (VerboseAsm && !TypeInfos.empty()) { + Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); Asm->OutStreamer.AddBlankLine(); + Entry = TypeInfos.size(); } + for (std::vector<const GlobalVariable *>::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { const GlobalVariable *GV = *I; - - Asm->OutStreamer.AddComment("TypeInfo"); + if (VerboseAsm) + Asm->OutStreamer.AddComment(Twine("TypeInfo ") + llvm::utostr(Entry--)); if (GV) Asm->EmitReference(GV, TTypeEncoding); else @@ -644,14 +700,21 @@ void DwarfException::EmitExceptionTable() { } // Emit the Exception Specifications. - if (!FilterIds.empty()) { - Asm->OutStreamer.AddComment("-- Filter IDs --"); + if (VerboseAsm && !FilterIds.empty()) { + Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); Asm->OutStreamer.AddBlankLine(); + Entry = 0; } for (std::vector<unsigned>::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { unsigned TypeID = *I; - Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0); + if (VerboseAsm) { + --Entry; + if (TypeID != 0) + Asm->OutStreamer.AddComment(Twine("FilterInfo ") + llvm::itostr(Entry)); + } + + Asm->EmitULEB128(TypeID); } Asm->EmitAlignment(2); |