qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

isel.c (14102B)


      1 #include "all.h"
      2 #include <limits.h>
      3 
      4 /* For x86_64, do the following:
      5  *
      6  * - check that constants are used only in
      7  *   places allowed
      8  * - ensure immediates always fit in 32b
      9  * - expose machine register contraints
     10  *   on instructions like division.
     11  * - implement fast locals (the streak of
     12  *   constant allocX in the first basic block)
     13  * - recognize complex addressing modes
     14  *
     15  * Invariant: the use counts that are used
     16  *            in sel() must be sound.  This
     17  *            is not so trivial, maybe the
     18  *            dce should be moved out...
     19  */
     20 
     21 typedef struct ANum ANum;
     22 
     23 struct ANum {
     24 	char n, l, r;
     25 	Ins *i;
     26 };
     27 
     28 static int amatch(Addr *, Ref, int, ANum *, Fn *);
     29 
     30 static int
     31 noimm(Ref r, Fn *fn)
     32 {
     33 	int64_t val;
     34 
     35 	if (rtype(r) != RCon)
     36 		return 0;
     37 	switch (fn->con[r.val].type) {
     38 	case CAddr:
     39 		/* we only support the 'small'
     40 		 * code model of the ABI, this
     41 		 * means that we can always
     42 		 * address data with 32bits
     43 		 */
     44 		return 0;
     45 	case CBits:
     46 		val = fn->con[r.val].bits.i;
     47 		return (val < INT32_MIN || val > INT32_MAX);
     48 	default:
     49 		die("invalid constant");
     50 	}
     51 }
     52 
     53 static int
     54 rslot(Ref r, Fn *fn)
     55 {
     56 	if (rtype(r) != RTmp)
     57 		return -1;
     58 	return fn->tmp[r.val].slot;
     59 }
     60 
     61 static void
     62 fixarg(Ref *r, int k, Ins *i, Fn *fn)
     63 {
     64 	char buf[32];
     65 	Addr a, *m;
     66 	Ref r0, r1;
     67 	int s, n, op;
     68 
     69 	r1 = r0 = *r;
     70 	s = rslot(r0, fn);
     71 	op = i ? i->op : Ocopy;
     72 	if (KBASE(k) == 1 && rtype(r0) == RCon) {
     73 		/* load floating points from memory
     74 		 * slots, they can't be used as
     75 		 * immediates
     76 		 */
     77 		r1 = MEM(fn->nmem);
     78 		vgrow(&fn->mem, ++fn->nmem);
     79 		memset(&a, 0, sizeof a);
     80 		a.offset.type = CAddr;
     81 		a.offset.local = 1;
     82 		n = gasstash(&fn->con[r0.val].bits, KWIDE(k) ? 8 : 4);
     83 		sprintf(buf, "fp%d", n);
     84 		a.offset.label = intern(buf);
     85 		fn->mem[fn->nmem-1] = a;
     86 	}
     87 	else if (op != Ocopy && k == Kl && noimm(r0, fn)) {
     88 		/* load constants that do not fit in
     89 		 * a 32bit signed integer into a
     90 		 * long temporary
     91 		 */
     92 		r1 = newtmp("isel", Kl, fn);
     93 		emit(Ocopy, Kl, r1, r0, R);
     94 	}
     95 	else if (s != -1) {
     96 		/* load fast locals' addresses into
     97 		 * temporaries right before the
     98 		 * instruction
     99 		 */
    100 		r1 = newtmp("isel", Kl, fn);
    101 		emit(Oaddr, Kl, r1, SLOT(s), R);
    102 	}
    103 	else if (!(isstore(op) && r == &i->arg[1])
    104 	&& !isload(op) && op != Ocall && rtype(r0) == RCon
    105 	&& fn->con[r0.val].type == CAddr) {
    106 		/* apple as does not support 32-bit
    107 		 * absolute addressing, use a rip-
    108 		 * relative leaq instead
    109 		 */
    110 		r1 = newtmp("isel", Kl, fn);
    111 		emit(Oaddr, Kl, r1, r0, R);
    112 	}
    113 	else if (rtype(r0) == RMem) {
    114 		/* eliminate memory operands of
    115 		 * the form $foo(%rip, ...)
    116 		 */
    117 		m = &fn->mem[r0.val];
    118 		if (req(m->base, R))
    119 		if (m->offset.type == CAddr) {
    120 			n = fn->ncon;
    121 			vgrow(&fn->con, ++fn->ncon);
    122 			fn->con[n] = m->offset;
    123 			m->offset.type = CUndef;
    124 			r0 = newtmp("isel", Kl, fn);
    125 			emit(Oaddr, Kl, r0, CON(n), R);
    126 			m->base = r0;
    127 		}
    128 	}
    129 	*r = r1;
    130 }
    131 
    132 static void
    133 seladdr(Ref *r, ANum *an, Fn *fn)
    134 {
    135 	Addr a;
    136 	Ref r0;
    137 
    138 	r0 = *r;
    139 	if (rtype(r0) == RTmp) {
    140 		memset(&a, 0, sizeof a);
    141 		if (!amatch(&a, r0, an[r0.val].n, an, fn))
    142 			return;
    143 		if (!req(a.base, R))
    144 		if (a.offset.type == CAddr) {
    145 			/* apple as does not support
    146 			 * $foo(%r0, %r1, M); try to
    147 			 * rewrite it or bail out if
    148 			 * impossible
    149 			 */
    150 			if (!req(a.index, R) || rtype(a.base) != RTmp)
    151 				return;
    152 			else {
    153 				a.index = a.base;
    154 				a.scale = 1;
    155 				a.base = R;
    156 			}
    157 		}
    158 		chuse(r0, -1, fn);
    159 		vgrow(&fn->mem, ++fn->nmem);
    160 		fn->mem[fn->nmem-1] = a;
    161 		chuse(a.base, +1, fn);
    162 		chuse(a.index, +1, fn);
    163 		*r = MEM(fn->nmem-1);
    164 	}
    165 }
    166 
    167 static int
    168 cmpswap(Ref arg[2], int op)
    169 {
    170 	switch (op) {
    171 	case NCmpI+Cflt:
    172 	case NCmpI+Cfle:
    173 		return 1;
    174 	case NCmpI+Cfgt:
    175 	case NCmpI+Cfge:
    176 		return 0;
    177 	}
    178 	return rtype(arg[0]) == RCon;
    179 }
    180 
    181 static void
    182 selcmp(Ref arg[2], int k, int swap, Fn *fn)
    183 {
    184 	Ref r;
    185 	Ins *icmp;
    186 
    187 	if (swap) {
    188 		r = arg[1];
    189 		arg[1] = arg[0];
    190 		arg[0] = r;
    191 	}
    192 	emit(Oxcmp, k, R, arg[1], arg[0]);
    193 	icmp = curi;
    194 	if (rtype(arg[0]) == RCon) {
    195 		assert(k != Kw);
    196 		icmp->arg[1] = newtmp("isel", k, fn);
    197 		emit(Ocopy, k, icmp->arg[1], arg[0], R);
    198 		fixarg(&curi->arg[0], k, curi, fn);
    199 	}
    200 	fixarg(&icmp->arg[0], k, icmp, fn);
    201 	fixarg(&icmp->arg[1], k, icmp, fn);
    202 }
    203 
    204 static void
    205 sel(Ins i, ANum *an, Fn *fn)
    206 {
    207 	Ref r0, r1;
    208 	int x, k, kc, swap;
    209 	int64_t sz;
    210 	Ins *i0, *i1;
    211 
    212 	if (rtype(i.to) == RTmp)
    213 	if (!isreg(i.to) && !isreg(i.arg[0]) && !isreg(i.arg[1]))
    214 	if (fn->tmp[i.to.val].nuse == 0) {
    215 		chuse(i.arg[0], -1, fn);
    216 		chuse(i.arg[1], -1, fn);
    217 		return;
    218 	}
    219 	i0 = curi;
    220 	k = i.cls;
    221 	switch (i.op) {
    222 	case Odiv:
    223 	case Orem:
    224 	case Oudiv:
    225 	case Ourem:
    226 		if (KBASE(k) == 1)
    227 			goto Emit;
    228 		if (i.op == Odiv || i.op == Oudiv)
    229 			r0 = TMP(RAX), r1 = TMP(RDX);
    230 		else
    231 			r0 = TMP(RDX), r1 = TMP(RAX);
    232 		emit(Ocopy, k, i.to, r0, R);
    233 		emit(Ocopy, k, R, r1, R);
    234 		if (rtype(i.arg[1]) == RCon) {
    235 			/* immediates not allowed for
    236 			 * divisions in x86
    237 			 */
    238 			r0 = newtmp("isel", k, fn);
    239 		} else
    240 			r0 = i.arg[1];
    241 		if (fn->tmp[r0.val].slot != -1)
    242 			err("unlikely argument %%%s in %s",
    243 				fn->tmp[r0.val].name, optab[i.op].name);
    244 		if (i.op == Odiv || i.op == Orem) {
    245 			emit(Oxidiv, k, R, r0, R);
    246 			emit(Osign, k, TMP(RDX), TMP(RAX), R);
    247 		} else {
    248 			emit(Oxdiv, k, R, r0, R);
    249 			emit(Ocopy, k, TMP(RDX), CON_Z, R);
    250 		}
    251 		emit(Ocopy, k, TMP(RAX), i.arg[0], R);
    252 		fixarg(&curi->arg[0], k, curi, fn);
    253 		if (rtype(i.arg[1]) == RCon)
    254 			emit(Ocopy, k, r0, i.arg[1], R);
    255 		break;
    256 	case Osar:
    257 	case Oshr:
    258 	case Oshl:
    259 		r0 = i.arg[1];
    260 		if (rtype(r0) == RCon)
    261 			goto Emit;
    262 		if (fn->tmp[r0.val].slot != -1)
    263 			err("unlikely argument %%%s in %s",
    264 				fn->tmp[r0.val].name, optab[i.op].name);
    265 		i.arg[1] = TMP(RCX);
    266 		emit(Ocopy, Kw, R, TMP(RCX), R);
    267 		emiti(i);
    268 		i1 = curi;
    269 		emit(Ocopy, Kw, TMP(RCX), r0, R);
    270 		fixarg(&i1->arg[0], argcls(&i, 0), i1, fn);
    271 		break;
    272 	case Onop:
    273 		break;
    274 	case Ostored:
    275 	case Ostores:
    276 	case Ostorel:
    277 	case Ostorew:
    278 	case Ostoreh:
    279 	case Ostoreb:
    280 		if (rtype(i.arg[0]) == RCon) {
    281 			if (i.op == Ostored)
    282 				i.op = Ostorel;
    283 			if (i.op == Ostores)
    284 				i.op = Ostorew;
    285 		}
    286 		seladdr(&i.arg[1], an, fn);
    287 		goto Emit;
    288 	case_Oload:
    289 		seladdr(&i.arg[0], an, fn);
    290 		goto Emit;
    291 	case Ocall:
    292 	case Osalloc:
    293 	case Ocopy:
    294 	case Oadd:
    295 	case Osub:
    296 	case Omul:
    297 	case Oand:
    298 	case Oor:
    299 	case Oxor:
    300 	case Oxtest:
    301 	case Ostosi:
    302 	case Odtosi:
    303 	case Oswtof:
    304 	case Osltof:
    305 	case Oexts:
    306 	case Otruncd:
    307 	case Ocast:
    308 	case_OExt:
    309 Emit:
    310 		emiti(i);
    311 		i1 = curi; /* fixarg() can change curi */
    312 		fixarg(&i1->arg[0], argcls(&i, 0), i1, fn);
    313 		fixarg(&i1->arg[1], argcls(&i, 1), i1, fn);
    314 		break;
    315 	case Oalloc:
    316 	case Oalloc+1:
    317 	case Oalloc+2: /* == Oalloc1 */
    318 		/* we need to make sure
    319 		 * the stack remains aligned
    320 		 * (rsp = 0) mod 16
    321 		 */
    322 		fn->dynalloc = 1;
    323 		if (rtype(i.arg[0]) == RCon) {
    324 			sz = fn->con[i.arg[0].val].bits.i;
    325 			if (sz < 0 || sz >= INT_MAX-15)
    326 				err("invalid alloc size %"PRId64, sz);
    327 			sz = (sz + 15)  & -16;
    328 			emit(Osalloc, Kl, i.to, getcon(sz, fn), R);
    329 		} else {
    330 			/* r0 = (i.arg[0] + 15) & -16 */
    331 			r0 = newtmp("isel", Kl, fn);
    332 			r1 = newtmp("isel", Kl, fn);
    333 			emit(Osalloc, Kl, i.to, r0, R);
    334 			emit(Oand, Kl, r0, r1, getcon(-16, fn));
    335 			emit(Oadd, Kl, r1, i.arg[0], getcon(15, fn));
    336 			if (fn->tmp[i.arg[0].val].slot != -1)
    337 				err("unlikely argument %%%s in %s",
    338 					fn->tmp[i.arg[0].val].name, optab[i.op].name);
    339 		}
    340 		break;
    341 	default:
    342 		if (isext(i.op))
    343 			goto case_OExt;
    344 		if (isload(i.op))
    345 			goto case_Oload;
    346 		if (iscmp(i.op, &kc, &x)) {
    347 			switch (x) {
    348 			case NCmpI+Cfeq:
    349 				/* zf is set when operands are
    350 				 * unordered, so we may have to
    351 				 * check pf
    352 				 */
    353 				r0 = newtmp("isel", Kw, fn);
    354 				r1 = newtmp("isel", Kw, fn);
    355 				emit(Oand, Kw, i.to, r0, r1);
    356 				emit(Oflagfo, k, r1, R, R);
    357 				i.to = r0;
    358 				break;
    359 			case NCmpI+Cfne:
    360 				r0 = newtmp("isel", Kw, fn);
    361 				r1 = newtmp("isel", Kw, fn);
    362 				emit(Oor, Kw, i.to, r0, r1);
    363 				emit(Oflagfuo, k, r1, R, R);
    364 				i.to = r0;
    365 				break;
    366 			}
    367 			swap = cmpswap(i.arg, x);
    368 			if (swap)
    369 				x = cmpop(x);
    370 			emit(Oflag+x, k, i.to, R, R);
    371 			selcmp(i.arg, kc, swap, fn);
    372 			break;
    373 		}
    374 		die("unknown instruction %s", optab[i.op].name);
    375 	}
    376 
    377 	while (i0>curi && --i0) {
    378 		assert(rslot(i0->arg[0], fn) == -1);
    379 		assert(rslot(i0->arg[1], fn) == -1);
    380 	}
    381 }
    382 
    383 static Ins *
    384 flagi(Ins *i0, Ins *i)
    385 {
    386 	while (i>i0) {
    387 		i--;
    388 		if (amd64_op[i->op].zflag)
    389 			return i;
    390 		if (amd64_op[i->op].lflag)
    391 			continue;
    392 		return 0;
    393 	}
    394 	return 0;
    395 }
    396 
    397 static void
    398 seljmp(Blk *b, Fn *fn)
    399 {
    400 	Ref r;
    401 	int c, k, swap;
    402 	Ins *fi;
    403 	Tmp *t;
    404 
    405 	if (b->jmp.type == Jret0 || b->jmp.type == Jjmp)
    406 		return;
    407 	assert(b->jmp.type == Jjnz);
    408 	r = b->jmp.arg;
    409 	t = &fn->tmp[r.val];
    410 	b->jmp.arg = R;
    411 	assert(rtype(r) == RTmp);
    412 	if (b->s1 == b->s2) {
    413 		chuse(r, -1, fn);
    414 		b->jmp.type = Jjmp;
    415 		b->s2 = 0;
    416 		return;
    417 	}
    418 	fi = flagi(b->ins, &b->ins[b->nins]);
    419 	if (!fi || !req(fi->to, r)) {
    420 		selcmp((Ref[2]){r, CON_Z}, Kw, 0, fn); /* todo, long jnz */
    421 		b->jmp.type = Jjf + Cine;
    422 	}
    423 	else if (iscmp(fi->op, &k, &c)
    424 	     && c != NCmpI+Cfeq /* see sel() */
    425 	     && c != NCmpI+Cfne) {
    426 		swap = cmpswap(fi->arg, c);
    427 		if (swap)
    428 			c = cmpop(c);
    429 		if (t->nuse == 1) {
    430 			selcmp(fi->arg, k, swap, fn);
    431 			*fi = (Ins){.op = Onop};
    432 		}
    433 		b->jmp.type = Jjf + c;
    434 	}
    435 	else if (fi->op == Oand && t->nuse == 1
    436 	     && (rtype(fi->arg[0]) == RTmp ||
    437 	         rtype(fi->arg[1]) == RTmp)) {
    438 		fi->op = Oxtest;
    439 		fi->to = R;
    440 		b->jmp.type = Jjf + Cine;
    441 		if (rtype(fi->arg[1]) == RCon) {
    442 			r = fi->arg[1];
    443 			fi->arg[1] = fi->arg[0];
    444 			fi->arg[0] = r;
    445 		}
    446 	}
    447 	else {
    448 		/* since flags are not tracked in liveness,
    449 		 * the result of the flag-setting instruction
    450 		 * has to be marked as live
    451 		 */
    452 		if (t->nuse == 1)
    453 			emit(Ocopy, Kw, R, r, R);
    454 		b->jmp.type = Jjf + Cine;
    455 	}
    456 }
    457 
    458 static int
    459 aref(Ref r, ANum *ai)
    460 {
    461 	switch (rtype(r)) {
    462 	case RCon:
    463 		return 2;
    464 	case RTmp:
    465 		return ai[r.val].n;
    466 	default:
    467 		die("constant or temporary expected");
    468 	}
    469 }
    470 
    471 static int
    472 ascale(Ref r, Con *con)
    473 {
    474 	int64_t n;
    475 
    476 	if (rtype(r) != RCon)
    477 		return 0;
    478 	if (con[r.val].type != CBits)
    479 		return 0;
    480 	n = con[r.val].bits.i;
    481 	return n == 1 || n == 2 || n == 4 || n == 8;
    482 }
    483 
    484 static void
    485 anumber(ANum *ai, Blk *b, Con *con)
    486 {
    487 	/* This should be made obsolete by a proper
    488 	 * reassoc pass.
    489 	 *
    490 	 * Rules:
    491 	 *
    492 	 *   RTmp(_) -> 0    tmp
    493 	 *   ( RTmp(_) -> 1    slot )
    494 	 *   RCon(_) -> 2    con
    495 	 *   0 * 2   -> 3    s * i (when constant is 1,2,4,8)
    496 	 */
    497 	static char add[10][10] = {
    498 		[2] [2] = 2,              /* folding */
    499 		[2] [4] = 4, [4] [2] = 4,
    500 		[2] [6] = 6, [6] [2] = 6,
    501 		[2] [7] = 7, [7] [2] = 7,
    502 		[0] [2] = 4, [2] [0] = 4, /* 4: o + b */
    503 		[0] [0] = 5,              /* 5: b + s * i */
    504 		[0] [3] = 5, [3] [0] = 5,
    505 		[2] [3] = 6, [3] [2] = 6, /* 6: o + s * i */
    506 		[2] [5] = 7, [5] [2] = 7, /* 7: o + b + s * i */
    507 		[0] [6] = 7, [6] [0] = 7,
    508 		[4] [3] = 7, [3] [4] = 7,
    509 	};
    510 	int a, a1, a2, n1, n2, t1, t2;
    511 	Ins *i;
    512 
    513 	for (i=b->ins; i<&b->ins[b->nins]; i++) {
    514 		if (rtype(i->to) == RTmp)
    515 			ai[i->to.val].i = i;
    516 		if (i->op != Oadd && i->op != Omul)
    517 			continue;
    518 		a1 = aref(i->arg[0], ai);
    519 		a2 = aref(i->arg[1], ai);
    520 		t1 = a1 != 1 && a1 != 2;
    521 		t2 = a2 != 1 && a2 != 2;
    522 		if (i->op == Oadd) {
    523 			a = add[n1 = a1][n2 = a2];
    524 			if (t1 && a < add[0][a2])
    525 				a = add[n1 = 0][n2 = a2];
    526 			if (t2 && a < add[a1][0])
    527 				a = add[n1 = a1][n2 = 0];
    528 			if (t1 && t2 && a < add[0][0])
    529 				a = add[n1 = 0][n2 = 0];
    530 		} else {
    531 			n1 = n2 = a = 0;
    532 			if (ascale(i->arg[0], con) && t2)
    533 				a = 3, n1 = 2, n2 = 0;
    534 			if (t1 && ascale(i->arg[1], con))
    535 				a = 3, n1 = 0, n2 = 2;
    536 		}
    537 		ai[i->to.val].n = a;
    538 		ai[i->to.val].l = n1;
    539 		ai[i->to.val].r = n2;
    540 	}
    541 }
    542 
    543 static int
    544 amatch(Addr *a, Ref r, int n, ANum *ai, Fn *fn)
    545 {
    546 	Ins *i;
    547 	int nl, nr, t, s;
    548 	Ref al, ar;
    549 
    550 	if (rtype(r) == RCon) {
    551 		if (!addcon(&a->offset, &fn->con[r.val]))
    552 			err("unlikely sum of $%s and $%s",
    553 				str(a->offset.label), str(fn->con[r.val].label));
    554 		return 1;
    555 	}
    556 	assert(rtype(r) == RTmp);
    557 	i = ai[r.val].i;
    558 	nl = ai[r.val].l;
    559 	nr = ai[r.val].r;
    560 	if (i) {
    561 		if (nl > nr) {
    562 			al = i->arg[1];
    563 			ar = i->arg[0];
    564 			t = nl, nl = nr, nr = t;
    565 		} else {
    566 			al = i->arg[0];
    567 			ar = i->arg[1];
    568 		}
    569 	}
    570 	switch (n) {
    571 	case 3: /* s * i */
    572 		a->index = al;
    573 		a->scale = fn->con[ar.val].bits.i;
    574 		return 0;
    575 	case 5: /* b + s * i */
    576 		switch (nr) {
    577 		case 0:
    578 			if (fn->tmp[ar.val].slot != -1) {
    579 				al = i->arg[1];
    580 				ar = i->arg[0];
    581 			}
    582 			a->index = ar;
    583 			a->scale = 1;
    584 			break;
    585 		case 3:
    586 			amatch(a, ar, nr, ai, fn);
    587 			break;
    588 		}
    589 		r = al;
    590 		/* fall through */
    591 	case 0:
    592 		s = fn->tmp[r.val].slot;
    593 		if (s != -1)
    594 			r = SLOT(s);
    595 		a->base = r;
    596 		return n || s != -1;
    597 	case 2: /* constants */
    598 	case 4: /* o + b */
    599 	case 6: /* o + s * i */
    600 	case 7: /* o + b + s * i */
    601 		amatch(a, ar, nr, ai, fn);
    602 		amatch(a, al, nl, ai, fn);
    603 		return 1;
    604 	default:
    605 		die("unreachable");
    606 	}
    607 }
    608 
    609 /* instruction selection
    610  * requires use counts (as given by parsing)
    611  */
    612 void
    613 amd64_isel(Fn *fn)
    614 {
    615 	Blk *b, **sb;
    616 	Ins *i;
    617 	Phi *p;
    618 	uint a;
    619 	int n, al;
    620 	int64_t sz;
    621 	ANum *ainfo;
    622 
    623 	/* assign slots to fast allocs */
    624 	b = fn->start;
    625 	/* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
    626 	for (al=Oalloc, n=4; al<=Oalloc1; al++, n*=2)
    627 		for (i=b->ins; i<&b->ins[b->nins]; i++)
    628 			if (i->op == al) {
    629 				if (rtype(i->arg[0]) != RCon)
    630 					break;
    631 				sz = fn->con[i->arg[0].val].bits.i;
    632 				if (sz < 0 || sz >= INT_MAX-15)
    633 					err("invalid alloc size %"PRId64, sz);
    634 				sz = (sz + n-1) & -n;
    635 				sz /= 4;
    636 				if (sz > INT_MAX - fn->slot)
    637 					die("alloc too large");
    638 				fn->tmp[i->to.val].slot = fn->slot;
    639 				fn->slot += sz;
    640 				*i = (Ins){.op = Onop};
    641 			}
    642 
    643 	/* process basic blocks */
    644 	n = fn->ntmp;
    645 	ainfo = emalloc(n * sizeof ainfo[0]);
    646 	for (b=fn->start; b; b=b->link) {
    647 		curi = &insb[NIns];
    648 		for (sb=(Blk*[3]){b->s1, b->s2, 0}; *sb; sb++)
    649 			for (p=(*sb)->phi; p; p=p->link) {
    650 				for (a=0; p->blk[a] != b; a++)
    651 					assert(a+1 < p->narg);
    652 				fixarg(&p->arg[a], p->cls, 0, fn);
    653 			}
    654 		memset(ainfo, 0, n * sizeof ainfo[0]);
    655 		anumber(ainfo, b, fn->con);
    656 		seljmp(b, fn);
    657 		for (i=&b->ins[b->nins]; i!=b->ins;)
    658 			sel(*--i, ainfo, fn);
    659 		b->nins = &insb[NIns] - curi;
    660 		idup(&b->ins, curi, b->nins);
    661 	}
    662 	free(ainfo);
    663 
    664 	if (debug['I']) {
    665 		fprintf(stderr, "\n> After instruction selection:\n");
    666 		printfn(fn, stderr);
    667 	}
    668 }