Browse Source

Added int constant folding

master
Raphael Roberts 4 years ago
parent
commit
3ca417a469
  1. 1
      README.md
  2. 38
      c2logic/compiler.py
  3. 21
      c2logic/consts.py

1
README.md

@ -21,6 +21,7 @@ Optimization Level:
- modify variables without using a temporary
2. more optimizations
- remove uncalled functions
- constant folding
3. turns on some potentially unsafe optimizations
- augmented assignment and pre/postincrement/decrement don't modify `__rax`
- returning from main becomes equivalent to `end`

38
c2logic/compiler.py

@ -5,10 +5,11 @@ from dataclasses import dataclass
from pycparser import c_ast, parse_file
from pycparser.c_ast import (
Compound, Constant, DeclList, Enum, FileAST, FuncDecl, Struct, TypeDecl, Typename
Compound, Constant, DeclList, Enum, FileAST, FuncDecl, Struct, TypeDecl, Typename, BinaryOp as
ast_BinaryOp
)
from .consts import func_binary_ops, func_unary_ops, SPECIAL_VARS
from .consts import func_binary_ops, func_unary_ops, SPECIAL_VARS, binary_ops_python
from .instructions import (
Instruction,
Noop,
@ -54,6 +55,29 @@ class Variable():
name: str
"""
def int_constant_fold(node):
if isinstance(node, ast_BinaryOp):
left = int_constant_fold(node.left)
right = int_constant_fold(node.right)
if isinstance(left, Constant) and isinstance(
right, Constant
) and left.type == 'int' and right.type == 'int':
try:
new_constant = Constant(
'int', str(binary_ops_python[node.op](int(left.value), int(right.value)))
)
return new_constant
except KeyError:
node.left = left
node.right = right
return node
else:
node.left = left
node.right = right
return node
else:
return node
class Compiler(c_ast.NodeVisitor):
def __init__(self, opt_level=0):
self.opt_level = opt_level
@ -345,6 +369,16 @@ class Compiler(c_ast.NodeVisitor):
self.push(Set("__rax", varname))
def visit_BinaryOp(self, node):
if self.opt_level >= 2:
new_node = int_constant_fold(node)
if isinstance(new_node, ast_BinaryOp):
self.visit_BinaryOp_base(new_node)
else:
self.visit(new_node)
else:
self.visit_BinaryOp_base(node)
def visit_BinaryOp_base(self, node):
self.visit(node.left)
left = self.get_special_var("__rbx")
self.set_to_rax(left)

21
c2logic/consts.py

@ -1,4 +1,6 @@
# see https://github.com/Anuken/Mindustry/blob/master/core/src/mindustry/logic/LogicOp.java
import operator
binary_ops = {
"+": "add",
"-": "sub",
@ -17,7 +19,24 @@ binary_ops = {
"&": "and",
"^": "xor"
}
binary_ops_python = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.floordiv,
"%": operator.mod,
"==": operator.eq,
"!=": operator.ne,
"<": operator.lt,
"<=": operator.le,
">": operator.gt,
">=": operator.ge,
">>": operator.rshift,
"<<": operator.lshift,
"|": operator.or_,
"&": operator.and_,
"^": operator.xor,
}
condition_ops = {
"==": "equal",
"!=": "notEqual",

Loading…
Cancel
Save