ORCA-Pascal/dag.pas

1 line
164 KiB
ObjectPascal
Raw Normal View History

{$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