optim.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 845 行 · 第 1/2 页
C
845 行
#ifndef lintstatic char *sccsid = " @(#)optim.c 1.3 (ULTRIX) 1/15/86";#endif lint/************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************** Modification History** David Metsky 14-Jan-86** 001 Replaced old version with BSD 4.3 version as part of upgrade.** Based on: optim.c 5.2 6/9/85**************************************************************************//* * optim.c * * Miscellaneous optimizer routines, f77 compiler pass 1. * * UCSD Chemistry modification history: * * $Log: optim.c,v $ * Revision 2.12 85/06/08 22:57:01 donn * Prevent core dumps -- bug in optinsert was causing lastslot to be wrong * when a slot was inserted at the end of the buffer. * * Revision 2.11 85/03/18 08:05:05 donn * Prevent warnings about implicit conversions. * * Revision 2.10 85/02/12 20:13:00 donn * Resurrected the hack in 2.6.1.1 to avoid creating a temporary when * there is a concatenation on the rhs of an assignment, and threw out * all the code dealing with starcat(). It seems that we can't use a * temporary because the lhs as well as the rhs may have nonconstant length. * * Revision 2.9 85/01/18 00:53:52 donn * Missed a call to free() in the last change... * * Revision 2.8 85/01/18 00:50:03 donn * Fixed goof made when modifying buffmnmx() to explicitly call expand(). * * Revision 2.7 85/01/15 18:47:35 donn * Changes to allow character*(*) variables to appear in concatenations in * the rhs of an assignment statement. * * Revision 2.6 84/12/16 21:46:27 donn * Fixed bug that prevented concatenations from being run together. Changed * buffpower() to not touch exponents greater than 64 -- let putpower do them. * * Revision 2.5 84/10/29 08:41:45 donn * Added hack to flushopt() to prevent the compiler from trying to generate * intermediate code after an error. * * Revision 2.4 84/08/07 21:28:00 donn * Removed call to p2flush() in putopt() -- this allows us to make better use * of the buffering on the intermediate code file. * * Revision 2.3 84/08/01 16:06:24 donn * Forced expand() to expand subscripts. * * Revision 2.2 84/07/19 20:21:55 donn * Decided I liked the expression tree algorithm after all. The algorithm * which repeatedly squares temporaries is now checked in as rev. 2.1. * * Revision 1.3.1.1 84/07/10 14:18:18 donn * I'm taking this branch off the trunk -- it works but it's not as good as * the old version would be if it worked right. * * Revision 1.5 84/07/09 22:28:50 donn * Added fix to buffpower() to prevent it chasing after huge exponents. * * Revision 1.4 84/07/09 20:13:59 donn * Replaced buffpower() routine with a new one that generates trees which can * be handled by CSE later on. * * Revision 1.3 84/05/04 21:02:07 donn * Added fix for a bug in buffpower() that caused func(x)**2 to turn into * func(x) * func(x). This bug had already been fixed in putpower()... * * Revision 1.2 84/03/23 22:47:21 donn * The subroutine argument temporary fixes from Bob Corbett didn't take into * account the fact that the code generator collects all the assignments to * temporaries at the start of a statement -- hence the temporaries need to * be initialized once per statement instead of once per call. * */#include "defs.h"#include "optim.h"/* * Information buffered for each slot type * * slot type expptr integer pointer * * IFN expr label - * GOTO - label - * LABEL - label - * EQ expr - - * CALL expr - - * CMGOTO expr num labellist* * STOP expr - - * DOHEAD [1] - ctlframe* * ENDDO [1] - ctlframe* * ARIF expr - labellist* * RETURN expr label - * ASGOTO expr - labellist* * PAUSE expr - - * ASSIGN expr label - * SKIOIFN expr label - * SKFRTEMP expr - - * * Note [1]: the nullslot field is a pointer to a fake slot which is * at the end of the slots which may be replaced by this slot. In * other words, it looks like this: * DOHEAD slot * slot \ * slot > ordinary IF, GOTO, LABEL slots which implement the DO * slot / * NULL slot */expptr expand();Slotp firstslot = NULL;Slotp lastslot = NULL;int numslots = 0;/* * turns off optimization option */optoff(){flushopt();optimflag = 0;}/* * initializes the code buffer for optimization */setopt(){register Slotp sp;for (sp = firstslot; sp; sp = sp->next) free ( (charptr) sp);firstslot = lastslot = NULL;numslots = 0;}/* * flushes the code buffer */LOCAL int alreadycalled = 0;flushopt(){register Slotp sp;int savelineno;if (alreadycalled) return; /* to prevent recursive call during errors */alreadycalled = 1;if (debugflag[1]) showbuffer ();frtempbuff ();savelineno = lineno;for (sp = firstslot; sp; sp = sp->next) { if (nerr == 0) putopt (sp); else frexpr (sp->expr); if(sp->ctlinfo) free ( (charptr) sp->ctlinfo); free ( (charptr) sp); numslots--; }firstslot = lastslot = NULL;numslots = 0;clearbb();lineno = savelineno;alreadycalled = 0;}/* * puts out code for the given slot (from the code buffer) */LOCAL putopt (sp)register Slotp sp;{ lineno = sp->lineno; switch (sp->type) { case SKNULL: break; case SKIFN: case SKIOIFN: putif(sp->expr, sp->label); break; case SKGOTO: putgoto(sp->label); break; case SKCMGOTO: putcmgo(sp->expr, sp->label, sp->ctlinfo); break; case SKCALL: putexpr(sp->expr); break; case SKSTOP: putexpr (call1 (TYSUBR, "s_stop", sp->expr)); break; case SKPAUSE: putexpr (call1 (TYSUBR, "s_paus", sp->expr)); break; case SKASSIGN: puteq (sp->expr, intrconv(sp->expr->headblock.vtype, mkaddcon(sp->label))); break; case SKDOHEAD: case SKENDDO: break; case SKEQ: putexpr(sp->expr); break; case SKARIF:#define LM ((struct Labelblock * *)sp->ctlinfo)[0]->labelno #define LZ ((struct Labelblock * *)sp->ctlinfo)[1]->labelno #define LP ((struct Labelblock * *)sp->ctlinfo)[2]->labelno prarif(sp->expr, LM, LZ, LP); break; case SKASGOTO: putbranch((Addrp) sp->expr); break; case SKLABEL: putlabel(sp->label); break; case SKRETURN: if (sp->expr) { putforce(TYINT, sp->expr); putgoto(sp->label); } else putgoto(sp->label); break; case SKFRTEMP: templist = mkchain (sp->expr,templist); break; default: badthing("SKtype", "putopt", sp->type); break; } /* * Recycle argument temporaries here. This must get done on a * statement-by-statement basis because the code generator * makes side effects happen at the start of a statement. */ argtemplist = hookup(argtemplist, activearglist); activearglist = CHNULL;}/* * copies one element of the control stack */LOCAL struct Ctlframe *cpframe(p)register char *p;{static int size = sizeof (struct Ctlframe);register int n;register char *q;struct Ctlframe *q0;q0 = ALLOC(Ctlframe);q = (char *) q0;n = size;while(n-- > 0) *q++ = *p++;return( q0);}/* * copies an array of labelblock pointers */LOCAL struct Labelblock **cplabarr(n,arr)struct Labelblock *arr[];int n;{struct Labelblock **newarr;register char *in, *out;register int i,j;newarr = (struct Labelblock **) ckalloc (n * sizeof (char *));for (i = 0; i < n; i++) { newarr[i] = ALLOC (Labelblock); out = (char *) newarr[i]; in = (char *) arr[i]; j = sizeof (struct Labelblock); while (j-- > 0) *out++ = *in++; }return (newarr);}/* * creates a new slot in the code buffer */LOCAL Slotp newslot(){register Slotp sp;++numslots;sp = ALLOC( slt );sp->next = NULL ;if (lastslot) { sp->prev = lastslot; lastslot = lastslot->next = sp; }else { firstslot = lastslot = sp; sp->prev = NULL; }sp->lineno = lineno;return (sp);}/* * removes (but not deletes) the specified slot from the code buffer */removeslot (sl)Slotp sl;{if (sl->next) sl->next->prev = sl->prev;else lastslot = sl->prev;if (sl->prev) sl->prev->next = sl->next;else firstslot = sl->next;sl->next = sl->prev = NULL;--numslots;}/* * inserts slot s1 before existing slot s2 in the code buffer; * appends to end of list if s2 is NULL. */insertslot (s1,s2)Slotp s1,s2;{if (s2) { if (s2->prev)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?