jitopt.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,669 行 · 第 1/4 页
C
1,669 行
/* * @(#)jitopt.c 1.24 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/utils.h"#include "javavm/include/bcutils.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitutils.h"#include "javavm/include/clib.h"#if 0 /* Temporarily commented out. *//* Loop descriptors *//* Back edges go tail -> head. So pc(head) < pc(tail). */struct CVMJITLoop { CVMJITIRBlock* headBlock; CVMJITIRBlock* tailBlock; CVMJITSet loopBlocks; CVMUint32 numBlocks;};/* * Nested loops. Each CVMJITNestedLoop entry contains an array of loop * pointers, and the size of this array. */struct CVMJITNestedLoop { CVMJITLoop** loops; CVMUint32 numLoopsContained;};#ifdef CVM_DEBUG/* Forward declarations for dumpers */static voiddumpBlocks(CVMJITCompilationContext* con, CVMJITIRBlock* rootblock, CVMUint32 numBlocks);static voiddumpLoops(CVMJITCompilationContext* con);static voiddumpNestedLoops(CVMJITCompilationContext* con);#endif /* CVM_DEBUG *//* * Iterator for DFS walk computation */typedef struct DFSIter { CVMJITIRBlock** dfsWalk; CVMUint32 nextIdx; char* visited; /* Explicit stack for iterative DFS walk */ CVMJITStack stack;} DFSIter;/* * Iterative DFS walker. This one is pre-order -- we visit each node * before we visit its successors. */static voiddfsOrderDoIt(CVMJITCompilationContext* con, DFSIter* iter);static voidvisitSucc(CVMJITCompilationContext* con, CVMUint32 succ, void* data){ DFSIter* iter = (DFSIter*)data; if (!iter->visited[succ]) { CVMJITstackPush(con, (CVMJITIRBlock*)(con->idToBlock[succ]), &iter->stack); }}static voiddfsOrderDoIt(CVMJITCompilationContext* con, DFSIter* iter){ while (!CVMJITstackIsEmpty(con, &iter->stack)) { CVMJITIRBlock* block; block = (CVMJITIRBlock*)CVMJITstackPop(con, &iter->stack); /* Pre-order traversal */ iter->dfsWalk[iter->nextIdx++] = block; iter->visited[block->blockID] = CVM_TRUE; CVMJITsetIterate(con, &block->successors, visitSucc, iter); }}static CVMJITIRBlock**computeDfsWalkDoIt(CVMJITCompilationContext* con, CVMJITIRBlock* rootblock, CVMUint32 numBlocks){ DFSIter iter; iter.visited = (char*)CVMJITmemNew(con, JIT_ALLOC_OPTIMIZER, numBlocks * sizeof(char)); iter.nextIdx = 0; /* Allocate one extra place to make the list NULL-terminated */ iter.dfsWalk = (CVMJITIRBlock**) CVMJITmemNew(con, JIT_ALLOC_OPTIMIZER, (numBlocks+1) * sizeof(CVMJITIRBlock*)); CVMJITstackInit(con, &iter.stack, numBlocks); /* Start walk with root block */ CVMJITstackPush(con, (CVMJITIRBlock*)rootblock, &iter.stack); /* And do the walk */ dfsOrderDoIt(con, &iter); /* NULL-terminated */ iter.dfsWalk[numBlocks] = NULL; return iter.dfsWalk;}/* * Compute DFS walk if it has not been computed already */static voidcomputeDfsWalkIfNeeded(CVMJITCompilationContext* con, CVMJITIRBlock* rootnode, CVMUint32 numBlocks){ if (con->dfsWalk == NULL) { con->dfsWalk = computeDfsWalkDoIt(con, rootnode, numBlocks); }}/* * Finding dominators. Blocks are traversed in DFS order for faster * convergence. */static voidaddDominators(CVMJITCompilationContext* con, CVMUint32 elem, void* data){ CVMJITSet* tempSet = (CVMJITSet*)data; CVMJITIRBlock* predBlock = con->idToBlock[elem]; CVMJITsetIntersection(con, tempSet, &predBlock->dominators);}voidfindDominators(CVMJITCompilationContext* con, CVMJITIRBlock* rootblock, CVMUint32 numBlocks){ CVMJITSet temp; CVMJITIRBlock* block; CVMJITIRBlock** dfsWalk; CVMBool change;#ifdef CVM_DEBUG CVMUint32 numIter = 0;#endif CVMJITsetInit(con, &temp); /* * Initially, the dominator set for each block but the root is * all the blocks. */ for (block = rootblock->next; block != NULL; block = block->next) { CVMJITsetInit(con, &block->dominators); CVMJITsetPopulate(con, &block->dominators, numBlocks); } /* * And the root block dominates only itself */ CVMJITsetInit(con, &rootblock->dominators); CVMJITsetAdd(con, &rootblock->dominators, rootblock->blockID); /* Compute pre-order DFS traversal of the blocks */ computeDfsWalkIfNeeded(con, rootblock, numBlocks); CVMassert(*con->dfsWalk == rootblock); /* * Compute until there are no changes */ do { dfsWalk = con->dfsWalk; change = CVM_FALSE; /* The pre-increment neatly skips over the root block */ while ((block = *(++dfsWalk)) != NULL) { CVMBool equals; /* Temp has all the blocks for a start */ CVMJITsetPopulate(con, &temp, numBlocks); /* * Find the intersection of the dominators of all * predecessors of this block */ CVMJITsetIterate(con, &block->predecessors, addDominators, &temp); /* And add the current block as a dominator */ CVMJITsetAdd(con, &temp, block->blockID); /* Had we already set the dominators of this block to the accumulated value? If so, no change happened */ CVMJITsetEquals(con, &temp, &block->dominators, equals); if (!equals) { change = CVM_TRUE; CVMJITsetCopy(con, &block->dominators, &temp); } }#ifdef CVM_DEBUG numIter++;#endif } while (change); CVMtraceJITIROPT(("JO: Computed dominators in %d iterations\n", numIter));}/* * Loop finder help. */typedef struct BackEdgeIter { CVMJITGrowableArray loops; CVMUint32 tail; /* The blockID of the tail node */ /* To be used in natural loop computation */ CVMJITStack stack; CVMJITLoop* currentLoop;} BackEdgeIter;static CVMJITLoop*newLoopStruct(CVMJITCompilationContext* con, BackEdgeIter* iter){ void* elem; CVMJITgarrNewElem(con, &iter->loops, elem); return (CVMJITLoop*)elem;}/* * Visit predecessor for loop computation purposes */static voidvisitPred(CVMJITCompilationContext* con, CVMUint32 pred, void* data){ CVMBool contains; BackEdgeIter* iter = (BackEdgeIter*)data; CVMJITLoop* loop = iter->currentLoop; CVMJITSet* loopBlocks = &loop->loopBlocks; CVMJITsetContains(loopBlocks, pred, contains); if (!contains) { CVMJITsetAdd(con, loopBlocks, pred); loop->numBlocks++; CVMJITstackPush(con, (CVMJITIRBlock*)(con->idToBlock[pred]), &iter->stack); }}/* * Find natural loop of the current back edge */static voidfindNaturalLoop(CVMJITCompilationContext* con, CVMJITLoop* loop, BackEdgeIter* iter){ CVMJITIRBlock* headBlock = loop->headBlock; CVMJITIRBlock* tailBlock = loop->tailBlock; iter->currentLoop = loop; loop->numBlocks = 1; CVMJITsetAdd(con, &loop->loopBlocks, headBlock->blockID); if (headBlock != tailBlock) { CVMJITsetAdd(con, &loop->loopBlocks, tailBlock->blockID); loop->numBlocks++; CVMJITstackPush(con, (CVMJITIRBlock*)tailBlock, &iter->stack); } while (!CVMJITstackIsEmpty(con, &iter->stack)) { CVMJITIRBlock* block; block = (CVMJITIRBlock*)CVMJITstackPop(con, &iter->stack); CVMJITsetIterate(con, &block->predecessors, visitPred, iter); }}/* Back edges go tail -> head. So pc(head) < pc(tail). * During each set iteration, tail is constant, and head changes * * Add this back edge and find its natural loop */static voidhandleBackEdge(CVMJITCompilationContext* con, CVMUint32 head, void* data){ BackEdgeIter* iter = (BackEdgeIter*)data; /* * Each back edge corresponds to a loop. Allocate space. */ CVMJITLoop* loop = newLoopStruct(con, iter); CVMtraceJITIROPT(("JO: Found back edge: head=%d, tail=%d\n", head, iter->tail)); loop->tailBlock = con->idToBlock[iter->tail]; loop->headBlock = con->idToBlock[head]; CVMJITsetInit(con, &loop->loopBlocks); /* Find out which blocks are included in the natural loop for the current back edge */ findNaturalLoop(con, loop, iter); /* Make sure the stack in iter is empty after each natural loop computation */ CVMassert(iter->stack.todoIdx == 0);}/* * Given loop data, find nested loops and order them. */typedef struct NestedLoopIter { CVMJITGrowableArray nestedLoops;} NestedLoopIter;static voidfindNestedLoops(CVMJITCompilationContext* con, NestedLoopIter* iter);#ifdef CVM_DEBUGstatic voidfindLoops(CVMJITCompilationContext* con, CVMJITIRBlock* rootblock, CVMUint32 numBlocks){ CVMJITIRBlock* block; CVMJITSet temp; BackEdgeIter iterBE; NestedLoopIter iterNL; findDominators(con, rootblock, numBlocks); CVMtraceJITIROPTExec(dumpBlocks(con, rootblock, numBlocks)); /* no loops yet */ CVMJITgarrInit(con, &iterBE.loops, sizeof(CVMJITLoop)); /* This stack will be used in natural loop computation */ CVMJITstackInit(con, &iterBE.stack, numBlocks); /* We have the dominators. Now look for back edges. */ CVMJITsetInit(con, &temp); for (block = rootblock; block != NULL; block = block->next) { CVMBool isEmpty; /* The intersection of the successors and the dominators gives you the loop closing branches, otherwise known as "back edges". */ CVMJITsetClear(con, &temp); CVMJITsetCopy(con, &temp, &block->successors); CVMJITsetIntersection(con, &temp, &block->dominators); CVMJITsetIsEmpty(con, &temp, isEmpty); if (!isEmpty) { /* We found some back edges. Record each, and compute its natural loops */ iterBE.tail = block->blockID; CVMJITsetIterate(con, &temp, handleBackEdge, &iterBE); CVMtraceJITIROPT(("JO: Loop closing branches from block #%d: ", block->blockID)); CVMtraceJITIROPTExec(CVMJITsetDumpElements(con, &temp)); CVMtraceJITIROPT(("\n")); } } CVMJITsetDestroy(con, &temp); /* * We have collected the loops in iterBE.loops. Pass info to con */ con->loops = (CVMJITLoop*)CVMJITgarrGetElems(con, &iterBE.loops); con->numLoops = CVMJITgarrGetNumElems(con, &iterBE.loops); CVMtraceJITIROPTExec(dumpLoops(con)); /* * We'll now be collecting nested loops */ CVMJITgarrInit(con, &iterNL.nestedLoops, sizeof(CVMJITNestedLoop)); findNestedLoops(con, &iterNL); /* * We have collected the loops in iterNL.nestedLoops. Pass info to con */ con->nestedLoops = (CVMJITNestedLoop*) CVMJITgarrGetElems(con, &iterNL.nestedLoops); con->numNestedLoops = CVMJITgarrGetNumElems(con, &iterNL.nestedLoops); CVMtraceJITIROPTExec(dumpNestedLoops(con));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?