Browse Source

Re-enabled MOVE instructions optimizer, added the ability to enable/disable it via ircode pragma commands.

Marco Bambini 8 năm trước cách đây
mục cha
commit
b85746ac73

+ 14 - 0
src/compiler/gravity_codegen.c

@@ -1178,6 +1178,9 @@ static void visit_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
 	CODEGEN_COUNT_REGISTERS(n1);
 	ircode_push_context(code);
 	
+	// disable MOVE optimization
+	ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 0);
+	
 	// generate code for the common id node
 	visit(node->id);
 	
@@ -1245,7 +1248,9 @@ static void visit_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
 			for (size_t j=0; j<n; ++j) {
 				// process each argument
 				gnode_t *arg = (gnode_t *)gnode_array_get(subnode->args, j);
+				ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 1);
 				visit(arg);
+				ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 0);
 				uint32_t nreg = ircode_register_pop_context_protect(code, true);
 				// make sure args are in consecutive register locations (from temp_target_register + 1 to temp_target_register + n)
 				if (nreg != temp_target_register + j + 2) {
@@ -1312,7 +1317,9 @@ static void visit_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
 			
 		} else if (tag == NODE_SUBSCRIPT_EXPR) {
 			// process index
+			ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 1);
 			visit(subnode->expr);
+			ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 0);
 			uint32_t index = ircode_register_pop(code);
 			
 			// generate LOADAT/STOREAT instruction
