I want to apply clang optimizations to a source file then generate its AST.
I tried passing -O3 flag but it seems that it is ignored.
For example I assume that for this snipped of program:
#include <stdio.h>
int main(void) {
int a = 5 + 5;
for (int i = 0; i < 10; i++) { }
printf("%i\n", a);
return 0;
}
Many optimizations can be applied, like removing the for loop converting 5 + 5 to 10.
When I dump the AST using clang -O3 -Xclang -ast-dump -fsyntax-only a.c I get the same AST without the optimization flag.
My goal is create a TranslationUnit with flag optimizations passed.
Maybe optimizations don't result into another AST? See if what you are looking for are IR dumps after each llvm optimization.
Related
I need to create an OpenCL application that instruments the code of the OpenCL kernel that it receives as input, for some exotic profiling purposes (haven't found what I need, so I need/want to do it myself).
I want to compile the kernel to an intermediate representation (LLVM-IR right now), instrument it (using the LLVM C++ bindings), transpile the instrumented code to SPIR-V and then create a kernel in the hostcode with clCreateProgramWithIL().
For now, I am just compiling a simple OpenCL kernel that adds 2 vectors, without instrumentation:
__kernel void vadd(
__global float* a,
__global float* b,
__global float* c,
const unsigned int count)
{
int i = get_global_id(0);
if(i < count) c[i] = a[i] + b[i];
}
For compiling the above to LLVM IR, I use the following command:
clang -c -emit-llvm -include libclc/generic/include/clc/clc.h -I libclc/generic/include/ vadd.cl -o vadd.bc -emit-llvm -O0 -x cl
Afterwards, I transpile vadd.bc to vadd.spv with the llvm-spirv tool (here).
Finally, I try building a kernel from the C hostcode like this:
...
cl_program program = clCreateProgramWithIL(context, binary_data->data, binary_data->size, &err);
err = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
...
After running the hostcode, I receive the above error from the clBuildProgram command:
CL_BUILD_PROGRAM_FAILURE
error: undefined reference to `get_global_id()'
error: backend compiler failed build.
It seems that the vadd.spv file is not link with the OpenCL kernel library. Any idea how to achieve this?
I wonder if it's possible to get the minimum/maximum number in Lua.
For example, in C++ we have the following
std::numeric_limits<int>::min();
std::numeric_limits<int>::max();
Is there something similar in Lua?
There is math.min and math.max that each take a list of values and return the minimum and the maximum value.
(I realized I might have misunderstood the question, as it's about integer limits, rather than comparison). There is math.mininteger and math.maxinteger that return "an integer with the minimum/maximum value for an integer".
As the other answer explains, this functionality is not available out-of-the-box in standard Lua. However, it is very easy to implement this functionality with your own Lua-C module.
test.cpp
#include <limits>
#include <lua.hpp>
static const luaL_Reg limits_lib[] = {
{nullptr, nullptr} // sentinel
};
LUAMOD_API int luaopen_limits(lua_State *L) {
luaL_newlib(L, limits_lib);
lua_pushnumber(L, std::numeric_limits<lua_Number>::max());
lua_setfield(L, -2, "maxnumber");
lua_pushnumber(L, std::numeric_limits<lua_Number>::min());
lua_setfield(L, -2, "minnumber");
return 1;
}
test.lua
local limits = require("limits")
print(limits.maxnumber)
print(limits.minnumber)
Example invocation:
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2 -shared -fPIC test.cpp -o limits.so -llua5.2
$ lua5.2 test.lua
1.7976931348623e+308
2.2250738585072e-308
Before Lua 5.3 all numbers were double by default and so can represent integers up to 2^52.
I want to slice the unused variables which are shown down with frama-c. But I have no idea which command line should I write to slice all unused variables with one command line
Last login: Thu Nov 9 20:48:42 on ttys000
Recep-MacBook-Pro:~ recepinanir$ cd desktop
Recep-MacBook-Pro:desktop recepinanir$ cat hw.c
#include <stdio.h>
int main()
{
int x= 10;
int y= 24;
int z;
printf("Hello World\n");
return 0;
}
Recep-MacBook-Pro:desktop recepinanir$ clang hw.c
Recep-MacBook-Pro:desktop recepinanir$ ./a.out
Hello World
Recep-MacBook-Pro:desktop recepinanir$ clang -Wall hw.c -o result
hw.c:5:9: warning: unused variable 'x' [-Wunused-variable]
int x= 10;
^
hw.c:6:9: warning: unused variable 'y' [-Wunused-variable]
int y= 24;
^
hw.c:7:9: warning: unused variable 'z' [-Wunused-variable]
int z;
^
3 warnings generated.
Recep-MacBook-Pro:desktop recepinanir$
As mentioned on https://frama-c.com/slicing.html, slicing is always relative some criterion, and the goal is to produce a program that is smaller to the original one, while presenting the same behavior with respect to the criterion. The Slicing plug-in itself gives several ways to build such criteria, but it seems that you are interested in the result of the Sparecode plugin (https://frama-c.com/sparecode.html): this is a specialized version of slicing, where the criterion is the program state at the end of the entry point of your analysis (i.e. main in your case). In other words, Sparecode will remove everything that does not contribute to the final result of the code under analysis. In your case, frama-c -sparecode-analysis hw.c gives the following result (note that the call to printf has been modified by the Variadic plug-in, and that its argument is not considered as useful for the final state of main. If this is an issue, you'd need to provide more specialized output functions, with an ACSL specification indicating that they have an impact to some global variable)
/* Generated by Frama-C */
#include "stdio.h"
/*# assigns \result, __fc_stdout->__fc_FILE_data;
assigns \result
\from (indirect: __fc_stdout->__fc_FILE_id),
__fc_stdout->__fc_FILE_data;
assigns __fc_stdout->__fc_FILE_data
\from (indirect: __fc_stdout->__fc_FILE_id),
__fc_stdout->__fc_FILE_data;
*/
int printf_va_1(void);
int main(void)
{
int __retres;
printf_va_1();
__retres = 0;
return __retres;
}
Finally, note that in the general case, Slicing (hence Sparecode) gives an overapproximation: it will only remove statements for which it is certain that they have no impact on the criterion.
I am writing a pre-processor for Free-Pascal (Course Work) using m4. I was reading the thread at stackoverflow here and from there reached a blog which essentially shows the basic usage of m4 for pre-processing for C. The blogger uses a testing C file test.c.m4 like this:
#include
define(`DEF', `3')
int main(int argc, char *argv[]) {
printf("%d\n", DEF);
return 0;
}
and generates processed C file like this using m4, which is fine.
$ m4 test.c.m4 > test.c
$ cat test.c
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("%dn", 3);
return 0;
}
My doubts are:
1. The programmer will write the code where the line
define(`DEF', `3')
would be
#define DEF 3
then who converts this line to the above line? We can use tool like sed or awk to do the same but then what is the use of m4. The thing that m4 does can be implemented using sed also.
It would be very helpful if someone can tell me how to convert the programmer's code into a file that can be used by m4.
2. I had another issue using m4. The comment in languages like C are removed before pre-processing so can this be done using m4? For this I was looking for commands in m4 by which I can replace the comments using regex and I found regexp(), but it requires the string to be replaced as argument which is not available in this case. So how to achieve this?
Sorry if this is a naive question. I read the documentation of m4 but could not find a solution.
m4 is the tool that will convert DEF to 3 in this case. It is true that sed or awk could serve the same purpose for this simple case but m4 is a much more powerful tool because it a) allows macros to be parameterized, b) includes conditionals, c) allows macros to be redefined through the input file, and much more. For example, one could write (in the file for.pas.m4, inspired by ratfor):
define(`LOOP',`for $1 := 1 to $2 do
begin')dnl
define(`ENDLOOP',`end')dnl
LOOP(i,10)
WriteLn(i);
ENDLOOP;
... which produces the following output ready for the Pascal compiler when processed by m4 for.pas.m4:
for i := 1 to 10 do
begin
WriteLn(i);
end;
Removing general Pascal comments using m4 would not be possible but creating a macro to include a comment that will be deleted by `m4' in processing is straightforward:
define(`NOTE',`dnl')dnl
NOTE(`This is a comment')
x := 3;
... produces:
x := 3;
Frequently-used macros that are to be expanded by m4 can be put in a common file that can be included at the start of any Pascal file that uses them, making it unnecessary to define all the required macros in every Pascal file. See include (file) in the m4 manual.
Hello I have to parse some LLVM IR code for a compiler course. I am very new to LLVM.
I have clang and LLVM on my computer, and when I compile a simple C program:
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < 10; i++) {
printf("Stuff!\n");
}
return 0;
}
using command: clang -cc1 test.c -emit-llvm
I get llvm IR with what I believe are called implicit blocks:
; <label>:4 ; preds = %9, %0
However my parser also needs to handle llvm IR with textual labels:
for.cond: ; preds = %for.inc, %entry
My problem is that I do not know how to generate such IR and was hoping someone show me how.
I tried Google and such, but I couldn't find appropriate information. Thanks in advance.
The accepted answer is no longer valid. Nor is it a good way to achieve the stated.
In case someone stumbles upon this question, like I did, I'm providing the answer.
clang-8 -S -fno-discard-value-names -emit-llvm test.c
use this site with Show detailed bytecode analysis checked
http://ellcc.org/demo/index.cgi