ORCA-C/DAG.pas

1 line
143 KiB
ObjectPascal
Raw Normal View History

{$optimize 7} {---------------------------------------------------------------} { } { DAG Creation } { } { Places intermediate codes into DAGs and trees. } { } {---------------------------------------------------------------} unit DAG; interface {$segment 'cg'} {$LibPrefix '0/obj/'} uses CCommon, CGI, CGC, Gen; {---------------------------------------------------------------} procedure DAG (code: icptr); { place an op code in a DAG or tree } { } { parameters: } { code - opcode } {---------------------------------------------------------------} implementation 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} peepTablesInitialized: boolean; {have the peephole tables been initialized?} rescan: boolean; {redo the optimization pass?} {-- External unsigned math routines; imported from Expression.pas --} function udiv (x,y: longint): longint; extern; function umod (x,y: longint): longint; extern; function umul (x,y: longint): longint; extern; {---------------------------------------------------------------} 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 match of operands required? } { } { Returns: True if trees are equivalent, else false. } function LongStrCmp (s1, s2: longStringPtr): boolean; { Are the strings s1 amd s2 equal? } { } { parameters: } { s1, s2 - strings to compare } { } { Returns: True if the strings are equal, else false } label 1; var i: integer; {loop/index variable} begin {LongStrCmp} LongStrCmp := false; if s1^.length = s2^.length then begin for i := 1 to s1^.length do if s1^.str[i] <> s2^.str[i] then goto 1; LongStrCmp := true; end; {if} 1: end; {LongStrCmp} 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_cui, pc_tl1, 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: 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 if op1^.right = op2^.right then result := true; if not result then if not exact then i