Ignore:
Timestamp:
Jun 27, 2016, 9:43:17 AM (3 years ago)
Author:
cameron
Message:

Updates for kernels with variable output length; stdout kernel

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/stdout_kernel.cpp

    r5007 r5076  
    1010namespace kernel {
    1111
    12     static Function * create_write(Module * const mod) {
    13         Function * write = mod->getFunction("write");
    14         if (write == nullptr) {
    15             FunctionType *write_type =
    16             TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
    17             write = cast<Function>(mod->getOrInsertFunction("write", write_type,
    18                                                              AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
    19         }
    20         return write;
     12static Function * create_write(Module * const mod) {
     13    Function * write = mod->getFunction("write");
     14    if (write == nullptr) {
     15        FunctionType *write_type =
     16        TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
     17        write = cast<Function>(mod->getOrInsertFunction("write", write_type,
     18                                                         AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
    2119    }
    22    
     20    return write;
     21}
    2322
    24 void generateStdOutKernel(Module * m, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder, unsigned fw) {
    25     LLVMContext & ctxt = m->getContext();
    26 
    27     Type * i32 = iBuilder->getIntNTy(32);
    28     Type * i64 = iBuilder->getIntNTy(64);
    29    
    30     // Insert this declaration in the module (if necessary):  declare i64 @write(i32, i8*, i64)
    31     Function * writefn = create_write(m);
    32     kBuilder->addInputStream(fw, "byte_pack");
    33     // No output streams.
    34     kBuilder->addInternalState(i64, "RemainingBytes");
    35 
    36     Function * function = kBuilder->prepareFunction();
    37    
    38     BasicBlock * full_block_write = BasicBlock::Create(ctxt, "full_block_write", function, 0);
    39     BasicBlock * final_block_write = BasicBlock::Create(ctxt, "final_block_write", function, 0);
    40     BasicBlock * exit_block = BasicBlock::Create(ctxt, "exit_stdout", function, 0);
    41     Value * bytes = iBuilder->CreateLoad(kBuilder->getInternalState("RemainingBytes"));
    42 
    43     Value * input = iBuilder->CreateBitCast(kBuilder->getInputStream(0), iBuilder->getInt8PtrTy());
    44     Value * blockSize = ConstantInt::get(i64, iBuilder->getBitBlockWidth());
    45 
    46     Value * fullblock_cond = iBuilder->CreateICmpULT(bytes, blockSize);
    47     iBuilder->CreateCondBr(fullblock_cond, final_block_write, full_block_write);
    48    
    49     iBuilder->SetInsertPoint(full_block_write);
    50     Value * outputBytes = ConstantInt::get(i64, iBuilder->getBitBlockWidth() * fw/8);
    51     iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
    52     Value * remain = iBuilder->CreateSub(bytes, blockSize);
    53     kBuilder->setInternalState("RemainingBytes", remain);
    54     iBuilder->CreatePtrToInt(remain, iBuilder->getInt64Ty());
    55     iBuilder->CreateBr(exit_block);
    56    
    57     iBuilder->SetInsertPoint(final_block_write);
    58     outputBytes = iBuilder->CreateMul(bytes, ConstantInt::get(i64, fw/8));
    59     iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
    60     kBuilder->setInternalState("RemainingBytes", ConstantInt::getNullValue(i64));
    61     iBuilder->CreateBr(exit_block);
    62 
    63    
    64     iBuilder->SetInsertPoint(exit_block);
    65    
    66     kBuilder->finalize();
     23//  Override the default void type for DoBlock functions.
     24void stdOutKernel::prepareKernel() {
     25    setDoBlockReturnType(mStreamType);
     26    KernelBuilder::prepareKernel();
    6727}
    6828
    6929
     30void stdOutKernel::generateDoBlockMethod() {
     31    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     32    Module * m = iBuilder->getModule();
     33    Function * writefn = create_write(m);
     34    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
     35    Type * i8PtrTy = iBuilder->getInt8PtrTy();
     36
     37    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
     38
     39    Value * self = getParameter(doBlockFunction, "self");
     40    Value * bufferPtr = getParameter(doBlockFunction, "bufferPtr");
     41    Value * bufferFinalBlockPtr = getScalarField(self, "bufferFinalBlockPtr");
     42    //iBuilder->CallPrintInt("bufferPtr", iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty()));
     43    //iBuilder->CallPrintInt("bufferFinalBlockPtr", iBuilder->CreatePtrToInt(bufferFinalBlockPtr, iBuilder->getInt64Ty()));
    7044   
     45   
     46    BasicBlock * flushBlock = BasicBlock::Create(iBuilder->getContext(), "flush", doBlockFunction, 0);
     47    BasicBlock * exitBlock = BasicBlock::Create(iBuilder->getContext(), "exit", doBlockFunction, 0);
     48    Value * inFinal = iBuilder->CreateICmpUGT(bufferPtr, bufferFinalBlockPtr);
     49    iBuilder->CreateCondBr(inFinal, flushBlock, exitBlock);
     50   
     51    iBuilder->SetInsertPoint(flushBlock);
     52    Value * basePtr = getScalarField(self, "bufferBasePtr");
     53    //iBuilder->CallPrintInt("bufferBasePtr", iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty()));
     54    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
     55    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
     56    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
     57   
     58    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
     59    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
     60    iBuilder->CreateRet(basePtr);
     61
     62    iBuilder->SetInsertPoint(exitBlock);
     63    iBuilder->CreateRet(bufferPtr);
     64    iBuilder->restoreIP(savePoint);
    7165}
     66
     67void stdOutKernel::generateFinalBlockMethod() {
     68    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     69    Module * m = iBuilder->getModule();
     70    Function * writefn = create_write(m);
     71    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
     72    Type * i8PtrTy = iBuilder->getInt8PtrTy();
     73   
     74    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_flush", finalBlockFunction, 0));
     75    Value * self = getParameter(finalBlockFunction, "self");
     76    Value * bufferPtr = getParameter(finalBlockFunction, "bufferPtr");
     77    Value * basePtr = getScalarField(self, "bufferBasePtr");
     78    // Flush the output.
     79    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
     80    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
     81    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
     82   
     83    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
     84    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
     85    iBuilder->CreateRet(basePtr);
     86    iBuilder->restoreIP(savePoint);
     87}
     88}
Note: See TracChangeset for help on using the changeset viewer.