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

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

More 32-bit fixes.

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