I wrote an inline function and implemented each basic block call to the inline function in LLVM's pass. However, the compilation error is as follows:
inline function call in a function with debug info must have a !dbg location
I wonder why? Am I missing a step or a parameter?
[+] the call instruction like this:
std::vector<Type*> Vct;
Vct.push_back(Int32Ty);
Vct.push_back(Int32Ty);
ArrayRef<Type*> Args(Vct);
FunctionType *Ty = FunctionType::get(Type::getVoidTy(*Ctx), Args,false);
FunctionCallee callee_ = M.getOrInsertFunction("HH",Ty);
Value *Args_[] = {IRB.getInt32(a),IRB.getInt32(b)};
const Twine Name = "";
IRB.CreateCall(callee_,Args_,Name);
Related
I tried to insert an assembly instruction into each base block using pass in the IR Pass of LLVM.
Update:
LLVMContext *Ctx = nullptr;
Ctx = &M.getContext();
BasicBlock::iterator IP = BB.getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
StringRef asmString = "int3";
StringRef constraints = "~{dirflag},~{fpsr},~{flags}";
llvm::InlineAsm *IA = llvm::InlineAsm::get(Ty,asmString,constraints,true,false,InlineAsm::AD_ATT);
ArrayRef<Value *> Args = None;
llvm::CallInst *Ptr = IRB.CreateCall(IA,Args);
Ptr->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
However, when I ran the pass on one of the test files, test.bc, I found that no INT3 instructions were inserted into the file.I compared the statement I created with Ptr:
call void asm sideeffect "int3", "~{dirflag},~{fpsr},~{flags}"() #4
And the real INT3 in IR is:
call void asm sideeffect "int3", "~{dirflag},~{fpsr},~{flags}"() #2, !srcloc !2
I wonder how can I modify my code to make it work?
The type of the inline assembly certainly don't have to match with the type of function it is used in.
For a int3 inline assembly you probably want a void (void) type, that is FunctionType::get(Type::getVoidTy(ctx), false).
I have a C++ header declared like:
struct Inner {
// ...
};
struct MyStruct {
Inner* _inner;
size_t _x;
size_t _y;
};
extern "C" {
MyStruct my_fn(MyStruct* s, bool flag_1, bool flag_2);
};
...which I'm compiling with clang into a shared library, whose functions I'm trying to invoke from LLVM code:
%"Inner" = type {i64, i64}
%"MyStruct" = type {%"Inner"*, i64, i64}
declare %"MyStruct" #"my_fn"(%"MyStruct"* %".1", i1 %".2", i1 %".3")
define void #"main"()
{
entry:
%".stack_buf_ptr" = alloca %"MyStruct"
; ... assign elements of %.stack_buf_ptr ...
%".15" = call %"MyStruct" #"my_fn"(%"MyStruct"* %".stack_buf_ptr", i1 true, i1 true)
}
The program crashes inside my_fn. However, what's peculiar is that the passed arguments have nonsense values, which I can see when I print them from my_fn, or if I inspect them in a debugger. Specifically, the first argument has the nonsense pointer value "0x7".
From reading the LLVM IR, I don't know how this is possible— the pointer is provided directly by LLVM's own alloca instruction. I get similar behavior if I try to pass the address of a global variable. More bizarrely, some of my other called functions with similar (but not identical) signatures work just fine.
The only explanation I can think of is a disagreement in calling convention, but it doesn't appear to be wrong in either case— the function is declared inside extern "C" { ... }, and when I use nm on the compiled shared library I can see that my_fn obeys the cdecl naming convention (it's listed as _my_fn). I also read from the documentation that LLVM function declarations default to cdecl.
I don't really know what to look at next. Could there be some reason why my types/signatures aren't matching in binary layout? Are there compiler settings for the shared library I should check that could fix/break things? What could be going on?
Why would the above LLVM code pass nonsense values to my_fn()?
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 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?
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).