source: icGREP/icgrep-devel/icgrep/llvm_gen.cpp @ 3935

Last change on this file since 3935 was 3935, checked in by daled, 5 years ago

The parser is now able to parse unicode categories.

File size: 19.8 KB
RevLine 
[3850]1/*
2 *  Copyright (c) 2014 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 "llvm_gen.h"
[3914]8#include "printer_pablos.h"
[3850]9
10extern "C" {
11  void wrapped_print_register(BitBlock bit_block) {
12      print_register<BitBlock>("", bit_block);
13  }
14}
15
16void LLVM_Generator::Print_Register(char *name, BitBlock bit_block)
17{
18    print_register<BitBlock>(name, bit_block);
19}
20
[3914]21LLVM_Generator::LLVM_Generator(std::string basis_pattern, std::string lf_ccname, int bits)
[3850]22{
23    mBasis_Pattern = basis_pattern;
[3914]24    m_lf_ccname = lf_ccname;
[3850]25    mBits = bits;
26}
27
28LLVM_Generator::~LLVM_Generator()
29{
30    delete mMod;
31}
32
33LLVM_Gen_RetVal LLVM_Generator::Generate_LLVMIR(CodeGenState cg_state, std::list<PabloS*> cc_cgo_stmtsl)
34{
35    //Create the module.
36    MakeLLVMModule();
37
[3854]38    //Create the jit execution engine.up
[3850]39    InitializeNativeTarget();
40    std::string ErrStr;
[3914]41
42    mExecutionEngine = EngineBuilder(mMod).setUseMCJIT(true).setErrorStr(&ErrStr).setOptLevel(CodeGenOpt::Level::Less).create();
[3850]43    if (!mExecutionEngine)
44    {
45        std::cout << "\nCould not create ExecutionEngine: " + ErrStr << std::endl;
46        exit(1);
47    }
48
49    InitializeNativeTargetAsmPrinter();
50    InitializeNativeTargetAsmParser();
51
52    DefineTypes();
53    DeclareFunctions();
54
55    Function::arg_iterator args = mFunc_process_block->arg_begin();
56    Value* ptr_basis_bits = args++;
57    ptr_basis_bits->setName("basis_bits");
58    mptr_carry_q = args++;
59    mptr_carry_q->setName("carry_q");
60    Value* ptr_output = args++;
61    ptr_output->setName("output");
62
63    //Create the carry queue.
64    mCarryQueueIdx = 0;
[3914]65    mCarryQueueSize = LLVM_Generator_Helper::CarryCount_PabloStatements(cg_state.stmtsl);
[3850]66
67    mBasicBlock = BasicBlock::Create(mMod->getContext(), "parabix_entry", mFunc_process_block,0);
68
69    //The basis bits structure
70    mPtr_basis_bits_addr = new AllocaInst(mStruct_Basis_Bits_Ptr1, "basis_bits.addr", mBasicBlock);
71    StoreInst* void_14 = new StoreInst(ptr_basis_bits, mPtr_basis_bits_addr, false, mBasicBlock);
72
73    for (int i = 0; i < mBits; i++)
74    {
75        StoreBitBlockMarkerPtr(mBasis_Pattern + INT2STRING(i), i);
76    }
77
78    //The output structure.
79    mPtr_output_addr = new AllocaInst(mStruct_Output_Ptr1, "output.addr", mBasicBlock);
80    StoreInst* void_16 = new StoreInst(ptr_output, mPtr_output_addr, false, mBasicBlock);
81
82    //Generate the IR instructions for the function.
83    Generate_PabloStatements(cc_cgo_stmtsl);
84    Generate_PabloStatements(cg_state.stmtsl);
85    SetReturnMarker(cg_state.newsym, 0);
[3914]86    SetReturnMarker(m_lf_ccname, 1);
[3850]87
88    //Terminate the block
89    ReturnInst::Create(mMod->getContext(), mBasicBlock);
90
91    //Create a verifier.  The verifier will print an error message if our module is malformed in any way.
92    verifyModule(*mMod, PrintMessageAction);
93
94    //Un-comment this line in order to display the IR that has been generated by this module.
95    //mMod->dump();
96
97    //Use the pass manager to run optimizations on the function.
98    FunctionPassManager fpm(mMod);
99
100    // Set up the optimizer pipeline.  Start with registering info about how the target lays out data structures.
101    fpm.add(new DataLayout(*mExecutionEngine->getDataLayout()));
102
[3914]103    fpm.add(createPromoteMemoryToRegisterPass()); //Transform to SSA form.
[3854]104
[3914]105    fpm.add(createBasicAliasAnalysisPass());      //Provide basic AliasAnalysis support for GVN. (Global Value Numbering)
106    fpm.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
107    fpm.add(createCFGSimplificationPass());       //Simplify the control flow graph (deleting unreachable blocks, etc).
108    fpm.add(createReassociatePass());             //Reassociate expressions.
109    fpm.add(createGVNPass());                     //Eliminate common subexpressions.
110
[3850]111    fpm.doInitialization();
112
113    fpm.run(*mFunc_process_block);
114
[3854]115    //mMod->dump();
116
[3850]117    mExecutionEngine->finalizeObject();
118
119    LLVM_Gen_RetVal retVal;
120    //Return the required size of the carry queue and a pointer to the process_block function.
[3914]121    retVal.carry_q_size = mCarryQueueSize;
[3850]122    retVal.process_block_fptr = mExecutionEngine->getPointerToFunction(mFunc_process_block);
123
124    return retVal;
125}
126
127void LLVM_Generator::DefineTypes()
128{
129    //The BitBlock vector.
130    m64x2Vect = VectorType::get(IntegerType::get(mMod->getContext(), 64), 2);
131    //A pointer to the BitBlock vector.
132    m64x2Vect_Ptr1 = PointerType::get(m64x2Vect, 0);
133
134    //Constant definitions.
135    mConst_int64_neg1 = ConstantInt::get(mMod->getContext(), APInt(64, StringRef("-1"), 10));
136
137    mConst_Aggregate_64x2_0 = ConstantAggregateZero::get(m64x2Vect);
138    std::vector<Constant*> const_packed_27_elems;
139    const_packed_27_elems.push_back(mConst_int64_neg1);
140    const_packed_27_elems.push_back(mConst_int64_neg1);
141    mConst_Aggregate_64x2_neg1 = ConstantVector::get(const_packed_27_elems);
142
143
144    StructType *StructTy_struct_Basis_bits = mMod->getTypeByName("struct.Basis_bits");
145    if (!StructTy_struct_Basis_bits) {
146        StructTy_struct_Basis_bits = StructType::create(mMod->getContext(), "struct.Basis_bits");
147    }
148    std::vector<Type*>StructTy_struct_Basis_bits_fields;
149    for (int i = 0; i < mBits; i++)
150    {
151        StructTy_struct_Basis_bits_fields.push_back(m64x2Vect);
152    }
153    if (StructTy_struct_Basis_bits->isOpaque()) {
154        StructTy_struct_Basis_bits->setBody(StructTy_struct_Basis_bits_fields, /*isPacked=*/false);
155    }
156
157    mStruct_Basis_Bits_Ptr1 = PointerType::get(StructTy_struct_Basis_bits, 0);
158
159    std::vector<Type*>FuncTy_0_args;
160    FuncTy_0_args.push_back(mStruct_Basis_Bits_Ptr1);
161
162    //The carry q array.
163    FuncTy_0_args.push_back(m64x2Vect_Ptr1);
164
165    //The output structure.
166    StructType *StructTy_struct_Output = mMod->getTypeByName("struct.Output");
167    if (!StructTy_struct_Output) {
168        StructTy_struct_Output = StructType::create(mMod->getContext(), "struct.Output");
169    }
170    std::vector<Type*>StructTy_struct_Output_fields;
171    StructTy_struct_Output_fields.push_back(m64x2Vect);
172    StructTy_struct_Output_fields.push_back(m64x2Vect);
173    if (StructTy_struct_Output->isOpaque()) {
174        StructTy_struct_Output->setBody(StructTy_struct_Output_fields, /*isPacked=*/false);
175    }
176    mStruct_Output_Ptr1 = PointerType::get(StructTy_struct_Output, 0);
177
178    //The &output parameter.
179    FuncTy_0_args.push_back(mStruct_Output_Ptr1);
180
181    mFuncTy_0 = FunctionType::get(
182     /*Result=*/Type::getVoidTy(mMod->getContext()),
183     /*Params=*/FuncTy_0_args,
184     /*isVarArg=*/false);
185}
186
187void LLVM_Generator::DeclareFunctions()
188{
189    //This function can be used for testing to print the contents of a register from JIT'd code to the terminal window.
190    mFunc_print_register = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(getGlobalContext()), m64x2Vect, NULL);
191    mExecutionEngine->addGlobalMapping(cast<GlobalValue>(mFunc_print_register), (void *)&wrapped_print_register);
192
193    SmallVector<AttributeSet, 4> Attrs;
194    AttributeSet PAS;
195    {
196        AttrBuilder B;
197        B.addAttribute(Attribute::ReadOnly);
198        B.addAttribute(Attribute::NoCapture);
199        PAS = AttributeSet::get(mMod->getContext(), 1U, B);
200    }
201    Attrs.push_back(PAS);
202    {
203        AttrBuilder B;
204        B.addAttribute(Attribute::NoCapture);
205        PAS = AttributeSet::get(mMod->getContext(), 2U, B);
206    }
207    Attrs.push_back(PAS);
208    {
209        AttrBuilder B;
210        B.addAttribute(Attribute::NoCapture);
211        PAS = AttributeSet::get(mMod->getContext(), 3U, B);
212    }
213    Attrs.push_back(PAS);
214    {
215        AttrBuilder B;
216        B.addAttribute(Attribute::NoUnwind);
217        B.addAttribute(Attribute::UWTable);
218        PAS = AttributeSet::get(mMod->getContext(), ~0U, B);
219    }
220    AttributeSet AttrSet = AttributeSet::get(mMod->getContext(), Attrs);
221
222    //Create the function that will be generated.
223    mFunc_process_block = mMod->getFunction("process_block");
224    if (!mFunc_process_block) {
225        mFunc_process_block = Function::Create(
226            /*Type=*/mFuncTy_0,
227            /*Linkage=*/GlobalValue::ExternalLinkage,
228            /*Name=*/"process_block", mMod);
229        mFunc_process_block->setCallingConv(CallingConv::C);
230    }
231    mFunc_process_block->setAttributes(AttrSet);
232}
233
234void LLVM_Generator::MakeLLVMModule()
235{
236    mMod = new Module("icgrep", getGlobalContext());
237    mMod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128");
238    mMod->setTargetTriple("x86_64-unknown-linux-gnu");
239}
240
241void LLVM_Generator::StoreBitBlockMarkerPtr(std::string name, int index)
242{
243    IRBuilder<> b(mBasicBlock);
244
245    Value* basis_bits_struct = b.CreateLoad(mPtr_basis_bits_addr);
246    Value* struct_indices[] = {b.getInt64(0), b.getInt32(index)};
247    Value* basis_bits_struct_GEP = b.CreateGEP(basis_bits_struct, struct_indices, name);
248    mMarkerMap.insert(make_pair(name, basis_bits_struct_GEP));
249}
250
251Value* LLVM_Generator::GetMarker(std::string name)
252{
253    IRBuilder<> b(mBasicBlock);
254
255    if (mMarkerMap.find(name) == mMarkerMap.end())
256    {       
257        Value* ptr = b.CreateAlloca(m64x2Vect);
258        Value* void_1 = b.CreateStore(mConst_Aggregate_64x2_0, ptr);
259        mMarkerMap.insert(make_pair(name, ptr));
260    }
261    std::map<std::string, Value*>::iterator itGet = mMarkerMap.find(name);
262
263    return itGet->second;
264}
265
266void LLVM_Generator::SetReturnMarker(std::string marker, int output_idx)
267{
268    IRBuilder<> b(mBasicBlock);
269
270    Value* marker_bitblock = b.CreateLoad(GetMarker(marker));
271    Value* output_struct = b.CreateLoad(mPtr_output_addr);
272    Value* output_indices[] = {b.getInt64(0), b.getInt32(output_idx)};
273    Value* output_struct_GEP = b.CreateGEP(output_struct, output_indices, "return" + marker);
274    Value* store_marker = b.CreateStore(marker_bitblock, output_struct_GEP);
275}
276
277std::string LLVM_Generator::Generate_PabloStatements(std::list<PabloS*> stmts)
278{
279    std::string retVal = "";
280
281    std::list<PabloS*>::iterator it;
282    for (it = stmts.begin(); it != stmts.end(); ++it)
283    {
284        retVal = Generate_PabloS(*it);
285    }
286
287    return retVal;
288}
289
290std::string LLVM_Generator::Generate_PabloS(PabloS *stmt)
291{
292    std::string retVal = "";
293
294    if (Assign* assign = dynamic_cast<Assign*>(stmt))
295    {
296        IRBuilder<> b(mBasicBlock);
297
298        b.CreateStore(Generate_PabloE(assign->getExpr()), GetMarker(assign->getM()));
299
300        retVal = assign->getM();
301    }
302    else if (While* whl = dynamic_cast<While*>(stmt))
303    {
304        int idx = mCarryQueueIdx;
305
[3914]306        //With this call to the while body we will account for all of the carry in values.
[3850]307        std::string returnMarker = Generate_PabloStatements(whl->getPSList());
308
[3914]309        BasicBlock*  whileCondBlock = BasicBlock::Create(mMod->getContext(), "while.cond", mFunc_process_block, 0);
310        BasicBlock*  whileBodyBlock = BasicBlock::Create(mMod->getContext(), "while.body",mFunc_process_block, 0);
311        BasicBlock*  whileEndBlock = BasicBlock::Create(mMod->getContext(), "while.end",mFunc_process_block, 0);
[3850]312
[3914]313        IRBuilder<> b(mBasicBlock);
314        b.CreateBr(whileCondBlock);
315        mBasicBlock = whileCondBlock;
316        IRBuilder<> b_cond(whileCondBlock);
317
[3850]318        Value* expression_marker_value = Generate_PabloE(whl->getExpr());
319        // Use an i128 compare for simplicity and speed.
320        Value* cast_marker_value_1 = b_cond.CreateBitCast(expression_marker_value, IntegerType::get(mMod->getContext(), 128));
321        Value* int_tobool1 = b_cond.CreateICmpEQ(cast_marker_value_1, ConstantInt::get(IntegerType::get(mMod->getContext(), 128), 0));
[3914]322        b_cond.CreateCondBr(int_tobool1, whileEndBlock, whileBodyBlock);
[3850]323
[3914]324        mBasicBlock = whileBodyBlock;
325        mCarryQueueIdx = 0;
326        //Store the current carry queue.
327        Value* ptr_last_carry_q = mptr_carry_q;
[3850]328
[3914]329        IRBuilder<> b_wb1(mBasicBlock);
330        //Create and initialize a new carry queue.
331        Value* ptr_while_carry_q = b_wb1.CreateAlloca(m64x2Vect, b_wb1.getInt64(mCarryQueueSize - idx));
332        for (int i=0; i<(mCarryQueueSize-idx); i++)
333        {
334            Value* carryq_idx1 = b_wb1.getInt64(i);
335            Value* carryq_GEP1 = b_wb1.CreateGEP(ptr_while_carry_q, carryq_idx1);
336            Value* void_1 = b_wb1.CreateStore(mConst_Aggregate_64x2_0, carryq_GEP1);
337        }
338
339        //Point mptr_carry_q to the new local carry queue.
340        mptr_carry_q = ptr_while_carry_q;
341
[3850]342        returnMarker = Generate_PabloStatements(whl->getPSList());
343
[3914]344        IRBuilder<> b_wb2(mBasicBlock);
345        //Copy back to the last carry queue the carries from the execution of the while statement list.
346        for (int c=0; c<(mCarryQueueSize-idx); c++)
347        {
348            Value* carryq_idx = b_wb2.getInt64(c);
349            Value* carryq_GEP = b_wb2.CreateGEP(mptr_carry_q, carryq_idx);
350            Value* carryq_value = b_wb2.CreateLoad(carryq_GEP);
[3850]351
[3914]352            Value* last_carryq_idx = b_wb2.getInt64(idx + c);
353            Value* last_carryq_GEP = b_wb2.CreateGEP(ptr_last_carry_q, last_carryq_idx);
354            Value* last_carryq_value = b_wb2.CreateLoad(last_carryq_GEP);
355
356            Value* new_carryq_value = b_wb2.CreateOr(carryq_value, last_carryq_value);
357            Value* void_1 = b_wb2.CreateStore(new_carryq_value, last_carryq_GEP);
358        }
359
360        b_wb2.CreateBr(whileCondBlock);
361
362        mBasicBlock = whileEndBlock;
363        mptr_carry_q = ptr_last_carry_q;
364        mCarryQueueIdx += idx;
365
[3850]366        retVal = returnMarker;
367    }
368
369    return retVal;
370}
371
372Value* LLVM_Generator::Generate_PabloE(PabloE *expr)
373{
374    Value* retVal = 0;
375
376    if (All* all = dynamic_cast<All*>(expr))
377    {
378        IRBuilder<> b(mBasicBlock);
379
380        if ((all->getNum() != 0) && (all->getNum() != 1))
381            std::cout << "\nErr: 'All' can only be set to 1 or 0.\n" << std::endl;
382        Value* ptr_all = b.CreateAlloca(m64x2Vect);
383        Value* void_1 = b.CreateStore((all->getNum() == 0 ? mConst_Aggregate_64x2_0 : mConst_Aggregate_64x2_neg1), ptr_all);
384        Value* all_value = b.CreateLoad(ptr_all);
385
386        retVal = all_value;
387    }
388    else if (Var* var = dynamic_cast<Var*>(expr))
389    {
390        IRBuilder<> b(mBasicBlock);
391
392        Value* var_value = b.CreateLoad(GetMarker(var->getVar()), false, var->getVar());
393
394        retVal = var_value;
395    }
396    else if (And* pablo_and = dynamic_cast<And*>(expr))
397    {
398        IRBuilder<> b(mBasicBlock);
399
400        Value* and_result = b.CreateAnd(Generate_PabloE(pablo_and->getExpr1()), Generate_PabloE(pablo_and->getExpr2()), "and_inst");
401
402        retVal = and_result;
403    }
404    else if (Or* pablo_or = dynamic_cast<Or*>(expr))
405    {
406        IRBuilder<> b(mBasicBlock);
407
408        Value* or_result = b.CreateOr(Generate_PabloE(pablo_or->getExpr1()), Generate_PabloE(pablo_or->getExpr2()), "or_inst");
409
410        retVal = or_result;
411    }
412    else if (Sel* pablo_sel = dynamic_cast<Sel*>(expr))
413    {
414        IRBuilder<>b(mBasicBlock);
415
416        Value* and_if_true_result = b.CreateAnd(Generate_PabloE(pablo_sel->getIf_expr()), Generate_PabloE(pablo_sel->getT_expr()));
417        Constant* const_packed_elems [] = {b.getInt64(-1), b.getInt64(-1)};
418        Constant* const_packed = ConstantVector::get(const_packed_elems);
419        Value* not_if_result = b.CreateXor(Generate_PabloE(pablo_sel->getIf_expr()), const_packed);
420        Value* and_if_false_result = b.CreateAnd(not_if_result, Generate_PabloE(pablo_sel->getF_expr()));
421        Value* or_result = b.CreateOr(and_if_true_result, and_if_false_result);
422
423        retVal = or_result;
424    }
425    else if (Not* pablo_not = dynamic_cast<Not*>(expr))
426    {
427        IRBuilder<> b(mBasicBlock);
428
429        Constant* const_packed_elems [] = {b.getInt64(-1), b.getInt64(-1)};
430        Constant* const_packed = ConstantVector::get(const_packed_elems);
431        Value* expr_value = Generate_PabloE(pablo_not->getExpr());
432        Value* xor_rslt = b.CreateXor(expr_value, const_packed, "xor_inst");
433
434        retVal = xor_rslt;
435    }
436    else if (CharClass* cc = dynamic_cast<CharClass*>(expr))
437    {
438        IRBuilder<> b(mBasicBlock);
439
440        Value* character_class = b.CreateLoad(GetMarker(cc->getCharClass()));
441
442        retVal = character_class;
443    }
444    else if (Advance* adv = dynamic_cast<Advance*>(expr))
445    {
446        IRBuilder<> b(mBasicBlock);
447
448        //CarryQ - carry in.
449        Value* carryq_idx = b.getInt64(mCarryQueueIdx);
450        Value* carryq_GEP = b.CreateGEP(mptr_carry_q, carryq_idx);
451        Value* carryq_value = b.CreateLoad(carryq_GEP);
452
453        Value* strm_value = Generate_PabloE(adv->getExpr());
454        Value* srli_1_value = b.CreateLShr(strm_value, 63);
455
456        Value* packed_shuffle;
[3914]457        Constant* const_packed_1_elems [] = {b.getInt32(0), b.getInt32(2)};
458        Constant* const_packed_1 = ConstantVector::get(const_packed_1_elems);
459        packed_shuffle = b.CreateShuffleVector(carryq_value, srli_1_value, const_packed_1, "packed_shuffle nw");
[3850]460
461        Constant* const_packed_2_elems[] = {b.getInt64(1), b.getInt64(1)};
462        Constant* const_packed_2 = ConstantVector::get(const_packed_2_elems);
463
464        Value* shl_value = b.CreateShl(strm_value, const_packed_2, "shl_value");
465        Value* result_value = b.CreateOr(shl_value, packed_shuffle, "or.result_value");
466
467        //CarryQ - carry out.
468        Value* cast_marker_value_1 = b.CreateBitCast(strm_value, IntegerType::get(mMod->getContext(), 128));
469        Value* srli_2_value = b.CreateLShr(cast_marker_value_1, 127);
470        Value* carryout_2_carry = b.CreateBitCast(srli_2_value, m64x2Vect);
[3914]471        Value* void_1 = b.CreateStore(carryout_2_carry, carryq_GEP);
[3850]472
473        //Increment the idx for the next advance or scan through.
474        mCarryQueueIdx++;
475
476        retVal = result_value;
477    }
478    else if (MatchStar* mstar = dynamic_cast<MatchStar*>(expr))
479    {
480        IRBuilder<> b(mBasicBlock);
481
482        //CarryQ - carry in.
483        Value* carryq_idx = b.getInt64(mCarryQueueIdx);
484        Value* carryq_GEP = b.CreateGEP(mptr_carry_q, carryq_idx);
485        Value* carryq_value = b.CreateLoad(carryq_GEP);
486        //Get the input stream.
487        Value* strm_value = Generate_PabloE(mstar->getExpr1());
488        //Get the character that is to be matched.
489        Value* cc_value = Generate_PabloE(mstar->getExpr2());
490
491        Value* and_value_1 = b.CreateAnd(cc_value, strm_value, "match_star_and_value_1");
492        Value* add_value_1 = b.CreateAdd(and_value_1, cc_value, "match_star_add_value_1");
493        Value* add_value_2 = b.CreateAdd(add_value_1, carryq_value, "match_star_add_value_2");
494        Value* xor_value_1 = b.CreateXor(add_value_2, mConst_Aggregate_64x2_neg1, "match_star_xor_value_1");
495        Value* and_value_2 = b.CreateAnd(cc_value, xor_value_1, "match_star_and_value_2");
496        Value* or_value_1 = b.CreateOr(and_value_1, and_value_2, "match_star_or_value_1");
497
498        Value* srli_instr_1 = b.CreateLShr(or_value_1, 63);
499
500        Value* cast_marker_value_1 = b.CreateBitCast(srli_instr_1, IntegerType::get(mMod->getContext(), 128));
501        Value* sll_1_value = b.CreateShl(cast_marker_value_1, 64);
502        Value* cast_marker_value_2 = b.CreateBitCast(sll_1_value, m64x2Vect);
503
504
505        Value* add_value_3 = b.CreateAdd(cast_marker_value_2, add_value_2, "match_star_add_value_3");
506        Value* xor_value_2 = b.CreateXor(add_value_3, mConst_Aggregate_64x2_neg1, "match_star_xor_value_2");
507        Value* and_value_3 = b.CreateAnd(cc_value, xor_value_2, "match_star_and_value_3");
508        Value* or_value_2  = b.CreateOr(and_value_1, and_value_3, "match_star_or_value_2 ");
509        Value* xor_value_3 = b.CreateXor(add_value_3, cc_value, "match_star_xor_value_3");
510        Value* result_value = b.CreateOr(xor_value_3, strm_value, "match_star_result_value");
511
512        //CarryQ - carry out:
513        Value* cast_marker_value_3 = b.CreateBitCast(or_value_2, IntegerType::get(mMod->getContext(), 128));
514        Value* srli_2_value = b.CreateLShr(cast_marker_value_3, 127);
515        Value* carryout_2_carry = b.CreateBitCast(srli_2_value, m64x2Vect);
516
517        Value* void_1 = b.CreateStore(carryout_2_carry, carryq_GEP);
518
519        mCarryQueueIdx++;
520
521        retVal = result_value;
522    }
523
524    return retVal;
525}
526
Note: See TracBrowser for help on using the repository browser.