Bases: DataFlowAnalysis
This analysis identifies executable code paths. It is a foundational analysis
that other dataflow analyses can depend on to correctly handle control flow.
NOTE: Due to the lack of control flow interfaces in xDSL (e.g., BranchOpInterface,
RegionBranchOpInterface, CallOpInterface), the analysis does not handle control flow at all.
Essentially, only the entry block of the top-level op's first region is marked as live.
Source code in xdsl/analysis/dead_code_analysis.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 | class DeadCodeAnalysis(DataFlowAnalysis):
"""
This analysis identifies executable code paths. It is a foundational analysis
that other dataflow analyses can depend on to correctly handle control flow.
NOTE: Due to the lack of control flow interfaces in xDSL (e.g., BranchOpInterface,
RegionBranchOpInterface, CallOpInterface), the analysis does not handle control flow at all.
Essentially, only the entry block of the top-level op's first region is marked as live.
"""
def initialize(self, op: Operation) -> None:
# Mark the entry block of the top-level op's first region as live.
if op.regions and op.regions[0].first_block:
entry_point = ProgramPoint.at_start_of_block(op.regions[0].first_block)
executable = self.get_or_create_state(entry_point, Executable)
self.propagate_if_changed(executable, executable.set_to_live())
def visit(self, point: ProgramPoint) -> None:
op = point.op
if op is None:
# This analysis only triggers on operations.
return
# special cased for the typical case where the analysis is run on a ModuleOp:
assert isinstance(op, ModuleOp) or not op.regions, (
"Cannot yet handle operations with regions"
)
# If parent block is not live, do nothing.
parent_block = op.parent
if parent_block:
assert parent_block.last_op
assert not parent_block.last_op.successors, (
"Block has successor blocks, which are not supported yet"
)
block_start_point = ProgramPoint.at_start_of_block(parent_block)
parent_executable = self.get_or_create_state(block_start_point, Executable)
# Create dependency: if block liveness changes, re-visit this op.
self.add_dependency(parent_executable, point)
if not parent_executable.live:
return
# Subscribe to block liveness to visit all ops if it becomes live.
parent_executable.block_content_subscribers.add(self)
# Assert that we don't have nested regions or control flow yet
assert not op.regions, (
f"Operation {op.name} has nested regions, which are not supported yet"
)
|
initialize(op: Operation) -> None
Source code in xdsl/analysis/dead_code_analysis.py
| def initialize(self, op: Operation) -> None:
# Mark the entry block of the top-level op's first region as live.
if op.regions and op.regions[0].first_block:
entry_point = ProgramPoint.at_start_of_block(op.regions[0].first_block)
executable = self.get_or_create_state(entry_point, Executable)
self.propagate_if_changed(executable, executable.set_to_live())
|
visit(point: ProgramPoint) -> None
Source code in xdsl/analysis/dead_code_analysis.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 | def visit(self, point: ProgramPoint) -> None:
op = point.op
if op is None:
# This analysis only triggers on operations.
return
# special cased for the typical case where the analysis is run on a ModuleOp:
assert isinstance(op, ModuleOp) or not op.regions, (
"Cannot yet handle operations with regions"
)
# If parent block is not live, do nothing.
parent_block = op.parent
if parent_block:
assert parent_block.last_op
assert not parent_block.last_op.successors, (
"Block has successor blocks, which are not supported yet"
)
block_start_point = ProgramPoint.at_start_of_block(parent_block)
parent_executable = self.get_or_create_state(block_start_point, Executable)
# Create dependency: if block liveness changes, re-visit this op.
self.add_dependency(parent_executable, point)
if not parent_executable.live:
return
# Subscribe to block liveness to visit all ops if it becomes live.
parent_executable.block_content_subscribers.add(self)
# Assert that we don't have nested regions or control flow yet
assert not op.regions, (
f"Operation {op.name} has nested regions, which are not supported yet"
)
|