[Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.101, 1.1.2.102

nascheme at users.sourceforge.net nascheme at users.sourceforge.net
Sat Feb 19 03:43:47 CET 2005


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18511/Python

Modified Files:
      Tag: ast-branch
	newcompile.c 
Log Message:
Use pointers to basic blocks rather than indexes into the u_blocks array.


Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.101
retrieving revision 1.1.2.102
diff -u -d -r1.1.2.101 -r1.1.2.102
--- newcompile.c	16 Jan 2005 17:09:12 -0000	1.1.2.101
+++ newcompile.c	19 Feb 2005 02:43:45 -0000	1.1.2.102
@@ -42,10 +42,6 @@
 
     ISSUES:
 
-     Tim mentioned that it's more common for a basic blocks representation
-     to use real pointers for jump targets rather than indexes into an
-     array of basic blocks.
-
      opcode_stack_effect() function should be reviewed since stack depth bugs
      could be really hard to find later.
 
@@ -53,20 +49,6 @@
     
 */
 
-/* fblockinfo tracks the current frame block.
-
-   A frame block is used to handle loops, try/except, and try/finally.
-   It's called a frame block to distinguish it from a basic block in the
-   compiler IR.
-*/
-
-enum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END };
-
-struct fblockinfo {
-        enum fblocktype fb_type;
-	int fb_block;
-};
-
 #define DEFAULT_BLOCK_SIZE 16
 #define DEFAULT_BLOCKS 8
 #define DEFAULT_CODE_SIZE 128
@@ -78,24 +60,42 @@
 	int i_hasarg : 1;
 	unsigned char i_opcode;
 	int i_oparg;
-	int i_target; /* target block index (if jump instruction) */
+	struct basicblock_ *i_target; /* target block (if jump instruction) */
 	int i_lineno;
 };
 
-struct basicblock {
+typedef struct basicblock_ {
+	/* number of instructions used */
 	int b_iused;
+	/* length of instruction array (b_instr) */
 	int b_ialloc;
-	/* If b_next is non-zero, it is the block id of the next
-	   block reached by normal control flow.
-	   Since a valid b_next must always be > 0,
-	   0 can be reserved to mean no next block. */
-	int b_next;
+	/* pointer to an array of instructions, initially NULL */
+	struct instr *b_instr;
+	/* If b_next is non-NULL, it is a pointer to the next
+	   block reached by normal control flow. */
+	struct basicblock_ *b_next;
 	/* b_seen is used to perform a DFS of basicblocks. */
 	int b_seen : 1;
 	/* b_return is true if a RETURN_VALUE opcode is inserted. */
 	int b_return : 1;
-	int b_startdepth; /* depth of stack upon entry of block */
-	struct instr b_instr[DEFAULT_BLOCK_SIZE];
+	/* depth of stack upon entry of block, computed by stackdepth() */
+	int b_startdepth;
+	/* instruction offset for block, computed by assemble_jump_offsets() */
+        int b_offset;
+} basicblock;
+
+/* fblockinfo tracks the current frame block.
+
+   A frame block is used to handle loops, try/except, and try/finally.
+   It's called a frame block to distinguish it from a basic block in the
+   compiler IR.
+*/
+
+enum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END };
+
+struct fblockinfo {
+        enum fblocktype fb_type;
+	basicblock *fb_block;
 };
 
 /* The following items change on entry and exit of code blocks.
@@ -121,9 +121,9 @@
 	int u_nblocks;     /* number of used blocks in u_blocks
 			      u_nblocks < u_nalloc */
 	int u_nalloc;      /* current alloc count for u_blocks */
-	int u_curblock;    /* index of current block in u_blocks */
+	basicblock *u_curblock; /* pointer to current block (from u_blocks) */
 	int u_tmpname;     /* temporary variables for list comps */
-	struct basicblock **u_blocks;
+	basicblock **u_blocks;
 
 	int u_nfblocks;
 	struct fblockinfo u_fblock[CO_MAXBLOCKS];
@@ -152,7 +152,7 @@
 	PyObject *a_bytecode;  /* string containing bytecode */
 	int a_offset;          /* offset into bytecode */
 	int a_nblocks;         /* number of reachable blocks */
-	int *a_postorder;      /* list of block indices in dfs postorder */
+	basicblock **a_postorder; /* list of blocks in dfs postorder */
 	PyObject *a_lnotab;    /* string containing lnotab */
 	int a_lnotab_off;      /* offset into lnotab */
 	int a_lineno;          /* last lineno of emitted instruction */
