How To Call #printf in LLVM through the module builder system - llvm

I am learning LLVM. I understand that thre are a number of useful C functions that are provided in LLVM already as intrinsic. So I'm trying to call the #printf function from my code.
I found the respective parts in the LLVM reference manual that describe the IR code to do that, which is relative clear:
declare i32 #printf(i8* noalias nocapture, ...)
call i32 (i8*, ...)* #printf(i8* %msg, i32 12, i8 42)
etc. But I am not able to find how to do that using the IRBuilder<> class. I checked the builder class but I wasn't able to figure anything out.
I don't want to pass any fancy variables, basically just something like
printf( "%lu", variable_64_bit );
in C or something like that.
Could anybody give me an idea what I must do to call the printf function through the builder.
Thanks in advance

I found an answer to this problem elsewhere. In fact it goes somewhat beyond my original question but it was helpful for me and hopefully it will help somebody else as well.

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);
Hope to be of help to you

Related

LLVM ERROR: MCJIT::runFunction does not support full-featured argument passing

I have got an example from here and I faced with a run error
LLVM ERROR: Target does not support MC emission!
which I fixed it by this.
nevertheless, I still observe runtime problem:
./example 3 5
LLVM ERROR: MCJIT::runFunction does not support full-featured argument passing. Please use ExecutionEngine::getFunctionAddress and cast the result to the desired function pointer type.
main.cpp
/**
* LLVM equivalent of:
*
* int sum(int a, int b) {
* return a + b;
* }
*/
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/BitWriter.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
LLVMModuleRef mod = LLVMModuleCreateWithName("my_module");
LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() };
LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0);
LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp");
LLVMBuildRet(builder, tmp);
char *error = NULL;
LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
LLVMExecutionEngineRef engine;
error = NULL;
LLVMLinkInMCJIT();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter(); // added
LLVMInitializeNativeAsmParser(); // added
if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0)
{
fprintf(stderr, "failed to create execution engine\n");
abort();
}
if (error)
{
fprintf(stderr, "error: %s\n", error);
LLVMDisposeMessage(error);
exit(EXIT_FAILURE);
}
if (argc < 3)
{
fprintf(stderr, "usage: %s x y\n", argv[0]);
exit(EXIT_FAILURE);
}
long long x = strtoll(argv[1], NULL, 10);
long long y = strtoll(argv[2], NULL, 10);
LLVMGenericValueRef args[] = {
LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)
};
LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args);
printf("%d\n", (int)LLVMGenericValueToInt(res, 0));
// Write out bitcode to file
if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) {
fprintf(stderr, "error writing bitcode to file, skipping\n");
}
LLVMDisposeBuilder(builder);
LLVMDisposeExecutionEngine(engine);
}
Though the meessage is clear for the view point of the code author, for me as a user it is so cryptic. How can I solve this?
From the documentation of MCJIT::runFunction:
For MCJIT execution engines, clients are encouraged to use the "GetFunctionAddress" method (rather than runFunction) and cast the returned uint64_t to the desired function pointer type. However, for backwards compatibility MCJIT's implementation can execute 'main-like' function (i.e. those returning void or int, and taking either no arguments or (int, char*[])).
So you can't call MCJIT::runFunction (and by extension the C API's LLVMRunFunction when used with an MCJIT engine) unless the arguments array is either empty or consists of only an i32 and an i8* (in that order). Your array contains two i32s, so it does not meet those restrictions.
As stated in the documentation (and the exception message), you should instead use ExecutionEngine::getFunctionAddress (or its C wrapper LLVMGetFunctionAddress), cast the result to int (*)(int, int) and then call it as f(0, 0);.

How to check if a target of an LLVM AllocaInst is a function pointer

