private LLVMValueRef BuildInitializeStateFunction(IEnumerable <LLVMTypeRef> parameterTypes)
        {
            LLVMTypeRef initializeStateFunctionType = LLVMTypeRef.FunctionType(
                SharedData.Context.VoidPointerType(),
                parameterTypes.ToArray(),
                false);
            LLVMValueRef      initializeStateFunction = Module.AddFunction(FunctionNames.GetInitializeStateFunctionName(_functionName), initializeStateFunctionType);
            var               builder    = SharedData.Context.CreateIRBuilder();
            LLVMBasicBlockRef entryBlock = initializeStateFunction.AppendBasicBlock("entry");

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef statePtr = SharedData.ModuleContext.CreateMalloc(builder, SharedData.AllocationSet.StateType, "statePtr");

            CurrentState = new OuterFunctionCompilerState(initializeStateFunction, builder)
            {
                StateMalloc = statePtr
            };
            GenerateStoreCompletionState(RuntimeConstants.FunctionNotDoneStatus);

            InitializeParameterAllocations(initializeStateFunction, builder);
            LLVMValueRef bitCastStatePtr = builder.CreateBitCast(statePtr, SharedData.Context.VoidPointerType(), "bitCastStatePtr");

            builder.CreateRet(bitCastStatePtr);

            return(initializeStateFunction);
        }
        private LLVMValueRef BuildPollFunction()
        {
            LLVMValueRef      pollFunction = Module.AddFunction(FunctionNames.GetPollFunctionName(_functionName), PollFunctionType(SharedData.Context));
            LLVMBasicBlockRef entryBlock   = pollFunction.AppendBasicBlock("entry");
            var builder = SharedData.Context.CreateIRBuilder();

            var outerFunctionCompilerState = new OuterFunctionCompilerState(pollFunction, builder);

            CurrentState = outerFunctionCompilerState;
            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef stateVoidPtr = pollFunction.GetParam(0u),
                         statePtr     = builder.CreateBitCast(stateVoidPtr, LLVMTypeRef.PointerType(SharedData.AllocationSet.StateType, 0u), "statePtr");

            outerFunctionCompilerState.StateMalloc = statePtr;

            // store the caller waker in the state
            // TODO: create constants for these positions
            LLVMValueRef waker = builder.BuildStructValue(
                SharedData.Context.WakerType(),
                new LLVMValueRef[] { pollFunction.GetParam(1u), pollFunction.GetParam(2u) },
                "callerWaker");

            builder.CreateStore(waker, builder.CreateStructGEP(statePtr, 1u, "callerWakerPtr"));

            // set initial fire counts
            foreach (AsyncStateGroupData groupData in AsyncStateGroups.Values)
            {
                groupData.CreateFireCountReset(builder);
            }

            // schedule initial group(s)
            CreateScheduleCallsForAsyncStateGroups(
                builder,
                statePtr,
                AsyncStateGroups.Keys.Where(group => !group.Predecessors.Any()));

            builder.CreateRetVoid();
            return(pollFunction);
        }