@@ -161,14 +161,14 @@
 
 static int compiler_enter_scope(struct compiler *, identifier, void *, int);
 static void compiler_free(struct compiler *);
-static int compiler_new_block(struct compiler *);
-static int compiler_next_instr(struct compiler *, int);
+static basicblock *compiler_new_block(struct compiler *);
+static int compiler_next_instr(struct compiler *, basicblock *);
 static int compiler_addop(struct compiler *, int);
 static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *);
 static int compiler_addop_i(struct compiler *, int, int);
-static int compiler_addop_j(struct compiler *, int, int, int);
-static void compiler_use_block(struct compiler *, int);
-static int compiler_use_new_block(struct compiler *);
+static int compiler_addop_j(struct compiler *, int, basicblock *, int);
+static void compiler_use_block(struct compiler *, basicblock *);
+static basicblock *compiler_use_new_block(struct compiler *);
 static int compiler_error(struct compiler *, const char *);
 static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
 
@@ -180,8 +180,10 @@
 static int compiler_visit_slice(struct compiler *, slice_ty,
 				expr_context_ty);
 
-static int compiler_push_fblock(struct compiler *, enum fblocktype, int);
-static void compiler_pop_fblock(struct compiler *, enum fblocktype, int);
+static int compiler_push_fblock(struct compiler *, enum fblocktype,
+				basicblock *);
+static void compiler_pop_fblock(struct compiler *, enum fblocktype,
+				basicblock *);
 
 static int inplace_binop(struct compiler *, operator_ty);
 static int expr_constant(expr_ty e);
@@ -438,8 +440,8 @@
 
 	u->u_nblocks = 0;
 	u->u_nalloc = DEFAULT_BLOCKS;
-	u->u_blocks = (struct basicblock **)PyObject_Malloc(
-		sizeof(struct basicblock *) * DEFAULT_BLOCKS);
+	u->u_blocks = (basicblock **)PyObject_Malloc(
+		sizeof(basicblock *) * DEFAULT_BLOCKS);
 	if (!u->u_blocks)
 		return 0;
 	u->u_tmpname = 0;
@@ -447,7 +449,7 @@
 	u->u_firstlineno = lineno;
 	u->u_lineno = 0;
 	u->u_lineno_set = false;
-	memset(u->u_blocks, 0, sizeof(struct basicblock *) * DEFAULT_BLOCKS);
+	memset(u->u_blocks, 0, sizeof(basicblock *) * DEFAULT_BLOCKS);
 	u->u_consts = PyDict_New();
 	if (!u->u_consts)
 		return 0;
@@ -483,16 +485,22 @@
 compiler_unit_check(struct compiler_unit *u)
 {
 	int i;
-	assert(u->u_curblock < u->u_nblocks);
 	assert(u->u_nblocks <= u->u_nalloc);
 	for (i = 0; i < u->u_nblocks; i++) {
-		struct basicblock *block = u->u_blocks[i];
+		basicblock *block = u->u_blocks[i];
 		assert(block);
 		assert(block != (void *)0xcbcbcbcb);
 		assert(block != (void *)0xfbfbfbfb);
-		assert(block->b_ialloc > 0);
-		assert(block->b_iused >= 0 
-		       && block->b_ialloc >= block->b_iused);
+		assert(block != (void *)0xdbdbdbdb);
+		if (block->b_instr != NULL) {
+			assert(block->b_ialloc > 0);
+			assert(block->b_iused > 0);
+			assert(block->b_ialloc >= block->b_iused);
+		}
+		else {
+			assert (block->b_iused == 0);
+			assert (block->b_ialloc == 0);
+		}
 	}
 }
 
@@ -502,8 +510,12 @@
 	int i;
 
 	compiler_unit_check(u);
-	for (i = 0; i < u->u_nblocks; i++)
-		PyObject_Free((void *)u->u_blocks[i]);
+	for (i = 0; i < u->u_nblocks; i++) {
+		basicblock *b = u->u_blocks[i];
+		if (b->b_instr)
+			PyObject_Free((void *)b->b_instr);
+		PyObject_Free((void *)b);
+	}
 	if (u->u_blocks)
 		PyObject_Free((void *)u->u_blocks);
 	Py_XDECREF(u->u_ste);
