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

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

Use dynamic size_t determination

File size: 4.3 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 * blockNo = getScalarField(self, blockNoScalar);
41    Value * inputStreamBlock = getStreamSetBlockPtr(self, "inputStreamSet", blockNo);
42
43    Value * bufferPtr = getScalarField(self, "bufferPtr");
44    Value * bufferFinalBlockPtr = getScalarField(self, "bufferFinalBlockPtr");
45    //iBuilder->CallPrintInt("bufferPtr", iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty()));
46    //iBuilder->CallPrintInt("bufferFinalBlockPtr", iBuilder->CreatePtrToInt(bufferFinalBlockPtr, iBuilder->getInt64Ty()));
47   
48   
49    BasicBlock * flushBlock = BasicBlock::Create(iBuilder->getContext(), "flush", doBlockFunction, 0);
50    BasicBlock * exitBlock = BasicBlock::Create(iBuilder->getContext(), "exit", doBlockFunction, 0);
51    Value * inFinal = iBuilder->CreateICmpUGT(bufferPtr, bufferFinalBlockPtr);
52    iBuilder->CreateCondBr(inFinal, flushBlock, exitBlock);
53   
54    iBuilder->SetInsertPoint(flushBlock);
55    Value * basePtr = getScalarField(self, "bufferBasePtr");
56    //iBuilder->CallPrintInt("bufferBasePtr", iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty()));
57    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
58    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
59    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
60   
61    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
62    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
63    iBuilder->CreateRet(basePtr);
64
65    iBuilder->SetInsertPoint(exitBlock);
66    iBuilder->CreateRet(bufferPtr);
67    iBuilder->restoreIP(savePoint);
68}
69
70void stdOutKernel::generateFinalBlockMethod() {
71    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
72    Module * m = iBuilder->getModule();
73    Function * writefn = create_write(m);
74    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
75    Type * i8PtrTy = iBuilder->getInt8PtrTy();
76   
77    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_flush", finalBlockFunction, 0));
78    Value * self = getParameter(finalBlockFunction, "self");
79    Value * bufferPtr = getParameter(finalBlockFunction, "bufferPtr");
80    Value * basePtr = getScalarField(self, "bufferBasePtr");
81    // Flush the output.
82    Value * baseAddress = iBuilder->CreatePtrToInt(basePtr, iBuilder->getInt64Ty());
83    Value * pointerAddress = iBuilder->CreatePtrToInt(bufferPtr, iBuilder->getInt64Ty());
84    Value * bytesToFlush = iBuilder->CreateSub(pointerAddress, baseAddress);
85   
86    iBuilder->CreateCall(writefn, std::vector<Value *>({iBuilder->getInt32(1), iBuilder->CreateBitCast(basePtr, i8PtrTy), bytesToFlush}));
87    // Buffer is flushed, return the buffer base pointer for subsequent output to the buffer.
88    iBuilder->CreateRet(basePtr);
89    iBuilder->restoreIP(savePoint);
90}
91}
Note: See TracBrowser for help on using the repository browser.