LLVM converting a Constant to a Value - opencl

I am using custom LLVM pass where if I encounter a store to
where the compiler converts the value to a Constant; e.g. there is an explicit store:
X[gidx] = 10;
Then LLVM will generate this error:
aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
The inheritance order goes as: Value<-User<-Constant, so this shouldn't be an issue, but it is. Using an a cast on the ConstantInt or ConstantFP has no effect on this error.
So I've tried this bloated solution:
Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
Instruction *allocInst = builder.CreateAlloca(old_value->getType());
builder.CreateStore(old_value, allocInst);
new_value = builder.CreateLoad(allocResultInst);
}
However this solution creates its own register errors when different type are involved, so I'd like to avoid it.
Does anyone know how to convert a Constant to a Value? It must be a simple issue that I'm not seeing. I'm developing on Ubuntu 12.04, LLVM 3, AMD gpu, OpenCL kernels.
Thanks ahead of time.
EDIT:
The original code that produces the first error listed is simply:
builder.CreateStore(old_value, store_addr);
EDIT2:
This old_value is declared as
Value *old_value = current_instruction->getOperand(0);
So I'm grabbing the value to be stored, in this case "10" from the first code line.

You didn't provide the code that caused this first assertion, but its wording is pretty clear: you are trying to create a store where the value operand and the pointer operand do not agree on their types. It would be useful for the question if you'd provide the code that generated that error.
Your second, so-called "bloated" solution, is the correct way to store old_value into the stack and then load it again. You write:
However this solution creates its own register errors when different type are involved
These "register errors" are the real issue you should be addressing.
In any case, the whole premise of "converting a constant to a value" is flawed - as you have correctly observed, all constants are values. There's no point storing a value into the stack with the sole purpose of loading it again, and indeed the standard LLVM pass "mem2reg" will completely remove such a sequence, replacing all uses of the load with the original value.

Related

Performing dead code elimination / slicing from original source code in Frama-C

