コード例 #1
0
ファイル: init.cpp プロジェクト: aulwes/Byfl
    /**
     * This function creates a module constructor function to create the
     * map from function keys to function names.  This function will be
     * automatically called when the module is loaded.
     *
     * The code was generated by using clang on a test file. The test
     * file looked like (foo.cc):
     * __attribute__((constructor))
     * static void init()
     * {
     * }
     *
     * Then, run:
     * 1. clang -S -emit-llvm -c foo.cc
     * 2. llc -march=cpp foo.bc -o foo.lc
     * The output foo.lc provides code for generating a ctor using LLVM.
     *
     */
    void BytesFlops::initializeKeyMap(Module& module)
    {
        if ( module.getFunction("func_key_map_ctor") )
            return;

        LLVMContext& ctx = module.getContext();

        // Type Definitions
        std::vector<Type*>StructTy_1_fields;
        StructTy_1_fields.push_back(IntegerType::get(ctx, 32));
        std::vector<Type*>FuncTy_3_args;

        FunctionType* FuncTy_3 = FunctionType::get(
                                /*Result=*/   Type::getVoidTy(ctx),
                                /*Params=*/   FuncTy_3_args,
                                /*isVarArg=*/ false);

        PointerType* PointerTy_2 = PointerType::get(FuncTy_3, 0);

        StructTy_1_fields.push_back(PointerTy_2);

        StructType *
        StructTy_1 = StructType::get(ctx, StructTy_1_fields,
                                     /*isPacked=*/false);

        ArrayType* ArrayTy_0 = NULL;

        // Function Declarations
        func_map_ctor = Function::Create(
                        /*Type=*/FuncTy_3,
                        /*Linkage=*/GlobalValue::InternalLinkage,
                        /*Name=*/"func_key_map_ctor", &module);
        func_map_ctor->setCallingConv(CallingConv::C);

        AttributeSet func__ZL4initv_PAL;
        SmallVector<AttributeSet, 4> Attrs;
        AttributeSet PAS;
        AttrBuilder B;
        B.addAttribute(Attribute::NoUnwind);
        B.addAttribute(Attribute::UWTable);
        PAS = AttributeSet::get(ctx, ~0U, B);

        Attrs.push_back(PAS);
        func__ZL4initv_PAL = AttributeSet::get(ctx, Attrs);
        func_map_ctor->setAttributes(func__ZL4initv_PAL);

        // Global Variable Declarations
        // Constant Definitions
        std::vector<Constant*> ctor_elems;
        std::vector<Constant*> const_struct_8_fields;
        ConstantInt* const_int32_9 = ConstantInt::get(ctx, APInt(32, StringRef("65535"), 10));
        const_struct_8_fields.push_back(const_int32_9);
        const_struct_8_fields.push_back(func_map_ctor);
        Constant* const_struct_8 = ConstantStruct::get(StructTy_1, const_struct_8_fields);
        ctor_elems.push_back(const_struct_8);

        GlobalVariable* llvm_global_ctors;

        /**
         * Add our constructor to the list of global constructors for the
         * module.  It's possible that a module already contains a ctor.
         */
        GlobalVariable*
        current_ctors = module.getGlobalVariable("llvm.global_ctors");
        if ( !current_ctors )
        {
            ArrayTy_0 = ArrayType::get(StructTy_1, 1);
        }
        else
        {
            // there are existing ctors, and the initializer points to them.
            // add ours to the initializer list (actually, we create a new
            // initializer list and add the existing ones to it).
            Constant * initializer = current_ctors->getInitializer();

            ConstantArray *
            ar = llvm::dyn_cast<ConstantArray>(initializer);
            assert( ar );

            int cnt = 0;
            Constant *
            elt = ar->getAggregateElement(cnt);

            // add existing ctors to new initializer list, and get rid
            // of the old one.
            while ( elt )
            {
                assert( llvm::dyn_cast<ConstantStruct>(elt) );
                ctor_elems.push_back(elt);
                cnt++;
                elt = ar->getAggregateElement(cnt);
            }
            ArrayTy_0 = ArrayType::get(StructTy_1, ctor_elems.size());
            current_ctors->eraseFromParent();
        }

        llvm_global_ctors = new GlobalVariable(/*Module=*/module,
                              /*Type=*/       ArrayTy_0,
                              /*isConstant=*/ false,
                              /*Linkage=*/    GlobalValue::AppendingLinkage,
                              /*Initializer=*/0, // has initializer, specified below
                              /*Name=*/       "llvm.global_ctors");


        Constant* ctor_array = ConstantArray::get(ArrayTy_0, ctor_elems);

        // Global Variable Definitions
        llvm_global_ctors->setInitializer(ctor_array);
    }