Skip to content

Commit 99f4f80

Browse files
marcomarquesdcBeyondMagic
authored andcommitted
Update ast.h
Adicionar o campo que diz se a variável foi usada ou não.
1 parent d2f595b commit 99f4f80

File tree

11 files changed

+124
-50
lines changed

11 files changed

+124
-50
lines changed

src/ast.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ typedef struct AstStmt
159159
int is_array;
160160
size_t array_size;
161161
AstExpr *array_init;
162+
163+
int is_used;
162164
} decl;
163165
struct
164166
{

src/codegen_lua.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static void emit_string_literal(FILE *out, const char *value);
2020
static void emit_array_declaration(FILE *out, const AstStmt *stmt, const FunctionTable *functions, int indent);
2121
static void emit_array_literal_expr(FILE *out, const AstExprList *elements, const FunctionTable *functions);
2222
static void emit_array_index(FILE *out, const AstExpr *expr, const FunctionTable *functions);
23+
static int expr_has_side_effects(const AstExpr *expr);
2324
static void emit_array_default_value(FILE *out, TypeKind type);
2425
static const FunctionSignature *lookup_signature(const FunctionTable *functions, const char *name);
2526
static const char *binary_op_token(AstBinaryOp op);
@@ -165,7 +166,10 @@ static void emit_statement(FILE *out, const AstStmt *stmt, const FunctionTable *
165166
case STMT_DECL:
166167
if (!stmt->data.decl.is_used && !stmt->data.decl.is_array)
167168
{
168-
return; // Dead Code Elimination: Variável desaparece do Lua!
169+
if (!stmt->data.decl.init || !expr_has_side_effects(stmt->data.decl.init))
170+
{
171+
return; // Dead Code Elimination: remove unused locals without side effects
172+
}
169173
}
170174

171175
if (stmt->data.decl.is_array)
@@ -396,6 +400,43 @@ static void emit_expression_raw(FILE *out, const AstExpr *expr, const FunctionTa
396400
}
397401
}
398402

403+
static int expr_has_side_effects(const AstExpr *expr)
404+
{
405+
if (!expr)
406+
{
407+
return 0;
408+
}
409+
410+
switch (expr->kind)
411+
{
412+
case EXPR_CALL:
413+
return 1;
414+
case EXPR_BINARY:
415+
return expr_has_side_effects(expr->data.binary.left) || expr_has_side_effects(expr->data.binary.right);
416+
case EXPR_UNARY:
417+
return expr_has_side_effects(expr->data.unary.operand);
418+
case EXPR_SUBSCRIPT:
419+
return expr_has_side_effects(expr->data.subscript.array) || expr_has_side_effects(expr->data.subscript.index);
420+
case EXPR_ARRAY_LITERAL:
421+
for (size_t i = 0; i < expr->data.array_literal.elements.count; ++i)
422+
{
423+
if (expr_has_side_effects(expr->data.array_literal.elements.items[i]))
424+
{
425+
return 1;
426+
}
427+
}
428+
return 0;
429+
case EXPR_IDENTIFIER:
430+
case EXPR_INT_LITERAL:
431+
case EXPR_FLOAT_LITERAL:
432+
case EXPR_BOOL_LITERAL:
433+
case EXPR_STRING_LITERAL:
434+
return 0;
435+
default:
436+
return 0;
437+
}
438+
}
439+
399440
static void emit_expression_as_bool(FILE *out, const AstExpr *expr, const FunctionTable *functions)
400441
{
401442
if (!expr)

src/optimizer.c

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ typedef struct
88
{
99
AstExpr **location;
1010
size_t stmt_index;
11+
AstStmt *stmt;
1112
} CseOccurrence;
1213

1314
typedef struct
@@ -32,15 +33,15 @@ static void optimize_block(AstBlock *block);
3233
static void optimize_statement_children(AstStmt *stmt);
3334
static void collect_block_candidates(AstBlock *block, CseEntryList *entries);
3435
static void collect_statement_candidates(AstStmt *stmt, size_t stmt_index, CseEntryList *entries);
35-
static void collect_expr_candidates(AstExpr **expr_ptr, size_t stmt_index, CseEntryList *entries);
36+
static void collect_expr_candidates(AstExpr **expr_ptr, size_t stmt_index, AstStmt *owner, CseEntryList *entries);
3637
static int expr_is_constant(const AstExpr *expr);
3738
static int expr_is_candidate(const AstExpr *expr);
3839
static char *expr_make_key(const AstExpr *expr);
39-
static void register_candidate(CseEntryList *entries, AstExpr **expr_ptr, size_t stmt_index);
40+
static void register_candidate(CseEntryList *entries, AstExpr **expr_ptr, size_t stmt_index, AstStmt *owner);
4041
static CseEntry *find_entry(CseEntryList *entries, const char *key);
4142
static void ensure_entry_capacity(CseEntryList *list, size_t needed);
4243
static void ensure_occ_capacity(CseEntry *entry, size_t needed);
43-
static void add_occurrence(CseEntry *entry, AstExpr **location, size_t stmt_index);
44+
static void add_occurrence(CseEntry *entry, AstExpr **location, size_t stmt_index, AstStmt *stmt);
4445
static void apply_cse(AstBlock *block, CseEntryList *entries);
4546
static void insert_statement(AstStmtList *list, size_t index, AstStmt *stmt);
4647
static AstExpr *make_temp_identifier(const char *name, TypeKind type);
@@ -49,6 +50,7 @@ static void free_entries(CseEntryList *entries);
4950
static char *dup_string(const char *value);
5051
static void *xmalloc(size_t size);
5152
static int compare_entries_by_index(const void *lhs, const void *rhs);
53+
static int occurrence_survives_dce(const CseOccurrence *occ);
5254

5355
void optimize_program(AstProgram *program)
5456
{
@@ -138,20 +140,20 @@ static void collect_statement_candidates(AstStmt *stmt, size_t stmt_index, CseEn
138140
case STMT_DECL:
139141
if (!stmt->data.decl.is_array && stmt->data.decl.init)
140142
{
141-
collect_expr_candidates(&stmt->data.decl.init, stmt_index, entries);
143+
collect_expr_candidates(&stmt->data.decl.init, stmt_index, stmt, entries);
142144
}
143145
break;
144146
case STMT_ASSIGN:
145-
collect_expr_candidates(&stmt->data.assign.value, stmt_index, entries);
147+
collect_expr_candidates(&stmt->data.assign.value, stmt_index, stmt, entries);
146148
break;
147149
case STMT_ARRAY_ASSIGN:
148-
collect_expr_candidates(&stmt->data.array_assign.value, stmt_index, entries);
150+
collect_expr_candidates(&stmt->data.array_assign.value, stmt_index, stmt, entries);
149151
break;
150152
case STMT_EXPR:
151153
case STMT_RETURN:
152154
if (stmt->data.expr)
153155
{
154-
collect_expr_candidates(&stmt->data.expr, stmt_index, entries);
156+
collect_expr_candidates(&stmt->data.expr, stmt_index, stmt, entries);
155157
}
156158
break;
157159
case STMT_WHILE:
@@ -164,7 +166,7 @@ static void collect_statement_candidates(AstStmt *stmt, size_t stmt_index, CseEn
164166
}
165167
}
166168

167-
static void collect_expr_candidates(AstExpr **expr_ptr, size_t stmt_index, CseEntryList *entries)
169+
static void collect_expr_candidates(AstExpr **expr_ptr, size_t stmt_index, AstStmt *owner, CseEntryList *entries)
168170
{
169171
if (!expr_ptr || !*expr_ptr)
170172
{
@@ -176,35 +178,35 @@ static void collect_expr_candidates(AstExpr **expr_ptr, size_t stmt_index, CseEn
176178
switch (expr->kind)
177179
{
178180
case EXPR_BINARY:
179-
collect_expr_candidates(&expr->data.binary.left, stmt_index, entries);
180-
collect_expr_candidates(&expr->data.binary.right, stmt_index, entries);
181+
collect_expr_candidates(&expr->data.binary.left, stmt_index, owner, entries);
182+
collect_expr_candidates(&expr->data.binary.right, stmt_index, owner, entries);
181183
break;
182184
case EXPR_UNARY:
183-
collect_expr_candidates(&expr->data.unary.operand, stmt_index, entries);
185+
collect_expr_candidates(&expr->data.unary.operand, stmt_index, owner, entries);
184186
break;
185187
case EXPR_CALL:
186188
for (size_t i = 0; i < expr->data.call.args.count; ++i)
187189
{
188-
collect_expr_candidates(&expr->data.call.args.items[i], stmt_index, entries);
190+
collect_expr_candidates(&expr->data.call.args.items[i], stmt_index, owner, entries);
189191
}
190192
break;
191193
case EXPR_ARRAY_LITERAL:
192194
for (size_t i = 0; i < expr->data.array_literal.elements.count; ++i)
193195
{
194-
collect_expr_candidates(&expr->data.array_literal.elements.items[i], stmt_index, entries);
196+
collect_expr_candidates(&expr->data.array_literal.elements.items[i], stmt_index, owner, entries);
195197
}
196198
break;
197199
case EXPR_SUBSCRIPT:
198-
collect_expr_candidates(&expr->data.subscript.array, stmt_index, entries);
199-
collect_expr_candidates(&expr->data.subscript.index, stmt_index, entries);
200+
collect_expr_candidates(&expr->data.subscript.array, stmt_index, owner, entries);
201+
collect_expr_candidates(&expr->data.subscript.index, stmt_index, owner, entries);
200202
break;
201203
default:
202204
break;
203205
}
204206

205207
if (expr_is_candidate(expr))
206208
{
207-
register_candidate(entries, expr_ptr, stmt_index);
209+
register_candidate(entries, expr_ptr, stmt_index, owner);
208210
}
209211
}
210212

@@ -244,7 +246,7 @@ static int expr_is_candidate(const AstExpr *expr)
244246
return expr_is_constant(expr);
245247
}
246248

247-
static void register_candidate(CseEntryList *entries, AstExpr **expr_ptr, size_t stmt_index)
249+
static void register_candidate(CseEntryList *entries, AstExpr **expr_ptr, size_t stmt_index, AstStmt *owner)
248250
{
249251
if (!entries || !expr_ptr || !*expr_ptr)
250252
{
@@ -273,7 +275,7 @@ static void register_candidate(CseEntryList *entries, AstExpr **expr_ptr, size_t
273275
entry->first_stmt_index = stmt_index;
274276
}
275277
}
276-
add_occurrence(entry, expr_ptr, stmt_index);
278+
add_occurrence(entry, expr_ptr, stmt_index, owner);
277279
}
278280

279281
static CseEntry *find_entry(CseEntryList *entries, const char *key)
@@ -342,7 +344,7 @@ static void ensure_occ_capacity(CseEntry *entry, size_t needed)
342344
entry->occurrence_capacity = new_capacity;
343345
}
344346

345-
static void add_occurrence(CseEntry *entry, AstExpr **location, size_t stmt_index)
347+
static void add_occurrence(CseEntry *entry, AstExpr **location, size_t stmt_index, AstStmt *stmt)
346348
{
347349
if (!entry)
348350
{
@@ -351,6 +353,7 @@ static void add_occurrence(CseEntry *entry, AstExpr **location, size_t stmt_inde
351353
ensure_occ_capacity(entry, entry->occurrence_count + 1);
352354
entry->occurrences[entry->occurrence_count].location = location;
353355
entry->occurrences[entry->occurrence_count].stmt_index = stmt_index;
356+
entry->occurrences[entry->occurrence_count].stmt = stmt;
354357
entry->occurrence_count++;
355358
}
356359

@@ -411,7 +414,21 @@ static void apply_cse(AstBlock *block, CseEntryList *entries)
411414
}
412415
}
413416

417+
int has_live_use = 0;
418+
for (size_t j = 0; j < entry->occurrence_count; ++j)
419+
{
420+
if (occurrence_survives_dce(&entry->occurrences[j]))
421+
{
422+
has_live_use = 1;
423+
break;
424+
}
425+
}
426+
414427
AstStmt *decl = ast_stmt_make_decl(entry->type, dup_string(temp_name), init_expr);
428+
if (has_live_use)
429+
{
430+
decl->data.decl.is_used = 1; /* mark as live so DCE keeps this temp */
431+
}
415432
insert_statement(&block->statements, entry->first_stmt_index + inserted, decl);
416433
inserted++;
417434
free(temp_name);
@@ -520,6 +537,19 @@ static int compare_entries_by_index(const void *lhs, const void *rhs)
520537
return 0;
521538
}
522539

540+
static int occurrence_survives_dce(const CseOccurrence *occ)
541+
{
542+
if (!occ || !occ->stmt)
543+
{
544+
return 1;
545+
}
546+
if (occ->stmt->kind != STMT_DECL)
547+
{
548+
return 1;
549+
}
550+
return occ->stmt->data.decl.is_used != 0;
551+
}
552+
523553
static char *expr_make_key(const AstExpr *expr)
524554
{
525555
if (!expr)
@@ -531,9 +561,12 @@ static char *expr_make_key(const AstExpr *expr)
531561
{
532562
case EXPR_INT_LITERAL:
533563
// Include type information in the key to distinguish between int and char literals
534-
if (expr->type == TYPE_CHAR) {
564+
if (expr->type == TYPE_CHAR)
565+
{
535566
snprintf(buffer, sizeof(buffer), "C:%lld", expr->data.int_value);
536-
} else {
567+
}
568+
else
569+
{
537570
snprintf(buffer, sizeof(buffer), "I:%lld", expr->data.int_value);
538571
}
539572
return dup_string(buffer);

src/semantic.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ static int analyze_statement(SemanticInfo *info, AstFunction *fn, SymbolTable *s
184184
TYPE_ARRAY,
185185
1,
186186
stmt->data.decl.array_size,
187-
stmt->data.decl.type))
187+
stmt->data.decl.type,
188+
stmt))
188189
{
189190
semantic_error("duplicate declaration of '%s' in function '%s'", stmt->data.decl.name, fn->name);
190191
return 0;
@@ -448,14 +449,11 @@ static TypeKind analyze_expression(SemanticInfo *info, SymbolTable *symbols, Ast
448449
expr->type = TYPE_UNKNOWN;
449450
return expr->type;
450451
}
451-
expr->type = symbol->type;
452-
return expr->type;
453-
}
454-
if (symbol->stmt_ref)
455-
{
456-
symbol->stmt_ref->data.decl.is_used = 1;
457-
}
458-
// ---------------------------
452+
if (symbol->stmt_ref)
453+
{
454+
symbol->stmt_ref->data.decl.is_used = 1;
455+
}
456+
// ---------------------------
459457

460458
expr->type = symbol->type;
461459
return expr->type;

src/symbol_table.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,8 @@ int symbol_table_add(SymbolTable *table, const char *name, TypeKind type, int is
129129
scope->items[scope->count].is_array = is_array ? 1 : 0;
130130
scope->items[scope->count].array_size = array_size;
131131
scope->items[scope->count].element_type = element_type;
132-
133-
// Adicione esta linha:
134-
scope->items[scope->count].stmt_ref = stmt_ref;
135-
136-
scope->count++;
137-
return 1;
138-
}
139-
ensure_capacity((void **)&scope->items, sizeof(Symbol), &scope->capacity, scope->count + 1);
140-
scope->items[scope->count].name = dup_string(name);
141-
scope->items[scope->count].type = type;
142-
scope->items[scope->count].is_array = is_array ? 1 : 0;
143-
scope->items[scope->count].array_size = array_size;
144-
scope->items[scope->count].element_type = element_type;
132+
scope->items[scope->count].stmt_ref = stmt_ref;
133+
145134
scope->count++;
146135
return 1;
147136
}

src/symbol_table.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ typedef struct
1010
int is_array;
1111
size_t array_size;
1212
TypeKind element_type;
13-
struct AstStmt *stmt_ref;
13+
struct AstStmt *stmt_ref;
1414
} Symbol;
15-
int symbol_table_add(SymbolTable *table, const char *name, TypeKind type, int is_array, size_t array_size, TypeKind element_type, struct AstStmt *stmt_ref);
15+
1616
typedef struct
1717
{
1818
Symbol *items;
@@ -45,7 +45,7 @@ void symbol_table_init(SymbolTable *table);
4545
void symbol_table_free(SymbolTable *table);
4646
void symbol_table_push_scope(SymbolTable *table);
4747
void symbol_table_pop_scope(SymbolTable *table);
48-
int symbol_table_add(SymbolTable *table, const char *name, TypeKind type, int is_array, size_t array_size, TypeKind element_type);
48+
int symbol_table_add(SymbolTable *table, const char *name, TypeKind type, int is_array, size_t array_size, TypeKind element_type, struct AstStmt *stmt_ref);
4949
const Symbol *symbol_table_lookup(const SymbolTable *table, const char *name);
5050

5151
void function_table_init(FunctionTable *table);

tests/pass/arith.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ int main()
66
int x = 7;
77
int y = 3;
88
int z = x % y; // ok: % em inteiros
9-
return x;
9+
printf("%f %d\n", c, z);
10+
return 0;
1011
}

tests/pass/arith.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ os.exit((function(args)
55
local x = 7
66
local y = 3
77
local z = (x % y)
8-
return x
8+
print(string.format("%f %d", c, z))
9+
return 0
910
end)(arg))

tests/pass/dead_variable.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
int main()
2+
{
3+
int a = 10;
4+
int b = 5 + 1;
5+
int c = 5 + 1;
6+
return 0;
7+
}

tests/pass/dead_variable.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
os.exit((function(args)
2+
return 0
3+
end)(arg))

0 commit comments

Comments
 (0)