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

📄 optim.p

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 P
📖 第 1 页 / 共 3 页
字号:
			    prooton^.expr^.opnd2^.exprVal^.exprVar;		end;	    end;	    if not possible then begin		ExprError(prooton^.expr,'AnalyzeForLoop: not opnd1 or opnd2?');		PrintOptExpr(prooton);	    end;	end;    end;    if possible then begin	if TraceOptim then begin	    writeln(output,'AnalyzeForLoop: found induction expression');	    PrintOptExpr(prooton);	end;	{ 	    create a parent expression node	    CopyExpr the non-index operand (of the binop) to outside the loop	    add the forFrom expression as the other operand	    EnterExpr the new parent expression	    assign the new expr as the forFrom	    repeat the above for the forTo expression	    if the binop is *, repeat the above for the forBy expression	    For each induction variable expression		ReduceCounts on expression (will not be evaluated)		Purge OptNode		set expr and parent pointers to nil.		    (must leave around because it might be rootCongruent)		set expr^.kind to EXPRVAR, expr^.exprVar to indexVar		EnterExpr new parent expression (parent pointer in old OptNode)	}	pen := prooton^.expr;	{ change expression type of variable to match expression }	ien^.exprType := pen^.exprType;	InductionExpr(ien,pen,stn^.forFrom,sol,opnd1);	InductionExpr(ien,pen,stn^.forTo,sol,opnd1);	if pen^.exprBinOp = TKASTERISK then begin	    InductionExpr(ien,pen,stn^.forBy,sol,opnd1);	    { make index operation be expression type }	    stn^.forIndexType := pen^.exprType;	end;	if TraceOptim then begin	    write(output,'from ');	    WriteExpr(output,stn^.forFrom);	    write(output,' to ');	    WriteExpr(output,stn^.forTo);	    write(output,' by ');	    WriteExpr(output,stn^.forBy);	    writeln(output);	end;	on := prooton;	repeat	    if on^.uniqueId >= ion^.uniqueId then begin		{ find expressions for this loop only }		ReduceNeededCounts(on,1);		on^.purged := true;		RemoveFromActiveList(on);		if opnd1 then begin		    opndon := ExprToOpt(on^.expr^.opnd1);		end else begin		    opndon := ExprToOpt(on^.expr^.opnd2);		end;		opndon^.removed := true;		en := on^.expr;	{ induction expression }		{ copy expression node so OptNodes will still be valid }		olden := NewExprNode(EXPRBINOP);		olden^ := en^;		{ replace en with value var index }		en^.kind := EXPRVAL;		ven := NewExprNode(EXPRVAR);		SameExprLine(ven,en);		en^.exprVal := ven;		ven^.exprVar := ien^.exprVar;		time := EnterExpr(ven,en,0);		time := EnterExpr(en,on^.parent,0);		on^.expr := olden;		on^.parent := nil;	{ expr is now detached }	    end;	    on := on^.nextCongruent;	until on = prooton;    end;until not possible;end;function ConsiderMove(on : OptNode; var preEval : ExprList; sol : SaveOptLevel)	: boolean;var    pon : OptNode;    didit : boolean;    en, ien : ExprNode;begin    didit := false;    if OptNloop or on^.loopConsidered then begin	{ do nothing }    end else begin	if not on^.marked	    and (on^.nonTrivial or (on^.containedNonTrivial <> nil))	    and (on^.rootCongruent^.defineTime < blockOptTime)	    and (on^.createLevel >= optBlockCeiling)	then begin	    { candidates for moving out are not marked, non-trivial, }	    {  depend only on things outside the loop, }	    {  and were calculated in this block }	    { check parent first }	    if on^.parent <> nil then begin		pon := ExprToOpt(on^.parent);		didit := ConsiderMove(pon,preEval,sol);	    end;	    if not didit then begin		if TraceActions then begin		    writeln(output,'Move out of loop ',blockOptTime:1);		    PrintOptExpr(on);		end;		en := on^.expr;		ien := CopyExpr(en,sol,nil);		{ expression should be preserved through whole block }		on^.rootEqual^.neededCount := on^.rootEqual^.neededCount + 1;		on^.rootEqual^.eligible := true;		preEval := AddToExprList(preEval,ien);	    end;	end;	on^.loopConsidered := true;    end;    ConsiderMove := didit;end;procedure OptFinishLoop(var preEval : ExprList; sol : SaveOptLevel);var    on, prevActive : OptNode;begin    preEval := AddToExprList(nil,nil);    on := activeExprs^.prevActive;    { traverse list backwards to get outermost expressions first }    while on <> activeExprs do begin	prevActive := on^.prevActive;	if on^.rootEqual <> on then begin	    { not a rootEqual expression }	    if TraceOpt then begin		writeln(output,'OptFinishLoop: active but not rootEqual ',		    on^.uniqueId:1);	    end;	end else if ConsiderMove(on,preEval,sol) then begin	    { moved it out of loop }	end else if on^.createLevel >= optBlockCeiling then begin	    { purge expression }	    on^.purged := true;	    RemoveFromActiveList(on);	end;	on := prevActive;    end;end;procedure Optimize;begin    InitOptimizer;    OptModule(globalModule);end;procedure StartOptProc;begin    ResetOptimizer;    optBlockLevel := 1;    optBlockCeiling := 1;    optBlockFloor := 1;end;procedure EndOptProc;beginend;procedure StartOptSplit{(var sol : SaveOptLevel)};begin    sol.level := optBlockLevel;    sol.floor := optBlockFloor;    sol.ceiling := optBlockCeiling;    sol.blockTime := blockOptTime;    blockOptTime := optTime;    optBlockLevel := optBlockLevel + 1;    optBlockCeiling := optBlockLevel;end;procedure NextOptSplit{(var sol : SaveOptLevel)};begin    OptRefresh;end;procedure EndOptSplit{(var sol : SaveOptLevel)};begin    OptRefresh;    optBlockLevel := sol.level;    optBlockFloor := sol.floor;    optBlockCeiling := sol.ceiling;    blockOptTime := sol.blockTime;    OptJoin;end;procedure StartOptLoop{(var sol : SaveOptLevel)};begin    sol.level := optBlockLevel;    sol.floor := optBlockFloor;    sol.ceiling := optBlockCeiling;    sol.blockTime := blockOptTime;    blockOptTime := optTime;    optBlockLevel := optBlockLevel + 1;    optBlockFloor := optBlockLevel;    optBlockCeiling := optBlockLevel;    optLoopNest := optLoopNest * LOOPBIAS;end;procedure EndOptLoop{(var sol : SaveOptLevel; var preEval : ExprList)};begin    optLoopNest := optLoopNest div LOOPBIAS;    OptFinishLoop(preEval,sol);    optBlockLevel := sol.level;    optBlockFloor := sol.floor;    optBlockCeiling := sol.ceiling;    blockOptTime := sol.blockTime;end;procedure OptRecursionReturn{(proc : ProcNode; stn : StmtNode)};var    en : ExprNode;    ok : boolean;    pen : ExprNode;    pn : ParamNode;    on : OptNode;    numParams : integer;begin    if OptNtail then begin    end else begin	en := stn^.returnVal;	if en^.kind = EXPRFUNC then begin	    if en^.func^.kind <> EXPRCONST then begin		{ not a constant procedure name }	    end else if en^.func^.exprConst^.kind <> DTPROC then begin		{ not a procedure constant }	    end else if proc <> en^.func^.exprConst^.procVal then begin		{ not the right procedure }	    end else begin		if TraceOptim then begin		    write(output,'OptRecursionReturn ');		    WriteString(output,proc^.name);		    writeln(output);		end;		ok := true;		numParams := 0;		if proc^.procType^.paramList <> nil then begin		    pen := en^.params^.first;		    pn := proc^.procType^.paramList^.first;		    while ok and (pn <> nil) do begin			if TraceOptim then begin			    write(output,pn^.kind,' ');			    WriteExpr(output,pen);			end;			if pn^.kind in [PARAMVAR,PARAMARRAYVAR] then begin			    if pen^.baseVar = nil then begin				ok := true;				if TraceOptim then begin				    write(output,' baseVar=nil');				end;			    end else if pen^.baseVar^.address.kind in				    [MEMNORMAL,MEMFAST]			    then begin				ok := proc <> pen^.baseVar^.address.proc;				if TraceOptim then begin				    write(output,' block=',ok);				end;			    end else if pen^.baseVar^.address.kind = MEMPARAM			    then begin				ok := pen^.baseVar^.indirect or (proc <>					pen^.baseVar^.address.proc);				if TraceOptim then begin				    write(output,' param=',ok);				end;			    end;			end;			if pn^.kind in [PARAMARRAYVALUE,PARAMARRAYVAR]			then begin			    if not pn^.paramType^.nocount then begin				pen := pen^.next;				numParams := numParams + 1;			    end;			end;			if TraceOptim then begin			    writeln(output);			end;			pen := pen^.next;			numParams := numParams + 1;			pn := pn^.next;		    end;		end;		if ok and (numParams <= MAXTAILPARAMS) then begin		    on := ExprToOpt(en^.func);		    on^.tailRecursion := true;		    proc^.tailRecursion := true;		end;	    end;	end;    end;end;procedure OptRecursionProc{(proc : ProcNode; stl : StmtList)};var    stn : StmtNode;    ok : boolean;    pen : ExprNode;    pn : ParamNode;    on : OptNode;    cn : CaseNode;begin    if OptNtail or (stl^.first = nil) then begin    end else begin	stn := stl^.last;	if stn^.kind = STMTPROC then begin	    if stn^.proc^.kind <> EXPRCONST then begin		{ not a constant procedure name }	    end else if stn^.proc^.exprConst^.kind <> DTPROC then begin		{ not a procedure constant }	    end else if proc <> stn^.proc^.exprConst^.procVal then begin		{ not the right procedure }	    end else begin		if TraceOptim then begin		    write(output,'OptRecursionProc ');		    WriteString(output,proc^.name);		    writeln(output);		end;		ok := true;		if proc^.procType^.paramList <> nil then begin		    pen := stn^.params^.first;		    pn := proc^.procType^.paramList^.first;		    while ok and (pen <> nil) do begin			if TraceOptim then begin			    write(output,pn^.kind,' ');			    WriteExpr(output,pen);			end;			if pn^.kind in [PARAMVAR,PARAMARRAYVAR] then begin			    if pen^.baseVar = nil then begin				ok := true;				if TraceOptim then begin				    write(output,' baseVar=nil');				end;			    end else if pen^.baseVar^.address.kind in				    [MEMNORMAL,MEMFAST]			    then begin				ok := proc <> pen^.baseVar^.address.proc;				if TraceOptim then begin				    write(output,' block=',ok);				end;			    end else if pen^.baseVar^.address.kind = MEMPARAM			    then begin				ok := pen^.baseVar^.indirect or (proc <>					pen^.baseVar^.address.proc);				if TraceOptim then begin				    write(output,' param=',ok);				end;			    end;			end;			if pn^.kind in [PARAMARRAYVALUE,PARAMARRAYVAR]			then begin			    if not pn^.paramType^.nocount then begin				pen := pen^.next;			    end;			end;			if TraceOptim then begin			    writeln(output);			end;			pen := pen^.next;			pn := pn^.next;		    end;		end;		if ok then begin		    on := ExprToOpt(stn^.proc);		    on^.tailRecursion := true;		    proc^.tailRecursion := true;		end;	    end;	end else if stn^.kind = STMTIF then begin	    OptRecursionProc(proc,stn^.thenList);	    OptRecursionProc(proc,stn^.elseList);	end else if stn^.kind = STMTWITH then begin	    OptRecursionProc(proc,stn^.withBody);	end else if stn^.kind = STMTCASE then begin	    cn := stn^.cases^.first;	    while cn <> nil do begin		OptRecursionProc(proc,cn^.stmts);		cn := cn^.next;	    end;	end;    end;end;procedure MarkIt(on : OptNode);begin    on^.marked := true;    if (on^.markLevel > optBlockLevel) or (on^.markLevel = 0) then begin	on^.markLevel := optBlockLevel;    end;    on^.rootCongruent^.defineTime := optTime;    if TraceMark then begin	write(output,'<',on^.uniqueId:1,'>');	if on <> on^.rootEqual then begin	    write(output,'$');	end;	markItCount := markItCount + 1;	if markItCount > 20 then begin	    writeln(output);	    markItCount := 0;	end;    end;end;procedure MarkOptAll;var    con, pon, mon : OptNode;    pen, men : ExprNode;    active, marked : integer;begin    if TraceOptim then begin	writeln(output,'MarkOptAll: start');    end;    optTime := optTime + 1;    markItCount := 0;    active := 0;    marked := 0;    con := cseRootExpr[EXPRVAL];    if con <> nil then begin	repeat	    mon := con;	    repeat		men := mon^.expr;		{ Experiment:		if men^.dependVar = nil then begin		end else if men^.dependVar^.name <> nil then begin		}		    MarkIt(mon);		    pen := mon^.parent;		    while pen <> nil do begin			pon := ExprToOpt(pen);			if pon <> nil then begin			    MarkIt(pon);			    pen := pon^.parent;			end else begin			    pen := nil;			end;		    end;		{ Experiment		end;		}		mon := mon^.nextCongruent;	    until mon = con;	    con := con^.nextClass;	until con = cseRootExpr[EXPRVAL];    end;    if TraceOptim then begin	writeln(output,'MarkOptAll: done ',marked:1,':',active:1);    end;end;procedure MarkOptExpr{(en : ExprNode)};var    baseVar : VarNode;    basePtrType : TypeNode;    con, mon, pon, von : OptNode;    men, pen : ExprNode;begin    if TraceMark then begin	write(output,'MarkOptExpr:');	WriteExpr(output,en);	writeln(output);    end;    markItCount := 0;    optTime := optTime + 1;    if en^.baseVar <> nil then begin	baseVar := en^.baseVar;	baseVar^.markTime.proc := currOptProc;	baseVar^.markTime.time := optTime;	if cseRootExpr[EXPRVAR] <> nil then begin	     von := cseRootExpr[EXPRVAR];	     repeat		if von^.expr^.exprVar = baseVar then begin		    von^.rootCongruent^.defineTime := optTime;		end;		von := von^.nextClass;	     until (von = cseRootExpr[EXPRVAR]);	end;	con := cseRootExpr[EXPRVAL];	if con <> nil then begin	    repeat		mon := con;		repeat		    men := mon^.expr;		    if men^.dependVar = baseVar then begin			MarkIt(mon);			pen := mon^.parent;			while pen <> nil do begin			    pon := ExprToOpt(pen);			    if pon <> nil then begin				MarkIt(pon);				pen := pon^.parent;			    end else begin				pen := nil;			    end;			end;		    end;		    mon := mon^.nextCongruent;		until mon = con;		con := con^.nextClass;	    until con = cseRootExpr[EXPRVAL];	end;    end else if en^.basePtrType = nil then begin	if TraceOptim then begin	    write(output,'MarkOptExpr: both nil ');	    WriteExpr(output,en);	    writeln(output);	end;    end;    if en^.basePtrType <> nil then begin	if en^.baseVar <> nil then begin	    if TraceOptim then begin		write(output,'MarkOptExpr: both not nil ');		WriteExpr(output,en);		writeln(output);	    end;	end;	basePtrType := en^.basePtrType;	basePtrType^.markTime.proc := currOptProc;	basePtrType^.markTime.time := optTime;	mon := cseRootExpr[EXPRVAL];	if mon <> nil then begin

⌨️ 快捷键说明

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