-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
compiler.ir: print even blocks without predecessors.
whitequark
committed
Nov 23, 2015
1 parent
d92b343
commit 8e96117
Showing
3 changed files
with
68 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .inline import inline |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
""" | ||
:func:`inline` inlines a call instruction in ARTIQ IR. | ||
The call instruction must have a statically known callee, | ||
it must be second to last in the basic block, and the basic | ||
block must have exactly one successor. | ||
""" | ||
|
||
from .. import ir | ||
|
||
def inline(call_insn): | ||
assert isinstance(call_insn, ir.Call) | ||
assert call_insn.static_target_function is not None | ||
assert len(call_insn.basic_block.successors()) == 1 | ||
assert call_insn.basic_block.index(call_insn) == \ | ||
len(call_insn.basic_block.instructions) - 2 | ||
|
||
value_map = {} | ||
source_function = call_insn.static_target_function | ||
target_function = call_insn.basic_block.function | ||
target_predecessor = call_insn.basic_block | ||
target_successor = call_insn.basic_block.successors()[0] | ||
target_return_phi = target_successor.prepend(ir.Phi(source_function.type.ret)) | ||
|
||
closure = target_predecessor.insert(ir.GetAttr(call_insn.target_function(), '__closure__'), | ||
before=call_insn) | ||
for actual_arg, formal_arg in zip([closure] + call_insn.arguments(), | ||
source_function.arguments): | ||
value_map[formal_arg] = actual_arg | ||
|
||
for source_block in source_function.basic_blocks: | ||
target_block = ir.BasicBlock([], "i." + source_block.name) | ||
target_function.add(target_block) | ||
value_map[source_block] = target_block | ||
|
||
def mapper(value): | ||
if isinstance(value, ir.Constant): | ||
return value | ||
else: | ||
return value_map[value] | ||
|
||
for source_insn in source_function.instructions(): | ||
target_block = value_map[source_insn.basic_block] | ||
if isinstance(source_insn, ir.Return): | ||
target_return_phi.add_incoming(mapper(source_insn.value()), target_block) | ||
target_insn = ir.Branch(target_successor) | ||
elif isinstance(source_insn, ir.Phi): | ||
target_insn = ir.Phi() | ||
else: | ||
target_insn = source_insn.copy(mapper) | ||
target_insn.name = "i." + source_insn.name | ||
value_map[source_insn] = target_insn | ||
target_block.append(target_insn) | ||
|
||
for source_insn in source_function.instructions(): | ||
if isinstance(source_insn, ir.Phi): | ||
target_insn = value_map[source_insn] | ||
for block, value in source_insn.incoming(): | ||
target_insn.add_incoming(value_map[value], value_map[block]) | ||
|
||
target_predecessor.terminator().replace_with(ir.Branch(value_map[source_function.entry()])) | ||
call_insn.replace_all_uses_with(target_return_phi) | ||
call_insn.erase() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters