예제 #1
0
 public ConstCharArrayBlock(
     LLVMCodeGenerator CodeGenerator,
     string Data)
 {
     this.codeGen = CodeGenerator;
     this.Data    = Data;
 }
예제 #2
0
 /// <summary>
 /// Creates a code block that produces the given vtable's ID.
 /// </summary>
 /// <param name="CodeGenerator">The code generator that creates the block.</param>
 /// <param name="VTablePointer">A pointer to the vtable whose type ID is to be retrieved.</param>
 public TypeIdBlock(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock VTablePointer)
 {
     this.codeGen       = CodeGenerator;
     this.VTablePointer = VTablePointer;
 }
예제 #3
0
 /// <summary>
 /// Creates a code block that produces a pointer to the given type's vtable.
 /// </summary>
 /// <param name="CodeGenerator">The code generator that creates the block.</param>
 /// <param name="VTableType">The type for which a vtable pointer is to be produced.</param>
 public TypeVTableBlock(
     LLVMCodeGenerator CodeGenerator,
     LLVMType VTableType)
 {
     this.codeGen    = CodeGenerator;
     this.VTableType = VTableType;
 }
예제 #4
0
 public ReturnBlock(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock ReturnValue)
 {
     this.codeGen = CodeGenerator;
     this.retVal  = ReturnValue;
 }
예제 #5
0
 public DelegatingBlock(
     LLVMCodeGenerator CodeGenerator,
     IType Type,
     Func <BasicBlockBuilder, BlockCodegen> Emit)
 {
     this.codeGen   = CodeGenerator;
     this.instrType = Type;
     this.impl      = Emit;
 }
예제 #6
0
 /// <summary>
 /// Creates a block that converts a delegate of one type to a delegate of another.
 /// </summary>
 /// <param name="CodeGenerator">The code generator that creates this block.</param>
 /// <param name="Delegate">The delegate to convert.</param>
 /// <param name="Type">The type to which the delegate is converted.</param>
 public DelegateCastBlock(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock Delegate,
     IType Type)
 {
     this.codeGen    = CodeGenerator;
     this.Delegate   = Delegate;
     this.targetType = Type;
 }
예제 #7
0
 public ConstantBlock(
     LLVMCodeGenerator CodeGenerator,
     IType Type,
     LLVMValueRef Value)
 {
     this.codeGen   = CodeGenerator;
     this.instrType = Type;
     this.val       = Value;
 }
예제 #8
0
 public CompareExchangeBlock(
     CodeBlock Destination,
     CodeBlock Value,
     CodeBlock Comparand,
     LLVMCodeGenerator CodeGenerator)
 {
     this.Destination = Destination;
     this.Value       = Value;
     this.Comparand   = Comparand;
 }
예제 #9
0
 public ComparisonBlock(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock Left,
     CodeBlock Right,
     LLVMIntPredicate Predicate)
 {
     this.codeGen   = CodeGenerator;
     this.lhs       = Left;
     this.rhs       = Right;
     this.predicate = Predicate;
 }
예제 #10
0
 public ReadModifyWriteBlock(
     CodeBlock DestinationAddress,
     CodeBlock Value,
     LLVMAtomicRMWBinOp Op,
     LLVMCodeGenerator CodeGenerator)
 {
     this.DestinationAddress = DestinationAddress;
     this.Value   = Value;
     this.Op      = Op;
     this.codeGen = CodeGenerator;
 }
예제 #11
0
 /// <summary>
 /// Creates a delegate block from the given callee, target block,
 /// operator and delegate type.
 /// </summary>
 /// <param name="CodeGenerator">The code generator that creates this block.</param>
 /// <param name="Callee">The callee.</param>
 /// <param name="Target">The target on which the callee is invoked.</param>
 /// <param name="Op">The operator to use to create a delegate.</param>
 /// <param name="Type">The type of delegate to create.</param>
 public DelegateBlock(
     LLVMCodeGenerator CodeGenerator,
     IMethod Callee,
     CodeBlock Target,
     Operator Op,
     IType Type)
 {
     this.codeGen    = CodeGenerator;
     this.Callee     = Callee;
     this.Target     = Target;
     this.Op         = Op;
     this.resultType = Type;
 }
