I want to know which all llvm IR statements correspond to the code inside a particular pragma in clang. My pragma is having the following structure.
#pragma markme
{
stmt1;
stmt2;
}
I need to know which all stmts were present between the opening braces and closing braces of mark me pragma.
Can we attach some metadata to these stmts? If yes could anyone point me to some reference.
I have searched on Google and found this
Add a pragma handler, which has a callback on the actions interface.
Add a sema implementation of the callback, which sets some internal bit in the Sema object.
Add a new bit to the 'for' statement, to specify whether this it had #pragma optimize set.
Modify codegin to emit the metadata based on that bit.
Could any one give more details on this.
I am using the latest llvm (llvm 3.4)
Note: Any help in any direction is appreciated. I know llvm may do optimizations that moves the statements around. But this is fine with me
Note that this has to be done in Clang, which knows about #pragma. LLVM itself knows nothing about them - #pragma are not part of the LLVM IR.
There are plenty of examples of generating metadata in Clang's lib/CodeGen directory. It all depends on where you want this metadata to appear - on instructions? On functions?
For attaching metadata to instructions look for setMetadata. For example, in lib/CodeGen/CGExpr.cpp, some profiling metadata is attached to branches. For placing module-level metadata, see lib/CodeGen/CodeGenModule.cpp.
Related
I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j
Where can I see the actual key-value pairs set in Google style? I can't find the definition in the clang repository.
They can be found in the Format.cpp file of the clang lib.
https://github.com/llvm/llvm-project/blob/04ee232ff212b6c308e2ebc7b6125892681c54ae/clang/lib/Format/Format.cpp#L660
This is the start of the LLVM style, then the following functions after it hold the other pre-defined configuration settings. If you are looking at a different version of the code base, look for the function 'getPredefinedStyle' to find the sub-calls that are used based on the style chosen.
I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.
I have been just playing around with Clang and Open64 and used the OpenMP library. I am somehow new to these three!
I was wondering if anyone could help me on finding what will the #pragma directives expand to. What I know is that a #pragma directive in the C file will be expanded to a some lines of codes. I was hoping if someone could tell me where should I look for to find it. I know for sure that Clang and Open64 compilers have output for assembly and their different intermediate representations. But since that is not useful, I want to know the exact codes that are expanded when encountering a directive.
Let me rephrase my question.
I know that an OpenMP #pragma directive is expanded into some lines of codes (or maybe I am wrong). I was hoping if someone could tell me where should I look for it in the sources of compiler or sources of OpenMP?
Let me give you an example.
Consider this piece of code:
#pragma omp parallel
{
printf("Hello world! %d", omp_get_thread_num());
}
As far as I know, it will be converted to something like this (or something more complex):
f1();
{
printf("Hello world! %d", omp_get_thread_num());
}
f2();
I want to know what are the f1() and f2() methods.
If I am wrong tell me. And if you know where should I look for in the code, let me know about that.
Thanks.
A short replication of the answer, since #AlanWik asked for it.
OpenMP is not a source to source translator, so there is no translated source code to look at. All of the conversions occur on the compiler data structures, so you need to look at those, or at the assembler output.
I have a file which looks something like this:
#include <Shlwapi.h>
...
void SomeFunction()
{
UrlCombineW(...)
}
This compiled just fine until I installed another Delphi component in C++ Builder IDE but now reports unresolved external for UrlCombineW. The above call was fine before installing this component.
It seems that the component is overwriting this in some way so I need to explicitly tell the compiler where to look for UrlCombineW. This is a function from Shlwapi.dll.
Compiler does not complain, but how do I explicitly tell the linker where to look for this function and avoid unresolved external error?
Expanding my comment to an answer.
You need to link to Shlwapi.lib in order for the linker to find the functions. (This explanation glosses over a few things, but a .lib, a library file, can be either a static or import library. A static library contains the functions themselves - it's basically a collection of .obj files bundled together; an import library says that functions X, Y and Z are found in a specific DLL.) Either way, if you link the .lib in you will get the functions that you need.
There are a couple of ways to do tell the linker to link in the file:
Use #pragma comment(lib, "Filename.lib") in a .cpp file somewhere. For your case, this is #pragma comment(lib, "Shlwapi.lib").
Add it to the project options, which in turn adds it to the linker command line. In C++ Builder you do this by actually adding the .lib file to the project, ie drag and drop it onto the project in the Project Manager, or use File > Add To Project.
Which you prefer is up to you. I tend to link to localized things locally - so in my code, there's only one unit which uses Shlwapi.h and the fact it does so is an implementation detail hidden from the outside, it's not shown in the interface. Therefore, in that file, I link using #pragma comment at the point I include the header. On the other hand, if you have something used far more widely - to pick the widest example, kernel32.lib - I would add that the project itself. (Note this is an example, you don't actually need to explicitly link to kernel32, that will be done for you!)