Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java @ 2773:27512ea6bbcb
exception dispatch simplification:
* BlockMap creates exception dispatch blocks (so they're iterated in the right order)
* GraphBuilder uses exception dispatch blocks, simplified handleException, removed updateDispatchChain
* simplified mergeOrClone
* removed successor & predecessor methods from BlockBegin
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Tue, 24 May 2011 12:07:17 +0200 |
parents | 49a8790b85a2 |
children | 706047ee5f2e |
comparison
equal
deleted
inserted
replaced
2772:3e3338a1abb9 | 2773:27512ea6bbcb |
---|---|
120 public boolean isLoopHeader; | 120 public boolean isLoopHeader; |
121 public int blockID; | 121 public int blockID; |
122 | 122 |
123 public Instruction firstInstruction; | 123 public Instruction firstInstruction; |
124 | 124 |
125 private Block[] successors; | 125 final HashSet<Block> successors = new HashSet<Block>(); |
126 private boolean visited; | 126 private boolean visited; |
127 private boolean active; | 127 private boolean active; |
128 private int loops; | 128 private int loops; |
129 } | |
130 | |
131 public static class ExceptionBlock extends Block { | |
132 public RiExceptionHandler handler; | |
133 public Block next; | |
134 public Block handlerBlock; | |
129 } | 135 } |
130 | 136 |
131 private static final Block[] NO_SUCCESSORS = new Block[0]; | 137 private static final Block[] NO_SUCCESSORS = new Block[0]; |
132 | 138 |
133 /** | 139 /** |
344 private Block makeBlock(int startBci) { | 350 private Block makeBlock(int startBci) { |
345 Block oldBlock = blockMap[startBci]; | 351 Block oldBlock = blockMap[startBci]; |
346 if (oldBlock == null) { | 352 if (oldBlock == null) { |
347 Block newBlock = new Block(); | 353 Block newBlock = new Block(); |
348 newBlock.startBci = startBci; | 354 newBlock.startBci = startBci; |
349 newBlock.successors = NO_SUCCESSORS; | |
350 blockMap[startBci] = newBlock; | 355 blockMap[startBci] = newBlock; |
351 return newBlock; | 356 return newBlock; |
352 | 357 |
353 } else if (oldBlock.startBci != startBci) { | 358 } else if (oldBlock.startBci != startBci) { |
354 // Backward branch into the middle of an already processed block. | 359 // Backward branch into the middle of an already processed block. |
355 // Add the correct fall-through successor. | 360 // Add the correct fall-through successor. |
356 Block newBlock = new Block(); | 361 Block newBlock = new Block(); |
357 newBlock.startBci = startBci; | 362 newBlock.startBci = startBci; |
358 newBlock.endBci = oldBlock.endBci; | 363 newBlock.endBci = oldBlock.endBci; |
359 newBlock.successors = oldBlock.successors; | 364 newBlock.successors.addAll(oldBlock.successors); |
360 | 365 |
361 oldBlock.endBci = startBci - 1; | 366 oldBlock.endBci = startBci - 1; |
362 oldBlock.successors = new Block[] {newBlock }; | 367 oldBlock.successors.clear(); |
368 oldBlock.successors.add(newBlock); | |
363 | 369 |
364 for (int i = startBci; i <= newBlock.endBci; i++) { | 370 for (int i = startBci; i <= newBlock.endBci; i++) { |
365 blockMap[i] = newBlock; | 371 blockMap[i] = newBlock; |
366 } | 372 } |
367 return newBlock; | 373 return newBlock; |
386 if (sux.isExceptionEntry) { | 392 if (sux.isExceptionEntry) { |
387 throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow"); | 393 throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow"); |
388 } | 394 } |
389 } | 395 } |
390 Block predecessor = blockMap[predBci]; | 396 Block predecessor = blockMap[predBci]; |
391 assert predecessor.successors.length == 0; | 397 assert predecessor.successors.size() == 0; |
392 predecessor.successors = successors; | 398 predecessor.successors.addAll(Arrays.asList(successors)); |
399 } | |
400 | |
401 private HashMap<RiExceptionHandler, ExceptionBlock> exceptionDispatch = new HashMap<RiExceptionHandler, ExceptionBlock>(); | |
402 | |
403 private ExceptionBlock unwindBlock; | |
404 | |
405 private ExceptionBlock makeUnwind() { | |
406 if (unwindBlock == null) { | |
407 unwindBlock = new ExceptionBlock(); | |
408 unwindBlock.startBci = -1; | |
409 unwindBlock.endBci = -1; | |
410 } | |
411 return unwindBlock; | |
412 } | |
413 | |
414 private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index) { | |
415 RiExceptionHandler handler = handlers.get(index); | |
416 if (handler.isCatchAll()) { | |
417 return blockMap[handler.handlerBCI()]; | |
418 } | |
419 ExceptionBlock block = exceptionDispatch.get(handler); | |
420 if (block == null) { | |
421 block = new ExceptionBlock(); | |
422 block.startBci = -1; | |
423 block.endBci = -1; | |
424 block.handler = handler; | |
425 block.successors.add(blockMap[handler.handlerBCI()]); | |
426 block.handlerBlock = blockMap[handler.handlerBCI()]; | |
427 Block next; | |
428 if (index < handlers.size() - 1) { | |
429 next = makeExceptionDispatch(handlers, index + 1); | |
430 } else { | |
431 next = makeUnwind(); | |
432 } | |
433 block.successors.add(next); | |
434 block.next = next; | |
435 exceptionDispatch.put(handler, block); | |
436 } | |
437 return block; | |
393 } | 438 } |
394 | 439 |
395 private void addExceptionEdges() { | 440 private void addExceptionEdges() { |
396 if (canTrap == null) { | 441 if (canTrap == null) { |
397 return; | 442 return; |
398 } | 443 } |
399 | 444 |
400 Block block = null; | |
401 HashSet<Block> newSuccessorsOfBlock = new HashSet<Block>(); | |
402 | |
403 for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { | 445 for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { |
404 Block newBlock = blockMap[bci]; | 446 Block block = blockMap[bci]; |
405 if (newBlock != block) { | 447 |
406 if (block != null) { | 448 ArrayList<RiExceptionHandler> handlers = null; |
407 block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]); | |
408 newSuccessorsOfBlock.clear(); | |
409 } | |
410 Collections.addAll(newSuccessorsOfBlock, newBlock.successors); | |
411 } | |
412 block = newBlock; | |
413 | |
414 for (RiExceptionHandler h : method.exceptionHandlers()) { | 449 for (RiExceptionHandler h : method.exceptionHandlers()) { |
415 if (h.startBCI() <= bci && bci < h.endBCI()) { | 450 if (h.startBCI() <= bci && bci < h.endBCI()) { |
416 newSuccessorsOfBlock.add(blockMap[h.handlerBCI()]); | 451 if (handlers == null) { |
452 handlers = new ArrayList<RiExceptionHandler>(); | |
453 } | |
454 handlers.add(h); | |
417 if (h.isCatchAll()) { | 455 if (h.isCatchAll()) { |
418 break; | 456 break; |
419 } | 457 } |
420 } | 458 } |
421 } | 459 } |
422 } | 460 if (handlers != null) { |
423 if (block != null) { | 461 Block dispatch = makeExceptionDispatch(handlers, 0); |
424 block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]); | 462 block.successors.add(dispatch); |
463 } | |
425 } | 464 } |
426 } | 465 } |
427 | 466 |
428 private void computeBlockOrder() { | 467 private void computeBlockOrder() { |
429 int loop = computeBlockOrder(blockMap[0]); | 468 int loop = computeBlockOrder(blockMap[0]); |
511 | 550 |
512 private void processLoopBlock(Block block) { | 551 private void processLoopBlock(Block block) { |
513 // process all the stores in this block | 552 // process all the stores in this block |
514 byte[] code = method.code(); | 553 byte[] code = method.code(); |
515 int bci = block.startBci; | 554 int bci = block.startBci; |
516 while (bci <= block.endBci) { | 555 if (bci >= 0) { |
517 int opcode = Bytes.beU1(code, bci); | 556 while (bci <= block.endBci) { |
518 if (isStore(opcode)) { | 557 int opcode = Bytes.beU1(code, bci); |
519 processStore(opcode, Bytes.beU1(code, bci + 1)); | |
520 | |
521 } else if (opcode == WIDE) { | |
522 opcode = Bytes.beU1(code, bci + 1); | |
523 if (isStore(opcode)) { | 558 if (isStore(opcode)) { |
524 processStore(opcode, Bytes.beU2(code, bci + 2)); | 559 processStore(opcode, Bytes.beU1(code, bci + 1)); |
525 } | 560 |
526 } | 561 } else if (opcode == WIDE) { |
527 bci += lengthOf(code, bci); | 562 opcode = Bytes.beU1(code, bci + 1); |
563 if (isStore(opcode)) { | |
564 processStore(opcode, Bytes.beU2(code, bci + 2)); | |
565 } | |
566 } | |
567 bci += lengthOf(code, bci); | |
568 } | |
528 } | 569 } |
529 } | 570 } |
530 | 571 |
531 private void processStore(int opcode, int local) { | 572 private void processStore(int opcode, int local) { |
532 switch (opcode) { | 573 switch (opcode) { |