# encoding: utf-8 # frozen_string_literal: true module Carbon module Tacky # A "builder." This is used in order to create an instruction set for a # block. The builder defines a set of methods that create and append # an instruction to the parent block. Each instruction gets its own # instruction ID relative to the parent block. # # @see http://llvm.org/releases/3.5.2/docs/LangRef.html The LLVM Language # Reference Manual. # @api semiprivate class Builder # Initialize the builder with the given block. # # @param block [Tacky::Block] The block to build onto. def initialize(block) @block = block end methods = ::LLVM::Builder.instance_methods - Object.instance_methods - %i(dispose insert_block position position_at_end position_before to_ptr) # @!method add(left, right, name = "") # Creates an `add` instruction. # @return [Tacky::Reference] # @!method aggregate_ret(*values) # Creates a `ret` instruction. # @return [Tacky::Reference] # @!method alloca(type, name = "") # Creates an `alloca` instruction. # @return [Tacky::Reference] # @!method and(left, right, name = "") # Creates an `and` instruction. # @return [Tacky::Reference] # @!method array_alloca(type, size, name = "") # Creates an `array_alloca` instruction. # @return [Tacky::Reference] # @!method ashr(left, right, name = "") # Creates an `ashr` instruction. # @return [Tacky::Reference] # @!method bit_cast(value, type, name = "") # Creates a `bitcast` instruction. # @return [Tacky::Reference] # @!method br(destination) # Creates a `br` instruction. # @return [Tacky::Reference] # @!method call(function, *arguments) # Creates a `call` instruction. # @return [Tacky::Reference] # @!method cond(iftrue, iffalse) # Creates a `br` instruction. # @return [Tacky::Reference] # @!method exact_sdiv(left, right, name = "") # Creates an `sdiv` instruction. # @return [Tacky::Reference] # @!method extract_element(vector, index, name = "") # Creates an `extract_element` instruction. # @return [Tacky::Reference] # @!method extract_value(aggregate, index, name = "") # Creates an `extract_value` instruction. # @return [Tacky::Reference] # @!method fadd(left, right, name = "") # Creates an `fadd` instruction. # @return [Tacky::Reference] # @!method fcmp(pred, left, right, name = "") # Creates an `fcmp` instruction. # @return [Tacky::Reference] # @!method fdiv(left, right, name = "") # Creates an `fdiv` instruction. # @return [Tacky::Reference] # @!method fmul(left, right, name = "") # Creates an `fmul` instruction. # @return [Tacky::Reference] # @!method fp2si(value, type, name = "") # Creates a `fptosi` instruction. # @return [Tacky::Reference] # @!method fp2ui(value, type, name = "") # Creates a `fptoui` instruction. # @return [Tacky::Reference] # @!method fp_cast(value, type, name = "") # Creates a `bitcast` instruction. # @return [Tacky::Reference] # @!method fp_ext(value, type, name = "") # Creates a `fpext` instruction. # @return [Tacky::Reference] # @!method fp_trunc(value, type, name = "") # Creates a `fptrunc` instruction. # @return [Tacky::Reference] # @!method free(pointer) # Creates a `free` instruction. # @return [Tacky::Reference] # @!method frem(left, right, name = "") # Creates a `frem` instruction. # @return [Tacky::Reference] # @!method fsub(left, right, name = "") # Creates a `fsub` instruction. # @return [Tacky::Reference] # @!method gep(value, indices, name = "") # Creates a `gep` instruction. # @return [Tacky::Reference] # @!method global_string(string, name = "") # Creates a `global_string` instruction. # @return [Tacky::Reference] # @!method global_string_pointer(string, name = "") # Creates a `global_string_pointer` instruction. # @return [Tacky::Reference] # @!method ibr(addr, destinations) # Creates a `ibr` instruction. # @return [Tacky::Reference] # @!method icmp(pred, left, right, name = "") # Creates an `icmp` instruction. # @return [Tacky::Reference] # @!method inbounds_gep(value, indices, name = "") # Creates an `gep` instruction. # @return [Tacky::Reference] # @!method insert_element(vector, value, index, name = "") # Creates an `insert_element` instruction. # @return [Tacky::Reference] # @!method insert_value(aggregate, value, index, name = "") # Creates an `insert_value` instruction. # @return [Tacky::Reference] # @!method int2ptr(value, type, name = "") # Creates an `inttoptr` instruction. # @return [Tacky::Reference] # @!method int_cast(value, type, name = "") # Creates an `bitcast` instruction. # @return [Tacky::Reference] # @!method invoke(function, params, normal, exception, name = "") # Creates an `invoke` instruction. # @return [Tacky::Reference] # @!method is_not_null(value, name = "") # Creates an `is_not_null` instruction. # @return [Tacky::Reference] # @!method is_null(value, name = "") # Creates an `is_null` instruction. # @return [Tacky::Reference] # @!method load(pointer, name = "") # Creates a `load` instruction. # @return [Tacky::Reference] # @!method lshr(left, right, name = "") # Creates a `lshr` instruction. # @return [Tacky::Reference] # @!method malloc(type, name = "") # Creates a `malloc` instruction. # @return [Tacky::Reference] # @!method mul(left, right, name = "") # Creates a `mul` instruction. # @return [Tacky::Reference] # @!method neg(value, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method not(value, name = "") # Creates a `not` instruction. # @return [Tacky::Reference] # @!method nsw_add(left, right, name = "") # Creates an `add` instruction. # @return [Tacky::Reference] # @!method nsw_mul(left, right, name = "") # Creates a `mul` instruction. # @return [Tacky::Reference] # @!method nsw_neg(left, right, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method nsw_sub(left, right, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method nuw_add(left, right, name = "") # Creates an `add` instruction. # @return [Tacky::Reference] # @!method nuw_mul(left, right, name = "") # Creates a `mul` instruction. # @return [Tacky::Reference] # @!method nuw_neg(left, right, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method nuw_sub(left, right, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method or(left, right, name = "") # Creates an `or` instruction. # @return [Tacky::Reference] # @!method phi(type, incoming, name = "") # Creates a `phi` instruction. # @return [Tacky::Reference] # @!method pointer_cast(value, type, name = "") # Creates a `bitcast` instruction. # @return [Tacky::Reference] # @!method ptr2int(value, type, name = "") # Creates a `ptrtoint` instruction. # @return [Tacky::Reference] # @!method ptr_diff(left, right, name = "") # Creates a `ptr_diff` instruction. # @return [Tacky::Reference] # @!method ret(value) # Creates a `ret` instruction. # @return [Tacky::Reference] # @!method ret_void(value) # Creates a `ret` instruction. # @return [Tacky::Reference] # @!method sdiv(left, right, name = "") # Creates an `sdiv` instruction. # @return [Tacky::Reference] # @!method select(check, vtrue, vfalse, name = "") # Creates a `select` instruction. # @return [Tacky::Reference] # @!method sext(value, type, name = "") # Creates a `sext` instruction. # @return [Tacky::Reference] # @!method sext_or_bit_cast(value, type, name = "") # Creates a `sext` or `bitcast` instruction, depending on the value # and type. # @return [Tacky::Reference] # @!method shl(left, right, name = "") # Creates a `shl` instruction. # @return [Tacky::Reference] # @!method shuffle_vector(vec1, vec2, mask, name = "") # Creates a `shuffle_vector` instruction. # @return [Tacky::Reference] # @!method si2fp(value, type, name = "") # Creates a `sitofp` instruction. # @return [Tacky::Reference] # @!method srem(left, right, name = "") # Creates a `srem` instruction. # @return [Tacky::Reference] # @!method store(pointer, value) # Creates a `store` instruction. # @return [Tacky::Reference] # @!method struct_gep(value, index, name = "") # Creates a `gep` instruction. # @return [Tacky::Reference] # @!method sub(left, right, name = "") # Creates a `sub` instruction. # @return [Tacky::Reference] # @!method switch(value, default, cases) # Creates a `switch` instruction. # @return [Tacky::Reference] # @!method trunc(value, type, name = "") # Creates a `trunc` instruction. # @return [Tacky::Reference] # @!method trunc_or_bit_cast(value, type, name = "") # Creates a `trunc` or `bitcast` instruction based on the value and # type. # @return [Tacky::Reference] # @!method udiv(left, right, name = "") # Creates a `udiv` instruction. # @return [Tacky::Reference] # @!method ui2fp(value, type, name = "") # Creates a `uitofp` instruction. # @return [Tacky::Reference] # @!method unreachable # Creates an `unreachable` instruction. # @return [Tacky::Reference] # @!method unwind # Creates an `unwind` instruction. # @return [Tacky::Reference] # @!method urem(left, right, name = "") # Creates a `urem` instruction. # @return [Tacky::Reference] # @!method zext(value, type, name = "") # Creates a `zext` instruction. # @return [Tacky::Reference] # @!method zext_or_bit_cast(value, type, name = "") # Creates a `zext` or `bitcast` instruction based on the value and # type. # @return [Tacky::Reference] methods.each { |m| define_method(m) { |*a| _call(m, *a) } } # Returns the size of a type. This may be a constant value or a # generated value. # # @param type [Concrete::Type] The type to find the size of. # @return [Tacky::Reference] A value representing the return value of # the instruction. def sizeof(type) _call(:_sizeof, type) end # Returns a null value of a given type. This may be a constant value or a # generated value. # # @param type [Concrete::Type] The type to null. # @return [Tacky::Reference] A value representing the return value of # the instruction. def null(type) _call(:_null, type) end # Creates an instruction, and returns a reference to that instruction. # The reference points to the instruction using the "instruction id," # which is essentially the instruction's place in the block. # # @api private # @param inst [::Symbol, ::String] The instruction name. # @param parameters [] The # parameters that are being passed to the instruction. # @param name [::String] The return value name of the instruction. # @return [Tacky::Reference] The reference to the new instruction. def _call(inst, *parameters, name: "") id = @block.next instruction = Tacky::Instruction.new(id, inst, parameters) instruction.name = name @block.instructions << instruction Tacky::Reference.new(id) end end end end