source: icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp @ 5267

Last change on this file since 5267 was 5267, checked in by nmedfort, 3 years ago

Code clean-up. Removed Pablo Call, SetIthBit? and Prototype.

File size: 23.3 KB
Line 
1/*
2 *  Copyright (c) 2014-16 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 "pablo_compiler.h"
8#include <pablo/pablo_kernel.h>
9#include <pablo/pablo_toolchain.h>
10#include <pablo/codegenstate.h>
11#include <pablo/boolean.h>
12#include <pablo/arithmetic.h>
13#include <pablo/branch.h>
14#include <pablo/pe_advance.h>
15#include <pablo/pe_lookahead.h>
16#include <pablo/pe_matchstar.h>
17#include <pablo/pe_scanthru.h>
18#include <pablo/pe_infile.h>
19#include <pablo/pe_count.h>
20#include <pablo/pe_integer.h>
21#include <pablo/pe_string.h>
22#include <pablo/pe_zeroes.h>
23#include <pablo/pe_ones.h>
24#include <pablo/pe_var.h>
25#include <pablo/ps_assign.h>
26#include <pablo/carry_manager.h>
27#include <IR_Gen/idisa_builder.h>
28#include <llvm/IR/Module.h>
29
30using namespace llvm;
31
32namespace pablo {
33
34using TypeId = PabloAST::ClassTypeId;
35
36void PabloCompiler::initializeKernelData() {
37    Examine();
38    mCarryManager->initializeCarryData(mKernel);
39}
40   
41void PabloCompiler::compile(Value * const self, Function * function) {
42
43    // Make sure that we generate code into the right module.
44    mSelf = self;
45    mFunction = function;
46
47    //Generate Kernel//
48    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", function, 0));
49
50    mCarryManager->initializeCodeGen(self, function);
51     
52    PabloBlock * const entryBlock = mKernel->getEntryBlock(); assert (entryBlock);
53    mMarkerMap.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
54    mMarkerMap.emplace(entryBlock->createOnes(), iBuilder->allOnes());
55
56    Value * const blockNo = mKernel->getScalarField(mSelf, blockNoScalar);
57
58    for (unsigned i = 0; i < mKernel->getNumOfInputs(); ++i) {
59        Var * var = mKernel->getInput(i);
60        std::string name = var->getName()->to_string();
61        Value * input = nullptr;
62        if (var->getType()->isSingleValueType()) {
63            input = mKernel->getScalarFieldPtr(mSelf, name);
64        } else {
65            input = mKernel->getStreamSetPtr(mSelf, name, blockNo);
66        }
67        mMarkerMap.emplace(var, input);
68    }
69
70    for (unsigned i = 0; i < mKernel->getNumOfOutputs(); ++i) {
71        Var * var = mKernel->getOutput(i);
72        std::string name = var->getName()->to_string();
73        Value * output = nullptr;
74        if (var->getType()->isSingleValueType()) {
75            output = mKernel->getScalarFieldPtr(mSelf, name);
76        } else {
77            output = mKernel->getStreamSetPtr(mSelf, name, blockNo);
78        }
79        mMarkerMap.emplace(var, output);
80    }
81
82    compileBlock(entryBlock);
83
84    #ifdef PRINT_TIMING_INFORMATION
85    const timestamp_t pablo_compilation_end = read_cycle_counter();
86    std::cerr << "PABLO COMPILATION TIME: " << (pablo_compilation_end - pablo_compilation_start) << std::endl;
87    #endif
88}
89
90inline void PabloCompiler::Examine() {
91    Examine(mKernel->getEntryBlock());
92}
93
94void PabloCompiler::Examine(const PabloBlock * const block) {
95    for (const Statement * stmt : *block) {
96        if (LLVM_UNLIKELY(isa<Lookahead>(stmt))) {
97            const Lookahead * const la = cast<Lookahead>(stmt);
98            assert (isa<Var>(la->getExpr()));
99            if (LLVM_LIKELY(la->getAmount() > mKernel->getLookAhead())) {
100                mKernel->setLookAhead(la->getAmount());
101            }
102        } else if (LLVM_UNLIKELY(isa<Branch>(stmt))) {
103            Examine(cast<Branch>(stmt)->getBody());
104        }
105    }   
106}
107
108inline void PabloCompiler::compileBlock(const PabloBlock * const block) {
109    for (const Statement * statement : *block) {
110        compileStatement(statement);
111    }
112}
113
114static const llvm::StringRef EmptyString;
115
116inline const llvm::StringRef & getName(const PabloAST * expr) {
117    if (expr->getName()) {
118        return expr->getName()->value();
119    }
120    return EmptyString;
121}
122
123void PabloCompiler::compileIf(const If * const ifStatement) {
124    //
125    //  The If-ElseZero stmt:
126    //  if <predicate:expr> then <body:stmt>* elsezero <defined:var>* endif
127    //  If the value of the predicate is nonzero, then determine the values of variables
128    //  <var>* by executing the given statements.  Otherwise, the value of the
129    //  variables are all zero.  Requirements: (a) no variable that is defined within
130    //  the body of the if may be accessed outside unless it is explicitly
131    //  listed in the variable list, (b) every variable in the defined list receives
132    //  a value within the body, and (c) the logical consequence of executing
133    //  the statements in the event that the predicate is zero is that the
134    //  values of all defined variables indeed work out to be 0.
135    //
136    //  Simple Implementation with Phi nodes:  a phi node in the if exit block
137    //  is inserted for each variable in the defined variable list.  It receives
138    //  a zero value from the ifentry block and the defined value from the if
139    //  body.
140    //
141
142    BasicBlock * const ifEntryBlock = iBuilder->GetInsertBlock();
143    BasicBlock * const ifBodyBlock = BasicBlock::Create(mFunction->getContext(), "if.body", mFunction);
144    BasicBlock * const ifEndBlock = BasicBlock::Create(mFunction->getContext(), "if.end", mFunction);
145   
146    std::vector<std::pair<const Var *, Value *>> incoming;
147
148    for (const Var * var : ifStatement->getEscaped()) {
149        auto f = mMarkerMap.find(var);
150        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
151            std::string tmp;
152            raw_string_ostream out(tmp);
153            var->print(out);
154            out << " is uninitialized prior to entering ";
155            ifStatement->print(out);
156            llvm::report_fatal_error(out.str());
157        }
158        incoming.emplace_back(var, f->second);
159    }
160
161    PabloBlock * ifBody = ifStatement->getBody();
162   
163    mCarryManager->enterIfScope(ifBody);
164
165    Value * condition = compileExpression(ifStatement->getCondition());
166    if (condition->getType() == iBuilder->getBitBlockType()) {
167        condition = iBuilder->bitblock_any(mCarryManager->generateSummaryTest(condition));
168    }
169   
170    iBuilder->CreateCondBr(condition, ifBodyBlock, ifEndBlock);
171   
172    // Entry processing is complete, now handle the body of the if.
173    iBuilder->SetInsertPoint(ifBodyBlock);
174
175    mCarryManager->enterIfBody(ifEntryBlock);
176
177    compileBlock(ifBody);
178
179    BasicBlock * ifExitBlock = iBuilder->GetInsertBlock();   
180
181    mCarryManager->leaveIfBody(ifExitBlock);
182
183    iBuilder->CreateBr(ifEndBlock);
184    //End Block
185    iBuilder->SetInsertPoint(ifEndBlock);
186
187    mCarryManager->leaveIfScope(ifEntryBlock, ifExitBlock);
188
189    for (const auto i : incoming) {
190        const Var * var; Value * value;
191        std::tie(var, value) = i;
192
193        auto f = mMarkerMap.find(var);
194        if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == value)) {
195            std::string tmp;
196            raw_string_ostream out(tmp);
197            var->print(out);
198            out << " was not assigned a value.";
199            llvm::report_fatal_error(out.str());
200        }
201
202        Value * const next = f->second;
203
204        assert (value->getType() == next->getType());
205
206        PHINode * phi = iBuilder->CreatePHI(value->getType(), 2, getName(var));
207        phi->addIncoming(value, ifEntryBlock);
208        phi->addIncoming(next, ifExitBlock);
209        f->second = phi;
210
211        assert (mMarkerMap[var] == phi);
212    }   
213}
214
215void PabloCompiler::compileWhile(const While * const whileStatement) {
216
217    PabloBlock * const whileBody = whileStatement->getBody();
218   
219    BasicBlock * whileEntryBlock = iBuilder->GetInsertBlock();
220
221    BasicBlock * whileBodyBlock = BasicBlock::Create(iBuilder->getContext(), "while.body", mFunction);
222
223    BasicBlock * whileEndBlock = BasicBlock::Create(iBuilder->getContext(), "while.end", mFunction);
224
225    const auto escaped = whileStatement->getEscaped();
226
227#ifdef ENABLE_BOUNDED_WHILE
228    PHINode * bound_phi = nullptr;  // Needed for bounded while loops.
229#endif
230    // On entry to the while structure, proceed to execute the first iteration
231    // of the loop body unconditionally.   The while condition is tested at the end of
232    // the loop.
233
234    mCarryManager->enterLoopScope(whileBody);
235
236    iBuilder->CreateBr(whileBodyBlock);
237
238    iBuilder->SetInsertPoint(whileBodyBlock);
239
240    //
241    // There are 3 sets of Phi nodes for the while loop.
242    // (1) Carry-ins: (a) incoming carry data first iterations, (b) zero thereafter
243    // (2) Carry-out accumulators: (a) zero first iteration, (b) |= carry-out of each iteration
244    // (3) Next nodes: (a) values set up before loop, (b) modified values calculated in loop.
245#ifdef ENABLE_BOUNDED_WHILE
246    // (4) The loop bound, if any.
247#endif
248
249    std::vector<std::pair<const Var *, PHINode *>> variants;
250
251    // for any Next nodes in the loop body, initialize to (a) pre-loop value.
252    for (const auto var : escaped) {
253        auto f = mMarkerMap.find(var);
254        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
255            std::string tmp;
256            raw_string_ostream out(tmp);
257            var->print(out);
258            out << " is uninitialized prior to entering ";
259            whileStatement->print(out);
260            llvm::report_fatal_error(out.str());
261        }
262        Value * entryValue = f->second;
263        PHINode * phi = iBuilder->CreatePHI(entryValue->getType(), 2, getName(var));
264        phi->addIncoming(entryValue, whileEntryBlock);
265        f->second = phi;
266        assert(mMarkerMap[var] == phi);
267        variants.emplace_back(var, phi);
268    }
269#ifdef ENABLE_BOUNDED_WHILE
270    if (whileStatement->getBound()) {
271        bound_phi = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "while_bound");
272        bound_phi->addIncoming(iBuilder->getSize(whileStatement->getBound()), whileEntryBlock);
273    }
274#endif
275
276    mCarryManager->enterLoopBody(whileEntryBlock);
277
278    //
279    // Now compile the loop body proper.  Carry-out accumulated values
280    // and iterated values of Next nodes will be computed.
281    compileBlock(whileBody);
282
283    // After the whileBody has been compiled, we may be in a different basic block.
284    BasicBlock * whileExitBlock = iBuilder->GetInsertBlock();
285
286    mCarryManager->leaveLoopBody(whileExitBlock);
287
288    // Terminate the while loop body with a conditional branch back.
289    Value * condition = compileExpression(whileStatement->getCondition());
290    if (condition->getType() == iBuilder->getBitBlockType()) {
291        condition = iBuilder->bitblock_any(condition);
292    }
293#ifdef ENABLE_BOUNDED_WHILE
294    if (whileStatement->getBound()) {
295        Value * new_bound = iBuilder->CreateSub(bound_phi, iBuilder->getSize(1));
296        bound_phi->addIncoming(new_bound, whileExitBlock);
297        condition = iBuilder->CreateAnd(condition, iBuilder->CreateICmpUGT(new_bound, ConstantInt::getNullValue(iBuilder->getSizeTy())));
298    }
299#endif
300
301    // and for any variant nodes in the loop body
302    for (const auto variant : variants) {
303        const Var * var; PHINode * phi;
304        std::tie(var, phi) = variant;
305        const auto f = mMarkerMap.find(var);
306        if (LLVM_UNLIKELY(f == mMarkerMap.end() || f->second == phi)) {
307            std::string tmp;
308            raw_string_ostream out(tmp);
309            var->print(out);
310            out << " was not assigned a value.";
311            llvm::report_fatal_error(out.str());
312        }
313        Value * exitValue = f->second;
314        assert (phi->getType() == exitValue->getType());
315        phi->addIncoming(exitValue, whileExitBlock);
316        f->second = phi;
317    }
318
319    iBuilder->CreateCondBr(condition, whileBodyBlock, whileEndBlock);
320
321    iBuilder->SetInsertPoint(whileEndBlock);
322
323    mCarryManager->leaveLoopScope(whileEntryBlock, whileExitBlock);
324
325}
326
327void PabloCompiler::compileStatement(const Statement * stmt) {
328
329    if (LLVM_UNLIKELY(isa<If>(stmt))) {
330        compileIf(cast<If>(stmt));
331    } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
332        compileWhile(cast<While>(stmt));
333    } else {
334        const PabloAST * expr = stmt;
335        Value * value = nullptr;
336        if (LLVM_UNLIKELY(isa<Assign>(stmt))) {
337
338            expr = cast<Assign>(stmt)->getVariable();
339            value = compileExpression(cast<Assign>(stmt)->getValue());
340
341            bool storeInstRequired = false;
342            if (LLVM_LIKELY(isa<Var>(expr))) {
343                for (unsigned i = 0; i < mKernel->getNumOfOutputs(); ++i) {
344                    if (expr == mKernel->getOutput(i)) {
345                        storeInstRequired = true;
346                        break;
347                    }
348                }
349            }
350
351            if (LLVM_UNLIKELY(storeInstRequired || isa<Extract>(expr))) {
352                const auto f = mMarkerMap.find(expr);
353                if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
354                    std::string tmp;
355                    raw_string_ostream out(tmp);
356                    out << "PabloCompiler: use-before-definition error: ";
357                    expr->print(out);
358                    out << " does not dominate ";
359                    stmt->print(out);
360                    llvm::report_fatal_error(out.str());
361                }
362                Value * const ptr = f->second;
363
364                assert (&(value->getContext()) == &(ptr->getContext()));
365
366                if (isa<Count>(cast<Assign>(stmt)->getValue())) {
367                    Value * count = iBuilder->CreateLoad(ptr);
368                    value = iBuilder->CreateTruncOrBitCast(value, count->getType());
369                    value = iBuilder->CreateAdd(value, count);
370                }
371
372                const Type * const type = value->getType();
373                if (isa<VectorType>(type) || isa<IntegerType>(type)) {
374                    const auto bitWidth = isa<VectorType>(type)
375                            ? cast<VectorType>(type)->getBitWidth()
376                            : cast<IntegerType>(type)->getBitWidth();
377                    iBuilder->CreateAlignedStore(value, ptr, bitWidth / 8);
378                } else {
379                    iBuilder->CreateStore(value, ptr);
380                }
381            }
382
383        } else if (const Extract * extract = dyn_cast<Extract>(stmt)) {
384            Value * array = compileExpression(extract->getArray(), false);
385            Value * index = compileExpression(extract->getIndex());
386            value = iBuilder->CreateGEP(array, {ConstantInt::getNullValue(index->getType()), index}, getName(stmt));
387        } else if (isa<And>(stmt)) {
388            value = compileExpression(stmt->getOperand(0));
389            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
390                value = iBuilder->simd_and(value, compileExpression(stmt->getOperand(1)));
391            }
392        } else if (isa<Or>(stmt)) {
393            value = compileExpression(stmt->getOperand(0));
394            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
395                value = iBuilder->simd_or(value, compileExpression(stmt->getOperand(1)));
396            }
397        } else if (isa<Xor>(stmt)) {
398            value = compileExpression(stmt->getOperand(0));
399            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
400                value = iBuilder->simd_xor(value, compileExpression(stmt->getOperand(1)));
401            }
402        } else if (const Sel * sel = dyn_cast<Sel>(stmt)) {
403            Value* ifMask = compileExpression(sel->getCondition());
404            Value* ifTrue = iBuilder->simd_and(ifMask, compileExpression(sel->getTrueExpr()));
405            Value* ifFalse = iBuilder->simd_and(iBuilder->simd_not(ifMask), compileExpression(sel->getFalseExpr()));
406            value = iBuilder->simd_or(ifTrue, ifFalse);
407        } else if (isa<Not>(stmt)) {
408            value = iBuilder->simd_not(compileExpression(stmt->getOperand(0)));
409        } else if (isa<Advance>(stmt)) {
410            const Advance * const adv = cast<Advance>(stmt);
411            // If our expr is an Extract op on a mutable Var then we need to pass the index value to the carry
412            // manager so that it properly selects the correct carry bit.
413            value = mCarryManager->advanceCarryInCarryOut(adv, compileExpression(adv->getExpression()));
414        } else if (const MatchStar * mstar = dyn_cast<MatchStar>(stmt)) {
415            Value * const marker = compileExpression(mstar->getMarker());
416            Value * const cc = compileExpression(mstar->getCharClass());
417            Value * const marker_and_cc = iBuilder->simd_and(marker, cc);
418            Value * const sum = mCarryManager->addCarryInCarryOut(mstar, marker_and_cc, cc);
419            value = iBuilder->simd_or(iBuilder->simd_xor(sum, cc), marker);
420        } else if (const ScanThru * sthru = dyn_cast<ScanThru>(stmt)) {
421            Value * const marker_expr = compileExpression(sthru->getScanFrom());
422            Value * const cc_expr = compileExpression(sthru->getScanThru());
423            Value * const sum = mCarryManager->addCarryInCarryOut(sthru, marker_expr, cc_expr);
424            value = iBuilder->simd_and(sum, iBuilder->simd_not(cc_expr));
425        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
426            Value * EOFmask = mKernel->getScalarField(mSelf, "EOFmask");
427            value = iBuilder->simd_xor(compileExpression(e->getExpr()), EOFmask);
428        } else if (const AtEOF * e = dyn_cast<AtEOF>(stmt)) {
429            Value * EOFbit = mKernel->getScalarField(mSelf, "EOFbit");
430            value = iBuilder->simd_and(compileExpression(e->getExpr()), EOFbit);
431        } else if (const Count * c = dyn_cast<Count>(stmt)) {
432            Value * const to_count = compileExpression(c->getExpr());
433            const unsigned counterSize = iBuilder->getSizeTy()->getBitWidth();
434            Value * const partial = iBuilder->simd_popcount(counterSize, to_count);
435            if (LLVM_UNLIKELY(counterSize <= 1)) {
436                value = partial;
437            } else {
438                value = iBuilder->mvmd_extract(counterSize, partial, 0);
439                const auto fields = (iBuilder->getBitBlockWidth() / counterSize);
440                for (unsigned i = 1; i < fields; ++i) {
441                    Value * temp = iBuilder->mvmd_extract(counterSize, partial, i);
442                    value = iBuilder->CreateAdd(value, temp);
443                }
444            }
445        } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
446            PabloAST * const var = l->getExpr();
447            if (LLVM_UNLIKELY(!isa<Var>(var))) {
448                throw std::runtime_error("Lookahead operations may only be applied to input streams");
449            }
450            unsigned index = 0;
451            for (; index < mKernel->getNumOfInputs(); ++index) {
452                if (mKernel->getInput(index) == var) {
453                    break;
454                }
455            }
456            if (LLVM_UNLIKELY(index >= mKernel->getNumOfInputs())) {
457                throw std::runtime_error("Lookahead has an illegal Var operand");
458            }
459            const unsigned bit_shift = (l->getAmount() % iBuilder->getBitBlockWidth());
460            const unsigned block_shift = (l->getAmount() / iBuilder->getBitBlockWidth());
461            std::string inputName = var->getName()->to_string();;
462            Value * blockNo = mKernel->getScalarField(mSelf, blockNoScalar);
463            Value * lookAhead_blockPtr  = mKernel->getStreamSetPtr(mSelf, inputName, iBuilder->CreateAdd(blockNo, iBuilder->getSize(block_shift)));
464            Value * lookAhead_inputPtr = iBuilder->CreateGEP(lookAhead_blockPtr, {iBuilder->getInt32(0), iBuilder->getInt32(index)});
465            Value * lookAhead = iBuilder->CreateBlockAlignedLoad(lookAhead_inputPtr);
466            if (bit_shift == 0) {  // Simple case with no intra-block shifting.
467                value = lookAhead;
468            } else { // Need to form shift result from two adjacent blocks.
469                Value * lookAhead_blockPtr1  = mKernel->getStreamSetPtr(mSelf, inputName, iBuilder->CreateAdd(blockNo, iBuilder->getSize(block_shift + 1)));
470                Value * lookAhead_inputPtr1 = iBuilder->CreateGEP(lookAhead_blockPtr1, {iBuilder->getInt32(0), iBuilder->getInt32(index)});
471                Value * lookAhead1 = iBuilder->CreateBlockAlignedLoad(lookAhead_inputPtr1);
472                if (LLVM_UNLIKELY((bit_shift % 8) == 0)) { // Use a single whole-byte shift, if possible.
473                    value = iBuilder->mvmd_dslli(8, lookAhead1, lookAhead, (bit_shift / 8));
474                } else {
475                    Type  * const streamType = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
476                    Value * b1 = iBuilder->CreateBitCast(lookAhead1, streamType);
477                    Value * b0 = iBuilder->CreateBitCast(lookAhead, streamType);
478                    Value * result = iBuilder->CreateOr(iBuilder->CreateShl(b1, iBuilder->getBitBlockWidth() - bit_shift), iBuilder->CreateLShr(b0, bit_shift));
479                    value = iBuilder->CreateBitCast(result, iBuilder->getBitBlockType());
480                }
481            }
482
483        } else {
484            std::string tmp;
485            llvm::raw_string_ostream out(tmp);
486            out << "Internal error: ";
487            stmt->print(out);
488            out << " is not a recognized statement in the Pablo compiler.";
489            throw std::runtime_error(out.str());
490        }
491
492        mMarkerMap[expr] = value;
493        if (DebugOptionIsSet(DumpTrace)) {
494            assert (expr->getName());
495            if (value->getType()->isVectorTy()) {
496                iBuilder->CallPrintRegister(expr->getName()->to_string(), value);
497            } else if (value->getType()->isIntegerTy()) {
498                iBuilder->CallPrintInt(expr->getName()->to_string(), value);
499            }
500        }
501    }
502}
503
504Value * PabloCompiler::compileExpression(const PabloAST * expr, const bool ensureLoaded) const {
505    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
506        return iBuilder->allOnes();
507    } else if (LLVM_UNLIKELY(isa<Zeroes>(expr))) {
508        return iBuilder->allZeroes();
509    } else if (LLVM_UNLIKELY(isa<Integer>(expr))) {
510        return iBuilder->getInt64(cast<Integer>(expr)->value());
511    } else if (LLVM_UNLIKELY(isa<Operator>(expr))) {
512        const Operator * op = cast<Operator>(expr);
513        Value * lh = compileExpression(op->getLH());
514        Value * rh = compileExpression(op->getRH());
515        assert (lh->getType() == rh->getType());
516        switch (op->getClassTypeId()) {
517            case TypeId::Add:
518                return iBuilder->CreateAdd(lh, rh);
519            case TypeId::Subtract:
520                return iBuilder->CreateSub(lh, rh);
521            case TypeId::LessThan:
522                return iBuilder->CreateICmpSLT(lh, rh);
523            case TypeId::LessThanEquals:
524                return iBuilder->CreateICmpSLE(lh, rh);
525            case TypeId::Equals:
526                return iBuilder->CreateICmpEQ(lh, rh);
527            case TypeId::GreaterThanEquals:
528                return iBuilder->CreateICmpSGE(lh, rh);
529            case TypeId::GreaterThan:
530                return iBuilder->CreateICmpSGT(lh, rh);
531            case TypeId::NotEquals:
532                return iBuilder->CreateICmpNE(lh, rh);
533            default:
534                break;
535        }
536        std::string tmp;
537        raw_string_ostream out(tmp);
538        expr->print(out);
539        out << " is not a valid Operator";
540        llvm::report_fatal_error(out.str());
541    }
542    const auto f = mMarkerMap.find(expr);
543    if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
544        std::string tmp;
545        llvm::raw_string_ostream out(tmp);
546        expr->print(out);
547        out << " was used before definition!";
548        throw std::runtime_error(out.str());
549    }
550    Value * value = f->second;
551    if (LLVM_UNLIKELY(isa<GetElementPtrInst>(value) && ensureLoaded)) {
552        value = iBuilder->CreateBlockAlignedLoad(value);
553    }
554    return value;
555}
556
557PabloCompiler::PabloCompiler(PabloKernel * kernel)
558: iBuilder(kernel->getBuilder())
559, mCarryManager(new CarryManager(iBuilder))
560, mKernel(kernel)
561, mFunction(nullptr) {
562
563}
564
565PabloCompiler::~PabloCompiler() {
566    delete mCarryManager;
567}
568
569}
Note: See TracBrowser for help on using the repository browser.