From d6b257ddc5f33ee52f87db151a62e3bc602a4585 Mon Sep 17 00:00:00 2001 From: Alessandro Di Federico Date: Wed, 1 Mar 2017 10:44:22 +0100 Subject: [PATCH] Dismiss basic block statistics collection If we need this again, we can do it in revamb-dump. --- codegenerator.cpp | 4 -- jumptargetmanager.cpp | 114 ---------------------------------------- jumptargetmanager.h | 119 +----------------------------------------- 3 files changed, 1 insertion(+), 236 deletions(-) diff --git a/codegenerator.cpp b/codegenerator.cpp index ced66575a..6ce95db5d 100644 --- a/codegenerator.cpp +++ b/codegenerator.cpp @@ -639,7 +639,6 @@ void CodeGenerator::translate(uint64_t VirtualAddress) { size_t ConsumedSize = 0; ConsumedSize = ptc.translate(VirtualAddress, InstructionList.get()); - JumpTargets.registerOriginalBB(VirtualAddress, ConsumedSize); DBG("ptc", dumpTranslation(dbg, InstructionList.get())); @@ -891,9 +890,6 @@ void CodeGenerator::translate(uint64_t VirtualAddress) { PM.add(createDeadCodeEliminationPass()); PM.run(*TheModule); - // TODO: transform the following in passes? - JumpTargets.collectBBSummary(BBSummaryPath); - JumpTargets.translateIndirectJumps(); JumpTargets.finalizeJumpTargets(); diff --git a/jumptargetmanager.cpp b/jumptargetmanager.cpp index 4060cc7d4..573a74a42 100644 --- a/jumptargetmanager.cpp +++ b/jumptargetmanager.cpp @@ -929,118 +929,6 @@ private: std::queue> NewPC; }; -void JumpTargetManager::collectBBSummary(std::string OutputPath) { - BasicBlockVisitor BBV(DispatcherSwitch); - uint64_t NewPC = 0; - uint64_t PC = 0; - BasicBlock *BB = nullptr; - while (NewPC == 0) - std::tie(BB, NewPC) = BBV.pop(); - BBSummary *Summary = nullptr; - - std::set CPUStateSet; - std::set FunctionsSet; - std::set OpcodesSet; - - while (BB != nullptr) { - if (NewPC != 0) { - PC = NewPC; - auto It = containingOriginalBB(PC); - assert(It != OriginalBBStats.end()); - Summary = &It->second; - } - - // Update stats - for (Instruction &I : *BB) { - // TODO: Data dependencies - unsigned Opcode = I.getOpcode(); - const char *OpcodeName = I.getOpcodeName(); - Summary->Opcode[OpcodeName]++; - OpcodesSet.insert(OpcodeName); - - switch (Opcode) { - case Instruction::Load: - { - auto *L = static_cast(&I); - if (auto *State = dyn_cast(L->getPointerOperand())) { - CPUStateSet.insert(State); - Summary->ReadState[State]++; - } - - break; - } - case Instruction::Store: - { - auto *S = static_cast(&I); - if (auto *State = dyn_cast(S->getPointerOperand())) { - CPUStateSet.insert(State); - Summary->ReadState[State]++; - } - - break; - } - case Instruction::Call: - { - auto *Call = static_cast(&I); - if (auto *F = Call->getCalledFunction()) { - FunctionsSet.insert(F); - Summary->CalledFunctions[F]++; - } - - break; - } - default: - break; - } - } - - std::tie(BB, NewPC) = BBV.pop(); - } - - std::vector CPUState; - std::copy(CPUStateSet.begin(), - CPUStateSet.end(), - std::back_inserter(CPUState)); - std::vector Functions; - std::copy(FunctionsSet.begin(), - FunctionsSet.end(), - std::back_inserter(Functions)); - std::vector Opcodes; - std::copy(OpcodesSet.begin(), - OpcodesSet.end(), - std::back_inserter(Opcodes)); - - std::ofstream Output(OutputPath); - - Output << "address,size"; - for (GlobalVariable *V : CPUState) - Output << ",read_" << V->getName().str(); - for (GlobalVariable *V : CPUState) - Output << ",write_" << V->getName().str(); - for (Function *F : Functions) - Output << ",call_" << F->getName().str(); - for (const char *OpcodeName : Opcodes) - Output << ",opcode_" << OpcodeName; - Output << "\n"; - - for (auto P : OriginalBBStats) { - Output << std::dec << P.first << "," - << std::dec << P.second.Size; - - for (GlobalVariable *V : CPUState) - Output << "," << std::dec << P.second.ReadState[V]; - for (GlobalVariable *V : CPUState) - Output << "," << std::dec << P.second.WrittenState[V]; - for (Function *F : Functions) - Output << "," << std::dec << P.second.CalledFunctions[F]; - for (const char *OpcodeName : Opcodes) - Output << "," << P.second.Opcode[OpcodeName]; - - Output << "\n"; - } - -} - void JumpTargetManager::translateIndirectJumps() { if (ExitTB->use_empty()) return; @@ -1136,8 +1024,6 @@ BasicBlock *JumpTargetManager::registerJT(uint64_t PC, JTReason Reason) { if (InstrIt != OriginalInstructionAddresses.end()) { // Case 2: the address has already been met, but needs to be promoted to // BasicBlock level. - registerOriginalBB(PC, 0); - BasicBlock *ContainingBlock = InstrIt->second->getParent(); if (InstrIt->second == &*ContainingBlock->begin()) NewBlock = ContainingBlock; diff --git a/jumptargetmanager.h b/jumptargetmanager.h index 2ca366bf8..da57315d8 100644 --- a/jumptargetmanager.h +++ b/jumptargetmanager.h @@ -106,29 +106,6 @@ private: using interval_set = boost::icl::interval_set; using interval = boost::icl::interval; - /// \brief Data structure to collect statistics about an input basic block - struct BBSummary { - BBSummary(uint32_t Size) : Size(Size) { } - - /// Size in bytes of the basic block - unsigned Size; - /// Associative map keeping track of how many times a certain register has - /// been read - std::map ReadState; - /// Associative map keeping track of how many times a certain register has - /// been written - std::map WrittenState; - /// Associative map keeping track of how many times a certain function has - /// been called in the associated basic block. This is particularly useful - /// to count calls to QEMU helper functions and to count the amount of - /// instructions (in the form of calls to `newpc`) - std::map CalledFunctions; - /// Associative map keeping track of how many times a certain LLVM - /// instruction is used in the code generated translating the input basic - /// block - std::map Opcode; - }; - public: using BlockWithAddress = std::pair; static const BlockWithAddress NoMoreTargets; @@ -249,14 +226,6 @@ public: /// \brief Translate the non-constant jumps into jumps to the dispatcher void translateIndirectJumps(); - /// \brief Collect staticists about all the translated basic blocks - /// - /// Create a CSV containing all the information in BBSummary for all the - /// translated basic blocks. - /// - /// \param OutputPath path where the output CSV file should be stored. - void collectBBSummary(std::string OutputPath); - /// \brief Return the most recent instruction writing the program counter /// /// Note that the search is performed only in the current basic block. The @@ -431,77 +400,6 @@ public: unsigned Size, Endianess ReadEndianess) const; - /// \brief Register a new basic block in terms of the input architecture - /// - /// \param Address virtual address where the basic block starts. - /// \param Size size, in bytes, of the given basic block. - void registerOriginalBB(uint64_t Address, uint32_t Size) { - // TODO: this part is useful in case of erroneus situations where a basic - // block includes another one, a more clean approach is probably to - // drop all those included and then split again where they were. - auto StartIt = OriginalBBStats.lower_bound(Address); - if (StartIt->first == Address && StartIt->second.Size == Size) - return; - - auto NextIt = StartIt; - while (NextIt != OriginalBBStats.end() - && NextIt->first < Address + Size - && NextIt->first + NextIt->second.Size < Address + Size) { - NextIt++; - } - - if (StartIt != NextIt) - OriginalBBStats.erase(StartIt, NextIt); - - auto ItStart = containingOriginalBB(Address); - bool StartMatches = ItStart != OriginalBBStats.end(); - - if (Size == 0) { - assert(StartMatches); - uint32_t NewSize = ItStart->second.Size - (Address - ItStart->first); - OriginalBBStats.insert({ Address, BBSummary(NewSize) }); - ItStart->second.Size = ItStart->first - Address; - return; - } - - auto ItEnd = containingOriginalBB(Address + Size); - bool EndMatches = ItEnd != OriginalBBStats.end(); - - if (!StartMatches && !EndMatches) { - OriginalBBStats.insert({ Address, BBSummary(Size) }); - } else if (StartMatches && !EndMatches) { - ItStart->second.Size = ItStart->first - Address; - OriginalBBStats.insert({ Address, BBSummary(Size) }); - } else if (!StartMatches && EndMatches) { - OriginalBBStats.insert({ Address, BBSummary(ItEnd->first - Address) }); - } else if (StartMatches && EndMatches) { - // 100% match - if (Address == ItStart->first && Size == ItStart->second.Size) - return; - - // Reduce the previous basic block - ItStart->second.Size = ItStart->first - Address; - assert(ItStart->second.Size != 0); - - // Set the size of the new basic block - if (ItEnd == ItStart) { - if (!(Address + Size == ItEnd->first + ItEnd->second.Size)) { - // We're in a mistranslation situation, just ignore the error - // TODO: emit a warning - return; - } - } else { - Size = ItEnd->first - Address; - } - - // Create the new basic block - OriginalBBStats.insert({ Address, BBSummary(Size) }); - - } else { - llvm_unreachable("Unexpected situation"); - } - } - /// \brief Increment the counter of emitted branches since the last reset void newBranch() { NewBranches++; } @@ -581,20 +479,6 @@ private: /// \brief Populate the interval -> Symbol map from Binary.Symbols void initializeSymbolMap(); - /// \brief Return an iterator to the entry containing the given address range - typename std::map::iterator - containingOriginalBB(uint64_t Address) { - // Get the less or equal entry - auto It = containing(OriginalBBStats, Address); - - // Check if it's within the upper bound - if (It == OriginalBBStats.end() - || !(Address < It->first + It->second.Size)) - return OriginalBBStats.end(); - - return It; - } - // TODO: instead of a gigantic switch case we could map the original memory // area and write the address of the translated basic block at the jump // target @@ -616,7 +500,7 @@ private: using InstructionMap = std::map; llvm::Module &TheModule; - llvm::LLVMContext& Context; + llvm::LLVMContext &Context; llvm::Function* TheFunction; /// Holds the association between a PC and the last generated instruction for /// the previous instruction. @@ -639,7 +523,6 @@ private: bool EnableOSRA; - std::map OriginalBBStats; unsigned NewBranches = 0; std::set UnusedCodePointers;