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

Last change on this file since 5385 was 5379, checked in by nmedfort, 3 years ago

Bug fixes for last check in

File size: 4.6 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(Value * /* doFinal */, const std::vector<Value *> & /* producerPos */) {
15
16    BasicBlock * setTermination = CreateBasicBlock("setTermination");
17    BasicBlock * stdInExit = CreateBasicBlock("stdInExit");
18    ConstantInt * segmentBytes = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth());
19    ConstantInt * segmentBytes2 = iBuilder->getSize(2 * mSegmentBlocks * iBuilder->getBitBlockWidth());
20    // on the first segment, we buffer twice the data to ensure the ScanMatch kernel can safely check for a non-LF line break
21    Value * const itemsAlreadyRead = getProducedItemCount("codeUnitBuffer");
22    Value * const bytesToRead = iBuilder->CreateSelect(iBuilder->CreateICmpEQ(itemsAlreadyRead, iBuilder->getSize(0)), segmentBytes2, segmentBytes);
23    reserveBytes("codeUnitBuffer", bytesToRead);
24    Value * const bytePtr = iBuilder->CreatePointerCast(getOutputStreamBlockPtr("codeUnitBuffer", iBuilder->getInt32(0)), iBuilder->getInt8PtrTy());
25    Value * const bytesRead = iBuilder->CreateReadCall(iBuilder->getInt32(STDIN_FILENO), bytePtr, bytesToRead);
26    Value * const itemsRead = iBuilder->CreateAdd(itemsAlreadyRead, iBuilder->CreateUDiv(bytesRead, iBuilder->getSize(mCodeUnitWidth / 8)));
27    setProducedItemCount("codeUnitBuffer", itemsRead);
28    iBuilder->CreateCondBr(iBuilder->CreateICmpEQ(bytesRead, ConstantInt::getNullValue(bytesRead->getType())), setTermination, stdInExit);
29    iBuilder->SetInsertPoint(setTermination);
30    setTerminationSignal();
31    iBuilder->CreateBr(stdInExit);
32    stdInExit->moveAfter(iBuilder->GetInsertBlock());
33    iBuilder->SetInsertPoint(stdInExit);
34}
35
36StdInKernel::StdInKernel(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
37: SegmentOrientedKernel(iBuilder, "stdin_source", {}, {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}}, {}, {}, {})
38, mSegmentBlocks(blocksPerSegment)
39, mCodeUnitWidth(codeUnitWidth) {
40   
41}
42
43void FileSource::generateInitMethod() {
44    BasicBlock * setTerminationOnFailure = CreateBasicBlock("setTerminationOnFailure");
45    BasicBlock * fileSourceInitExit = CreateBasicBlock("fileSourceInitExit");
46    Value * handle = iBuilder->CreateFOpenCall(getScalarField("fileName"), iBuilder->CreateGlobalStringPtr("r"));
47    setScalarField("IOstreamPtr", handle);
48    Value * failure = iBuilder->CreateICmpEQ(iBuilder->CreatePtrToInt(handle, iBuilder->getSizeTy()), iBuilder->getSize(0));
49    iBuilder->CreateCondBr(failure, setTerminationOnFailure, fileSourceInitExit);
50    iBuilder->SetInsertPoint(setTerminationOnFailure);
51    setTerminationSignal();
52    iBuilder->CreateBr(fileSourceInitExit);
53    iBuilder->SetInsertPoint(fileSourceInitExit);
54}
55   
56void FileSource::generateDoSegmentMethod(Value * /* doFinal */, const std::vector<Value *> & /* producerPos */) {
57
58    BasicBlock * closeFile = CreateBasicBlock("closeFile");
59    BasicBlock * fileSourceExit = CreateBasicBlock("fileSourceExit");
60    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
61   
62    Value * produced = getProducedItemCount("codeUnitBuffer");
63    Value * bytePtr = getOutputStreamBlockPtr("codeUnitBuffer", iBuilder->getInt32(0));
64    bytePtr = iBuilder->CreatePointerCast(bytePtr, iBuilder->getInt8PtrTy());
65
66    Value * IOstreamPtr = getScalarField("IOstreamPtr");
67    Value * itemsToDo = iBuilder->getSize(mSegmentBlocks * iBuilder->getBitBlockWidth());
68    Value * nRead = iBuilder->CreateFReadCall(bytePtr, itemsToDo, itemBytes, IOstreamPtr);
69    produced = iBuilder->CreateAdd(produced, nRead);
70    setProducedItemCount("codeUnitBuffer", produced);
71    Value * lessThanFullSegment = iBuilder->CreateICmpULT(nRead, itemsToDo);
72    iBuilder->CreateCondBr(lessThanFullSegment, closeFile, fileSourceExit);
73
74    iBuilder->SetInsertPoint(closeFile);
75    iBuilder->CreateFCloseCall(IOstreamPtr);
76    setTerminationSignal();
77    iBuilder->CreateBr(fileSourceExit);
78   
79    iBuilder->SetInsertPoint(fileSourceExit);
80   
81}
82   
83FileSource::FileSource(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
84: SegmentOrientedKernel(iBuilder, "filesink", {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "codeUnitBuffer"}}, {},
85                {Binding{iBuilder->getInt8PtrTy(), "fileName"}}, {}, {Binding{iBuilder->getFILEptrTy(), "IOstreamPtr"}})
86, mSegmentBlocks(blocksPerSegment)
87, mCodeUnitWidth(codeUnitWidth) {
88}
89
90}
Note: See TracBrowser for help on using the repository browser.