Inserting an llvm intrinsic in LLVM IR - llvm

I am trying to insert a custom defined intrinsic (int_x86_addenc_32) in llvm which is defined in IntrinsicsX86.td. Can someone help me with the code of calling such an intrinsic. (Intrinsic::getDeclaration(???))
On including Intrinsics.h,
I get an error saying ‘int_x86_addenc_32’ is not a member of ‘llvm::Intrinsic’.
Any help would be appreciated.
Thanks!

Related

what exactly happens when I compile instruction __atomic_add_fetch

I have a instruction in my code calling function __atomic_add_fetch. When I compile this code, I am getting compilation error as below
error: undefined reference to '__atomic_fetch_add_8'
I really could not understand why it is throwing undefined reference to __atomic_fetch_add_8 when I am calling __atomic_add_fetch. Could somebody please help me understand what exactly happening while compiling this code?
Note: I am specifically looking to understand "what is internally happening that translates __atomic_add_fetch into __atomic_fetch_add_8". Not the solution to fix compilation issue.
You should be using the standardized atomic_fetch_add.
In any case, it looks like your __atomic_fetch_add with the given argument type (presumably an 8-byte integer) cannot be resolved to an assembly instruction(s) on your platform so it is getting resolved to a function call for which you'll need to link libatomic (-latomic).
Edit with details:
On gcc, __atomic_fetch_add appears to be the compiler built in used to implement stdatomic.h's atomic_fetch_and_explicit (which is just a simple macro name for it). As I've noted, you should really be using the standard name atomic_fetch_add_explicit, not the nonportable implementation detail that __atomic_fetch_add is.
Regardless, the issue seems to be that gcc and clang don't implement atomic_fetch_and_explicit with instructions on ARM (unlike on ARM64 or x86-64) but instead they generate a call to a (global-lock-using) function from the libatomic library. The name of the function seems to be derived from the number of bytes in the integer you're trying to fetch_add to
(__atomic_fetch_add_8 if you're fetch_adding to _Atomic uin64_t
__atomic_fetch_add_4 if you're fetch_adding to _Atomic uin32_t, etc.).
https://gcc.godbolt.org/z/S67g7b

Calling conventions in LLVM IR

LLVM allows call instructions and defines to specify a calling convention. Does the IR itself already need to adhere to the specified convention? For example when using ccc, I believe that the return value would need to fit in the 64-bit eax on my OS/architecture. Am I allowed to write LLVM IR code that returns a struct of 3 i32's? Does LLVM convert that to something that adheres to the C calling convention? Could I change the calling convention without changing any other code?
When I look at the output of compiling a C file with -emit-llvm, the IR generator already applied the calling convention, and would allocate at the call site, and convert the return value as a pointer parameter. Is that absolutely necessary at this stage? What does LLVM do with the information of which calling convention to use at the next stage, -emit-obj?
There are many things mixed here, unfortunately. The calling convention is usually defined in terms of the source language. And many necessary details are already lost when converting to LLVM IR. So, in order to preserve the ABI and calling convention frontend is supposed to properly lay out arguments / return values so they will be properly codegen'ed at LLVM level.
So, making long story short: the calling convention contains both high-level (source language) and low-level requirements. The former are handled by frontend and the latter – by the backend. You can change the LLVM IR, but you need to make sure that the code generated will be indeed compatible with your C code. And on some platforms this might be complicated.

Prevent Intel compiler from over-optimizing un-used variables?

Is there a way to tell the Intel compiler to not optimize-away un-used variables? I am trying to time some code and I currently prevent the optimization by using a cout statement on the variables.
Ideally the solution would tell the compiler to not remove the variable via a pragma/hint, otherwise I would have to use a program-wise argument?
Use the volatile keyword when assigning your variable to let the compiler know not to optimize it. As far as I know, this is a C/C++ standard so it should work on any compiler. See the MSDN link for more info.

How do I get LLVM types from Clang?

I'm looking to write a tool using Clang. The details are fairly immaterial, but what I'm looking to do is get an llvm type from Clang. For example, I'd like to go from "printf" to llvm::Function*, and "size_t" to a llvm::Type*. But I can't find any functions in Clang that give out these functions. I've decided that I can ask Clang to mangle the names, and then ask the llvm::Module* for the data- but I can't find how to get an llvm::Module* that corresponds to a Clang invocation.
How can I get the internal LLVM data from Clang?
Ultimately, the code generation APIs are not part of Clang's public API. This is for good reason, because they are awful.
However, you can create a clang::CodeGen::CodeGenModule, which you can use to codegen a given TU into a provided llvm::Module. Then, you can get the mangled name of a symbol by using the getMangledName function on the CodeGenModule.
However, do not attempt to use the provided functions for converting from a clang::QualType to an llvm::Type*- they are unusably broken. The only viable strategy I have found for reliably performing this conversion is to find a function with a signature, for example, a member function, and then query the Module for the type of that parameter, for example, this. But this is pretty ABI-specific and a nasty hack. You can also compute the LLVM type name that Clang generates for a given type and search for it in the module, but this is not always successful.
In general, you cannot. clang internals are made in layers as well. So, you cannot simply grab a piece of AST and say 'Hey, give me a function'. AST is converted to LLVM IR at the IR generation step module at a time. This way we can be sure everything is parsed and semantically correct and complete.
So, if you really need all this sort of thing, then you need to hook into clang really late, after IR generation and try to operate on loosely coupled AST and LLVM IR at that time.

MSVC Compiler Error C4315 - No Documentation Found

When compiling my app today, I encountered this warning (the code, I think, is irrelevant):
warning C4315: 'MyClass' : 'this' pointer for member 'MyClass::my_data_' may not be aligned 8 as expected by the constructor
I am not able to find any documentation about this warning, in either the online help, my locally-installed help, or via a google search. I did find one link on a MS forum:
No documentation for compiler warning C4315
But no information about the error itself.
Do you have any information about this error? I'm trying to fogure out how to fix it.
I'd look for something (buried in a header?) changing the structure packing from the default.
The warning seems to be saying that whatever type MyClass::my_data_ is expects to be 8-byte aligned, but it's not being placed at that alignment inside MyClass.
Search for #pragma pack(some-number) directives that aren't reset with a #pragma pack().
Using #pragma pack(show) would probably be helpful, too.