1 line
143 KiB
ObjectPascal
1 line
143 KiB
ObjectPascal
|
{$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
|