Pass structure by parameter with LLVM

大兔子大兔子 提交于 2019-12-12 12:30:34

问题


Is it possible to pass structure by parameter ?

Is it compatible with the C abi ?

[edit]

Basically, I would like to have a C++ POD which would contain two members (the structure would be a fat pointer, with a pointer and an integer), and be able to pass this structure as function parameter in call instructions (even when calling C code).

I'm not using fat pointer now (the pointer and the integer are each in a different function parameter), and I would like to know if it's possible before starting a pretty big refactoring !


回答1:


Absolutely, you can. Here's an example:

struct MyStruct_t {
    char *charPointer;
    int number;
};

void myFunction(MyStruct_t myStructAsParam) {

    printf("String: %s, Number: %i", myStructAsParam.charPointer, myStructAsParam.number);
    // Your stuff here.
}



回答2:


You can do this.

You can figure out what the LLVM code is for sample C by copying and pasting the C code into LLVM's online demo at http://llvm.org/demo/index.cgi.

If you copy and paste the code at codepad.org in, you'll see that LLVM generates the following for myFunction:

define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32     %myStructAsParam.coerce1) nounwind uwtable {
  %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1)
  ret void
}

Of course, if you look at the call you'll notice that no copy is being made. It's up to the calling function to do that. If we write a small C function:

void myCallingFunction(MyStruct_t *foobar)
{
  myFunction(*foobar);
}

We can see that the LLVM bitcode generated for myCallingFunction is:

define void @_Z17myCallingFunctionP10MyStruct_t(%struct.MyStruct_t* nocapture %foobar)   nounwind uwtable {
  %foobar.0 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 0
  %tmp = load i8** %foobar.0, align 8
  %foobar.1 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 1
  %tmp1 = load i32* %foobar.1, align 8
  %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %tmp, i32 %tmp1) nounwind
  ret void
}

The calling function makes a copy of the struct, and then passes in the address of the copy.



来源:https://stackoverflow.com/questions/12755882/pass-structure-by-parameter-with-llvm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!