1 line
164 KiB
ObjectPascal
1 line
164 KiB
ObjectPascal
|
{$optimize 15}
{---------------------------------------------------------------}
{ }
{ DAG Creation }
{ }
{ Places intermediate codes into DAGs and trees. }
{ }
{---------------------------------------------------------------}
unit DAG;
interface
{$segment 'cg'}
{$LibPrefix '0/obj/'}
uses PCommon, CGI, CGC, Gen;
{---------------------------------------------------------------}
procedure DAG (code: icptr);
{ place an op code in a DAG or tree }
{ }
{ parameters: }
{ code - opcode }
{---------------------------------------------------------------}
implementation
const
peepSpinRate = 20; {PeepHoleOptimize spin rate}
var
c_ind: iclist; {vars that can be changed by indirect stores}
maxLoc: integer; {max local label number used by compiler}
memberOp: icptr; {operation found by Member}
optimizations: array[pcodes] of integer; {starting indexes into peeptable}
peepSpin: 0..peepSpinRate; {spinner delay for PeepHoleOptimize}
peepTablesInitialized: boolean; {have the peephole tables been initialized?}
prsFound: boolean; {are there any pc_prs opcodes?}
rescan: boolean; {redo the optimization pass?}
{-- External unsigned math routines ----------------------------}
function udiv (x,y: longint): longint; extern;
function umod (x,y: longint): longint; extern;
function umul (x,y: longint): longint; extern;
{---------------------------------------------------------------}
function SetsEqual (s1, s2: setPtr): boolean;
{ See if two sets are equal }
{ }
{ parameters: }
{ s1, s2 - sets to compare }
{ }
{ Returns: True if the sets are equal, else false }
label 1;
var
i: unsigned; {loop/index variable}
begin {SetsEqual}
SetsEqual := false;
if s1^.smax = s2^.smax then begin
for i := 1 to s1^.smax do
if s1^.sval[i] <> s2^.sval[i] then
goto 1;
SetsEqual := true;
end; {if}
1: ;
end; {SetsEqual}
function CodesMatch (op1, op2: icptr; exact: boolean): boolean;
{ Check to see if the trees op1 and op2 are equivalent }
{ }
{ parameters: }
{ op1, op2 - trees to check }
{ exact - is an exact of operands match required? }
{ }
{ Returns: True if trees are equivalent, else false. }
function OpsEqual (op1, op2: icptr): boolean;
{ See if the operands are equal }
{ }
{ parameters: }
{ op1, op2 - operations to check }
{ }
{ Returns: True if the operands are equivalent, else }
{ false. }
var
result: boolean; {temp result}
begin {OpsEqual}
result := false;
case op1^.opcode of
pc_cup, pc_cum, pc_cui, pc_csp, pc_tl1, pc_tl2, pc_vct, pc_pds, pc_bno:
{this rule prevents optimizations from removing sensitive operations}
;
pc_adi, pc_adl, pc_adr, pc_and, pc_lnd, pc_bnd, pc_bal, pc_bor,
pc_blr, pc_bxr, pc_blx, pc_equ, pc_neq, pc_ior, pc_lor, pc_mpi,
pc_umi, pc_mpl, pc_uml, pc_mpr, pc_int, pc_uni: begin
if op1^.left = op2^.left then
if op1^.right = op2^.right then
result := true;
if not result then
if op1^.left = op2^.right then
if op1^.right = op2^.left then
result := true;
if not result then
if not exact then
if CodesMatch(op1^.left, op2^.left, false) then
if CodesMatch(op1^.right, op2^.right, false) then
result := true;
if not result then
if not exact then
if CodesMatch(op1^.left, op2^.right, false) then
if CodesMatch(op1^.right, op2^.left, false) then
result := true;
end;
otherwise: begin
if op1^.left = op2^.left then
|