summaryrefslogtreecommitdiff
path: root/tools/codegen
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-02-27 12:36:41 -0800
committerJames Iry <jamesiry@gmail.com>2013-03-06 07:20:15 -0800
commitb50a0d811f0fb99ccbc295741e66bab348b3f99e (patch)
treea53e6b32dbc8df07f4ce3bbe48a854e473d0d2cc /tools/codegen
parentb8c8299be52e1bffc0efec54bd7294510e36022e (diff)
downloadscala-b50a0d811f0fb99ccbc295741e66bab348b3f99e.tar.gz
scala-b50a0d811f0fb99ccbc295741e66bab348b3f99e.tar.bz2
scala-b50a0d811f0fb99ccbc295741e66bab348b3f99e.zip
SI-7006 Prevent unreachable blocks in GenICode
This commit makes GenICode prevent the generation of most unreachable blocks. The new unreachable block prevention code can be disabled with a compiler flag. Because full unreachable analysis is no longer necessary for normal code it makes the unreachable block analysis run only under -optimise. A test is included to make sure unreachable code doesn't cause issues in code gen. A concrete example will help. def foo(): X = { try return something() catch { case e: Throwable => println(e) throw e } unreachableCode() ] Here unreachableCode() is unreachable but GenICode would create ICode for it and then ASM would turn it into a pile of NOPS. A previous commit added a reachability analysis step to eliminate that unreachable code but that added a bit of time to the compilation process even when optimization was turned off. This commit avoids generating most unreachable ICode in the first place so that full reachability analysis is only needed after doing other optimization work. The new code works by extending a mechanism that was already in place. When GenICode encountered a THROW or RETURN it would put the current block into "ignore" mode so that no further instructions would be written into the block. However, that ignore mode flag was itself ignored when it came to figuring out if follow on blocks should be written. So this commit goes through places like try/catch and if/else and uses the ignore mode of the current block to decide whether to create follow on blocks, or if it already has, to kill by putting them into ignore mode and closing them where they'll be removed from the method's list of active blocks. It's not quite as good as full reachability analysis. In particular because a label def can be emitted before anything that jumps to it, this simple logic is forced to leave label defs alone and that means some of them may be unreachable without being removed. However, in practice it gets close the the benefit of reachability analysis at very nearly no cost.
Diffstat (limited to 'tools/codegen')
0 files changed, 0 insertions, 0 deletions