示例#1
0
文件: llvm.cpp 项目: WoodMath/mathmap
void
code_emitter::setup_xy_vars_from_closure ()
{
    Value *t_var = lookup_internal(::lookup_internal(filter->v.mathmap.internals, "t", true));
    Value *xy_vars_untyped = builder->CreateCall4(module->getFunction(string("calc_closure_xy_vars")),
						  invocation_arg, closure_arg, t_var, init_frame_function);
    xy_vars_var = builder->CreateBitCast(xy_vars_untyped, PointerType::getUnqual(xy_vars_type));
}
示例#2
0
void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len,
                const Analysis& A) {
    Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty()));

    CallSite CS = B.CreateMemSet(Dst, Val, Len, 1 /*Align*/, false /*isVolatile*/);
    if (A.CGNode)
        A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(CS.getCalledFunction()));
}
示例#3
0
文件: llvm.cpp 项目: WoodMath/mathmap
void
code_emitter::setup_filter_function (bool is_main_filter_function)
{
    Function *filter_function = is_main_filter_function
	? lookup_main_filter_function(module, filter)
	: lookup_filter_function(module, filter);
    Function::arg_iterator args = filter_function->arg_begin();
    Value *slice_arg = NULL;

    if (is_main_filter_function)
    {
	slice_arg = args++;
	slice_arg->setName("slice");
    }
    else
    {
	invocation_arg = args++;
	invocation_arg->setName("invocation");
    }
    closure_arg = args++;
    closure_arg->setName("closure");
    if (is_main_filter_function)
    {
	x_vars_var = args++;
	x_vars_var->setName("x_vars");
	y_vars_var = args++;
	y_vars_var->setName("y_vars");
    }
    set_internal(::lookup_internal(filter->v.mathmap.internals, "x", true), args++);
    set_internal(::lookup_internal(filter->v.mathmap.internals, "y", true), args++);
    set_internal(::lookup_internal(filter->v.mathmap.internals, "t", true), args++);
    pools_arg = args++;
    pools_arg->setName("pools");

    BasicBlock *block = BasicBlock::Create("entry", filter_function);

    builder = new IRBuilder<> (block);

    if (is_main_filter_function)
    {
	x_vars_var = builder->CreateBitCast(x_vars_var, PointerType::getUnqual(x_vars_type));
	y_vars_var = builder->CreateBitCast(y_vars_var, PointerType::getUnqual(y_vars_type));
	frame_arg = builder->CreateCall(module->getFunction(string("get_slice_frame")), slice_arg);
	invocation_arg = builder->CreateCall(module->getFunction(string("get_frame_invocation")), frame_arg);
    }

    set_internals_from_invocation(invocation_arg);

    if (is_main_filter_function)
	set_xy_vars_from_frame ();
    else
	setup_xy_vars_from_closure ();

    alloc_complex_copy_var();

    current_function = filter_function;
}
示例#4
0
CodeGenBlock::CodeGenBlock(int args, int locals, CodeGenLexicalScope
		*enclosingScope, CodeGenModule *Mod) 
	: CodeGenLexicalScope(Mod), parentScope(enclosingScope) 
{
	Value *enclosingContext = enclosingScope->getContext();
	// Define the layout of a block
	BlockTy = StructType::get(
		Mod->Context,
		IdTy,                          // 0 - isa.
		IMPTy,                         // 1 - Function pointer.
		Type::getInt32Ty(Mod->Context),// 2 - Number of args.
		enclosingContext->getType(),   // 3 - Context.
		NULL);
	std::vector<const Type*> argTy;
	argTy.push_back(PointerType::getUnqual(BlockTy));

	// FIXME: Broken on Etoile runtime - _cmd needs to be a GEP on _call
	argTy.push_back(SelTy);
	for (int i=0 ; i<args ; ++i) 
	{
		argTy.push_back(IdTy);
	}
	FunctionType *BlockFunctionTy = FunctionType::get(IdTy, argTy, false);

	IRBuilder<> *MethodBuilder = enclosingScope->getBuilder();

	// Create the block object
	
	// The NewBlock function gets a block from a pool.  It should really be
	// inlined.
	Block = MethodBuilder->CreateAlloca(BlockTy);

	Module *TheModule = CGM->getModule();
	// Create the block function
	CurrentFunction = Function::Create(BlockFunctionTy,
		GlobalValue::InternalLinkage, "BlockFunction", TheModule);
	InitialiseFunction(Args, Locals, locals);

	// Set the isa pointer
	Value *isa = MethodBuilder->CreateLoad(
		TheModule->getGlobalVariable(".smalltalk_block_stack_class", true));
	storeInStruct(MethodBuilder, Block, isa, 0);

	// Store the block function in the object
	storeInStruct(MethodBuilder, Block,
		MethodBuilder->CreateBitCast(CurrentFunction, IMPTy), 1);
	// Store the number of arguments
	storeInStruct(MethodBuilder, Block, 
			ConstantInt::get(Type::getInt32Ty(Mod->Context), args), 2);
	// Set the context
	storeInStruct(MethodBuilder, Block, enclosingScope->getContext(), 3);


}
示例#5
0
// Calls to setjmp(p) are lowered to _setjmp3(p, 0) by the frontend.
// The idea behind _setjmp3 is that it takes an optional number of personality
// specific parameters to indicate how to restore the personality-specific frame
// state when longjmp is initiated.  Typically, the current TryLevel is saved.
void WinEHStatePass::rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F,
                                           CallSite CS, Value *State) {
  // Don't rewrite calls with a weird number of arguments.
  if (CS.getNumArgOperands() != 2)
    return;

  Instruction *Inst = CS.getInstruction();

  SmallVector<OperandBundleDef, 1> OpBundles;
  CS.getOperandBundlesAsDefs(OpBundles);

  SmallVector<Value *, 3> OptionalArgs;
  if (Personality == EHPersonality::MSVC_CXX) {
    OptionalArgs.push_back(CxxLongjmpUnwind);
    OptionalArgs.push_back(State);
    OptionalArgs.push_back(emitEHLSDA(Builder, &F));
  } else if (Personality == EHPersonality::MSVC_X86SEH) {
    OptionalArgs.push_back(SehLongjmpUnwind);
    OptionalArgs.push_back(State);
    if (UseStackGuard)
      OptionalArgs.push_back(Cookie);
  } else {
    llvm_unreachable("unhandled personality!");
  }

  SmallVector<Value *, 5> Args;
  Args.push_back(
      Builder.CreateBitCast(CS.getArgOperand(0), Builder.getInt8PtrTy()));
  Args.push_back(Builder.getInt32(OptionalArgs.size()));
  Args.append(OptionalArgs.begin(), OptionalArgs.end());

  CallSite NewCS;
  if (CS.isCall()) {
    auto *CI = cast<CallInst>(Inst);
    CallInst *NewCI = Builder.CreateCall(SetJmp3, Args, OpBundles);
    NewCI->setTailCallKind(CI->getTailCallKind());
    NewCS = NewCI;
  } else {
    auto *II = cast<InvokeInst>(Inst);
    NewCS = Builder.CreateInvoke(
        SetJmp3, II->getNormalDest(), II->getUnwindDest(), Args, OpBundles);
  }
  NewCS.setCallingConv(CS.getCallingConv());
  NewCS.setAttributes(CS.getAttributes());
  NewCS->setDebugLoc(CS->getDebugLoc());

  Instruction *NewInst = NewCS.getInstruction();
  NewInst->takeName(Inst);
  Inst->replaceAllUsesWith(NewInst);
  Inst->eraseFromParent();
}
void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len,
                const Analysis& A) {
    Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty()));

    Module *M = B.GetInsertBlock()->getParent()->getParent();
    Type* intTy = Len->getType();
    Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
    Type *Tys[2] = {VoidPtrTy, intTy};
    Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset,
        llvm::makeArrayRef(Tys, 2));
    Value *Align = ConstantInt::get(B.getInt32Ty(), 1);

    CallSite CS = B.CreateCall5(MemSet, Dst, Val, Len, Align, B.getFalse());
    if (A.CGNode)
        A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet));
}
示例#7
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);
}
示例#8
0
文件: llvm.cpp 项目: WoodMath/mathmap
Value*
code_emitter::convert_complex_return_value (Value *result)
{
    /* The result is complex, whose representation
       differs between archs, and we need to transform
       it into another arch-dependent
       representation. */
    if (sizeof(gpointer) == 4)
    {
	Value *local = complex_copy_var;
	Value *local_ptr = builder->CreateBitCast(local, PointerType::getUnqual(Type::Int64Ty));
	builder->CreateStore(result, local_ptr);
	result = builder->CreateLoad(local);
    }
    else if (sizeof(gpointer) == 8)
	result = builder->CreateExtractValue(result, 0);
    else
	g_assert_not_reached();

    return result;
}
示例#9
0
Value* ColExpression::getValue() {
    IRBuilder<>* builder = codegen::getBuilder();
    DataType dt = codegen::getAttType(index);
    Value* tupleptr = codegen::getTupleptr();

    Value *indices[1];
    indices[0] = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), (uint64_t) index);
    ArrayRef<Value*> indicesRef(indices);

    Value *dataptr = builder->CreateInBoundsGEP(tupleptr, indicesRef);

    switch(dt){
        case DOUBLE:
            return builder->CreateLoad(
                    builder->CreateBitCast(dataptr, Type::getDoublePtrTy(getGlobalContext()))
            );
        case LONG:
        case STRING:
        case DATE:
            return builder->CreateLoad(dataptr);
    }
}
示例#10
0
文件: llvm.cpp 项目: WoodMath/mathmap
Value*
code_emitter::setup_init_x_or_y_function (string function_name, const char *internal_name, StructType *vars_type)
{
    current_function = module->getFunction(function_name);

    Value *slice_arg;

    Function::arg_iterator args = current_function->arg_begin();

    slice_arg = args++;
    slice_arg->setName("slice");
    closure_arg = args++;
    closure_arg->setName("closure");
    set_internal(::lookup_internal(filter->v.mathmap.internals, internal_name, true), args++);
    set_internal(::lookup_internal(filter->v.mathmap.internals, "t", true), args++);

    BasicBlock *block = BasicBlock::Create("entry", current_function);

    builder = new IRBuilder<> (block);

    frame_arg = builder->CreateCall(module->getFunction(string("get_slice_frame")), slice_arg);
    invocation_arg = builder->CreateCall(module->getFunction(string("get_frame_invocation")), frame_arg);
    pools_arg = builder->CreateCall(module->getFunction("get_slice_pools"), slice_arg);

    set_internals_from_invocation(invocation_arg);

    set_xy_vars_from_frame();

    ret_var = builder->CreateCall2(module->getFunction(string("_mathmap_pools_alloc")),
				   pools_arg, emit_sizeof(vars_type));

    Value *vars_var = builder->CreateBitCast(ret_var, PointerType::getUnqual(vars_type));

    alloc_complex_copy_var();

    return vars_var;
}
示例#11
0
文件: llvm.cpp 项目: WoodMath/mathmap
void
code_emitter::setup_init_frame_function ()
{
    Value *t_arg;
    Function::arg_iterator args = init_frame_function->arg_begin();

    invocation_arg = args++;
    invocation_arg->setName("invocation");
    //frame_arg = args++;
    //frame_arg->setName("frame");
    closure_arg = args++;
    closure_arg->setName("closure");
    t_arg = args++;
    t_arg->setName("t");
    pools_arg = args++;
    pools_arg->setName("pools");

    BasicBlock *block = BasicBlock::Create("entry", init_frame_function);

    builder = new IRBuilder<> (block);

    //invocation_arg = builder->CreateCall(module->getFunction(string("get_frame_invocation")), frame_arg);
    //pools_arg = builder->CreateCall(module->getFunction(string("get_frame_pools")), frame_arg);

    set_internal(::lookup_internal(filter->v.mathmap.internals, "t", true), t_arg);

    set_internals_from_invocation(invocation_arg);

    ret_var = builder->CreateCall2(module->getFunction(string("_mathmap_pools_alloc")),
				   pools_arg, emit_sizeof(xy_vars_type));
    xy_vars_var = builder->CreateBitCast(ret_var, PointerType::getUnqual(xy_vars_type));

    alloc_complex_copy_var();

    current_function = init_frame_function;
}
示例#12
0
std::pair<Value *, Value *>
AMDGPUPromoteAlloca::getLocalSizeYZ(IRBuilder<> &Builder) {
  if (!IsAMDHSA) {
    Function *LocalSizeYFn
      = Intrinsic::getDeclaration(Mod, Intrinsic::r600_read_local_size_y);
    Function *LocalSizeZFn
      = Intrinsic::getDeclaration(Mod, Intrinsic::r600_read_local_size_z);

    CallInst *LocalSizeY = Builder.CreateCall(LocalSizeYFn, {});
    CallInst *LocalSizeZ = Builder.CreateCall(LocalSizeZFn, {});

    LocalSizeY->setMetadata(LLVMContext::MD_range, MaxWorkGroupSizeRange);
    LocalSizeZ->setMetadata(LLVMContext::MD_range, MaxWorkGroupSizeRange);

    return std::make_pair(LocalSizeY, LocalSizeZ);
  }

  // We must read the size out of the dispatch pointer.
  assert(IsAMDGCN);

  // We are indexing into this struct, and want to extract the workgroup_size_*
  // fields.
  //
  //   typedef struct hsa_kernel_dispatch_packet_s {
  //     uint16_t header;
  //     uint16_t setup;
  //     uint16_t workgroup_size_x ;
  //     uint16_t workgroup_size_y;
  //     uint16_t workgroup_size_z;
  //     uint16_t reserved0;
  //     uint32_t grid_size_x ;
  //     uint32_t grid_size_y ;
  //     uint32_t grid_size_z;
  //
  //     uint32_t private_segment_size;
  //     uint32_t group_segment_size;
  //     uint64_t kernel_object;
  //
  // #ifdef HSA_LARGE_MODEL
  //     void *kernarg_address;
  // #elif defined HSA_LITTLE_ENDIAN
  //     void *kernarg_address;
  //     uint32_t reserved1;
  // #else
  //     uint32_t reserved1;
  //     void *kernarg_address;
  // #endif
  //     uint64_t reserved2;
  //     hsa_signal_t completion_signal; // uint64_t wrapper
  //   } hsa_kernel_dispatch_packet_t
  //
  Function *DispatchPtrFn
    = Intrinsic::getDeclaration(Mod, Intrinsic::amdgcn_dispatch_ptr);

  CallInst *DispatchPtr = Builder.CreateCall(DispatchPtrFn, {});
  DispatchPtr->addAttribute(AttributeSet::ReturnIndex, Attribute::NoAlias);
  DispatchPtr->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);

  // Size of the dispatch packet struct.
  DispatchPtr->addDereferenceableAttr(AttributeSet::ReturnIndex, 64);

  Type *I32Ty = Type::getInt32Ty(Mod->getContext());
  Value *CastDispatchPtr = Builder.CreateBitCast(
    DispatchPtr, PointerType::get(I32Ty, AMDGPUAS::CONSTANT_ADDRESS));

  // We could do a single 64-bit load here, but it's likely that the basic
  // 32-bit and extract sequence is already present, and it is probably easier
  // to CSE this. The loads should be mergable later anyway.
  Value *GEPXY = Builder.CreateConstInBoundsGEP1_64(CastDispatchPtr, 1);
  LoadInst *LoadXY = Builder.CreateAlignedLoad(GEPXY, 4);

  Value *GEPZU = Builder.CreateConstInBoundsGEP1_64(CastDispatchPtr, 2);
  LoadInst *LoadZU = Builder.CreateAlignedLoad(GEPZU, 4);

  MDNode *MD = llvm::MDNode::get(Mod->getContext(), None);
  LoadXY->setMetadata(LLVMContext::MD_invariant_load, MD);
  LoadZU->setMetadata(LLVMContext::MD_invariant_load, MD);
  LoadZU->setMetadata(LLVMContext::MD_range, MaxWorkGroupSizeRange);

  // Extract y component. Upper half of LoadZU should be zero already.
  Value *Y = Builder.CreateLShr(LoadXY, 16);

  return std::make_pair(Y, LoadZU);
}
示例#13
0
void GNUstep::IMPCacher::SpeculativelyInline(Instruction *call, Function
        *function) {
    BasicBlock *beforeCallBB = call->getParent();
    BasicBlock *callBB = SplitBlock(beforeCallBB, call, Owner);
    BasicBlock *inlineBB = BasicBlock::Create(Context, "inline",
                           callBB->getParent());


    BasicBlock::iterator iter = call;
    iter++;

    BasicBlock *afterCallBB = SplitBlock(iter->getParent(), iter, Owner);

    removeTerminator(beforeCallBB);

    // Put a branch before the call, testing whether the callee really is the
    // function
    IRBuilder<> B = IRBuilder<>(beforeCallBB);
    Value *callee = isa<CallInst>(call) ? cast<CallInst>(call)->getCalledValue()
                    : cast<InvokeInst>(call)->getCalledValue();

    const FunctionType *FTy = function->getFunctionType();
    const FunctionType *calleeTy = cast<FunctionType>(
                                       cast<PointerType>(callee->getType())->getElementType());
    if (calleeTy != FTy) {
        callee = B.CreateBitCast(callee, function->getType());
    }

    Value *isInlineValid = B.CreateICmpEQ(callee, function);
    B.CreateCondBr(isInlineValid, inlineBB, callBB);

    // In the inline BB, add a copy of the call, but this time calling the real
    // version.
    Instruction *inlineCall = call->clone();
    Value *inlineResult= inlineCall;
    inlineBB->getInstList().push_back(inlineCall);

    B.SetInsertPoint(inlineBB);

    if (calleeTy != FTy) {
        for (unsigned i=0 ; i<FTy->getNumParams() ; i++) {
            LLVMType *callType = calleeTy->getParamType(i);
            LLVMType *argType = FTy->getParamType(i);
            if (callType != argType) {
                inlineCall->setOperand(i, new
                                       BitCastInst(inlineCall->getOperand(i), argType, "", inlineCall));
            }
        }
        if (FTy->getReturnType() != calleeTy->getReturnType()) {
            if (FTy->getReturnType() == Type::getVoidTy(Context)) {
                inlineResult = Constant::getNullValue(calleeTy->getReturnType());
            } else {
                inlineResult =
                    new BitCastInst(inlineCall, calleeTy->getReturnType(), "", inlineBB);
            }
        }
    }

    B.CreateBr(afterCallBB);

    // Unify the return values
    if (call->getType() != Type::getVoidTy(Context)) {
        PHINode *phi = CreatePHI(call->getType(), 2, "", afterCallBB->begin());
        call->replaceAllUsesWith(phi);
        phi->addIncoming(call, callBB);
        phi->addIncoming(inlineResult, inlineBB);
    }

    // Really do the real inlining
    InlineFunctionInfo IFI(0, 0);
    if (CallInst *c = dyn_cast<CallInst>(inlineCall)) {
        c->setCalledFunction(function);
        InlineFunction(c, IFI);
    } else if (InvokeInst *c = dyn_cast<InvokeInst>(inlineCall)) {
        c->setCalledFunction(function);
        InlineFunction(c, IFI);
    }
}
示例#14
0
文件: llvm.cpp 项目: WoodMath/mathmap
void
code_emitter::set_xy_vars_from_frame ()
{
    Value *xy_vars_untyped = builder->CreateCall(module->getFunction(string("get_frame_xy_vars")), frame_arg);
    xy_vars_var = builder->CreateBitCast(xy_vars_untyped, PointerType::getUnqual(xy_vars_type));
}