Как вызвать @printf в LLVM через систему построения модулей

Я изучаю LLVM. Я понимаю, что это ряд полезных функций C, которые уже встроены в LLVM. Итак, я пытаюсь вызвать функцию @printf из своего кода.

Я нашел соответствующие части в справочном руководстве LLVM, которые описывают IR-код для этого, что относительно ясно:

declare i32 @printf(i8* noalias nocapture, ...)
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42)

и т.д. Но я не могу найти, как это сделать с помощью класса IRBuilder ‹>. Я проверил класс строителя, но ничего не смог понять.

Я не хочу передавать какие-либо причудливые переменные, в основном что-то вроде

printf( "%lu", variable_64_bit );

в C или что-то в этом роде.

Может ли кто-нибудь дать мне представление о том, что я должен сделать, чтобы вызвать функцию printf через построитель.

заранее спасибо


person Rick    schedule 14.05.2015    source источник
comment
Вы имеете в виду IRBuilder?   -  person Ismail Badawi    schedule 15.05.2015
comment
Да, извините, я исправляю свои вопросы по этому поводу   -  person Rick    schedule 15.05.2015


Ответы (2)


Я нашел ответ на эту проблему в другом месте . Фактически, это несколько выходит за рамки моего первоначального вопроса, но было полезно для меня и, надеюсь, поможет и кому-то другому.

person Rick    schedule 15.05.2015

    void kprintf(Module *mod, BasicBlock *bb, const char *format, ...)
    {
        Function *func_printf = mod->getFunction("printf");
        if (!func_printf) {
            PointerType *Pty = PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
            FunctionType *FuncTy9 = FunctionType::get(IntegerType::get(mod->getContext(), 32), true);

            func_printf = Function::Create(FuncTy9, GlobalValue::ExternalLinkage, "printf", mod);
            func_printf->setCallingConv(CallingConv::C);

            AttrListPtr func_printf_PAL;
            func_printf->setAttributes(func_printf_PAL);
        }

        IRBuilder <> builder(mod->getContext());
        builder.SetInsertPoint(bb);

        Value *str = builder.CreateGlobalStringPtr(format);
        std::vector <Value *> int32_call_params;
        int32_call_params.push_back(str);

        va_list ap;
        va_start(ap, format);

        char *str_ptr = va_arg(ap, char*);
        Value *format_ptr = builder.CreateGlobalStringPtr(str_ptr);
        int32_call_params.push_back(format_ptr);

        std::vector<llvm::Value*> extra;
        do {
            llvm::Value *op = va_arg(ap, llvm::Value*);
            if (op) {
                int32_call_params.push_back(op);
            } else {
                break;
            }
        } while (1);
        va_end(ap);

        CallInst * int32_call = CallInst::Create(func_printf, int32_call_params, "call", bb);
    }
    #define oprintf(...) kprintf(__VA_ARGS__)
    #define llvm_printf(...) oprintf(mod, bb, __VA_ARGS__, NULL)

    llvm_printf("Output: 0x%08X %f %d\n", 0x12345678, 3.1415926, 12345);

Надеюсь помочь вам

person Silent_DXX    schedule 21.09.2017