Skip to content

Commit

Permalink
Remove double print assembly.ll
Browse files Browse the repository at this point in the history
  • Loading branch information
ladisgin authored and misonijnik committed Apr 12, 2023
1 parent e4ec539 commit eea2f58
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 70 deletions.
13 changes: 8 additions & 5 deletions include/klee/Module/InstructionInfoTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef KLEE_INSTRUCTIONINFOTABLE_H
#define KLEE_INSTRUCTIONINFOTABLE_H

#include <llvm/ADT/Optional.h>
#include <llvm/Support/raw_ostream.h>
#include <memory>
#include <string>
#include <unordered_map>
Expand All @@ -32,13 +34,13 @@ struct InstructionInfo {
/// @brief Column number in source file.
unsigned column;
/// @brief Line number in generated assembly.ll.
unsigned assemblyLine;
llvm::Optional<uint64_t> assemblyLine;
/// @brief Source file name.
const std::string &file;

public:
InstructionInfo(unsigned id, const std::string &file, unsigned line,
unsigned column, unsigned assemblyLine)
unsigned column, llvm::Optional<uint64_t> assemblyLine)
: id{id}, line{line}, column{column},
assemblyLine{assemblyLine}, file{file} {}
};
Expand All @@ -50,13 +52,13 @@ struct FunctionInfo {
/// @brief Line number in source file.
unsigned line;
/// @brief Line number in generated assembly.ll.
uint64_t assemblyLine;
llvm::Optional<uint64_t> assemblyLine;
/// @brief Source file name.
const std::string &file;

public:
FunctionInfo(unsigned id, const std::string &file, unsigned line,
uint64_t assemblyLine)
llvm::Optional<uint64_t> assemblyLine)
: id{id}, line{line}, assemblyLine{assemblyLine}, file{file} {}

