Generate recursively basic block for this expression

ssa An instance of the SSA class initialized with the enclosing APropdef old_block A basic block not completely filled Return the last created block (the last block can be nested)

Property definitions

nitc :: ssa $ AExpr :: generate_basic_blocks
	# Generate recursively basic block for this expression
	# *`ssa` An instance of the SSA class initialized with the enclosing `APropdef`
	# *`old_block` A basic block not completely filled
	# Return the last created block (the last block can be nested)
	fun generate_basic_blocks(ssa: SSA, old_block: BasicBlock): BasicBlock
	do
		return old_block
	end
src/ssa.nit:574,2--581,4

nitc :: ssa $ ABlockExpr :: generate_basic_blocks
	# The block needs to know if a new block is created
	redef fun generate_basic_blocks(ssa, old_block)
	do
		var last_block = old_block
		var current_block: BasicBlock

		# Recursively continue in the body of the block
		for i in [0..self.n_expr.length[ do
			current_block = self.n_expr[i].generate_basic_blocks(ssa, last_block)

			if current_block.need_update then
				if i < (self.n_expr.length-1) then
					# Current_block must be filled
					current_block.first = self.n_expr[i+1]
					current_block.last = self.n_expr[i+1]
					current_block.need_update = false
				else
					# Put the current block at the end of the block
					current_block.first = last_block.last
					current_block.last = last_block.last
				end
			end

			if not current_block.last isa AEscapeExpr or current_block.last isa AReturnExpr then
				# Re-affected the last block
				current_block.last = self.n_expr[i]
			end

			last_block = current_block
		end

		return last_block
	end
src/ssa.nit:924,2--956,4

nitc :: ssa $ AVardeclExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		var decl = self.variable.as(not null)

		# Add the corresponding variable to the enclosing mpropdef
		ssa.propdef.variables.add(decl)

		decl.original_variable = decl
		decl.assignment_blocks.add(old_block)
		old_block.variables.add(decl)

		if self.n_expr != null then
			self.variable.dep_exprs.add(self.n_expr.as(not null))
			old_block = self.n_expr.generate_basic_blocks(ssa, old_block)
		end

		return old_block
	end
src/ssa.nit:605,2--622,4

nitc :: ssa $ AIfExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# Terminate the previous block
		old_block.last = self

		# We start two new blocks if the if has two branches
		var block_then = new BasicBlock

		# Visit the test of the if
		self.n_expr.generate_basic_blocks(ssa, old_block)

		# Launch the recursion in two successors if they exist
		if self.n_then != null then
			old_block.link(block_then)

			block_then.first = self.n_then.as(not null)
			block_then.last = self.n_then.as(not null)
			self.n_then.generate_basic_blocks(ssa, block_then)
		end

		var block_else = new BasicBlock

		if self.n_else != null then
			old_block.link(block_else)

			block_else.first = self.n_else.as(not null)
			block_else.last = self.n_else.as(not null)
			self.n_else.generate_basic_blocks(ssa, block_else)
		end

		# Create a new BasicBlock to represent the two successor
		# branches of the if
		var new_block = new BasicBlock
		new_block.first = self
		new_block.last = self

		if self.n_then != null then block_then.link(new_block)

		# The new block needs to be filled by the caller
		new_block.need_update = true

		if block_else.predecessors.length != 0 then block_else.link(new_block)

		return new_block
	end
src/ssa.nit:960,2--1004,4

nitc :: ssa $ AIfexprExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# Terminate the previous block
		old_block.last = self

		# We start two new blocks if the if has two branches
		var block_then = new BasicBlock

		# Visit the test of the if
		self.n_expr.generate_basic_blocks(ssa, old_block)

		# Launch the recursion in two successors if they exist
		old_block.link(block_then)

		block_then.first = self.n_then
		block_then.last = self.n_then
		self.n_then.generate_basic_blocks(ssa, block_then)

		var block_else = new BasicBlock

		old_block.link(block_else)

		block_else.first = self.n_else
		block_else.last = self.n_else
		self.n_else.generate_basic_blocks(ssa, block_else)

		# Create a new BasicBlock to represent the two successor
		# branches of the if
		var new_block = new BasicBlock
		new_block.first = self
		new_block.last = self

		block_then.link(new_block)

		# The new block needs to be filled by the caller
		new_block.need_update = true

		block_else.link(new_block)

		return new_block
	end
src/ssa.nit:1008,2--1048,4

nitc :: ssa $ AAssertExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)

		# The condition of the assert is the last expression of the previous block
		old_block.last = self.n_expr

		# The block if the assert fail
		var block_false = new BasicBlock

		if self.n_else != null then
			block_false.first = self.n_else.as(not null)
			block_false.last = self.n_else.as(not null)
			self.n_else.generate_basic_blocks(ssa, block_false)
		else
			block_false.first = self
			block_false.last = self
		end

		old_block.link(block_false)

		# The block if the assert is true: the execution continue
		var block_true = new BasicBlock
		block_true.first = self
		block_true.last = self

		old_block.link(block_true)

		return block_true
	end
src/ssa.nit:693,2--722,4

nitc :: ssa $ AArrayExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		for nexpr in self.n_exprs do
			old_block = nexpr.generate_basic_blocks(ssa, old_block)
		end

		return old_block
	end
src/ssa.nit:765,2--772,4

nitc :: ssa $ AParExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:826,2--829,4

nitc :: ssa $ AOnceExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:833,2--836,4

nitc :: ssa $ ASendExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# A call does not finish the current block,
		# because we create intra-procedural basic blocks here

		ssa.propdef.object_sites.add(self)

		# Recursively goes into arguments to find variables if any
		for e in self.raw_arguments do e.generate_basic_blocks(ssa, old_block)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:840,2--851,4

nitc :: ssa $ ASuperExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# Recursively goes into arguments to find variables if any
		for arg in self.n_args.n_exprs do arg.generate_basic_blocks(ssa, old_block)

		return old_block
	end
src/ssa.nit:869,2--875,4

nitc :: ssa $ ANewExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		for e in self.n_args.n_exprs do e.generate_basic_blocks(ssa, old_block)

		ssa.propdef.object_sites.add(self)

		return old_block
	end
src/ssa.nit:879,2--886,4

nitc :: ssa $ AVarExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.variable.as(not null).read_blocks.add(old_block)
		old_block.variables.add(self.variable.as(not null))

		self.variable.as(not null).original_variable = self.variable.as(not null)
		# Save this read site in the block
		old_block.read_sites.add(self)
		old_block.variables_sites.add(self)

		return old_block
	end
src/ssa.nit:590,2--601,4

nitc :: ssa $ ANotExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:750,2--753,4

nitc :: ssa $ ACrangeExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:785,2--789,4

nitc :: ssa $ AOrangeExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:793,2--797,4

nitc :: ssa $ AIsaExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		ssa.propdef.object_sites.add(self)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:801,2--806,4

nitc :: ssa $ AAsCastExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		ssa.propdef.object_sites.add(self)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:810,2--815,4

nitc :: ssa $ AAsNotnullExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:819,2--822,4

nitc :: ssa $ AAttrExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		ssa.propdef.object_sites.add(self)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:890,2--895,4

nitc :: ssa $ AIssetAttrExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:917,2--920,4

nitc :: ssa $ AOrElseExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:757,2--761,4

nitc :: ssa $ ASuperstringExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		for nexpr in self.n_exprs do old_block = nexpr.generate_basic_blocks(ssa, old_block)

		return old_block
	end
src/ssa.nit:776,2--781,4

nitc :: ssa $ ASendReassignFormExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)

		ssa.propdef.object_sites.add(self)

		# Recursively goes into arguments to find variables if any
		for e in self.raw_arguments do e.generate_basic_blocks(ssa, old_block)

		return self.n_value.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:855,2--865,4

