niv / neverwinter.nim

CLI tools and nim library used in Neverwinter Nights: Enhanced Edition development
MIT License
131 stars 29 forks source link

Optimize away dead branches when the IF condition is a constant #124

Closed mtijanic closed 5 months ago

mtijanic commented 5 months ago

In a script like:

void main() {
    if (1) {
        PrintString("THEN branch");
    } else {
        PrintString("ELSE branch");
    }
}

the generated code looks like:

void #loader():  [0:8]
  0   0   JSR      main                                      
  6   6   RET                                                

void main(): test.nss:1 [8:70]
  8   0   CONST.I  1              if (1) {                   
  14  6   JZ       46                                        
  20  12  CONST.S  "THEN branch"  PrintString("THEN branch");
  35  27  ACTION   PrintString                               
  40  32  JMP      68                                        
  46  38  NOP                     } else {                   
  48  40  CONST.S  "ELSE branch"  PrintString("ELSE branch");
  63  55  ACTION   PrintString                               
  68  60  RET                     }    

and the parse tree is: image

With this change, we detect this parse tree and trim it down to: image

which results in the following NCS:

void #loader():  [0:8]
  0   0   JSR      main                                      
  6   6   RET                                                

void main(): test.nss:2 [8:30]
  8   0   CONST.S  "THEN branch"  PrintString("THEN branch");
  23  15  ACTION   PrintString                               
  28  20  RET                     }                

See comments in TrimParseTree() for details.

Testing

Changelog

Performance Improvements

Licence

mtijanic commented 5 months ago

Based on testing from Daz and Jasperre, I'm happy for this to go in and get some more testing.

mtijanic commented 5 months ago

Well, it ain't getting any more testing sitting in a PR, so this is the logical next step. Let it soak here a while and then pull into preview.