%pointer = alloca void (i32)*, align 8
How to check if %pointer is a function pointer?Can I get the parameter list of the function pointer?
Let Create a function that check if an Alloca Instruction Type is a function pointer.
bool isFunctionPointerType(Type *type){
// Check the type here
if(PointerType *pointerType=dyn_cast<PointerType>(type)){
return isFunctionPointerType(pointerType->getElementType());
}
//Exit Condition
else if(type->isFunctionTy()){
return true;
}
return false;
}
In your runOnModule/runOnFunction Pass
if(AllocaInst *allocaInst=dyn_cast<AllocaInst>(inst)){
if(isFunctionPointerType(allocaInst->getType())){
errs()<<"Funtion Pointer Type\n";
}
}
The above pass are tested on the following source.c code
#include <stdio.h>
void fun(int a)
{
printf("Value of a is %d\n", a);
}
int main()
{
void (*fun_ptr)(int) = &fun;
(*fun_ptr)(10);
return 0;
}
Corresponding LLVM Bitcode without any optimization
entry:
%retval = alloca i32, align 4
%fun_ptr = alloca void (i32)*, align 8
store i32 0, i32* %retval, align 4
call void #llvm.dbg.declare(metadata void (i32)** %fun_ptr, metadata !11,
... metadata !15), !dbg !16
store void (i32)* #_Z3funi, void (i32)** %fun_ptr, align 8, !dbg !16
%0 = load void (i32)*, void (i32)** %fun_ptr, align 8, !dbg !17
call void %0(i32 10), !dbg !18
ret i32 0, !dbg !19
Successfully detect func_ptr as a function pointer.
Note that the code use recursion to find the type recursively
Another way is to track the used of func_ptr using def-use chain in LLVM, ie by tracking the StoreInst and check if the source operand is a pointer to function : haven't try yet.
Hope this helps...
If it help please mark it as correct solution or upvote.. Thanks..

GCC Plugin, add new optimizing pragma

I'm creating a GCC plugin.
I'm trying to create a plugin for a specific loop transformation - unroll loop exactly N (parameter given) times.
I have installed plugins correctly and I can successfully register my pragma in compilation process.
When I register pragma with function c_register_pragma, I can handle it in lexical analysis (with function handle_my_pragma), but how can I find it then?
I can also define my own pass and traverse GIMPLE, but there is no trace of any pragma.
So my question is: Where is my pragma and how can I influence my code with it?
Or what would you suggest to reach my goal? It doesn't have to be with pragma, but it seemed to be a good idea.
Also, I know about MELT, but within the study of GCC, I would prefer pure plugin in C.
My code
static bool looplugin_gate(void)
{
return true;
}
static unsigned looplugin_exec(void)
{
printf( "===looplugin_exec===\n" );
basic_block bb;
gimple stmt;
gimple_stmt_iterator gsi;
FOR_EACH_BB(bb)
{
for (gsi=gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi), j++)
{
stmt = gsi_stmt(gsi);
print_gimple_stmt (stdout, stmt, 0, TDF_SLIM);
}
}
return 0;
}
void handle_my_pragma(cpp_reader *ARG_UNUSED(dummy))
{
printf ("=======Handling loopragma=======\n" );
enum cpp_ttype token;
tree x;
int num = -1;
token = pragma_lex (&x);
if (TREE_CODE (x) != INTEGER_CST)
warning (0, "invalid constant in %<#pragma looppragma%> - ignored");
num = TREE_INT_CST_LOW (x);
printf( "Detected #pragma loopragma %d\n", num );
}
static void register_my_pragma (void *event_data, void *data)
{
warning (0, G_("Callback to register pragmas"));
c_register_pragma (NULL, "loopragma", handle_my_pragma);
}
static struct opt_pass myopt_pass =
{
.type = GIMPLE_PASS,
.name = "LoopPlugin",
.gate = looplugin_gate,
.execute = looplugin_exec
};
int plugin_init(struct plugin_name_args *info, /* Argument infor */
struct plugin_gcc_version *ver) /* Version of GCC */
{
const char * plugin_name = info->base_name;
struct register_pass_info pass;
pass.pass = &myopt_pass;
pass.reference_pass_name = "ssa";
pass.ref_pass_instance_number = 1;
pass.pos_op = PASS_POS_INSERT_BEFORE;
register_callback( plugin_name, PLUGIN_PRAGMAS, register_my_pragma, NULL );
register_callback( plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass );
return 0;
}
PS: If there was someone familiar with GCC plugins development and had a good heart :), please contact me (mbukovy gmail com). I'm doing this because of my final thesis (own choice) and I welcome any soulmate.
When I register pragma with function c_register_pragma, I can handle it in lexical analysis (with function handle_my_pragma), but how can I find it then?
There is an option (actually, a hack) to create fictive helper function call at the place of pragma, when parsing. Then you can detect this function by name in intermediate representation.
Aslo, several days ago there was a question in GCC ML from felix.yang (huawei) "How to deliver loop-related pragma information from TREE to RTL?" - http://comments.gmane.org/gmane.comp.gcc.devel/135243 - check the thread
Some recommendations from the list:
Look at how we implement #pragma ivdep (see replace_loop_annotate ()
and fortran/trans-stmt.c where it builds ANNOTATE_EXPR).
Patch with replace_loop_annotate() function addition and ivdep pragma implementation: "Re: Patch: Add #pragma ivdep support to the ME and C FE" by Tobias Burnus (2013-08-24).
I do not think registering a DEFERRED pragma in plugin is possible, since the handler for deferred pragma is not exposed in GCC plugin level.
So your pragma just works during preprocessing stage instead of parsing stage, then, it is quite tricky to achieve an optimization goal.

