/// extractLexicalScopes - Extract instruction ranges for each lexical scopes /// for the given machine function. void LexicalScopes:: extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges, DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { // 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) { const MachineInstr *RangeBeginMI = NULL; const MachineInstr *PrevMI = NULL; DebugLoc PrevDL; for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; // Check if instruction has valid location information. const DebugLoc MIDL = MInsn->getDebugLoc(); if (MIDL.isUnknown()) { PrevMI = MInsn; continue; } // If scope has not changed then skip this instruction. if (MIDL == PrevDL) { PrevMI = MInsn; continue; } // Ignore DBG_VALUE. It does not contribute to any instruction in output. if (MInsn->isDebugValue()) continue; if (RangeBeginMI) { // If we have already seen a beginning of an instruction range and // current instruction scope does not match scope of first instruction // in this range then create a new instruction range. InsnRange R(RangeBeginMI, PrevMI); MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); MIRanges.push_back(R); } // This is a beginning of a new instruction range. RangeBeginMI = MInsn; // Reset previous markers. PrevMI = MInsn; PrevDL = MIDL; } // Create last instruction range. if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { InsnRange R(RangeBeginMI, PrevMI); MIRanges.push_back(R); MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); } } }
void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) { // Ignore DBG_VALUE locations and function prologue. if (!Asm || MI->isDebugValue() || MI->getFlag(MachineInstr::FrameSetup)) return; DebugLoc DL = MI->getDebugLoc(); if (DL == PrevInstLoc || DL.isUnknown()) return; maybeRecordLocation(DL, Asm->MF); }
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, const LLVMContext &Ctx) { if (!DL.isUnknown()) { // Print source line info. DIScope Scope(DL.getScope(Ctx)); assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope."); // Omit the directory, because it's likely to be long and uninteresting. CommentOS << Scope.getFilename(); CommentOS << ':' << DL.getLine(); if (DL.getCol() != 0) CommentOS << ':' << DL.getCol(); DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); if (!InlinedAtDL.isUnknown()) { CommentOS << " @[ "; printDebugLoc(InlinedAtDL, CommentOS, Ctx); CommentOS << " ]"; } } }
unsigned ScopeInfoFinder::getInstLine(const Instruction *I) { DebugLoc Loc = I->getDebugLoc(); if (Loc.isUnknown()) { if (DEBUG_MATCHER) { errs() << "Unknown LOC" << "\n"; } return 0; } return Loc.getLine(); }
unsigned ScopeInfoFinder::getLastLine(Function *F) { if (F == NULL || F->begin() == F->end()) //empty block return 0; const BasicBlock & BB = F->back(); const Instruction & I = BB.back(); DebugLoc Loc = I.getDebugLoc(); if (Loc.isUnknown()) return 0; return Loc.getLine(); }
void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) { assert(!CurFn && "Can't process two functions at once!"); if (!Asm || !Asm->MMI->hasDebugInfo()) return; const Function *GV = MF->getFunction(); assert(FnDebugInfo.count(GV) == false); VisitedFunctions.push_back(GV); CurFn = &FnDebugInfo[GV]; // Find the end of the function prolog. // FIXME: is there a simpler a way to do this? Can we just search // for the first instruction of the function, not the last of the prolog? DebugLoc PrologEndLoc; bool EmptyPrologue = true; for (const auto &MBB : *MF) { if (!PrologEndLoc.isUnknown()) break; for (const auto &MI : MBB) { if (MI.isDebugValue()) continue; // First known non-DBG_VALUE and non-frame setup location marks // the beginning of the function body. // FIXME: do we need the first subcondition? if (!MI.getFlag(MachineInstr::FrameSetup) && (!MI.getDebugLoc().isUnknown())) { PrologEndLoc = MI.getDebugLoc(); break; } EmptyPrologue = false; } } // Record beginning of function if we have a non-empty prologue. if (!PrologEndLoc.isUnknown() && !EmptyPrologue) { DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext()); maybeRecordLocation(FnStartDL, MF); } }
bool DISubprogram::Verify() const { auto *N = getRaw(); if (!N) return false; if (!isScopeRef(N->getScope())) return false; if (auto *Op = N->getType()) if (!isa<MDNode>(Op)) return false; if (!isTypeRef(getContainingType())) return false; if (isLValueReference() && isRValueReference()) return false; // If a DISubprogram has an llvm::Function*, then scope chains from all // instructions within the function should lead to this DISubprogram. if (auto *F = getFunction()) { for (auto &BB : *F) { for (auto &I : BB) { DebugLoc DL = I.getDebugLoc(); if (DL.isUnknown()) continue; MDNode *Scope = nullptr; MDNode *IA = nullptr; // walk the inlined-at scopes while ((IA = DL.getInlinedAt())) DL = DebugLoc::getFromDILocation(IA); DL.getScopeAndInlinedAt(Scope, IA); if (!Scope) return false; assert(!IA); while (!DIDescriptor(Scope).isSubprogram()) { DILexicalBlockFile D(Scope); Scope = D.isLexicalBlockFile() ? D.getScope() : DebugLoc::getFromDILexicalBlock(Scope).getScope(); if (!Scope) return false; } if (!DISubprogram(Scope).describes(F)) return false; } } } return true; }
/// fixupLineNumbers - Update inlined instructions' line numbers to /// to encode location where these instructions are inlined. static void fixupLineNumbers(Function *Fn, Function::iterator FI, Instruction *TheCall) { DebugLoc TheCallDL = TheCall->getDebugLoc(); if (TheCallDL.isUnknown()) return; for (; FI != Fn->end(); ++FI) { for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { DebugLoc DL = BI->getDebugLoc(); if (!DL.isUnknown()) { BI->setDebugLoc(updateInlinedAtInfo(DL, TheCallDL, BI->getContext())); if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) { LLVMContext &Ctx = BI->getContext(); MDNode *InlinedAt = BI->getDebugLoc().getInlinedAt(Ctx); DVI->setOperand(2, createInlinedVariable(DVI->getVariable(), InlinedAt, Ctx)); } } } } }
void DIVariable::printExtendedName(raw_ostream &OS) const { const LLVMContext &Ctx = DbgNode->getContext(); StringRef Res = getName(); if (!Res.empty()) OS << Res << "," << getLineNumber(); if (MDNode *InlinedAt = getInlinedAt()) { DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); if (!InlinedAtDL.isUnknown()) { OS << " @["; printDebugLoc(InlinedAtDL, OS, Ctx); OS << "]"; } } }
bool DISubprogram::Verify() const { if (!isSubprogram()) return false; // Make sure context @ field 2 is a ScopeRef and type @ field 3 is a MDNode. if (!fieldIsScopeRef(DbgNode, 2)) return false; if (!fieldIsMDNode(DbgNode, 3)) return false; // Containing type @ field 4. if (!fieldIsTypeRef(DbgNode, 4)) return false; // A subprogram can't be both & and &&. if (isLValueReference() && isRValueReference()) return false; // If a DISubprogram has an llvm::Function*, then scope chains from all // instructions within the function should lead to this DISubprogram. if (auto *F = getFunction()) { for (auto &BB : *F) { for (auto &I : BB) { DebugLoc DL = I.getDebugLoc(); if (DL.isUnknown()) continue; MDNode *Scope = nullptr; MDNode *IA = nullptr; // walk the inlined-at scopes while ((IA = DL.getInlinedAt())) DL = DebugLoc::getFromDILocation(IA); DL.getScopeAndInlinedAt(Scope, IA); if (!Scope) return false; assert(!IA); while (!DIDescriptor(Scope).isSubprogram()) { DILexicalBlockFile D(Scope); Scope = D.isLexicalBlockFile() ? D.getScope() : DebugLoc::getFromDILexicalBlock(Scope).getScope(); if (!Scope) return false; } if (!DISubprogram(Scope).describes(F)) return false; } } } return DbgNode->getNumOperands() == 9 && getNumHeaderFields() == 12; }
void Matcher::processBasicBlock(Function *F) { for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) { /** Use first and last instruction to get the scope information **/ Instruction *first = & FI->front(); Instruction *last = & FI->back(); if (first == NULL || last == NULL) { errs() << "NULL scope instructions " << "\n"; continue; } DebugLoc Loc = first->getDebugLoc(); if (Loc.isUnknown()) { errs() << "Unknown LOC information" << "\n"; continue; } errs() << "Block :" << Loc.getLine(); Loc = last->getDebugLoc(); if (Loc.isUnknown()) { errs() << "Unknown LOC information" << "\n"; continue; } errs() << ", " << Loc.getLine() << "\n"; } }
void DebugLoc::dump(const LLVMContext &Ctx) const { #ifndef NDEBUG if (!isUnknown()) { dbgs() << getLine(); if (getCol() != 0) dbgs() << ',' << getCol(); DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); if (!InlinedAtDL.isUnknown()) { dbgs() << " @ "; InlinedAtDL.dump(Ctx); } else dbgs() << "\n"; } #endif }
void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) { if (DL.isUnknown()) return; if (!BeforePrintingInsn) return; const LLVMContext &Context = EmissionDetails.MF->getFunction()->getContext(); if (DL.getScope(Context) != 0 && PrevDL != DL) { JITEvent_EmittedFunctionDetails::LineStart NextLine; NextLine.Address = getCurrentPCValue(); NextLine.Loc = DL; EmissionDetails.LineStarts.push_back(NextLine); } PrevDL = DL; }
/// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i))); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; ++BI) { if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) processDeclare(DDI); DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext &Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isCompileUnit()) addCompileUnit(DICompileUnit(Scope)); else if (Scope.isSubprogram()) processSubprogram(DISubprogram(Scope)); else if (Scope.isLexicalBlock()) processLexicalBlock(DILexicalBlock(Scope)); if (MDNode *IA = Loc.getInlinedAt(Ctx)) processLocation(DILocation(IA)); } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { if (DIG.getVersion() <= LLVMDebugVersion10) addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); } } } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) processSubprogram(DISubprogram(NMD->getOperand(i))); }
void Matcher::processInst(Function *F) { for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) { /** Get each instruction's scope information **/ for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; BI++) { DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext & Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isLexicalBlock()) { DILexicalBlock DILB(Scope); errs() << "Block :" << DILB.getLineNumber() << ", " << DILB.getColumnNumber() << "\n"; } } } }
/// dominates - Return true if DebugLoc's lexical scope dominates at least one /// machine instruction's lexical scope in a given machine basic block. bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) { LexicalScope *Scope = getOrCreateLexicalScope(DL); if (!Scope) return false; // Current function scope covers all basic blocks in the function. if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF) return true; bool Result = false; for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ++I) { DebugLoc IDL = I->getDebugLoc(); if (IDL.isUnknown()) continue; if (LexicalScope *IScope = getOrCreateLexicalScope(IDL)) if (Scope->dominates(IScope)) return true; } return Result; }
void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const { if (!isUnknown()) { // Print source line info. DIScope Scope(getScope(Ctx)); assert((!Scope || Scope.isScope()) && "Scope of a DebugLoc should be null or a DIScope."); if (Scope) OS << Scope.getFilename(); else OS << "<unknown>"; OS << ':' << getLine(); if (getCol() != 0) OS << ':' << getCol(); DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); if (!InlinedAtDL.isUnknown()) { OS << " @[ "; InlinedAtDL.print(Ctx, OS); OS << " ]"; } } }
bool SancusModuleCreator::handleFunction(Function& f) { if (f.isIntrinsic() || f.isDeclaration()) return false; bool modified = false; // HACK: clang fails to add the needed attributes to main(), add them here if (f.getName() == "main") { f.setSection(".init9"); f.setAlignment(2); modified = true; } SancusModuleInfo info = getSancusModuleInfo(&f); if (info.isInSm) { f.setSection(info.getTextSection()); modified = true; } if (info.isEntry) entries.push_back(&f); std::map<Instruction*, Instruction*> verifications; std::map<Instruction*, Instruction*> replacements; for (inst_iterator it = inst_begin(f), end = inst_end(f); it != end; ++it) { Instruction* inst = &*it; CallSite cs(inst); if (!cs) continue; Function* callee = getCalledFunction(cs); if (callee == nullptr) { if (CallInst* ci = cast<CallInst>(&*it)) { if (ci->isInlineAsm()) continue; } DebugLoc loc = inst->getDebugLoc(); std::string locStr; if (!loc.isUnknown()) { Twine t(" (" + Twine(loc.getLine()) + ":" + Twine(loc.getCol()) + ")"); locStr = t.str(); } // FIXME this warning is too strict since it also fires on "normal" // function pointers. we should try to warn only when a function // pointer is used inside an SM or is created from an SM function. errs() << "WARNING: In function " << f.getName() << locStr << ": Function pointers not supported yet\n"; continue; } else if (callee->isIntrinsic()) continue; else if (callee->getName() == "sancus_call") { replacements[cs.getInstruction()] = handleSancusCall(cs).getInstruction(); continue; } if (Instruction* v = getVerification(info, getSancusModuleInfo(callee), *f.getParent())) { verifications[inst] = v; } Function* stub = getStub(f, *callee); cs.setCalledFunction(stub); if (stub != callee) modified = true; } for (auto pair : verifications) pair.second->insertBefore(pair.first); for (auto pair : replacements) { auto oldInst = pair.first; auto newInst = pair.second; newInst->insertBefore(oldInst); oldInst->replaceAllUsesWith(newInst); oldInst->eraseFromParent(); } return modified; }
/// runOnMachineFunction - This emits the frame section, autos section and /// assembly for each instruction. Also takes care of function begin debug /// directive and file begin debug directive (if required) for the function. /// bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { this->MF = &MF; // This calls the base class function required to be called at beginning // of runOnMachineFunction. SetupMachineFunction(MF); // Get the mangled name. const Function *F = MF.getFunction(); CurrentFnName = Mang->getMangledName(F); // Emit the function frame (args and temps). EmitFunctionFrame(MF); DbgInfo.BeginFunction(MF); // Emit the autos section of function. EmitAutos(CurrentFnName); // Now emit the instructions of function in its code section. const MCSection *fCodeSection = getObjFileLowering().getSectionForFunction(CurrentFnName); // Start the Code Section. O << "\n"; OutStreamer.SwitchSection(fCodeSection); // Emit the frame address of the function at the beginning of code. O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; // Emit function start label. O << CurrentFnName << ":\n"; DebugLoc CurDL; O << "\n"; // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { printBasicBlockLabel(I, true); O << '\n'; } // Print a basic block. for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Emit the line directive if source line changed. const DebugLoc DL = II->getDebugLoc(); if (!DL.isUnknown() && DL != CurDL) { DbgInfo.ChangeDebugLoc(MF, DL); CurDL = DL; } // Print the assembly for the instruction. printMachineInstruction(II); } } // Emit function end debug directives. DbgInfo.EndFunction(MF); return false; // we didn't modify anything. }
void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { if (const MachineSDNode *MN = dyn_cast<MachineSDNode>(this)) { if (!MN->memoperands_empty()) { OS << "<"; OS << "Mem:"; for (MachineSDNode::mmo_iterator i = MN->memoperands_begin(), e = MN->memoperands_end(); i != e; ++i) { OS << **i; if (llvm::next(i) != e) OS << " "; } OS << ">"; } } else if (const ShuffleVectorSDNode *SVN = dyn_cast<ShuffleVectorSDNode>(this)) { OS << "<"; for (unsigned i = 0, e = ValueList[0].getVectorNumElements(); i != e; ++i) { int Idx = SVN->getMaskElt(i); if (i) OS << ","; if (Idx < 0) OS << "u"; else OS << Idx; } OS << ">"; } else if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) { OS << '<' << CSDN->getAPIntValue() << '>'; } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) { if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle) OS << '<' << CSDN->getValueAPF().convertToFloat() << '>'; else if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEdouble) OS << '<' << CSDN->getValueAPF().convertToDouble() << '>'; else { OS << "<APFloat("; CSDN->getValueAPF().bitcastToAPInt().dump(); OS << ")>"; } } else if (const GlobalAddressSDNode *GADN = dyn_cast<GlobalAddressSDNode>(this)) { int64_t offset = GADN->getOffset(); OS << '<'; WriteAsOperand(OS, GADN->getGlobal()); OS << '>'; if (offset > 0) OS << " + " << offset; else OS << " " << offset; if (unsigned int TF = GADN->getTargetFlags()) OS << " [TF=" << TF << ']'; } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) { OS << "<" << FIDN->getIndex() << ">"; } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(this)) { OS << "<" << JTDN->getIndex() << ">"; if (unsigned int TF = JTDN->getTargetFlags()) OS << " [TF=" << TF << ']'; } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){ int offset = CP->getOffset(); if (CP->isMachineConstantPoolEntry()) OS << "<" << *CP->getMachineCPVal() << ">"; else OS << "<" << *CP->getConstVal() << ">"; if (offset > 0) OS << " + " << offset; else OS << " " << offset; if (unsigned int TF = CP->getTargetFlags()) OS << " [TF=" << TF << ']'; } else if (const TargetIndexSDNode *TI = dyn_cast<TargetIndexSDNode>(this)) { OS << "<" << TI->getIndex() << '+' << TI->getOffset() << ">"; if (unsigned TF = TI->getTargetFlags()) OS << " [TF=" << TF << ']'; } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) { OS << "<"; const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); if (LBB) OS << LBB->getName() << " "; OS << (const void*)BBDN->getBasicBlock() << ">"; } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) { OS << ' ' << PrintReg(R->getReg(), G ? G->getTarget().getRegisterInfo() :0); } else if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(this)) { OS << "'" << ES->getSymbol() << "'"; if (unsigned int TF = ES->getTargetFlags()) OS << " [TF=" << TF << ']'; } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) { if (M->getValue()) OS << "<" << M->getValue() << ">"; else OS << "<null>"; } else if (const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(this)) { if (MD->getMD()) OS << "<" << MD->getMD() << ">"; else OS << "<null>"; } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) { OS << ":" << N->getVT().getEVTString(); } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) { OS << "<" << *LD->getMemOperand(); bool doExt = true; switch (LD->getExtensionType()) { default: doExt = false; break; case ISD::EXTLOAD: OS << ", anyext"; break; case ISD::SEXTLOAD: OS << ", sext"; break; case ISD::ZEXTLOAD: OS << ", zext"; break; } if (doExt) OS << " from " << LD->getMemoryVT().getEVTString(); const char *AM = getIndexedModeName(LD->getAddressingMode()); if (*AM) OS << ", " << AM; OS << ">"; } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(this)) { OS << "<" << *ST->getMemOperand(); if (ST->isTruncatingStore()) OS << ", trunc to " << ST->getMemoryVT().getEVTString(); const char *AM = getIndexedModeName(ST->getAddressingMode()); if (*AM) OS << ", " << AM; OS << ">"; } else if (const MemSDNode* M = dyn_cast<MemSDNode>(this)) { OS << "<" << *M->getMemOperand() << ">"; } else if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(this)) { OS << "<"; WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false); OS << ", "; WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false); OS << ">"; if (unsigned int TF = BA->getTargetFlags()) OS << " [TF=" << TF << ']'; } if (G) if (unsigned Order = G->GetOrdering(this)) OS << " [ORD=" << Order << ']'; if (getNodeId() != -1) OS << " [ID=" << getNodeId() << ']'; DebugLoc dl = getDebugLoc(); if (G && !dl.isUnknown()) { DIScope Scope(dl.getScope(G->getMachineFunction().getFunction()->getContext())); OS << " dbg:"; // Omit the directory, since it's usually long and uninteresting. if (Scope.Verify()) OS << Scope.getFilename(); else OS << "<unknown>"; OS << ':' << dl.getLine(); if (dl.getCol() != 0) OS << ':' << dl.getCol(); } }
/// runOnMachineFunction - This uses the printInstruction() /// method to print assembly for each instruction. /// bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { this->MF = &MF; // This calls the base class function required to be called at beginning // of runOnMachineFunction. SetupMachineFunction(MF); // Get the mangled name. const Function *F = MF.getFunction(); CurrentFnName = Mang->getValueName(F); // Emit the function variables. EmitFunctionFrame(MF); // Emit function begin debug directives DbgInfo.EmitFunctBeginDI(F); EmitAutos(CurrentFnName); const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str(); const Section *fCodeSection = TAI->getNamedSection(codeSection, SectionFlags::Code); O << "\n"; // Start the Code Section. SwitchToSection (fCodeSection); // Emit the frame address of the function at the beginning of code. O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; // Emit function start label. O << CurrentFnName << ":\n"; // For emitting line directives, we need to keep track of the current // source line. When it changes then only emit the line directive. unsigned CurLine = 0; O << "\n"; // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { printBasicBlockLabel(I, true); O << '\n'; } for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Emit the line directive if source line changed. const DebugLoc DL = II->getDebugLoc(); if (!DL.isUnknown()) { unsigned line = MF.getDebugLocTuple(DL).Line; if (line != CurLine) { O << "\t.line " << line << "\n"; CurLine = line; } } // Print the assembly for the instruction. printMachineInstruction(II); } } // Emit function end debug directives. DbgInfo.EmitFunctEndDI(F, CurLine); return false; // we didn't modify anything. }