예제 #12
0
 public BinaryBlock(
     LLVMCodeGenerator CodeGenerator,
     CodeBlock Left,
     CodeBlock Right,
     IType Type,
     Func <LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string, LLVMValueRef> BuildBinary)
 {
     this.codeGen    = CodeGenerator;
     this.lhs        = Left;
     this.rhs        = Right;
     this.resultType = Type;
     this.build      = BuildBinary;
 }
예제 #13
0
        /// <summary>
        /// Declares the given field if it is static and has not been declared
        /// already. An LLVM value that corresponds to the declaration is returned.
        /// </summary>
        /// <param name="Field">The field to declare.</param>
        /// <returns>An LLVM global.</returns>
        public LLVMValueRef DeclareGlobal(IField Field)
        {
            if (!Field.IsStatic)
            {
                throw new InvalidOperationException(
                          "Instance field '" + Field.Name +
                          "' cannot be declared as a global.");
            }

            LLVMValueRef result;

            if (!declaredGlobals.TryGetValue(Field, out result))
            {
                // Declare the global.
                var abiMangler = LLVMSymbolTypeMember.GetLLVMAbi(Field, assembly).Mangler;
                result = DeclareGlobal(Declare(Field.FieldType), abiMangler.Mangle(Field, true));

                if (Field is LLVMField)
                {
                    var llvmField = (LLVMField)Field;

                    // Set the field's linkage.
                    result.SetLinkage(llvmField.Linkage);

                    if (!llvmField.IsImport)
                    {
                        // Zero-initialize it.
                        var codeGenerator     = new Codegen.LLVMCodeGenerator(null);
                        var defaultValueBlock = (Codegen.CodeBlock)codeGenerator.EmitDefaultValue(Field.FieldType);
                        var defaultValueRef   = defaultValueBlock.Emit(
                            new Codegen.BasicBlockBuilder(
                                new Codegen.FunctionBodyBuilder(this, default(LLVMValueRef)),
                                default(LLVMBasicBlockRef)));
                        LLVMSharp.LLVM.SetInitializer(result, defaultValueRef.Value);
                    }
                }

                // Store it in the dictionary.
                declaredGlobals[Field] = result;
            }
            return(result);
        }
예제 #14
0
        private LLVMValueRef DeclareArrayLength(IMethod Method)
        {
            var arrayType = Method.DeclaringType.AsArrayType();

            // Declare T[,...].Length.
            var abi      = LLVMSymbolTypeMember.GetLLVMAbi(Method, assembly);
            var funcType = DeclarePrototype(Method);
            var funcDef  = AddFunction(module, abi.Mangler.Mangle(Method, true), funcType);

            funcDef.SetLinkage(LLVMLinkage.LLVMWeakODRLinkage);
            AddAttributeAtIndex(
                funcDef,
                LLVMAttributeIndex.LLVMAttributeFunctionIndex,
                CreateEnumAttribute("nounwind"));

            // Define T[,...].Length's body.
            var codeGenerator = new Codegen.LLVMCodeGenerator(Method);

            // T[,...].Length computes the product of all dimensions.
            var dimensions = new ICodeBlock[arrayType.ArrayRank];

            for (int i = 0; i < dimensions.Length; i++)
            {
                dimensions[i] = codeGenerator.EmitDereferencePointer(
                    new Codegen.GetDimensionPtrBlock(
                        codeGenerator,
                        (Codegen.CodeBlock)codeGenerator.GetThis().EmitGet(),
                        i));
            }

            var body = (Codegen.CodeBlock)codeGenerator.EmitReturn(codeGenerator.EmitProduct(dimensions));

            // Emit T[,...].Length's body.
            var bodyBuilder       = new Codegen.FunctionBodyBuilder(this, funcDef);
            var entryPointBuilder = bodyBuilder.AppendBasicBlock("entry");

            entryPointBuilder = codeGenerator.Prologue.Emit(entryPointBuilder);
            body.Emit(entryPointBuilder);

            return(funcDef);
        }
예제 #15
0
        public SequenceBlock(
            LLVMCodeGenerator CodeGenerator,
            CodeBlock FirstBlock,
            CodeBlock SecondBlock)
        {
            this.codeGen     = CodeGenerator;
            this.firstBlock  = FirstBlock;
            this.secondBlock = SecondBlock;
            var firstType  = FirstBlock.Type;
            var secondType = SecondBlock.Type;

            if (secondType == PrimitiveTypes.Void &&
                firstType != PrimitiveTypes.Void)
            {
                this.secondIsResult = false;
                this.resultType     = firstType;
            }
            else
            {
                this.secondIsResult = true;
                this.resultType     = secondType;
            }
        }