How can I add reference to a variable defined in previous function in LLVM IR?

I'm new to LLVM IR and I'm implementing PL0 language. http://en.wikipedia.org/wiki/PL/0
I'm generating the testfile as following:
const a = 10;
var b, c;
procedure check1;
var dd;
procedure check2;
c := 2;
begin
dd := 1
end;
begin
b := -1024+53*(-514-766)/93+100;
c := b
end.
And the LLVM IR I generated is like this:
; ModuleID = 'LLVM Module'
define void #__global_main_entry__() {
BlockUnitEntry:
%b = alloca i32
%c = alloca i32
store i32 -1653, i32* %b
%b1 = load i32* %b
store i32 %b1, i32* %c
ret void
}
define void #check1() {
ProcedureEntry:
%dd = alloca i32
store i32 1, i32* %dd
ret void
}
define void #check2() {
ProcedureEntry:
store i32 2, i32* %c
ret void
}
I got a painful error here (at destruction):
While deleting: i32* %c
Use still stuck around after Def is destroyed: store i32 2, i32* %c
test004_llvm_generate: /files/Install/LLVM_Framework/llvm/lib/IR/Value.cpp:79: virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
I guess that using variable c(defined in __global_main_entry__) in procedure check2 adds a ref in llvm::Value, when destructing __global_main_entry__ the ref at check2 is causing the error.
I do not know how to solve the problem, and if you have time to be specific, please~
(Moreover, except for the official documentation of llvm. Are there any more resources on LLVM? I found that most tutorials are outdated.)
My full list of code is here: https://github.com/adamcavendish/PL0Compiler
Thanks in advance.
Your IR is malformed - you cannot refer to an instruction from the body of a function different from the one in which the instruction appears, so referring to %c in #check2 is illegal. The failure just happened to occur during module destruction, but it can occur in other circumstances as well.
In general, I recommend running opt -verify on your IR if you're not sure it's legal, it will give you nice error messages. My Eclipse plugin might also help if you want to experiment with IR to see when it is and isn't legal.
As for a solution, it looks like you should create a global variable to represent c, not an instruction. Then you can store into it and load from it in every function in the module.

How do you create a debug only function that takes a variable argument list? Like printf()

