40 #define DEBUG_NAME "compiler2/PassManager"
48 RT_REGISTER_GROUP(compiler2_rtgroup,
"compiler2-pipeline",
"compiler2 pass pipeline")
50 typedef alloc::unordered_map<PassInfo::IDTy,RTTimer>::type PassTimerMap;
51 PassTimerMap pass_timers;
58 Option<bool> print_pass_dependencies(
"PrintPassDependencies",
"compiler2: print pass dependencies",
false,::
cacao::option::xx_root());
65 assert(PI &&
"Pass not registered");
71 RTTimer &timer = pass_timers[ID];
82 P->set_PassRunner(
this);
92 LOG(
"runPasses" <<
nl);
95 for (
auto i = PS.schedule_begin(),
e = PS.schedule_end();
i !=
e; ++
i) {
99 PassTimerMap::iterator f = pass_timers.find(
id);
100 assert(f != pass_timers.end());
101 RTTimer &timer = f->second;
105 LOG(
"initialize: " << PS.get_Pass_name(
id) <<
nl);
107 LOG(
"start: " << PS.get_Pass_name(
id) <<
nl);
114 PU = P->get_PassUsage(PU);
118 LOG(
"mark invalid" << PS.get_Pass_name(*
i) <<
nl);
121 LOG(
"verifying: " << PS.get_Pass_name(
id) <<
nl);
128 LOG(
"finialize: " << PS.get_Pass_name(
id) <<
nl);
140 #define DEBUG_NAME "compiler2/PassManager/Scheduler"
143 #if defined(ENABLE_LOGGING) || !defined(NDEBUG)
145 PassManager* latest = NULL;
148 if (!latest)
return "PassManager not available";
149 return latest->get_Pass_name(
id);
151 #endif // defined(ENABLE_LOGGING) || !defined(NDEBUG)
153 template <
class InputIterator,
class ValueType>
154 inline bool contains(InputIterator begin, InputIterator end,
const ValueType &val) {
155 return std::find(begin,end,val) != end;
158 template <
class Container,
class ValueType>
160 bool operator()(
const Container &c,
const ValueType &val) {
161 return contains(c.begin(),c.end(),val);
165 template <
class ValueType>
166 struct ContainsFn<typename alloc::
set<ValueType>::type,ValueType> {
167 bool operator()(
const typename alloc::set<ValueType>::type &c,
const ValueType &val) {
168 return c.find(val) != c.end();
172 template <
class ValueType>
173 struct ContainsFn<alloc::unordered_set<ValueType>,ValueType> {
174 bool operator()(
const typename alloc::unordered_set<ValueType>::type &c,
const ValueType &val) {
175 return c.find(val) != c.end();
179 template <
class Container,
class ValueType>
180 inline bool contains(
const Container &c,
const ValueType &val) {
181 return ContainsFn<Container,ValueType>()(c,val);
185 typedef alloc::unordered_map<PassInfo::IDTy,PassUsage>::type ID2PUTy;
186 typedef alloc::unordered_map<PassInfo::IDTy,alloc::unordered_set<PassInfo::IDTy>::type >::type ID2MapTy;
189 public std::unary_function<PassInfo::IDTy,void> {
194 : reverse_require_map(reverse_require_map), ready(ready) {}
197 if (
ready.erase(
id)) {
198 LOG3(
" invalidated: " << get_Pass_name(
id) <<
nl);
204 class PassScheduler {
208 alloc::list<PassInfo::IDTy>::type &
stack;
217 : unhandled(unhandled), ready(ready), stack(stack), new_schedule(new_schedule),
218 pu_map(pu_map), reverse_require_map(reverse_require_map) {}
221 if (contains(
ready,
id))
return;
223 if (contains(
stack,
id)) {
224 ABORT_MSG(
"PassManager: dependency cycle detected",
225 "Pass " << get_Pass_name(
id) <<
" already stacked for scheduling!");
230 LOG3(
"prescheduled: " << get_Pass_name(
id) <<
nl);
237 LOG3(
" schedule_after: " << get_Pass_name(*
i) <<
nl);
246 LOG3(
" requires: " << get_Pass_name(*
i) <<
nl);
254 LOG3(
"scheduled: " << get_Pass_name(
id) <<
nl);
261 LOG3(
" modifies: " << get_Pass_name(*
i) <<
nl);
274 struct RunBefore :
public std::unary_function<PassInfo::IDTy,void> {
279 : pu_map(pu_map), id(id) {}
283 pu_map[before].add_requires(
id);
287 struct ScheduleBefore :
public std::unary_function<PassInfo::IDTy,void> {
292 : pu_map(pu_map), id(id) {}
295 pu_map[before].add_schedule_after(
id);
299 struct AddReverseRequire :
public std::unary_function<PassInfo::IDTy,void> {
304 : map(map), id(id) {}
307 map[required_by].insert(
id);
311 struct ReverseRequire :
312 public std::unary_function<ID2PUTy::value_type,void> {
315 ReverseRequire(ID2MapTy &
map) : map(map) {}
317 void operator()(argument_type pair) {
318 std::for_each(pair.second.requires_begin(), pair.second.requires_end(),AddReverseRequire(
map,pair.first));
325 #if defined(ENABLE_LOGGING) || !defined(NDEBUG)
330 if (option::print_pass_dependencies) {
347 if (!pass->is_enabled()) {
355 pass->get_PassUsage(PA);
362 std::for_each(pu_map.begin(),pu_map.end(),ReverseRequire(reverse_require_map));
365 PassScheduler scheduler(unhandled,ready,stack,new_schedule,pu_map,reverse_require_map);
366 while (!unhandled.empty()) {
368 unhandled.pop_front();
371 assert(stack.empty());
375 LOG2(
"old Schedule:" <<
nl);
376 for (ScheduleListTy::const_iterator
i =
schedule.begin(),
380 LOG2(
"new Schedule:" <<
nl);
381 for (ScheduleListTy::const_iterator
i = new_schedule.begin(),
382 e = new_schedule.end();
i !=
e ; ++
i) {
ID2MapTy & reverse_require_map
PassUPtrTy & get_Pass(PassInfo::IDTy ID)
std::unique_ptr< Pass > PassUPtrTy
ResultReadyMapTy result_ready
Map of ready results.
static PassManager & get()
const_iterator destroys_end() const
std::deque< T, Allocator< T > > type
alloc::vector< PassInfo::IDTy >::type ScheduleListTy
#define DEBUG_COND_N(VERBOSE)
std::unordered_set< PassInfo::IDTy, std::hash< PassInfo::IDTy >, std::equal_to< PassInfo::IDTy >, Allocator< PassInfo::IDTy > > type
PassUPtrTy create_Pass(PassInfo::IDTy ID) const
void print_PassDependencyGraph()
#define RT_REGISTER_GROUP(var, name, description)
Register a new (toplevel) group.
std::list< T, Allocator< T > > type
PassManager::ScheduleListTy & new_schedule
const_iterator schedule_before_end() const
const_iterator run_before_begin() const
alloc::list< PassInfo::IDTy >::type & stack
Stores the interdependencies of a pass.
const_iterator schedule_before_begin() const
PassMapTy passes
Stores pass instances so other passes can retrieve their results.
static PassInfoMapTy & registered_passes()
Pass * create_Pass() const
This file contains the real-time timing utilities.
This file contains the command line option parsing library.
#define LOG(STMT)
Analogous to DEBUG.
const char * get_Pass_name(PassInfo::IDTy ID)
jmethodID jint const void jint const jvmtiAddrLocationMap * map
const_iterator destroys_begin() const
const char * get_name() const
alloc::deque< PassInfo::IDTy >::type & unhandled
const_iterator run_before_end() const
PIIDSet::const_iterator const_iterator
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
void runPasses(JITData &JD)
run passes
ScheduleListTy schedule
This is the pass schedule.