⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optim.p

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 P
📖 第 1 页 / 共 3 页
字号:
(*#@(#)optim.p	4.1	Ultrix	7/17/90 *)(**************************************************************************** *									    * *  Copyright (c) 1984 by						    * *  DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts.		    * *  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.							    * * 									    * *  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.		    * * 									    *$Header: optim.p,v 1.7 84/06/06 13:04:29 powell Exp $ ****************************************************************************)#include "globals.h"#include "const.h"#include "bexpr.h"#include "optim.h"#include "otree.h"#include "ocount.h"#include "builtin.h"const    NUMOPTEXP = 10000;var    optBlockLevel, optBlockCeiling, optBlockFloor : OptBlockLevel;    activeExprs : OptNode;	{ dummy root for all non-purged expressions }    allExprs : OptNode;		{ dummy root for all expressions }    generateUniqueId : integer;    { the following table is the map from ExprNodes to OptNodes }    { It is used ONLY to avoid recompilations during development }    idToOpt : array [0..NUMOPTEXP] of OptNode;    markItCount : integer;    addressUnit : cardinal;function ExprToOpt{(en : ExprNode) : OptNode};begin    if en = nil then begin	ExprToOpt := nil;    end else begin	ExprToOpt := idToOpt[en^.opt];    end;end;{ Set up new one expecting no matches }function NewOptNode(expr, parent : ExprNode) : OptNode;var    newOne : OptNode;begin    new(newOne);    newOne^.uniqueId := generateUniqueId;    if TraceOptim then begin	writeln('NewOptNode:',newOne^.uniqueId:1);    end;    expr^.opt := newOne^.uniqueId;	{ "backward pointer" }    idToOpt[expr^.opt] := newOne;    generateUniqueId := generateUniqueId + 1;    newOne^.nextClass := newOne;    newOne^.prevClass := newOne;    newOne^.nextCongruent := newOne;    newOne^.prevCongruent := newOne;    newOne^.rootCongruent := newOne;    newOne^.nextEqual := newOne;    newOne^.prevEqual := newOne;    newOne^.rootEqual := newOne;    newOne^.createLevel := optBlockLevel;    newOne^.markLevel := 0;    newOne^.joinMarkLevel := 0;    newOne^.marked := false;    newOne^.joinMark := false;    newOne^.purged := false;    newOne^.removed := false;    newOne^.expr := expr;    newOne^.parent := parent;    newOne^.tempNumber := NULLTEMP;    newOne^.usage := OUSEINDIVIDUAL;    newOne^.nonTrivial := false;    newOne^.eligible := false;    newOne^.address := false;    newOne^.containedNonTrivial := nil;    newOne^.tailRecursion := false;    newOne^.loopConsidered := false;    newOne^.neededCount := 1;    newOne^.referencedCount := 1;    newOne^.loopNest := optLoopNest;    newOne^.usedCount := 0;    newOne^.defineTime := 0;    AddToAllList(allExprs^.prevAll,newOne);    newOne^.nextActive := nil;    newOne^.prevActive := nil;    NewOptNode := newOne;end;procedure ResetOptimizer;var    ek : ExprKind;    token : Token;    i : integer;begin    for ek := EXPRBAD to EXPRCHECK do begin	cseRootExpr[ek] := nil;    end;    for token := TKENDOFFILE to TKNULL do begin	cseRootUnOp[token] := nil;	cseRootBinOp[token] := nil;    end;    new(activeExprs);    activeExprs^.nextActive := activeExprs;    activeExprs^.prevActive := activeExprs;    new(allExprs);    allExprs^.nextAll := allExprs;    allExprs^.prevAll := allExprs;    optTime := 1;end;procedure InitOptimizer;var    i : integer;begin    case target of	TARGETVAX : addressUnit := BYTESIZE;	TARGETTITAN : addressUnit := WORDSIZE;    end;    for i := 0 to NUMOPTEXP do begin	idToOpt[i] := nil;    end;    generateUniqueId := 1;    optLoopNest := 1;    ResetOptimizer;end;procedure OptJoin;var    ron, on : OptNode;begin    if TraceOpt then begin	writeln(output,'Join ',optBlockLevel:1);    end;    on := activeExprs^.nextActive;    markItCount := 0;    while on <> activeExprs do begin	if (on^.markLevel >= optBlockLevel) or		(on^.joinMarkLevel >= optBlockLevel)	then begin	    on^.marked := true;	    on^.markLevel := optBlockLevel;	    on^.joinMark := false;	    on^.joinMarkLevel := 0;	    if TraceMark then begin		write(output,'<+',on^.uniqueId:1,'>');		markItCount := markItCount + 1;		if markItCount > 20 then begin		    writeln(output);		    markItCount := 0;		end;	    end;	end;	on := on^.nextActive;    end;end;procedure OptRefresh;var    on, nextActive : OptNode;begin    if TraceOpt then begin	writeln(output,'Refresh ',optBlockLevel:1);    end;    markItCount := 0;    on := activeExprs^.nextActive;    while on <> activeExprs do begin	nextActive := on^.nextActive;	if on^.createLevel >= optBlockCeiling then begin	    { purge expression }	    on^.purged := true;	    RemoveFromActiveList(on);	    if TraceMark then begin		write(output,'<X',on^.uniqueId:1,'>');		markItCount := markItCount + 1;		if markItCount > 20 then begin		    writeln(output);		    markItCount := 0;		end;	    end;	end else if on^.markLevel >= optBlockCeiling then begin	    on^.joinMark := on^.joinMark or on^.marked;	    on^.joinMarkLevel := optBlockCeiling;	    on^.marked := false;	    on^.markLevel := 0;	    if TraceMark then begin		write(output,'<-',on^.uniqueId:1,'>');		markItCount := markItCount + 1;		if markItCount > 20 then begin		    writeln(output);		    markItCount := 0;		end;	    end;	end;	on := nextActive;    end;end;{ CopyExpr: duplicate the expression tree (including associated OptNodes)}{  Make the expressions be at the specified level }function CopyExpr(en : ExprNode; sol : SaveOptLevel; parent : ExprNode)	: ExprNode;var    on, eon, non, ron, search : OptNode;    nen, pen, npen : ExprNode;    npl : ExprList;    found : boolean;begin    nen := NewExprNode(en^.kind);    SameExprLine(nen,en);    nen^.exprType := en^.exprType;    nen^ := en^;	{ copy miscellaneous fields }    case en^.kind of	EXPRCONST :	nen^.exprConst := en^.exprConst;	EXPRVAR :	nen^.exprVar := en^.exprVar;	EXPRNAME,	EXPRSYM,	EXPRSET : ExprError(en,'CopyExpr: unexpected expr');	EXPRUNOP : begin	    nen^.opnd := CopyExpr(en^.opnd,sol,nen);	    nen^.exprUnOp := en^.exprUnOp;	end;	EXPRBINOP : begin	    nen^.opnd1 := CopyExpr(en^.opnd1,sol,nen);	    nen^.opnd2 := CopyExpr(en^.opnd2,sol,nen);	    nen^.exprBinOp := en^.exprBinOp;	    nen^.operType := en^.operType;	end;	EXPRSUBSCR : begin	    nen^.arr := CopyExpr(en^.arr,sol,nen);	    nen^.subsExpr := CopyExpr(en^.subsExpr,sol,nen);	    nen^.subsOffset := en^.subsOffset;	end;	EXPRDOT : begin	    nen^.rec := CopyExpr(en^.rec,sol,nen);	    nen^.fieldName := en^.fieldName;	    nen^.field := en^.field;	end;	EXPRDEREF : begin	    nen^.ptr := CopyExpr(en^.ptr,sol,nen);	    nen^.realPtr := en^.realPtr;	end;	EXPRFUNC : begin	    nen^.func := CopyExpr(en^.func,sol,nen);	    npl := AddToExprList(nil,nil);	    pen := en^.params^.first;	    while pen <> nil do begin		npen := CopyExpr(pen,sol,nen);		npl := AddToExprList(npl,npen);		pen := pen^.next;	    end;	    nen^.params := npl;	end;	EXPRVAL : begin	    nen^.exprVal := CopyExpr(en^.exprVal,sol,nen);	end;	EXPRCHECK : begin	    nen^.checkExpr := CopyExpr(en^.checkExpr,sol,nen);	end;    end;    on := ExprToOpt(en);    non := NewOptNode(nen,nil);    { make it look as if it were created outside the loop }    non^.createLevel := sol.level;    non^.address := on^.address;    non^.nonTrivial := on^.nonTrivial;    non^.containedNonTrivial := on^.containedNonTrivial;    non^.eligible := on^.eligible;    non^.parent := parent;    ron := on^.rootEqual;    if TraceOptim then begin	writeln(output,'CopyExpr: id=',on^.uniqueId:1,'/',	    ron^.uniqueId:1,' create=',ron^.createLevel:1,	    ' level=',sol.level:1);    end;    { search for an equal expression in the enclosing block }    search := ron^.rootCongruent;    found := false;    repeat	if (search^.rootEqual <> search) or search^.marked or search^.purged		or (search^.createLevel > sol.ceiling)		or (search^.createLevel < sol.floor)	then begin	    { not equal }	    search := search^.nextCongruent;	end else begin	    { equal }	    found := true;	end;    until found or (search = ron^.rootCongruent);    if found then begin	{ expression is already in outer block, make this another reference }	AddToEqualList(search,non);	if search <> ron then begin	    { Consolidate this equal list with the outer one }	    if TraceOptim then begin		writeln(output,'CopyExpr: adding to list');		PrintOptExpr(search);		PrintOptExpr(ron);		PrintOptExpr(non);	    end;	    { Add in counts from inner block expression }	    search^.neededCount := search^.neededCount + ron^.neededCount;	    search^.referencedCount := search^.referencedCount					    + ron^.referencedCount;	    { append the inner equal list to the outer one }	    { fix up root pointer }	    eon := ron;	    repeat		eon^.rootEqual := search;		eon := eon^.nextEqual;	    until eon = ron;	    { append lists }	    search^.prevEqual^.nextEqual := ron;	    ron^.prevEqual^.nextEqual := search;	    eon := search^.prevEqual;	    search^.prevEqual := ron^.prevEqual;	    ron^.prevEqual := eon;	end;    end else begin	{ expression is needed once by pre-evaluation }	non^.neededCount := ron^.neededCount + 1;	{ consider pre-evaluation another reference }	non^.referencedCount := ron^.referencedCount + 1;	{ make this be the root equal expression }	eon := ron;	repeat	    eon^.rootEqual := non;	    eon := eon^.nextEqual;	until eon = ron;	{ insert new OptNode in front of rootEqual }	non^.prevEqual := ron^.prevEqual;	non^.nextEqual := ron;	ron^.prevEqual^.nextEqual := non;	ron^.prevEqual := non;	AddToCongruentList(ron^.rootCongruent^.prevCongruent,non);    end;    CopyExpr := nen;end;procedure InductionExpr(indexen, patternen : ExprNode; var opnden : ExprNode;    sol : SaveOptLevel; opnd1 : boolean);var    newen, olden, otheren : ExprNode;    newon, opndon, otheron : OptNode;    time : OptTime;    constant : boolean;    constVal : cardinal;begin    opndon := ExprToOpt(opnden);    if opnd1 then begin	constant := (patternen^.opnd2^.kind = EXPRCONST)			and (opnden^.kind = EXPRCONST);	if constant then begin	    constVal := OrdOf(patternen^.opnd2^.exprConst);	end;    end else begin	constant := (patternen^.opnd1^.kind = EXPRCONST)			and (opnden^.kind = EXPRCONST);	if constant then begin	    constVal := OrdOf(patternen^.opnd1^.exprConst);	end;    end;    if constant then begin	case patternen^.exprBinOp of	    TKPLUS : constVal := constVal + OrdOf(opnden^.exprConst);	    TKMINUS : constVal := -constVal + OrdOf(opnden^.exprConst);	    TKASTERISK : constVal := constVal * OrdOf(opnden^.exprConst);	end;	ReduceNeededCounts(opndon,1);	opndon^.purged := true;	RemoveFromActiveList(opndon);	{ copy expression node so OptNodes will still be valid }	olden := NewExprNode(EXPRCONST);	olden^ := opnden^;	opnden^.kind := EXPRCONST;	opnden^.exprConst := CardinalConst(constVal);	opnden^.exprType := patternen^.exprType;	time := EnterExpr(opnden,nil,0);	opndon^.expr := olden;	opndon^.parent := nil;	{ expr is now detached }    end else begin	newen := NewExprNode(EXPRBINOP);	SameExprLine(newen,opnden);	newen^.exprBinOp := patternen^.exprBinOp;	newen^.exprType := patternen^.exprType;	newen^.operType := patternen^.operType;	if opnd1 then begin	    newen^.opnd2 := CopyExpr(patternen^.opnd2,sol,newen);	    otheren := patternen^.opnd2;	    newen^.opnd1 := opnden;	end else begin	    newen^.opnd1 := CopyExpr(patternen^.opnd1,sol,newen);	    otheren := patternen^.opnd1;	    newen^.opnd2 := opnden;	end;	otheron := ExprToOpt(otheren);	opndon^.parent := newen;	time := Latest(opndon^.rootCongruent^.defineTime,					otheron^.rootCongruent^.defineTime);	time := EnterExpr(newen,nil,time);	newon := ExprToOpt(newen);	newon^.createLevel := sol.level;	opnden := newen;    end;end;procedure AnalyzeForLoop{(ien : ExprNode; stn : StmtNode; sol : SaveOptLevel)};var    ion, on, opndon, pon, prooton, von, oon : OptNode;    pen, en, olden, ven : ExprNode;    possible : boolean;    opnd1 : boolean;    time : OptTime;    itercount : integer;beginitercount := 0;repeat    if TraceOptim then begin	if itercount > 0 then begin	    writeln(output,'**** One More Time');	end;	writeln(output,'AnalyzeForLoop');    end;    itercount := itercount + 1;    { index opt node }    ion := ExprToOpt(ien);    { parent rootEqual }    prooton := nil;    possible := true;    on := ion;    repeat	if on^.parent = nil then begin	    if TraceOptim then begin		writeln(output,'nil parent');		PrintOptExpr(on);	    end;	end else if on^.removed then begin	    if TraceOptim then begin		writeln(output,'removed');		PrintOptExpr(on);	    end;	end else begin	    { get assumed value expression }	    von := ExprToOpt(on^.parent);	    if von^.uniqueId < ion^.uniqueId then begin		{ expression created before loop }		if TraceOptim then begin		    writeln(output,'irrelevant');		    PrintOptExpr(von);		end;	    end else if (von^.expr^.kind <> EXPRVAL) or (von^.parent = nil)	    then begin		{ wrong kind of expression }		possible := false;	    end else begin		{ get candidate induction expression }		pon := ExprToOpt(von^.parent);		if prooton <> nil then begin		    if prooton <> pon^.rootCongruent then begin			{ two different uses }			possible := false;		    end else begin			{ another identical use }		    end;		end else if pon^.expr^.kind <> EXPRBINOP then begin		    { candidates must be bin op }		    possible := false;		end else if not (pon^.expr^.exprBinOp in			    [TKPLUS,TKASTERISK,TKMINUS])		then begin		    { only linear arithmetic operations are allowed }		    possible := false;		end else begin		    opnd1 := pon^.expr^.opnd1 = von^.expr;		    if opnd1 then begin			oon := ExprToOpt(pon^.expr^.opnd2);		    end else begin			oon := ExprToOpt(pon^.expr^.opnd1);		    end;		    possible := not oon^.marked and			(oon^.rootCongruent^.defineTime <= blockOptTime);		    if possible then begin			{ a winner! }			prooton := pon^.rootCongruent;		    end;		end;		if TraceOptim then begin		    if possible then begin			writeln(output,'potential ',pon^.rootCongruent^.defineTime:1,				':',blockOptTime:1)		    end else begin			writeln(output,'ruining ',pon^.rootCongruent^.defineTime:1,				':',blockOptTime:1)		    end;		    PrintOptExpr(pon);		end;	    end;	end;	on := on^.nextCongruent;    until not possible or (on = ion);    possible := possible and (prooton <> nil);    if possible then begin	opnd1 := false;	if prooton^.expr^.opnd1^.kind = EXPRVAL then begin	    if prooton^.expr^.opnd1^.exprVal^.kind = EXPRVAR then begin		opnd1 := ien^.exprVar = prooton^.expr^.opnd1^.exprVal^.exprVar;	    end;	end;	if not opnd1 then begin	    { make sure opnd2 fits }	    possible := false;	    if prooton^.expr^.opnd2^.kind = EXPRVAL then begin		if prooton^.expr^.opnd2^.exprVal^.kind = EXPRVAR then begin		    possible := ien^.exprVar =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -