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

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

u8u16 progress

File size: 2.9 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#include <kernels/stdout_kernel.h>
6#include <kernels/kernel.h>
7#include <IDISA/idisa_builder.h>
8#include <llvm/IR/TypeBuilder.h>
9
10namespace kernel {
11
12    static Function * create_write(Module * const mod) {
13        Function * write = mod->getFunction("write");
14        if (write == nullptr) {
15            FunctionType *write_type =
16            TypeBuilder<long(int, char *, long), false>::get(mod->getContext());
17            write = cast<Function>(mod->getOrInsertFunction("write", write_type,
18                                                             AttributeSet().addAttribute(mod->getContext(), 2U, Attribute::NoAlias)));
19        }
20        return write;
21    }
22   
23
24void generateStdOutKernel(Module * m, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder, unsigned fw) {
25    LLVMContext & ctxt = m->getContext();
26
27    Type * i32 = iBuilder->getIntNTy(32);
28    Type * i64 = iBuilder->getIntNTy(64);
29   
30    // Insert this declaration in the module (if necessary):  declare i64 @write(i32, i8*, i64)
31    Function * writefn = create_write(m);
32    kBuilder->addInputStream(fw, "byte_pack");
33    // No output streams.
34    kBuilder->addInternalState(i64, "RemainingBytes");
35
36    Function * function = kBuilder->prepareFunction();
37   
38    BasicBlock * full_block_write = BasicBlock::Create(ctxt, "full_block_write", function, 0);
39    BasicBlock * final_block_write = BasicBlock::Create(ctxt, "final_block_write", function, 0);
40    BasicBlock * exit_block = BasicBlock::Create(ctxt, "exit_stdout", function, 0);
41    Value * bytes = iBuilder->CreateLoad(kBuilder->getInternalState("RemainingBytes"));
42
43    Value * input = iBuilder->CreateBitCast(kBuilder->getInputStream(0), iBuilder->getInt8PtrTy());
44    Value * blockSize = ConstantInt::get(i64, iBuilder->getBitBlockWidth());
45
46    Value * fullblock_cond = iBuilder->CreateICmpULT(bytes, blockSize);
47    iBuilder->CreateCondBr(fullblock_cond, final_block_write, full_block_write);
48   
49    iBuilder->SetInsertPoint(full_block_write);
50    Value * outputBytes = ConstantInt::get(i64, iBuilder->getBitBlockWidth() * fw/8);
51    iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
52    Value * remain = iBuilder->CreateSub(bytes, blockSize);
53    kBuilder->setInternalState("RemainingBytes", remain);
54    iBuilder->CreatePtrToInt(remain, iBuilder->getInt64Ty());
55    iBuilder->CreateBr(exit_block);
56   
57    iBuilder->SetInsertPoint(final_block_write);
58    outputBytes = iBuilder->CreateMul(bytes, ConstantInt::get(i64, fw/8));
59    iBuilder->CreateCall(writefn, std::vector<Value *>({ConstantInt::get(i32, 1), input, outputBytes}));
60    kBuilder->setInternalState("RemainingBytes", ConstantInt::getNullValue(i64));
61    iBuilder->CreateBr(exit_block);
62
63   
64    iBuilder->SetInsertPoint(exit_block);
65   
66    kBuilder->finalize();
67}
68
69
70   
71}
Note: See TracBrowser for help on using the repository browser.