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

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

Changes working towards simplifying accessing stream elements + some modifications to simplify include / forward declarations within the CodeGen? library.

File size: 4.8 KB
RevLine 
[4988]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
[5260]5#include "stdout_kernel.h"
6#include <llvm/IR/Module.h>
[5238]7#include <IR_Gen/idisa_builder.h>
[4988]8
[5260]9using namespace llvm;
10
[4988]11namespace kernel {
12
[5195]13// The doBlock method is deprecated.   But in case it is used, just call doSegment with
[5185]14// 1 as the number of blocks to do.
[5246]15void StdOutKernel::generateDoBlockMethod() const {
[5202]16    auto savePoint = iBuilder->saveIP();
[5076]17    Module * m = iBuilder->getModule();
[5185]18    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
19    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
20    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
21    Value * self = getParameter(doBlockFunction, "self");
[5234]22    iBuilder->CreateCall(doSegmentFunction, {self, iBuilder->getSize(1)});
[5185]23    iBuilder->CreateRetVoid();
24    iBuilder->restoreIP(savePoint);
25}
26           
[5195]27// Rather than using doBlock logic to write one block at a time, this custom
28// doSegment method, writes the entire segment with a single write call.
[5246]29void StdOutKernel::generateDoSegmentMethod() const {
[5202]30    auto savePoint = iBuilder->saveIP();
[5185]31    Module * m = iBuilder->getModule();
32    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
[5076]33    Type * i8PtrTy = iBuilder->getInt8PtrTy();
[5185]34   
35    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
[5246]36    Constant * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
37    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
[5185]38   
39    Function::arg_iterator args = doSegmentFunction->arg_begin();
40    Value * self = &*(args++);
41    Value * blocksToDo = &*(args);
42    ////iBuilder->CallPrintInt("blocksToDo", blocksToDo);
43    Value * streamStructPtr = getStreamSetStructPtr(self, "codeUnitBuffer");
44    //iBuilder->CallPrintInt("streamStructPtr", iBuilder->CreatePtrToInt(streamStructPtr, iBuilder->getInt64Ty()));
[4988]45
[5192]46    LoadInst * producerPos = iBuilder->CreateAtomicLoadAcquire(mStreamSetInputBuffers[0]->getProducerPosPtr(streamStructPtr));
[5185]47    //iBuilder->CallPrintInt("producerPos", producerPos);
[5247]48    Value * processed = getProcessedItemCount(self, "codeUnitBuffer");
[5195]49    Value * itemsAvail = iBuilder->CreateSub(producerPos, processed);
50    Value * itemsMax = iBuilder->CreateMul(blocksToDo, blockItems);
51    Value * lessThanFullSegment = iBuilder->CreateICmpULT(itemsAvail, itemsMax);
52    Value * itemsToDo = iBuilder->CreateSelect(lessThanFullSegment, itemsAvail, itemsMax);
53   
[5188]54    Value * blockNo = getScalarField(self, blockNoScalar);
[5195]55    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(processed, blockItems), itemBytes);
[5260]56    Value * bytePtr = getStreamView(i8PtrTy, self, "codeUnitBuffer", blockNo, byteOffset);
[5243]57    iBuilder->CreateWriteCall(iBuilder->getInt32(1), bytePtr, iBuilder->CreateMul(itemsToDo, itemBytes));
58
[5188]59    processed = iBuilder->CreateAdd(processed, itemsToDo);
[5247]60    setProcessedItemCount(self, "codeUnitBuffer", processed);
[5195]61    setScalarField(self, blockNoScalar, iBuilder->CreateUDiv(processed, blockItems));
[5185]62    mStreamSetInputBuffers[0]->setConsumerPos(streamStructPtr, processed);
[5195]63
[5185]64    iBuilder->CreateRetVoid();
[5076]65    iBuilder->restoreIP(savePoint);
[4988]66}
[5007]67
[5246]68void StdOutKernel::generateFinalBlockMethod() const {
[5202]69    auto savePoint = iBuilder->saveIP();
[5076]70    Module * m = iBuilder->getModule();
71    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
[5260]72    Type * i8PtrTy = iBuilder->getInt8PtrTy();   
[5076]73    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "fb_flush", finalBlockFunction, 0));
[5246]74    Constant * blockItems = iBuilder->getSize(iBuilder->getBitBlockWidth());
75    Constant * itemBytes = iBuilder->getSize(mCodeUnitWidth/8);
[5076]76    Value * self = getParameter(finalBlockFunction, "self");
[5185]77    Value * streamStructPtr = getStreamSetStructPtr(self, "codeUnitBuffer");
[5192]78    LoadInst * producerPos = iBuilder->CreateAtomicLoadAcquire(mStreamSetInputBuffers[0]->getProducerPosPtr(streamStructPtr));
[5247]79    Value * processed = getProcessedItemCount(self, "codeUnitBuffer");
[5185]80    Value * itemsAvail = iBuilder->CreateSub(producerPos, processed);
81    Value * blockNo = getScalarField(self, blockNoScalar);
[5195]82    Value * byteOffset = iBuilder->CreateMul(iBuilder->CreateURem(processed, blockItems), itemBytes);
[5260]83    Value * bytePtr = getStreamView(i8PtrTy, self, "codeUnitBuffer", blockNo, byteOffset);
[5243]84    iBuilder->CreateWriteCall(iBuilder->getInt32(1), bytePtr, iBuilder->CreateMul(itemsAvail, itemBytes));
[5247]85    setProcessedItemCount(self, "codeUnitBuffer", producerPos);
[5185]86    mStreamSetInputBuffers[0]->setConsumerPos(streamStructPtr, producerPos);
[5195]87    setTerminationSignal(self);
[5185]88    iBuilder->CreateRetVoid();
[5076]89    iBuilder->restoreIP(savePoint);
[4988]90}
[5076]91}
Note: See TracBrowser for help on using the repository browser.