From a329a133d66a86249a3b1ce8025a88f4c0b197c4 Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Wed, 13 Nov 2013 23:43:19 +0100 Subject: Simplify acquisition of debug informtion for instruction info with newer LLVM versions With newer LLVM versions (starting with LLVM 2.7) debug information are directly associated as meta data with each instruction. Therefore, debug information can be acquired directly from each instruction. --- lib/Module/InstructionInfoTable.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'lib/Module/InstructionInfoTable.cpp') diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp index 301db1ff..4285c6b0 100644 --- a/lib/Module/InstructionInfoTable.cpp +++ b/lib/Module/InstructionInfoTable.cpp @@ -111,6 +111,26 @@ InstructionInfoTable::InstructionInfoTable(Module *m) const std::string *initialFile = &dummyString; unsigned initialLine = 0; +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) + for (inst_iterator it = inst_begin(fnIt), ie = inst_end(fnIt); it != ie; + ++it) { + const std::string *initialFile = &dummyString; + unsigned initialLine = 0; + Instruction *instr = &*it; + unsigned assemblyLine = 0; + + std::map::const_iterator ltit = + lineTable.find(instr); + if (ltit!=lineTable.end()) + assemblyLine = ltit->second; + getInstructionDebugInfo(instr, initialFile, initialLine); + infos.insert(std::make_pair(instr, + InstructionInfo(id++, + *initialFile, + initialLine, + assemblyLine))); + } +#else // It may be better to look for the closest stoppoint to the entry // following the CFG, but it is not clear that it ever matters in // practice. @@ -118,7 +138,7 @@ InstructionInfoTable::InstructionInfoTable(Module *m) it != ie; ++it) if (getInstructionDebugInfo(&*it, initialFile, initialLine)) break; - + typedef std::map > sourceinfo_ty; sourceinfo_ty sourceInfo; @@ -167,6 +187,7 @@ InstructionInfoTable::InstructionInfoTable(Module *m) } } while (!worklist.empty()); } +#endif } } -- cgit 1.4.1 From 58de8cdce75bcee981ec813c57fb2ed7e83e9878 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Dec 2013 16:01:51 +0000 Subject: Remove old algorithm for acquiring debug info. Since LLVM 2.7, debug information is attached directly to most instructions so the simpler algorithm added in 5ecfd6e2fd5becc10be355b3a20d014e76e40518 can be used. Since support for LLVM version < 2.9 has been removed the old algorithm should be removed. This has been tested with LLVM 2.9 and LLVM 3.3 --- lib/Module/Checks.cpp | 19 ++++++------ lib/Module/InstructionInfoTable.cpp | 61 ------------------------------------- 2 files changed, 10 insertions(+), 70 deletions(-) (limited to 'lib/Module/InstructionInfoTable.cpp') diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp index bf37eea2..80b6b245 100644 --- a/lib/Module/Checks.cpp +++ b/lib/Module/Checks.cpp @@ -82,13 +82,13 @@ bool DivCheckPass::runOnModule(Module &M) { NULL); divZeroCheckFunction = cast(fc); } -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) - CallInst * ci = -#endif - CallInst::Create(divZeroCheckFunction, denominator, "", &*i); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) + + CallInst * ci = CallInst::Create(divZeroCheckFunction, denominator, "", &*i); + + // Set debug location of checking call to that of the div/rem + // operation so error locations are reported in the correct + // location. ci->setDebugLoc(binOp->getDebugLoc()); -#endif moduleChanged = true; } } @@ -143,13 +143,14 @@ bool OvershiftCheckPass::runOnModule(Module &M) { } // Inject CallInstr to check if overshifting possible + CallInst* ci = #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) - CallInst * ci = CallInst::Create(overshiftCheckFunction, args, "", &*i); - // set debug information from binary operand to preserve it - ci->setDebugLoc(binOp->getDebugLoc()); + CallInst::Create(overshiftCheckFunction, args, "", &*i); #else CallInst::Create(overshiftCheckFunction, args.begin(), args.end(), "", &*i); #endif + // set debug information from binary operand to preserve it + ci->setDebugLoc(binOp->getDebugLoc()); moduleChanged = true; } } diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp index 4285c6b0..204457d2 100644 --- a/lib/Module/InstructionInfoTable.cpp +++ b/lib/Module/InstructionInfoTable.cpp @@ -108,10 +108,7 @@ InstructionInfoTable::InstructionInfoTable(Module *m) for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); fnIt != fn_ie; ++fnIt) { - const std::string *initialFile = &dummyString; - unsigned initialLine = 0; -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) for (inst_iterator it = inst_begin(fnIt), ie = inst_end(fnIt); it != ie; ++it) { const std::string *initialFile = &dummyString; @@ -130,64 +127,6 @@ InstructionInfoTable::InstructionInfoTable(Module *m) initialLine, assemblyLine))); } -#else - // It may be better to look for the closest stoppoint to the entry - // following the CFG, but it is not clear that it ever matters in - // practice. - for (inst_iterator it = inst_begin(fnIt), ie = inst_end(fnIt); - it != ie; ++it) - if (getInstructionDebugInfo(&*it, initialFile, initialLine)) - break; - - typedef std::map > - sourceinfo_ty; - sourceinfo_ty sourceInfo; - for (llvm::Function::iterator bbIt = fnIt->begin(), bbie = fnIt->end(); - bbIt != bbie; ++bbIt) { - std::pair - res = sourceInfo.insert(std::make_pair(bbIt, - std::make_pair(initialFile, - initialLine))); - if (!res.second) - continue; - - std::vector worklist; - worklist.push_back(bbIt); - - do { - BasicBlock *bb = worklist.back(); - worklist.pop_back(); - - sourceinfo_ty::iterator si = sourceInfo.find(bb); - assert(si != sourceInfo.end()); - const std::string *file = si->second.first; - unsigned line = si->second.second; - - for (BasicBlock::iterator it = bb->begin(), ie = bb->end(); - it != ie; ++it) { - Instruction *instr = it; - unsigned assemblyLine = 0; - std::map::const_iterator ltit = - lineTable.find(instr); - if (ltit!=lineTable.end()) - assemblyLine = ltit->second; - getInstructionDebugInfo(instr, file, line); - infos.insert(std::make_pair(instr, - InstructionInfo(id++, - *file, - line, - assemblyLine))); - } - - for (succ_iterator it = succ_begin(bb), ie = succ_end(bb); - it != ie; ++it) { - if (sourceInfo.insert(std::make_pair(*it, - std::make_pair(file, line))).second) - worklist.push_back(*it); - } - } while (!worklist.empty()); - } -#endif } } -- cgit 1.4.1 From 6829fb93ce36afc852c97928b94ab9ad5e221aec Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Dec 2013 16:23:10 +0000 Subject: Only record debug info into InstructionInfoTable if debug information is actually available. In addition if doing a DEBUG build then the command line flag -debug-only=klee_missing_debug shows the instructions missing debug information and -debug-only=klee_obtained_debug show the instructions with debug information. --- lib/Module/InstructionInfoTable.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'lib/Module/InstructionInfoTable.cpp') diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp index 204457d2..19d7e511 100644 --- a/lib/Module/InstructionInfoTable.cpp +++ b/lib/Module/InstructionInfoTable.cpp @@ -33,6 +33,7 @@ #include "llvm/Analysis/DebugInfo.h" #endif #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Support/Debug.h" #include #include @@ -120,12 +121,23 @@ InstructionInfoTable::InstructionInfoTable(Module *m) lineTable.find(instr); if (ltit!=lineTable.end()) assemblyLine = ltit->second; - getInstructionDebugInfo(instr, initialFile, initialLine); - infos.insert(std::make_pair(instr, - InstructionInfo(id++, - *initialFile, - initialLine, - assemblyLine))); + if (getInstructionDebugInfo(instr, initialFile, initialLine)) + { + infos.insert(std::make_pair(instr, + InstructionInfo(id++, + *initialFile, + initialLine, + assemblyLine))); + DEBUG_WITH_TYPE("klee_obtained_debug", dbgs() << + "Instruction: \"" << *instr << "\" (assembly line " << assemblyLine << + ") has debug location " << *initialFile << ":" << initialLine << "\n"); + } + else + { + DEBUG_WITH_TYPE("klee_missing_debug", dbgs() << + "Instruction: \"" << *instr << "\" (assembly line " << assemblyLine << + ") is missing debug info.\n"); + } } } } -- cgit 1.4.1