@@ -1333,6 +1340,9 @@ static void visit_postfix_expr (gvisitor_t *self, gnode_postfix_expr_t *node) {
 	
 	CODEGEN_COUNT_REGISTERS(n2);
 	CODEGEN_ASSERT_REGISTERS(n1, n2, (is_assignment) ? -1 : 1);
+	
+	// re-enable MOVE optimization
+	ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 1);
 }
 
 static void visit_file_expr (gvisitor_t *self, gnode_file_expr_t *node) {
@@ -1570,6 +1580,7 @@ static void visit_list_expr (gvisitor_t *self, gnode_list_expr_t *node) {
 	if (n % max_fields != 0) ++nloops;
 	uint32_t nprocessed = 0;
 	
+	ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 0);
 	while (nprocessed < n) {
 		size_t k = (n - nprocessed > max_fields) ? max_fields : (n - nprocessed);
 		size_t idxstart = nprocessed;
@@ -1598,7 +1609,9 @@ static void visit_list_expr (gvisitor_t *self, gnode_list_expr_t *node) {
 			
 			if (ismap) {
 				e = gnode_array_get(node->list2, j);
+				ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 1);
 				visit(e);
+				ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 0);
 				nreg = ircode_register_pop_context_protect(code, true);
 				
 				if (nreg != dest + i + 1) {
@@ -1622,6 +1635,7 @@ static void visit_list_expr (gvisitor_t *self, gnode_list_expr_t *node) {
 		ircode_pop_context(code);
 	}
 	
+	ircode_pragma(code, PRAGMA_MOVE_OPTIMIZATION, 1);
 	CODEGEN_COUNT_REGISTERS(n2);
 	CODEGEN_ASSERT_REGISTERS(n1, n2, 1);
 }

+ 8 - 3
src/compiler/gravity_ircode.c

@@ -269,7 +269,7 @@ void ircode_dump  (void *_code) {
 		int32_t		p2 = inst->p2;
 		int32_t		p3 = inst->p3;
 		if (inst->tag == SKIP_TAG) continue;
-		if (inst->tag == PRAGMA_OPTIMIZATION) continue;
+		if (inst->tag == PRAGMA_MOVE_OPTIMIZATION) continue;
 		if (inst->tag == LABEL_TAG) {printf("LABEL %d:\n", p1); continue;}
 		
 		uint8_t n = opcode_numop(op);
@@ -287,7 +287,7 @@ void ircode_dump  (void *_code) {
 			case 2: {
 				if (op == LOADI) {
 					if (inst->tag == DOUBLE_TAG) printf("%05d\t%s %d %.2f\n", line, opcode_name(op), p1, inst->d);
-					else printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, (int32_t)inst->n);
+					else printf("%05d\t%s %d %lld\n", line, opcode_name(op), p1, inst->n);
 				} else if (op == LOADK) {
 					if (p2 < CPOOL_INDEX_MAX) printf("%05d\t%s %d %d\n", line, opcode_name(op), p1, p2);
 					else printf("%05d\t%s %d %s\n", line, opcode_name(op), p1, opcode_constname(p2));
@@ -345,6 +345,11 @@ void ircode_marklabel (ircode_t *code, uint32_t nlabel) {
 	marray_push(inst_t*, *code->list, inst);
 }
 
+// MARK: -
+void ircode_pragma (ircode_t *code, optag_t tag, uint32_t value) {
+	ircode_add_tag(code, 0, value, 0, 0, tag);
+}
+
 // MARK: -
 
 void ircode_set_index (uint32_t index, ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3) {
@@ -517,7 +522,7 @@ void ircode_register_unset_skip_clear (ircode_t *code, uint32_t nreg) {
 	code->skipclear[nreg] = false;
 }
 
-void ircode_register_clear_temps (ircode_t *code) {
+void ircode_register_clear_temps (ircode_t *code) {	
 	// clear all temporary registers (if not protected)
 	for (uint32_t i=code->nlocals; i<=code->maxtemp; ++i) {
 		if (!code->skipclear[i]) code->state[i] = false;

+ 2 - 1
src/compiler/gravity_ircode.h

@@ -37,7 +37,7 @@ typedef enum {
 		SKIP_TAG,
 		RANGE_INCLUDE_TAG,
 		RANGE_EXCLUDE_TAG,
-		PRAGMA_OPTIMIZATION
+		PRAGMA_MOVE_OPTIMIZATION
 } optag_t;
 
 typedef struct {
@@ -77,6 +77,7 @@ void		ircode_marklabel (ircode_t *code, uint32_t nlabel);
 void		inst_setskip (inst_t *inst);
 uint8_t		opcode_numop (opcode_t op);
 
+void		ircode_pragma (ircode_t *code, optag_t tag, uint32_t value);
 void		ircode_add (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3);
 void		ircode_add_tag (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, optag_t tag);
 void		ircode_add_array (ircode_t *code, opcode_t op, uint32_t p1, uint32_t p2, uint32_t p3, uint32_r r);

+ 7 - 2
src/compiler/gravity_optimizer.c

@@ -23,6 +23,7 @@
 #define IS_SKIP(inst)					(inst->tag == SKIP_TAG)
 #define IS_LABEL(inst)					(inst->tag == LABEL_TAG)
 #define IS_NOTNULL(inst)				(inst)
+#define IS_PRAGMA_MOVE_OPT(inst)		(inst->tag == PRAGMA_MOVE_OPTIMIZATION)
 
 // http://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html
 #define OPCODE_SET(op,code)								op = (code & 0x3F) << 26
@@ -59,6 +60,7 @@ static void finalize_function (gravity_function_t *f) {
 	for (uint32_t i=0; i<count; ++i) {
 		inst_t *inst = ircode_get(code, i);
 		if (IS_SKIP(inst)) continue;
+		if (IS_PRAGMA_MOVE_OPT(inst)) continue;
 		if (IS_LABEL(inst)) {
 			// insert key inst->p1 into hash table labels with value ninst (next instruction)
 			gravity_hash_insert(labels, VALUE_FROM_INT(inst->p1), VALUE_FROM_INT(ninst));
@@ -77,6 +79,7 @@ static void finalize_function (gravity_function_t *f) {
 		inst_t *inst = ircode_get(code, i);
 		if (IS_SKIP(inst)) continue;
 		if (IS_LABEL(inst)) continue;
+		if (IS_PRAGMA_MOVE_OPT(inst)) continue;
 		
 		uint32_t op = 0x0;
 		switch (inst->op) {
@@ -383,7 +386,6 @@ static bool optimize_math_instruction (ircode_t *code, inst_t *inst, uint32_t i)
 }
 
 static bool optimize_move_instruction (ircode_t *code, inst_t *inst, uint32_t i) {
-	return false;
 	inst_t *inst1 = NULL;
 	pop1_instruction(code, i, &inst1);
 	if (inst1 == NULL) return false;
@@ -456,6 +458,7 @@ gravity_function_t *gravity_optimizer(gravity_function_t *f) {
 	
 	ircode_t	*code = (ircode_t *)f->bytecode;
 	uint32_t	count = ircode_count(code);
+	bool		optimizer = true;
 	
 	f->ntemps = ircode_ntemps(code);
 	
@@ -478,9 +481,11 @@ gravity_function_t *gravity_optimizer(gravity_function_t *f) {
 	}
 	
 	loop_move:
+	optimizer = true;
 	for (uint32_t i=0; i<count; ++i) {
 		inst_t *inst = current_instruction(code, i);
-		if (IS_MOVE(inst)) {
+		if (IS_PRAGMA_MOVE_OPT(inst)) optimizer = (bool)inst->p1;
+		if (optimizer && IS_MOVE(inst)) {
 			bool b = optimize_move_instruction (code, inst, i);
 			if (b) goto loop_move;
 		}