I have an LLVM pass that traverses input IR code and performs analysis on called functions. My analysis function signature is functionTracer(const Function* pFunc) and I call it on a CallInst's getCalledFunction().
At the start of my analysis function I create a copy of the passed in function that I manipulate during the analysis:
Function* pFunctionToAnalyze = CloneFunction(pFunction,VMap,false);
I have a C++ main that calls a function f2(int i):
int main(){
int a = 3;
int b = f2(a);
int c = f2(b);
}
I turn this code into IR and submit to my pass. My code appears to execute and perform the manipulations I want but I get the following error output:
While deleting: i32 (i32)* %_Z2f2i
Use still stuck around after Def is destroyed: %call1 = call i32 #_Z2f2i(i32 %1)
Use still stuck around after Def is destroyed: %call = call i32 #_Z2f2i(i32 %0)
module: /home/src/extern/llvm/llvm-3.7.0.src/lib/IR/Value.cpp:82:
virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
Aborted (core dumped)
Do I need to perform manual clean up of the Cloned function, pFunctionToAnalyze, at the end of my analysis function to remove Uses before returning? Is there a better way to copy function contents for analysis that may modify it?
There's an example on that in lib/Transforms/IPO/PartialInlining.cpp
// Clone the function, so that we can hack away on it.
ValueToValueMapTy VMap;
Function* duplicateFunction = CloneFunction(F, VMap,
/*ModuleLevelChanges=*/false);
And in the end of the pass:
duplicateFunction->replaceAllUsesWith(F);
duplicateFunction->eraseFromParent();
Isn't that what fixes your problem?
Related
From the following example call:
call void %4(%class.EtherAppReq* %2, i64 %5)
I want to extract the temporary %4 to pass it as an argument of another function. To do this, I need it as Value class object. How could I do it?
Value *target = call->getCalledValue();
Value *args[] = {point, target};
Builder.CreateCall(func, args);
It caused a segmentation fault because of target.
CallInst::getCalledValue() to get a pointer to %4.
What I did is attempt to getCalledFunctionFirst, if NULL then getCalledValue and stripPointerCasts, if still fails then bail out or skip this one
I'm trying to use forward declaration of functions in LLVM, but I'm not able to do it... The reason for doing that is this error:
error: invalid forward reference to function 'f' with wrong type! "
Right now I'm trying to do it with this code:
std::vector<Type *> args_type = f->get_args_type();
Module* mod = get_module();
std::string struct_name("struct.");
struct_name.append(f->get_name());
Type* StructTy = mod->getTypeByName(struct_name);
if (!StructTy) {
StructTy = Type::getVoidTy(getGlobalContext());
}
FunctionType *ftype = FunctionType::get(StructTy, args_type, false);
//Function *func = Function::Create(ftype, GlobalValue::InternalLinkage, f->get_name(), get_module());
Constant* c = mod->getOrInsertFunction(f->get_name(), ftype);
Function *func = cast<Function>(c);
But it does not show in the IR when I generate the code. When I create the function again using this same code shown above, it works. I wonder if it's because I insert a BasicBlock right after when I start insert things within the function.
Right now that's how it is my IR
define internal void #main() {
entry:
...
}
define internal %struct.f #f(i32* %x) {
entry:
...
}
I believe that putting an declare %struct.f #f(i32*) before the #main function would fix this issue, but I can't figure out how to do it...
Summary: I just want to create something with a declare on top of the file, so I can use the define it later and start inserting instructions of the function
Ok, it seems LLVM does that 'automatically'.
I just realized that the functions changed their orders when I ran the code again. So, if you create a function before even though you don't insert any code (body), it will create the prototype and wait for any further declarations to the body, as long as you reference this function with the getOrInsert() method of the Module class.
I don't know if this is the right answer or if it's clear, but it solved my problem...
I know the basics of interacting with lua and C, and I am currently trying to perform the following line of lua in c++
Func1():Func2().Table1.value1
I am trying to get the value of "value2" and use it in my C program. The following is the code I wrote to attempt to get this value in C.
int GetNumber()
{
int retn = 0;
g_clientlua.lua_getfield(LUA_REGISTRYINDEX, "Player");
g_clientlua.lua_getfield(-1, "Func2");
g_clientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1");
g_clientlua.lua_call(0, 1);
g_clientlua.lua_call(1, 1);
if (g_clientlua.lua_isnil(-1))
return retn;
g_clientlua.lua_getfield(-1, "Table1");
if (g_clientlua.lua_isnil(-1))
return retn;
g_clientlua.lua_getfield(-1, "value1");
if (g_clientlua.lua_isnil(-1))
return retn;
retn = (int)g_clientlua.lua_tointeger(-1);
}
The clientlua thing is an object that basically just allows me to call a method which calls it's lua_* function equivalent and fills the lua_state pointer parameter with a member variable that is a pointer to the lua state.
Every time I call this, it complains about me causing a lua stack leak. To solve this, I tried adding a lua_pop(3) to the end, but then it just crashes my program without reporting an error, so I assume I am doing something wrong.
Anyone have any words of wisdom for me? Kinda lost here. I doubt the above code is even written properly, how would I write the above lua call in C?
You need to call Func1 before you try to get Func2 as Func2 comes from the table that Func1 returns (and not from the global table).
Then you need to call Func2 and look up Table1 in that returned value, etc.
What "stack leak" complaint are you getting? If you are calling this function from C directly then yes, you need to be sure that anything you put on the lua stack (that isn't for consumption by the caller, etc.) is popped from the lua stack before you return.
The GetNumber function isn't doing exactly the same as the lua snippet you're going for. Specifically GetNumber is getting the value of "Func2" from the registry while your lua snippet is getting the value of "Func2" from the table returned by Func1(). Unless you're certain that registry.Player.Func2 == Func1().Func2 is always true, your C++ version will not have the same behavior.
Let's break down Func1():Func2().Table1.value1 into more explicit steps to help with the C translation:
Get function associated with _G.Func1
Call that function and get a table back
Get function associated with "Func2" from the returned table in step 2
Call that function and pass as argument the table from step 2. Get another table back as result
I found it helpful to track what the stack contains as a side-comment as the operations are performed:
int GetNumber()
{
// Func1()
gclientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1"); // Func1
g_clientlua.lua_call(0, 1); // {}
// Func2( {} )
g_clientlua.lua_getfield(-1, "Func2"); // {}, Func2
g_clientlua.lua_insert(-2); // Func2, {}
g_clientlua.lua_call(1, 1); // {}
if( g_clientlua.lua_type(-1) != LUA_TTABLE )
{
g_clientlua.lua_pop(1);
return 0;
}
// {}.Table1
g_clientlua.lua_getfield(-1, "Table1"); // {}, {}(Table1)
if( g_clientlua.lua_type(-1) != LUA_TTABLE )
{
g_clientlua.lua_pop(2);
return 0;
}
// tonumber( Table1.value1 )
g_clientlua.lua_getfield(-1, "value1"); // {}, {}(Table1), value1
int retn = g_clientlua.lua_tointeger(-1);
g_clientlua.lua_pop(3);
return retn;
}
Notice that GetNumber pops off all the arguments it places on the stack before returning. This ensures that GetNumber leaves the lua stack the way it was found. This can probably be automated with RAII if you're using C++.
I am attempting to write some compiler and use LLVM to generate intermediate code. Unfortunately, LLVM documentation is not very great and even somewhat confusing.
At the moment I have lexer,grammar and AST implemented. I was also following some examples found on Internet. My current AST works as follows: it has the abstract base class Tree*, from which other trees inherit (so, like one for variable definition, one for statement list, one for binary expression etc.).
I am trying to implement the variable definition, so for the input
class Test{
int main()
{
int x;
}
}
I want LLVM output to be:
; ModuleID = "Test"
define i32 #main() {
entry:
%x = alloca i32
return i32 0
}
However, right now I can get %x = alloca i32 part to the part where main function is created, but the actual output is missing the %x = alloca i32. So, the output I'm getting is as follows:
; ModuleID = "Test"
define i32 #main() {
entry:
return i32 0
}
my Codegen() for variable declaration is shown bellow (symbol table for now is just a list, I am trying to keep things as simple as possible at the moment):
llvm::Value *decafStmtList::Codegen() {
string name = SyandTy.back(); // Just a name of a variable
string type = SyandTy.front(); // and its type in string format
Type* typeVal = getLLVMType(decafType(str2DecafType(type))); // get LLVM::*Type representation
llvm::AllocaInst *Alloca = Builder.CreateAlloca(typeVal, 0, name.c_str());
Value *V = Alloca;
return Alloca;//Builder.CreateLoad(V, name.c_str());
}
The part where I am generating my #main is as follows:
Note: I have commented out the print_int function (this is the function I will use later to print things, but for now I don't need it). If I'll uncomment the print_int function, TheFunction will not pass verifier(TheFunction) -> complains about module being broken and parameters not matching the signature.
Function *gen_main_def(llvm::Value *RetVal, Function *print_int) {
if (RetVal == 0) {
throw runtime_error("something went horribly wrong\n");
}
// create the top-level definition for main
FunctionType *FT = FunctionType::get(IntegerType::get(getGlobalContext(), 32), false);
Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "main", TheModule);
if (TheFunction == 0) {
throw runtime_error("empty function block");
}
// Create a new basic block which contains a sequence of LLVM instructions
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// All subsequent calls to IRBuilder will place instructions in this location
Builder.SetInsertPoint(BB);
/*
Function *CalleeF = TheModule->getFunction(print_int->getName());
if (CalleeF == 0) {
throw runtime_error("could not find the function print_int\n");
}*/
// print the value of the expression and we are done
// Value *CallF = Builder.CreateCall(CalleeF, RetVal, "calltmp");
// Finish off the function.
// return 0 from main, which is EXIT_SUCCESS
Builder.CreateRet(ConstantInt::get(getGlobalContext(), APInt(32, 0)));
return TheFunction;
}
If someone knows why my Alloca object is not being generated, please help me out - any hints will be greatly appreciated.
Thank you
EDIT:
Codegen is called from the grammar:
start: program
program: extern_list decafclass
{
ProgramAST *prog = new ProgramAST((decafStmtList *)$1, (ClassAST *)$2);
if (printAST) {
cout << getString(prog) << endl;
}
Value *RetVal = prog->Codegen();
delete $1; // get rid of abstract syntax tree
delete $2; // get rid of abstract syntax tree
// we create an implicit print_int function call to print
// out the value of the expression.
Function *print_int = gen_print_int_def();
Function *TheFunction = gen_main_def(RetVal, print_int);
verifyFunction(*TheFunction);
}
EDIT: I figured it out, basically the createAlloca has to be called after the basicblock when generating main;
There are two weird things here:
All you do is call Builder.CreateRet... I don't see how there could be any code in main unless you call something that creates the corresponding instructions. In particular, you never seem to call the CodeGen part.
You pass a size of zero to CreateAlloc. I think the size should be one for a single variable.
Also, make sure that you don't call any LLVM optimization passes after generating your code. Those passes would optimize the value away (it's never used, thus dead code).
I want to replace the call to malloc with call to cumemhostalloc function.
float *h_A=(float *)malloc(size);
should be replaced with
cuMemHostAlloc((void **)&h_A,size,2);
I use the following code for this,
*if (dyn_cast<CallInst> (j))
{
Ip=cast<Instruction>(j);
CastInst* ci_hp = new BitCastInst(ptr_h_A, PointerTy_23, "" );
BB->getInstList().insert(Ip,ci_hp);
errs()<<"\n Cast instruction is inserted"<<*ci_hp;
li_size = new LoadInst(al_size, "", false);
li_size->setAlignment(4);
BB->getInstList().insert(Ip,li_size);
errs()<<"\n Load instruction is inserted"<<*li_size;
ConstantInt* const_int32_34 = ConstantInt::get(M->getContext(), APInt(32, StringRef("2"), 10));
std::vector<Value*> cumemhaparams;
cumemhaparams.push_back(ci_hp);
cumemhaparams.push_back(li_size);
cumemhaparams.push_back(const_int32_34);
CallInst* cumemha = CallInst::Create(func_cuMemHostAlloc, cumemhaparams, "");
cumemha->setCallingConv(CallingConv::C);
cumemha->setTailCall(false);
AttrListPtr cumemha_PAL;
cumemha->setAttributes(cumemha_PAL);
ReplaceInstWithInst(callinst->getParent()->getInstList(), j,cumemha);*
}
But I get the following error,
/home/project/llvmfin/llvm-3.0.src/lib/VMCore/Value.cpp:287: void llvm::Value::replaceAllUsesWith(llvm::Value*): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' failed.
Is it because the call to malloc is replaced with a function that has a different signature?
Almost. Call to malloc produce a value, your function - does not. So, you have to replace call with a load, not with another call
Also, looking into your code:
Do not play with instlists directly. Use IRBuilder + iterators instead
You can check for CallInst and declare var at the same time, no need to additional cast to Instruction.