source: icGREP/icgrep-devel/icgrep/u8u16.cpp @ 5079

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

Minor u8u16 updates, 8-bit p2sKernel with compressed output

File size: 18.8 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 *  icgrep is a trademark of International Characters.
5 */
6
7#include <string>
8#include <iostream>
9#include <fstream>
10#include <sstream>
11
12#include <llvm/IR/Function.h>
13#include <llvm/IR/Module.h>
14#include <llvm/ExecutionEngine/ExecutionEngine.h>
15#include <llvm/ExecutionEngine/MCJIT.h>
16#include <llvm/IRReader/IRReader.h>
17#include <llvm/IR/Verifier.h>
18#include <llvm/Support/Debug.h>
19
20#include <llvm/Support/CommandLine.h>
21
22#include <toolchain.h>
23#include <re/re_cc.h>
24#include <cc/cc_compiler.h>
25#include <pablo/pablo_toolchain.h>
26#include <pablo/pablo_kernel.h>
27#include <pablo/function.h>
28#include <IDISA/idisa_builder.h>
29#include <IDISA/idisa_target.h>
30#include <kernels/interface.h>
31#include <kernels/kernel.h>
32#include <kernels/s2p_kernel.h>
33#include <kernels/p2s_kernel.h>
34#include <kernels/deletion.h>
35#include <kernels/stdout_kernel.h>
36
37#include <utf_encoding.h>
38
39// mmap system
40#include <boost/filesystem.hpp>
41#include <boost/iostreams/device/mapped_file.hpp>
42using namespace boost::iostreams;
43using namespace boost::filesystem;
44
45#include <fcntl.h>
46static cl::OptionCategory u8u16Options("u8u16 Options",
47                                            "Transcoding control options.");
48
49static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore, cl::cat(u8u16Options));
50
51//
52//
53//
54namespace pablo {
55
56PabloFunction * u8u16_pablo(const Encoding encoding) {
57    //  input: 8 basis bit streams
58    //  output: 16 u8-indexed streams, + delmask stream + error stream
59    PabloFunction * function = PabloFunction::Create("u8u16", 8, 18);
60    cc::CC_Compiler ccc(*function, encoding);
61   
62    PabloBuilder pBuilder(ccc.getBuilder().getPabloBlock(), ccc.getBuilder());
63    const std::vector<Var *> u8_bits = ccc.getBasisBits();
64    // Outputs
65    Assign * u16_hi[8];
66    Assign * u16_lo[8];
67    Assign * delmask;
68    Assign * error_mask;
69   
70    // The logic for processing non-ASCII bytes is to be embedded within an if-hierarchy.
71    PabloAST * nonASCII = ccc.compileCC(re::makeCC(0x80, 0xFF));
72   
73    // Builder for the if statement handling all non-ASCII logic
74    PabloBuilder nAb = PabloBuilder::Create(pBuilder);
75    // Bits 3 through 7 of a 2-byte prefix are data bits, needed to
76    // produce the UTF-16 code unit data ...,
77    PabloAST * bit3a1 = nAb.createAdvance(u8_bits[3], 1);
78    PabloAST * bit4a1 = nAb.createAdvance(u8_bits[4], 1);
79    PabloAST * bit5a1 = nAb.createAdvance(u8_bits[5], 1);
80    PabloAST * bit6a1 = nAb.createAdvance(u8_bits[6], 1);
81    PabloAST * bit7a1 = nAb.createAdvance(u8_bits[7], 1);
82   
83    // Entry condition for 3 or 4 byte sequences: we have a prefix byte in the range 0xE0-0xFF.
84    PabloAST * pfx34 = ccc.compileCC(re::makeCC(0xE0, 0xFF), nAb);
85    // Builder for the if statement handling all logic for 3- and 4-byte sequences.
86    PabloBuilder p34b = PabloBuilder::Create(nAb);
87    // Bits 4 through 7 of a 3-byte prefix are data bits.  They must be moved
88    // to the final position of the 3-byte sequence.
89    PabloAST * bit2a1 = p34b.createAdvance(u8_bits[2], 1);
90    PabloAST * bit4a2 = p34b.createAdvance(bit4a1, 1);
91    PabloAST * bit5a2 = p34b.createAdvance(bit5a1, 1);
92    PabloAST * bit6a2 = p34b.createAdvance(bit6a1, 1);
93    PabloAST * bit7a2 = p34b.createAdvance(bit7a1, 1);
94    //
95    // Logic for 4-byte UTF-8 sequences
96    //
97    // Entry condition  or 4 byte sequences: we have a prefix byte in the range 0xF0-0xFF.
98    PabloAST * pfx4 = ccc.compileCC(re::makeCC(0xF0, 0xFF), p34b);
99    // Builder for the if statement handling all logic for 4-byte sequences only.
100    PabloBuilder p4b = PabloBuilder::Create(p34b);
101    // Illegal 4-byte sequences
102    PabloAST * F0 = ccc.compileCC(re::makeCC(0xF0), p4b);
103    PabloAST * F4 = ccc.compileCC(re::makeCC(0xF4), p4b);
104    PabloAST * F0_err = p4b.createAnd(p4b.createAdvance(F0, 1), ccc.compileCC(re::makeCC(0x80, 0x8F), p4b));
105    PabloAST * F4_err = p4b.createAnd(p4b.createAdvance(F4, 1), ccc.compileCC(re::makeCC(0x90, 0xBF), p4b));
106    PabloAST * F5_FF = ccc.compileCC(re::makeCC(0xF5, 0xFF), p4b);
107    Assign * FX_err = p4b.createAssign("FX_err", p4b.createOr(F5_FF, p4b.createOr(F0_err, F4_err)));
108    //
109    // 4-byte prefixes have a scope that extends over the next 3 bytes.
110    Assign * u8scope42 = p4b.createAssign("u8scope42", p4b.createAdvance(pfx4, 1));
111    Assign * u8scope43 = p4b.createAssign("u8scope43", p4b.createAdvance(u8scope42, 1));
112    Assign * u8scope44 = p4b.createAssign("u8scope44", p4b.createAdvance(u8scope43, 1));
113    //
114   
115    //  From the 4-byte sequence 11110abc 10defghi 10jklmno 10pqrstu,
116    //  we must calculate the value abcde - 1 to produce the bit values
117    //  for u16_hi6, hi7, lo0, lo1 at the scope43 position.
118    Assign * s43_lo1 = p4b.createAssign("scope43_lo1", p4b.createAnd(u8scope43, p4b.createNot(bit3a1)));           // e - 1
119    Assign * s43_lo0 = p4b.createAssign("scope43_lo0", p4b.createAnd(u8scope43, p4b.createXor(bit2a1, s43_lo1)));  // d - borrow
120    PabloAST * brw1 = p4b.createAnd(s43_lo1, p4b.createNot(bit2a1));
121    Assign * s43_hi7 = p4b.createAssign("scope43_hi7", p4b.createAnd(u8scope43, p4b.createXor(bit7a2, brw1)));     // c - borrow
122    PabloAST * brw2 = p4b.createAnd(brw1, p4b.createNot(bit7a2));
123    Assign * s43_hi6 = p4b.createAssign("scope43_hi6", p4b.createAnd(u8scope43, p4b.createXor(bit6a2, brw2)));     // b - borrow
124    //
125    Assign * s43_lo2 = p4b.createAssign("scope43_lo2", p4b.createAnd(u8scope43, bit4a1));
126    Assign * s43_lo3 = p4b.createAssign("scope43_lo3", p4b.createAnd(u8scope43, bit5a1));
127    Assign * s43_lo4 = p4b.createAssign("scope43_lo4", p4b.createAnd(u8scope43, bit6a1));
128    Assign * s43_lo5 = p4b.createAssign("scope43_lo5", p4b.createAnd(u8scope43, bit7a1));
129    Assign * s43_lo6 = p4b.createAssign("scope43_lo6", p4b.createAnd(u8scope43, u8_bits[2]));
130    Assign * s43_lo7 = p4b.createAssign("scope43_lo7", p4b.createAnd(u8scope43, u8_bits[3]));
131    //
132    //
133    p34b.createIf(pfx4,
134                  {FX_err, u8scope42, u8scope43, u8scope44, s43_hi6, s43_hi7,
135                   s43_lo0, s43_lo1, s43_lo2, s43_lo3, s43_lo4, s43_lo5, s43_lo6, s43_lo7},
136                   p4b);
137    //
138    // Combined logic for 3 and 4 byte sequences
139    //
140    PabloAST * pfx3 = ccc.compileCC(re::makeCC(0xE0, 0xEF), p34b);
141    Assign * u8scope32 = p34b.createAssign("u8scope32", p34b.createAdvance(pfx3, 1));
142    Assign * u8scope33 = p34b.createAssign("u8scope33", p34b.createAdvance(u8scope32, 1));
143
144    // Illegal 3-byte sequences
145    PabloAST * E0 = ccc.compileCC(re::makeCC(0xE0), p34b);
146    PabloAST * ED = ccc.compileCC(re::makeCC(0xED), p34b);
147    PabloAST * E0_err = p34b.createAnd(p34b.createAdvance(E0, 1), ccc.compileCC(re::makeCC(0x80, 0x9F), p34b));
148    PabloAST * ED_err = p34b.createAnd(p34b.createAdvance(ED, 1), ccc.compileCC(re::makeCC(0xA0, 0xBF), p34b));
149    Assign * EX_FX_err = p34b.createAssign("EX_FX_err", p34b.createOr(p34b.createOr(E0_err, ED_err), FX_err));
150    // Two surrogate UTF-16 units are computed at the 3rd and 4th positions of 4-byte sequences.
151    PabloAST * surrogate = p34b.createOr(u8scope43, u8scope44);
152   
153    Assign * p34del = p34b.createAssign("p34del", p34b.createOr(u8scope32, u8scope42));
154
155
156    // The high 5 bits of the UTF-16 code unit are only nonzero for 3 and 4-byte
157    // UTF-8 sequences.
158    u16_hi[0] = p34b.createAssign("u16_hi0", p34b.createOr(p34b.createAnd(u8scope33, bit4a2), surrogate));
159    u16_hi[1] = p34b.createAssign("u16_hi1", p34b.createOr(p34b.createAnd(u8scope33, bit5a2), surrogate));
160    u16_hi[2] = p34b.createAssign("u16_hi2", p34b.createAnd(u8scope33, bit6a2));
161    u16_hi[3] = p34b.createAssign("u16_hi3", p34b.createOr(p34b.createAnd(u8scope33, bit7a2), surrogate));
162    u16_hi[4] = p34b.createAssign("u16_hi4", p34b.createOr(p34b.createAnd(u8scope33, bit2a1), surrogate));
163   
164    //
165    nAb.createIf(pfx34, 
166                 {u8scope33, EX_FX_err, p34del, 
167                  u16_hi[0], u16_hi[1], u16_hi[2], u16_hi[3], u16_hi[4], u8scope44, s43_hi6, s43_hi7,
168                  s43_lo0, s43_lo1, s43_lo2, s43_lo3, s43_lo4, s43_lo5, s43_lo6, s43_lo7},
169                 p34b);
170    //
171    // Combined logic for 2, 3 and 4 byte sequences
172    //
173    PabloAST * pfx2 = ccc.compileCC(re::makeCC(0xC0, 0xDF), nAb);
174    PabloAST * u8scope22 = nAb.createAdvance(pfx2, 1);
175    Assign * u8lastscope = nAb.createAssign("u8lastscope", nAb.createOr(u8scope22, nAb.createOr(u8scope33, u8scope44)));
176    PabloAST * u8anyscope = nAb.createOr(u8lastscope, p34del);
177
178    PabloAST * C0_C1_err = ccc.compileCC(re::makeCC(0xC0, 0xC1), nAb);
179    PabloAST * scope_suffix_mismatch = nAb.createXor(u8anyscope, ccc.compileCC(re::makeCC(0x80, 0xBF), nAb));
180    error_mask = nAb.createAssign("errormask", nAb.createOr(scope_suffix_mismatch, nAb.createOr(C0_C1_err, EX_FX_err)));
181    delmask = nAb.createAssign("delmask", nAb.createOr(p34del, ccc.compileCC(re::makeCC(0xC0, 0xFF), nAb)));
182   
183    // The low 3 bits of the high byte of the UTF-16 code unit as well as the high bit of the
184    // low byte are only nonzero for 2, 3 and 4 byte sequences.
185    u16_hi[5] = nAb.createAssign("u16_hi5", nAb.createOr(nAb.createAnd(u8lastscope, bit3a1), u8scope44));
186    u16_hi[6] = nAb.createAssign("u16_hi6", nAb.createOr(nAb.createAnd(u8lastscope, bit4a1), s43_hi6));
187    u16_hi[7] = nAb.createAssign("u16_hi7", nAb.createOr(nAb.createAnd(u8lastscope, bit5a1), s43_hi7));
188    u16_lo[0] = nAb.createAssign("u16_lo0", nAb.createOr(nAb.createAnd(u8lastscope, bit6a1), s43_lo0));
189    Assign * p234_lo1 = nAb.createAssign("p234_lo1", nAb.createOr(nAb.createAnd(u8lastscope, bit7a1), s43_lo1));
190
191    pBuilder.createIf(nonASCII, 
192                      {error_mask, delmask, u8lastscope,
193                       u16_hi[0], u16_hi[1], u16_hi[2], u16_hi[3], u16_hi[4], u16_hi[5], u16_hi[6], u16_hi[7],
194                       u16_lo[0], p234_lo1, s43_lo2, s43_lo3, s43_lo4, s43_lo5, s43_lo6, s43_lo7},
195                      nAb);
196    //
197    //
198    PabloAST * ASCII = ccc.compileCC(re::makeCC(0x0, 0x7F));
199    PabloAST * last_byte = pBuilder.createOr(ASCII, u8lastscope);
200    u16_lo[1] = pBuilder.createAssign("u16_lo1", pBuilder.createOr(pBuilder.createAnd(ASCII, u8_bits[1]), p234_lo1));
201    u16_lo[2] = pBuilder.createAssign("u16_lo2", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[2]), s43_lo2));
202    u16_lo[3] = pBuilder.createAssign("u16_lo3", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[3]), s43_lo3));
203    u16_lo[4] = pBuilder.createAssign("u16_lo4", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[4]), s43_lo4));
204    u16_lo[5] = pBuilder.createAssign("u16_lo5", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[5]), s43_lo5));
205    u16_lo[6] = pBuilder.createAssign("u16_lo6", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[6]), s43_lo6));
206    u16_lo[7] = pBuilder.createAssign("u16_lo7", pBuilder.createOr(pBuilder.createAnd(last_byte, u8_bits[7]), s43_lo7));
207   
208    for (unsigned i = 0; i < 8; i++) {
209        function->setResult(i, pBuilder.createAssign("u16_hi" + std::to_string(i), u16_hi[i]));
210        function->setResult(i+8, pBuilder.createAssign("u16_lo" + std::to_string(i), u16_lo[i]));
211    }
212    function->setResult(16, pBuilder.createAssign("delbits", delmask));
213    function->setResult(17, pBuilder.createAssign("errors", error_mask));
214
215    return function;
216}
217}
218
219
220
221using namespace kernel;
222
223const unsigned u16OutputBlocks = 64;
224
225Function * u8u16Pipeline(Module * mMod, IDISA::IDISA_Builder * iBuilder, pablo::PabloFunction * function) {
226    Type * mBitBlockType = iBuilder->getBitBlockType();
227    unsigned mBlockSize = iBuilder->getBitBlockWidth();
228    s2pKernel  s2pk(iBuilder);
229    s2pk.generateKernel();
230   
231    pablo_function_passes(function);
232    pablo::PabloKernel  u8u16k(iBuilder, "u8u16", function, {});
233    u8u16k.generateKernel();
234   
235    deletionKernel delK(iBuilder, iBuilder->getBitBlockWidth()/16, 16);
236    delK.generateKernel();
237   
238    p2s_16Kernel_withCompressedOutput p2sk(iBuilder);   
239    p2sk.generateKernel();
240   
241    stdOutKernel stdOutK(iBuilder, 16);
242    stdOutK.generateKernel();
243   
244    Type * const int64ty = iBuilder->getInt64Ty();
245    Type * i16PtrTy = PointerType::get(iBuilder->getInt16Ty(), 0);
246    Type * const voidTy = Type::getVoidTy(mMod->getContext());
247    Type * const inputType = PointerType::get(ArrayType::get(ArrayType::get(mBitBlockType, 8), 1), 0);
248   
249    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", voidTy, inputType, int64ty, nullptr));
250    main->setCallingConv(CallingConv::C);
251    Function::arg_iterator args = main->arg_begin();
252   
253    Value * const inputStream = &*(args++);
254    inputStream->setName("input");
255    Value * const bufferSize = &*(args++);
256    bufferSize->setName("bufferSize");
257   
258    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
259   
260    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
261   
262    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
263    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
264    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
265   
266    StreamSetBuffer ByteStream(iBuilder, StreamSetType(1, 8), 0);
267    StreamSetBuffer BasisBits(iBuilder, StreamSetType(8, 1), 1);
268    StreamSetBuffer U8u16Bits(iBuilder, StreamSetType(18, 1), 1);
269    StreamSetBuffer U16Bits(iBuilder, StreamSetType(16, 1), 1);
270    StreamSetBuffer DeletionCounts(iBuilder, StreamSetType(1, 1), 1);
271    StreamSetBuffer U16out(iBuilder, StreamSetType(1, 16), u16OutputBlocks);
272
273    ByteStream.setStreamSetBuffer(inputStream);
274    Value * basisBits = BasisBits.allocateBuffer();
275    Value * u8u16Bits = U8u16Bits.allocateBuffer();
276    Value * u16Bits = U16Bits.allocateBuffer();
277    Value * delCounts = DeletionCounts.allocateBuffer();
278    Value * u16out = U16out.allocateBuffer();
279   
280    Value * s2pInstance = s2pk.createInstance({});
281    Value * u8u16Instance = u8u16k.createInstance({});
282    Value * delInstance = delK.createInstance({});
283    Value * p2sInstance = p2sk.createInstance({});
284    Value * stdOutInstance = stdOutK.createInstance({u16out, iBuilder->CreateGEP(u16out, {iBuilder->getInt32(u16OutputBlocks-2)})});
285   
286    Value * initialBufferSize = bufferSize;
287    BasicBlock * initialBlock = entryBlock;
288    Value * initialBlockNo = iBuilder->getInt64(0);
289   
290    iBuilder->CreateBr(fullCondBlock);
291   
292   
293    iBuilder->SetInsertPoint(fullCondBlock);
294    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
295    remainingBytes->addIncoming(initialBufferSize, initialBlock);
296    PHINode * blockNo = iBuilder->CreatePHI(int64ty, 2, "blockNo");
297    blockNo->addIncoming(initialBlockNo, initialBlock);
298    PHINode * outputBuffer = iBuilder->CreatePHI(PointerType::get(U16out.getStreamSetBlockType(), 0), 2, "outputBuffer");
299    outputBuffer->addIncoming(u16out, initialBlock);
300   
301    Constant * const step = ConstantInt::get(int64ty, mBlockSize);
302    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
303    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
304   
305    iBuilder->SetInsertPoint(fullBodyBlock);
306   
307    s2pk.createDoBlockCall(s2pInstance, {ByteStream.getBlockPointer(blockNo), basisBits});
308    u8u16k.createDoBlockCall(u8u16Instance, {basisBits, u8u16Bits});
309    delK.createDoBlockCall(delInstance, {u8u16Bits, u16Bits, delCounts});
310    Value * units_generated = p2sk.createDoBlockCall(p2sInstance, {u16Bits, delCounts, outputBuffer});
311    Value * u16out_next = iBuilder->CreateBitCast(iBuilder->CreateGEP(iBuilder->CreateBitCast(outputBuffer, i16PtrTy), units_generated), outputBuffer->getType());
312    u16out_next = stdOutK.createDoBlockCall(stdOutInstance, {u16out_next});
313   
314    Value * diff = iBuilder->CreateSub(remainingBytes, step);
315   
316    remainingBytes->addIncoming(diff, fullBodyBlock);
317    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), fullBodyBlock);
318    outputBuffer->addIncoming(u16out_next, fullBodyBlock);
319    iBuilder->CreateBr(fullCondBlock);
320   
321    iBuilder->SetInsertPoint(finalBlock);
322    s2pk.createFinalBlockCall(s2pInstance, remainingBytes, {ByteStream.getBlockPointer(blockNo), basisBits});
323    u8u16k.createFinalBlockCall(u8u16Instance, remainingBytes, {basisBits, u8u16Bits});
324    delK.createFinalBlockCall(delInstance, remainingBytes, {u8u16Bits, u16Bits, delCounts});
325    units_generated = p2sk.createFinalBlockCall(p2sInstance, remainingBytes, {u16Bits, delCounts, outputBuffer});
326    u16out_next = iBuilder->CreateBitCast(iBuilder->CreateGEP(iBuilder->CreateBitCast(outputBuffer, i16PtrTy), units_generated), outputBuffer->getType());
327    stdOutK.createFinalBlockCall(stdOutInstance, remainingBytes, {u16out_next});
328
329    iBuilder->CreateRetVoid();
330    return main;
331}
332
333
334
335
336
337typedef void (*u8u16FunctionType)(char * byte_data, size_t filesize);
338
339static ExecutionEngine * u8u16Engine = nullptr;
340
341u8u16FunctionType u8u16CodeGen(void) {
342                           
343    Module * M = new Module("u8u16", getGlobalContext());
344    IDISA::IDISA_Builder * idb = IDISA::GetIDISA_Builder(M);
345
346    Encoding encoding(Encoding::Type::UTF_8, 8);
347    pablo::PabloFunction * function = pablo::u8u16_pablo(encoding);
348   
349    llvm::Function * main_IR = u8u16Pipeline(M, idb, function);
350   
351    verifyModule(*M, &dbgs());
352    //std::cerr << "ExecuteKernels(); done\n";
353    u8u16Engine = JIT_to_ExecutionEngine(M);
354   
355    u8u16Engine->finalizeObject();
356    //std::cerr << "finalizeObject(); done\n";
357
358    delete idb;
359    return reinterpret_cast<u8u16FunctionType>(u8u16Engine->getPointerToFunction(main_IR));
360}
361
362void u8u16(u8u16FunctionType fn_ptr, const std::string & fileName) {
363    std::string mFileName = fileName;
364    size_t mFileSize;
365    char * mFileBuffer;
366   
367    const path file(mFileName);
368    if (exists(file)) {
369        if (is_directory(file)) {
370            return;
371        }
372    } else {
373        std::cerr << "Error: cannot open " << mFileName << " for processing. Skipped.\n";
374        return;
375    }
376   
377    mFileSize = file_size(file);
378    mapped_file_source mFile;
379    if (mFileSize == 0) {
380        mFileBuffer = nullptr;
381    }
382    else {
383        try {
384            mFile.open(mFileName);
385        } catch (std::exception &e) {
386            std::cerr << "Error: Boost mmap of " << mFileName << ": " << e.what() << std::endl;
387            return;
388        }
389        mFileBuffer = const_cast<char *>(mFile.data());
390    }
391    //std::cerr << "mFileSize =" << mFileSize << "\n";
392    //std::cerr << "fn_ptr =" << std::hex << reinterpret_cast<intptr_t>(fn_ptr) << "\n";
393
394    fn_ptr(mFileBuffer, mFileSize);
395
396    mFile.close();
397   
398}
399
400
401int main(int argc, char *argv[]) {
402    cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>{&u8u16Options, pablo::pablo_toolchain_flags(), codegen::codegen_flags()});
403    cl::ParseCommandLineOptions(argc, argv);
404
405    u8u16FunctionType fn_ptr = u8u16CodeGen();
406
407    for (unsigned i = 0; i != inputFiles.size(); ++i) {
408        u8u16(fn_ptr, inputFiles[i]);
409    }
410
411    delete u8u16Engine;
412
413    return 0;
414}
415
416                       
Note: See TracBrowser for help on using the repository browser.