2017-01-08 Jeff Law <law@redhat.com>
+ PR rtl-optimizatin/81308
+ * tree-switch-conversion.c (cfg_altered): New file scoped static.
+ (process_switch): If group_case_labels makes a change, then set
+ cfg_altered.
+ (pass_convert_switch::execute): If a switch is converted, then
+ set cfg_altered. Return TODO_cfg_cleanup if cfg_altered is true.
+
PR rtl-optimization/81308
* recog.c (split_all_insns): Conditionally cleanup the CFG after
splitting insns.
+2018-01-08 Jeff Law <law@redhat.com>
+
+ PR rtl-optimizatin/81308
+ * g++.dg/pr81308-1.C: New test.
+ * g++.dg/pr81308-2.C: New test.
+
2018-01-08 Vidya Praveen <vidyapraveen@arm.com>
PR target/83663 - Revert r255946
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-w -O2 -fno-exceptions -std=c++11 -fpermissive" } */
+
+namespace a {
+template <typename b, b c> struct d { static constexpr b e = c; };
+template <typename> struct f : d<bool, __is_trivially_copyable(int)> {};
+}
+typedef long g;
+template <typename> struct h { static const bool e = a::f<int>::e; };
+namespace a {
+template <typename> struct ah;
+template <typename> class ai;
+}
+class i {
+public:
+ operator[](long) const {}
+};
+template <typename, int> class am : public i {};
+class an;
+class k : public am<a::ai<an>, h<a::ai<a::ah<an>>>::e> {};
+class l {
+public:
+ aq();
+};
+class ar extern as;
+typedef k at;
+class m {
+ virtual bool av(int, unsigned &, at &, int &, g &, bool);
+};
+class ar {
+public:
+ typedef m *aw(const &, int &, const &, const &);
+};
+struct ax {
+ static ay(ar::aw);
+};
+template <class az> struct n {
+ n(ar) { ax::ay(ba); }
+ static m *ba(const &bb, int &bc, const &bd, const &be) { az(bb, bc, bd, be); }
+};
+namespace {
+class G : m {
+ unsigned bi(const at &, l &);
+ bool av(int, unsigned &, at &, int &, g &, bool);
+
+public:
+ G(const, int, const, const) {}
+};
+}
+bool G::av(int, unsigned &, at &bl, int &, g &, bool) {
+ l bo;
+ bi(bl, bo);
+}
+o() { n<G> bp(as); }
+namespace {
+enum { bq, br };
+}
+unsigned G::bi(const at &bl, l &bo) {
+ unsigned bs;
+ for (char *j;; j += 2)
+ switch (*j) {
+ case bq:
+ bl[bs];
+ case br:
+ bo.aq();
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-w -O2" } */
+
+struct A {
+ int operator[](int) const {}
+};
+struct B {
+ void m_fn1();
+};
+struct C {
+ virtual bool m_fn2(int, unsigned &, A &, int &, unsigned long &, bool);
+};
+template <class MCAsmParserImpl> struct D {
+ D(int) { MCAsmParserImpl(0, 0, 0, 0); }
+};
+int a;
+namespace {
+struct F : C {
+ bool m_fn2(int, unsigned &, A &, int &, unsigned long &, bool);
+ unsigned m_fn3(const A &, B &);
+ F(int, int, int, int) {}
+};
+}
+bool F::m_fn2(int, unsigned &, A &p3, int &, unsigned long &, bool) {
+ B b;
+ m_fn3(p3, b);
+}
+void fn1() { D<F>(0); }
+unsigned F::m_fn3(const A &p1, B &p2) {
+ for (int *p;; p++)
+ switch (*p) {
+ case 0:
+ p1[a];
+ case 1:
+ p2.m_fn1();
+ }
+}
+
targetm.case_values_threshold(), or be its own param. */
#define MAX_CASE_BIT_TESTS 3
+/* Track whether or not we have altered the CFG and thus may need to
+ cleanup the CFG when complete. */
+bool cfg_altered;
+
/* Split the basic block at the statement pointed to by GSIP, and insert
a branch to the target basic block of E_TRUE conditional on tree
expression COND.
/* Group case labels so that we get the right results from the heuristics
that decide on the code generation approach for this switch. */
- group_case_labels_stmt (swtch);
+ cfg_altered |= group_case_labels_stmt (swtch);
/* If this switch is now a degenerate case with only a default label,
there is nothing left for us to do. */
{
basic_block bb;
+ cfg_altered = false;
FOR_EACH_BB_FN (bb, fun)
{
const char *failure_reason;
failure_reason = process_switch (as_a <gswitch *> (stmt));
if (! failure_reason)
{
+ cfg_altered = true;
if (dump_file)
{
fputs ("Switch converted\n", dump_file);
}
}
- return 0;
+ return cfg_altered ? TODO_cleanup_cfg : 0;
}
} // anon namespace