FunctionInfo(const FunctionInfo &) = delete;
Expand All @@ -74,7 +76,8 @@ class InstructionInfoTable {
std::vector<std::unique_ptr<std::string>> internedStrings;

public:
explicit InstructionInfoTable(const llvm::Module &m);
explicit InstructionInfoTable(
const llvm::Module &m, std::unique_ptr<llvm::raw_fd_ostream> assemblyFS);

unsigned getMaxID() const;
const InstructionInfo &getInfo(const llvm::Instruction &) const;
Expand Down
9 changes: 6 additions & 3 deletions lib/Core/ExecutionState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,12 @@ void ExecutionState::dumpStack(llvm::raw_ostream &out) const {
Function *f = sf.kf->function;
const InstructionInfo &ii = *target->info;
out << "\t#" << idx++;
std::stringstream AssStream;
AssStream << std::setw(8) << std::setfill('0') << ii.assemblyLine;
out << AssStream.str();
if (ii.assemblyLine.hasValue()) {
std::stringstream AssStream;
AssStream << std::setw(8) << std::setfill('0')
<< ii.assemblyLine.getValue();
out << AssStream.str();
}
out << " in " << f->getName().str() << " (";
// Yawn, we could go up and print varargs if we wanted to.
unsigned index = 0;
Expand Down
16 changes: 9 additions & 7 deletions lib/Core/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,9 +1461,10 @@ void Executor::printDebugInstructions(ExecutionState &state) {
!DebugPrintInstructions.isSet(FILE_COMPACT)) {
(*stream) << " " << state.pc->getSourceLocation() << ':';
}

(*stream) << state.pc->info->assemblyLine << ':' << state.getID();

if (state.pc->info->assemblyLine.hasValue()) {
(*stream) << state.pc->info->assemblyLine.getValue() << ':';
}
(*stream) << state.getID();
if (DebugPrintInstructions.isSet(STDERR_ALL) ||
DebugPrintInstructions.isSet(FILE_ALL))
(*stream) << ':' << *(state.pc->inst);
Expand Down Expand Up @@ -4197,10 +4198,11 @@ void Executor::terminateStateOnError(ExecutionState &state,
llvm::raw_string_ostream msg(MsgString);
msg << "Error: " << message << '\n';
if (!ii.file.empty()) {
msg << "File: " << ii.file << '\n'
<< "Line: " << ii.line << '\n'
<< "assembly.ll line: " << ii.assemblyLine << '\n'
<< "State: " << state.getID() << '\n';
msg << "File: " << ii.file << '\n' << "Line: " << ii.line << '\n';
if (ii.assemblyLine.hasValue()) {
msg << "assembly.ll line: " << ii.assemblyLine.getValue() << '\n';
}
msg << "State: " << state.getID() << '\n';
}
msg << "Stack: \n";
state.dumpStack(msg);
Expand Down
14 changes: 11 additions & 3 deletions lib/Core/StatsTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,10 @@ void StatsTracker::writeIStats() {
of << "fl=" << ii.file << "\n";
sourceFile = ii.file;
}
of << ii.assemblyLine << " ";

assert(ii.assemblyLine.hasValue());
of << ii.assemblyLine.getValue() << " ";

of << ii.line << " ";
for (unsigned i = 0; i < nStats; i++)
if (istatsMask.test(i))
Expand All @@ -766,10 +769,15 @@ void StatsTracker::writeIStats() {
of << "cfl=" << fii.file << "\n";
of << "cfn=" << f->getName().str() << "\n";
of << "calls=" << csi.count << " ";
of << fii.assemblyLine << " ";

assert(fii.assemblyLine.hasValue());
of << fii.assemblyLine.getValue() << " ";

of << fii.line << "\n";

of << ii.assemblyLine << " ";
assert(ii.assemblyLine.hasValue());
of << ii.assemblyLine.getValue() << " ";

of << ii.line << " ";
for (unsigned i = 0; i < nStats; i++) {
if (istatsMask.test(i)) {
Expand Down
1 change: 1 addition & 0 deletions lib/Module/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(KLEE_MODULE_COMPONENT_SRCS
PhiCleaner.cpp
RaiseAsm.cpp
ReturnSplitter.cpp
StreamWithLine.cpp
)

if (USE_WORKAROUND_LLVM_PR39177)
Expand Down
75 changes: 34 additions & 41 deletions lib/Module/InstructionInfoTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "klee/Module/InstructionInfoTable.h"
#include "klee/Config/Version.h"

#include "StreamWithLine.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DebugInfo.h"
Expand All @@ -25,6 +26,7 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <llvm/ADT/Optional.h>

#include <cstdint>
#include <map>
Expand All @@ -35,64 +37,47 @@ using namespace klee;
class InstructionToLineAnnotator : public llvm::AssemblyAnnotationWriter {
public:
void emitInstructionAnnot(const llvm::Instruction *i,
llvm::formatted_raw_ostream &os) {
os << "%%%";
os << reinterpret_cast<std::uintptr_t>(i);
llvm::formatted_raw_ostream &os) override {
os << "%%%" + std::to_string(reinterpret_cast<std::uintptr_t>(i));
}

void emitFunctionAnnot(const llvm::Function *f,
llvm::formatted_raw_ostream &os) {
os << "%%%";
os << reinterpret_cast<std::uintptr_t>(f);
llvm::formatted_raw_ostream &os) override {
os << "%%%" + std::to_string(reinterpret_cast<std::uintptr_t>(f));
}
};

static std::map<uintptr_t, uint64_t>
buildInstructionToLineMap(const llvm::Module &m) {
static std::unordered_map<uintptr_t, uint64_t>
buildInstructionToLineMap(const llvm::Module &m,
std::unique_ptr<llvm::raw_fd_ostream> assemblyFS) {

std::map<uintptr_t, uint64_t> mapping;
std::unordered_map<uintptr_t, uint64_t> mapping;
InstructionToLineAnnotator a;
std::string str;

llvm::raw_string_ostream os(str);
StreamWithLine os(std::move(assemblyFS));
m.print(os, &a);
os.flush();

const char *s;

unsigned line = 1;
for (s = str.c_str(); *s; s++) {
if (*s != '\n')
continue;

line++;
if (s[1] != '%' || s[2] != '%' || s[3] != '%')
continue;

s += 4;
char *end;
uint64_t value = strtoull(s, &end, 10);
if (end != s) {
mapping.insert(std::make_pair(value, line));
}
s = end;
}

return mapping;
return os.getMapping();
}

class DebugInfoExtractor {
std::vector<std::unique_ptr<std::string>> &internedStrings;
std::map<uintptr_t, uint64_t> lineTable;
std::unordered_map<uintptr_t, uint64_t> lineTable;

const llvm::Module &module;
bool withAsm = false;

public:
DebugInfoExtractor(
std::vector<std::unique_ptr<std::string>> &_internedStrings,
const llvm::Module &_module)
const llvm::Module &_module,
std::unique_ptr<llvm::raw_fd_ostream> assemblyFS)
: internedStrings(_internedStrings), module(_module) {
lineTable = buildInstructionToLineMap(module);
if (assemblyFS) {
withAsm = true;
lineTable = buildInstructionToLineMap(module, std::move(assemblyFS));
}
}

std::string &getInternedString(const std::string &s) {
Expand All @@ -111,7 +96,10 @@ class DebugInfoExtractor {
}

std::unique_ptr<FunctionInfo> getFunctionInfo(const llvm::Function &Func) {
auto asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Func));
llvm::Optional<uint64_t> asmLine;
if (withAsm) {
asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Func));
}
auto dsub = Func.getSubprogram();

if (dsub != nullptr) {
Expand All @@ -127,7 +115,10 @@ class DebugInfoExtractor {

std::unique_ptr<InstructionInfo>
getInstructionInfo(const llvm::Instruction &Inst, const FunctionInfo *f) {
auto asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Inst));
llvm::Optional<uint64_t> asmLine;
if (withAsm) {
asmLine = lineTable.at(reinterpret_cast<std::uintptr_t>(&Inst));
}

// Retrieve debug information associated with instruction
auto dl = Inst.getDebugLoc();
Expand Down Expand Up @@ -161,18 +152,20 @@ class DebugInfoExtractor {
}
};

InstructionInfoTable::InstructionInfoTable(const llvm::Module &m) {
InstructionInfoTable::InstructionInfoTable(
const llvm::Module &m, std::unique_ptr<llvm::raw_fd_ostream> assemblyFS) {
// Generate all debug instruction information
DebugInfoExtractor DI(internedStrings, m);
DebugInfoExtractor DI(internedStrings, m, std::move(assemblyFS));

for (const auto &Func : m) {
auto F = DI.getFunctionInfo(Func);
auto FR = F.get();
functionInfos.insert(std::make_pair(&Func, std::move(F)));
functionInfos.emplace(&Func, std::move(F));

for (auto it = llvm::inst_begin(Func), ie = llvm::inst_end(Func); it != ie;
++it) {
auto instr = &*it;
infos.insert(std::make_pair(instr, DI.getInstructionInfo(*instr, FR)));
infos.emplace(instr, DI.getInstructionInfo(*instr, FR));
}
}

Expand Down
20 changes: 10 additions & 10 deletions lib/Module/KModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,6 @@ void KModule::optimiseAndPrepare(
}

void KModule::manifest(InterpreterHandler *ih, bool forceSourceOutput) {
if (OutputSource || forceSourceOutput) {
std::unique_ptr<llvm::raw_fd_ostream> os(ih->openOutputFile("assembly.ll"));
assert(os && !os->has_error() && "unable to open source output");
*os << *module;
}

if (OutputModule) {
std::unique_ptr<llvm::raw_fd_ostream> f(ih->openOutputFile("final.bc"));
Expand All @@ -362,14 +357,19 @@ void KModule::manifest(InterpreterHandler *ih, bool forceSourceOutput) {
#endif
}

/* Build shadow structures */

infos = std::unique_ptr<InstructionInfoTable>(
new InstructionInfoTable(*module.get()));
{
/* Build shadow structures */
std::unique_ptr<llvm::raw_fd_ostream> assemblyFS;
if (OutputSource || forceSourceOutput) {
assemblyFS = ih->openOutputFile("assembly.ll");
}
infos =
std::make_unique<InstructionInfoTable>(*module, std::move(assemblyFS));
}

std::vector<Function *> declarations;

for (auto &Function : *module) {
for (auto &Function : module->functions()) {
if (Function.isDeclaration()) {
declarations.push_back(&Function);
}
Expand Down
Loading

0 comments on commit eea2f58

Please sign in to comment.