mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Replaced std::unordered_set (nodict) with Yosys::pool
This commit is contained in:
		
							parent
							
								
									9e6fb0b02c
								
							
						
					
					
						commit
						ec4751e55c
					
				
					 8 changed files with 394 additions and 137 deletions
				
			
		
							
								
								
									
										352
									
								
								kernel/hashmap.h
									
										
									
									
									
								
							
							
						
						
									
										352
									
								
								kernel/hashmap.h
									
										
									
									
									
								
							|  | @ -57,6 +57,21 @@ template<> struct hash_ops<std::string> { | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct hash_cstr_ops { | ||||
| 	bool cmp(const char *a, const char *b) const { | ||||
| 		for (int i = 0; a[i] || b[i]; i++) | ||||
| 			if (a[i] != b[i]) | ||||
| 				return false; | ||||
| 		return true; | ||||
| 	} | ||||
| 	unsigned int hash(const char *a) const { | ||||
| 		size_t hash = 5381; | ||||
| 		while (*a) | ||||
| 			 hash = mkhash(hash, *(a++)); | ||||
| 		 return hash; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct hash_ptr_ops { | ||||
| 	bool cmp(const void *a, const void *b) const { | ||||
| 		return a == b; | ||||
|  | @ -423,4 +438,341 @@ public: | |||
| 	const_iterator end() const { return const_iterator(this, entries.size()); } | ||||
| }; | ||||
| 
 | ||||
| template<typename K, typename OPS = hash_ops<K>> | ||||
| class pool | ||||
| { | ||||
| 	struct entry_t | ||||
| 	{ | ||||
| 		int link; | ||||
| 		K key; | ||||
| 
 | ||||
| 		entry_t() : link(-1) { } | ||||
| 		entry_t(const K &key) : link(1), key(key) { } | ||||
| 
 | ||||
| 		bool is_free() const { return link < 0; } | ||||
| 		int get_next() const { return (link > 0 ? link : -link) - 2; } | ||||
| 		bool get_last() const { return get_next() == -1; } | ||||
| 		void set_next_used(int next) { link = next + 2; } | ||||
| 		void set_next_free(int next) { link = -(next + 2); } | ||||
| 	}; | ||||
| 
 | ||||
| 	std::vector<int> hashtable; | ||||
| 	std::vector<entry_t> entries; | ||||
| 	int free_list, counter; | ||||
| 	OPS ops; | ||||
| 
 | ||||
| 	void init() | ||||
| 	{ | ||||
| 		free_list = -1; | ||||
| 		counter = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	void init_from(const pool<K, OPS> &other) | ||||
| 	{ | ||||
| 		hashtable.clear(); | ||||
| 		entries.clear(); | ||||
| 
 | ||||
| 		counter = other.size(); | ||||
| 		int new_size = grow_size(counter); | ||||
| 		entries.reserve(new_size); | ||||
| 
 | ||||
| 		for (auto &it : other) | ||||
| 			entries.push_back(entry_t(it)); | ||||
| 		entries.resize(new_size); | ||||
| 		rehash(); | ||||
| 	} | ||||
| 
 | ||||
| 	size_t grow_size(size_t old_size) | ||||
| 	{ | ||||
| 		if (old_size <         53) return         53; | ||||
| 		if (old_size <        113) return        113; | ||||
| 		if (old_size <        251) return        251; | ||||
| 		if (old_size <        503) return        503; | ||||
| 		if (old_size <       1130) return       1130; | ||||
| 		if (old_size <       2510) return       2510; | ||||
| 		if (old_size <       5030) return       5030; | ||||
| 		if (old_size <      11300) return      11300; | ||||
| 		if (old_size <      25100) return      25100; | ||||
| 		if (old_size <      50300) return      50300; | ||||
| 		if (old_size <     113000) return     113000; | ||||
| 		if (old_size <     251000) return     251000; | ||||
| 		if (old_size <     503000) return     503000; | ||||
| 		if (old_size <    1130000) return    1130000; | ||||
| 		if (old_size <    2510000) return    2510000; | ||||
| 		if (old_size <    5030000) return    5030000; | ||||
| 		if (old_size <   11300000) return   11300000; | ||||
| 		if (old_size <   25100000) return   25100000; | ||||
| 		if (old_size <   50300000) return   50300000; | ||||
| 		if (old_size <  113000000) return  113000000; | ||||
| 		if (old_size <  251000000) return  251000000; | ||||
| 		if (old_size <  503000000) return  503000000; | ||||
| 		if (old_size < 1130000000) return 1130000000; | ||||
| 		throw std::length_error("maximum size for pool reached"); | ||||
| 	} | ||||
| 
 | ||||
| 	int mkhash(const K &key) const | ||||
| 	{ | ||||
| 		unsigned int hash = 0; | ||||
| 		if (!hashtable.empty()) | ||||
| 			hash = ops.hash(key) % (unsigned int)(hashtable.size()); | ||||
| 		return hash; | ||||
| 	} | ||||
| 
 | ||||
| 	void rehash() | ||||
| 	{ | ||||
| 		free_list = -1; | ||||
| 
 | ||||
| 		hashtable.resize(entries.size()); | ||||
| 		for (auto &h : hashtable) | ||||
| 			h = -1; | ||||
| 
 | ||||
| 		for (int i = 0; i < int(entries.size()); i++) | ||||
| 			if (entries[i].is_free()) { | ||||
| 				entries[i].set_next_free(free_list); | ||||
| 				free_list = i; | ||||
| 			} else { | ||||
| 				int hash = mkhash(entries[i].key); | ||||
| 				entries[i].set_next_used(hashtable[hash]); | ||||
| 				hashtable[hash] = i; | ||||
| 			} | ||||
| 	} | ||||
| 
 | ||||
| 	void do_erase(const K &key, int hash) | ||||
| 	{ | ||||
| 		int last_index = -1; | ||||
| 		int index = hashtable.empty() ? -1 : hashtable[hash]; | ||||
| 		while (1) { | ||||
| 			if (index < 0) | ||||
| 				return; | ||||
| 			if (ops.cmp(entries[index].key, key)) { | ||||
| 				if (last_index < 0) | ||||
| 					hashtable[hash] = entries[index].get_next(); | ||||
| 				else | ||||
| 					entries[last_index].set_next_used(entries[index].get_next()); | ||||
| 				entries[index].key = K(); | ||||
| 				entries[index].set_next_free(free_list); | ||||
| 				free_list = index; | ||||
| 				if (--counter == 0) | ||||
| 					init(); | ||||
| 				return; | ||||
| 			} | ||||
| 			last_index = index; | ||||
| 			index = entries[index].get_next(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	int lookup_index(const K &key, int hash) const | ||||
| 	{ | ||||
| 		int index = hashtable.empty() ? -1 : hashtable[hash]; | ||||
| 		while (1) { | ||||
| 			if (index < 0) | ||||
| 				return -1; | ||||
| 			if (ops.cmp(entries[index].key, key)) | ||||
| 				return index; | ||||
| 			index = entries[index].get_next(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	int insert_at(const K &key, int hash) | ||||
| 	{ | ||||
| 		if (free_list < 0) | ||||
| 		{ | ||||
| 			int i = entries.size(); | ||||
| 			entries.resize(grow_size(i)); | ||||
| 			entries[i].key = key; | ||||
| 			entries[i].set_next_used(0); | ||||
| 			counter++; | ||||
| 			rehash(); | ||||
| 			return i; | ||||
| 		} | ||||
| 
 | ||||
| 		int i = free_list; | ||||
| 		free_list = entries[i].get_next(); | ||||
| 		entries[i].key = key; | ||||
| 		entries[i].set_next_used(hashtable[hash]); | ||||
| 		hashtable[hash] = i; | ||||
| 		counter++; | ||||
| 		return i; | ||||
| 	} | ||||
| 
 | ||||
| public: | ||||
| 	class iterator | ||||
| 	{ | ||||
| 		pool<K, OPS> *ptr; | ||||
| 		int index; | ||||
| 	public: | ||||
| 		iterator() { } | ||||
| 		iterator(pool<K, OPS> *ptr, int index) : ptr(ptr), index(index) { } | ||||
| 		iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } | ||||
| 		iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } | ||||
| 		bool operator==(const iterator &other) const { return index == other.index; } | ||||
| 		bool operator!=(const iterator &other) const { return index != other.index; } | ||||
| 		K &operator*() { return ptr->entries[index].key; } | ||||
| 		K *operator->() { return &ptr->entries[index].key; } | ||||
| 		const K &operator*() const { return ptr->entries[index].key; } | ||||
| 		const K *operator->() const { return &ptr->entries[index].key; } | ||||
| 	}; | ||||
| 
 | ||||
| 	class const_iterator | ||||
| 	{ | ||||
| 		const pool<K, OPS> *ptr; | ||||
| 		int index; | ||||
| 	public: | ||||
| 		const_iterator() { } | ||||
| 		const_iterator(const pool<K, OPS> *ptr, int index) : ptr(ptr), index(index) { } | ||||
| 		const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } | ||||
| 		const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } | ||||
| 		bool operator==(const const_iterator &other) const { return index == other.index; } | ||||
| 		bool operator!=(const const_iterator &other) const { return index != other.index; } | ||||
| 		const K &operator*() const { return ptr->entries[index].key; } | ||||
| 		const K *operator->() const { return &ptr->entries[index].key; } | ||||
| 	}; | ||||
| 
 | ||||
| 	pool() | ||||
| 	{ | ||||
| 		init(); | ||||
| 	} | ||||
| 
 | ||||
| 	pool(const pool<K, OPS> &other) | ||||
| 	{ | ||||
| 		init_from(other); | ||||
| 	} | ||||
| 
 | ||||
| 	pool(pool<K, OPS> &&other) | ||||
| 	{ | ||||
| 		free_list = -1; | ||||
| 		counter = 0; | ||||
| 		swap(other); | ||||
| 	} | ||||
| 
 | ||||
| 	pool<K, OPS> &operator=(const pool<K, OPS> &other) { | ||||
| 		clear(); | ||||
| 		init_from(other); | ||||
| 		return *this; | ||||
| 	} | ||||
| 
 | ||||
| 	pool<K, OPS> &operator=(pool<K, OPS> &&other) { | ||||
| 		clear(); | ||||
| 		swap(other); | ||||
| 		return *this; | ||||
| 	} | ||||
| 
 | ||||
| 	pool(const std::initializer_list<K> &list) | ||||
| 	{ | ||||
| 		init(); | ||||
| 		for (auto &it : list) | ||||
| 			insert(it); | ||||
| 	} | ||||
| 
 | ||||
| 	template<class InputIterator> | ||||
| 	pool(InputIterator first, InputIterator last) | ||||
| 	{ | ||||
| 		init(); | ||||
| 		insert(first, last); | ||||
| 	} | ||||
| 
 | ||||
| 	template<class InputIterator> | ||||
| 	void insert(InputIterator first, InputIterator last) | ||||
| 	{ | ||||
| 		for (; first != last; ++first) | ||||
| 			insert(*first); | ||||
| 	} | ||||
| 
 | ||||
| 	iterator insert(const K &key) | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		int i = lookup_index(key, hash); | ||||
| 		if (i >= 0) | ||||
| 			return iterator(this, i); | ||||
| 		i = insert_at(key, hash); | ||||
| 		return iterator(this, i); | ||||
| 	} | ||||
| 
 | ||||
| 	void erase(const K &key) | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		do_erase(key, hash); | ||||
| 	} | ||||
| 
 | ||||
| 	void erase(const iterator it) | ||||
| 	{ | ||||
| 		int hash = mkhash(it->first); | ||||
| 		do_erase(it->first, hash); | ||||
| 	} | ||||
| 
 | ||||
| 	int count(const K &key) const | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		int i = lookup_index(key, hash); | ||||
| 		return i < 0 ? 0 : 1; | ||||
| 	} | ||||
| 
 | ||||
| 	iterator find(const K &key) | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		int i = lookup_index(key, hash); | ||||
| 		if (i < 0) | ||||
| 			return end(); | ||||
| 		return iterator(this, i); | ||||
| 	} | ||||
| 
 | ||||
| 	const_iterator find(const K &key) const | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		int i = lookup_index(key, hash); | ||||
| 		if (i < 0) | ||||
| 			return end(); | ||||
| 		return const_iterator(this, i); | ||||
| 	} | ||||
| 
 | ||||
| 	bool operator[](const K &key) const | ||||
| 	{ | ||||
| 		int hash = mkhash(key); | ||||
| 		int i = lookup_index(key, hash); | ||||
| 		return i >= 0; | ||||
| 	} | ||||
| 
 | ||||
| 	void swap(pool<K, OPS> &other) | ||||
| 	{ | ||||
| 		hashtable.swap(other.hashtable); | ||||
| 		entries.swap(other.entries); | ||||
| 		std::swap(free_list, other.free_list); | ||||
| 		std::swap(counter, other.counter); | ||||
| 	} | ||||
| 
 | ||||
| 	bool operator==(const pool<K, OPS> &other) const { | ||||
| 		if (counter != other.counter) | ||||
| 			return false; | ||||
| 		if (counter == 0) | ||||
| 			return true; | ||||
| 		if (entries.size() < other.entries.size()) | ||||
| 			for (auto &it : *this) { | ||||
| 				auto oit = other.find(it.first); | ||||
| 				if (oit == other.end() || oit->second != it.second) | ||||
| 					return false; | ||||
| 			} | ||||
| 		else | ||||
| 			for (auto &oit : other) { | ||||
| 				auto it = find(oit.first); | ||||
| 				if (it == end() || it->second != oit.second) | ||||
| 					return false; | ||||
| 			} | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	bool operator!=(const pool<K, OPS> &other) const { | ||||
| 		return !(*this == other); | ||||
| 	} | ||||
| 
 | ||||
| 	size_t size() const { return counter; } | ||||
| 	bool empty() const { return counter == 0; } | ||||
| 	void clear() { hashtable.clear(); entries.clear(); init(); } | ||||
| 
 | ||||
| 	iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } | ||||
| 	iterator end() { return iterator(this, entries.size()); } | ||||
| 
 | ||||
| 	const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } | ||||
| 	const_iterator end() const { return const_iterator(this, entries.size()); } | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ YOSYS_NAMESPACE_BEGIN | |||
| RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; | ||||
| std::vector<int> RTLIL::IdString::global_refcount_storage_; | ||||
| std::vector<char*> RTLIL::IdString::global_id_storage_; | ||||
| dict<char*, int, RTLIL::IdString::char_ptr_ops> RTLIL::IdString::global_id_index_; | ||||
| dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_; | ||||
| std::vector<int> RTLIL::IdString::global_free_idx_list_; | ||||
| 
 | ||||
| RTLIL::Const::Const() | ||||
|  | @ -480,7 +480,7 @@ namespace { | |||
| 	{ | ||||
| 		RTLIL::Module *module; | ||||
| 		RTLIL::Cell *cell; | ||||
| 		nodict<RTLIL::IdString> expected_params, expected_ports; | ||||
| 		pool<RTLIL::IdString> expected_params, expected_ports; | ||||
| 
 | ||||
| 		InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } | ||||
| 
 | ||||
|  | @ -1132,7 +1132,7 @@ namespace { | |||
| 	struct DeleteWireWorker | ||||
| 	{ | ||||
| 		RTLIL::Module *module; | ||||
| 		const nodict<RTLIL::Wire*> *wires_p; | ||||
| 		const pool<RTLIL::Wire*, hash_ptr_ops> *wires_p; | ||||
| 
 | ||||
| 		void operator()(RTLIL::SigSpec &sig) { | ||||
| 			std::vector<RTLIL::SigChunk> chunks = sig; | ||||
|  | @ -1146,7 +1146,7 @@ namespace { | |||
| 	}; | ||||
| } | ||||
| 
 | ||||
| void RTLIL::Module::remove(const nodict<RTLIL::Wire*> &wires) | ||||
| void RTLIL::Module::remove(const pool<RTLIL::Wire*, hash_ptr_ops> &wires) | ||||
| { | ||||
| 	log_assert(refcount_wires_ == 0); | ||||
| 
 | ||||
|  | @ -2169,9 +2169,9 @@ RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits) | |||
| 	check(); | ||||
| } | ||||
| 
 | ||||
| RTLIL::SigSpec::SigSpec(nodict<RTLIL::SigBit> bits) | ||||
| RTLIL::SigSpec::SigSpec(pool<RTLIL::SigBit> bits) | ||||
| { | ||||
| 	cover("kernel.rtlil.sigspec.init.nodict_bits"); | ||||
| 	cover("kernel.rtlil.sigspec.init.pool_bits"); | ||||
| 
 | ||||
| 	width_ = 0; | ||||
| 	hash_ = 0; | ||||
|  | @ -2378,22 +2378,22 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other | |||
| 
 | ||||
| void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) | ||||
| { | ||||
| 	nodict<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict(); | ||||
| 	pool<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict(); | ||||
| 	remove2(pattern_bits, other); | ||||
| } | ||||
| 
 | ||||
| void RTLIL::SigSpec::remove(const nodict<RTLIL::SigBit> &pattern) | ||||
| void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern) | ||||
| { | ||||
| 	remove2(pattern, NULL); | ||||
| } | ||||
| 
 | ||||
| void RTLIL::SigSpec::remove(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const | ||||
| void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const | ||||
| { | ||||
| 	RTLIL::SigSpec tmp = *this; | ||||
| 	tmp.remove2(pattern, other); | ||||
| } | ||||
| 
 | ||||
| void RTLIL::SigSpec::remove2(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) | ||||
| void RTLIL::SigSpec::remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) | ||||
| { | ||||
| 	if (other) | ||||
| 		cover("kernel.rtlil.sigspec.remove_other"); | ||||
|  | @ -2439,11 +2439,11 @@ void RTLIL::SigSpec::remove2(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpe | |||
| 
 | ||||
| RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const | ||||
| { | ||||
| 	nodict<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict(); | ||||
| 	pool<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_nodict(); | ||||
| 	return extract(pattern_bits, other); | ||||
| } | ||||
| 
 | ||||
| RTLIL::SigSpec RTLIL::SigSpec::extract(const nodict<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const | ||||
| RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const | ||||
| { | ||||
| 	if (other) | ||||
| 		cover("kernel.rtlil.sigspec.extract_other"); | ||||
|  | @ -2943,12 +2943,12 @@ std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const | |||
| 	return sigbits; | ||||
| } | ||||
| 
 | ||||
| nodict<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_nodict() const | ||||
| pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_nodict() const | ||||
| { | ||||
| 	cover("kernel.rtlil.sigspec.to_sigbit_nodict"); | ||||
| 	cover("kernel.rtlil.sigspec.to_sigbit_pool"); | ||||
| 
 | ||||
| 	pack(); | ||||
| 	nodict<RTLIL::SigBit> sigbits; | ||||
| 	pool<RTLIL::SigBit> sigbits; | ||||
| 	for (auto &c : chunks_) | ||||
| 		for (int i = 0; i < c.width; i++) | ||||
| 			sigbits.insert(RTLIL::SigBit(c, i)); | ||||
|  |  | |||
							
								
								
									
										132
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							
							
						
						
									
										132
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							|  | @ -22,27 +22,6 @@ | |||
| #ifndef RTLIL_H | ||||
| #define RTLIL_H | ||||
| 
 | ||||
| namespace std { | ||||
| 	template<> struct hash<Yosys::RTLIL::IdString> { | ||||
| 		size_t operator()(const Yosys::RTLIL::IdString &arg) const; | ||||
| 	}; | ||||
| 	template<> struct equal_to<Yosys::RTLIL::IdString> { | ||||
| 		bool operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const; | ||||
| 	}; | ||||
| 	template<> struct hash<Yosys::RTLIL::SigBit> { | ||||
| 		size_t operator()(const Yosys::RTLIL::SigBit &arg) const; | ||||
| 	}; | ||||
| 	template<> struct equal_to<Yosys::RTLIL::SigBit> { | ||||
| 		bool operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const; | ||||
| 	}; | ||||
| 	template<> struct hash<Yosys::RTLIL::SigSpec> { | ||||
| 		size_t operator()(const Yosys::RTLIL::SigSpec &arg) const; | ||||
| 	}; | ||||
| 	template<> struct equal_to<Yosys::RTLIL::SigSpec> { | ||||
| 		bool operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const; | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| YOSYS_NAMESPACE_BEGIN | ||||
| 
 | ||||
| namespace RTLIL | ||||
|  | @ -97,48 +76,6 @@ namespace RTLIL | |||
| 	{ | ||||
| 		// the global id string cache
 | ||||
| 
 | ||||
| 		struct char_ptr_cmp { | ||||
| 			bool operator()(const char *a, const char *b) const { | ||||
| 				for (int i = 0; a[i] || b[i]; i++) | ||||
| 					if (a[i] != b[i]) | ||||
| 						return a[i] < b[i]; | ||||
| 				return false; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		struct char_ptr_hash { | ||||
| 			size_t operator()(const char *a) const { | ||||
| 				size_t hash = 5381; | ||||
| 				for (int c; (c = *a); a++) | ||||
| 					hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ | ||||
| 				return hash; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		struct char_ptr_eq { | ||||
| 			bool operator()(const char *a, const char *b) const { | ||||
| 				for (int i = 0; a[i] || b[i]; i++) | ||||
| 					if (a[i] != b[i]) | ||||
| 						return false; | ||||
| 				return true; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		struct char_ptr_ops { | ||||
| 			bool cmp(const char *a, const char *b) const { | ||||
| 				for (int i = 0; a[i] || b[i]; i++) | ||||
| 					if (a[i] != b[i]) | ||||
| 						return false; | ||||
| 				return true; | ||||
| 			} | ||||
| 			unsigned int hash(const char *a) const { | ||||
| 				size_t hash = 5381; | ||||
| 				while (*a) | ||||
| 					hash = mkhash(hash, *(a++)); | ||||
| 				return hash; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		static struct destruct_guard_t { | ||||
| 			bool ok; // POD, will be initialized to zero
 | ||||
| 			destruct_guard_t() { ok = true; } | ||||
|  | @ -147,7 +84,7 @@ namespace RTLIL | |||
| 
 | ||||
| 		static std::vector<int> global_refcount_storage_; | ||||
| 		static std::vector<char*> global_id_storage_; | ||||
| 		static dict<char*, int, char_ptr_ops> global_id_index_; | ||||
| 		static dict<char*, int, hash_cstr_ops> global_id_index_; | ||||
| 		static std::vector<int> global_free_idx_list_; | ||||
| 
 | ||||
| 		static inline int get_reference(int idx) | ||||
|  | @ -282,8 +219,8 @@ namespace RTLIL | |||
| 			return index_; | ||||
| 		} | ||||
| 
 | ||||
| 		// The following is a helper key_compare class. Instead of for example nodict<Cell*>
 | ||||
| 		// use nodict<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
 | ||||
| 		// The following is a helper key_compare class. Instead of for example pool<Cell*>
 | ||||
| 		// use pool<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
 | ||||
| 		// set has an influence on the algorithm.
 | ||||
| 
 | ||||
| 		template<typename T> struct compare_ptr_by_name { | ||||
|  | @ -303,7 +240,7 @@ namespace RTLIL | |||
| 		bool in(IdString rhs) { return *this == rhs; } | ||||
| 		bool in(const char *rhs) { return *this == rhs; } | ||||
| 		bool in(const std::string &rhs) { return *this == rhs; } | ||||
| 		bool in(const nodict<IdString> &rhs) { return rhs.count(*this) != 0; } | ||||
| 		bool in(const pool<IdString> &rhs) { return rhs.count(*this) != 0; } | ||||
| 	}; | ||||
| 
 | ||||
| 	static inline std::string escape_id(std::string str) { | ||||
|  | @ -470,8 +407,8 @@ namespace RTLIL | |||
| 			return list_p->size(); | ||||
| 		} | ||||
| 
 | ||||
| 		operator nodict<T>() const { | ||||
| 			nodict<T> result; | ||||
| 		operator pool<T>() const { | ||||
| 			pool<T> result; | ||||
| 			for (auto &it : *list_p) | ||||
| 				result.insert(it.second); | ||||
| 			return result; | ||||
|  | @ -485,7 +422,7 @@ namespace RTLIL | |||
| 			return result; | ||||
| 		} | ||||
| 
 | ||||
| 		nodict<T> to_set() const { return *this; } | ||||
| 		pool<T> to_set() const { return *this; } | ||||
| 		std::vector<T> to_vector() const { return *this; } | ||||
| 	}; | ||||
| }; | ||||
|  | @ -619,7 +556,7 @@ public: | |||
| 	SigSpec(RTLIL::SigBit bit, int width = 1); | ||||
| 	SigSpec(std::vector<RTLIL::SigChunk> chunks); | ||||
| 	SigSpec(std::vector<RTLIL::SigBit> bits); | ||||
| 	SigSpec(nodict<RTLIL::SigBit> bits); | ||||
| 	SigSpec(pool<RTLIL::SigBit> bits); | ||||
| 	SigSpec(std::set<RTLIL::SigBit> bits); | ||||
| 	SigSpec(bool bit); | ||||
| 
 | ||||
|  | @ -676,15 +613,15 @@ public: | |||
| 	void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; | ||||
| 	void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); | ||||
| 
 | ||||
| 	void remove(const nodict<RTLIL::SigBit> &pattern); | ||||
| 	void remove(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const; | ||||
| 	void remove2(const nodict<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other); | ||||
| 	void remove(const pool<RTLIL::SigBit> &pattern); | ||||
| 	void remove(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const; | ||||
| 	void remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other); | ||||
| 
 | ||||
| 	void remove(int offset, int length = 1); | ||||
| 	void remove_const(); | ||||
| 
 | ||||
| 	RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||
| 	RTLIL::SigSpec extract(const nodict<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||
| 	RTLIL::SigSpec extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const; | ||||
| 	RTLIL::SigSpec extract(int offset, int length = 1) const; | ||||
| 
 | ||||
| 	void append(const RTLIL::SigSpec &signal); | ||||
|  | @ -717,7 +654,7 @@ public: | |||
| 	bool match(std::string pattern) const; | ||||
| 
 | ||||
| 	std::set<RTLIL::SigBit> to_sigbit_set() const; | ||||
| 	nodict<RTLIL::SigBit> to_sigbit_nodict() const; | ||||
| 	pool<RTLIL::SigBit> to_sigbit_nodict() const; | ||||
| 	std::vector<RTLIL::SigBit> to_sigbit_vector() const; | ||||
| 	std::map<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_map(const RTLIL::SigSpec &other) const; | ||||
| 	dict<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_dict(const RTLIL::SigSpec &other) const; | ||||
|  | @ -742,8 +679,8 @@ public: | |||
| struct RTLIL::Selection | ||||
| { | ||||
| 	bool full_selection; | ||||
| 	nodict<RTLIL::IdString> selected_modules; | ||||
| 	dict<RTLIL::IdString, nodict<RTLIL::IdString>> selected_members; | ||||
| 	pool<RTLIL::IdString> selected_modules; | ||||
| 	dict<RTLIL::IdString, pool<RTLIL::IdString>> selected_members; | ||||
| 
 | ||||
| 	Selection(bool full = true) : full_selection(full) { } | ||||
| 
 | ||||
|  | @ -782,7 +719,7 @@ struct RTLIL::Monitor | |||
| 
 | ||||
| struct RTLIL::Design | ||||
| { | ||||
| 	nodict<RTLIL::Monitor*> monitors; | ||||
| 	pool<RTLIL::Monitor*, hash_ptr_ops> monitors; | ||||
| 	dict<std::string, std::string> scratchpad; | ||||
| 
 | ||||
| 	int refcount_modules_; | ||||
|  | @ -869,7 +806,7 @@ protected: | |||
| 
 | ||||
| public: | ||||
| 	RTLIL::Design *design; | ||||
| 	nodict<RTLIL::Monitor*> monitors; | ||||
| 	pool<RTLIL::Monitor*, hash_ptr_ops> monitors; | ||||
| 
 | ||||
| 	int refcount_wires_; | ||||
| 	int refcount_cells_; | ||||
|  | @ -879,7 +816,7 @@ public: | |||
| 	std::vector<RTLIL::SigSig> connections_; | ||||
| 
 | ||||
| 	RTLIL::IdString name; | ||||
| 	nodict<RTLIL::IdString> avail_parameters; | ||||
| 	pool<RTLIL::IdString> avail_parameters; | ||||
| 	dict<RTLIL::IdString, RTLIL::Memory*> memories; | ||||
| 	dict<RTLIL::IdString, RTLIL::Process*> processes; | ||||
| 	RTLIL_ATTRIBUTE_MEMBERS | ||||
|  | @ -923,7 +860,7 @@ public: | |||
| 	RTLIL::ObjRange<RTLIL::Cell*> cells() { return RTLIL::ObjRange<RTLIL::Cell*>(&cells_, &refcount_cells_); } | ||||
| 
 | ||||
| 	// Removing wires is expensive. If you have to remove wires, remove them all at once.
 | ||||
| 	void remove(const nodict<RTLIL::Wire*> &wires); | ||||
| 	void remove(const pool<RTLIL::Wire*, hash_ptr_ops> &wires); | ||||
| 	void remove(RTLIL::Cell *cell); | ||||
| 
 | ||||
| 	void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); | ||||
|  | @ -1313,35 +1250,4 @@ void RTLIL::Process::rewrite_sigspecs(T functor) | |||
| 
 | ||||
| YOSYS_NAMESPACE_END | ||||
| 
 | ||||
| inline size_t std::hash<Yosys::RTLIL::IdString>::operator()(const Yosys::RTLIL::IdString &arg) const { | ||||
| 	return arg.index_; | ||||
| } | ||||
| 
 | ||||
| inline bool std::equal_to<Yosys::RTLIL::IdString>::operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const { | ||||
| 	return lhs.index_ == rhs.index_; | ||||
| } | ||||
| 
 | ||||
| inline size_t std::hash<Yosys::RTLIL::SigBit>::operator()(const Yosys::RTLIL::SigBit &arg) const { | ||||
| 	if (arg.wire) { | ||||
| 		size_t hash = arg.wire->name.index_; | ||||
| 		hash = ((hash << 5) + hash) + arg.offset; | ||||
| 		return hash; | ||||
| 	} | ||||
| 	return arg.data; | ||||
| } | ||||
| 
 | ||||
| inline bool std::equal_to<Yosys::RTLIL::SigBit>::operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const { | ||||
| 	if (lhs.wire || rhs.wire) | ||||
| 		return lhs.wire == rhs.wire && lhs.offset == rhs.offset; | ||||
| 	return lhs.data == rhs.data; | ||||
| } | ||||
| 
 | ||||
| inline size_t std::hash<Yosys::RTLIL::SigSpec>::operator()(const Yosys::RTLIL::SigSpec &arg) const { | ||||
| 	return arg.get_hash(); | ||||
| } | ||||
| 
 | ||||
| inline bool std::equal_to<Yosys::RTLIL::SigSpec>::operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const { | ||||
| 	return lhs == rhs; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -124,7 +124,6 @@ | |||
| 
 | ||||
| YOSYS_NAMESPACE_BEGIN | ||||
| 
 | ||||
| #define nodict std::unordered_set | ||||
| #include "kernel/hashmap.h" | ||||
| using std::vector; | ||||
| 
 | ||||
|  |  | |||
|  | @ -91,10 +91,10 @@ struct DeletePass : public Pass { | |||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			nodict<RTLIL::Wire*> delete_wires; | ||||
| 			nodict<RTLIL::Cell*> delete_cells; | ||||
| 			nodict<RTLIL::IdString> delete_procs; | ||||
| 			nodict<RTLIL::IdString> delete_mems; | ||||
| 			pool<RTLIL::Wire*, hash_ptr_ops> delete_wires; | ||||
| 			pool<RTLIL::Cell*, hash_ptr_ops> delete_cells; | ||||
| 			pool<RTLIL::IdString> delete_procs; | ||||
| 			pool<RTLIL::IdString> delete_mems; | ||||
| 
 | ||||
| 			for (auto &it : module->wires_) | ||||
| 				if (design->selected(module, it.second)) | ||||
|  |  | |||
|  | @ -176,7 +176,7 @@ struct SplitnetsPass : public Pass { | |||
| 
 | ||||
| 			module->rewrite_sigspecs(worker); | ||||
| 
 | ||||
| 			nodict<RTLIL::Wire*> delete_wires; | ||||
| 			pool<RTLIL::Wire*, hash_ptr_ops> delete_wires; | ||||
| 			for (auto &it : worker.splitmap) | ||||
| 				delete_wires.insert(it.first); | ||||
| 			module->remove(delete_wires); | ||||
|  |  | |||
|  | @ -262,7 +262,7 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos | |||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	nodict<RTLIL::Wire*> del_wires; | ||||
| 	pool<RTLIL::Wire*, hash_ptr_ops> del_wires; | ||||
| 
 | ||||
| 	int del_wires_count = 0; | ||||
| 	for (auto wire : maybe_del_wires) | ||||
|  |  | |||
|  | @ -28,11 +28,11 @@ PRIVATE_NAMESPACE_BEGIN | |||
| 
 | ||||
| struct WreduceConfig | ||||
| { | ||||
| 	nodict<IdString> supported_cell_types; | ||||
| 	pool<IdString> supported_cell_types; | ||||
| 
 | ||||
| 	WreduceConfig() | ||||
| 	{ | ||||
| 		supported_cell_types = nodict<IdString>({ | ||||
| 		supported_cell_types = pool<IdString>({ | ||||
| 			"$not", "$pos", "$neg", | ||||
| 			"$and", "$or", "$xor", "$xnor", | ||||
| 			"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue