Linking multiple IR files for code analysis

Hello all,

Following are the code samples being used to extract the LLVM IR files.

scan.h :-

namespace scan_range {
class Example {
public:
explicit Example(int data);
int x;
int y;
void addData(int a, int b);
};
}

main.cpp :-

int main() {
int value = 41;
cout << "Main func " << value << “\n”;
std::make_shared<scan_range::Example>(value);
return 0;
}

call.cpp

namespace scan_range {
void addData(int x, int y) { cout << x + y << “\n”; }

void initData(int value) {
int a = 1;
int b = 2;
cout << "Received value " << value << “\n”;
addData(1, 2);
}

Example::Example(int data) {
cout << “Const called\n”;
initData(data);
}
}

Now that I have the IR of the above 2 CPP files, I am making use of llvm-link along with the flags disable-lazy-loading and internalize, to combine it into a single IR file.

Once the final IR is generated, I am making use of the CallGraph pass to see if there is path between 2 functions (Example :- Between main and initData in the above, it should be True).

I observe that after linking, the call from the IR of main.cpp

call void @_ZN10scan_range7ExampleC1Ei (demangled_name :- scan_range::Example::Example(int))

to the constructor of call.cpp

define dso_local void @_ZN10scan_range7ExampleC2Ei (demangled_name :- scan_range::Example::Example(int))

is being captured by the following

@_ZN10scan_range7ExampleC1Ei = dso_local unnamed_addr alias void (ptr, i32), ptr @_ZN10scan_range7ExampleC2Ei

I want to resolve the call instruction from main.cpp to the constructor function in call.cpp automatically. Is there any pass which can help my case?

Thank you.

If I’m understanding your question correctly, then I will point out that
the GlobalOpt pass in LLVM will replace uses of a GlobalAlias with the
aliasee if both the alias and the aliasee are not preemptible.

For example, see Compiler Explorer

Hey, I tried it (It works for few example usecases). But the issue with it is, it’s now completely removing main function (As main is just calling the constructor in this case), which shouldn’t be the case. Is there a way to circumvent it?