source: icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp @ 5126

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

Add getStride to IDISA builders; allows Stride > BlockSize? on GPU

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
6
7#include <toolchain.h>
8#include "pipeline.h"
9#include "utf_encoding.h"
10
11#include <IDISA/idisa_builder.h>
12
13#include <kernels/interface.h>
14#include <kernels/kernel.h>
15#include <kernels/s2p_kernel.h>
16
17
18using namespace kernel;
19
20
21void generatePipelineLoop(IDISA::IDISA_Builder * iBuilder, std::vector<KernelBuilder *> kernels, std::vector<Value *> instances, Value * fileSize) {
22   
23    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
24    Function * main = entryBlock->getParent();
25       
26    const unsigned segmentSize = codegen::SegmentSize;
27    Type * const size_ty = iBuilder->getSizeTy();
28
29    // Create the basic blocks for the loop.
30    BasicBlock * segmentCondBlock = nullptr;
31    BasicBlock * segmentBodyBlock = nullptr;
32    if (segmentSize > 1) {
33        segmentCondBlock = BasicBlock::Create(iBuilder->getContext(), "segmentCond", main, 0);
34        segmentBodyBlock = BasicBlock::Create(iBuilder->getContext(), "segmentBody", main, 0);
35    }
36    BasicBlock * fullCondBlock = BasicBlock::Create(iBuilder->getContext(), "fullCond", main, 0);
37    BasicBlock * fullBodyBlock = BasicBlock::Create(iBuilder->getContext(), "fullBody", main, 0);
38    BasicBlock * finalBlock = BasicBlock::Create(iBuilder->getContext(), "final", main, 0);
39   
40   
41    Value * initialBufferSize = nullptr;
42    Value * initialBlockNo = nullptr;
43    BasicBlock * initialBlock = nullptr;
44    Value * rslt = nullptr;
45   
46    if (segmentSize > 1) {
47        iBuilder->CreateBr(segmentCondBlock);
48        iBuilder->SetInsertPoint(segmentCondBlock);
49        PHINode * remainingBytes = iBuilder->CreatePHI(size_ty, 2, "remainingBytes");
50        remainingBytes->addIncoming(fileSize, entryBlock);
51        PHINode * blockNo = iBuilder->CreatePHI(size_ty, 2, "blockNo");
52        blockNo->addIncoming(ConstantInt::get(size_ty, 0), entryBlock);
53       
54        Constant * const step = ConstantInt::get(size_ty, iBuilder->getStride() * segmentSize);
55        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
56        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
57       
58        iBuilder->SetInsertPoint(segmentBodyBlock);
59        Value * segBlocks = ConstantInt::get(size_ty, segmentSize);
60        for (unsigned i = 0; i < kernels.size(); i++) {
61            kernels[i]->createDoSegmentCall(instances[i], segBlocks);
62        }
63        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
64        blockNo->addIncoming(iBuilder->CreateAdd(blockNo, segBlocks), segmentBodyBlock);
65       
66        iBuilder->CreateBr(segmentCondBlock);
67        initialBufferSize = remainingBytes;
68        initialBlockNo = blockNo;
69        initialBlock = segmentCondBlock;
70    } else {
71        initialBufferSize = fileSize;
72        initialBlockNo = ConstantInt::get(size_ty, 0);
73        initialBlock = entryBlock;
74        iBuilder->CreateBr(fullCondBlock);
75    }
76   
77    iBuilder->SetInsertPoint(fullCondBlock);
78    PHINode * remainingBytes = iBuilder->CreatePHI(size_ty, 2, "remainingBytes");
79    remainingBytes->addIncoming(initialBufferSize, initialBlock);
80    PHINode * blockNo = iBuilder->CreatePHI(size_ty, 2, "blockNo");
81    blockNo->addIncoming(initialBlockNo, initialBlock);
82   
83    Constant * const step = ConstantInt::get(size_ty, iBuilder->getStride());
84    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
85    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
86   
87    // Full Block Pipeline loop
88    iBuilder->SetInsertPoint(fullBodyBlock);
89    for (unsigned i = 0; i < kernels.size(); i++) {
90        kernels[i]->createDoSegmentCall(instances[i], ConstantInt::get(size_ty, 1));
91    }
92   
93    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
94    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, ConstantInt::get(size_ty, 1)), fullBodyBlock);
95    iBuilder->CreateBr(fullCondBlock);
96   
97    iBuilder->SetInsertPoint(finalBlock);
98    for (unsigned i = 0; i < kernels.size(); i++) {
99        kernels[i]->createFinalBlockCall(instances[i], remainingBytes);
100    }
101}
Note: See TracBrowser for help on using the repository browser.