* [google gcc-4_7] Inlining and devirtualization tests
@ 2013-01-16 5:34 Maxim Kuvyrkov
2013-01-16 5:42 ` Xinliang David Li
0 siblings, 1 reply; 3+ messages in thread
From: Maxim Kuvyrkov @ 2013-01-16 5:34 UTC (permalink / raw)
To: Xinliang David Li; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 351 bytes --]
David,
This patch adds tests for inlining and devirtualization optimizations, some of which are already in google's gcc-4_7 branch. It is only right to add tests for these optimizations. Main gcc-4_7 branch and trunk pass tests 1 and 5, while Google's gcc-4_7 branch also passes tests 2 and 3.
OK to apply?
Thanks,
--
Maxim Kuvyrkov
[-- Attachment #2: 0001-Inlining-and-devirtualizaion-tests.patch --]
[-- Type: application/octet-stream, Size: 15860 bytes --]
From 596cf08845f5962e29ceae043849dac0469fbbee Mon Sep 17 00:00:00 2001
From: Maxim Kuvyrkov <maxim.kuvyrkov@gmail.com>
Date: Wed, 16 Jan 2013 18:24:26 +1300
Subject: [PATCH] Inlining and devirtualizaion tests *
g++.dg/ipa/inline-devirt-{1235}.C: New tests. *
g++.dg/ipa/inline-devirt-{46789}.C: New tests, xfailed for
now.
---
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C | 54 +++++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C | 49 +++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C | 49 +++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C | 54 +++++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C | 29 +++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C | 34 ++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C | 70 ++++++++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C | 72 +++++++++++++++++
gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C | 85 ++++++++++++++++++++
9 files changed, 496 insertions(+)
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
create mode 100644 gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
new file mode 100644
index 0000000..58b04d0
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
@@ -0,0 +1,54 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+ virtual unsigned char calculate() = 0;
+ virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+ unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+ virtual unsigned char calculate() { return 2; }
+};
+
+static void print(X& c)
+{
+ printf("%d\n", c.calculate());
+ printf("+1: %d\n", c.calculate() + 1);
+}
+
+static void print(Y& c)
+{
+ printf("%d\n", c.calculate());
+ printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+ X x;
+ Y y;
+
+ print(x);
+ print(y);
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
new file mode 100644
index 0000000..62add89
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
@@ -0,0 +1,49 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+ virtual unsigned char calculate() = 0;
+ virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+ virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+ unsigned char calculate() { return 2; }
+};
+
+static void print(Calculable& c)
+{
+ printf("%d\n", c.calculate());
+ printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+ X x;
+ Y y;
+
+ print(x);
+ print(y);
+
+ return 0;
+
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
new file mode 100644
index 0000000..7e62f01
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
@@ -0,0 +1,49 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 3 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+ virtual unsigned char calculate() const = 0;
+ virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+ virtual unsigned char calculate() const { return 0; }
+};
+
+class Y : public Calculable
+{
+public:
+ virtual unsigned char calculate() const { return 3; }
+};
+
+static void print(const Calculable& c)
+{
+ for (int i = 0; i < c.calculate(); i++)
+ {
+ printf("%d\n", c.calculate());
+ }
+}
+
+int main()
+{
+ X x;
+ Y y;
+
+ print(x);
+ print(y);
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
new file mode 100644
index 0000000..f5857d2
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
@@ -0,0 +1,54 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 2 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdint.h>
+#include <stdio.h>
+
+class String
+{
+public:
+ virtual uint64_t length() const = 0;
+ virtual char get(uint64_t index) const = 0;
+ virtual void set(uint64_t index, char value) = 0;
+ virtual char& operator[] (uint64_t value) = 0;
+ virtual ~String() {};
+};
+
+template<uint64_t size> class FixedString : public String
+{
+private:
+ char contents[size + 1];
+
+public:
+ virtual uint64_t length() const { return size; }
+ virtual char get(uint64_t index) const { return contents[index]; }
+ virtual void set(uint64_t index, char value) { contents[index] = value; }
+ virtual char& operator[] (uint64_t index) { return contents[index]; }
+
+ FixedString() { contents[size] = '\0'; }
+};
+
+void print_length (const String& string)
+{
+ for (uint64_t i = 0; i < string.length(); i++)
+ {
+ printf("%d\n", string.get(i));
+ }
+}
+
+int main()
+{
+ FixedString<2> empty;
+ empty[0] = 'a';
+ empty[1] = 'b';
+
+ print_length(empty);
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 97\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 98\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
new file mode 100644
index 0000000..8acfff1
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
@@ -0,0 +1,29 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+typedef unsigned char(*Calculable)(void);
+typedef Calculable(*CalculateStrategy)(void);
+
+unsigned char one() { return 1; }
+Calculable oneStrategy() { return one; }
+unsigned char two() { return 2; }
+Calculable twoStrategy() { return two; }
+
+int main()
+{
+ printf("%d\n", oneStrategy()());
+ printf("+1: %d\n", oneStrategy()() + 1);
+ printf("%d\n", twoStrategy()());
+ printf("+1: %d\n", twoStrategy()() + 1);
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
new file mode 100644
index 0000000..8549012
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
@@ -0,0 +1,34 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+typedef unsigned char(*Calculable)(void);
+typedef Calculable(*CalculateStrategy)(void);
+
+unsigned char one() { return 1; }
+Calculable oneStrategy() { return one; }
+unsigned char two() { return 2; }
+Calculable twoStrategy() { return two; }
+
+static void print(CalculateStrategy calculateStrategy)
+{
+ printf("%d\n", calculateStrategy()());
+ printf("+1: %d\n", calculateStrategy()() + 1);
+}
+
+int main()
+{
+ print(oneStrategy);
+ print(twoStrategy);
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
new file mode 100644
index 0000000..0343ddd
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
@@ -0,0 +1,70 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -std=c++0x -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+class Stream
+{
+public:
+ virtual unsigned char read() = 0;
+ virtual ~Stream() {}
+};
+
+class Connection
+{
+public:
+ virtual void open() = 0;
+ virtual void close() = 0;
+ virtual ~Connection() {}
+};
+
+class Socket : public Stream, public Connection
+{
+public:
+ virtual unsigned char read() = 0;
+ virtual void open() = 0;
+ virtual void close() { printf("generic close\n"); }
+};
+
+class LinuxSocket : public Socket
+{
+public:
+ virtual unsigned char read() { return 'l'; }
+ virtual void open() { printf("linux open\n"); }
+};
+
+class CustomSocket : public Socket
+{
+public:
+ virtual unsigned char read() { return 0; }
+ virtual void open() { printf("custom open\n"); }
+ virtual void close() { printf("custom close\n"); }
+};
+
+static void readToEnd(Stream* stream)
+{
+ while (stream->read() == 0) { printf("got it\n"); }
+}
+
+static Socket* createSocket()
+{
+ return new LinuxSocket();
+}
+
+int main()
+{
+ auto socket = createSocket();
+ socket->open();
+ readToEnd(socket);
+ socket->close();
+
+ delete socket;
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "__builtin_puts \\(&\"linux open\"\\\[0\\\]\\);\n" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "__builtin_puts \\(&\"generic close\"\\\[0\\\]\\);\n" "optimized" { xfail *-*-* } } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
new file mode 100644
index 0000000..dac85cd
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
@@ -0,0 +1,72 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 4 printf()s in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized" }
+
+#include <stdio.h>
+
+template<class TOutput, typename TInput> class Factory
+{
+public:
+ virtual TOutput* createFrom(TInput) = 0;
+ virtual ~Factory() {};
+};
+
+class Calculable
+{
+public:
+ virtual unsigned char calculate() = 0;
+ virtual ~Calculable() {};
+};
+
+class X : public Calculable
+{
+public:
+ virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+ virtual unsigned char calculate() { throw; }
+};
+
+enum Letter
+{
+ LetterX,
+ LetterY
+};
+
+class CalculableFactory : Factory<Calculable, Letter>
+{
+public:
+ virtual Calculable* createFrom(Letter letter)
+ {
+ switch(letter)
+ {
+ case LetterX: return new X();
+ default: return new Y();
+ }
+ }
+};
+
+
+static void print(Calculable* c)
+{
+ printf("+1: %d\n", c->calculate() + 1);
+}
+
+int main()
+{
+ CalculableFactory calcuableFactory;
+ Calculable* calculable = calcuableFactory.createFrom(LetterX);
+
+ print(calculable);
+
+ delete calculable;
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C
new file mode 100644
index 0000000..8334389
--- /dev/null
+++ b/gcc-4_7/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C
@@ -0,0 +1,85 @@
+/* Verify that the inliner makes good decisions and the example
+ is optimized to 1 printf() in main(). */
+// { dg-do compile }
+// { dg-options "-O2 -std=c++0x -fdump-tree-optimized" }
+
+#include <stdio.h>
+#include <memory>
+
+using namespace std;
+
+template<class TOutput, typename TInput> class Factory
+{
+public:
+ virtual shared_ptr<TOutput> createFrom(TInput) = 0;
+ virtual ~Factory() {};
+};
+
+class Calculable
+{
+public:
+ virtual unsigned char calculate() = 0;
+ virtual ~Calculable() {};
+};
+
+enum LetterType
+{
+ LetterX,
+ LetterY
+};
+
+class Letter
+{
+public:
+ Letter(LetterType type) : _type(type) {}
+ virtual ~Letter() {}
+
+protected:
+ LetterType _type;
+};
+
+class X : public Letter, public Calculable
+{
+public:
+ X() : Letter(LetterX) {}
+ virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Letter, public Calculable
+{
+public:
+ Y() : Letter(LetterY) {}
+ virtual unsigned char calculate() { throw; }
+};
+
+class CalculableFactory : Factory<Calculable, LetterType>
+{
+public:
+ virtual shared_ptr<Calculable> createFrom(LetterType letter)
+ {
+ switch(letter)
+ {
+ case LetterX: return make_shared<X>();
+ default: return make_shared<Y>();
+ }
+ }
+};
+
+
+static void print(Calculable& c)
+{
+ printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+ CalculableFactory calcuableFactory;
+ auto calculable = calcuableFactory.createFrom(LetterX);
+
+ print(*calculable);
+
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { cleanup-tree-dump "optimized" } }
--
1.7.9.5
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [google gcc-4_7] Inlining and devirtualization tests
2013-01-16 5:34 [google gcc-4_7] Inlining and devirtualization tests Maxim Kuvyrkov
@ 2013-01-16 5:42 ` Xinliang David Li
2013-01-16 19:54 ` Maxim Kuvyrkov
0 siblings, 1 reply; 3+ messages in thread
From: Xinliang David Li @ 2013-01-16 5:42 UTC (permalink / raw)
To: Maxim Kuvyrkov; +Cc: GCC Patches
Looks fine. Why adding tests that are expected to fail? Are these
tests passing with trunk?
David
On Tue, Jan 15, 2013 at 9:33 PM, Maxim Kuvyrkov
<maxim.kuvyrkov@gmail.com> wrote:
> David,
>
> This patch adds tests for inlining and devirtualization optimizations, some of which are already in google's gcc-4_7 branch. It is only right to add tests for these optimizations. Main gcc-4_7 branch and trunk pass tests 1 and 5, while Google's gcc-4_7 branch also passes tests 2 and 3.
>
> OK to apply?
>
> Thanks,
>
> --
> Maxim Kuvyrkov
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [google gcc-4_7] Inlining and devirtualization tests
2013-01-16 5:42 ` Xinliang David Li
@ 2013-01-16 19:54 ` Maxim Kuvyrkov
0 siblings, 0 replies; 3+ messages in thread
From: Maxim Kuvyrkov @ 2013-01-16 19:54 UTC (permalink / raw)
To: Xinliang David Li; +Cc: GCC Patches
On 16/01/2013, at 6:41 PM, Xinliang David Li wrote:
> Looks fine. Why adding tests that are expected to fail? Are these
> tests passing with trunk?
They are expected to fail only due to optimization analysis not being up to snuff yet, not because it's a bad idea to optimize a particular testcase. As inlining and devirtualization analysis improves, these tests will start passing.
Thanks,
--
Maxim Kuvyrkov
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-01-16 19:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-16 5:34 [google gcc-4_7] Inlining and devirtualization tests Maxim Kuvyrkov
2013-01-16 5:42 ` Xinliang David Li
2013-01-16 19:54 ` Maxim Kuvyrkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).