mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Made make_struct_member_range side-effect-free again
This commit is contained in:
		
							parent
							
								
									f94eec952f
								
							
						
					
					
						commit
						22090011ab
					
				
					 1 changed files with 20 additions and 20 deletions
				
			
		| 
						 | 
					@ -418,27 +418,28 @@ static AstNode *multiply_by_const(AstNode *expr_node, int stride)
 | 
				
			||||||
	return new AstNode(AST_MUL, expr_node, node_int(stride));
 | 
						return new AstNode(AST_MUL, expr_node, node_int(stride));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void normalize_struct_index(AstNode *rnode, AstNode *member_node, int dimension)
 | 
					static AstNode *normalize_struct_index(AstNode *expr, AstNode *member_node, int dimension)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						expr = expr->clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (member_node->multirange_swapped[dimension]) {
 | 
						if (member_node->multirange_swapped[dimension]) {
 | 
				
			||||||
		// The dimension has swapped range; swap index into the struct accordingly.
 | 
							// The dimension has swapped range; swap index into the struct accordingly.
 | 
				
			||||||
		int msb = member_node->multirange_dimensions[dimension] - 1;
 | 
							int msb = member_node->multirange_dimensions[dimension] - 1;
 | 
				
			||||||
		for (auto &expr : rnode->children) {
 | 
					 | 
				
			||||||
		expr = new AstNode(AST_SUB, node_int(msb), expr);
 | 
							expr = new AstNode(AST_SUB, node_int(msb), expr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						return expr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static AstNode *struct_index_lsb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int &stride)
 | 
					static AstNode *struct_index_lsb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int &stride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	normalize_struct_index(rnode, member_node, dimension);
 | 
					 | 
				
			||||||
	stride /= member_node->multirange_dimensions[dimension];
 | 
						stride /= member_node->multirange_dimensions[dimension];
 | 
				
			||||||
	auto right = rnode->children.back()->clone();
 | 
						auto right = normalize_struct_index(rnode->children.back(), member_node, dimension);
 | 
				
			||||||
	auto offset = stride > 1 ? multiply_by_const(right, stride) : right;
 | 
						auto offset = stride > 1 ? multiply_by_const(right, stride) : right;
 | 
				
			||||||
	return new AstNode(AST_ADD, lsb_offset, offset);
 | 
						return new AstNode(AST_ADD, lsb_offset, offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static AstNode *struct_index_msb_offset(AstNode *lsb_offset, AstNode *rnode, int stride)
 | 
					static AstNode *struct_index_msb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int stride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	log_assert(rnode->children.size() <= 2);
 | 
						log_assert(rnode->children.size() <= 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,15 +452,12 @@ static AstNode *struct_index_msb_offset(AstNode *lsb_offset, AstNode *rnode, int
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		// rnode->children.size() == 2
 | 
							// rnode->children.size() == 2
 | 
				
			||||||
		// Slice, e.g. s.a[i:j]
 | 
							// Slice, e.g. s.a[i:j]
 | 
				
			||||||
		auto left = rnode->children[0]->clone();
 | 
							auto left = normalize_struct_index(rnode->children[0], member_node, dimension);
 | 
				
			||||||
		auto right = rnode->children[1]->clone();
 | 
							auto right = normalize_struct_index(rnode->children[1], member_node, dimension);
 | 
				
			||||||
		auto slice_offset = new AstNode(AST_SUB, left, right);
 | 
							offset = new AstNode(AST_SUB, left, right);
 | 
				
			||||||
		if (stride == 1) {
 | 
							if (stride > 1) {
 | 
				
			||||||
			offset = slice_offset;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			// offset = (msb - lsb + 1)*stride - 1
 | 
								// offset = (msb - lsb + 1)*stride - 1
 | 
				
			||||||
			auto slice_width = new AstNode(AST_ADD, slice_offset, node_int(1));
 | 
								auto slice_width = new AstNode(AST_ADD, offset, node_int(1));
 | 
				
			||||||
			offset = new AstNode(AST_SUB, multiply_by_const(slice_width, stride), node_int(1));
 | 
								offset = new AstNode(AST_SUB, multiply_by_const(slice_width, stride), node_int(1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -488,25 +486,27 @@ AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node)
 | 
				
			||||||
	auto rnode = node->children[0];
 | 
						auto rnode = node->children[0];
 | 
				
			||||||
	auto lsb_offset = node_int(member_node->range_right);
 | 
						auto lsb_offset = node_int(member_node->range_right);
 | 
				
			||||||
	int stride = range_left - range_right + 1;
 | 
						int stride = range_left - range_right + 1;
 | 
				
			||||||
 | 
						size_t i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Calculate LSB offset for the final index / slice
 | 
						// Calculate LSB offset for the final index / slice
 | 
				
			||||||
	if (rnode->type == AST_RANGE) {
 | 
						if (rnode->type == AST_RANGE) {
 | 
				
			||||||
		lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, 0, stride);
 | 
							lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, i, stride);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (rnode->type == AST_MULTIRANGE) {
 | 
						else if (rnode->type == AST_MULTIRANGE) {
 | 
				
			||||||
		// Add offset for each dimension
 | 
							// Add offset for each dimension
 | 
				
			||||||
		auto mrnode = rnode;
 | 
							auto mrnode = rnode;
 | 
				
			||||||
		for (size_t i = 0; i < mrnode->children.size(); i++) {
 | 
							for (i = 0; i < mrnode->children.size(); i++) {
 | 
				
			||||||
			rnode = mrnode->children[i];
 | 
								rnode = mrnode->children[i];
 | 
				
			||||||
			lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, i, stride);
 | 
								lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, i, stride);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							i--;  // Step back to the final index / slice
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		struct_op_error(node);
 | 
							struct_op_error(node);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Calculate MSB offset for the final index / slice
 | 
						// Calculate MSB offset for the final index / slice
 | 
				
			||||||
	auto msb_offset = struct_index_msb_offset(lsb_offset->clone(), rnode, stride);
 | 
						auto msb_offset = struct_index_msb_offset(lsb_offset->clone(), rnode, member_node, i, stride);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return new AstNode(AST_RANGE, msb_offset, lsb_offset);
 | 
						return new AstNode(AST_RANGE, msb_offset, lsb_offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue