From: Maxim Kuvyrkov <maxim.kuvyrkov@gmail.com>
To: Xinliang David Li <davidxl@google.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: [google gcc-4_7] Inlining and devirtualization tests
Date: Wed, 16 Jan 2013 05:34:00 -0000 [thread overview]
Message-ID: <DBB042D4-1F7D-444F-82A8-2B1E830AEF1E@gmail.com> (raw)
[-- 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
next reply other threads:[~2013-01-16 5:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-16 5:34 Maxim Kuvyrkov [this message]
2013-01-16 5:42 ` Xinliang David Li
2013-01-16 19:54 ` Maxim Kuvyrkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DBB042D4-1F7D-444F-82A8-2B1E830AEF1E@gmail.com \
--to=maxim.kuvyrkov@gmail.com \
--cc=davidxl@google.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).