浏览代码

+ more restrictions on pred/succ to dec/inc optimization
o check if the argument can be used as a call by reference parameter
o check if the argument has no side-effects
+ tests

git-svn-id: trunk@34816 -

florian 8 年之前
父节点
当前提交
a27b07b342
共有 4 个文件被更改,包括 78 次插入2 次删除
  1. 2 0
      .gitattributes
  2. 3 2
      compiler/nld.pas
  3. 42 0
      tests/test/units/system/tpredsucc1.pp
  4. 31 0
      tests/test/units/system/tpredsucc2.pp

+ 2 - 0
.gitattributes

@@ -13339,6 +13339,8 @@ tests/test/units/system/todd.pp svneol=native#text/plain
 tests/test/units/system/tparam.pp svneol=native#text/plain
 tests/test/units/system/tpchlen.pp svneol=native#text/plain
 tests/test/units/system/tpi.pp svneol=native#text/plain
+tests/test/units/system/tpredsucc1.pp svneol=native#text/pascal
+tests/test/units/system/tpredsucc2.pp svneol=native#text/pascal
 tests/test/units/system/trandom.pp svneol=native#text/plain
 tests/test/units/system/trdtxt01.pp svneol=native#text/plain
 tests/test/units/system/trdtxt02.pp svneol=native#text/plain

+ 3 - 2
compiler/nld.pas

@@ -569,8 +569,9 @@ implementation
           ((tinlinenode(right).inlinenumber=in_succ_x) or (tinlinenode(right).inlinenumber=in_pred_x)) and
           (tinlinenode(right).left.isequal(left)) and
           ((localswitches*[cs_check_overflow,cs_check_range])=[]) and
-          ((right.localswitches*[cs_check_overflow,cs_check_range])=[])
-           then
+          ((right.localswitches*[cs_check_overflow,cs_check_range])=[]) and
+          valid_for_var(tinlinenode(right).left,false) and
+          not(might_have_sideeffects(tinlinenode(right).left)) then
           begin
             if tinlinenode(right).inlinenumber=in_succ_x then
               result:=cinlinenode.create(

+ 42 - 0
tests/test/units/system/tpredsucc1.pp

@@ -0,0 +1,42 @@
+{$mode objfpc}
+
+type
+  tmyclass = class
+    i : integer;
+    function GetI : Integer;
+    procedure SetI(const _i : Integer);
+    property i1 : integer read GetI write SetI;
+    property i2 : integer read i write i;
+  end;
+
+
+function tmyclass.GetI : Integer;
+  begin
+    Result:=i;
+  end;
+
+procedure tmyclass.SetI(const _i : Integer);
+  begin
+    i:=_i;
+  end;
+
+var
+  myclass : tmyclass;
+
+begin
+  myclass:=tmyclass.create;
+  myclass.i1:=1;
+
+  myclass.i1:=pred(myclass.i1);
+  myclass.i1:=succ(myclass.i1);
+
+  myclass.i2:=pred(myclass.i2);
+  myclass.i2:=succ(myclass.i2);
+
+  if myclass.i<>1 then
+    halt(1);
+
+  myclass.free;
+
+  writeln('ok');
+end.

+ 31 - 0
tests/test/units/system/tpredsucc2.pp

@@ -0,0 +1,31 @@
+{$mode objfpc}
+var
+  counter : longint;
+
+function f : Integer;
+  begin
+    inc(counter);
+    f:=1;
+  end;
+
+
+var
+  s : array[0..10] of Integer;
+
+begin
+  s[1]:=1234;
+  counter:=0;
+
+  s[f]:=succ(s[f]);
+  s[f]:=pred(s[f]);
+
+  if s[1]<>1234 then
+    halt(1);
+
+  if counter<>4 then
+    halt(2);
+
+  writeln('ok');
+end.
+
+