source: icGREP/icgrep-devel/icgrep/kernels/stdin_kernel.cpp @ 5286

Last change on this file since 5286 was 5286, checked in by nmedfort, 2 years ago

Continuation of work to simplify Kernel writing

File size: 5.5 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#include <kernels/stdin_kernel.h>
6#include <llvm/IR/Module.h>
7#include <kernels/kernel.h>
8#include <IR_Gen/idisa_builder.h>
9
10using namespace llvm;
11
12namespace kernel {
13   
14void StdInKernel::generateDoSegmentMethod(Function *doSegmentFunction, Value *self, Value *doFinal, const std::vector<Value *> &producerPos) const {
15
16    Type * i8PtrTy = iBuilder->getInt8PtrTy();
17   
18    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
19    BasicBlock * setTermination = BasicBlock::Create(iBuilder->getContext(), "setTermination", doSegmentFunction, 0);
20    BasicBlock * stdInExit = BasicBlock::Create(iBuilder->getContext(), "stdInExit", doSegmentFunction, 0);
21    ConstantInt * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
22    ConstantInt * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
23    ConstantInt * segmentBytes = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth() * mCodeUnitWidth/8);
24    ConstantInt * stdin_fileno = iBuilder->getInt32(STDIN_FILENO);
25    Value * produced = getProducedItemCount(self, "codeUnitBuffer");
26    Value * blockNo = iBuilder->CreateUDiv(produced, blockItems);
27    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(produced, blockItems), itemBytes);
28    Value * bytePtr = getStreamView(i8PtrTy, self, "codeUnitBuffer", blockNo, byteOffset);
29   
30    Value * nRead = iBuilder->CreateReadCall(stdin_fileno, bytePtr, segmentBytes);
31    Value * bytesRead = iBuilder->CreateSelect(iBuilder->CreateICmpSLT(nRead, iBuilder->getSize(0)), iBuilder->getSize(0), nRead);
32    produced = iBuilder->CreateAdd(produced, iBuilder->CreateUDiv(bytesRead, itemBytes));
33    setProducedItemCount(self, "codeUnitBuffer", produced);
34    Value * lessThanFullSegment = iBuilder->CreateICmpULT(bytesRead, segmentBytes);
35    iBuilder->CreateCondBr(lessThanFullSegment, setTermination, stdInExit);
36    iBuilder->SetInsertPoint(setTermination);
37    setTerminationSignal(self);
38    iBuilder->CreateBr(stdInExit);
39   
40    iBuilder->SetInsertPoint(stdInExit);
41
42   
43}
44
45StdInKernel::StdInKernel(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
46: SegmentOrientedKernel(iBuilder, "stdin_source", {}, {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}}, {}, {}, {})
47, mSegmentBlocks(blocksPerSegment)
48, mCodeUnitWidth(codeUnitWidth) {
49   
50}
51
52void FileSource::generateInitMethod(Function * initFunction, Value * self) const {
53    BasicBlock * setTerminationOnFailure = BasicBlock::Create(iBuilder->getContext(), "setTerminationOnFailure", initFunction, 0);
54    BasicBlock * fileSourceInitExit = BasicBlock::Create(iBuilder->getContext(), "fileSourceInitExit", initFunction, 0);
55    Value * handle = iBuilder->CreateFOpenCall(getScalarField(self, "fileName"), iBuilder->CreateGlobalStringPtr("r"));
56    setScalarField(self, "IOstreamPtr", handle);
57    Value * failure = iBuilder->CreateICmpEQ(iBuilder->CreatePtrToInt(handle, iBuilder->getSizeTy()), iBuilder->getSize(0));
58    iBuilder->CreateCondBr(failure, setTerminationOnFailure, fileSourceInitExit);
59    iBuilder->SetInsertPoint(setTerminationOnFailure);
60    setTerminationSignal(self);
61    iBuilder->CreateBr(fileSourceInitExit);
62    iBuilder->SetInsertPoint(fileSourceInitExit);
63}
64   
65void FileSource::generateDoSegmentMethod(Function * doSegmentFunction, Value *self, Value * doFinal, const std::vector<Value *> & producerPos) const {
66
67    PointerType * i8PtrTy = iBuilder->getInt8PtrTy();
68   
69    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
70    BasicBlock * closeFile = BasicBlock::Create(iBuilder->getContext(), "closeFile", doSegmentFunction, 0);
71    BasicBlock * fileSourceExit = BasicBlock::Create(iBuilder->getContext(), "fileSourceExit", doSegmentFunction, 0);
72    Constant * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
73    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
74   
75    Value * produced = getProducedItemCount(self, "codeUnitBuffer");
76    Value * blockNo = iBuilder->CreateUDiv(produced, blockItems);
77    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(produced, blockItems), itemBytes);
78    Value * bytePtr = getStreamView(i8PtrTy, self, "codeUnitBuffer", blockNo, byteOffset);
79    Value * IOstreamPtr = getScalarField(self, "IOstreamPtr");
80    Value * itemsToDo = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth());
81    Value * nRead = iBuilder->CreateFReadCall(bytePtr, itemsToDo, itemBytes, IOstreamPtr);
82    produced = iBuilder->CreateAdd(produced, nRead);
83    setProducedItemCount(self, "codeUnitBuffer", produced);
84    Value * lessThanFullSegment = iBuilder->CreateICmpULT(nRead, itemsToDo);
85    iBuilder->CreateCondBr(lessThanFullSegment, closeFile, fileSourceExit);
86
87    iBuilder->SetInsertPoint(closeFile);
88    iBuilder->CreateFCloseCall(IOstreamPtr);
89    setTerminationSignal(self);
90    iBuilder->CreateBr(fileSourceExit);
91   
92    iBuilder->SetInsertPoint(fileSourceExit);
93   
94}
95   
96FileSource::FileSource(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
97: SegmentOrientedKernel(iBuilder, "filesink", {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}}, {},
98                {Binding{iBuilder->getInt8PtrTy(), "fileName"}}, {}, {Binding{iBuilder->getFILEptrTy(), "IOstreamPtr"}})
99, mSegmentBlocks(blocksPerSegment)
100, mCodeUnitWidth(codeUnitWidth) {
101}
102
103}
Note: See TracBrowser for help on using the repository browser.