EDIT: The original question had unnecessary details
I have a source file which I do value analysis in Frama-C, some of the code is highlighted as dead code in the normalized window, no the original source code.
Can I obtain a slice of the original code that removes the dead code?
Short answer: there's nothing in the current Frama-C version that will let you do that directly. Moreover, if your original code contains macros, Frama-C will not even see the real original code, as it relies on an external preprocessor (e.g. cpp) to do macro expansion.
Longer answer: Each statement in the normalized (aka CIL) Abstract Syntax Tree (AST, the internal representation of C code within Frama-C) contains information about the location (start point and end point) of the original statement where it stems from, and this information is also available in the original AST (aka Cabs). It might thus be possible for someone with a good knowledge of Frama-C's inner workings (e.g. a reader of the developer's manual), to build a correspondance between both, and to use that to detect dead statement in Cabs. Going even further, one could bypass Cabs, and identify zones in the original text of the program which are dead code. Note however that it would be a tedious and quite error prone (notably because a single original statement can be expanded in several normalized ones) task.
Given your clarifications, I stand by #Virgile's answer; but for people interested in performing some simplistic dead code elimination within Frama-C, the script below, gifted by a colleague who has no SO account, could be helpful.
(* remove_dead_code.ml *)
let main () =
!Db.Value.compute ();
Slicing.Api.Project.reset_slicing ();
let selection = ref Slicing.Api.Select.empty_selects in
let o = object (self)
inherit Visitor.frama_c_inplace
method !vstmt_aux stmt =
if Db.Value.is_reachable_stmt stmt then
selection :=
Slicing.Api.Select.select_stmt ~spare:true
!selection
stmt
(Extlib.the self#current_kf);
Cil.DoChildren
end in
Visitor.visitFramacFileSameGlobals o (Ast.get ());
Slicing.Api.Request.add_persistent_selection !selection;
Slicing.Api.Request.apply_all_internal ();
Slicing.Api.Slice.remove_uncalled ();
ignore (Slicing.Api.Project.extract "no-dead")
let () = Db.Main.extend main
Usage:
frama-c -load-script remove_dead_code.ml file.c -then-last -print -ocode output.c
Note that this script does not work in all cases and could have further improvements (e.g. to handle initializers), but for some quick-and-dirty hacking, it can still be helpful.

DelimitedFiles.readdlm(source, ....) modifies source, is that really intended and where in the documentation/definition is this explained?

surprised to find that DelimitedFiles.readdlm(source, ...) changes the source input parameter. surprised because Ι could find no indication hereof in the official documentation https://docs.julialang.org/en/v1/stdlib/DelimitedFiles/index.html. is this just a standard assumption about mutability in julia? i thought that somefunction that might change an input parameter would indicate this with somefunction! (adding ! to the function name)?
Ι used the function as follows:
out = DelimitedFiles.readdlm(source,',',header=true)
before the call, source has type Array{UInt8,1} and has several elements. after the call, out has type Tuple{Array{Any,2},Array{AbstractString,2}}, source has type Array{UInt8,1} (unchanged) and source is empty (changed).
The reason is that String(vec::Vector{UInt8}) does not perform a copy but takes ownership of vec (and mutates it).
For now you should write:
out = DelimitedFiles.readdlm(copy(source),',',header=true)
I have asked a question here to clarify what is the intended target behavior (copying or non-copying).

Game Maker code error

Now I'm making an endless runner where objects are spawned in front on me randomly.
I was told to make a spawnController and globalController object, so I did. Then this code should be put in the controller under step event
if(tick = 32)
{
tick = 0;
instance_create(room_width,room_height,random(spike,groundBlock));
instance_create(room_width,irandom_range(0,room_height-32));
}
tick += 1;
Is there anything wrong with it because i get an error, which is:
In object spawnController, event Step, action 1 at line 4: Wrong number of arguments to function or script.
instance_create(room_width,irandom_range(0,room_height-32));
The error messages in GM can sometimes be a bit unclear.. But in this case it was pretty clear. It goes about this line. And one of the scripts has too few arguments. Either irandom_range or instance_create you forgot an argument.
irandom_range takes two arguments to make a random number, so that is correct.
instance_create however takes 3 arguments: x,y position and the object from which you wish to create an instance. You're simply missing that argument (and the error tells you that). I think that is a typo as you do it correctly in the creation above.
Manual about instance_create
You have a syntax error here:
instance_create(room_width,irandom_range(0,room_height-32);
There's no closing parentheses or a 3rd argument.
One thing that stood out to me is that you used random instead of choose. Im not sure there is a difference in this situation, but choose allows you to list as many arguments you want.
But the other thing as was pointed out, was that your missing the object you want the 4th life to create. You need to specify what object you want it to make.
instance_create(room_width, irandom_range(0,room_height-32), OBJECT);

how to remove warnings regarding use of scanf in Qt?

I used scanf() in my program,when I compile it I'm getting a lot of warnings regarding use of scanf as follows:
D:\myspace\projects\nnf\NNFAdaptor\NNFAdaptor\main.cpp
C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
I also tried using _CRT_SECURE_NO_WARNINGS but it is not present in my Qt (headers),it is shown as error.
Put #define _CRT_SECURE_NO_WARNINGS at the top of your main.cpp (before any #includes).
That class of warnings is mostly wrong (particularly about what to use instead) but it really is true that you should not use scanf, because:
It is very easy to write a format specification that is dangerous in the same way that gets is dangerous, i.e. it will write past the end of a buffer without noticing. It is possible to write format specifications that don't have this problem but it is much harder.
It is almost impossible to write a scanf-based input parser that can handle ill-formed input reliably.
Overflow in any numeric conversion is technically undefined behavior, which means the C library is allowed to crash your program just because someone typed too many digits. (Good C libraries will not do anything worse than produce garbage in your result variable, but that can itself be a headache.)
You should not use scanf_s instead; it attempts to paper over problem 1 but doesn't entirely succeed, and it doesn't address problems 2 and 3 at all. Since you are using Qt, I recommend:
Read entire lines into std::strings using std::getline.
Parse them with QRegExp.
Convert numeric strings to numbers with e.g. QString::toDouble.
If your input syntax is more complicated than regexes can handle, investigate QLALR.

Matlab: Attempt to reference field of non-structure array

I am using the Kernel Density Estimator toolbox form http://www.ics.uci.edu/~ihler/code/kde.html . But I am getting the following error when I try to execute the demo files -
>> demo_kde_3
KDE Example #3 : Product sampling methods (single, anecdotal run)
Attempt to reference field of non-structure array.
Error in double (line 10)
if (npd.N > 0) d = 1; % return 1 if the density exists
Error in repmat (line 49)
nelems = prod(double(siz));
Error in kde (line 39)
if (size(ks,1) == 1) ks = repmat(ks,[size(points,1),1]); end;
Error in demo_kde_3 (line 8)
p = kde([.1,.45,.55,.8],.05); % create a mixture of 4 gaussians for
testing
Can anyone suggest what might be wrong? I am new to Matlab and having a hard time to figure out the problem.
Thank You,
Try changing your current directory away from the #kde folder; you may have to add the #kde folder to your path when you do this. For example run:
cd('c:\');
addpath('full\path\to\the\folder\#kde');
You may also need to add
addpath('full\path\to\the\folder\#kde\examples');
Then see if it works.
It looks like function repmat (a mathworks function) is picking up the #kde class's version of the double function, causing an error. Usually, only objects of the class #kde can invoke that functions which are in the #kde folder.
I rarely use the #folder form of class definitions, so I'm not completely sure of the semantics; I'm curious if this has any effect on the error.
In general, I would not recommend using the #folder class format for any development that you do. The mathworks overhauled their OO paradigm a few versions ago to a much more familiar (and useful) format. Use help classdef to see more. This #kde code seems to predate this upgrade.
MATLAB gives you the code line where the error occurs. As double and repmat belong to MATLAB, the bug probably is in kde.m line 39. Open that file in MATLAB debugger, set a breakpoint on that line (so the execution stops immediately before the execution of that specific line), and then when the code is stopped there, check the situation. Try the entire code line in console (copy-paste or type it, do not single-step, as causing an uncatched error while single-stepping ends the execution of code in debugger), it should give you an error (but doesn't stop execution). Then try pieces of the code of that code line, what works as it should and what not, eg. does the result of size(points, 1) make any sense.
However, debugging unfamiliar code is not an easy task, especially if you're a beginner in MATLAB. But if you learn and understand the essential datatypes of MATLAB (arrays, cell arrays and structs) and the different ways they can be addressed, and apply that knowledge to the situation on the line 39 of kde.m, hopefully you can fix the bug.
Repmat calls double and expects the built-in double to be called.
However I would guess that this is not part of that code:
if (npd.N > 0) d = 1; % return 1 if the density exists
So if all is correct this means that the buil-tin function double has been overloaded, and that this is the reason why the code crashes.
EDIT:
I see that #Pursuit has already addressed the issue but I will leave my answer in place as it describes the method of detection a bit more.

Resources