mirror of
https://github.com/irmen/prog8.git
synced 2025-02-08 16:30:28 +00:00
improve callgraph unused subroutine check for routines called from inline asm
This commit is contained in:
parent
0b1f30d98c
commit
cac4c1eb1e
@ -160,11 +160,22 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
fun unused(module: Module) = module !in usedModules
|
fun unused(module: Module) = module !in usedModules
|
||||||
|
|
||||||
fun unused(sub: Subroutine): Boolean {
|
fun unused(sub: Subroutine): Boolean {
|
||||||
return sub !in usedSubroutines && !nameInAssemblyCode(sub.name, listOf("p8s_", ""))
|
if(sub in usedSubroutines)
|
||||||
|
return false
|
||||||
|
val asm = nameInAssemblyCode(sub.name, listOf("p8s_", ""))
|
||||||
|
if(asm!=null) {
|
||||||
|
// check that the asm block that calls us, is inside a subroutine that is unused or not
|
||||||
|
val containingSub = asm.definingSubroutine
|
||||||
|
return if(containingSub != null && containingSub !== sub)
|
||||||
|
unused(containingSub)
|
||||||
|
else
|
||||||
|
false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unused(block: Block): Boolean {
|
fun unused(block: Block): Boolean {
|
||||||
return block !in usedBlocks && !nameInAssemblyCode(block.name, listOf("p8b_", ""))
|
return block !in usedBlocks && nameInAssemblyCode(block.name, listOf("p8b_", ""))==null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unused(decl: VarDecl): Boolean {
|
fun unused(decl: VarDecl): Boolean {
|
||||||
@ -187,13 +198,13 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val prefixes = listOf("p8b_", "p8v_", "p8s_", "p8c_", "p8l_", "p8_", "")
|
private val prefixes = listOf("p8b_", "p8v_", "p8s_", "p8c_", "p8l_", "p8_", "")
|
||||||
private fun nameInAssemblyCode(name: String, knownAsmPrefixes: List<String> = emptyList()): Boolean {
|
private fun nameInAssemblyCode(name: String, knownAsmPrefixes: List<String> = emptyList()): InlineAssembly? {
|
||||||
if(knownAsmPrefixes.isNotEmpty())
|
if(knownAsmPrefixes.isNotEmpty())
|
||||||
return allAssemblyNodes.any {
|
return allAssemblyNodes.firstOrNull {
|
||||||
knownAsmPrefixes.any { prefix -> prefix+name in it.names }
|
knownAsmPrefixes.any { prefix -> prefix+name in it.names }
|
||||||
}
|
}
|
||||||
|
|
||||||
return allAssemblyNodes.any {
|
return allAssemblyNodes.firstOrNull {
|
||||||
prefixes.any { prefix -> prefix+name in it.names }
|
prefixes.any { prefix -> prefix+name in it.names }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
callgraph issue? : if a sub contains another sub and it calls that, the outer sub is never removed even if it doesn't get called?
|
|
||||||
(diskio, when read4hex is placed back inside internal_f_tell() )
|
|
||||||
|
|
||||||
|
|
||||||
Improve register load order in subroutine call args assignments:
|
Improve register load order in subroutine call args assignments:
|
||||||
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
||||||
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
|
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
|
||||||
|
@ -35,7 +35,7 @@ main {
|
|||||||
|
|
||||||
|
|
||||||
irq {
|
irq {
|
||||||
const ubyte BAR_Y_OFFSET = 6
|
const ubyte BAR_Y_OFFSET = 5
|
||||||
uword next_irq_line = 0
|
uword next_irq_line = 0
|
||||||
ubyte anim1 = 0
|
ubyte anim1 = 0
|
||||||
ubyte av1 = 0
|
ubyte av1 = 0
|
||||||
@ -47,7 +47,7 @@ irq {
|
|||||||
next_irq_line += BAR_Y_OFFSET
|
next_irq_line += BAR_Y_OFFSET
|
||||||
anim1 += 7
|
anim1 += 7
|
||||||
anim2 += 4
|
anim2 += 4
|
||||||
if next_irq_line > 480-BAR_Y_OFFSET {
|
if next_irq_line > 480 {
|
||||||
av1++
|
av1++
|
||||||
av2 += 2
|
av2 += 2
|
||||||
anim1 = av1
|
anim1 = av1
|
||||||
@ -55,6 +55,10 @@ irq {
|
|||||||
next_irq_line = 0
|
next_irq_line = 0
|
||||||
; erase the bars
|
; erase the bars
|
||||||
gfx2.horizontal_line(0, 0, 320, 3)
|
gfx2.horizontal_line(0, 0, 320, 3)
|
||||||
|
; gfx2.position(0, 0)
|
||||||
|
; repeat 10 {
|
||||||
|
; gfx2.next_pixels(pixels, len(pixels))
|
||||||
|
; }
|
||||||
} else {
|
} else {
|
||||||
; add new bar on top
|
; add new bar on top
|
||||||
gfx2.position(math.sin8u(anim1)/2 + math.cos8u(anim2)/2 + $0010, 0)
|
gfx2.position(math.sin8u(anim1)/2 + math.cos8u(anim2)/2 + $0010, 0)
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
%import monogfx
|
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
monogfx.hires()
|
; nothing!
|
||||||
monogfx.circle(320, 240, 200, true)
|
}
|
||||||
sys.wait(60)
|
}
|
||||||
monogfx.drawmode(monogfx.MODE_STIPPLE)
|
|
||||||
monogfx.disc(320, 240, 200, true)
|
|
||||||
sys.wait(60)
|
|
||||||
monogfx.drawmode(monogfx.MODE_NORMAL)
|
|
||||||
monogfx.safe_disc(320, 240, 200, true)
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
|
derp {
|
||||||
|
asmsub f_tell() -> uword @R0, uword @R1, uword @R2, uword @R3 {
|
||||||
|
%asm {{
|
||||||
|
jmp p8s_internal_f_tell
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub internal_f_tell() {
|
||||||
|
cx16.r1 = read4hex()
|
||||||
|
|
||||||
|
sub read4hex() -> uword {
|
||||||
|
str @shared hex = "0000000000000000000000000000000000000000000"
|
||||||
|
cx16.r0++
|
||||||
|
return cx16.r0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user