added global code motion
This commit is contained in:
parent
09d6cf4b46
commit
032c04ad1d
4 changed files with 1341 additions and 17 deletions
45
ir.h
45
ir.h
|
|
@ -5,6 +5,8 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
struct _ir_node;
|
struct _ir_node;
|
||||||
|
struct _basic_block;
|
||||||
|
|
||||||
struct symbol_def {
|
struct symbol_def {
|
||||||
struct _ir_node *node;
|
struct _ir_node *node;
|
||||||
bool is_lvalue;
|
bool is_lvalue;
|
||||||
|
|
@ -12,6 +14,28 @@ struct symbol_def {
|
||||||
|
|
||||||
typedef struct { char *key; struct symbol_def *value; } symbol_table;
|
typedef struct { char *key; struct symbol_def *value; } symbol_table;
|
||||||
|
|
||||||
|
// Basic block for CFG representation
|
||||||
|
typedef struct _basic_block {
|
||||||
|
int id;
|
||||||
|
struct _ir_node *control; // Control node that starts this block (region, loop, proj, start)
|
||||||
|
struct _ir_node **nodes; // Scheduled nodes in this block (stb_ds array)
|
||||||
|
struct _basic_block **preds; // Predecessor blocks (stb_ds array)
|
||||||
|
struct _basic_block **succs; // Successor blocks (stb_ds array)
|
||||||
|
struct _basic_block *idom; // Immediate dominator
|
||||||
|
struct _basic_block **dom_children; // Children in dominator tree (stb_ds array)
|
||||||
|
int dom_depth; // Depth in dominator tree
|
||||||
|
int loop_depth; // Loop nesting depth (for GCM optimization)
|
||||||
|
bool visited; // For graph traversals
|
||||||
|
} basic_block;
|
||||||
|
|
||||||
|
// Function representation after GCM
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
basic_block *entry; // Entry block
|
||||||
|
basic_block **blocks; // All blocks in RPO order (stb_ds array)
|
||||||
|
int block_count;
|
||||||
|
} ir_function;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OC_START,
|
OC_START,
|
||||||
OC_ADD,
|
OC_ADD,
|
||||||
|
|
@ -24,6 +48,13 @@ typedef enum {
|
||||||
OC_BXOR,
|
OC_BXOR,
|
||||||
OC_NEG,
|
OC_NEG,
|
||||||
OC_EQ,
|
OC_EQ,
|
||||||
|
OC_NEQ,
|
||||||
|
OC_LT,
|
||||||
|
OC_GT,
|
||||||
|
OC_LE,
|
||||||
|
OC_GE,
|
||||||
|
OC_AND,
|
||||||
|
OC_OR,
|
||||||
|
|
||||||
OC_CONST_INT,
|
OC_CONST_INT,
|
||||||
OC_CONST_FLOAT,
|
OC_CONST_FLOAT,
|
||||||
|
|
@ -40,6 +71,9 @@ typedef enum {
|
||||||
|
|
||||||
OC_IF,
|
OC_IF,
|
||||||
OC_PROJ,
|
OC_PROJ,
|
||||||
|
OC_LOOP,
|
||||||
|
|
||||||
|
OC_CALL,
|
||||||
|
|
||||||
OC_STOP,
|
OC_STOP,
|
||||||
OC_RETURN,
|
OC_RETURN,
|
||||||
|
|
@ -57,9 +91,20 @@ typedef struct _ir_node {
|
||||||
f64 const_float;
|
f64 const_float;
|
||||||
symbol_table **symbol_tables;
|
symbol_table **symbol_tables;
|
||||||
char *start_name;
|
char *start_name;
|
||||||
|
char *call_name;
|
||||||
} data;
|
} data;
|
||||||
|
// GCM scheduling fields
|
||||||
|
struct _basic_block *early; // Earliest legal block
|
||||||
|
struct _basic_block *late; // Latest legal block
|
||||||
|
struct _basic_block *block; // Final scheduled block
|
||||||
|
bool pinned; // True if node must stay in its block (control nodes, phi, etc.)
|
||||||
|
bool scheduled; // True if already scheduled
|
||||||
} ir_node;
|
} ir_node;
|
||||||
|
|
||||||
void ir_build(ast_node *ast);
|
void ir_build(ast_node *ast);
|
||||||
|
|
||||||
|
// Global Code Motion and Scheduling
|
||||||
|
ir_function *gcm_schedule(ir_node *func_start);
|
||||||
|
void gcm_print_scheduled(ir_function *func);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
11
sema.c
11
sema.c
|
|
@ -558,11 +558,20 @@ static type *get_expression_type(sema *s, ast_node *node)
|
||||||
node->expr_type = t;
|
node->expr_type = t;
|
||||||
return t;
|
return t;
|
||||||
case NODE_CALL:
|
case NODE_CALL:
|
||||||
prot = shget(prototypes, intern_string(s, node->expr.call.name, node->expr.call.name_len));
|
node->expr.call.name = intern_string(s, node->expr.call.name, node->expr.call.name_len);
|
||||||
|
prot = shget(prototypes, node->expr.call.name);
|
||||||
if (!prot) {
|
if (!prot) {
|
||||||
error(node, "unknown function.");
|
error(node, "unknown function.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
// Process call arguments
|
||||||
|
ast_node *arg = node->expr.call.parameters;
|
||||||
|
while (arg && arg->type == NODE_UNIT) {
|
||||||
|
if (arg->expr.unit_node.expr) {
|
||||||
|
get_expression_type(s, arg->expr.unit_node.expr);
|
||||||
|
}
|
||||||
|
arg = arg->expr.unit_node.next;
|
||||||
|
}
|
||||||
t = prot->type;
|
t = prot->type;
|
||||||
node->expr_type = t;
|
node->expr_type = t;
|
||||||
return t;
|
return t;
|
||||||
|
|
|
||||||
14
test.l
14
test.l
|
|
@ -1,12 +1,8 @@
|
||||||
u32 main(u32 b)
|
u32 main(u32 n)
|
||||||
{
|
{
|
||||||
u32 a = 4;
|
i32 i = 0;
|
||||||
//return a;
|
loop while i < 10 {
|
||||||
if (b == 3) {
|
i = i + 1;
|
||||||
return 3;
|
|
||||||
} else {
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue