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

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

Simplify kernel DoBlock? interface

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 int64ty = iBuilder->getInt64Ty();
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   
45    if (segmentSize > 1) {
46        iBuilder->CreateBr(segmentCondBlock);
47        iBuilder->SetInsertPoint(segmentCondBlock);
48        PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
49        remainingBytes->addIncoming(fileSize, entryBlock);
50        PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
51        blockNo->addIncoming(iBuilder->getInt64(0), entryBlock);
52       
53        Constant * const step = ConstantInt::get(int64ty, iBuilder->getBitBlockWidth() * segmentSize);
54        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
55        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
56       
57        iBuilder->SetInsertPoint(segmentBodyBlock);
58        Value * segBlocks = ConstantInt::get(int64ty, segmentSize);
59        for (unsigned i = 0; i < kernels.size(); i++) {
60            kernels[i]->createDoSegmentCall(instances[i], segBlocks);
61        }
62        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
63        blockNo->addIncoming(iBuilder->CreateAdd(blockNo, segBlocks), segmentBodyBlock);
64       
65        iBuilder->CreateBr(segmentCondBlock);
66        initialBufferSize = remainingBytes;
67        initialBlockNo = blockNo;
68        initialBlock = segmentCondBlock;
69    } else {
70        initialBufferSize = fileSize;
71        initialBlockNo = ConstantInt::get(int64ty, 0);
72        initialBlock = entryBlock;
73        iBuilder->CreateBr(fullCondBlock);
74    }
75   
76    iBuilder->SetInsertPoint(fullCondBlock);
77    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
78    remainingBytes->addIncoming(initialBufferSize, initialBlock);
79    PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
80    blockNo->addIncoming(initialBlockNo, initialBlock);
81   
82    Constant * const step = ConstantInt::get(int64ty, iBuilder->getBitBlockWidth());
83    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
84    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
85   
86    // Full Block Pipeline loop
87    iBuilder->SetInsertPoint(fullBodyBlock);
88   
89    for (unsigned i = 0; i < kernels.size(); i++) {
90        kernels[i]->createDoSegmentCall(instances[i], ConstantInt::get(int64ty, 1));
91    }
92   
93    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
94    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), fullBodyBlock);
95    iBuilder->CreateBr(fullCondBlock);
96   
97    iBuilder->SetInsertPoint(finalBlock);
98   
99    for (unsigned i = 0; i < kernels.size(); i++) {
100        kernels[i]->createFinalBlockCall(instances[i], remainingBytes);
101    }
102}
Note: See TracBrowser for help on using the repository browser.