예제 #16
0
        public override BlockCodegen Emit(BasicBlockBuilder BasicBlock)
        {
            var delegateAndBlock = Delegate.Emit(BasicBlock);

            BasicBlock = delegateAndBlock.BasicBlock;

            var methodTypeAllocBlock = (CodeBlock)codeGen.Allocate(
                new StaticCastExpression(
                    LLVMCodeGenerator.ToExpression(
                        new ConstantBlock(codeGen, PrimitiveTypes.UInt64, SizeOf(DelegateBlock.MethodTypeLayout))),
                    PrimitiveTypes.UInt64),
                Type).Emit(codeGen);

            var methodTypeAllocCodegen = methodTypeAllocBlock.Emit(BasicBlock);

            BasicBlock = methodTypeAllocCodegen.BasicBlock;

            BuildStore(
                BasicBlock.Builder,
                AtAddressEmitVariable.BuildConstantLoad(
                    BasicBlock.Builder,
                    BuildBitCast(
                        BasicBlock.Builder,
                        delegateAndBlock.Value,
                        PointerType(DelegateBlock.MethodTypeLayout, 0),
                        "delegate_ptr"),
                    "delegate_data"),
                methodTypeAllocCodegen.Value);

            BuildStore(
                BasicBlock.Builder,
                TypeVTableBlock.BuildTypeVTable(BasicBlock, Type),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 0, "vtable_ptr_ptr"));

            return(new BlockCodegen(BasicBlock, methodTypeAllocCodegen.Value));
        }
예제 #17
0
        public override BlockCodegen Emit(BasicBlockBuilder BasicBlock)
        {
            var targetAndBlock = InvocationBlock.EmitTarget(BasicBlock, Target);

            BasicBlock = targetAndBlock.BasicBlock;

            var calleeAndBlock = InvocationBlock.EmitCallee(BasicBlock, targetAndBlock.Value, Callee, Op);

            BasicBlock = calleeAndBlock.BasicBlock;

            var methodTypeAllocBlock = (CodeBlock)codeGen.Allocate(
                new StaticCastExpression(
                    LLVMCodeGenerator.ToExpression(
                        new ConstantBlock(codeGen, PrimitiveTypes.UInt64, SizeOf(MethodTypeLayout))),
                    PrimitiveTypes.UInt64),
                Type).Emit(codeGen);

            var methodTypeAllocCodegen = methodTypeAllocBlock.Emit(BasicBlock);

            BasicBlock = methodTypeAllocCodegen.BasicBlock;

            BuildStore(
                BasicBlock.Builder,
                TypeVTableBlock.BuildTypeVTable(BasicBlock, Type),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 0, "vtable_ptr_ptr"));

            bool hasContext = targetAndBlock.Value.Pointer != IntPtr.Zero;

            if (hasContext)
            {
                BuildStore(
                    BasicBlock.Builder,
                    BuildBitCast(
                        BasicBlock.Builder,
                        targetAndBlock.Value,
                        PointerType(Int8Type(), 0),
                        "context_obj"),
                    BuildStructGEP(
                        BasicBlock.Builder,
                        methodTypeAllocCodegen.Value,
                        1,
                        "context_obj_ptr"));
            }

            BuildStore(
                BasicBlock.Builder,
                BuildBitCast(
                    BasicBlock.Builder,
                    calleeAndBlock.Value,
                    PointerType(Int8Type(), 0),
                    "opaque_func_ptr"),
                BuildStructGEP(
                    BasicBlock.Builder,
                    methodTypeAllocCodegen.Value,
                    2,
                    "func_ptr_ptr"));

            BuildStore(
                BasicBlock.Builder,
                ConstInt(Int1Type(), hasContext ? 1ul : 0ul, false),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 3, "has_context_ptr"));

            return(new BlockCodegen(BasicBlock, methodTypeAllocCodegen.Value));
        }
예제 #18
0
 /// <summary>
 /// Creates a block that produces the default value of the given struct type.
 /// </summary>
 /// <param name="CodeGenerator">The code generator that creates this block.</param>
 /// <param name="Type">The struct value whose default value is to be created.</param>
 public DefaultStructBlock(LLVMCodeGenerator CodeGenerator, LLVMType Type)
 {
     this.codeGen    = CodeGenerator;
     this.structType = Type;
 }