@@ -540,75 +552,73 @@
 	return 1; /* XXX void? */
 }
 
-/* Allocate a new block and return its index in c_blocks.
-   Returns -1 on error.
+/* Allocate a new block and return a pointer to it.
+   Returns NULL on error.
 */
 
-static int
+static basicblock *
 compiler_new_block(struct compiler *c)
 {
-	struct basicblock *b;
+	basicblock *b;
 	struct compiler_unit *u;
-	int block;
+	int i;
 
 	u = c->u;
 	if (u->u_nblocks == u->u_nalloc) {
 		int newsize = ((u->u_nalloc + u->u_nalloc)
-			       * sizeof(struct basicblock *));
-		u->u_blocks = (struct basicblock **)PyObject_Realloc(
+			       * sizeof(basicblock *));
+		u->u_blocks = (basicblock **)PyObject_Realloc(
 			u->u_blocks, newsize);
 		if (u->u_blocks == NULL)
-			return -1;
+			return NULL;
 		memset(u->u_blocks + u->u_nalloc, 0,
-		       sizeof(struct basicblock *) * u->u_nalloc);
+		       sizeof(basicblock *) * u->u_nalloc);
 		u->u_nalloc += u->u_nalloc;
 	}
-	b = (struct basicblock *)PyObject_Malloc(sizeof(struct basicblock));
+	b = (basicblock *)PyObject_Malloc(sizeof(basicblock));
 	if (b == NULL)
-		return -1;
-	memset((void *)b, 0, sizeof(struct basicblock));
-	b->b_ialloc = DEFAULT_BLOCK_SIZE;
-	block = u->u_nblocks++;
-	assert(u->u_blocks[block] == NULL);
-	u->u_blocks[block] = b;
-	return block;
+		return NULL;
+	memset((void *)b, 0, sizeof(basicblock));
+	assert (b->b_next == NULL);
+	i = u->u_nblocks++;
+	assert(u->u_blocks[i] == NULL);
+	u->u_blocks[i] = b;
+	return b;
 }
 
 static void
-compiler_use_block(struct compiler *c, int block)
+compiler_use_block(struct compiler *c, basicblock *block)
 {
-	assert(block < c->u->u_nblocks);
+        assert (block != NULL);
 	c->u->u_curblock = block;
-	assert(c->u->u_blocks[block]);
 }
 
-static int
+static basicblock *
 compiler_use_new_block(struct compiler *c)
 {
-	int block = compiler_new_block(c);
-	if (block < 0)
-		return 0;
+	basicblock *block = compiler_new_block(c);
+	if (block == NULL)
+		return NULL;
 	c->u->u_curblock = block;
 	return block;
 }
 
-static int
+static basicblock *
 compiler_next_block(struct compiler *c)
 {
-	int block = compiler_new_block(c);
-	if (block < 0)
-		return 0;
-	c->u->u_blocks[c->u->u_curblock]->b_next = block;
+	basicblock *block = compiler_new_block(c);
+	if (block == NULL)
+		return NULL;
+	c->u->u_curblock->b_next = block;
 	c->u->u_curblock = block;
 	return block;
 }
 
-static int
-compiler_use_next_block(struct compiler *c, int block)
+static basicblock *
+compiler_use_next_block(struct compiler *c, basicblock *block)
 {
-	assert(block < c->u->u_nblocks);
-	c->u->u_blocks[c->u->u_curblock]->b_next = block;
-	assert(c->u->u_blocks[block]);
+	assert(block != NULL);
+	c->u->u_curblock->b_next = block;
 	c->u->u_curblock = block;
 	return block;
 }
@@ -619,34 +629,33 @@
  */
 
 static int
