From 8fe43377e165d115c78654090ee655ce2f7e229e Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 3 May 2008 10:27:55 +0000 Subject: [PATCH] + convert case of into if statement, resolves #10517 git-svn-id: trunk@10873 - --- .gitattributes | 1 + compiler/nset.pas | 73 ++++++++++++++++++++++- tests/test/opt/tcaseopt1.pp | 112 ++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 tests/test/opt/tcaseopt1.pp diff --git a/.gitattributes b/.gitattributes index f99eafe0b7..15eabc669f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7270,6 +7270,7 @@ tests/test/cg/variants/tvarol96.pp svneol=native#text/plain tests/test/dumpclass.pp svneol=native#text/plain tests/test/dumpmethods.pp svneol=native#text/plain tests/test/opt/README -text +tests/test/opt/tcaseopt1.pp svneol=native#text/plain tests/test/opt/tcmov.pp svneol=native#text/plain tests/test/opt/tcse1.pp svneol=native#text/plain tests/test/opt/tcse2.pp svneol=native#text/plain diff --git a/compiler/nset.pas b/compiler/nset.pas index 0ad464075b..e53ae42b29 100644 --- a/compiler/nset.pas +++ b/compiler/nset.pas @@ -116,7 +116,7 @@ implementation verbose, symconst,symdef,symsym,symtable,defutil,defcmp, htypechk,pass_1, - nbas,ncnv,ncon,nld,cgobj,cgbase; + nbas,ncnv,ncon,nld,nflw,cgobj,cgbase; {***************************************************************************** @@ -609,10 +609,10 @@ implementation end; - function tcasenode.pass_1 : tnode; var i : integer; + node_thenblock,node_elseblock : tnode; begin result:=nil; expectloc:=LOC_VOID; @@ -628,7 +628,74 @@ implementation { may be handle else tree } if assigned(elseblock) then - firstpass(elseblock); + begin + firstpass(elseblock); + + { kill case? } + if blocks.count=0 then + begin + result:=elseblock; + elseblock:=nil; + exit; + end; + end + else + if blocks.count=0 then + begin + result:=cnothingnode.create; + exit; + end; + + if is_boolean(left.resultdef) then + begin + case blocks.count of + 2: + begin + if boolean(qword(labels^._low))=false then + begin + node_thenblock:=pcaseblock(blocks[labels^.greater^.blockid])^.statement; + node_elseblock:=pcaseblock(blocks[labels^.blockid])^.statement; + pcaseblock(blocks[labels^.greater^.blockid])^.statement:=nil; + end + else + begin + node_thenblock:=pcaseblock(blocks[labels^.blockid])^.statement; + node_elseblock:=pcaseblock(blocks[labels^.less^.blockid])^.statement; + pcaseblock(blocks[labels^.less^.blockid])^.statement:=nil; + end; + pcaseblock(blocks[labels^.blockid])^.statement:=nil; + end; + 1: + begin + if labels^._low=labels^._high then + begin + if boolean(qword(labels^._low))=false then + begin + node_thenblock:=elseblock; + node_elseblock:=pcaseblock(blocks[labels^.blockid])^.statement; + end + else + begin + node_thenblock:=pcaseblock(blocks[labels^.blockid])^.statement; + node_elseblock:=elseblock; + end; + pcaseblock(blocks[labels^.blockid])^.statement:=nil; + elseblock:=nil; + end + else + begin + result:=pcaseblock(blocks[labels^.blockid])^.statement; + pcaseblock(blocks[labels^.blockid])^.statement:=nil; + elseblock:=nil; + exit; + end; + end; + else + internalerror(200805031); + end; + result:=cifnode.create(left,node_thenblock,node_elseblock); + left:=nil; + end; end; diff --git a/tests/test/opt/tcaseopt1.pp b/tests/test/opt/tcaseopt1.pp new file mode 100644 index 0000000000..6af0d15ced --- /dev/null +++ b/tests/test/opt/tcaseopt1.pp @@ -0,0 +1,112 @@ +Procedure TestCaseBool; +Var + L1, L2: LongWord; + b : boolean; +begin + b:=false; + + l1:=$deadbeef; + case b of + true: + l1:=0; + else + l1:=1234; + end; + if l1<>1234 then + halt(1); + + l1:=$deadbeef; + case b of + false: + l1:=1234; + else + l1:=0; + end; + if l1<>1234 then + halt(1); + + l1:=$deadbeef; + case b of + true: + l1:=0; + false: + l1:=1234; + end; + if l1<>1234 then + halt(1); + + l1:=$deadbeef; + case b of + false..true: + l1:=1234; + else + l1:=0; + end; + if l1<>1234 then + halt(1); + + l1:=$deadbeef; + case b of + false..true: + l1:=1234; + end; + if l1<>1234 then + halt(1); + + + { set b to true } + b:=true; + + l1:=$deadbeef; + case b of + true: + l1:=0; + else + l1:=1234; + end; + if l1<>0 then + halt(1); + + l1:=$deadbeef; + case b of + false: + l1:=1234; + else + l1:=0; + end; + if l1<>0 then + halt(1); + + l1:=$deadbeef; + case b of + true: + l1:=0; + false: + l1:=1234; + end; + if l1<>0 then + halt(1); + + l1:=$deadbeef; + case b of + false..true: + l1:=1234; + else + l1:=0; + end; + if l1<>1234 then + halt(1); + + l1:=$deadbeef; + case b of + false..true: + l1:=1234; + end; + if l1<>1234 then + halt(1); +end; + +begin + TestCaseBool; + writeln('ok'); +end.