source: icGREP/icgrep-devel/icgrep/kernels/alignedprint.cpp @ 5335

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

Continued work on parenthesis matching; addition of Pablo ScanTo? and AdvanceThenScanTo/Thru? statements. Bug fix for Pablo Compiler for escaping variables.

File size: 7.5 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
6#include "alignedprint.h"
7#include <IR_Gen/idisa_builder.h>  // for IDISA_Builder
8
9using namespace llvm;
10
11namespace kernel {
12
13    void p2s_step(IDISA::IDISA_Builder * iBuilder, Value * p0, Value * p1, Value * hi_mask, unsigned shift, Value * &s1, Value * &s0) {
14    Value * t0 = iBuilder->simd_if(1, hi_mask, p0, iBuilder->simd_srli(16, p1, shift));
15    Value * t1 = iBuilder->simd_if(1, hi_mask, iBuilder->simd_slli(16, p0, shift), p1);
16    s1 = iBuilder->esimd_mergeh(8, t1, t0);
17    s0 = iBuilder->esimd_mergel(8, t1, t0);
18}
19
20void p2s(IDISA::IDISA_Builder * iBuilder, Value * p[], Value * s[]) {
21    Value * bit00004444[2];
22    Value * bit22226666[2];
23    Value * bit11115555[2];
24    Value * bit33337777[2];
25    p2s_step(iBuilder, p[0], p[4], iBuilder->simd_himask(8), 4, bit00004444[1], bit00004444[0]);
26    p2s_step(iBuilder, p[1], p[5], iBuilder->simd_himask(8), 4, bit11115555[1], bit11115555[0]);
27    p2s_step(iBuilder, p[2], p[6], iBuilder->simd_himask(8), 4, bit22226666[1], bit22226666[0]);
28    p2s_step(iBuilder, p[3], p[7], iBuilder->simd_himask(8), 4, bit33337777[1], bit33337777[0]);
29    Value * bit00224466[4];
30    Value * bit11335577[4];
31    for (unsigned j = 0; j<2; j++) {
32        p2s_step(iBuilder, bit00004444[j], bit22226666[j],iBuilder->simd_himask(4), 2, bit00224466[2*j+1], bit00224466[2*j]);
33        p2s_step(iBuilder, bit11115555[j], bit33337777[j],iBuilder->simd_himask(4), 2, bit11335577[2*j+1], bit11335577[2*j]);
34    }
35    for (unsigned j = 0; j<4; j++) {
36        p2s_step(iBuilder, bit00224466[j], bit11335577[j], iBuilder->simd_himask(2), 1, s[2*j+1], s[2*j]);
37    }
38}
39
40void PrintableBits::generateDoBlockMethod() {
41    // Load current block
42    Value * bitStrmVal = loadInputStreamBlock("bitStream", iBuilder->getInt32(0));
43
44    Value * bits[8];
45
46    /*
47    00110001 is the Unicode codepoint for '1' and 00101110 is the codepoint for '.'.
48    We want to output a byte stream that is aligned with the input bitstream such that it contains 00110001 in each 1 position and 00101110 in each 0 position.
49   
50    For example, consider input bitstream 101. Our desired output is:
51    00110001 00101110 00110001
52
53    We can do the bitstream to bytestream conversion in parallel by viewing the output stream in terms of parallel bit streams.
54
55    0   0   0 -> First bit position of every byte is all zeros
56    0   0   0 -> Same for second bit
57    1   1   1 -> Third bit is all ones
58    1   0   1 -> 4th bit is 1 for a '1' byte and '0' for a zero byte. Matches input bit stream
59    0   1   0 -> opposite
60    0   1   0 -> opposite
61    0   1   0 -> opposite
62    1   0   1 -> same as 4th bit position.
63   
64    Armed with the above we can do the bit->byte conversion all at once
65    rather than byte at a time! That's what we do below.
66    */
67
68    bits[0] = ConstantInt::getNullValue(iBuilder->getBitBlockType());
69    bits[1] = ConstantInt::getNullValue(iBuilder->getBitBlockType());
70    bits[2] = ConstantInt::getAllOnesValue(iBuilder->getBitBlockType());
71    bits[3] = bitStrmVal;
72    Value * negBitStrmVal = iBuilder->simd_not(bitStrmVal);
73    bits[4] = negBitStrmVal;
74    bits[5] = negBitStrmVal;
75    bits[6] = negBitStrmVal;
76    bits[7] = bitStrmVal;
77   
78    // Reassemble the paralell bit streams into a byte stream
79    Value * printableBytes[8];
80    p2s(iBuilder, bits, printableBytes);
81   
82    for (unsigned j = 0; j < 8; ++j) {
83        storeOutputStreamPack("byteStream", iBuilder->getInt32(0), iBuilder->getInt32(j), iBuilder->bitCast(printableBytes[j]));
84    }
85}
86
87void SelectStream::generateDoBlockMethod() {
88    if (mStreamIndex >= mSizeInputStreamSet)
89        llvm::report_fatal_error("Stream index out of bounds.\n");
90   
91    Value * bitStrmVal = loadInputStreamBlock("bitStreams", iBuilder->getInt32(mStreamIndex));
92
93    storeOutputStreamBlock("bitStream", iBuilder->getInt32(0), bitStrmVal);
94}
95
96void PrintableStreamSet::generateDoBlockMethod() {
97
98    /*
99    00110001 is the Unicode codepoint for '1' and 00101110 is the codepoint for '.'.
100    We want to output a byte stream that is aligned with the input bitstream such that it contains 00110001 in each 1 position and 00101110 in each 0 position.
101
102    For example, consider input bitstream 101. Our desired output is:
103    00110001 00101110 00110001
104
105    We can do the bitstream to bytestream conversion in parallel by viewing the output stream in terms of parallel bit streams.
106
107    0   0   0 -> First bit position of every byte is all zeros
108    0   0   0 -> Same for second bit
109    1   1   1 -> Third bit is all ones
110    1   0   1 -> 4th bit is 1 for a '1' byte and '0' for a zero byte. Matches input bit stream
111    0   1   0 -> opposite
112    0   1   0 -> opposite
113    0   1   0 -> opposite
114    1   0   1 -> same as 4th bit position.
115
116    Armed with the above we can do the bit->byte conversion all at once
117    rather than byte at a time! That's what we do below.
118    */
119
120    BasicBlock * entry = iBuilder->GetInsertBlock();
121    BasicBlock * cond = CreateBasicBlock("cond");
122    BasicBlock * body = CreateBasicBlock("body");
123    BasicBlock * exit = CreateBasicBlock("exit");
124
125    Value * count = getInputStreamSetCount("bitStream");
126    iBuilder->CreateBr(cond);
127    iBuilder->SetInsertPoint(cond);
128    PHINode * i = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "i");
129    i->addIncoming(iBuilder->getSize(0), entry);
130
131    iBuilder->CreateCondBr(iBuilder->CreateICmpNE(i, count), body, exit);
132    iBuilder->SetInsertPoint(body);
133    // Load current block
134    Value * bitStrmVal = loadInputStreamBlock("bitStream", i);
135
136    Value * bits[8];
137
138    bits[0] = ConstantInt::getNullValue(iBuilder->getBitBlockType());
139    bits[1] = ConstantInt::getNullValue(iBuilder->getBitBlockType());
140    bits[2] = ConstantInt::getAllOnesValue(iBuilder->getBitBlockType());
141    bits[3] = bitStrmVal;
142    Value * negBitStrmVal = iBuilder->simd_not(bitStrmVal);
143    bits[4] = negBitStrmVal;
144    bits[5] = negBitStrmVal;
145    bits[6] = negBitStrmVal;
146    bits[7] = bitStrmVal;
147
148    // Reassemble the paralell bit streams into a byte stream
149    Value * printableBytes[8];
150    p2s(iBuilder, bits, printableBytes);
151    for (unsigned j = 0; j < 8; ++j) {
152        storeOutputStreamPack("byteStream", i, iBuilder->getInt32(j), iBuilder->bitCast(printableBytes[j]));
153    }
154
155    i->addIncoming(iBuilder->CreateAdd(i, iBuilder->getSize(1)), iBuilder->GetInsertBlock());
156    iBuilder->CreateBr(cond);
157
158    iBuilder->SetInsertPoint(exit);
159}
160
161PrintableBits::PrintableBits(IDISA::IDISA_Builder * builder)
162: BlockOrientedKernel(builder, "PrintableBits", {Binding{builder->getStreamSetTy(1), "bitStream"}}, {Binding{builder->getStreamSetTy(1, 8), "byteStream"}}, {}, {}, {})
163{
164    setNoTerminateAttribute(true);
165    setDoBlockUpdatesProducedItemCountsAttribute(false);
166}
167
168SelectStream::SelectStream(IDISA::IDISA_Builder * builder, unsigned sizeInputStreamSet, unsigned streamIndex)
169: BlockOrientedKernel(builder, "SelectStream", {Binding{builder->getStreamSetTy(sizeInputStreamSet), "bitStreams"}}, {Binding{builder->getStreamSetTy(1, 1), "bitStream"}}, {}, {}, {}), mSizeInputStreamSet(sizeInputStreamSet), mStreamIndex(streamIndex)
170{
171    setNoTerminateAttribute(true);
172    setDoBlockUpdatesProducedItemCountsAttribute(false);
173
174}
175
176PrintableStreamSet::PrintableStreamSet(IDISA::IDISA_Builder * builder)
177: BlockOrientedKernel(builder, "PrintableStreamSet", {Binding{builder->getStreamSetTy(0), "bitStream"}}, {Binding{builder->getStreamSetTy(0, 8), "byteStream"}}, {}, {}, {}) {
178    setNoTerminateAttribute(true);
179    setDoBlockUpdatesProducedItemCountsAttribute(false);
180}
181
182
183
184}
Note: See TracBrowser for help on using the repository browser.