-compiler_next_instr(struct compiler *c, int block)
+compiler_next_instr(struct compiler *c, basicblock *b)
 {
-	struct basicblock *b;
-	assert(block < c->u->u_nblocks);
-	b = c->u->u_blocks[block];
-	assert(b);
-	if (b->b_iused == b->b_ialloc) {
-		void *ptr;
-		int oldsize, newsize;
-		oldsize = sizeof(struct basicblock);
-		if (b->b_ialloc > DEFAULT_BLOCK_SIZE)
-			oldsize += ((b->b_ialloc - DEFAULT_BLOCK_SIZE)
-				    * sizeof(struct instr));
-		newsize = oldsize + b->b_ialloc * sizeof(struct instr);
-		if (newsize <= 0) {
+	assert(b != NULL);
+        if (b->b_instr == NULL) {
+		b->b_instr = PyObject_Malloc(sizeof(struct instr) *
+					     DEFAULT_BLOCK_SIZE);
+		if (b->b_instr == NULL) {
 			PyErr_NoMemory();
 			return -1;
 		}
-		b->b_ialloc <<= 1;
-		ptr = PyObject_Realloc((void *)b, newsize);
-		if (ptr == NULL)
+		b->b_ialloc = DEFAULT_BLOCK_SIZE;
+		memset((char *)b->b_instr, 0,
+		       sizeof(struct instr) * DEFAULT_BLOCK_SIZE);
+        }
+	else if (b->b_iused == b->b_ialloc) {
+		size_t oldsize, newsize;
+		oldsize = b->b_ialloc * sizeof(struct instr);
+		newsize = oldsize << 1;
+		if (newsize == 0) {
+			PyErr_NoMemory();
 			return -1;
-		memset((char *)ptr + oldsize, 0, newsize - oldsize);
-		if (ptr != (void *)b) {
-			fprintf(stderr, "resize block %d\n", block);
-			c->u->u_blocks[block] = (struct basicblock *)ptr;
-			b = ptr;
 		}
+		b->b_ialloc <<= 1;
+		b->b_instr = PyObject_Realloc((void *)b->b_instr, newsize);
+		if (b->b_instr == NULL)
+			return -1;
+		memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
 	}
 	return b->b_iused++;
 }
@@ -658,11 +667,11 @@
 static void
 compiler_set_lineno(struct compiler *c, int off)
 {
-	struct basicblock *b;
+	basicblock *b;
 	if (c->u->u_lineno_set)
 		return;
 	c->u->u_lineno_set = true;
-	b = c->u->u_blocks[c->u->u_curblock];
+	b = c->u->u_curblock;
  	b->b_instr[off].i_lineno = c->u->u_lineno;
 }
 
@@ -886,13 +895,13 @@
 static int
 compiler_addop(struct compiler *c, int opcode)
 {
-	struct basicblock *b;
+	basicblock *b;
 	struct instr *i;
 	int off;
 	off = compiler_next_instr(c, c->u->u_curblock);
 	if (off < 0)
 		return 0;
-	b = c->u->u_blocks[c->u->u_curblock];
+	b = c->u->u_curblock;
 	i = &b->b_instr[off];
 	i->i_opcode = opcode;
 	i->i_hasarg = 0;
@@ -972,7 +981,7 @@
 	off = compiler_next_instr(c, c->u->u_curblock);
 	if (off < 0)
 		return 0;
-	i = &c->u->u_blocks[c->u->u_curblock]->b_instr[off];
+	i = &c->u->u_curblock->b_instr[off];
 	i->i_opcode = opcode;
 	i->i_oparg = oparg;
 	i->i_hasarg = 1;
@@ -981,19 +990,19 @@
 }
 
 static int
-compiler_addop_j(struct compiler *c, int opcode, int block, int absolute)
+compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
 {
 	struct instr *i;
 	int off;
 
-	assert(block >= 0);
+	assert(b != NULL);
 	off = compiler_next_instr(c, c->u->u_curblock);
 	if (off < 0)
 		return 0;
 	compiler_set_lineno(c, off);
-	i = &c->u->u_blocks[c->u->u_curblock]->b_instr[off];
+	i = &c->u->u_curblock->b_instr[off];
 	i->i_opcode = opcode;
-	i->i_target = block;
+	i->i_target = b;
 	i->i_hasarg = 1;
 	if (absolute)
 		i->i_jabs = 1;
@@ -1014,12 +1023,12 @@
 
 
 #define NEW_BLOCK(C) { \
-        if (compiler_use_new_block((C)) < 0) \
+        if (compiler_use_new_block((C)) == NULL) \
 	        return 0; \
 }
 
 #define NEXT_BLOCK(C) { \
-        if (compiler_next_block((C)) < 0) \
+        if (compiler_next_block((C)) == NULL) \
 	        return 0; \
 }
 
@@ -1410,14 +1419,14 @@
 static int
 compiler_if(struct compiler *c, stmt_ty s)
 {
-	int end, next;
+	basicblock *end, *next;
 
 	assert(s->kind == If_kind);
 	end = compiler_new_block(c);
-	if (end < 0)
+	if (end == NULL)
 		return 0;
         next = compiler_new_block(c);
-        if (next < 0)
+        if (next == NULL)
             return 0;
         VISIT(c, expr, s->v.If.test);
         ADDOP_JREL(c, JUMP_IF_FALSE, next);
@@ -1435,12 +1444,12 @@
 static int
 compiler_for(struct compiler *c, stmt_ty s)
 {
-	int start, cleanup, end;
+	basicblock *start, *cleanup, *end;
 
 	start = compiler_new_block(c);
 	cleanup = compiler_new_block(c);
 	end = compiler_new_block(c);
-	if (start < 0 || end < 0 || cleanup < 0)
+	if (start == NULL || end == NULL || cleanup == NULL)
 		return 0;
 	ADDOP_JREL(c, SETUP_LOOP, end);
 	if (!compiler_push_fblock(c, LOOP, start))
@@ -1463,7 +1472,7 @@
 static int
 compiler_while(struct compiler *c, stmt_ty s)
 {
-	int loop, orelse, end, anchor;
+	basicblock *loop, *orelse, *end, *anchor;
 	int constant = expr_constant(s->v.While.test);
 
 	if (constant == 0)
@@ -1472,18 +1481,18 @@
 	end = compiler_new_block(c);
 	if (constant == -1) {
 		anchor = compiler_new_block(c);
-		if (anchor < 0)
+		if (anchor == NULL)
 			return 0;
 	}
-	if (loop < 0 || end < 0)
+	if (loop == NULL || end == NULL)
 		return 0;
 	if (s->v.While.orelse) {
 		orelse = compiler_new_block(c);
-		if (orelse < 0)
+		if (orelse == NULL)
 			return 0;
 	}
 	else
-		orelse = -1;
+		orelse = NULL;
 
 	ADDOP_JREL(c, SETUP_LOOP, end);
 	compiler_use_next_block(c, loop);
@@ -1507,7 +1516,7 @@
 		ADDOP(c, POP_BLOCK);
 	}
 	compiler_pop_fblock(c, LOOP, loop);
-	if (orelse != -1)
+	if (orelse != NULL)
 		VISIT_SEQ(c, stmt, s->v.While.orelse);
 	compiler_use_next_block(c, end);
 
@@ -1579,10 +1588,10 @@
 static int
 compiler_try_finally(struct compiler *c, stmt_ty s)
 {
-	int body, end;
+	basicblock *body, *end;
 	body = compiler_new_block(c);
 	end = compiler_new_block(c);
-	if (body < 0 || end < 0)
+	if (body == NULL || end == NULL)
 		return 0;
 
 	ADDOP_JREL(c, SETUP_FINALLY, end);
@@ -1641,13 +1650,14 @@
 static int
 compiler_try_except(struct compiler *c, stmt_ty s)
 {
-	int i, n, body, orelse, except, end;
+        basicblock *body, *orelse, *except, *end;
+	int i, n;
 
 	body = compiler_new_block(c);
 	except = compiler_new_block(c);
 	orelse = compiler_new_block(c);
 	end = compiler_new_block(c);
-	if (body < 0 || except < 0 || orelse < 0 || end < 0)
+	if (body == NULL || except == NULL || orelse == NULL || end == NULL)
 		return 0;
 	ADDOP_JREL(c, SETUP_EXCEPT, except);
 	compiler_use_next_block(c, body);
@@ -1665,7 +1675,7 @@
 		if (!handler->type && i < n-1)
 		    return compiler_error(c, "default 'except:' must be last");
 		except = compiler_new_block(c);
-		if (except < 0)
+		if (except == NULL)
 			return 0;
 		if (handler->type) {
 			ADDOP(c, DUP_TOP);
@@ -1792,7 +1802,7 @@
 compiler_assert(struct compiler *c, stmt_ty s)
 {
 	static PyObject *assertion_error = NULL;
-	int end;
+	basicblock *end;
 
 	if (Py_OptimizeFlag)
 		return 1;
@@ -1803,7 +1813,7 @@
 	}
 	VISIT(c, expr, s->v.Assert.test);
 	end = compiler_new_block(c);
-	if (end < 0)
+	if (end == NULL)
 		return 0;
 	ADDOP_JREL(c, JUMP_IF_TRUE, end);
 	ADDOP(c, POP_TOP);
@@ -2167,7 +2177,8 @@
 static int
 compiler_boolop(struct compiler *c, expr_ty e)
 {
-	int end, jumpi, i, n;
+	basicblock *end;
+	int jumpi, i, n;
 	asdl_seq *s;
 
 	assert(e->kind == BoolOp_kind);
@@ -2221,7 +2232,8 @@
 static int
 compiler_compare(struct compiler *c, expr_ty e)
 {
-	int i, n, cleanup = -1;
+	int i, n;
+        basicblock *cleanup = NULL;
 
 	/* XXX the logic can be cleaned up for 1 or multiple comparisons */
 	VISIT(c, expr, e->v.Compare.left);
@@ -2229,6 +2241,8 @@
 	assert(n > 0);
 	if (n > 1) {
 		cleanup = compiler_new_block(c);
+                if (cleanup == NULL)
+                    return 0;
 		VISIT(c, expr, asdl_seq_GET(e->v.Compare.comparators, 0));
 	}
 	for (i = 1; i < n; i++) {
@@ -2248,7 +2262,9 @@
 		/* XXX We're casting a void* to cmpop_ty in the next stmt. */
 	       cmpop((cmpop_ty)asdl_seq_GET(e->v.Compare.ops, n - 1)));
 	if (n > 1) {
-		int end = compiler_new_block(c);
+		basicblock *end = compiler_new_block(c);
+                if (end == NULL)
+                    return 0;
 		ADDOP_JREL(c, JUMP_FORWARD, end);
 		compiler_use_next_block(c, cleanup);
 		ADDOP(c, ROT_TWO);
@@ -2304,14 +2320,16 @@
 	   and then write to the element */
 
 	comprehension_ty l;
-	int start, anchor, skip, if_cleanup, i, n;
+	basicblock *start, *anchor, *skip, *if_cleanup;
+        int i, n;
 
 	start = compiler_new_block(c);
 	skip = compiler_new_block(c);
 	if_cleanup = compiler_new_block(c);
 	anchor = compiler_new_block(c);
 
-        if (start < 0 || skip < 0 || if_cleanup < 0 || anchor < 0)
+        if (start == NULL || skip == NULL || if_cleanup == NULL ||
+                anchor == NULL)
             return 0;
 
 	l = asdl_seq_GET(generators, gen_index);
@@ -2585,7 +2603,7 @@
 }
 
 static int
-compiler_push_fblock(struct compiler *c, enum fblocktype t, int b)
+compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
 {
 	struct fblockinfo *f;
 	if (c->u->u_nfblocks >= CO_MAXBLOCKS)
@@ -2597,7 +2615,7 @@
 }
 
 static void
-compiler_pop_fblock(struct compiler *c, enum fblocktype t, int b)
+compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
 {
 	struct compiler_unit *u = c->u;
 	assert(u->u_nfblocks > 0);
@@ -2809,40 +2827,34 @@
 */
 
 static void
-dfs(struct compiler *c, int block, struct assembler *a)
+dfs(struct compiler *c, basicblock *b, struct assembler *a)
 {
 	int i;
-	struct basicblock *b;
 	struct instr *instr = NULL;
 
-	if (block >= c->u->u_nblocks)
-		return;
-	b = c->u->u_blocks[block];
 	if (b->b_seen)
 		return;
 	b->b_seen = 1;
-	if (b->b_next)
+	if (b->b_next != NULL)
 		dfs(c, b->b_next, a);
 	for (i = 0; i < b->b_iused; i++) {
 		instr = &b->b_instr[i];
 		if (instr->i_jrel || instr->i_jabs)
 			dfs(c, instr->i_target, a);
 	}
-	a->a_postorder[a->a_nblocks++] = block;
+	a->a_postorder[a->a_nblocks++] = b;
 }
 
 int
-stackdepth_walk(struct compiler *c, int block, int depth, int maxdepth)
+stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
 {
 	int i;
 	struct instr *instr;
-	struct basicblock *b;
-	b = c->u->u_blocks[block];
 	if (b->b_seen || b->b_startdepth >= depth)
 		return maxdepth;
 	b->b_seen = 1;
 	b->b_startdepth = depth;
-	fprintf(stderr, "block %d\n", block);
+	fprintf(stderr, "block %p\n", b);
 	for (i = 0; i < b->b_iused; i++) {
 		instr = &b->b_instr[i];
 		depth += opcode_stack_effect(instr->i_opcode, instr->i_oparg);
@@ -2879,7 +2891,7 @@
 		c->u->u_blocks[i]->b_seen = 0;
 		c->u->u_blocks[i]->b_startdepth = INT_MIN;
 	}
-	return stackdepth_walk(c, 0, 0, 0);
+	return stackdepth_walk(c, c->u->u_blocks[0], 0, 0);
 }
 
 static int
@@ -2893,7 +2905,8 @@
 	a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
 	if (!a->a_lnotab)
 		return 0;
-	a->a_postorder = (int *)PyObject_Malloc(sizeof(int) * nblocks);
+	a->a_postorder = (basicblock **)PyObject_Malloc(
+                                            sizeof(basicblock *) * nblocks);
 	if (!a->a_postorder)
 		return 0;
 	return 1;
@@ -2923,7 +2936,7 @@
 }
 
 static int
-blocksize(struct basicblock *b)
+blocksize(basicblock *b)
 {
 	int i;
 	int size = 0;
@@ -3121,28 +3134,21 @@
 static int
 assemble_jump_offsets(struct assembler *a, struct compiler *c)
 {
-	int *blockoff;
 	int bsize, totsize = 0;
 	int i, j;
 
 	/* Compute the size of each block and fixup jump args.
-	   Replace block index with position in bytecode. */
-	blockoff = malloc(sizeof(int) * c->u->u_nblocks);
-	if (!blockoff)
-		return 0;
-	/* blockoff computed in dfs postorder, but stored using
-	   c_blocks[] indices.
-	*/
+	   Replace block pointer with position in bytecode. */
 	assert(a->a_nblocks <= c->u->u_nblocks);
 	for (i = a->a_nblocks - 1; i >= 0; i--) {
-		int block = a->a_postorder[i];
-		bsize = blocksize(c->u->u_blocks[block]);
-		blockoff[block] = totsize;
+		basicblock *b = a->a_postorder[i];
+		bsize = blocksize(b);
+		b->b_offset = totsize;
 		totsize += bsize;
 	}
 	for (i = 0; i < c->u->u_nblocks; i++) {
-		struct basicblock *b = c->u->u_blocks[i];
-		bsize = blockoff[i];
+		basicblock *b = c->u->u_blocks[i];
+		bsize = b->b_offset;
 		for (j = 0; j < b->b_iused; j++) {
 			struct instr *instr = &b->b_instr[j];
 			/* Relative jumps are computed relative to
@@ -3151,15 +3157,13 @@
 			*/
 			bsize += instrsize(instr);
 			if (instr->i_jabs)
-				instr->i_oparg = blockoff[instr->i_target];
+				instr->i_oparg = instr->i_target->b_offset;
 			else if (instr->i_jrel) {
-				int delta = blockoff[instr->i_target] - bsize;
+				int delta = instr->i_target->b_offset - bsize;
 				instr->i_oparg = delta;
 			}
 		}
 	}
-	free(blockoff);
-
 	return 1;
 }
 
@@ -3289,7 +3293,7 @@
 
 	if (!assemble_init(&a, c->u->u_nblocks))
 		goto error;
-	dfs(c, 0, &a);
+	dfs(c, c->u->u_blocks[0], &a);
 
 	/* Can't modify the bytecode after computing jump offsets. */
 	if (!assemble_jump_offsets(&a, c))
@@ -3297,10 +3301,10 @@
 
 	/* Emit code in reverse postorder from dfs. */
 	for (i = a.a_nblocks - 1; i >= 0; i--) {
-		struct basicblock *b = c->u->u_blocks[a.a_postorder[i]];
+		basicblock *b = a.a_postorder[i];
 		fprintf(stderr, 
-                        "\nblock %d: order=%d used=%d alloc=%d next=%d\n",
-			i, a.a_postorder[i], b->b_iused, b->b_ialloc,
+                        "\nblock %p: order=%d used=%d alloc=%d next=%p\n",
+			a.a_postorder[i], i, b->b_iused, b->b_ialloc,
 			b->b_next);
 		for (j = 0; j < b->b_iused; j++)
 			if (!assemble_emit(&a, &b->b_instr[j]))



More information about the Python-checkins mailing list