6db2f270ecfd57c104dae546cabcf6698aefac4d
[gcc.git] / gcc / testsuite / g++.dg / opt / pr56999.C
1 // PR rtl-optimization/56999
2 // { dg-do run }
3 // { dg-options "-O2" }
4 // { dg-additional-options "-fpic" { target fpic } }
5 // { dg-additional-options "-march=i686 -mtune=atom" { target ia32 } }
6 // { dg-require-visibility "" }
7
8 extern "C" void abort (void);
9 extern "C" void exit (int);
10 volatile bool do_exit = true;
11 struct JSScript;
12 struct JITScript { int i; };
13 #pragma GCC visibility push(hidden)
14 typedef struct JSCompartment JSCompartment;
15 typedef struct JSContext JSContext;
16 namespace js
17 {
18 struct ContextFriendFields
19 {
20 JSCompartment *compartment;
21 };
22 struct TempAllocPolicy
23 {
24 };
25 template <class T>
26 struct Vector
27 {
28 T *mBegin;
29 T *begin () { return mBegin; }
30 T & operator[] (unsigned i) { return begin ()[i]; }
31 template <class U>
32 __attribute__((noinline, noclone))
33 bool append (U) { asm volatile ("" : : : "memory"); if (do_exit) abort (); return false; }
34 };
35 namespace types
36 {
37 struct TypeCompartment;
38 }
39 namespace mjit
40 {
41 }
42 namespace ion
43 {
44 struct IonScript;
45 }
46 namespace types
47 {
48 struct CompilerOutput
49 {
50 enum Kind { MethodJIT, ParallelIon };
51 JSScript *script;
52 unsigned kindInt : 2;
53 bool constructing : 1;
54 bool barriers : 1;
55 bool pendingRecompilation : 1;
56 Kind kind () const { return static_cast <Kind> (kindInt); }
57 bool isValid () const;
58 };
59 struct RecompileInfo
60 {
61 unsigned outputIndex;
62 CompilerOutput *compilerOutput (TypeCompartment & types) const;
63 CompilerOutput *compilerOutput (JSContext *cx) const;
64 };
65 struct TypeCompartment
66 {
67 Vector <CompilerOutput> *constrainedOutputs;
68 Vector <RecompileInfo> *pendingRecompiles;
69 void addPendingRecompile (JSContext *cx, const RecompileInfo & info);
70 };
71 }
72 }
73 struct JSScript
74 {
75 struct JITScriptHandle
76 {
77 static volatile JITScript *UNJITTABLE __attribute__((visibility ("default")));
78 JITScript *value;
79 bool isValid () { return value != UNJITTABLE; }
80 JITScript *getValid () { return value; }
81 };
82 struct JITScriptSet
83 {
84 JITScriptHandle jitHandleNormal, jitHandleNormalBarriered;
85 JITScriptHandle jitHandleCtor, jitHandleCtorBarriered;
86 JITScriptHandle jitNull1, jitNull2;
87 };
88 JITScriptSet *mJITInfo;
89 void *ion;
90 JITScriptHandle *jitHandle (bool constructing, bool barriers)
91 {
92 return constructing ? (barriers ? &mJITInfo->jitHandleCtorBarriered
93 : &mJITInfo->jitHandleCtor)
94 : (barriers ? &mJITInfo->jitHandleNormalBarriered
95 : &mJITInfo->jitHandleNormal);
96 }
97 JITScript *getJIT (bool constructing, bool barriers)
98 {
99 JITScriptHandle *jith = jitHandle (constructing, barriers);
100 return jith->isValid () ? jith->getValid () : __null;
101 }
102 };
103 struct JSContext : js::ContextFriendFields
104 {
105 };
106 namespace js
107 {
108 __attribute__((noinline, noclone))
109 void CancelOffThreadIonCompile (JSCompartment *, JSScript *)
110 {
111 if (do_exit)
112 exit (0);
113 }
114 }
115 struct JSCompartment
116 {
117 js::types::TypeCompartment types;
118 };
119 namespace js
120 {
121 namespace types
122 {
123 inline bool CompilerOutput::isValid () const
124 {
125 if (!script)
126 return false;
127 switch (kind ())
128 {
129 case MethodJIT:
130 {
131 JITScript *jit = script->getJIT (constructing, barriers);
132 if (!jit)
133 return false;
134 }
135 case ParallelIon:
136 return true;
137 }
138 return false;
139 }
140 inline CompilerOutput *RecompileInfo::compilerOutput (TypeCompartment & types) const
141 {
142 return &(*types.constrainedOutputs)[outputIndex];
143 }
144 inline CompilerOutput *RecompileInfo::compilerOutput (JSContext *cx) const
145 {
146 return compilerOutput (cx->compartment->types);
147 }
148 }
149 }
150 using namespace js::types;
151 __attribute__((noinline, noclone)) void
152 TypeCompartment::addPendingRecompile (JSContext *cx, const RecompileInfo & info)
153 {
154 CompilerOutput *co = info.compilerOutput (cx);
155 if (co->pendingRecompilation)
156 if (co->isValid ())
157 CancelOffThreadIonCompile (cx->compartment, co->script);
158 if (co->isValid ())
159 pendingRecompiles->append (info);
160 }
161 volatile JITScript *JSScript::JITScriptHandle::UNJITTABLE;
162 int
163 main ()
164 {
165 JSContext cx;
166 JSCompartment com;
167 RecompileInfo info;
168 cx.compartment = &com;
169 info.outputIndex = 0;
170 js::Vector<CompilerOutput> v;
171 JITScript js;
172 JSScript::JITScriptSet set;
173 __builtin_memset (&set, 0, sizeof set);
174 set.jitHandleCtor.value = &js;
175 JSScript s;
176 s.mJITInfo = &set;
177 CompilerOutput co;
178 co.kindInt = 0;
179 co.constructing = true;
180 co.barriers = false;
181 co.pendingRecompilation = true;
182 co.script = &s;
183 v.mBegin = &co;
184 com.types.constrainedOutputs = &v;
185 com.types.pendingRecompiles = __null;
186 com.types.addPendingRecompile (&cx, info);
187 abort ();
188 }