1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Dalvik.h" 18 #include "Dataflow.h" 19 #include "Loop.h" 20 #include "libdex/DexOpcodes.h" 21 22 /* Enter the node to the dfsOrder list then visit its successors */ 23 static void recordDFSPreOrder(CompilationUnit *cUnit, BasicBlock *block) 24 { 25 26 if (block->visited || block->hidden) return; 27 block->visited = true; 28 29 /* Enqueue the block id */ 30 dvmInsertGrowableList(&cUnit->dfsOrder, block->id); 31 32 if (block->fallThrough) recordDFSPreOrder(cUnit, block->fallThrough); 33 if (block->taken) recordDFSPreOrder(cUnit, block->taken); 34 if (block->successorBlockList.blockListType != kNotUsed) { 35 GrowableListIterator iterator; 36 dvmGrowableListIteratorInit(&block->successorBlockList.blocks, 37 &iterator); 38 while (true) { 39 SuccessorBlockInfo *successorBlockInfo = 40 (SuccessorBlockInfo *) dvmGrowableListIteratorNext(&iterator); 41 if (successorBlockInfo == NULL) break; 42 BasicBlock *succBB = successorBlockInfo->block; 43 recordDFSPreOrder(cUnit, succBB); 44 } 45 } 46 return; 47 } 48 49 /* Sort the blocks by the Depth-First-Search pre-order */ 50 static void computeDFSOrder(CompilationUnit *cUnit) 51 { 52 /* Initialize or reset the DFS order list */ 53 if (cUnit->dfsOrder.elemList == NULL) { 54 dvmInitGrowableList(&cUnit->dfsOrder, cUnit->numBlocks); 55 } else { 56 /* Just reset the used length on the counter */ 57 cUnit->dfsOrder.numUsed = 0; 58 } 59 60 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerClearVisitedFlag, 61 kAllNodes, 62 false /* isIterative */); 63 64 recordDFSPreOrder(cUnit, cUnit->entryBlock); 65 cUnit->numReachableBlocks = cUnit->dfsOrder.numUsed; 66 } 67 68 /* 69 * Mark block bit on the per-Dalvik register vector to denote that Dalvik 70 * register idx is defined in BasicBlock bb. 71 */ 72 static bool fillDefBlockMatrix(CompilationUnit *cUnit, BasicBlock *bb) 73 { 74 if (bb->dataFlowInfo == NULL) return false; 75 76 BitVectorIterator iterator; 77 78 dvmBitVectorIteratorInit(bb->dataFlowInfo->defV, &iterator); 79 while (true) { 80 int idx = dvmBitVectorIteratorNext(&iterator); 81 if (idx == -1) break; 82 /* Block bb defines register idx */ 83 dvmCompilerSetBit(cUnit->defBlockMatrix[idx], bb->id); 84 } 85 return true; 86 } 87 88 static void computeDefBlockMatrix(CompilationUnit *cUnit) 89 { 90 int numRegisters = cUnit->numDalvikRegisters; 91 /* Allocate numDalvikRegisters bit vector pointers */ 92 cUnit->defBlockMatrix = (BitVector **) 93 dvmCompilerNew(sizeof(BitVector *) * numRegisters, true); 94 int i; 95 96 /* Initialize numRegister vectors with numBlocks bits each */ 97 for (i = 0; i < numRegisters; i++) { 98 cUnit->defBlockMatrix[i] = dvmCompilerAllocBitVector(cUnit->numBlocks, 99 false); 100 } 101 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerFindLocalLiveIn, 102 kAllNodes, 103 false /* isIterative */); 104 dvmCompilerDataFlowAnalysisDispatcher(cUnit, fillDefBlockMatrix, 105 kAllNodes, 106 false /* isIterative */); 107 108 if (cUnit->jitMode == kJitMethod) { 109 /* 110 * Also set the incoming parameters as defs in the entry block. 111 * Only need to handle the parameters for the outer method. 112 */ 113 int inReg = cUnit->method->registersSize - cUnit->method->insSize; 114 for (; inReg < cUnit->method->registersSize; inReg++) { 115 dvmCompilerSetBit(cUnit->defBlockMatrix[inReg], 116 cUnit->entryBlock->id); 117 } 118 } 119 } 120 121 /* Compute the post-order traversal of the CFG */ 122 static void computeDomPostOrderTraversal(CompilationUnit *cUnit, BasicBlock *bb) 123 { 124 BitVectorIterator bvIterator; 125 dvmBitVectorIteratorInit(bb->iDominated, &bvIterator); 126 GrowableList *blockList = &cUnit->blockList; 127 128 /* Iterate through the dominated blocks first */ 129 while (true) { 130 int bbIdx = dvmBitVectorIteratorNext(&bvIterator); 131 if (bbIdx == -1) break; 132 BasicBlock *dominatedBB = 133 (BasicBlock *) dvmGrowableListGetElement(blockList, bbIdx); 134 computeDomPostOrderTraversal(cUnit, dominatedBB); 135 } 136 137 /* Enter the current block id */ 138 dvmInsertGrowableList(&cUnit->domPostOrderTraversal, bb->id); 139 140 /* hacky loop detection */ 141 if (bb->taken && dvmIsBitSet(bb->dominators, bb->taken->id)) { 142 cUnit->hasLoop = true; 143 } 144 } 145 146 static void checkForDominanceFrontier(BasicBlock *domBB, 147 const BasicBlock *succBB) 148 { 149 /* 150 * TODO - evaluate whether phi will ever need to be inserted into exit 151 * blocks. 152 */ 153 if (succBB->iDom != domBB && 154 succBB->blockType == kDalvikByteCode && 155 succBB->hidden == false) { 156 dvmSetBit(domBB->domFrontier, succBB->id); 157 } 158 } 159 160 /* Worker function to compute the dominance frontier */ 161 static bool computeDominanceFrontier(CompilationUnit *cUnit, BasicBlock *bb) 162 { 163 GrowableList *blockList = &cUnit->blockList; 164 165 /* Calculate DF_local */ 166 if (bb->taken) { 167 checkForDominanceFrontier(bb, bb->taken); 168 } 169 if (bb->fallThrough) { 170 checkForDominanceFrontier(bb, bb->fallThrough); 171 } 172 if (bb->successorBlockList.blockListType != kNotUsed) { 173 GrowableListIterator iterator; 174 dvmGrowableListIteratorInit(&bb->successorBlockList.blocks, 175 &iterator); 176 while (true) { 177 SuccessorBlockInfo *successorBlockInfo = 178 (SuccessorBlockInfo *) dvmGrowableListIteratorNext(&iterator); 179 if (successorBlockInfo == NULL) break; 180 BasicBlock *succBB = successorBlockInfo->block; 181 checkForDominanceFrontier(bb, succBB); 182 } 183 } 184 185 /* Calculate DF_up */ 186 BitVectorIterator bvIterator; 187 dvmBitVectorIteratorInit(bb->iDominated, &bvIterator); 188 while (true) { 189 int dominatedIdx = dvmBitVectorIteratorNext(&bvIterator); 190 if (dominatedIdx == -1) break; 191 BasicBlock *dominatedBB = (BasicBlock *) 192 dvmGrowableListGetElement(blockList, dominatedIdx); 193 BitVectorIterator dfIterator; 194 dvmBitVectorIteratorInit(dominatedBB->domFrontier, &dfIterator); 195 while (true) { 196 int dfUpIdx = dvmBitVectorIteratorNext(&dfIterator); 197 if (dfUpIdx == -1) break; 198 BasicBlock *dfUpBlock = (BasicBlock *) 199 dvmGrowableListGetElement(blockList, dfUpIdx); 200 checkForDominanceFrontier(bb, dfUpBlock); 201 } 202 } 203 204 return true; 205 } 206 207 /* Worker function for initializing domination-related data structures */ 208 static bool initializeDominationInfo(CompilationUnit *cUnit, BasicBlock *bb) 209 { 210 int numTotalBlocks = cUnit->blockList.numUsed; 211 212 if (bb->dominators == NULL ) { 213 bb->dominators = dvmCompilerAllocBitVector(numTotalBlocks, 214 false /* expandable */); 215 bb->iDominated = dvmCompilerAllocBitVector(numTotalBlocks, 216 false /* expandable */); 217 bb->domFrontier = dvmCompilerAllocBitVector(numTotalBlocks, 218 false /* expandable */); 219 } else { 220 dvmClearAllBits(bb->dominators); 221 dvmClearAllBits(bb->iDominated); 222 dvmClearAllBits(bb->domFrontier); 223 } 224 /* Set all bits in the dominator vector */ 225 dvmSetInitialBits(bb->dominators, numTotalBlocks); 226 227 return true; 228 } 229 230 /* Worker function to compute each block's dominators */ 231 static bool computeBlockDominators(CompilationUnit *cUnit, BasicBlock *bb) 232 { 233 GrowableList *blockList = &cUnit->blockList; 234 int numTotalBlocks = blockList->numUsed; 235 BitVector *tempBlockV = cUnit->tempBlockV; 236 BitVectorIterator bvIterator; 237 238 /* 239 * The dominator of the entry block has been preset to itself and we need 240 * to skip the calculation here. 241 */ 242 if (bb == cUnit->entryBlock) return false; 243 244 dvmSetInitialBits(tempBlockV, numTotalBlocks); 245 246 /* Iterate through the predecessors */ 247 dvmBitVectorIteratorInit(bb->predecessors, &bvIterator); 248 while (true) { 249 int predIdx = dvmBitVectorIteratorNext(&bvIterator); 250 if (predIdx == -1) break; 251 BasicBlock *predBB = (BasicBlock *) dvmGrowableListGetElement( 252 blockList, predIdx); 253 /* tempBlockV = tempBlockV ^ dominators */ 254 dvmIntersectBitVectors(tempBlockV, tempBlockV, predBB->dominators); 255 } 256 dvmSetBit(tempBlockV, bb->id); 257 if (dvmCompareBitVectors(tempBlockV, bb->dominators)) { 258 dvmCopyBitVector(bb->dominators, tempBlockV); 259 return true; 260 } 261 return false; 262 } 263 264 /* Worker function to compute the idom */ 265 static bool computeImmediateDominator(CompilationUnit *cUnit, BasicBlock *bb) 266 { 267 GrowableList *blockList = &cUnit->blockList; 268 BitVector *tempBlockV = cUnit->tempBlockV; 269 BitVectorIterator bvIterator; 270 BasicBlock *iDom; 271 272 if (bb == cUnit->entryBlock) return false; 273 274 dvmCopyBitVector(tempBlockV, bb->dominators); 275 dvmClearBit(tempBlockV, bb->id); 276 dvmBitVectorIteratorInit(tempBlockV, &bvIterator); 277 278 /* Should not see any dead block */ 279 assert(dvmCountSetBits(tempBlockV) != 0); 280 if (dvmCountSetBits(tempBlockV) == 1) { 281 iDom = (BasicBlock *) dvmGrowableListGetElement( 282 blockList, dvmBitVectorIteratorNext(&bvIterator)); 283 bb->iDom = iDom; 284 } else { 285 int iDomIdx = dvmBitVectorIteratorNext(&bvIterator); 286 assert(iDomIdx != -1); 287 while (true) { 288 int nextDom = dvmBitVectorIteratorNext(&bvIterator); 289 if (nextDom == -1) break; 290 BasicBlock *nextDomBB = (BasicBlock *) 291 dvmGrowableListGetElement(blockList, nextDom); 292 /* iDom dominates nextDom - set new iDom */ 293 if (dvmIsBitSet(nextDomBB->dominators, iDomIdx)) { 294 iDomIdx = nextDom; 295 } 296 297 } 298 iDom = (BasicBlock *) dvmGrowableListGetElement(blockList, iDomIdx); 299 /* Set the immediate dominator block for bb */ 300 bb->iDom = iDom; 301 } 302 /* Add bb to the iDominated set of the immediate dominator block */ 303 dvmCompilerSetBit(iDom->iDominated, bb->id); 304 return true; 305 } 306 307 /* Compute dominators, immediate dominator, and dominance fronter */ 308 static void computeDominators(CompilationUnit *cUnit) 309 { 310 int numReachableBlocks = cUnit->numReachableBlocks; 311 int numTotalBlocks = cUnit->blockList.numUsed; 312 313 /* Initialize domination-related data structures */ 314 dvmCompilerDataFlowAnalysisDispatcher(cUnit, initializeDominationInfo, 315 kReachableNodes, 316 false /* isIterative */); 317 318 /* Set the dominator for the root node */ 319 dvmClearAllBits(cUnit->entryBlock->dominators); 320 dvmSetBit(cUnit->entryBlock->dominators, cUnit->entryBlock->id); 321 322 if (cUnit->tempBlockV == NULL) { 323 cUnit->tempBlockV = dvmCompilerAllocBitVector(numTotalBlocks, 324 false /* expandable */); 325 } else { 326 dvmClearAllBits(cUnit->tempBlockV); 327 } 328 dvmCompilerDataFlowAnalysisDispatcher(cUnit, computeBlockDominators, 329 kPreOrderDFSTraversal, 330 true /* isIterative */); 331 332 cUnit->entryBlock->iDom = NULL; 333 dvmCompilerDataFlowAnalysisDispatcher(cUnit, computeImmediateDominator, 334 kReachableNodes, 335 false /* isIterative */); 336 337 /* 338 * Now go ahead and compute the post order traversal based on the 339 * iDominated sets. 340 */ 341 if (cUnit->domPostOrderTraversal.elemList == NULL) { 342 dvmInitGrowableList(&cUnit->domPostOrderTraversal, numReachableBlocks); 343 } else { 344 cUnit->domPostOrderTraversal.numUsed = 0; 345 } 346 347 computeDomPostOrderTraversal(cUnit, cUnit->entryBlock); 348 assert(cUnit->domPostOrderTraversal.numUsed == 349 (unsigned) cUnit->numReachableBlocks); 350 351 /* Now compute the dominance frontier for each block */ 352 dvmCompilerDataFlowAnalysisDispatcher(cUnit, computeDominanceFrontier, 353 kPostOrderDOMTraversal, 354 false /* isIterative */); 355 } 356 357 /* 358 * Perform dest U= src1 ^ ~src2 359 * This is probably not general enough to be placed in BitVector.[ch]. 360 */ 361 static void computeSuccLiveIn(BitVector *dest, 362 const BitVector *src1, 363 const BitVector *src2) 364 { 365 if (dest->storageSize != src1->storageSize || 366 dest->storageSize != src2->storageSize || 367 dest->expandable != src1->expandable || 368 dest->expandable != src2->expandable) { 369 ALOGE("Incompatible set properties"); 370 dvmAbort(); 371 } 372 373 unsigned int idx; 374 for (idx = 0; idx < dest->storageSize; idx++) { 375 dest->storage[idx] |= src1->storage[idx] & ~src2->storage[idx]; 376 } 377 } 378 379 /* 380 * Iterate through all successor blocks and propagate up the live-in sets. 381 * The calculated result is used for phi-node pruning - where we only need to 382 * insert a phi node if the variable is live-in to the block. 383 */ 384 static bool computeBlockLiveIns(CompilationUnit *cUnit, BasicBlock *bb) 385 { 386 BitVector *tempDalvikRegisterV = cUnit->tempDalvikRegisterV; 387 388 if (bb->dataFlowInfo == NULL) return false; 389 dvmCopyBitVector(tempDalvikRegisterV, bb->dataFlowInfo->liveInV); 390 if (bb->taken && bb->taken->dataFlowInfo) 391 computeSuccLiveIn(tempDalvikRegisterV, bb->taken->dataFlowInfo->liveInV, 392 bb->dataFlowInfo->defV); 393 if (bb->fallThrough && bb->fallThrough->dataFlowInfo) 394 computeSuccLiveIn(tempDalvikRegisterV, 395 bb->fallThrough->dataFlowInfo->liveInV, 396 bb->dataFlowInfo->defV); 397 if (bb->successorBlockList.blockListType != kNotUsed) { 398 GrowableListIterator iterator; 399 dvmGrowableListIteratorInit(&bb->successorBlockList.blocks, 400 &iterator); 401 while (true) { 402 SuccessorBlockInfo *successorBlockInfo = 403 (SuccessorBlockInfo *) dvmGrowableListIteratorNext(&iterator); 404 if (successorBlockInfo == NULL) break; 405 BasicBlock *succBB = successorBlockInfo->block; 406 if (succBB->dataFlowInfo) { 407 computeSuccLiveIn(tempDalvikRegisterV, 408 succBB->dataFlowInfo->liveInV, 409 bb->dataFlowInfo->defV); 410 } 411 } 412 } 413 if (dvmCompareBitVectors(tempDalvikRegisterV, bb->dataFlowInfo->liveInV)) { 414 dvmCopyBitVector(bb->dataFlowInfo->liveInV, tempDalvikRegisterV); 415 return true; 416 } 417 return false; 418 } 419 420 /* Insert phi nodes to for each variable to the dominance frontiers */ 421 static void insertPhiNodes(CompilationUnit *cUnit) 422 { 423 int dalvikReg; 424 const GrowableList *blockList = &cUnit->blockList; 425 BitVector *phiBlocks = 426 dvmCompilerAllocBitVector(cUnit->numBlocks, false); 427 BitVector *tmpBlocks = 428 dvmCompilerAllocBitVector(cUnit->numBlocks, false); 429 BitVector *inputBlocks = 430 dvmCompilerAllocBitVector(cUnit->numBlocks, false); 431 432 cUnit->tempDalvikRegisterV = 433 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false); 434 435 dvmCompilerDataFlowAnalysisDispatcher(cUnit, computeBlockLiveIns, 436 kPostOrderDFSTraversal, 437 true /* isIterative */); 438 439 /* Iterate through each Dalvik register */ 440 for (dalvikReg = 0; dalvikReg < cUnit->numDalvikRegisters; dalvikReg++) { 441 bool change; 442 BitVectorIterator iterator; 443 444 dvmCopyBitVector(inputBlocks, cUnit->defBlockMatrix[dalvikReg]); 445 dvmClearAllBits(phiBlocks); 446 447 /* Calculate the phi blocks for each Dalvik register */ 448 do { 449 change = false; 450 dvmClearAllBits(tmpBlocks); 451 dvmBitVectorIteratorInit(inputBlocks, &iterator); 452 453 while (true) { 454 int idx = dvmBitVectorIteratorNext(&iterator); 455 if (idx == -1) break; 456 BasicBlock *defBB = 457 (BasicBlock *) dvmGrowableListGetElement(blockList, idx); 458 459 /* Merge the dominance frontier to tmpBlocks */ 460 dvmUnifyBitVectors(tmpBlocks, tmpBlocks, defBB->domFrontier); 461 } 462 if (dvmCompareBitVectors(phiBlocks, tmpBlocks)) { 463 change = true; 464 dvmCopyBitVector(phiBlocks, tmpBlocks); 465 466 /* 467 * Iterate through the original blocks plus the new ones in 468 * the dominance frontier. 469 */ 470 dvmCopyBitVector(inputBlocks, phiBlocks); 471 dvmUnifyBitVectors(inputBlocks, inputBlocks, 472 cUnit->defBlockMatrix[dalvikReg]); 473 } 474 } while (change); 475 476 /* 477 * Insert a phi node for dalvikReg in the phiBlocks if the Dalvik 478 * register is in the live-in set. 479 */ 480 dvmBitVectorIteratorInit(phiBlocks, &iterator); 481 while (true) { 482 int idx = dvmBitVectorIteratorNext(&iterator); 483 if (idx == -1) break; 484 BasicBlock *phiBB = 485 (BasicBlock *) dvmGrowableListGetElement(blockList, idx); 486 /* Variable will be clobbered before being used - no need for phi */ 487 if (!dvmIsBitSet(phiBB->dataFlowInfo->liveInV, dalvikReg)) continue; 488 MIR *phi = (MIR *) dvmCompilerNew(sizeof(MIR), true); 489 phi->dalvikInsn.opcode = (Opcode)kMirOpPhi; 490 phi->dalvikInsn.vA = dalvikReg; 491 phi->offset = phiBB->startOffset; 492 dvmCompilerPrependMIR(phiBB, phi); 493 } 494 } 495 } 496 497 /* 498 * Worker function to insert phi-operands with latest SSA names from 499 * predecessor blocks 500 */ 501 static bool insertPhiNodeOperands(CompilationUnit *cUnit, BasicBlock *bb) 502 { 503 BitVector *ssaRegV = cUnit->tempSSARegisterV; 504 BitVectorIterator bvIterator; 505 GrowableList *blockList = &cUnit->blockList; 506 MIR *mir; 507 508 /* Phi nodes are at the beginning of each block */ 509 for (mir = bb->firstMIRInsn; mir; mir = mir->next) { 510 if (mir->dalvikInsn.opcode != (Opcode)kMirOpPhi) 511 return true; 512 int ssaReg = mir->ssaRep->defs[0]; 513 int encodedDalvikValue = 514 (int) dvmGrowableListGetElement(cUnit->ssaToDalvikMap, ssaReg); 515 int dalvikReg = DECODE_REG(encodedDalvikValue); 516 517 dvmClearAllBits(ssaRegV); 518 519 /* Iterate through the predecessors */ 520 dvmBitVectorIteratorInit(bb->predecessors, &bvIterator); 521 while (true) { 522 int predIdx = dvmBitVectorIteratorNext(&bvIterator); 523 if (predIdx == -1) break; 524 BasicBlock *predBB = (BasicBlock *) dvmGrowableListGetElement( 525 blockList, predIdx); 526 int encodedSSAValue = 527 predBB->dataFlowInfo->dalvikToSSAMap[dalvikReg]; 528 int ssaReg = DECODE_REG(encodedSSAValue); 529 dvmSetBit(ssaRegV, ssaReg); 530 } 531 532 /* Count the number of SSA registers for a Dalvik register */ 533 int numUses = dvmCountSetBits(ssaRegV); 534 mir->ssaRep->numUses = numUses; 535 mir->ssaRep->uses = 536 (int *) dvmCompilerNew(sizeof(int) * numUses, false); 537 mir->ssaRep->fpUse = 538 (bool *) dvmCompilerNew(sizeof(bool) * numUses, true); 539 540 BitVectorIterator phiIterator; 541 542 dvmBitVectorIteratorInit(ssaRegV, &phiIterator); 543 int *usePtr = mir->ssaRep->uses; 544 545 /* Set the uses array for the phi node */ 546 while (true) { 547 int ssaRegIdx = dvmBitVectorIteratorNext(&phiIterator); 548 if (ssaRegIdx == -1) break; 549 *usePtr++ = ssaRegIdx; 550 } 551 } 552 553 return true; 554 } 555 556 /* Perform SSA transformation for the whole method */ 557 void dvmCompilerMethodSSATransformation(CompilationUnit *cUnit) 558 { 559 /* Compute the DFS order */ 560 computeDFSOrder(cUnit); 561 562 /* Compute the dominator info */ 563 computeDominators(cUnit); 564 565 /* Allocate data structures in preparation for SSA conversion */ 566 dvmInitializeSSAConversion(cUnit); 567 568 /* Find out the "Dalvik reg def x block" relation */ 569 computeDefBlockMatrix(cUnit); 570 571 /* Insert phi nodes to dominance frontiers for all variables */ 572 insertPhiNodes(cUnit); 573 574 /* Rename register names by local defs and phi nodes */ 575 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion, 576 kPreOrderDFSTraversal, 577 false /* isIterative */); 578 579 /* 580 * Shared temp bit vector used by each block to count the number of defs 581 * from all the predecessor blocks. 582 */ 583 cUnit->tempSSARegisterV = dvmCompilerAllocBitVector(cUnit->numSSARegs, 584 false); 585 586 /* Insert phi-operands with latest SSA names from predecessor blocks */ 587 dvmCompilerDataFlowAnalysisDispatcher(cUnit, insertPhiNodeOperands, 588 kReachableNodes, 589 false /* isIterative */); 590 } 591 592 /* Build a loop. Return true if a loop structure is successfully identified. */ 593 bool dvmCompilerBuildLoop(CompilationUnit *cUnit) 594 { 595 /* Compute the DFS order */ 596 computeDFSOrder(cUnit); 597 598 /* Compute the dominator info */ 599 computeDominators(cUnit); 600 601 /* Loop structure not recognized/supported - return false */ 602 if (dvmCompilerFilterLoopBlocks(cUnit) == false) 603 return false; 604 605 /* Re-compute the DFS order just for the loop */ 606 computeDFSOrder(cUnit); 607 608 /* Re-compute the dominator info just for the loop */ 609 computeDominators(cUnit); 610 611 /* Allocate data structures in preparation for SSA conversion */ 612 dvmInitializeSSAConversion(cUnit); 613 614 /* Find out the "Dalvik reg def x block" relation */ 615 computeDefBlockMatrix(cUnit); 616 617 /* Insert phi nodes to dominance frontiers for all variables */ 618 insertPhiNodes(cUnit); 619 620 /* Rename register names by local defs and phi nodes */ 621 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion, 622 kPreOrderDFSTraversal, 623 false /* isIterative */); 624 625 /* 626 * Shared temp bit vector used by each block to count the number of defs 627 * from all the predecessor blocks. 628 */ 629 cUnit->tempSSARegisterV = dvmCompilerAllocBitVector(cUnit->numSSARegs, 630 false); 631 632 /* Insert phi-operands with latest SSA names from predecessor blocks */ 633 dvmCompilerDataFlowAnalysisDispatcher(cUnit, insertPhiNodeOperands, 634 kReachableNodes, 635 false /* isIterative */); 636 637 if (gDvmJit.receivedSIGUSR2 || gDvmJit.printMe) { 638 dvmDumpCFG(cUnit, "/sdcard/cfg/"); 639 } 640 641 return true; 642 } 643