source: icGREP/icgrep-devel/icgrep/kernels/stdout_kernel.cpp @ 5076

Last change on this file since 5076 was 5076, checked in by cameron, 3 years ago

Updates for kernels with variable output length; stdout kernel

File size: 4.1 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#include <kernels/stdout_kernel.h>
6#include <kernels/kernel.h>
7#include <IDISA/idisa_builder.h>
8#include <llvm/IR/TypeBuilder.h>
9
10namespace kernel {
11
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)));
19    }
20    return write;
21}
22
23//  Override the default void type for DoBlock functions.
24void stdOutKernel::prepareKernel() {
25    setDoBlockReturnType(mStreamType);
26    KernelBuilder::prepareKernel();
27}
28
29
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()));
44   
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);
65}
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 TracBrowser for help on using the repository browser.