-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimize1.c
134 lines (119 loc) · 3.76 KB
/
optimize1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <stdlib.h>
#include "parse.h"
#include "compile.h"
#include "optimize1.h"
/*
* Intermediate AST Optimizations
*
* for TiBc (Ti B compiler)
*
* by Ben Jones
* 2/12/2019
*/
void propogate_constants(expression *expr){
long int value_a;
long int value_b;
if(expr->type == OPERATOR && (expr->sub_type == ADD || expr->sub_type == SUBTRACT || expr->sub_type == MULTIPLY || expr->sub_type == DIVIDE || expr->sub_type == AND || expr->sub_type == OR || expr->sub_type == XOR || expr->sub_type == ELEMENT)){
propogate_constants(expr->expr1);
propogate_constants(expr->expr2);
if(expr->expr1->type == LITERAL && expr->expr2->type == LITERAL && expr->expr1->sub_type == INTEGER && expr->expr2->sub_type == INTEGER){
value_a = expr->expr1->const_pointer->int_value;
value_b = expr->expr2->const_pointer->int_value;
free_expression(expr->expr1);
free_expression(expr->expr2);
expr->type = LITERAL;
expr->const_pointer = create_constant(INTEGER, 0);
switch(expr->sub_type){
case ADD:
expr->const_pointer->int_value = value_a + value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case SUBTRACT:
expr->const_pointer->int_value = value_a - value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case MULTIPLY:
expr->const_pointer->int_value = value_a*value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case DIVIDE:
expr->const_pointer->int_value = value_a/value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case AND:
expr->const_pointer->int_value = value_a&value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case OR:
expr->const_pointer->int_value = value_a|value_b;
OPTIMIZE1_CONTINUE = 1;
break;
case XOR:
expr->const_pointer->int_value = value_a^value_b;
OPTIMIZE1_CONTINUE = 1;
break;
}
expr->sub_type = INTEGER;
}
}
}
void const_index_expression(expression *expr, block *func){
unsigned int calculated_index;
variable *var_pointer;
if(expr->type == UNARY || (expr->type == OPERATOR && expr->sub_type == ASSIGN)){
const_index_expression(expr->expr2, func);
} else if(expr->type == OPERATOR){
const_index_expression(expr->expr1, func);
const_index_expression(expr->expr2, func);
}
if(expr->type == OPERATOR && expr->sub_type == ELEMENT && expr->expr1->type == IDENTIFIER && expr->expr1->var_pointer->type == LOCALLIST && expr->expr2->type == LITERAL){
calculated_index = *(func->local_size) - expr->expr2->const_pointer->int_value + 1;
var_pointer = expr->expr1->var_pointer;
expr->reg = expr->expr1->reg;
free_expression(expr->expr1);
free_expression(expr->expr2);
expr->type = LOADSTACK;
expr->const_pointer = create_constant(INTEGER, 0);
expr->const_pointer->int_value = calculated_index;
OPTIMIZE1_CONTINUE = 1;
}
}
void optimize1_expression(expression *expr, block *func){
propogate_constants(expr);
const_index_expression(expr, func);
}
void optimize1_statement(statement *s, block *func){
if(!s->type){
optimize1_expression(s->expr, func);
} else if(s->type == KEYWORD){
if(s->sub_type == IF || s->sub_type == WHILE){
optimize1_block(s->code, func);
}
if(s->sub_type == RETURN || s->sub_type == IF || s->sub_type == WHILE){
optimize1_expression(s->expr, func);
}
}
}
void optimize1_block(block *b, block *func){
unsigned char output;
linked_list *statements;
statements = b->statements;
while(statements->next){
statements = statements->next;
optimize1_statement((statement *) statements->value, func);
}
}
void _optimize1(void *void_var){
variable *var;
var = (variable *) void_var;
if(var->is_function && !var->is_data){
optimize1_block(var->function, var->function);
}
}
void optimize1(dictionary global_space){
OPTIMIZE1_CONTINUE = 1;
while(OPTIMIZE1_CONTINUE){
OPTIMIZE1_CONTINUE = 0;
iterate_dictionary(global_space, _optimize1);
}
}