the API of creating a switch instruct(
SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10,
MDNode *BranchWeights = nullptr,
MDNode *Unpredictable = nullptr)
) needs a default BasicBlock, but in my code, due to the design, I cannot get default BasicBlock when creating, and usually, default case is written as the last statement in a switch statement, so can I create a switch instruct and assign the default BasicBlock later?
Pass nullptr to the Create() function to get a SwitchInst object and use SwitchInst::setDefaultDest() later.
Related
I write a function to create a empty basicblock:
BasicBlock* createEmptyBlock(){
llvm::LLVMContext context;
IRBuilder<> builder(context);
Function *mainFunction;
mainFunction->setDoesNotReturn();
BasicBlock* mainblock = BasicBlock::Create(context, "entrypoint", mainFunction);
return mainblock;
}
but when insert my instruction in the front of this mainblock:
Instruction *newBInst_0 = setBranchInst(F, inst, 1);//product a inst
llvm::BasicBlock *bb;
bb=createEmptyBlock();
newBInst_0->insertBefore(bb->front());//there are some errors
bb->insertInto(&F,&block);
I found some errors when I insert
What's wrong with this?
You should try to stop creating a context and builder instance each time you call createEmptyBlock. Just one context is required per thread and in general one builder instance so llvm helps you keep track of where to insert ir. This really helps with method calls such as builder.GetInsertBlock()
Also you don't need to attach a block to a function each time you create one. You're function could now look like this
BasicBlock* createEmptyBlock(){
BasicBlock* mainblock = BasicBlock::Create(context, "entrypoint");
return mainblock;
}
supposing you'd want all your block labels to be prefixed with "entrypoint". Plus, the function body is nearly a one-liner. Why not just inline it like so
Instruction *newBInst_0 = setBranchInst(F, inst, 1);//product a inst
llvm::BasicBlock *bb = BasicBlock::Create(context, "entrypoint");
bb->insertInto(&F,&block);
newBInst_0->insertBefore(bb->front());
supposing your builder and context instances are global variables (which I recommend they should).
It also looks like you're not using your builder instance much. Try exploring some of its methods such as builder.SetInsertPoint and builder.CreateCondBr
Is there any easy and reliable way (a.k.a. not regex) to get the QualType of a function pointer declaration as a string but with a name attached to it? I tried looking into leveraging QualType::getAsString(const PrintingPolicy &Policy), but unfortunately, there is no option with that configuration.
e.g.
int (*)(void) ----> int (*whatever_name_here)(void)
You can create VarDecl and print that.
Assuming ctx is your ASTContext and type is your QualType, here is what you can do:
// Create identifier.
IdentifierInfo id = ctx.Idents.get("whatever_name_here");
// Create variable declaration.
VarDecl *vd = VarDecl::Create(ctx, ctx.getTranslationUnitDecl(),
SourceLocation(), SourceLocation(), &id, type, nullptr, StorageClass:SC_None);
// Print it.
vd->print(/* put your llvm::raw_stream here */, ctx.getPrintingPolicy());
In the library I am using it has functions with different signatures as follows
void Func( int* ptr);
void Func( float* ptr);
void Func( double* ptr);
My function needs to decide which function to call depending on an input flag iSwitch as follows:
void test( int iSwitch, void* ptr1)
{
switch (iSwitch)
{
case 0:
Func( (int*) ptr1);
break;
case 1:
Func((float*) ptr1);
break;
case 3:
Func((double*) ptr1);
break;
}
}
It should be OK. However I do not want to put Func inside the switch block. I want to be able to somehow switch type of pointer first in the switch block and then have only 1 Func after that in which ptr1 is dynamically casted to the corresponding type.
Specifically, I want something as follows:
void test( int iSwitch, void* ptr1)
{
switch( iSwitch)
{
// I want to be able to somehow switch type of pointer (say DummyDataType) here depending iSwitch
}
Func(( DummyDataType) ptr1);
}
Can you please advice how I can do this?
Thank you !
You can't store a type in a variable, and then use it in a cast later, if that's what you're asking. The compiler needs to know the type of a cast at compile time, otherwise it can't correctly generate the code in order to do it. Additionally the compiler needs to know the type of an argument to a function at compile time. Otherwise, it won't know which version of the function to dispatch. I think your solution is as good as it's going to get, although if you're using a flag to switch on the type of a variable, you might want to take a look at your design. Maybe give us some more context and we can offer some better solutions.
I have working code where I can create as many Point objects as I want, but it re-creates the object template each time the constructor is called, which seems like it's probably wrong.
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
// make the Point constructor function available to JS
global_templ->Set(v8::String::NewFromUtf8(isolate, "Point"), FunctionTemplate::New(isolate, v8_Point));
and then the constructor itself:
void v8_Point(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate());
// this bit should probably be cached somehow
Local<ObjectTemplate> point_template = ObjectTemplate::New(args.GetIsolate());
point_template->SetInternalFieldCount(1);
point_template->SetAccessor(String::NewFromUtf8(args.GetIsolate(), "x"), GetPointX, SetPointX);
point_template->SetAccessor(String::NewFromUtf8(args.GetIsolate(), "y"), GetPointY, SetPointY);
// end section to be cached
Local<Object> obj = point_template->NewInstance();
Point * p = new Point(1,1);
obj->SetInternalField(0, External::New(args.GetIsolate(), p));
args.GetReturnValue().Set(obj);
}
But it seems like I should be able to pass in the point_template object instead of re-creating it each time. I saw that there's a Data() field in args, but that only allows for a Value type and an ObjectTemplate is of type Template, not Value.
Any help on the right way to do this would be greatly appreciated.
I figured it out finally.
In javascript, when you add a function via a FunctionTemplate and then call it as a constructor (e.g. new MyFunction), then in your c++ callback the args.This() will be a new object created by the using the FunctionTemplate's InstanceTemplate object template.
// Everything has to go in a single global template (as I understand)
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
// create the function template and tell it the callback to use
Local<FunctionTemplate> point_constructor = FunctionTemplate::New(isolate, v8_Point);
// set the internal field count so our actual c++ object can tag along
// with the javascript object so our accessors can use it
point_constructor->InstanceTemplate()->SetInternalFieldCount(1);
// associate getters and setters for the 'x' field on point
point_constructor->InstanceTemplate()->SetAccessor(String::NewFromUtf8(isolate, "x"), GetPointX, SetPointX);
... add any other function and object templates to the global template ...
// add the global template to the context our javascript will run in
Local<Context> x_context = Context::New(isolate, NULL, global_templ);
Then, for the actual function:
void v8_Point(const v8::FunctionCallbackInfo<v8::Value>& args) {
// (just an example of a handy utility function)
// whether or not it was called as "new Point()" or just "Point()"
printf("Is constructor call: %s\n", args.IsConstructCall()?"yes":"no");
// create your c++ object that will follow the javascript object around
// make sure not to make it on the stack or it won't be around later when you need it
Point * p = new Point();
// another handy helper function example
// see how the internal field count is what it was set to earlier
// in the InstanceTemplate
printf("Internal field count: %d\n",args.This()->InternalFieldCount()); // this prints the value '1'
// put the new Point object into the internal field
args.This()->SetInternalField(0, External::New(args.GetIsolate(), p));
// return the new object back to the javascript caller
args.GetReturnValue().Set(args.This());
}
Now, when you write the getter and setter, you have access to your actual c++ object in the body of them:
void GetPointX(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
Local<Object> self = info.Holder();
// This is where we take the actual c++ object that was embedded
// into the javascript object and get it back to a useable c++ object
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<Point*>(ptr)->x_; //x_ is the name of the field in the c++ object
// return the value back to javascript
info.GetReturnValue().Set(value);
}
void SetPointX(Local<String> property, Local<Value> value,
const PropertyCallbackInfo<void>& info) {
Local<Object> self = info.Holder();
// same concept here as in the "getter" above where you get access
// to the actual c++ object and then set the value from javascript
// into the actual c++ object field
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
Almost all of this came from here: https://developers.google.com/v8/embed?hl=en#accessing-dynamic-variables
except it doesn't talk about the proper way to make your objects in a repeatable fashion.
I figured out how to clean up the c++ object in the internal field, but I don't have time to put the whole answer here. You have to pass in a Global object into your weak callback by creating a hybrid field (a struct works well) on the heap that has both the global object and a pointer to your c++ object. You can then delete your c++ object, call Reset() on your Global and then delete the whole thing. I'll try to add actual code, but may forget.
Here is a good source: https://code.google.com/p/chromium/codesearch#chromium/src/v8/src/d8.cc&l=1064 lines 1400-1441 are what you want. (edit: line numbers seem to be wrong now - maybe the link above has changed?)
Remember, v8 won't garbage collect small amounts of memory, so you may never see it. Also, just because your program ends doesn't mean the GC will run. You can use isolate->AdjustAmountOfExternalAllocatedMemory(length); to tell v8 about the size of the memory you've allocated (it includes this in its calculations about when there's too much memory in use and GC needs to run) and you can use isolate->IdleNotificationDeadline(1); to give the GC a chance to run (though it may choose not to).
I want to replace the call to malloc with call to cumemhostalloc function.
float *h_A=(float *)malloc(size);
should be replaced with
cuMemHostAlloc((void **)&h_A,size,2);
I use the following code for this,
*if (dyn_cast<CallInst> (j))
{
Ip=cast<Instruction>(j);
CastInst* ci_hp = new BitCastInst(ptr_h_A, PointerTy_23, "" );
BB->getInstList().insert(Ip,ci_hp);
errs()<<"\n Cast instruction is inserted"<<*ci_hp;
li_size = new LoadInst(al_size, "", false);
li_size->setAlignment(4);
BB->getInstList().insert(Ip,li_size);
errs()<<"\n Load instruction is inserted"<<*li_size;
ConstantInt* const_int32_34 = ConstantInt::get(M->getContext(), APInt(32, StringRef("2"), 10));
std::vector<Value*> cumemhaparams;
cumemhaparams.push_back(ci_hp);
cumemhaparams.push_back(li_size);
cumemhaparams.push_back(const_int32_34);
CallInst* cumemha = CallInst::Create(func_cuMemHostAlloc, cumemhaparams, "");
cumemha->setCallingConv(CallingConv::C);
cumemha->setTailCall(false);
AttrListPtr cumemha_PAL;
cumemha->setAttributes(cumemha_PAL);
ReplaceInstWithInst(callinst->getParent()->getInstList(), j,cumemha);*
}
But I get the following error,
/home/project/llvmfin/llvm-3.0.src/lib/VMCore/Value.cpp:287: void llvm::Value::replaceAllUsesWith(llvm::Value*): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' failed.
Is it because the call to malloc is replaced with a function that has a different signature?
Almost. Call to malloc produce a value, your function - does not. So, you have to replace call with a load, not with another call
Also, looking into your code:
Do not play with instlists directly. Use IRBuilder + iterators instead
You can check for CallInst and declare var at the same time, no need to additional cast to Instruction.