unit srCacheOp; {$mode objfpc}{$H+} interface uses ginodes, srNode, srCFGParser, srType, srReg, srOp; type PsrCacheOpKey=^TsrCacheOpKey; TsrCacheOpKey=packed record place:TsrOpBlock; OpId :DWORD; dtype:TsrDataType; count:DWORD; pData:PPsrRegNode; end; TsrCacheOp=class public pLeft,pRight:TsrCacheOp; class function c(n1,n2:PsrCacheOpKey):Integer; static; private key:TsrCacheOpKey; public pDst:TsrNode; end; PsrCacheOpList=^TsrCacheOpList; TsrCacheOpList=object type TNodeTree=specialize TNodeTreeClass; var FEmit:TCustomEmit; FTree:TNodeTree; Procedure Init(Emit:TCustomEmit); inline; function Fetch(place:TsrOpBlock;OpId:DWORD;rtype:TsrDataType;count:Byte;src:PPsrRegNode):TsrCacheOp; end; function _up_to_real(t:TsrOpBlock):TsrOpBlock; implementation function _up_to_real(t:TsrOpBlock):TsrOpBlock; begin repeat if not t.IsType(ntOpBlock) then Break; if IsReal(t.bType) then Break; t:=t.Parent; until false; Result:=t; end; //-- class function TsrCacheOp.c(n1,n2:PsrCacheOpKey):Integer; begin //place (not need order sort) Result:=ord(ptruint(n1^.place)>ptruint(n2^.place))-ord(ptruint(n1^.place)0) then Exit; //OpId Result:=ord(n1^.OpId>n2^.OpId)-ord(n1^.OpId0) then Exit; //dtype Result:=ord(n1^.dtype>n2^.dtype)-ord(n1^.dtype0) then Exit; //count Result:=ord(n1^.count>n2^.count)-ord(n1^.count0) then Exit; //(not need order sort) Result:=ComparePtruint(PPtruint(n1^.pData),PPtruint(n2^.pData),n1^.count); end; Procedure TsrCacheOpList.Init(Emit:TCustomEmit); inline; begin FEmit:=Emit; end; function TsrCacheOpList.Fetch(place:TsrOpBlock;OpId:DWORD;rtype:TsrDataType;count:Byte;src:PPsrRegNode):TsrCacheOp; var size:ptruint; key:TsrCacheOpKey; begin Assert(place<>nil); place:=_up_to_real(place); Result:=nil; // key:=Default(TsrCacheOpKey); key.place:=place; key.OpId :=OpId; key.dtype:=rtype; key.count:=count; key.pData:=src; // Result:=FTree.Find(@key); if (Result=nil) then begin Result:=FEmit.specialize New; Result.key:=key; size:=count*SizeOf(Pointer); Result.key.pData:=FEmit.Alloc(size); Move(src^,Result.key.pData^,size); FTree.Insert(Result); end; end; end.