Index: src/Common/Stats/Base.h
===================================================================
--- src/Common/Stats/Base.h	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,86 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Heap.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Fri Mar 03 14:53:53 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <cstdint>
-#include <iostream>
-
-namespace Stats {
-	namespace Base {
-		class TreeImpl;
-
-		struct TreeTop {
-			TreeImpl * head = nullptr;
-			TreeImpl * tail = nullptr;
-
-			inline void append(TreeImpl * node);
-		};
-
-		template<typename func_t>
-		void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy = false);
-
-		class TreeImpl {
-		public:
-			virtual void print(std::ostream &) = 0;
-
-			const char * const name;
-			TreeImpl(const char * const name) : name(name) {}
-
-		protected:
-			virtual ~TreeImpl() = default;
-
-			TreeImpl * next = nullptr;
-			TreeTop children;
-
-			friend struct TreeTop;
-
-			template<typename func_t>
-			friend void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy);
-		};
-
-		void TreeTop::append(TreeImpl * node) {
-			if(!head) { head = node; }
-			else      { tail->next = node;}
-			tail = node;
-		}
-
-		template<typename func_t>
-		inline void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy) {
-			auto it = range.head;
-			while(it) {
-				auto next = it->next;
-				func(it, level);
-				ForAll(it->children, level + 1, func);
-				if(destroy) delete it;
-				it = next;
-			}
-		}
-
-		template<TreeTop & top>
-		class Tree : public TreeImpl {
-		public:
-			Tree(const char * const name) : TreeImpl{name} {
-				top.append(this);
-			}
-
-			Tree(const char * const name, Tree * parent) : TreeImpl{name} {
-				parent->children.append(this);
-			}
-		protected:
-			virtual ~Tree() = default;
-		};
-	}
-}
Index: src/Common/Stats/Base.hpp
===================================================================
--- src/Common/Stats/Base.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Base.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,86 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Heap.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Fri Mar 03 14:53:53 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+#include <cstdint>
+#include <iostream>
+
+namespace Stats {
+	namespace Base {
+		class TreeImpl;
+
+		struct TreeTop {
+			TreeImpl * head = nullptr;
+			TreeImpl * tail = nullptr;
+
+			inline void append(TreeImpl * node);
+		};
+
+		template<typename func_t>
+		void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy = false);
+
+		class TreeImpl {
+		public:
+			virtual void print(std::ostream &) = 0;
+
+			const char * const name;
+			TreeImpl(const char * const name) : name(name) {}
+
+		protected:
+			virtual ~TreeImpl() = default;
+
+			TreeImpl * next = nullptr;
+			TreeTop children;
+
+			friend struct TreeTop;
+
+			template<typename func_t>
+			friend void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy);
+		};
+
+		void TreeTop::append(TreeImpl * node) {
+			if(!head) { head = node; }
+			else      { tail->next = node;}
+			tail = node;
+		}
+
+		template<typename func_t>
+		inline void ForAll(TreeTop & range, std::size_t level, func_t func, bool destroy) {
+			auto it = range.head;
+			while(it) {
+				auto next = it->next;
+				func(it, level);
+				ForAll(it->children, level + 1, func);
+				if(destroy) delete it;
+				it = next;
+			}
+		}
+
+		template<TreeTop & top>
+		class Tree : public TreeImpl {
+		public:
+			Tree(const char * const name) : TreeImpl{name} {
+				top.append(this);
+			}
+
+			Tree(const char * const name, Tree * parent) : TreeImpl{name} {
+				parent->children.append(this);
+			}
+		protected:
+			virtual ~Tree() = default;
+		};
+	}
+}
Index: src/Common/Stats/Counter.cc
===================================================================
--- src/Common/Stats/Counter.cc	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,58 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Counter.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Thu Feb 28 13::27:10 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#include "Counter.h"
-
-#include <algorithm>
-#include <cstring>
-#include <functional>
-#include <iomanip>
-
-namespace Stats {
-	namespace Counters {
-		void print() {
-			if(!top.head) return;
-			size_t nc = 0;
-			Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
-				nc = std::max(nc, (4 * level) + std::strlen(node->name));
-			});
-
-			const char * const title = "Counter Statistic";
-			size_t nct = nc + 14;
-			std::cerr << std::string(nct, '=') << std::endl;
-			std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
-			std::cerr << title << std::endl;
-			std::cerr << std::string(nct, '-') << std::endl;
-
-
-			Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
-				std::cerr << std::string(level * 4, ' ');
-				std::cerr << node->name;
-				std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
-				std::cerr << " | ";
-				std::cerr << std::setw(9);
-				node->print(std::cerr);
-				std::cerr << " |";
-				std::cerr << '\n';
-			}, true);
-
-			std::cerr << std::string(nct, '-') << std::endl;
-		}
-
-		Base::TreeTop top;
-
-		extern bool enabled;
-	}
-}
Index: src/Common/Stats/Counter.cpp
===================================================================
--- src/Common/Stats/Counter.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Counter.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,58 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Counter.cpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Thu Feb 28 13::27:10 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "Counter.hpp"
+
+#include <algorithm>
+#include <cstring>
+#include <functional>
+#include <iomanip>
+
+namespace Stats {
+	namespace Counters {
+		void print() {
+			if(!top.head) return;
+			size_t nc = 0;
+			Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
+				nc = std::max(nc, (4 * level) + std::strlen(node->name));
+			});
+
+			const char * const title = "Counter Statistic";
+			size_t nct = nc + 14;
+			std::cerr << std::string(nct, '=') << std::endl;
+			std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
+			std::cerr << title << std::endl;
+			std::cerr << std::string(nct, '-') << std::endl;
+
+
+			Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
+				std::cerr << std::string(level * 4, ' ');
+				std::cerr << node->name;
+				std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
+				std::cerr << " | ";
+				std::cerr << std::setw(9);
+				node->print(std::cerr);
+				std::cerr << " |";
+				std::cerr << '\n';
+			}, true);
+
+			std::cerr << std::string(nct, '-') << std::endl;
+		}
+
+		Base::TreeTop top;
+
+		extern bool enabled;
+	}
+}
Index: src/Common/Stats/Counter.h
===================================================================
--- src/Common/Stats/Counter.h	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,146 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Counter.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Thu Feb 28 12::05:10 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <cstdint>
-#include <iostream>
-
-#include "Common/Stats/Base.h"
-
-#if defined( NO_STATISTICS )
-	#define NO_COUNTER_STATISTICS
-#endif
-
-namespace Stats {
-	namespace Counters {
-# 		if defined(NO_COUNTERS_STATISTICS)
-
-			static inline void print() {}
-
-			class CounterGroup {
-			public:
-			};
-
-			class SimpleCounter {
-			public:
-				inline void operator++() {}
-				inline void operator++(int) {}
-				inline void operator+=(size_t) {}
-			};
-
-			template<typename T>
-			class AverageCounter {
-			public:
-				inline void push(T value) {}
-			};
-
-			template<typename T>
-			class MaxCounter {
-			public:
-				inline void push(T value) {}
-			};
-
-			template<typename counter_t>
-			counter_t * build(const char * const name) {
-				return nullptr;
-			}
-
-			template<typename counter_t>
-			counter_t * build(const char * const name, Base::Tree<top> * parent) {
-					return nullptr;
-			}
-#		else
-			extern bool enabled;
-
-			extern Base::TreeTop top;
-
-			class CounterGroup : public Base::Tree<top> {
-			public:
-				CounterGroup(const char * const name ) : Base::Tree<top>(name) {}
-				CounterGroup(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent) {}
-
-				virtual void print(std::ostream & os) override { os << ""; }
-			protected:
-				virtual ~CounterGroup() = default;
-			};
-
-			class SimpleCounter : public Base::Tree<top> {
-			public:
-				SimpleCounter(const char * const name ) : Base::Tree<top>(name) {}
-				SimpleCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent) {}
-
-				virtual void print(std::ostream & os) override { os << count; }
-
-				inline void operator++()             { if(!enabled) return; count++;        }
-				inline void operator++(int)          { if(!enabled) return; count++;        }
-				inline void operator+=(size_t value) { if(!enabled) return; count += value; }
-
-			protected:
-				virtual ~SimpleCounter() = default;
-
-			private:
-				size_t count = 0;
-			};
-
-			template<typename T>
-			class AverageCounter : public Base::Tree<top> {
-			public:
-				AverageCounter(const char * const name ) : Base::Tree<top>(name), sum{} {}
-				AverageCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent), sum{} {}
-
-				virtual void print(std::ostream & os) { os << sum / count; }
-
-				inline void push(T value) { if(!enabled) return; sum += value; count++; }
-
-			protected:
-				virtual ~AverageCounter() = default;
-
-			private:
-				T sum;
-				size_t count = 1;
-			};
-
-			template<typename T>
-			class MaxCounter : public Base::Tree<top> {
-			public:
-				MaxCounter(const char * const name ) : Base::Tree<top>(name), max{} {}
-				MaxCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent), max{} {}
-
-				virtual void print(std::ostream & os) { os << max; }
-
-				inline void push(T value) { if(!enabled) return; max = std::max(max, value); }
-
-			protected:
-				virtual ~MaxCounter() = default;
-
-			private:
-				T max;
-			};
-
-			template<typename counter_t>
-			counter_t * build(const char * const name) {
-				if(!enabled) return nullptr;
-				return new counter_t(name);
-			}
-
-			template<typename counter_t>
-			counter_t * build(const char * const name, Base::Tree<top> * parent) {
-				if(!enabled) return nullptr;
-				return new counter_t(name, parent);
-			}
-#		endif
-	}
-}
Index: src/Common/Stats/Counter.hpp
===================================================================
--- src/Common/Stats/Counter.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Counter.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,146 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Counter.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Thu Feb 28 12::05:10 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+#include <cstdint>
+#include <iostream>
+
+#include "Common/Stats/Base.hpp"
+
+#if defined( NO_STATISTICS )
+	#define NO_COUNTER_STATISTICS
+#endif
+
+namespace Stats {
+	namespace Counters {
+# 		if defined(NO_COUNTERS_STATISTICS)
+
+			static inline void print() {}
+
+			class CounterGroup {
+			public:
+			};
+
+			class SimpleCounter {
+			public:
+				inline void operator++() {}
+				inline void operator++(int) {}
+				inline void operator+=(size_t) {}
+			};
+
+			template<typename T>
+			class AverageCounter {
+			public:
+				inline void push(T value) {}
+			};
+
+			template<typename T>
+			class MaxCounter {
+			public:
+				inline void push(T value) {}
+			};
+
+			template<typename counter_t>
+			counter_t * build(const char * const name) {
+				return nullptr;
+			}
+
+			template<typename counter_t>
+			counter_t * build(const char * const name, Base::Tree<top> * parent) {
+					return nullptr;
+			}
+#		else
+			extern bool enabled;
+
+			extern Base::TreeTop top;
+
+			class CounterGroup : public Base::Tree<top> {
+			public:
+				CounterGroup(const char * const name ) : Base::Tree<top>(name) {}
+				CounterGroup(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent) {}
+
+				virtual void print(std::ostream & os) override { os << ""; }
+			protected:
+				virtual ~CounterGroup() = default;
+			};
+
+			class SimpleCounter : public Base::Tree<top> {
+			public:
+				SimpleCounter(const char * const name ) : Base::Tree<top>(name) {}
+				SimpleCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent) {}
+
+				virtual void print(std::ostream & os) override { os << count; }
+
+				inline void operator++()             { if(!enabled) return; count++;        }
+				inline void operator++(int)          { if(!enabled) return; count++;        }
+				inline void operator+=(size_t value) { if(!enabled) return; count += value; }
+
+			protected:
+				virtual ~SimpleCounter() = default;
+
+			private:
+				size_t count = 0;
+			};
+
+			template<typename T>
+			class AverageCounter : public Base::Tree<top> {
+			public:
+				AverageCounter(const char * const name ) : Base::Tree<top>(name), sum{} {}
+				AverageCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent), sum{} {}
+
+				virtual void print(std::ostream & os) { os << sum / count; }
+
+				inline void push(T value) { if(!enabled) return; sum += value; count++; }
+
+			protected:
+				virtual ~AverageCounter() = default;
+
+			private:
+				T sum;
+				size_t count = 1;
+			};
+
+			template<typename T>
+			class MaxCounter : public Base::Tree<top> {
+			public:
+				MaxCounter(const char * const name ) : Base::Tree<top>(name), max{} {}
+				MaxCounter(const char * const name, Base::Tree<top> * parent) : Base::Tree<top>(name, parent), max{} {}
+
+				virtual void print(std::ostream & os) { os << max; }
+
+				inline void push(T value) { if(!enabled) return; max = std::max(max, value); }
+
+			protected:
+				virtual ~MaxCounter() = default;
+
+			private:
+				T max;
+			};
+
+			template<typename counter_t>
+			counter_t * build(const char * const name) {
+				if(!enabled) return nullptr;
+				return new counter_t(name);
+			}
+
+			template<typename counter_t>
+			counter_t * build(const char * const name, Base::Tree<top> * parent) {
+				if(!enabled) return nullptr;
+				return new counter_t(name, parent);
+			}
+#		endif
+	}
+}
Index: src/Common/Stats/Heap.cc
===================================================================
--- src/Common/Stats/Heap.cc	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,272 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Heap.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Thu May  3 16:16:10 2018
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri May  4 17:27:31 2018
-// Update Count     : 28
-//
-
-#include <cassert>
-#include <cmath>
-#include <cstddef>
-#include <cstring>
-#include <iomanip>
-#include <iostream>
-
-#if defined(__has_feature)
-	#if __has_feature(address_sanitizer)
-		#define NO_HEAP_STATISTICS
-	# endif
-#endif
-
-#if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
-	#if !defined(NO_HEAP_STATISTICS)
-		#define NO_HEAP_STATISTICS
-	#endif
-#endif
-
-namespace Stats {
-	namespace Heap {
-#if defined( NO_HEAP_STATISTICS )
-		void newPass( const char * const ) {}
-
-		void print() {}
-#else
-		extern bool enabled;
-
-		struct StatBlock {
-			const char * name  = nullptr;	///< Name of this pass
-			size_t mallocs     = 0;			///< Allocations in this pass
-			size_t frees       = 0;			///< Frees in this pass
-			size_t n_allocs    = 0;			///< Current number of live allocations
-			size_t peak_allocs = 0;			///< Peak number of live allocations this pass
-		};
-
-		StatBlock    passes[100] = {{ "Pre-Parse", 0, 0, 0, 0 }};
-		const size_t passes_size = sizeof(passes) / sizeof(passes[0]);
-		size_t       passes_cnt = 1;
-
-		StatBlock    stacktrace_stats[100];
-		size_t       stacktrace_stats_count = 0;
-		bool         stacktrace_stats_enabled = true;
-
-		size_t       trace[1000];
-		const size_t stacktrace_max_depth = sizeof(trace) / sizeof(size_t);
-		size_t       stacktrace_depth;
-
-		size_t new_stacktrace_id(const char * const name) {
-			stacktrace_stats[stacktrace_stats_count].name = name;
-			return stacktrace_stats_count++;
-		}
-
-		void stacktrace_push(size_t id) {
-			++stacktrace_depth;
-			assertf(stacktrace_depth < stacktrace_max_depth, "Stack trace too deep: increase size of array in Heap.cc");
-			trace[stacktrace_depth] = id;
-		}
-
-		void stacktrace_pop() {
-			assertf(stacktrace_depth > 0, "Invalid stack tracing operation: trace is empty");
-			--stacktrace_depth;
-		}
-
-		void newPass( const char * const name ) {
-			passes[passes_cnt].name    = name;
-			passes[passes_cnt].mallocs = 0;
-			passes[passes_cnt].frees   = 0;
-			passes[passes_cnt].n_allocs
-				= passes[passes_cnt].peak_allocs
-				= passes[passes_cnt-1].n_allocs;
-			passes_cnt++;
-
-			assertf(passes_cnt < passes_size, "Too many passes for Stats::Heap, increase the size of the array in Heap.cc");
-		}
-
-		void print(size_t value, size_t total) {
-			std::cerr << std::setw(12) << value;
-			std::cerr << "(" << std::setw(3);
-			std::cerr << (value == 0 ? 0 : value * 100 / total);
-			std::cerr << "%) | ";
-		}
-
-		void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees, size_t overall_peak) {
-			std::cerr << std::setw(nc) << stat.name;
-			std::cerr << " | ";
-
-			print(stat.mallocs,     total_mallocs);
-			print(stat.frees,       total_frees  );
-			print(stat.peak_allocs, overall_peak );
-			std::cerr << "\n";
-		}
-
-		void print(char c, size_t nc) {
-			for(size_t i = 0; i < nc; i++) {
-				std::cerr << c;
-			}
-			std::cerr << '\n';
-		}
-
-		void print() {
-			if(!enabled) return;
-
-			size_t nc = 0;
-			size_t total_mallocs = 0;
-			size_t total_frees   = 0;
-			size_t overall_peak  = 0;
-			for(size_t i = 0; i < passes_cnt; i++) {
-				nc = std::max(nc, std::strlen(passes[i].name));
-				total_mallocs += passes[i].mallocs;
-				total_frees   += passes[i].frees;
-				overall_peak = std::max(overall_peak, passes[i].peak_allocs);
-			}
-			size_t nct = nc + 65;
-
-			const char * const title = "Heap Usage Statistic";
-			print('=', nct);
-			for(size_t i = 0; i < (nct - std::strlen(title)) / 2; i++) std::cerr << ' ';
-			std::cerr << title << std::endl;
-			print('-', nct);
-			std::cerr << std::setw(nc) << "Pass";
-			std::cerr << " |       Malloc Count |         Free Count |        Peak Allocs |" << std::endl;
-
-			print('-', nct);
-			for(size_t i = 0; i < passes_cnt; i++) {
-				print(passes[i], nc, total_mallocs, total_frees, overall_peak);
-			}
-
-			print('-', nct);
-			std::cerr << std::setw(nc) << "Trace";
-			std::cerr << " |       Malloc Count |         Free Count |        Peak Allocs |" << std::endl;
-
-			print('-', nct);
-			for (size_t i = 0; i < stacktrace_stats_count; i++) {
-				print(stacktrace_stats[i], nc, total_mallocs, total_frees, overall_peak);
-			}
-			print('-', nct);
-			print({"Sum", total_mallocs, total_frees, 0, overall_peak},
-				nc, total_mallocs, total_frees, overall_peak);
-
-		}
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-		extern "C" {
-#include <dlfcn.h>
-#include <execinfo.h>
-		}
-
-	//=============================================================================================
-	// Interposing helpers
-	//=============================================================================================
-
-		typedef void (* generic_fptr_t)(void);
-		generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
-			const char * error;
-
-			static void * library;
-			if ( ! library ) {
-#				if defined( RTLD_NEXT )
-					library = RTLD_NEXT;
-#				else
-					// missing RTLD_NEXT => must hard-code library name, assuming libstdc++
-					library = dlopen( "libc.so.6", RTLD_LAZY );
-					error = dlerror();
-					if ( error ) {
-						std::cerr << "interpose_symbol : failed to open libc, " << error << std::endl;
-						abort();
-					}
-#				endif // RTLD_NEXT
-			} // if
-
-			generic_fptr_t fptr;
-
-#			if defined( _GNU_SOURCE )
-				if ( version ) {
-					fptr = (generic_fptr_t)dlvsym( library, symbol, version );
-				} else {
-					fptr = (generic_fptr_t)dlsym( library, symbol );
-				}
-#			else
-				fptr = (generic_fptr_t)dlsym( library, symbol );
-#			endif // _GNU_SOURCE
-
-			error = dlerror();
-			if ( error ) {
-				std::cerr << "interpose_symbol : internal error, " << error << std::endl;
-				abort();
-			}
-
-			return fptr;
-		}
-
-		extern "C" {
-			void * malloc( size_t size ) __attribute__((malloc));
-			void * malloc( size_t size ) {
-				static auto __malloc = reinterpret_cast<void * (*)(size_t)>(interpose_symbol( "malloc", nullptr ));
-				if( enabled && passes_cnt > 0 ) {
-					passes[passes_cnt - 1].mallocs++;
-					passes[passes_cnt - 1].n_allocs++;
-					passes[passes_cnt - 1].peak_allocs
-						= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
-				}
-
-				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
-					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
-				}
-				return __malloc( size );
-			}
-
-			void free( void * ptr ) {
-				static auto __free = reinterpret_cast<void   (*)(void *)>(interpose_symbol( "free", nullptr ));
-				if( enabled && passes_cnt > 0 ) {
-					passes[passes_cnt - 1].frees++;
-					passes[passes_cnt - 1].n_allocs--;
-				}
-				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
-					stacktrace_stats[trace[stacktrace_depth]].frees++;
-				}
-				return __free( ptr );
-			}
-
-			void * calloc( size_t nelem, size_t size ) {
-				static auto __calloc = reinterpret_cast<void * (*)(size_t, size_t)>(interpose_symbol( "calloc", nullptr ));
-				if( enabled && passes_cnt > 0 ) {
-					passes[passes_cnt - 1].mallocs++;
-					passes[passes_cnt - 1].n_allocs++;
-					passes[passes_cnt - 1].peak_allocs
-						= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
-				}
-				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
-					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
-				}
-				return __calloc( nelem, size );
-			}
-
-			void * realloc( void * ptr, size_t size ) {
-				static auto __realloc = reinterpret_cast<void * (*)(void *, size_t)>(interpose_symbol( "realloc", nullptr ));
-				void * s = __realloc( ptr, size );
-				if ( enabled && s != ptr && passes_cnt > 0 ) {			// did realloc get new storage ?
-					passes[passes_cnt - 1].mallocs++;
-					passes[passes_cnt - 1].frees++;
-				} // if
-				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
-					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
-					stacktrace_stats[trace[stacktrace_depth]].frees++;
-				}
-				return s;
-			}
-		}
-#endif
-	}
-}
Index: src/Common/Stats/Heap.cpp
===================================================================
--- src/Common/Stats/Heap.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Heap.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,272 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Heap.cc --
+//
+// Author           : Thierry Delisle
+// Created On       : Thu May  3 16:16:10 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri May  4 17:27:31 2018
+// Update Count     : 28
+//
+
+#include <cassert>
+#include <cmath>
+#include <cstddef>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+
+#if defined(__has_feature)
+	#if __has_feature(address_sanitizer)
+		#define NO_HEAP_STATISTICS
+	# endif
+#endif
+
+#if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
+	#if !defined(NO_HEAP_STATISTICS)
+		#define NO_HEAP_STATISTICS
+	#endif
+#endif
+
+namespace Stats {
+	namespace Heap {
+#if defined( NO_HEAP_STATISTICS )
+		void newPass( const char * const ) {}
+
+		void print() {}
+#else
+		extern bool enabled;
+
+		struct StatBlock {
+			const char * name  = nullptr;	///< Name of this pass
+			size_t mallocs     = 0;			///< Allocations in this pass
+			size_t frees       = 0;			///< Frees in this pass
+			size_t n_allocs    = 0;			///< Current number of live allocations
+			size_t peak_allocs = 0;			///< Peak number of live allocations this pass
+		};
+
+		StatBlock    passes[100] = {{ "Pre-Parse", 0, 0, 0, 0 }};
+		const size_t passes_size = sizeof(passes) / sizeof(passes[0]);
+		size_t       passes_cnt = 1;
+
+		StatBlock    stacktrace_stats[100];
+		size_t       stacktrace_stats_count = 0;
+		bool         stacktrace_stats_enabled = true;
+
+		size_t       trace[1000];
+		const size_t stacktrace_max_depth = sizeof(trace) / sizeof(size_t);
+		size_t       stacktrace_depth;
+
+		size_t new_stacktrace_id(const char * const name) {
+			stacktrace_stats[stacktrace_stats_count].name = name;
+			return stacktrace_stats_count++;
+		}
+
+		void stacktrace_push(size_t id) {
+			++stacktrace_depth;
+			assertf(stacktrace_depth < stacktrace_max_depth, "Stack trace too deep: increase size of array in Heap.cc");
+			trace[stacktrace_depth] = id;
+		}
+
+		void stacktrace_pop() {
+			assertf(stacktrace_depth > 0, "Invalid stack tracing operation: trace is empty");
+			--stacktrace_depth;
+		}
+
+		void newPass( const char * const name ) {
+			passes[passes_cnt].name    = name;
+			passes[passes_cnt].mallocs = 0;
+			passes[passes_cnt].frees   = 0;
+			passes[passes_cnt].n_allocs
+				= passes[passes_cnt].peak_allocs
+				= passes[passes_cnt-1].n_allocs;
+			passes_cnt++;
+
+			assertf(passes_cnt < passes_size, "Too many passes for Stats::Heap, increase the size of the array in Heap.cc");
+		}
+
+		void print(size_t value, size_t total) {
+			std::cerr << std::setw(12) << value;
+			std::cerr << "(" << std::setw(3);
+			std::cerr << (value == 0 ? 0 : value * 100 / total);
+			std::cerr << "%) | ";
+		}
+
+		void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees, size_t overall_peak) {
+			std::cerr << std::setw(nc) << stat.name;
+			std::cerr << " | ";
+
+			print(stat.mallocs,     total_mallocs);
+			print(stat.frees,       total_frees  );
+			print(stat.peak_allocs, overall_peak );
+			std::cerr << "\n";
+		}
+
+		void print(char c, size_t nc) {
+			for(size_t i = 0; i < nc; i++) {
+				std::cerr << c;
+			}
+			std::cerr << '\n';
+		}
+
+		void print() {
+			if(!enabled) return;
+
+			size_t nc = 0;
+			size_t total_mallocs = 0;
+			size_t total_frees   = 0;
+			size_t overall_peak  = 0;
+			for(size_t i = 0; i < passes_cnt; i++) {
+				nc = std::max(nc, std::strlen(passes[i].name));
+				total_mallocs += passes[i].mallocs;
+				total_frees   += passes[i].frees;
+				overall_peak = std::max(overall_peak, passes[i].peak_allocs);
+			}
+			size_t nct = nc + 65;
+
+			const char * const title = "Heap Usage Statistic";
+			print('=', nct);
+			for(size_t i = 0; i < (nct - std::strlen(title)) / 2; i++) std::cerr << ' ';
+			std::cerr << title << std::endl;
+			print('-', nct);
+			std::cerr << std::setw(nc) << "Pass";
+			std::cerr << " |       Malloc Count |         Free Count |        Peak Allocs |" << std::endl;
+
+			print('-', nct);
+			for(size_t i = 0; i < passes_cnt; i++) {
+				print(passes[i], nc, total_mallocs, total_frees, overall_peak);
+			}
+
+			print('-', nct);
+			std::cerr << std::setw(nc) << "Trace";
+			std::cerr << " |       Malloc Count |         Free Count |        Peak Allocs |" << std::endl;
+
+			print('-', nct);
+			for (size_t i = 0; i < stacktrace_stats_count; i++) {
+				print(stacktrace_stats[i], nc, total_mallocs, total_frees, overall_peak);
+			}
+			print('-', nct);
+			print({"Sum", total_mallocs, total_frees, 0, overall_peak},
+				nc, total_mallocs, total_frees, overall_peak);
+
+		}
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+		extern "C" {
+#include <dlfcn.h>
+#include <execinfo.h>
+		}
+
+	//=============================================================================================
+	// Interposing helpers
+	//=============================================================================================
+
+		typedef void (* generic_fptr_t)(void);
+		generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
+			const char * error;
+
+			static void * library;
+			if ( ! library ) {
+#				if defined( RTLD_NEXT )
+					library = RTLD_NEXT;
+#				else
+					// missing RTLD_NEXT => must hard-code library name, assuming libstdc++
+					library = dlopen( "libc.so.6", RTLD_LAZY );
+					error = dlerror();
+					if ( error ) {
+						std::cerr << "interpose_symbol : failed to open libc, " << error << std::endl;
+						abort();
+					}
+#				endif // RTLD_NEXT
+			} // if
+
+			generic_fptr_t fptr;
+
+#			if defined( _GNU_SOURCE )
+				if ( version ) {
+					fptr = (generic_fptr_t)dlvsym( library, symbol, version );
+				} else {
+					fptr = (generic_fptr_t)dlsym( library, symbol );
+				}
+#			else
+				fptr = (generic_fptr_t)dlsym( library, symbol );
+#			endif // _GNU_SOURCE
+
+			error = dlerror();
+			if ( error ) {
+				std::cerr << "interpose_symbol : internal error, " << error << std::endl;
+				abort();
+			}
+
+			return fptr;
+		}
+
+		extern "C" {
+			void * malloc( size_t size ) __attribute__((malloc));
+			void * malloc( size_t size ) {
+				static auto __malloc = reinterpret_cast<void * (*)(size_t)>(interpose_symbol( "malloc", nullptr ));
+				if( enabled && passes_cnt > 0 ) {
+					passes[passes_cnt - 1].mallocs++;
+					passes[passes_cnt - 1].n_allocs++;
+					passes[passes_cnt - 1].peak_allocs
+						= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
+				}
+
+				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
+					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
+				}
+				return __malloc( size );
+			}
+
+			void free( void * ptr ) {
+				static auto __free = reinterpret_cast<void   (*)(void *)>(interpose_symbol( "free", nullptr ));
+				if( enabled && passes_cnt > 0 ) {
+					passes[passes_cnt - 1].frees++;
+					passes[passes_cnt - 1].n_allocs--;
+				}
+				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
+					stacktrace_stats[trace[stacktrace_depth]].frees++;
+				}
+				return __free( ptr );
+			}
+
+			void * calloc( size_t nelem, size_t size ) {
+				static auto __calloc = reinterpret_cast<void * (*)(size_t, size_t)>(interpose_symbol( "calloc", nullptr ));
+				if( enabled && passes_cnt > 0 ) {
+					passes[passes_cnt - 1].mallocs++;
+					passes[passes_cnt - 1].n_allocs++;
+					passes[passes_cnt - 1].peak_allocs
+						= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
+				}
+				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
+					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
+				}
+				return __calloc( nelem, size );
+			}
+
+			void * realloc( void * ptr, size_t size ) {
+				static auto __realloc = reinterpret_cast<void * (*)(void *, size_t)>(interpose_symbol( "realloc", nullptr ));
+				void * s = __realloc( ptr, size );
+				if ( enabled && s != ptr && passes_cnt > 0 ) {			// did realloc get new storage ?
+					passes[passes_cnt - 1].mallocs++;
+					passes[passes_cnt - 1].frees++;
+				} // if
+				if ( stacktrace_stats_enabled && stacktrace_depth > 0) {
+					stacktrace_stats[trace[stacktrace_depth]].mallocs++;
+					stacktrace_stats[trace[stacktrace_depth]].frees++;
+				}
+				return s;
+			}
+		}
+#endif
+	}
+}
Index: src/Common/Stats/Heap.h
===================================================================
--- src/Common/Stats/Heap.h	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,27 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Heap.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Thu May  3 16:16:10 2018
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri May  4 14:34:08 2018
-// Update Count     : 3
-//
-
-#pragma once
-
-namespace Stats {
-	namespace Heap {
-		void newPass( const char * const name );
-		void print();
-
-		size_t new_stacktrace_id(const char * const name);
-		void stacktrace_push(size_t id);
-		void stacktrace_pop();
-	}
-}
Index: src/Common/Stats/Heap.hpp
===================================================================
--- src/Common/Stats/Heap.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Heap.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,27 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Heap.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Thu May  3 16:16:10 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri May  4 14:34:08 2018
+// Update Count     : 3
+//
+
+#pragma once
+
+namespace Stats {
+	namespace Heap {
+		void newPass( const char * const name );
+		void print();
+
+		size_t new_stacktrace_id(const char * const name);
+		void stacktrace_push(size_t id);
+		void stacktrace_pop();
+	}
+}
Index: src/Common/Stats/ResolveTime.cc
===================================================================
--- src/Common/Stats/ResolveTime.cc	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,67 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// ResolveTime.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Wed Sep 16 15:45:51 2020
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#include "ResolveTime.h"
-
-#include <fstream>
-#include <iomanip>
-
-#include "AST/Fwd.hpp"
-#include "AST/Expr.hpp"
-#include "AST/Print.hpp"
-#include "AST/Type.hpp"
-
-namespace Stats {
-	namespace ResolveTime {
-		static inline long long rdtscl(void) {
-			#if defined( __i386 ) || defined( __x86_64 )
-				unsigned int lo, hi;
-				__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
-				return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
-			#elif defined( __aarch64__ )
-				int64_t value;
-				asm volatile("mrs %0, cntvct_el0" : "=r"(value));
-				return value;
-			#else
-				#error unknown hardware architecture
-			#endif
-		}
-
-		extern bool enabled;
-		bool started = false;
-		long long before;
-		std::ostream & out = std::cout;
-
-		void start( const ast::Expr * expr ) {
-			if(enabled) {
-				assert(!started);
-				started = true;
-
-				out << expr->location << " : ";
-
-				before = rdtscl();
-			}
-		}
-		void stop() {
-			if(enabled) {
-				assert(started);
-				auto after = rdtscl();
-				out << (after - before) << std::endl;
-
-				started = false;
-			}
-		}
-	};
-};
Index: src/Common/Stats/ResolveTime.cpp
===================================================================
--- src/Common/Stats/ResolveTime.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/ResolveTime.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,67 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ResolveTime.cpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Wed Sep 16 15:45:51 2020
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "ResolveTime.hpp"
+
+#include <fstream>
+#include <iomanip>
+
+#include "AST/Fwd.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Print.hpp"
+#include "AST/Type.hpp"
+
+namespace Stats {
+	namespace ResolveTime {
+		static inline long long rdtscl(void) {
+			#if defined( __i386 ) || defined( __x86_64 )
+				unsigned int lo, hi;
+				__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+				return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
+			#elif defined( __aarch64__ )
+				int64_t value;
+				asm volatile("mrs %0, cntvct_el0" : "=r"(value));
+				return value;
+			#else
+				#error unknown hardware architecture
+			#endif
+		}
+
+		extern bool enabled;
+		bool started = false;
+		long long before;
+		std::ostream & out = std::cout;
+
+		void start( const ast::Expr * expr ) {
+			if(enabled) {
+				assert(!started);
+				started = true;
+
+				out << expr->location << " : ";
+
+				before = rdtscl();
+			}
+		}
+		void stop() {
+			if(enabled) {
+				assert(started);
+				auto after = rdtscl();
+				out << (after - before) << std::endl;
+
+				started = false;
+			}
+		}
+	};
+};
Index: src/Common/Stats/ResolveTime.h
===================================================================
--- src/Common/Stats/ResolveTime.h	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,38 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// ResolveTime.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Wed Sep 16 15:45:51 2020
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include "Common/Stats/Base.h"
-
-#if defined( NO_STATISTICS )
-	#define NO_RESOLVE_TIME_STATISTICS
-#endif
-
-namespace ast {
-	class Expr;
-}
-
-namespace Stats {
-	namespace ResolveTime {
-		#if defined(NO_RESOLVE_TIME_STATISTICS)
-			void start( const ast::Expr * ) {}
-			void stop() {}
-		#else
-			void start( const ast::Expr * );
-			void stop();
-		#endif
-	};
-};
Index: src/Common/Stats/ResolveTime.hpp
===================================================================
--- src/Common/Stats/ResolveTime.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/ResolveTime.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,38 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ResolveTime.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Wed Sep 16 15:45:51 2020
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+#include "Common/Stats/Base.hpp"
+
+#if defined( NO_STATISTICS )
+	#define NO_RESOLVE_TIME_STATISTICS
+#endif
+
+namespace ast {
+	class Expr;
+}
+
+namespace Stats {
+	namespace ResolveTime {
+		#if defined(NO_RESOLVE_TIME_STATISTICS)
+			void start( const ast::Expr * ) {}
+			void stop() {}
+		#else
+			void start( const ast::Expr * );
+			void stop();
+		#endif
+	};
+};
Index: src/Common/Stats/Stats.cc
===================================================================
--- src/Common/Stats/Stats.cc	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,91 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Stats.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Fri Mar 01 15:45:08 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-
-namespace Stats {
-	namespace Counters {
-		bool enabled = false;
-		void print();
-	}
-
-	namespace Heap {
-		bool enabled = false;
-		void print();
-	}
-
-	namespace Time {
-		bool enabled = false;
-		void print();
-	}
-
-	namespace ResolveTime {
-		bool enabled = false;
-	}
-
-	struct {
-		const char * const opt;
-		bool & enabled;
-	}
-	statistics[] = {
-		{ "counters", Counters::enabled },
-		{ "heap"    , Heap::enabled },
-		{ "time"    , Time::enabled },
-		{ "resolve" , ResolveTime::enabled },
-	};
-
-	void set_param(std::string & param) {
-		if(param == "all") {
-			for(auto & stat : statistics) {
-				stat.enabled = true;
-			}
-			return;
-		}
-
-		if(param == "none") {
-			for(auto & stat : statistics) {
-				stat.enabled = false;
-			}
-			return;
-		}
-
-		for(auto & stat : statistics) {
-			if(stat.opt == param) {
-				stat.enabled = true;
-				return;
-			}
-		}
-
-		std::cerr << "Ignoring unknown statistic " << param << std::endl;
-	}
-
-	void parse_params(const char * const params) {
-		std::stringstream ss(params);
-		while(ss.good()) {
-			std::string substr;
-			getline( ss, substr, ',' );
-			set_param(substr);
-		}
-	}
-
-	void print() {
-		Counters::print();
-		Heap::print();
-		Time::print();
-	}
-}
Index: src/Common/Stats/Stats.cpp
===================================================================
--- src/Common/Stats/Stats.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Stats.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,91 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Stats.cc --
+//
+// Author           : Thierry Delisle
+// Created On       : Fri Mar 01 15:45:08 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+
+namespace Stats {
+	namespace Counters {
+		bool enabled = false;
+		void print();
+	}
+
+	namespace Heap {
+		bool enabled = false;
+		void print();
+	}
+
+	namespace Time {
+		bool enabled = false;
+		void print();
+	}
+
+	namespace ResolveTime {
+		bool enabled = false;
+	}
+
+	struct {
+		const char * const opt;
+		bool & enabled;
+	}
+	statistics[] = {
+		{ "counters", Counters::enabled },
+		{ "heap"    , Heap::enabled },
+		{ "time"    , Time::enabled },
+		{ "resolve" , ResolveTime::enabled },
+	};
+
+	void set_param(std::string & param) {
+		if(param == "all") {
+			for(auto & stat : statistics) {
+				stat.enabled = true;
+			}
+			return;
+		}
+
+		if(param == "none") {
+			for(auto & stat : statistics) {
+				stat.enabled = false;
+			}
+			return;
+		}
+
+		for(auto & stat : statistics) {
+			if(stat.opt == param) {
+				stat.enabled = true;
+				return;
+			}
+		}
+
+		std::cerr << "Ignoring unknown statistic " << param << std::endl;
+	}
+
+	void parse_params(const char * const params) {
+		std::stringstream ss(params);
+		while(ss.good()) {
+			std::string substr;
+			getline( ss, substr, ',' );
+			set_param(substr);
+		}
+	}
+
+	void print() {
+		Counters::print();
+		Heap::print();
+		Time::print();
+	}
+}
Index: src/Common/Stats/Time.cc
===================================================================
--- src/Common/Stats/Time.cc	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,199 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Time.cc --
-//
-// Author           : Thierry Delisle
-// Created On       : Mon Mar 04 15:16:07 2019
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#include "Time.h"
-
-#include <cassert>
-#include <chrono>
-#include <cstdint>
-#include <cstring>
-#include <iostream>
-#include <iomanip>
-#include <stack>
-
-namespace Stats {
-	namespace Time {
-#		if !defined(NO_TIME_STATISTICS)
-			extern bool enabled;
-
-			Base::TreeTop top;
-
-			typedef  std::chrono::time_point<std::chrono::high_resolution_clock> point_t;
-			std::chrono::duration<double> total;
-
-			point_t global_begin;
-
-			int prevl = 0;
-			int currl = 0;
-
-			template<typename T>
-			static inline std::ostream & operator<<(std::ostream & os, const std::chrono::duration<T> & dd) {
-				auto d = std::chrono::duration_cast<std::chrono::milliseconds>(dd);
-				auto minutes = std::chrono::duration_cast<std::chrono::minutes>(d);
-				auto seconds = std::chrono::duration_cast<std::chrono::seconds>(d % std::chrono::minutes(1));
-				auto millis  = std::chrono::duration_cast<std::chrono::milliseconds>(d % std::chrono::seconds(1));
-
-				bool zmin = minutes == minutes.zero();
-				bool zsec = seconds == seconds.zero();
-				bool zmil = millis  == millis .zero();
-
-				if(!zmin) {
-					os << std::setw(4) << minutes.count() << "m";
-				} else {
-					os << std::string(5, ' ');
-				}
-
-				if(!zmin || !zsec) {
-					if(!zmin) os << std::setfill('0');
-					os << std::setw(2) << seconds.count() << "s";
-				} else {
-					os << std::string(3, ' ');
-				}
-				os << std::setfill(' ');
-
-				if(!zmin || !zsec || !zmil) {
-					if(!zmin || !zsec) os << std::setfill('0');
-					os << std::setw(3) << millis .count();
-				} else {
-					os << std::string(4, ' ');
-				}
-				os << std::setfill(' ');
-
-				return os;
-			}
-
-			class TimerNode : public Base::Tree<top> {
-			public:
-				TimerNode(const char * const name )
-					: Base::Tree<top>(name)
-				{}
-
-				TimerNode(const char * const name, Base::Tree<top> * parent)
-					: Base::Tree<top>(name, parent)
-
-				{}
-
-				virtual void print(std::ostream & os) override {
-					if(currl > prevl) {
-						parents.push(last);
-					}
-					for(auto lvl = prevl - currl; lvl > 0; lvl--) {
-						parents.pop();
-					}
-					last = end - begin;
-
-					assert(finished);
-					std::chrono::duration<double> diff = end - begin;
-					os << diff << " | ";
-					if(parents.empty()) {
-						os << "     N/A | ";
-					} else {
-						os << std::setw(7) << std::setprecision(0);
-						os << size_t(100.0 * diff.count() / parents.top().count()) << "% | ";
-					}
-					os << std::setw(5) << std::setprecision(0);
-					os << size_t(100.0 * diff.count() / total.count()) << "% ";
-				}
-
-				void start() {
-					begin = std::chrono::high_resolution_clock::now();
-				}
-
-				void finish() {
-					end = std::chrono::high_resolution_clock::now();
-					finished = true;
-				}
-
-			protected:
-				virtual ~TimerNode() = default;
-
-			private:
-				bool finished = false;
-
-				point_t begin;
-				point_t end;
-
-				static std::chrono::duration<double> last;
-				static std::stack<std::chrono::duration<double>> parents;
-			};
-
-			std::stack<TimerNode *> nodes;
-
-			std::chrono::duration<double> TimerNode::last;
-			std::stack<std::chrono::duration<double>> TimerNode::parents;
-
-			void StartGlobal() {
-				global_begin = std::chrono::high_resolution_clock::now();
-			}
-
-			void StartBlock(const char * const name) {
-				if(!enabled) return;
-				auto node = nodes.empty()
-					? new TimerNode(name)
-					: new TimerNode(name, nodes.top());
-
-				nodes.push(node);
-				node->start();
-			}
-
-			void StopBlock() {
-				if(!enabled) return;
-				nodes.top()->finish();
-				nodes.pop();
-			}
-
-			void print() {
-				if(!top.head) return;
-				auto global_end = std::chrono::high_resolution_clock::now();
-				total = global_end - global_begin;
-
-				size_t nc = 0;
-				Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
-					nc = std::max(nc, (4 * level) + std::strlen(node->name));
-				});
-
-				size_t nct = nc + 37;
-				std::cerr << std::string(nct, '=') << std::endl;
-				const char * const title = "Timing Results";
-				std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
-				std::cerr << title << std::endl;
-				std::cerr << std::string(nct, '-') << std::endl;
-				std::cerr << "Location";
-				std::cerr << std::string(nc - (std::strlen("Location")), ' ');
-				std::cerr << " | ";
-				std::cerr << "       Time | ";
-				std::cerr << "% parent | ";
-				std::cerr << "% total |" << std::endl;
-				std::cerr << std::string(nct, '-') << std::endl;
-
-				Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
-					currl = level;
-					std::cerr << std::string(level * 4, ' ');
-					std::cerr << node->name;
-					std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
-					std::cerr << " | ";
-					node->print(std::cerr);
-					std::cerr << " |";
-					std::cerr << '\n';
-					prevl = level;
-				}, true);
-
-				std::cerr << std::string(nct, '-') << std::endl;
-				std::cerr << "Total " << total << std::endl;
-				std::cerr << std::string(nct, '-') << std::endl;
-			}
-#		endif
-	}
-}
Index: src/Common/Stats/Time.cpp
===================================================================
--- src/Common/Stats/Time.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Time.cpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,199 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Time.cpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Mon Mar 04 15:16:07 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "Time.hpp"
+
+#include <cassert>
+#include <chrono>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <iomanip>
+#include <stack>
+
+namespace Stats {
+	namespace Time {
+#		if !defined(NO_TIME_STATISTICS)
+			extern bool enabled;
+
+			Base::TreeTop top;
+
+			typedef  std::chrono::time_point<std::chrono::high_resolution_clock> point_t;
+			std::chrono::duration<double> total;
+
+			point_t global_begin;
+
+			int prevl = 0;
+			int currl = 0;
+
+			template<typename T>
+			static inline std::ostream & operator<<(std::ostream & os, const std::chrono::duration<T> & dd) {
+				auto d = std::chrono::duration_cast<std::chrono::milliseconds>(dd);
+				auto minutes = std::chrono::duration_cast<std::chrono::minutes>(d);
+				auto seconds = std::chrono::duration_cast<std::chrono::seconds>(d % std::chrono::minutes(1));
+				auto millis  = std::chrono::duration_cast<std::chrono::milliseconds>(d % std::chrono::seconds(1));
+
+				bool zmin = minutes == minutes.zero();
+				bool zsec = seconds == seconds.zero();
+				bool zmil = millis  == millis .zero();
+
+				if(!zmin) {
+					os << std::setw(4) << minutes.count() << "m";
+				} else {
+					os << std::string(5, ' ');
+				}
+
+				if(!zmin || !zsec) {
+					if(!zmin) os << std::setfill('0');
+					os << std::setw(2) << seconds.count() << "s";
+				} else {
+					os << std::string(3, ' ');
+				}
+				os << std::setfill(' ');
+
+				if(!zmin || !zsec || !zmil) {
+					if(!zmin || !zsec) os << std::setfill('0');
+					os << std::setw(3) << millis .count();
+				} else {
+					os << std::string(4, ' ');
+				}
+				os << std::setfill(' ');
+
+				return os;
+			}
+
+			class TimerNode : public Base::Tree<top> {
+			public:
+				TimerNode(const char * const name )
+					: Base::Tree<top>(name)
+				{}
+
+				TimerNode(const char * const name, Base::Tree<top> * parent)
+					: Base::Tree<top>(name, parent)
+
+				{}
+
+				virtual void print(std::ostream & os) override {
+					if(currl > prevl) {
+						parents.push(last);
+					}
+					for(auto lvl = prevl - currl; lvl > 0; lvl--) {
+						parents.pop();
+					}
+					last = end - begin;
+
+					assert(finished);
+					std::chrono::duration<double> diff = end - begin;
+					os << diff << " | ";
+					if(parents.empty()) {
+						os << "     N/A | ";
+					} else {
+						os << std::setw(7) << std::setprecision(0);
+						os << size_t(100.0 * diff.count() / parents.top().count()) << "% | ";
+					}
+					os << std::setw(5) << std::setprecision(0);
+					os << size_t(100.0 * diff.count() / total.count()) << "% ";
+				}
+
+				void start() {
+					begin = std::chrono::high_resolution_clock::now();
+				}
+
+				void finish() {
+					end = std::chrono::high_resolution_clock::now();
+					finished = true;
+				}
+
+			protected:
+				virtual ~TimerNode() = default;
+
+			private:
+				bool finished = false;
+
+				point_t begin;
+				point_t end;
+
+				static std::chrono::duration<double> last;
+				static std::stack<std::chrono::duration<double>> parents;
+			};
+
+			std::stack<TimerNode *> nodes;
+
+			std::chrono::duration<double> TimerNode::last;
+			std::stack<std::chrono::duration<double>> TimerNode::parents;
+
+			void StartGlobal() {
+				global_begin = std::chrono::high_resolution_clock::now();
+			}
+
+			void StartBlock(const char * const name) {
+				if(!enabled) return;
+				auto node = nodes.empty()
+					? new TimerNode(name)
+					: new TimerNode(name, nodes.top());
+
+				nodes.push(node);
+				node->start();
+			}
+
+			void StopBlock() {
+				if(!enabled) return;
+				nodes.top()->finish();
+				nodes.pop();
+			}
+
+			void print() {
+				if(!top.head) return;
+				auto global_end = std::chrono::high_resolution_clock::now();
+				total = global_end - global_begin;
+
+				size_t nc = 0;
+				Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
+					nc = std::max(nc, (4 * level) + std::strlen(node->name));
+				});
+
+				size_t nct = nc + 37;
+				std::cerr << std::string(nct, '=') << std::endl;
+				const char * const title = "Timing Results";
+				std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
+				std::cerr << title << std::endl;
+				std::cerr << std::string(nct, '-') << std::endl;
+				std::cerr << "Location";
+				std::cerr << std::string(nc - (std::strlen("Location")), ' ');
+				std::cerr << " | ";
+				std::cerr << "       Time | ";
+				std::cerr << "% parent | ";
+				std::cerr << "% total |" << std::endl;
+				std::cerr << std::string(nct, '-') << std::endl;
+
+				Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
+					currl = level;
+					std::cerr << std::string(level * 4, ' ');
+					std::cerr << node->name;
+					std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
+					std::cerr << " | ";
+					node->print(std::cerr);
+					std::cerr << " |";
+					std::cerr << '\n';
+					prevl = level;
+				}, true);
+
+				std::cerr << std::string(nct, '-') << std::endl;
+				std::cerr << "Total " << total << std::endl;
+				std::cerr << std::string(nct, '-') << std::endl;
+			}
+#		endif
+	}
+}
Index: src/Common/Stats/Time.h
===================================================================
--- src/Common/Stats/Time.h	(revision b0b1e15bc9750713820f8fdd7b0d6249055c0946)
+++ 	(revision )
@@ -1,76 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Time.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Fri Mar 01 15:14:11 2019
-// Last Modified By : Andrew Beach
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include "Common/Stats/Base.h"
-
-#if defined( NO_STATISTICS )
-	#define NO_TIME_STATISTICS
-#endif
-
-namespace Stats {
-	namespace Time {
-#		if defined(NO_TIME_STATISTICS)
-			inline void StartGlobal() {}
-
-			inline void StartBlock(const char * const) {}
-			inline void StopBlock() {}
-
-			inline void print() {}
-
-			struct BlockGuard {
-				BlockGuard(const char * const) {}
-				~BlockGuard() {}
-			};
-
-			template<typename func_t>
-			inline void TimeBlock(const char *, func_t f) {
-				f();
-			}
-
-			template<typename ret_t = void, typename func_t, typename... arg_t>
-			inline ret_t TimeCall(
-					const char *, func_t func, arg_t&&... arg) {
-				return func(std::forward<arg_t>(arg)...);
-			}
-#		else
-			void StartGlobal();
-
-			void StartBlock(const char * const name);
-			void StopBlock();
-
-			void print();
-
-			struct BlockGuard {
-				BlockGuard(const char * const name ) { StartBlock(name); }
-				~BlockGuard() { StopBlock(); }
-			};
-
-			template<typename func_t>
-			inline void TimeBlock(const char * name, func_t func) {
-				BlockGuard guard(name);
-				func();
-			}
-
-			template<typename ret_t = void, typename func_t, typename... arg_t>
-			inline ret_t TimeCall(
-					const char * name, func_t func, arg_t&&... arg) {
-				BlockGuard guard(name);
-				return func(std::forward<arg_t>(arg)...);
-			}
-#		endif
-	}
-}
Index: src/Common/Stats/Time.hpp
===================================================================
--- src/Common/Stats/Time.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
+++ src/Common/Stats/Time.hpp	(revision c92bdcc6ef9bc5c1b005f67d1c9f428bb8bd2b4c)
@@ -0,0 +1,76 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Time.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Fri Mar 01 15:14:11 2019
+// Last Modified By : Andrew Beach
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+#include "Common/Stats/Base.hpp"
+
+#if defined( NO_STATISTICS )
+	#define NO_TIME_STATISTICS
+#endif
+
+namespace Stats {
+	namespace Time {
+#		if defined(NO_TIME_STATISTICS)
+			inline void StartGlobal() {}
+
+			inline void StartBlock(const char * const) {}
+			inline void StopBlock() {}
+
+			inline void print() {}
+
+			struct BlockGuard {
+				BlockGuard(const char * const) {}
+				~BlockGuard() {}
+			};
+
+			template<typename func_t>
+			inline void TimeBlock(const char *, func_t f) {
+				f();
+			}
+
+			template<typename ret_t = void, typename func_t, typename... arg_t>
+			inline ret_t TimeCall(
+					const char *, func_t func, arg_t&&... arg) {
+				return func(std::forward<arg_t>(arg)...);
+			}
+#		else
+			void StartGlobal();
+
+			void StartBlock(const char * const name);
+			void StopBlock();
+
+			void print();
+
+			struct BlockGuard {
+				BlockGuard(const char * const name ) { StartBlock(name); }
+				~BlockGuard() { StopBlock(); }
+			};
+
+			template<typename func_t>
+			inline void TimeBlock(const char * name, func_t func) {
+				BlockGuard guard(name);
+				func();
+			}
+
+			template<typename ret_t = void, typename func_t, typename... arg_t>
+			inline ret_t TimeCall(
+					const char * name, func_t func, arg_t&&... arg) {
+				BlockGuard guard(name);
+				return func(std::forward<arg_t>(arg)...);
+			}
+#		endif
+	}
+}