nitc :: ssa $ AAttrAssignExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		ssa.propdef.object_sites.add(self)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:899,2--904,4

nitc :: ssa $ AAttrReassignExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		ssa.propdef.object_sites.add(self)

		return self.n_expr.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:908,2--913,4

nitc :: ssa $ AReturnExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# The return just set the current block and stop the recursion
		if self.n_expr != null then
			old_block = self.n_expr.generate_basic_blocks(ssa, old_block)

			# Store the return expression in the dependences of the dedicated returnvar
			ssa.propdef.returnvar.dep_exprs.add(n_expr.as(not null))
		end

		old_block.last = self

		return old_block
	end
src/ssa.nit:676,2--689,4

nitc :: ssa $ ABreakExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		# Finish the old block
		old_block.last = self

		return old_block
	end
src/ssa.nit:659,2--665,4

nitc :: ssa $ AContinueExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		return old_block
	end
src/ssa.nit:669,2--672,4

nitc :: ssa $ ADoExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		old_block.last = self

		# The beginning of the block is the first instruction
		var block = new BasicBlock
		block.first = self.n_block.as(not null)
		block.last = self.n_block.as(not null)

		old_block.link(block)
		return self.n_block.generate_basic_blocks(ssa, block)
	end
src/ssa.nit:1052,2--1063,4

nitc :: ssa $ AWhileExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		old_block.last = self

		# The beginning of the block is the test of the while
		var block = new BasicBlock
		block.first = self.n_expr
		block.last = self.n_block.as(not null)

		old_block.link(block)

		self.n_expr.generate_basic_blocks(ssa, old_block)
		self.n_block.generate_basic_blocks(ssa, block)

		# Link the inside of the block to the previous block
		block.link_special(old_block)

		# Create a new Block after the while
		var new_block = new BasicBlock
		new_block.first = self
		new_block.last = self
		new_block.need_update = true

		old_block.link_special(new_block)

		return new_block
	end
src/ssa.nit:1067,2--1093,4

nitc :: ssa $ ALoopExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		old_block.last = self

		# The beginning of the block is the first instruction
		var block = new BasicBlock
		block.first = self.n_block.as(not null)
		block.last = self.n_block.as(not null)

		old_block.link(block)
		self.n_block.generate_basic_blocks(ssa, block)

		return block
	end
src/ssa.nit:1097,2--1110,4

nitc :: ssa $ AForExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		old_block.last = self

		# The beginning of the block is the first instruction
		var block = new BasicBlock
		block.first = self.n_groups.first.n_expr
		block.last = self.n_block.as(not null)

		for g in n_groups do
			# Visit the test of the if
			g.n_expr.generate_basic_blocks(ssa, block)

			# Collect the variables declared in the for
			for v in g.variables do
				ssa.propdef.variables.add(v)
			end
		end

		old_block.link(block)

		block.link(old_block)

		var new_block = new BasicBlock
		new_block.first = self
		new_block.last = self

		new_block.need_update = true

		return new_block
	end
src/ssa.nit:1114,2--1144,4

nitc :: ssa $ AOrExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:726,2--730,4

nitc :: ssa $ AImpliesExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:734,2--738,4

nitc :: ssa $ AAndExpr :: generate_basic_blocks
	redef fun generate_basic_blocks(ssa, old_block)
	do
		self.n_expr.generate_basic_blocks(ssa, old_block)
		return self.n_expr2.generate_basic_blocks(ssa, old_block)
	end
src/ssa.nit:742,2--746,4