2
0
Эх сурвалжийг харах

+ fold also (string const+(string const+string var))
* string tree folding code moved into level 2 opt. block

git-svn-id: trunk@47986 -

florian 4 жил өмнө
parent
commit
3109005791

+ 62 - 23
compiler/nadd.pas

@@ -536,12 +536,28 @@ implementation
 
 
       function SwapLeftWithRightRight : tnode;
       function SwapLeftWithRightRight : tnode;
         var
         var
-          hp: tnode;
+          hp,hp2 : tnode;
         begin
         begin
-          hp:=left;
-          left:=taddnode(right).right;
-          taddnode(right).right:=hp;
-          right:=right.simplify(false);
+          { keep the order of val+const else string operations might cause an error }
+          hp:=taddnode(right).right;
+
+          taddnode(right).right:=taddnode(right).left;
+          taddnode(right).left:=left;
+
+          right.resultdef:=nil;
+          do_typecheckpass(right);
+          hp2:=right.simplify(forinline);
+          if assigned(hp2) then
+            right:=hp2;
+          if resultdef.typ<>pointerdef then
+            begin
+              { ensure that the constant is not expanded to a larger type due to overflow,
+                but this is only useful if no pointer operation is done }
+              right:=ctypeconvnode.create_internal(right,resultdef);
+              do_typecheckpass(right);
+            end;
+          left:=right;
+          right:=hp;
           result:=GetCopyAndTypeCheck;
           result:=GetCopyAndTypeCheck;
         end;
         end;
 
 
@@ -1207,23 +1223,7 @@ implementation
              exit;
              exit;
           end;
           end;
 
 
-        { try to fold
-                    op
-                   /  \
-                 op  const1
-                /  \
-              val const2
-
-          while operating on strings
-        }
-        if (cs_opt_level2 in current_settings.optimizerswitches) and (nodetype=addn) and ((rt=stringconstn) or is_constcharnode(right)) and (left.nodetype=nodetype) and
-          (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right)) then
-          begin
-            Result:=SwapRightWithLeftLeft;
-            exit;
-          end;
-
-          { set constant evaluation }
+        { set constant evaluation }
         if (right.nodetype=setconstn) and
         if (right.nodetype=setconstn) and
            not assigned(tsetconstnode(right).left) and
            not assigned(tsetconstnode(right).left) and
            (left.nodetype=setconstn) and
            (left.nodetype=setconstn) and
@@ -1381,9 +1381,48 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
-        { slow simplifications }
+        if cs_opt_level1 in current_settings.optimizerswitches then
+          begin
+          end;
+
+        { slow simplifications and/or more sophisticated transformations which might make debugging harder }
         if cs_opt_level2 in current_settings.optimizerswitches then
         if cs_opt_level2 in current_settings.optimizerswitches then
           begin
           begin
+            if nodetype=addn then
+              begin
+                { try to fold
+                            op
+                           /  \
+                         op  const1
+                        /  \
+                      val const2
+
+                  while operating on strings
+                }
+                if ((rt=stringconstn) or is_constcharnode(right)) and (left.nodetype=nodetype) and
+                  (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right)) then
+                  begin
+                    Result:=SwapRightWithLeftLeft;
+                    exit;
+                  end;
+
+                { try to fold
+                              op
+                             /  \
+                         const1  op
+                                /  \
+                            const2 val
+
+                  while operating on strings
+                }
+                if ((lt=stringconstn) or is_constcharnode(left)) and (right.nodetype=nodetype) and
+                  (compare_defs(resultdef,right.resultdef,nothingn)=te_exact) and ((taddnode(right).left.nodetype=stringconstn) or is_constcharnode(taddnode(right).left)) then
+                  begin
+                    Result:=SwapLeftWithRightRight;
+                    exit;
+                  end;
+              end;
+
             { the comparison is might be expensive and the nodes are usually only
             { the comparison is might be expensive and the nodes are usually only
               equal if some previous optimizations were done so don't check
               equal if some previous optimizations were done so don't check
               this simplification always
               this simplification always

+ 30 - 1
tests/webtbs/tw38267b.pp

@@ -1,6 +1,6 @@
 { %opt=-O3 -Sg }
 { %opt=-O3 -Sg }
 {$mode objfpc} {$longstrings+}
 {$mode objfpc} {$longstrings+}
-label start1, end1, start2, end2, start3, end3;
+label start1, end1, start2, end2, start3, end3, start4, end4;
 
 
 var
 var
 	s: string;
 	s: string;
@@ -88,5 +88,34 @@ end3:
     if PtrUint(CodePointer(@end3) - CodePointer(@start3))>300 then
     if PtrUint(CodePointer(@end3) - CodePointer(@start3))>300 then
       halt(3);
       halt(3);
     writeln;
     writeln;
+
+	writeln('31 literals concatenated with 1 dynamic string, they could fold but didn''t at all:');
+start4:
+	s := 'Once like a Great House' + (LineEnding +
+		('founded on sand,' + (LineEnding +
+		('Stood our Temple' + (LineEnding +
+		('whose pillars on troubles were based.' + (LineEnding +
+		('Now mischievous spirits, bound,' + (LineEnding +
+		('in dim corners stand,' + (LineEnding +
+		('Rotted columns, but' + (LineEnding +
+		('with iron-bound bands embraced' + (LineEnding +
+		('Cracked, crumbling marble,' + (LineEnding +
+		('tempered on every hand,' + (LineEnding +
+		('By strong steel' + (LineEnding +
+		('forged in fire and faith.' + (LineEnding +
+		('Shackled, these wayward servants' + (LineEnding +
+		('serve the land,' + (LineEnding +
+		('The Temple secured' + (LineEnding +
+		('by the Builder’s grace.' +
+		Copy('', 1, 0)))))))))))))))))))))))))))))));
+end4:
+    writeln(Copy(s, 1, 0), PtrUint(CodePointer(@end4) - CodePointer(@start4)), ' b of code');
+    { more than 100 bytes of code might point out that the constants are not folded,
+      example x86_64-linux: not folded: 1384 bytes; folded: 108 bytes
+    }
+    if PtrUint(CodePointer(@end4) - CodePointer(@start4))>300 then
+      halt(4);
+
+
     writeln('ok');
     writeln('ok');
 end.
 end.