picotool icon indicating copy to clipboard operation
picotool copied to clipboard

Prunning unused functions and variables

Open tupini07 opened this issue 2 years ago • 2 comments

First of all thanks for making such a great tool!

This is more of a feasibility question than an actual issue: I was curious about how hard would it be to have build exclude unused functions (and potentially also variables) when building.

I'm sure there are many like me that like to make a library of common functions and reuse it in different games. However, most of the time not all functions are used, which means it is necessary to do some manual cleaning for each game so that only the necessary functions are included (and tokens are saved).

Besides being really helpful to save tokens I think this feature would also enable the creation of more reusable pico8 libraries, where the library can be arbitrarily large, and users can just invoke what they need, and unused stuff will just get pruned during building.

tupini07 avatar Sep 23 '21 14:09 tupini07

Dead code elimination is my holy grail for picotool! 🌟 The intent is for the parser to be powerful enough to make changes directly to the AST, then write it back out as text, preserving as much of the original as is desired. The build step can do "token optimization:" perform data flow analysis to identify globals and constants, do build-time evaluation of constant expressions, and remove unused definitions and branches.

My original intent was to improve the parser before diving into this. The current parser is weak and difficult to maintain, more of a proof of concept than something I'd want to do dataflow analysis with. But yes it should be feasible.

Before:

-- get draw_tile() routine:
#include "tilestuff.lua"

player_x=40
player_y=50
player_sprite=7

debug_mode=false
show_debug_markers=true
function draw_debug_marker(tilenum) ... end

function _update()
  if (btn(1)) player_x += 1
  if (btn(2)) player_y += 1
  -- etc.
end

function _draw()
  for tile=1,5 do
    if debug_mode and show_debug_markers then
      draw_debug_marker(tile)
    end
    draw_tile(tile)
  end
  spr(player_sprite, player_x, player_y)
end

After token and character optimization (approximately):

function a(b) ... end
c=40
d=50
function _update()
if(btn(1))c+=1
if(btn(2))d+=1
end
function _draw()
for e=1,5 do
a(e)
end
spr(7,c,d)
end

Support for token optimized library use is the chief motivation, 100% agreed!

dansanderson avatar Sep 27 '21 01:09 dansanderson

Support for constants would be HUGE. That might not even require any further analysis steps; you could just mark variables as constant with a magic comment and let the same preprocessor that deals with require substitute it out.

GiovanH avatar Oct 05 '21 23:10 GiovanH