Пример #1
0
void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
                                               Function *Handler) {
  // Emit the .safeseh directive for this function.
  Handler->addFnAttr("safeseh");

  Type *LinkTy = getEHLinkRegistrationType();
  // Handler = Handler
  Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
  Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
  // Next = [fs:00]
  Constant *FSZero =
      Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
  Value *Next = Builder.CreateLoad(FSZero);
  Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
  // [fs:00] = Link
  Builder.CreateStore(Link, FSZero);
}
Пример #2
0
int main(int argc, char **argv)
{
    InitializeNativeTarget();
    LLVMContext &Context = getGlobalContext();
    Module *m = new Module("test", Context);
    Type *intTy  = Type::getInt64Ty(Context);

    StructType* structTy = StructType::create(Context, "struct.list");
    std::vector<Type*> fields;
    fields.push_back(intTy);
    fields.push_back(PointerType::get(structTy, 0));
    if (structTy->isOpaque()) {
        structTy->setBody(fields, false);
    }

    /*
     * int f1(struct x *p) { return p->next->l1; }
     */
    std::vector<Type*> args_type;
    args_type.push_back(PointerType::get(structTy, 0));

    FunctionType *fnTy = FunctionType::get(intTy, args_type, false);
    Function *func = Function::Create(fnTy,
            GlobalValue::ExternalLinkage, "f1", m);
    Value *v = func->arg_begin();
    BasicBlock *bb = BasicBlock::Create(Context, "EntryBlock", func);
    IRBuilder<> *builder = new IRBuilder<>(bb);
    v = builder->CreateStructGEP(v, 1);
    v = builder->CreateLoad(v, "load0");
    v = builder->CreateStructGEP(v, 0);
    v = builder->CreateLoad(v, "load1");
    builder->CreateRet(v);

    (*m).dump();
    {
        ExecutionEngine *ee = EngineBuilder(m). 
            setEngineKind(EngineKind::JIT).create();
        void *f = ee->getPointerToFunction(func);
        typedef int (*func_t) (struct x *);
        struct x o = {10, NULL}, v = {};
        v.next = &o;
        std::cout << ((func_t)f)(&v) << std::endl;
    }
    return 0;
}
Пример #3
0
void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
  // Clone Link into the current BB for better address mode folding.
  if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
    GEP = cast<GetElementPtrInst>(GEP->clone());
    Builder.Insert(GEP);
    Link = GEP;
  }
  Type *LinkTy = getEHLinkRegistrationType();
  // [fs:00] = Link->Next
  Value *Next =
      Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
  Constant *FSZero =
      Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
  Builder.CreateStore(Next, FSZero);
}
Пример #4
0
codegen_value ast::distribution::codegen(Module *module, IRBuilder<> &builder) {
  typecheck_vector param_types = get_parameter_types();

  return errors::codegen_call<typecheck_vector, codegen_value>(param_types, [this, module, &builder] (vector<type_spec> &param_types) -> codegen_value {
      Type *param_struct_ty = getParameterType(param_types);

      boost::function<void (Value*, Module*, IRBuilder<>&)> loader = [this, &param_types] (Value *ctx, Module *module, IRBuilder<> &builder) -> void {
	//create variable names pointing to each member of the param struct    
	for (unsigned int param_idx = 0; param_idx < params.size(); ++param_idx) {
	  const distribution_parameter &param = params[param_idx];
	  
	  Value *param_ptr = builder.CreateStructGEP(ctx, param_idx);
	  variable_symbol_table::entry_type entry(param_ptr, param_types[param_idx], false);
	  variables().set(param.name, entry);
	}
      };
      
      //enter new scope
      push_distribution_context(name, param_struct_ty->getPointerTo(), loader);
      
      //evaluate all internal declarations
      codegen_vector content_eval;
      for (auto it = internal_decl.begin(); it != internal_decl.end(); it++) {
	codegen_value eval = (*it)->codegen(module, builder);
	content_eval = errors::codegen_vector_push_back(content_eval, eval);
      }
      
      //find the 'evaluate' function (error if not declared)
      codegen_value eval_func = check_for_evaluate();

      //find the 'pdf' function
      codegen_value pdf_func = check_for_pdf();

      //find the 'emission' function
      codegen_value emit_func = check_for_emission();
      
      //find the 'sample' function
      codegen_value sample_func = check_for_sample();
      
      //leave new scope
      pop_distribution_context(module, builder);
      
      vector<function_argument> ctor_arguments;
      for (unsigned int param_idx = 0; param_idx < params.size(); ++param_idx) {
	function_argument arg{params[param_idx].name, param_types[param_idx], false};
	ctor_arguments.push_back(arg);
      }

      string ctor_name = function_generate_name(name, function_scope_name(), ctor_arguments);

      //define an externally visible function to evaluate this distribution (vectors must be passed by pointer, not value).
      //then define an externally visible function to instantiate this distribution
      boost::function<codegen_value (Value *&, Value *&,
				     Value *&, Value *&)> check_funcs = [this,
									 &ctor_name,
									 &param_types, param_struct_ty,
									 module, &builder] (Value *&eval_ptr,
											    Value *&sample_ptr,
											    Value *&pdf_ptr,
											    Value *&emit_ptr) -> codegen_value {
	Value *eval_f = create_evaluator(cast_or_null<Function>(eval_ptr), param_struct_ty, module, builder);
	Value *sample_f = create_sampler(cast_or_null<Function>(sample_ptr), param_struct_ty, module, builder);
	Value *pdf_f = create_pdf(cast_or_null<Function>(pdf_ptr), param_struct_ty, module, builder);
	Value *emit_f = create_emission(cast_or_null<Function>(emit_ptr), param_struct_ty, module, builder);
	
	Function *dtor_f = createDestructor(module, builder, param_struct_ty, param_types);
	
	return createConstructor(module, builder,
				 ctor_name,
				 param_struct_ty, param_types,
				 eval_f, sample_f, pdf_f, emit_f,
				 dtor_f);
      };
      codegen_value ctor_val = errors::codegen_apply(check_funcs, eval_func, sample_func, pdf_func, emit_func);
      
      //final error checking, add the constructor to the function symtab
      boost::function<codegen_value (vector<Value*> &, Value*&, Value*&)> op = [this,
										&ctor_arguments,
										&param_types,
										module, &builder] (vector<Value*> &,
												   Value *&,
												   Value *&ctor_ptr) -> codegen_value {

	Function *ctor = cast<Function>(ctor_ptr);
	function_entry entry = function_entry::make_entry(name, function_scope_name(),
							  state->types["dfunc"], ctor_arguments);
	entry.func = ctor;
	function_table().set(entry.to_key(), entry);
	
	//also export the constructor
	exports::function_export exp;
	exp.name = entry.name;
	exp.full_name = entry.full_name;
	exp.return_type = entry.return_type;
	exp.arguments = entry.arguments;
	state->exports.add_function(exp);
	
	return ctor;
      };
      
      return errors::codegen_apply(op, content_eval, eval_func, ctor_val);
    });
}
Пример #5
0
codegen_value ast::distribution::createConstructor(Module *module, IRBuilder<> &builder,
						   const string &ctor_name,
						   Type *parameter_type,
						   const vector<type_spec> &param_type_list,
						   Value *eval, Value *sample, Value *pdf, Value *emit,
						   Function *dtor) {
  //create function accepting parameters as arguments
  vector<Type*> arg_types;
  for (auto it = param_type_list.begin(); it != param_type_list.end(); ++it) arg_types.push_back((*it)->llvm_type());

  FunctionType *ft = FunctionType::get(state->types["dfunc"]->llvm_type(), arg_types, false);
  Function *f = Function::Create(ft, Function::ExternalLinkage, ctor_name, module);
  BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "func_entry", f);
  builder.SetInsertPoint(bb);
  
  //setup arguments for the alloc call
  Value *gd_scene = module->getNamedGlobal(".__gd_scene");
  assert(gd_scene != NULL);
  Value *scene_ptr = builder.CreateLoad(gd_scene);

  //compute the shader flags
  codegen_value flag_val = codegen_all_flags(module, builder);

  return errors::codegen_call(flag_val, [&] (Value *&flag_bitmask) -> codegen_value {
      //get memory for a new distribution object
      Value *dfunc_ptr = state->types["dfunc"]->allocate(module, builder);
  
      //initialize the object and dynamically allocate parameter memory (calling a builtin function)
      Type* int_ptr_ty = Type::getInt32Ty(getGlobalContext())->getPointerTo();
      vector<Type*> alloc_arg_types({state->types["scene_ptr"]->llvm_type(),
	    Type::getInt32Ty(getGlobalContext()), state->types["shader_flag"]->llvm_type(),
	    int_ptr_ty, int_ptr_ty, int_ptr_ty, int_ptr_ty,
	    dtor->getType(), dfunc_ptr->getType()});
      FunctionType *alloc_type = FunctionType::get(Type::getInt32PtrTy(getGlobalContext()), alloc_arg_types, false);
      Function *alloc_func = GetExternalFunction(module, "gd_builtin_alloc_dfunc", alloc_type);
      
      int param_data_size = DataLayout(module).getTypeAllocSize(parameter_type);
      Constant *param_size_arg = ConstantInt::get(getGlobalContext(), APInt(8*sizeof(int), param_data_size));
      
      vector<Value*> alloc_args({scene_ptr, param_size_arg, flag_bitmask,
	    builder.CreatePointerCast(eval, int_ptr_ty),
	    builder.CreatePointerCast(sample, int_ptr_ty),
	    builder.CreatePointerCast(pdf, int_ptr_ty),
	    builder.CreatePointerCast(emit, int_ptr_ty),
	    dtor, dfunc_ptr});
      Value *param_ptr = builder.CreatePointerCast(builder.CreateCall(alloc_func, alloc_args),
						   parameter_type->getPointerTo(), "dfunc_param_ptr");
      
      //set each parameter
      auto arg_it = f->arg_begin();
      unsigned int field_idx = 0;
      for (auto it = param_type_list.begin(); it != param_type_list.end(); ++it, ++arg_it, ++field_idx) {
	Value *param_copy = (*it)->copy(arg_it, module, builder);
	(*it)->store(param_copy, builder.CreateStructGEP(param_ptr, field_idx), module, builder);
      }
      
      //return the object
      Value *rt_val = builder.CreateLoad(dfunc_ptr, "dist_ref");
      builder.CreateRet(rt_val);
      return f;
    });
}