Added instruction counting
This commit is contained in:
		@@ -28,6 +28,8 @@ void InstructionBlock::GenerateCode()
 | 
			
		||||
    auto ir_builder = Module()->IrBuilder();
 | 
			
		||||
    ir_builder->SetInsertPoint(entry_basic_block);
 | 
			
		||||
 | 
			
		||||
    module->GenerateIncInstructionCount();
 | 
			
		||||
 | 
			
		||||
    instruction->GenerateCode(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,15 @@ void ModuleGen::Run()
 | 
			
		||||
    GenerateBlockAddressArray();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModuleGen::GenerateIncInstructionCount()
 | 
			
		||||
{
 | 
			
		||||
    auto load = ir_builder->CreateLoad(instruction_count);
 | 
			
		||||
    auto inc = ir_builder->CreateAdd(load, ir_builder->getInt32(1));
 | 
			
		||||
    auto store = ir_builder->CreateStore(inc, instruction_count);
 | 
			
		||||
    tbaa->TagInstructionCount(load);
 | 
			
		||||
    tbaa->TagInstructionCount(store);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModuleGen::BranchReadPC()
 | 
			
		||||
{
 | 
			
		||||
    if (verify)
 | 
			
		||||
@@ -111,6 +120,9 @@ void ModuleGen::GenerateGlobals()
 | 
			
		||||
 | 
			
		||||
    // bool Verify - contains the value of verify for citra usage
 | 
			
		||||
    new GlobalVariable(*module, ir_builder->getInt1Ty(), true, GlobalValue::ExternalLinkage, ir_builder->getInt1(verify), "Verify");
 | 
			
		||||
 | 
			
		||||
    instruction_count = new GlobalVariable(*Module(), ir_builder->getInt32Ty(), false, GlobalValue::ExternalLinkage,
 | 
			
		||||
        ir_builder->getInt32(0), "InstructionCount");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModuleGen::GenerateBlockAddressArray()
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    void Run();
 | 
			
		||||
 | 
			
		||||
    void GenerateIncInstructionCount();
 | 
			
		||||
    // Generate code to read pc and run all following instructions, used in cases of indirect branch
 | 
			
		||||
    void BranchReadPC();
 | 
			
		||||
    // Generate code to write to pc and run all following instructions, used in cases of direct branch
 | 
			
		||||
@@ -80,6 +81,11 @@ private:
 | 
			
		||||
     */
 | 
			
		||||
    llvm::ArrayType *block_address_array_type;
 | 
			
		||||
    llvm::GlobalVariable *block_address_array;
 | 
			
		||||
    /*
 | 
			
		||||
     * i32 InstructionCount;
 | 
			
		||||
     *  The count of instructions executed
 | 
			
		||||
     */
 | 
			
		||||
    llvm::GlobalVariable *instruction_count;
 | 
			
		||||
    /*
 | 
			
		||||
     * i8 *GetBlockAddress(u32 pc)
 | 
			
		||||
     *  Returns the address of the block for the instruction at pc
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ void TBAA::GenerateTags()
 | 
			
		||||
        register_nodes[i] = md_builder.createTBAAScalarTypeNode(ss.str(), tbaa_root);
 | 
			
		||||
    }
 | 
			
		||||
    const_node = md_builder.createTBAAScalarTypeNode("Readonly", tbaa_root);
 | 
			
		||||
    instruction_count_node = md_builder.createTBAAScalarTypeNode("InstructionCount", tbaa_root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TBAA::TagRegister(Instruction* instruction, Register reg)
 | 
			
		||||
@@ -30,4 +31,9 @@ void TBAA::TagRegister(Instruction* instruction, Register reg)
 | 
			
		||||
void TBAA::TagConst(Instruction* instruction)
 | 
			
		||||
{
 | 
			
		||||
    instruction->setMetadata(LLVMContext::MD_tbaa, const_node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TBAA::TagInstructionCount(llvm::Instruction* instruction)
 | 
			
		||||
{
 | 
			
		||||
    instruction->setMetadata(LLVMContext::MD_tbaa, instruction_count_node);
 | 
			
		||||
}
 | 
			
		||||
@@ -21,9 +21,11 @@ public:
 | 
			
		||||
 | 
			
		||||
    void TagRegister(llvm::Instruction *instruction, Register reg);
 | 
			
		||||
    void TagConst(llvm::Instruction *instruction);
 | 
			
		||||
    void TagInstructionCount(llvm::Instruction *instruction);
 | 
			
		||||
private:
 | 
			
		||||
    llvm::MDNode *register_nodes[RegisterCount];
 | 
			
		||||
    // Tag for everything that is never written.
 | 
			
		||||
    // Since it is never written, one tag works
 | 
			
		||||
    llvm::MDNode *const_node;
 | 
			
		||||
    llvm::MDNode *instruction_count_node;
 | 
			
		||||
};
 | 
			
		||||
@@ -3985,7 +3985,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if ENABLE_BINARY_TRANSLATION
 | 
			
		||||
        BinaryTranslationLoader::Run();
 | 
			
		||||
        num_instrs = BinaryTranslationLoader::Run(num_instrs);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (cpu->TFlag)
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> g_loaded_object_info;
 | 
			
		||||
 | 
			
		||||
void(*g_run_function)();
 | 
			
		||||
bool(*g_can_run_function)();
 | 
			
		||||
uint32_t *g_instruction_count;
 | 
			
		||||
 | 
			
		||||
// Used by the verifier
 | 
			
		||||
struct SavedState
 | 
			
		||||
@@ -117,7 +118,16 @@ void BinaryTranslationLoader::Load(FileUtil::IOFile& file)
 | 
			
		||||
 | 
			
		||||
    g_run_function = static_cast<decltype(g_run_function)>(g_dyld->getSymbolAddress("Run"));
 | 
			
		||||
    g_can_run_function = static_cast<decltype(g_can_run_function)>(g_dyld->getSymbolAddress("CanRun"));
 | 
			
		||||
    g_verify = *static_cast<bool*>(g_dyld->getSymbolAddress("Verify"));
 | 
			
		||||
    auto verify_ptr = static_cast<bool*>(g_dyld->getSymbolAddress("Verify"));
 | 
			
		||||
    g_instruction_count = static_cast<uint32_t *>(g_dyld->getSymbolAddress("InstructionCount"));
 | 
			
		||||
 | 
			
		||||
    if (!g_run_function || !g_can_run_function || !verify_ptr || !g_instruction_count)
 | 
			
		||||
    {
 | 
			
		||||
        LOG_WARNING(Loader, "Cannot load optimized file, missing critical function");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_verify = *verify_ptr;
 | 
			
		||||
 | 
			
		||||
    g_enabled = true;
 | 
			
		||||
}
 | 
			
		||||
@@ -145,18 +155,19 @@ bool BinaryTranslationLoader::CanRun(bool specific_address)
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BinaryTranslationLoader::Run()
 | 
			
		||||
uint32_t BinaryTranslationLoader::Run(uint32_t instruction_count)
 | 
			
		||||
{
 | 
			
		||||
    // No need to check the PC, Run does it anyway
 | 
			
		||||
    if (!CanRun(false)) return;
 | 
			
		||||
    if (!CanRun(false)) return instruction_count;
 | 
			
		||||
    // If verify is enabled, it will run opcodes
 | 
			
		||||
    if (g_verify) return;
 | 
			
		||||
    if (g_verify) return instruction_count;
 | 
			
		||||
 | 
			
		||||
    RunInternal();
 | 
			
		||||
    return RunInternal(instruction_count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BinaryTranslationLoader::RunInternal()
 | 
			
		||||
uint32_t BinaryTranslationLoader::RunInternal(uint32_t instruction_count)
 | 
			
		||||
{
 | 
			
		||||
    *g_instruction_count = instruction_count;
 | 
			
		||||
    g_run_function();
 | 
			
		||||
 | 
			
		||||
    g_state->TFlag = g_state->Reg[15] & 1;
 | 
			
		||||
@@ -164,6 +175,8 @@ void BinaryTranslationLoader::RunInternal()
 | 
			
		||||
        g_state->Reg[15] &= 0xfffffffe;
 | 
			
		||||
    else
 | 
			
		||||
        g_state->Reg[15] &= 0xfffffffc;
 | 
			
		||||
 | 
			
		||||
    return *g_instruction_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Swap(void *a, void *b, size_t size)
 | 
			
		||||
@@ -198,7 +211,7 @@ void BinaryTranslationLoader::VerifyCallback()
 | 
			
		||||
        g_state_copy.SwapWith(*g_state);
 | 
			
		||||
 | 
			
		||||
        // Run the opcode
 | 
			
		||||
        RunInternal();
 | 
			
		||||
        RunInternal(0);
 | 
			
		||||
 | 
			
		||||
        // Test
 | 
			
		||||
        auto current_as_saved_state = SavedState(*g_state);
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,9 @@ public:
 | 
			
		||||
    // If specific_address, checks the specific PC too
 | 
			
		||||
    static bool CanRun(bool specific_address);
 | 
			
		||||
    // Runs the state provided at SetCpuState.
 | 
			
		||||
    static void Run();
 | 
			
		||||
    // Returns instruction_count + number of instructions executed
 | 
			
		||||
    static uint32_t Run(uint32_t instruction_count);
 | 
			
		||||
    // Link between Run and VerifyCallback
 | 
			
		||||
    static void RunInternal();
 | 
			
		||||
    static uint32_t RunInternal(uint32_t instruction_count);
 | 
			
		||||
    static void VerifyCallback();
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user