I'd like to make a debug logging function with the same parameters as printf. But one that can be removed by the pre-processor during optimized builds.
For example:
Debug_Print("Warning: value %d > 3!\n", value);
I've looked at variadic macros but those aren't available on all platforms. gcc supports them, msvc does not.
I still do it the old way, by defining a macro (XTRACE, below) which correlates to either a no-op or a function call with a variable argument list. Internally, call vsnprintf so you can keep the printf syntax:
#include <stdio.h>
void XTrace0(LPCTSTR lpszText)
{
::OutputDebugString(lpszText);
}
void XTrace(LPCTSTR lpszFormat, ...)
{
va_list args;
va_start(args, lpszFormat);
int nBuf;
TCHAR szBuffer[512]; // get rid of this hard-coded buffer
nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
::OutputDebugString(szBuffer);
va_end(args);
}
Then a typical #ifdef switch:
#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
Well that can be cleaned up quite a bit but it's the basic idea.
This is how I do debug print outs in C++. Define 'dout' (debug out) like this:
#ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif
In the code I use 'dout' just like 'cout'.
dout << "in foobar with x= " << x << " and y= " << y << '\n';
If the preprocessor replaces 'dout' with '0 && cout' note that << has higher precedence than && and short-circuit evaluation of && makes the whole line evaluate to 0. Since the 0 is not used the compiler generates no code at all for that line.
Here's something that I do in C/C++. First off, you write a function that uses the varargs stuff (see the link in Stu's posting). Then do something like this:
int debug_printf( const char *fmt, ... );
#if defined( DEBUG )
#define DEBUG_PRINTF(x) debug_printf x
#else
#define DEBUG_PRINTF(x)
#endif
DEBUG_PRINTF(( "Format string that takes %s %s\n", "any number", "of args" ));
All you have to remember is to use double-parens when calling the debug function, and the whole line will get removed in non-DEBUG code.
Ah, vsprintf() was the thing I was missing. I can use this to pass the variable argument list directly to printf():
#include <stdarg.h>
#include <stdio.h>
void DBG_PrintImpl(char * format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
printf("%s", buffer);
va_end(args);
}
Then wrap the whole thing in a macro.
Another fun way to stub out variadic functions is:
#define function sizeof
#CodingTheWheel:
There is one slight problem with your approach. Consider a call such as
XTRACE("x=%d", x);
This works fine in the debug build, but in the release build it will expand to:
("x=%d", x);
Which is perfectly legitimate C and will compile and usually run without side-effects but generates unnecessary code. The approach I usually use to eliminate that problem is:
Make the XTrace function return an int (just return 0, the return value doesn't matter)
Change the #define in the #else clause to:
0 && XTrace
Now the release version will expand to:
0 && XTrace("x=%d", x);
and any decent optimizer will throw away the whole thing since short-circuit evaluation would have prevented anything after the && from ever being executed.
Of course, just as I wrote that last sentence, I realized that perhaps the original form might be optimized away too and in the case of side effects, such as function calls passed as parameters to XTrace, it might be a better solution since it will make sure that debug and release versions will behave the same.
In C++ you can use the streaming operator to simplify things:
#if defined _DEBUG
class Trace
{
public:
static Trace &GetTrace () { static Trace trace; return trace; }
Trace &operator << (int value) { /* output int */ return *this; }
Trace &operator << (short value) { /* output short */ return *this; }
Trace &operator << (Trace &(*function)(Trace &trace)) { return function (*this); }
static Trace &Endl (Trace &trace) { /* write newline and flush output */ return trace; }
// and so on
};
#define TRACE(message) Trace::GetTrace () << message << Trace::Endl
#else
#define TRACE(message)
#endif
and use it like:
void Function (int param1, short param2)
{
TRACE ("param1 = " << param1 << ", param2 = " << param2);
}
You can then implement customised trace output for classes in much the same way you would do it for outputting to std::cout.
What platforms are they not available on? stdarg is part of the standard library:
http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html
Any platform not providing it is not a standard C implementation (or very, very old). For those, you will have to use varargs:
http://opengroup.org/onlinepubs/007908775/xsh/varargs.h.html
Part of the problem with this kind of functionality is that often it requires
variadic macros. These were standardized fairly recently(C99), and lots of
old C compilers do not support the standard, or have their own special work
around.
Below is a debug header I wrote that has several cool features:
Supports C99 and C89 syntax for debug macros
Enable/Disable output based on function argument
Output to file descriptor(file io)
Note: For some reason I had some slight code formatting problems.
#ifndef _DEBUG_H_
#define _DEBUG_H_
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "stdarg.h"
#include "stdio.h"
#define ENABLE 1
#define DISABLE 0
extern FILE* debug_fd;
int debug_file_init(char *file);
int debug_file_close(void);
#if HAVE_C99
#define PRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stdout, format, ##__VA_ARGS__); \
} \
}
#else
void PRINT(int enable, char *fmt, ...);
#endif
#if _DEBUG
#if HAVE_C99
#define DEBUG(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
}
#define DEBUGPRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, format, ##__VA_ARGS__); \
} \
}
#else /* HAVE_C99 */
void DEBUG(int enable, char *fmt, ...);
void DEBUGPRINT(int enable, char *fmt, ...);
#endif /* HAVE_C99 */
#else /* _DEBUG */
#define DEBUG(x, format, ...)
#define DEBUGPRINT(x, format, ...)
#endif /* _DEBUG */
#endif /* _DEBUG_H_ */
Have a look at this thread:
How to make a variadic macro (variable number of arguments)
It should answer your question.
This is what I use:
inline void DPRINTF(int level, char *format, ...)
{
# ifdef _DEBUG_LOG
va_list args;
va_start(args, format);
if(debugPrint & level) {
vfprintf(stdout, format, args);
}
va_end(args);
# endif /* _DEBUG_LOG */
}
which costs absolutely nothing at run-time when the _DEBUG_LOG flag is turned off.
This is a TCHAR version of user's answer, so it will work as ASCII (normal), or Unicode mode (more or less).
#define DEBUG_OUT( fmt, ...) DEBUG_OUT_TCHAR( \
TEXT(##fmt), ##__VA_ARGS__ )
#define DEBUG_OUT_TCHAR( fmt, ...) \
Trace( TEXT("[DEBUG]") #fmt, \
##__VA_ARGS__ )
void Trace(LPCTSTR format, ...)
{
LPTSTR OutputBuf;
OutputBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, \
(size_t)(4096 * sizeof(TCHAR)));
va_list args;
va_start(args, format);
int nBuf;
_vstprintf_s(OutputBuf, 4095, format, args);
::OutputDebugString(OutputBuf);
va_end(args);
LocalFree(OutputBuf); // tyvm #sam shaw
}
I say, "more or less", because it won't automatically convert ASCII string arguments to WCHAR, but it should get you out of most Unicode scrapes without having to worry about wrapping the format string in TEXT() or preceding it with L.
Largely derived from MSDN: Retrieving the Last-Error Code
Not exactly what's asked in the question . But this code will be helpful for debugging purposes , it will print each variable's value along with it's name . This is completely type independent and supports variable number of arguments.
And can even display values of STL's nicely , given that you overload output operator for them
#define show(args...) describe(#args,args);
template<typename T>
void describe(string var_name,T value)
{
clog<<var_name<<" = "<<value<<" ";
}
template<typename T,typename... Args>
void describe(string var_names,T value,Args... args)
{
string::size_type pos = var_names.find(',');
string name = var_names.substr(0,pos);
var_names = var_names.substr(pos+1);
clog<<name<<" = "<<value<<" | ";
describe(var_names,args...);
}
Sample Use :
int main()
{
string a;
int b;
double c;
a="string here";
b = 7;
c= 3.14;
show(a,b,c);
}
Output :
a = string here | b = 7 | c = 3.14
Having come across the problem today, my solution is the following macro:
static TCHAR __DEBUG_BUF[1024];
#define DLog(fmt, ...) swprintf(__DEBUG_BUF, fmt, ##__VA_ARGS__); OutputDebugString(__DEBUG_BUF);
You can then call the function like this:
int value = 42;
DLog(L"The answer is: %d\n", value);