From 8e1dfef14c2eb972fc322f74b15c789848c44b3f Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 30 Apr 2014 08:20:00 -0500 Subject: [PATCH] Remove the old PPAnalyst::Flatten function that is no longer in use. --- Source/Core/Core/PowerPC/PPCAnalyst.cpp | 296 ------------------------ Source/Core/Core/PowerPC/PPCAnalyst.h | 4 - 2 files changed, 300 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index e762221886..edf1425299 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -269,302 +269,6 @@ bool CanSwapAdjacentOps(const CodeOp &a, const CodeOp &b) return true; } -// Does not yet perform inlining - although there are plans for that. -// Returns the exit address of the next PC -u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, - BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, - int blockSize, u32* merged_addresses, - int capacity_of_merged_addresses, int& size_of_merged_addresses) -{ - if (capacity_of_merged_addresses < FUNCTION_FOLLOWING_THRESHOLD) { - PanicAlert("Capacity of merged_addresses is too small!"); - } - std::fill_n(merged_addresses, capacity_of_merged_addresses, 0); - merged_addresses[0] = address; - size_of_merged_addresses = 1; - - memset(st, 0, sizeof(*st)); - - // Disabled the following optimization in preference of FAST_ICACHE - //UGeckoInstruction previnst = Memory::Read_Opcode_JIT_LC(address - 4); - //if (previnst.hex == 0x4e800020) - // st->isFirstBlockOfFunction = true; - - gpa->any = true; - fpa->any = false; - - for (int i = 0; i < 32; i++) - { - gpa->firstRead[i] = -1; - gpa->firstWrite[i] = -1; - gpa->numReads[i] = 0; - gpa->numWrites[i] = 0; - } - - u32 blockstart = address; - int maxsize = blockSize; - - int num_inst = 0; - int numFollows = 0; - int numCycles = 0; - - CodeOp *code = buffer->codebuffer; - bool foundExit = false; - - u32 return_address = 0; - - // Do analysis of the code, look for dependencies etc - int numSystemInstructions = 0; - for (int i = 0; i < maxsize; i++) - { - UGeckoInstruction inst = JitInterface::Read_Opcode_JIT(address); - - if (inst.hex != 0) - { - num_inst++; - memset(&code[i], 0, sizeof(CodeOp)); - GekkoOPInfo *opinfo = GetOpInfo(inst); - code[i].opinfo = opinfo; - // FIXME: code[i].address may not be correct due to CST1 code. - code[i].address = address; - code[i].inst = inst; - code[i].branchTo = -1; - code[i].branchToIndex = -1; - code[i].skip = false; - numCycles += opinfo->numCycles; - - code[i].wantsCR0 = false; - code[i].wantsCR1 = false; - code[i].wantsPS1 = false; - - int flags = opinfo->flags; - - if (flags & FL_USE_FPU) - fpa->any = true; - - if (flags & FL_TIMER) - gpa->anyTimer = true; - - // Does the instruction output CR0? - if (flags & FL_RC_BIT) - code[i].outputCR0 = inst.hex & 1; //todo fix - else if ((flags & FL_SET_CRn) && inst.CRFD == 0) - code[i].outputCR0 = true; - else - code[i].outputCR0 = (flags & FL_SET_CR0) ? true : false; - - // Does the instruction output CR1? - if (flags & FL_RC_BIT_F) - code[i].outputCR1 = inst.hex & 1; //todo fix - else if ((flags & FL_SET_CRn) && inst.CRFD == 1) - code[i].outputCR1 = true; - else - code[i].outputCR1 = (flags & FL_SET_CR1) ? true : false; - - int numOut = 0; - int numIn = 0; - if (flags & FL_OUT_A) - { - code[i].regsOut[numOut++] = inst.RA; - gpa->SetOutputRegister(inst.RA, i); - } - if (flags & FL_OUT_D) - { - code[i].regsOut[numOut++] = inst.RD; - gpa->SetOutputRegister(inst.RD, i); - } - if (flags & FL_OUT_S) - { - code[i].regsOut[numOut++] = inst.RS; - gpa->SetOutputRegister(inst.RS, i); - } - if ((flags & FL_IN_A) || ((flags & FL_IN_A0) && inst.RA != 0)) - { - code[i].regsIn[numIn++] = inst.RA; - gpa->SetInputRegister(inst.RA, i); - } - if (flags & FL_IN_B) - { - code[i].regsIn[numIn++] = inst.RB; - gpa->SetInputRegister(inst.RB, i); - } - if (flags & FL_IN_C) - { - code[i].regsIn[numIn++] = inst.RC; - gpa->SetInputRegister(inst.RC, i); - } - if (flags & FL_IN_S) - { - code[i].regsIn[numIn++] = inst.RS; - gpa->SetInputRegister(inst.RS, i); - } - - // Set remaining register slots as unused (-1) - for (int j = numIn; j < 3; j++) - code[i].regsIn[j] = -1; - for (int j = numOut; j < 2; j++) - code[i].regsOut[j] = -1; - for (int j = 0; j < 3; j++) - code[i].fregsIn[j] = -1; - code[i].fregOut = -1; - - switch (opinfo->type) - { - case OPTYPE_INTEGER: - case OPTYPE_LOAD: - case OPTYPE_STORE: - case OPTYPE_LOADFP: - case OPTYPE_STOREFP: - break; - case OPTYPE_FPU: - break; - case OPTYPE_BRANCH: - if (code[i].inst.hex == 0x4e800020) - { - // For analysis purposes, we can assume that blr eats flags. - code[i].outputCR0 = true; - code[i].outputCR1 = true; - } - break; - case OPTYPE_SYSTEM: - case OPTYPE_SYSTEMFP: - numSystemInstructions++; - break; - } - - bool follow = false; - u32 destination = 0; - if (inst.OPCD == 18 && blockSize > 1) - { - //Is bx - should we inline? yes! - if (inst.AA) - destination = SignExt26(inst.LI << 2); - else - destination = address + SignExt26(inst.LI << 2); - if (destination != blockstart) - follow = true; - } - else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && - (inst.BO & (1 << 4)) && (inst.BO & (1 << 2)) && - return_address != 0) - { - // bclrx with unconditional branch = return - follow = true; - destination = return_address; - return_address = 0; - - if (inst.LK) - return_address = address + 4; - } - else if (inst.OPCD == 31 && inst.SUBOP10 == 467) - { - // mtspr - const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); - if (index == SPR_LR) { - // We give up to follow the return address - // because we have to check the register usage. - return_address = 0; - } - } - - if (follow) - numFollows++; - // TODO: Find the optimal value for FUNCTION_FOLLOWING_THRESHOLD. - // If it is small, the performance will be down. - // If it is big, the size of generated code will be big and - // cache clearning will happen many times. - // TODO: Investivate the reason why - // "0" is fastest in some games, MP2 for example. - if (numFollows > FUNCTION_FOLLOWING_THRESHOLD) - follow = false; - - if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMergeBlocks) { - follow = false; - } - - if (!follow) - { - if (opinfo->flags & FL_ENDBLOCK) //right now we stop early - { - foundExit = true; - break; - } - address += 4; - } - else - { - // We don't "code[i].skip = true" here - // because bx may store a certain value to the link register. - // Instead, we skip a part of bx in Jit**::bx(). - address = destination; - merged_addresses[size_of_merged_addresses++] = address; - } - } - else - { - // ISI exception or other critical memory exception occurred (game over) - break; - } - } - st->numCycles = numCycles; - - // Instruction Reordering Pass - if (num_inst > 1) - { - // Bubble down compares towards branches, so that they can be merged. - // -2: -1 for the pair, -1 for not swapping with the final instruction which is probably the branch. - for (int i = 0; i < num_inst - 2; i++) - { - CodeOp &a = code[i]; - CodeOp &b = code[i + 1]; - // All integer compares can be reordered. - if ((a.inst.OPCD == 10 || a.inst.OPCD == 11) || - (a.inst.OPCD == 31 && (a.inst.SUBOP10 == 0 || a.inst.SUBOP10 == 32))) - { - // Got a compare instruction. - if (CanSwapAdjacentOps(a, b)) { - // Alright, let's bubble it down! - CodeOp c = a; - a = b; - b = c; - } - } - } - } - - if (!foundExit && num_inst > 0) - { - // A broken block is a block that does not end in a branch - broken_block = true; - } - - // Scan for CR0 dependency - // assume next block wants CR0 to be safe - bool wantsCR0 = true; - bool wantsCR1 = true; - bool wantsPS1 = true; - for (int i = num_inst - 1; i >= 0; i--) - { - if (code[i].outputCR0) - wantsCR0 = false; - if (code[i].outputCR1) - wantsCR1 = false; - if (code[i].outputPS1) - wantsPS1 = false; - wantsCR0 |= code[i].wantsCR0; - wantsCR1 |= code[i].wantsCR1; - wantsPS1 |= code[i].wantsPS1; - code[i].wantsCR0 = wantsCR0; - code[i].wantsCR1 = wantsCR1; - code[i].wantsPS1 = wantsPS1; - } - - *realsize = num_inst; - // ... - return address; -} - - // Most functions that are relevant to analyze should be // called by another function. Therefore, let's scan the // entire space for bl operations and find what functions diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.h b/Source/Core/Core/PowerPC/PPCAnalyst.h index e9242eccfe..16c4f2cd14 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/PowerPC/PPCAnalyst.h @@ -175,10 +175,6 @@ public: u32 Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 blockSize); }; -u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, - BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, - int blockSize, u32* merged_addresses, - int capacity_of_merged_addresses, int& size_of_merged_addresses); void LogFunctionCall(u32 addr); void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB *func_db); bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size = 0);