Routines can be declared `preserved`.

This commit is contained in:
Chris Pressey 2019-10-21 21:45:59 +01:00
parent 2192a48e0e
commit 1098347fa5
5 changed files with 55 additions and 7 deletions

View File

@ -8,6 +8,9 @@ History of SixtyPical
approximates the set of routines which are not called
by any other routine, with an eye to omitting them from
the final executable.
* A routine can be declared `preserved`, which prevents a
compiler from omitting it from the final executable, even
if it determines it is not called by any other routine.
* The `dcc6502-adapter` test adapter was updated to conform
to the output of the latest version of `dcc6502`.

View File

@ -33,8 +33,8 @@ def construct_callgraph(program):
potential_calls = node['potentially-calls']
if routine.name in potential_calls:
potentially_called_by.append(name)
if getattr(routine, 'explicitly_marked_as_called', None) or routine.name == 'main':
potentially_called_by.append('*marked*')
if getattr(routine, 'preserved', None) or routine.name == 'main':
potentially_called_by.append('*preserved*')
graph[routine.name]['potentially-called-by'] = potentially_called_by
return graph

View File

@ -111,8 +111,12 @@ class Parser(object):
name = self.scanner.token
self.scanner.scan()
self.current_routine_name = name
preserved = False
if self.scanner.consume('preserved'):
preserved = True
type_, routine = self.routine(name)
self.declare(name, routine, type_)
routine.preserved = preserved
routines.append(routine)
self.current_routine_name = None
self.scanner.check_type('EOF')

View File

@ -12,7 +12,7 @@ called.
The `main` routine is always called. The thing that it will
be called by is the system, but the callgraph analyzer will
simply consider it to be "marked as called".
simply consider it to be "marked as preserved".
| define main routine
| {
@ -20,7 +20,7 @@ simply consider it to be "marked as called".
= {
= "main": {
= "potentially-called-by": [
= "*marked*"
= "*preserved*"
= ],
= "potentially-calls": []
= }
@ -39,7 +39,7 @@ If a routine is called by another routine, this fact will be noted.
= {
= "main": {
= "potentially-called-by": [
= "*marked*"
= "*preserved*"
= ],
= "potentially-calls": [
= "other"
@ -68,7 +68,7 @@ the final executable.
= {
= "main": {
= "potentially-called-by": [
= "*marked*"
= "*preserved*"
= ],
= "potentially-calls": []
= },
@ -78,6 +78,35 @@ the final executable.
= }
= }
If a routine is not called by another routine, but it is declared
explicitly as `preserved`, then it will not be considered unused,
and a compiler or linker will not be permitted to omit it from
the final executable. This is useful for interrupt routines and
such that really are used by some part of the system, even if not
directly by another SixtyPical routine.
| define main routine
| {
| }
|
| define other preserved routine
| {
| }
= {
= "main": {
= "potentially-called-by": [
= "*preserved*"
= ],
= "potentially-calls": []
= },
= "other": {
= "potentially-called-by": [
= "*preserved*"
= ],
= "potentially-calls": []
= }
= }
If two routines potentially call each other, this will be noted,
even if nothing else potentially calls either of those routines.
This may change in the future.
@ -98,7 +127,7 @@ This may change in the future.
= {
= "main": {
= "potentially-called-by": [
= "*marked*"
= "*preserved*"
= ],
= "potentially-calls": []
= },

View File

@ -73,6 +73,18 @@ Extern routines
| @ 65487
= ok
Preserved routine.
| define main routine {
| ld a, $ff
| add a, $01
| }
| define foo preserved routine {
| ld a, 0
| add a, 1
| }
= ok
Trash.
| define main routine {